Zarządzanie zadaniami i ocenami

Interfejs Classroom obsługuje 5 typów zadań: Projekty, projekty testów, pytania z krótką odpowiedzią, pytania jednokrotnego wyboru; Materiały. Interfejs Classroom API obsługuje obecnie 3 z tych typów, są określane jako CourseWorkType w przypadku interfejsu API: Projekty, Krótka odpowiedź i pytania jednokrotnego wyboru.

Aby uzyskać dostęp do tej funkcji, możesz użyć zasób CourseWork, które reprezentują zadanie lub pytanie przypisane uczniom danego szkolenia, w tym wszelkie dodatkowe materiały i szczegóły, takie jak termin datę lub maksymalną liczbę punktów.

Oprócz zasobu CourseWork możesz zarządzać ukończonymi projektami z zasobem StudentSubmission. W sekcjach poniżej .

Tworzenie projektów

Projekty można tworzyć wyłącznie w imieniu nauczycieli. próba utworzenia projektów na zajęciach w imieniu ucznia spowoduje w błędzie 403 PERMISSION_DENIED. Podobnie administratorzy domeny nie mogą tworzyć projektów na zajęcia, których nie uczą i próby wykonania za pomocą interfejsu API; spowoduje również błąd 403 PERMISSION_DENIED.

Tworząc projekty za pomocą metody courses.courseWork.create, może dołączać linki jako element materials widoczny w przykładowym kodzie poniżej:

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)

Wynik zawiera identyfikator przypisany przez serwer, którego można użyć do odwoływania się w innych żądaniach do interfejsu API.

Aby uwzględnić połączone materiały w projekcie utworzonym przy użyciu interfejsu Classroom API: użyj zasobu linku, który określa docelowy URL. Classroom automatycznie pobierze tytuł i obraz miniatury. Interfejs Classroom API natywnie obsługuje też Dysk Google i materiały YouTube, które mogą dołączane do zasobu DriveFile lub zasobu wideo w YouTube o podobnym sposób.

Aby określić termin, w polach dueDate i dueTime ustaw wartość odpowiadającego czasowi UTC. Termin musi przypadać w przyszłości.

Pobieranie projektów i pytań

Możesz pobierać projekty i pytania dla uczniów i nauczycieli w na odpowiednich zajęciach lub przez administratora domeny. Aby pobrać określoną projektu lub pytania, skorzystaj z kursów.courseWork.get. Aby pobrać wszystkie projektów lub pytań (opcjonalnie spełniających niektóre kryteria), użyj courses.courseWork.list.

Wymagany zakres zależy od roli, jaką użytkownik wysyłający prośbę ma w Google Cloud. Jeśli użytkownik jest uczniem, użyj jednego z tych zakresów:

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

Jeśli użytkownik jest nauczycielem lub administratorem domeny, użyj jednej z tych metod: zakresy:

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

Posiadanie uprawnień do pobierania projektu lub pytania nie oznacza, pozwolenia na dostęp do materiałów lub ich metadanych. W praktyce oznacza to, administrator może nie zobaczyć tytułu dołączonego pliku z Dysku, jeśli nie jest członkiem zajęć. Jeśli chcesz zezwolić administratorom na dostęp do konta użytkownika plików, patrz sekcja dla całej domeny przekazanie dostępu Google.

Zarządzanie odpowiedziami uczniów

StudentSubmission reprezentuje pracę ucznia i ocenę ucznia za projekt lub pytanie. StudentSubmission jest niejawnie tworzony dla każdego ucznia, gdy nowe pytanie lub projekt został utworzony.

W sekcjach poniżej znajdziesz omówienie typowych działań związanych z zarządzaniem odpowiedziami uczniów.

Pobieranie odpowiedzi uczniów

Uczniowie mogą pobierać własne zadania, a nauczyciele – pobierać zadania dla wszystkich uczestników zajęć, a administratorzy domeny mogą pobrać przesłanych przez wszystkich uczniów w domenie. Zadanie przesłane przez ucznia przypisać identyfikator; jeśli znasz identyfikator, użyj courses.courseWork.studentSubmissions.get, aby go pobrać.

Użyj metody courses.courseWork.studentSubmissions.list, aby uzyskać StudentSubmission zasobów, które spełniają określone kryteria, jak pokazano w ten przykład:

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)

Pobieranie zasobów StudentSubmission należących do określonego ucznia przez określając parametr userId, jak w tym przykładzie:

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")

Uczniowie są identyfikowani po unikalnym identyfikatorze lub adresie e-mail użytkownika, zwracane przez pakiet SDK Google Admin. Bieżący użytkownik może również odnieść się do własnej Identyfikator utworzony za pomocą skrótu "me".

Można również pobierać projekty przesłane przez uczniów do wszystkich projektów w Google Cloud. Aby to zrobić, użyj literału "-" jako elementu courseWorkId, jak pokazano na ekranie ten przykład:

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()

Wymagany zakres zależy od roli, jaką użytkownik wysyłający prośbę ma w Google Cloud. Jeśli użytkownik jest nauczycielem lub domeną, użyj tego zakresu administrator:

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

Jeśli użytkownik jest uczniem, użyj tego zakresu:

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

Posiadanie uprawnień do pobierania zadań przesłanych przez ucznia nie oznacza, uprawnień dostępu do załączników lub metadanych załączników. W praktyce oznacza, że administrator może nie zobaczyć tytułu dołączonego pliku z Dysku, jeśli ale nie są oni w tych zajęciach. Jeśli chcesz zezwolić administratorom na dostęp plików użytkowników, patrz Przewodnika przekazywania dostępu w całej domenie.

Dodawanie załączników do odpowiedzi uczniów

Możesz załączyć linki do zadań przesłanych przez ucznia, dołączając Link, DriveFile lub YouTubeVideo zasób. Odbywa się to za pomocą courses.courseWork.studentSubmissions.modifyAttachments, jak widać w tabeli ten przykład:

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")

Załącznik linku jest definiowany przez docelowy adres URL. Classroom będzie automatycznie pobrać tytuł i obraz miniatury. Pozostałe materiały znajdziesz na stronie odpowiednie strony referencyjne.

StudentSubmission może zmodyfikować tylko nauczyciel lub do ucznia. Materials możesz załączyć tylko wtedy, gdy CourseWorkType zadania przesłane przez ucznia wynosi ASSIGNMENT.

Wymagany zakres zależy od roli, jaką użytkownik wysyłający prośbę ma w Google Cloud. Jeśli użytkownik jest nauczycielem, użyj tego zakresu:

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

Jeśli użytkownik jest uczniem, użyj tego zakresu:

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

Zarządzanie stanem odpowiedzi ucznia

Odpowiedź ucznia może zostać wycofana, oddana lub zwrócona. Pole stanu w polu StudentSubmission wskazuje obecny stan. Aby zmienić stan, wywołaj jedną z tych metod:

Wszystkie te metody przyjmują puste treści. Przykład:

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()

Tylko uczeń, który jest właścicielem elementu StudentSubmission, może go oddać lub odzyskać. Można odzyskać tylko oddane zadania. Nauczyciele mogą zwrócić tylko StudentSubmission oddanych.

Ocenianie odpowiedzi uczniów

Zasób StudentSubmission ma 2 pola do przechowywania ocen: assignedGrade, czyli ocena przekazywana uczniom, i draftGrade, czyli wstępna ocena widoczna tylko dla nauczycieli. Te pola zostały zaktualizowane przy użyciu courses.courseWork.studentSubmissions.patch z maską pola zawierających odpowiednie pola, jak pokazano w poniższym przykładzie.

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()

Podczas pracy z interfejsem Classroom nauczyciele nie mogą wystawiać ocen, dopóki nie mają najpierw zapisane oceny robocze. Przypisana ocena może zostać zwrócona uczniami. Aplikacje muszą emulować to zachowanie. Twoja aplikacja może ocenić projekt ucznia na jeden z dwóch sposobów:

  • Przypisz tylko draftGrade. Przydaje się to na przykład, pozwalając nauczycielowi ręcznie sprawdzać oceny przed ich sfinalizowaniem. Uczniowie nie widzą ocen roboczych.

  • Aby w pełni ocenić projekt, przypisz zadania draftGrade i assignedGrade.

Wyświetl listę przypisanych ocen

Aby wyświetlić listę wszystkich ocen za dany element kursu, zapoznaj się z Obiekt odpowiedzi metody 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'))}")