수업 과제 및 성적 관리

클래스룸 UI는 과제, 퀴즈 과제, 단답형 질문, 객관식 질문 자료. Classroom API는 현재 다음 세 가지 유형을 지원합니다. API: 과제 도구, 단답형의 CourseWorkType입니다. 객관식 문제입니다.

이 기능에 액세스하려면 CourseWork 리소스, 이는 모든 추가 자료 및 세부정보(예: 마감일 미정)를 포함하여 지정할 수 있습니다.

CourseWork 리소스 외에도 완료된 과제를 관리할 수 있습니다. StudentSubmission 리소스를 사용합니다. 다음 섹션에서는 이러한 사항을 설명합니다. 더 자세히 살펴보겠습니다

과제 만들기

과제는 강의의 교사를 대신 만들 수 있습니다. 학생을 대신하여 강의에서 과제를 만들려고 하면 403 PERMISSION_DENIED 오류 발생 마찬가지로 도메인 관리자는 자신이 가르치지 않는 강의에 대한 과제 및 API를 통해 그러한 작업을 수행하려는 경우 403 PERMISSION_DENIED 오류도 발생합니다.

courses.courseWork.create 메서드를 사용하여 할당을 만들 때는 아래 샘플 코드와 같이 링크를 materials로 첨부할 수 있습니다.

자바

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를 통해 만든 과제에 연결된 자료를 포함하려면 다음 단계를 따르세요. 링크 리소스를 사용하여 타겟 URL입니다. 클래스룸에서 제목과 썸네일 이미지를 자동으로 가져옵니다. Classroom API는 기본적으로 Google Drive와 YouTube 자료를 지원하므로 DriveFile 리소스에 포함된 파일 YouTubeVideo resource를 유사한 있습니다.

마감일을 지정하려면 dueDatedueTime 입력란을 해당 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 리소스는 과제에 대한 학생의 과제물과 성적을 나타냅니다. 있습니다. StudentSubmission 새로운 질문이나 질문이 생기면 각 학생에게 암시적으로 확인할 수 있습니다.

다음 섹션에서는 학생의 응답을 관리하는 일반적인 작업을 설명합니다.

학생 응답 검색

학생은 자신이 제출한 과제를, 교사는 제출물을 가져올 수 있습니다. 액세스할 수 있으며 도메인 관리자는 제출할 수 있습니다. 각 학생이 제출한 과제는 식별자가 할당되고 식별자를 알고 있는 경우 courses.courseWork.studentSubmissions.get를 클릭하여 가져옵니다.

courses.courseWork.studentSubmissions.list 메서드를 사용하여 일부 기준과 일치하는 StudentSubmission 리소스. 다음 샘플을 참조하세요.

자바

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 매개변수를 지정합니다.

자바

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 다음 샘플을 참조하세요.

자바

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

학생 제출물을 검색할 수 있는 권한이 있다고 해서 이는 첨부파일 또는 첨부파일 메타데이터에 대한 액세스 권한 실제로 이것은 관리자가 첨부된 드라이브 파일의 제목을 볼 수 없는 경우 과정의 구성원이 아닙니다 관리자 액세스 권한을 부여하려는 경우 사용자 파일에 대한 자세한 내용은 도메인 전체 위임 가이드를 참조하세요.

학생 응답에 첨부파일 추가하기

Link을 첨부하여 학생 제출물에 링크를 첨부할 수 있습니다. DriveFile 또는 YouTubeVideo 리소스입니다. 이 작업은 courses.courseWork.studentSubmissions.modifyAttachments 다음 샘플을 참조하세요.

자바

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에 의해 정의됩니다. 클래스룸은 자동으로 제목과 썸네일 이미지를 가져옵니다. 다른 자료에 대해서는 해당 참조 페이지에 표시됩니다.

StudentSubmission는 교사 또는 다음 사용자만 수정할 수 있습니다. 소유권을 주장할 수 있습니다. 다음 경우에만 Materials를 연결할 수 있습니다. 학생 제출물의 CourseWorkTypeASSIGNMENT입니다.

필요한 범위는 요청하는 사용자가 오신 것을 환영합니다 사용자가 교사인 경우 다음 범위를 사용하세요.

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

사용자가 학생인 경우 다음 범위를 사용하세요.

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

학생 응답 상태 관리

학생 응답은 제출 취소, 제출 또는 반환될 수 있습니다. 상태 필드 StudentSubmission는 현재 상태를 나타냅니다. 상태를 변경하려면 다음 방법 중 하나를 사용합니다.

이러한 메서드는 모두 빈 본문을 사용합니다. 예:

자바

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 리소스에는 성적을 저장하는 두 개의 필드가 있습니다. 학생에게 보고된 성적인 assignedGradedraftGrade 교사에게만 표시되는 임시 성적입니다. 필드가 업데이트됨 필드 마스크와 함께 courses.courseWork.studentSubmissions.patch 사용 적절한 필드를 포함해야 합니다.

자바

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

클래스룸 UI를 사용하는 경우 교사가 성적을 매기려면 임시 성적이 먼저 저장되었습니다. 그러면 할당된 성적을 다음 학생에게 돌려줄 수 있습니다. 학생입니다. 애플리케이션은 이 동작을 에뮬레이션해야 합니다. 애플리케이션은 다음 두 가지 방법 중 하나로 학생의 과제를 채점합니다.

  • draftGrade만 할당합니다. 예를 들어 교사가 학생들에게 채점하기 전에 수동으로 성적을 검토할 수 있습니다 학생은 임시 성적을 볼 수 없습니다.

  • 과제를 완전히 채점하려면 draftGradeassignedGrade을 모두 할당합니다.

할당된 성적 나열

특정 수업 과제 항목의 모든 성적을 표시하려면 courses.courseWork.studentSubmissions.list 메서드의 응답 객체:

자바

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