課題と成績の管理

Classroom UI は 5 つの5種類の授業、課題、 テスト付きの課題、記述式問題、多肢選択式の問題、 資料、Classroom API は現在、次の 3 つのタイプをサポートしています。 API では CourseWorkType と呼ばれます: アサインメント、記述式 多肢選択式の問題もあります

この機能にアクセスするには、 CourseWork リソース これは、生徒に割り当てられた課題または問題を表します。 追加教材や詳細を含む、特定のコースに関する 日付または最高スコアを指定します

CourseWork リソースに加えて、完了した課題も管理できます。 StudentSubmission リソースに置き換えます。以降のセクションでは、 詳しく説明します。

課題を作成する

課題は、コースの教師および教師の代理としてのみ作成できます。 生徒に代わってコースの課題を作成しようとすると、 403 PERMISSION_DENIED エラーが返されます。同様に、ドメイン管理者は API を使用して指導していないコースの課題や実施を試みている 403 PERMISSION_DENIED エラーも発生します。

courses.courseWork.create メソッドを使用して割り当てを作成する場合、次の操作を行います。 次のサンプルコードに示すように、リンクを materials として添付できます。

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)

結果には、サーバーによって割り当てられた識別子が含まれます。この識別子を使用して、 他の API リクエストでの割り当ての 再割り当ては行われません

Classroom API で作成した課題にリンク付きの資料を含めるには、次の操作を行います。 Link リソースを使用します。 指定します。タイトルとサムネイル画像が自動的に取得されます。 Classroom API は Google ドライブと YouTube の教材もネイティブにサポートしているため、 DriveFile リソースに含まれる 類似のリソースの YouTubeVideo リソース できます。

期限を指定するには、dueDate フィールドと dueTime フィールドを期限に設定します。 UTC 時間です。期限には将来の日付を指定してください。

課題と質問を取得する

教育機関の生徒と教師の課題や質問を取得できます。 ドメイン管理者に確認してください特定のデータセットを取得するには、 使用する場合は、courses.courseWork.get を使用します。すべての (必要に応じて一部の条件に一致するもの)、 courses.courseWork.list.

必要なスコープは、リクエスト元のユーザーが持っているロール 説明しますユーザーが学生の場合は、次のいずれかのスコープを使用します。

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

ユーザーが教師またはドメイン管理者である場合は、次のいずれかを使用します。 スコープ:

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

課題または問題を取得する権限があることは、 アクセス権限を設定できます。これは実際には ドライブ ファイルのタイトルが表示されないことを コースのメンバーではなくても大丈夫です。管理者にアクセスを許可する場合は、 詳しくは、ドメイン全体の 委任 ご覧ください

生徒の解答を管理する

StudentSubmission resource は、課題に対する生徒の提出物と成績を表します。 質問にお答えします。StudentSubmission 新しい質問や質問が投稿されると、各生徒に対してリソースが暗黙的に作成されます。 割り当てが作成されます。

以降のセクションでは、生徒の解答を管理する一般的な操作について説明します。

生徒の回答を取得する

生徒は自分の提出物を取得でき、教師は提出物を取得できる できます。ドメイン管理者はすべての生徒について 課題を提出できるようになります。生徒の提出物ごとに 識別子を割り当てID がわかっている場合は、 courses.courseWork.studentSubmissions.get を使用してこれを取得します。

courses.courseWork.studentSubmissions.list メソッドを使用して取得します。 次の条件に一致する StudentSubmission リソース: 次のサンプルをご覧ください。

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)

特定の生徒に属する StudentSubmission リソースを次の方法で取得する userId パラメータを指定する。次のサンプルをご覧ください。

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

生徒は、次のように、ユーザーの一意の ID またはメールアドレスで識別されます。 Google Admin SDK から返されます。現在のユーザーは自分の "me" 省略形を使用して ID を作成します。

また、組織内のすべての課題について、 説明しますそのためには、以下に示すように、リテラル "-"courseWorkId として使用します。 次のサンプルをご覧ください。

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

必要なスコープは、リクエスト元のユーザーが持っているロール 説明しますユーザーが教師またはドメインである場合は、次のスコープを使用します 管理者:

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

ユーザーが生徒の場合は、次のスコープを使用します。

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

生徒の提出物を取得する権限があることは、 アクセス権を付与する必要があります。実際には、 ドライブ ファイルのタイトルを管理者が確認できない コースのメンバーではありません管理者にアクセスを許可するには、 詳細については、 ドメイン全体の委任に関するガイドをご覧ください。

生徒の解答に添付ファイルを追加する

生徒の提出物にリンクを添付するには、LinkDriveFile または YouTubeVideo リソース。これには、 courses.courseWork.studentSubmissions.modifyAttachments: 次のサンプルをご覧ください。

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

リンクの添付ファイルは、ターゲット URL で定義されます。Classroom は自動的に タイトルとサムネイル画像を取得しますその他の資料については それぞれのリファレンスページをご覧ください。

StudentSubmission を変更できるのは、コースの教師または 持つ生徒です。Materials を追加できるのは、 生徒の提出物の CourseWorkTypeASSIGNMENT です。

必要なスコープは、リクエスト元のユーザーが持っているロール 説明しますユーザーが教師の場合は、次のスコープを使用します。

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

ユーザーが生徒の場合は、次のスコープを使用します。

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

生徒の回答ステータスを管理する

生徒の解答は、提出を取り消したり、提出したり、返却したりできます。state フィールド StudentSubmission の現在の状態を示します。状態を変更するには、 次のいずれかの方法を使用できます。

これらのメソッドはすべて空の本文を取ります。例:

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

StudentSubmission を所有している生徒のみが、課題を提出または再利用できます。 再申請できるのは、提出された提出物のみです。コースの教師は、 提出済みの状態の StudentSubmission

生徒の回答を採点する

StudentSubmission リソースには、成績を保存するための 2 つのフィールドがあります。 assignedGrade(生徒に報告された成績)とdraftGrade、 教師のみに表示される仮成績です。これらのフィールドは フィールド マスクで courses.courseWork.studentSubmissions.patch を使用する 次のサンプルに示すとおり、適切なフィールドが格納されています。

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

Classroom の UI を使用する場合、教師が Classroom の UI を操作するまでは、成績を割り当てることができません。 仮成績を保存したことがある場合はその後、出題された成績を 説明します。アプリはこの動作をエミュレートする必要があります。アプリケーションで 次の 2 つの方法のいずれかで生徒の課題を採点できます。

  • draftGrade のみを割り当てます。これは、たとえば、教師が Google Meet を使用して 成績を手動で確認する。生徒は仮成績を表示できません。

  • 課題を完全に採点するには、draftGradeassignedGrade の両方を割り当てます。

で確認できます。

割り当てられた成績を一覧表示する

特定の学習項目のすべての成績を一覧表示するには、 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'))}")