Quản lý Bài tập

Ứng dụng Lớp học hỗ trợ 3 loại mục trong luồng: CourseWork, CourseWorkMaterialsAnnouncements. Hướng dẫn này mô tả cách quản lý CourseWork, nhưng các API cho tất cả các mục phát trực tuyến đều tương tự nhau. Hãy xem Tài nguyên API để tìm hiểu thêm về các loại mục trong luồng và sự khác biệt giữa các loại mục đó.

Tài nguyên CourseWork đại diện cho một bài tập đã được giao cho học viên trong một khoá học cụ thể, bao gồm mọi tài liệu và thông tin chi tiết bổ sung, chẳng hạn như ngày đến hạn hoặc điểm số tối đa. Có 4 loại phụ của CourseWork: bài tập, bài tập kiểm tra, câu hỏi ngắncâu hỏi trắc nghiệm. API Lớp học hỗ trợ ba loại phụ trong số này: bài tập, câu hỏi có câu trả lời ngắn và câu hỏi trắc nghiệm. Các loại này được biểu thị bằng trường CourseWork.workType.

Ngoài tài nguyên CourseWork, bạn có thể quản lý công việc đã hoàn thành bằng tài nguyên StudentSubmission.

Tạo bài tập

Bạn chỉ có thể tạo CourseWork thay mặt cho giáo viên của khoá học. Việc cố gắng tạo CourseWork thay mặt cho học viên hoặc quản trị viên miền không phải là giáo viên trong khoá học sẽ dẫn đến lỗi PERMISSION_DENIED. Hãy xem bài viết Các loại người dùng để tìm hiểu thêm về các vai trò khác nhau trong Lớp học.

Khi tạo CourseWork bằng phương thức courses.courseWork.create, bạn có thể đính kèm đường liên kết dưới dạng materials, như trong mã mẫu bên dưới:

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)

Các trường titleworkType là bắt buộc. Tất cả các trường khác là không bắt buộc. Nếu bạn không chỉ định state, CourseWork sẽ được tạo ở trạng thái bản nháp.

Sử dụng Tài nguyên liên kết với mục tiêu url được chỉ định để đưa tài liệu được liên kết vào CourseWork. Lớp học tự động tìm nạp title và URL hình thu nhỏ (thumbnailUrl). API Lớp học cũng hỗ trợ nội dung trên Google Drive và YouTube theo cách tương tự, có thể được đưa vào tài nguyên DriveFile hoặc tài nguyên YouTubeVideo.

Để chỉ định ngày đến hạn, hãy đặt các trường dueDatedueTime thành giờ UTC tương ứng. Ngày đến hạn phải là ngày trong tương lai.

Phản hồi CourseWork bao gồm một giá trị nhận dạng do máy chủ chỉ định có thể được dùng để tham chiếu việc chỉ định trong các yêu cầu API khác.

Truy xuất Bài tập

Bạn có thể thay mặt học viên và giáo viên của khoá học tương ứng truy xuất CourseWork. Bạn cũng có thể thay mặt quản trị viên miền truy xuất CourseWork, ngay cả khi họ không phải là giáo viên trong khoá học. Để truy xuất một CourseWork cụ thể, hãy sử dụng courses.courseWork.get. Để truy xuất tất cả CourseWork (không bắt buộc phải khớp với một số tiêu chí), hãy sử dụng courses.courseWork.list.

Phạm vi bắt buộc phụ thuộc vào vai trò của người dùng yêu cầu trong khoá học. Nếu người dùng là học viên, hãy sử dụng một trong các phạm vi sau:

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

Nếu người dùng là giáo viên hoặc quản trị viên miền, hãy sử dụng một trong các phạm vi sau:

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

Việc có quyền truy xuất CourseWork không đồng nghĩa với việc có quyền truy cập vào tài liệu hoặc siêu dữ liệu của tài liệu. Trong thực tế, điều này có nghĩa là quản trị viên có thể không thấy tiêu đề của tệp Drive đính kèm nếu họ không phải là thành viên của khoá học.

Quản lý câu trả lời của học viên

Tài nguyên StudentSubmission đại diện cho bài tập mà học viên đã làm cho một CourseWork. Tài nguyên này bao gồm siêu dữ liệu liên quan đến bài tập, chẳng hạn như trạng thái bài tập và điểm. StudentSubmission được tạo ngầm cho mỗi học viên khi tạo một CourseWork mới.

Các phần sau đây giải thích các thao tác phổ biến để quản lý câu trả lời của học viên.

Truy xuất câu trả lời của học viên

Học viên có thể truy xuất bài nộp của riêng mình, giáo viên có thể truy xuất bài nộp của tất cả học viên trong khoá học và quản trị viên miền có thể truy xuất tất cả bài nộp của tất cả học viên trong miền của họ. Mỗi StudentSubmission được chỉ định một giá trị nhận dạng. Nếu bạn biết giá trị nhận dạng, hãy sử dụng courses.courseWork.studentSubmissions.get để truy xuất nội dung đã gửi.

Sử dụng phương thức courses.courseWork.studentSubmissions.list để lấy tất cả tài nguyên StudentSubmission khớp với một số tiêu chí, như trong mẫu sau:

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)

Truy xuất các tài nguyên StudentSubmission thuộc về một học viên cụ thể bằng cách chỉ định tham số userId, như trong mẫu sau:

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

Học viên được xác định bằng mã nhận dạng duy nhất hoặc địa chỉ email, như được thể hiện trong tài nguyên Student. Người dùng hiện tại cũng có thể tham chiếu đến mã nhận dạng của riêng họ bằng cách sử dụng ký hiệu viết tắt "me".

Bạn cũng có thể truy xuất bài tập mà học viên đã nộp cho tất cả bài tập trong một khoá học. Để thực hiện việc này, hãy sử dụng giá trị cố định "-" làm courseWorkId, như trong mẫu sau:

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

Phạm vi bắt buộc phụ thuộc vào vai trò của người dùng yêu cầu trong khoá học. Nếu người dùng là giáo viên hoặc quản trị viên miền, hãy sử dụng phạm vi sau:

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

Nếu người dùng là học viên, hãy sử dụng phạm vi sau:

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

Việc có quyền truy xuất StudentSubmission không đồng nghĩa với việc có quyền truy cập vào tệp đính kèm hoặc siêu dữ liệu của tệp đính kèm. Trong thực tế, điều này có nghĩa là quản trị viên có thể không thấy tiêu đề của tệp Drive đính kèm nếu họ không phải là thành viên của khoá học.

Thêm tệp đính kèm vào câu trả lời của học viên

Bạn có thể đính kèm đường liên kết đến bài nộp của học viên bằng cách đính kèm tài nguyên Link, DriveFile hoặc YouTubeVideo. Bạn có thể thực hiện việc này bằng courses.courseWork.studentSubmissions.modifyAttachments, như trong mẫu sau:

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

Tệp đính kèm Link được xác định bởi url mục tiêu; Lớp học sẽ tự động tìm nạp title và hình thu nhỏ (thumbnailUrl). Hãy xem Material để tìm hiểu về những tài liệu có thể đính kèm vào StudentSubmissions.

Chỉ giáo viên của khoá học hoặc học viên sở hữu khoá học mới có thể sửa đổi StudentSubmission. Bạn chỉ có thể đính kèm Materials nếu CourseWorkType của StudentSubmissionASSIGNMENT.

Phạm vi bắt buộc phụ thuộc vào vai trò của người dùng yêu cầu trong khoá học. Nếu người dùng là giáo viên, hãy sử dụng phạm vi sau:

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

Nếu người dùng là học viên, hãy sử dụng phạm vi sau:

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