Gestire le attività del corso e i voti

La UI di Classroom supporta cinque tipi di lavori del corso: Compiti, quiz, domande a risposta breve, domande a scelta multipla e Materiali. Attualmente l'API Classroom supporta tre di questi tipi, ovvero sono note come CourseWorkType per l'API: Compiti, Risposta breve e a scelta multipla.

Per accedere a questa funzionalità, puoi utilizzare Risorsa CourseWork, che rappresenta un compito o una domanda assegnati agli studenti in corso specifico, inclusi eventuali materiali e dettagli aggiuntivi, come o il punteggio massimo.

Oltre alla risorsa CourseWork, puoi gestire i compiti completati con la risorsa StudentSubmission. Queste sono descritte nelle sezioni seguenti in modo più dettagliato.

Crea compiti

I compiti possono essere creati solo per conto degli insegnanti del corso. il tentativo di creare compiti in un corso per conto di uno studente avrà come risultato in un errore 403 PERMISSION_DENIED. Analogamente, anche gli amministratori di dominio non possono ai corsi per i quali non insegna e che tentano di farlo tramite l'API genererà anche un errore 403 PERMISSION_DENIED.

Quando crei compiti utilizzando il metodo courses.courseWork.create, devi puoi allegare link come materials, come mostrato nel seguente codice campione:

Java

classroom/snippets/src/main/java/CreateCourseWork.java
CourseWork courseWork = null;
try {
  // Create a link to add as a material on course work.
  Link articleLink =
      new Link()
          .setTitle("SR-71 Blackbird")
          .setUrl("https://www.lockheedmartin.com/en-us/news/features/history/blackbird.html");

  // Create a list of Materials to add to course work.
  List<Material> materials = Arrays.asList(new Material().setLink(articleLink));

  /* Create new CourseWork object with the material attached.
  Set workType to `ASSIGNMENT`. Possible values of workType can be found here:
  https://developers.google.com/classroom/reference/rest/v1/CourseWorkType
  Set state to `PUBLISHED`. Possible values of state can be found here:
  https://developers.google.com/classroom/reference/rest/v1/courses.courseWork#courseworkstate */
  CourseWork content =
      new CourseWork()
          .setTitle("Supersonic aviation")
          .setDescription(
              "Read about how the SR-71 Blackbird, the world’s fastest and "
                  + "highest-flying manned aircraft, was built.")
          .setMaterials(materials)
          .setWorkType("ASSIGNMENT")
          .setState("PUBLISHED");

  courseWork = service.courses().courseWork().create(courseId, content).execute();

  /* Prints the created courseWork. */
  System.out.printf("CourseWork created: %s\n", courseWork.getTitle());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf("The courseId does not exist: %s.\n", courseId);
  } else {
    throw e;
  }
  throw e;
} catch (Exception e) {
  throw e;
}
return courseWork;

Python

classroom/snippets/classroom_create_coursework.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_create_coursework(course_id):
  """
  Creates the coursework the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member

  try:
    service = build("classroom", "v1", credentials=creds)
    coursework = {
        "title": "Ant colonies",
        "description": """Read the article about ant colonies
                              and complete the quiz.""",
        "materials": [
            {"link": {"url": "http://example.com/ant-colonies"}},
            {"link": {"url": "http://example.com/ant-quiz"}},
        ],
        "workType": "ASSIGNMENT",
        "state": "PUBLISHED",
    }
    coursework = (
        service.courses()
        .courseWork()
        .create(courseId=course_id, body=coursework)
        .execute()
    )
    print(f"Assignment created with ID {coursework.get('id')}")
    return coursework

  except HttpError as error:
    print(f"An error occurred: {error}")
    return error


if __name__ == "__main__":
  # Put the course_id of course whose coursework needs to be created,
  # the user has access to.
  classroom_create_coursework(453686957652)

Il risultato include un identificatore assegnato dal server che può essere utilizzato come riferimento l'assegnazione in altre richieste API.

Per includere materiali collegati in un compito creato tramite l'API Classroom: utilizza una risorsa Link, specificando l'URL di destinazione. Classroom recupera automaticamente il titolo e l'immagine della miniatura. L'API Classroom supporta in modo nativo anche Google Drive e i materiali di YouTube, che possono incluso in una risorsa DriveFile risorsa YouTubeVideo in una sezione simile in molti modi diversi.

Per specificare una data di scadenza, imposta i campi dueDate e dueTime su corrispondente all'ora UTC. La data di scadenza deve essere una data futura.

Recuperare compiti e domande

Puoi recuperare compiti e domande per studenti e insegnanti del corso corrispondente o da un amministratore di dominio. Per recuperare uno specifico un compito o una domanda, usa courses.courseWork.get. Per recuperare tutte compiti o domande (che potrebbero corrispondere ad alcuni criteri), usa courses.courseWork.list.

L'ambito richiesto dipende dal ruolo dell'utente che ha inviato la richiesta nella più avanti in questo corso. Se l'utente è uno studente, utilizza uno dei seguenti ambiti:

  • https://www.googleapis.com/auth/classroom.coursework.me.readonly
  • https://www.googleapis.com/auth/classroom.coursework.me

Se l'utente è un insegnante o un amministratore di dominio, utilizza una delle seguenti opzioni: ambiti:

  • https://www.googleapis.com/auth/classroom.coursework.students.readonly
  • https://www.googleapis.com/auth/classroom.coursework.students

L'autorizzazione a recuperare un compito o una domanda non implica le autorizzazioni di accesso ai materiali o ai relativi metadati. In pratica, questo significa gli amministratori potrebbero non vedere il titolo di un file di Drive allegato se sono non è un membro del corso. Se vuoi consentire agli amministratori di accedere all'utente vedi i file a livello di dominio delega guida.

Gestisci le risposte degli studenti

Un StudentSubmission rappresenta il lavoro svolto e il voto di uno studente per un compito domanda. Un StudentSubmission di risorse viene creata in modo implicito per ogni studente quando l'assegnazione.

Le sezioni seguenti illustrano le azioni comuni che gestiscono le risposte degli studenti.

Recupera le risposte degli studenti

Gli studenti possono recuperare i propri compiti, gli insegnanti possono recuperare i contenuti inviati per tutti gli studenti dei loro corsi e gli amministratori di dominio possono recuperare per tutti gli studenti del dominio. I contenuti inviati da ogni studente sono Hanno assegnato un identificatore; se conosci l'identificatore, usa courses.courseWork.studentSubmissions.get per recuperarla.

Utilizza il metodo courses.courseWork.studentSubmissions.list per ottenere StudentSubmission risorse che soddisfano alcuni criteri, come mostrato in nell'esempio seguente:

Java

classroom/snippets/src/main/java/ListSubmissions.java
List<StudentSubmission> studentSubmissions = new ArrayList<>();
String pageToken = null;

try {
  do {
    ListStudentSubmissionsResponse response =
        service
            .courses()
            .courseWork()
            .studentSubmissions()
            .list(courseId, courseWorkId)
            .setPageToken(pageToken)
            .execute();

    /* Ensure that the response is not null before retrieving data from it to avoid errors. */
    if (response.getStudentSubmissions() != null) {
      studentSubmissions.addAll(response.getStudentSubmissions());
      pageToken = response.getNextPageToken();
    }
  } while (pageToken != null);

  if (studentSubmissions.isEmpty()) {
    System.out.println("No student submission found.");
  } else {
    for (StudentSubmission submission : studentSubmissions) {
      System.out.printf(
          "Student id (%s), student submission id (%s)\n",
          submission.getUserId(), submission.getId());
    }
  }
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s) or courseWorkId (%s) does not exist.\n", courseId, courseWorkId);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmissions;

Python

classroom/snippets/classroom_list_submissions.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_list_submissions(course_id, coursework_id):
  """
  Creates the courses the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  submissions = []
  page_token = None

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      response = (
          coursework.studentSubmissions()
          .list(
              pageToken=page_token,
              courseId=course_id,
              courseWorkId=coursework_id,
              pageSize=10,
          )
          .execute()
      )
      submissions.extend(response.get("studentSubmissions", []))
      page_token = response.get("nextPageToken", None)
      if not page_token:
        break

    if not submissions:
      print("No student submissions found.")

    print("Student Submissions:")
    for submission in submissions:
      print(
          "Submitted at:"
          f"{(submission.get('id'), submission.get('creationTime'))}"
      )

  except HttpError as error:
    print(f"An error occurred: {error}")
    submissions = None
  return submissions


if __name__ == "__main__":
  # Put the course_id and coursework_id of course whose list needs to be
  # submitted.
  classroom_list_submissions(453686957652, 466086979658)

Recupera le risorse di StudentSubmission che appartengono a un determinato studente tramite specificando il parametro userId, come mostrato nell'esempio seguente:

Java

classroom/snippets/src/main/java/ListStudentSubmissions.java
List<StudentSubmission> studentSubmissions = new ArrayList<>();
String pageToken = null;

try {
  do {
    // Set the userId as a query parameter on the request.
    ListStudentSubmissionsResponse response =
        service
            .courses()
            .courseWork()
            .studentSubmissions()
            .list(courseId, courseWorkId)
            .setPageToken(pageToken)
            .set("userId", userId)
            .execute();

    /* Ensure that the response is not null before retrieving data from it to avoid errors. */
    if (response.getStudentSubmissions() != null) {
      studentSubmissions.addAll(response.getStudentSubmissions());
      pageToken = response.getNextPageToken();
    }
  } while (pageToken != null);

  if (studentSubmissions.isEmpty()) {
    System.out.println("No student submission found.");
  } else {
    for (StudentSubmission submission : studentSubmissions) {
      System.out.printf("Student submission: %s.\n", submission.getId());
    }
  }

Python

classroom/snippets/classroom_list_student_submissions.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_list_student_submissions(course_id, coursework_id, user_id):
  """
  Creates the courses the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  submissions = []
  page_token = None

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      response = (
          coursework.studentSubmissions()
          .list(
              pageToken=page_token,
              courseId=course_id,
              courseWorkId=coursework_id,
              userId=user_id,
          )
          .execute()
      )
      submissions.extend(response.get("studentSubmissions", []))
      page_token = response.get("nextPageToken", None)
      if not page_token:
        break

    if not submissions:
      print("No student submissions found.")

    print("Student Submissions:")
    for submission in submissions:
      print(
          "Submitted at:"
          f"{(submission.get('id'), submission.get('creationTime'))}"
      )

  except HttpError as error:
    print(f"An error occurred: {error}")
  return submissions


if __name__ == "__main__":
  # Put the course_id, coursework_id and user_id of course whose list needs
  # to be submitted.
  classroom_list_student_submissions(453686957652, 466086979658, "me")

Gli studenti sono identificati dall'ID univoco o dall'indirizzo email dell'utente, come restituiti dall'SDK della Console di amministrazione Google. L'utente corrente può anche fare riferimento al proprio ID utilizzando la forma abbreviata "me".

È anche possibile ottenere i contenuti inviati dagli studenti per tutti i compiti più avanti in questo corso. Per farlo, utilizza il valore letterale "-" come courseWorkId, come mostrato nel nell'esempio seguente:

Java

service.courses().courseWork().studentSubmissions()
    .list(courseId, "-")
    .set("userId", userId)
    .execute();

Python

service.courses().courseWork().studentSubmissions().list(
    courseId=<course ID or alias>,
    courseWorkId='-',
    userId=<user ID>).execute()

L'ambito richiesto dipende dal ruolo dell'utente che ha inviato la richiesta nella più avanti in questo corso. Utilizza il seguente ambito se l'utente è un insegnante o un dominio amministratore:

  • https://www.googleapis.com/auth/classroom.coursework.students.readonly
  • https://www.googleapis.com/auth/classroom.coursework.students

Utilizza il seguente ambito se l'utente è uno studente:

  • https://www.googleapis.com/auth/classroom.coursework.me.readonly
  • https://www.googleapis.com/auth/classroom.coursework.me

L'autorizzazione a recuperare i contenuti inviati da uno studente non implica le autorizzazioni di accesso agli allegati o ai relativi metadati. In pratica, questo indica che un amministratore potrebbe non vedere il titolo di un file di Drive allegato se non fanno parte del corso. Se vuoi consentire l'accesso da parte degli amministratori ai file degli utenti, consulta delega a livello di dominio.

Aggiungere allegati alla risposta di uno studente

Puoi allegare i link ai contenuti inviati da uno studente allegando un Link, Risorsa DriveFile o YouTubeVideo. Questo viene fatto con courses.courseWork.studentSubmissions.modifyAttachments, come mostrato in nell'esempio seguente:

Java

classroom/snippets/src/main/java/ModifyAttachmentsStudentSubmission.java
StudentSubmission studentSubmission = null;
try {
  // Create ModifyAttachmentRequest object that includes a new attachment with a link.
  Link link = new Link().setUrl("https://en.wikipedia.org/wiki/Irrational_number");
  Attachment attachment = new Attachment().setLink(link);
  ModifyAttachmentsRequest modifyAttachmentsRequest =
      new ModifyAttachmentsRequest().setAddAttachments(Arrays.asList(attachment));

  // The modified studentSubmission object is returned with the new attachment added to it.
  studentSubmission =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .modifyAttachments(courseId, courseWorkId, id, modifyAttachmentsRequest)
          .execute();

  /* Prints the modified student submission. */
  System.out.printf(
      "Modified student submission attachments: '%s'.\n",
      studentSubmission.getAssignmentSubmission().getAttachments());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s), courseWorkId (%s), or studentSubmissionId (%s) does "
            + "not exist.\n",
        courseId, courseWorkId, id);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmission;

Python

classroom/snippets/classroom_add_attachment.py
def classroom_add_attachment(course_id, coursework_id, submission_id):
  """
  Adds attachment to existing course with specific course_id.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  request = {
      "addAttachments": [
          {"link": {"url": "http://example.com/quiz-results"}},
          {"link": {"url": "http://example.com/quiz-reading"}},
      ]
  }

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      coursework.studentSubmissions().modifyAttachments(
          courseId=course_id,
          courseWorkId=coursework_id,
          id=submission_id,
          body=request,
      ).execute()

  except HttpError as error:
    print(f"An error occurred: {error}")


if __name__ == "__main__":
  # Put the course_id, coursework_id and submission_id of course in which
  # attachment needs to be added.
  classroom_add_attachment("course_id", "coursework_id", "me")

Un allegato al link viene definito dall'URL di destinazione; Classroom eseguirà automaticamente recupera il titolo e l'immagine della miniatura. Puoi trovare ulteriori informazioni sugli altri materiali all'indirizzo le rispettive pagine di riferimento.

La StudentSubmission può essere modificata solo da un insegnante del corso o lo studente proprietario. Puoi allegare Materials solo se il file CourseWorkType dei contenuti inviati dallo studente è ASSIGNMENT.

L'ambito richiesto dipende dal ruolo dell'utente che ha inviato la richiesta nella più avanti in questo corso. Utilizza il seguente ambito se l'utente è un insegnante:

  • https://www.googleapis.com/auth/classroom.coursework.students

Utilizza il seguente ambito se l'utente è uno studente:

  • https://www.googleapis.com/auth/classroom.coursework.me

Gestisci lo stato delle risposte degli studenti

Le risposte degli studenti possono essere ritirate, consegnate o rispedite. Il campo dello stato in StudentSubmission indica lo stato attuale. Per modificare lo stato, chiama uno dei seguenti metodi:

Tutti questi metodi hanno un corpo vuoto. Esempio:

Java

classroom/snippets/src/main/java/ReturnStudentSubmission.java
try {
  service
      .courses()
      .courseWork()
      .studentSubmissions()
      .classroomReturn(courseId, courseWorkId, id, null)
      .execute();
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s), courseWorkId (%s), or studentSubmissionId (%s) does "
            + "not exist.\n",
        courseId, courseWorkId, id);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}

Python

service.courses().courseWork().studentSubmission().turnIn(
    courseId=<course ID or alias>,
    courseWorkId=<courseWork ID>,
    id=<studentSubmission ID>,
    body={}).execute()

Solo lo studente proprietario di una StudentSubmission può consegnarla o rivendicarla. Solo un invio consegnato può essere rivendicato. Gli insegnanti del corso possono restituire solo StudentSubmission che è in stato Consegnato.

Valuta le risposte degli studenti

La risorsa StudentSubmission ha due campi in cui archiviare i voti: assignedGrade, che è il voto segnalato agli studenti, e draftGrade, che è un voto provvisorio visibile solo agli insegnanti. Questi campi sono stati aggiornati utilizzando courses.courseWork.studentSubmissions.patch con una maschera dei campi contenente i campi appropriati, come mostrato nell'esempio che segue.

Java

classroom/snippets/src/main/java/PatchStudentSubmission.java
StudentSubmission studentSubmission = null;
try {
  // Updating the draftGrade and assignedGrade fields for the specific student submission.
  StudentSubmission content =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .get(courseId, courseWorkId, id)
          .execute();
  content.setAssignedGrade(90.00);
  content.setDraftGrade(80.00);

  // The updated studentSubmission object is returned with the new draftGrade and assignedGrade.
  studentSubmission =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .patch(courseId, courseWorkId, id, content)
          .set("updateMask", "draftGrade,assignedGrade")
          .execute();

  /* Prints the updated student submission. */
  System.out.printf(
      "Updated student submission draft grade (%s) and assigned grade (%s).\n",
      studentSubmission.getDraftGrade(), studentSubmission.getAssignedGrade());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s), courseWorkId (%s), or studentSubmissionId (%s) does "
            + "not exist.\n",
        courseId, courseWorkId, id);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmission;

Python

studentSubmission = {
  'assignedGrade': 99,
  'draftGrade': 80
}
service.courses().courseWork().studentSubmissions().patch(
    courseId=<course ID or alias>,
    courseWorkId=<courseWork ID>,
    id=<studentSubmission ID>,
    updateMask='assignedGrade,draftGrade',
    body=studentSubmission).execute()

Quando utilizzano l'interfaccia utente di Classroom, gli insegnanti non possono assegnare un voto finché non aver salvato un voto provvisorio. Il voto assegnato può quindi essere restituito studente. Le applicazioni devono emulare questo comportamento. La tua applicazione può valutare il compito di uno studente in uno dei due modi seguenti:

  • Assegna solo il valore draftGrade. È utile, ad esempio, per consentire all'insegnante manualmente i voti prima di finalizzarli. Gli studenti non possono visualizzare i voti provvisori.

  • Assegna sia il draftGrade sia assignedGrade per valutare completo un compito.

di Gemini Advanced.

Elencare i voti assegnati

Puoi elencare tutti i voti di un particolare elemento delle attività del corso esplorando la Oggetto risposta del metodo courses.courseWork.studentSubmissions.list:

Java

classroom/snippets/src/main/java/ListStudentSubmissions.java
  ListStudentSubmissionsResponse response =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .list(courseId, courseWorkId)
          .setPageToken(pageToken)
          .execute();

  /* Ensure that the response is not null before retrieving data from it to avoid errors. */
  if (response.getStudentSubmissions() != null) {
    studentSubmissions.addAll(response.getStudentSubmissions());
    pageToken = response.getNextPageToken();
  }
} while (pageToken != null);

if (studentSubmissions.isEmpty()) {
  System.out.println("No student submissions found.");
} else {
  for (StudentSubmission submission : studentSubmissions) {
    System.out.printf(
        "User ID %s, Assigned grade: %s\n",
        submission.getUserId(), submission.getAssignedGrade());
  }
}

Python

response = coursework.studentSubmissions().list(
    courseId=course_id,
    courseWorkId=coursework_id,
    pageSize=10).execute()
submissions.extend(response.get('studentSubmissions', []))

if not submissions:
    print('No student submissions found.')

print('Student Submissions:')
for submission in submissions:
    print(f"Submitted at:"
          f"{(submission.get('userId'), submission.get('assignedGrade'))}")