开始使用评分准则

rubric 是教师在对学生的提交内容进行评分时可以使用的模板。借助 Classroom API,您可以代表教师管理这些评分准则。

Google 课堂界面中的评分准则视图 图 1. 查看 Google 课堂作业中的评分准则示例。

本指南介绍了 Rubrics API 的基本概念和功能。请参阅这些帮助中心文章,了解评分准则的一般结构,以及如何在 Google 课堂界面中按照评分准则进行评分

前提条件

本指南假定您满足以下条件:

为桌面应用授权凭据

如需以最终用户身份进行身份验证并在您的应用中访问用户数据,您需要创建一个或多个 OAuth 2.0 客户端 ID。客户端 ID 用于向 Google 的 OAuth 服务器标识单个应用。如果您的应用在多个平台上运行,则必须为每个平台创建一个单独的客户端 ID。

  1. 前往 Google Cloud 控制台中的 GCP “凭据”页面
  2. 依次点击创建凭据 > OAuth 客户端 ID
  3. 点击应用类型 > 桌面应用
  4. 名称字段中,输入凭据的名称。此名称仅在 Google Cloud 控制台中显示。例如,“评分准则预览客户端”。
  5. 点击创建。系统会显示 OAuth 客户端已创建的屏幕,其中显示了您的新客户端 ID 和客户端密钥。
  6. 点击下载 JSON,然后点击确定。新创建的凭据会显示在 OAuth 2.0 客户端 ID 下方。
  7. 将下载的 JSON 文件另存为 credentials.json,然后将该文件移动到工作目录。
  8. 点击创建凭据 > API 密钥,并记下 API 密钥。

如需了解详情,请参阅创建访问凭据

配置 OAuth 范围

根据项目的现有 OAuth 范围,您可能需要配置额外的范围。

  1. 前往 OAuth 同意屏幕
  2. 依次点击 Edit App > Save and Continue,进入“Scopes”屏幕。
  3. 点击添加或移除范围
  4. 添加以下范围(如果您还没有这些范围):
    • https://www.googleapis.com/auth/classroom.coursework.students
    • https://www.googleapis.com/auth/classroom.courses
  5. 然后,依次点击更新 > 保存并继续 > 保存并继续 > 返回信息中心

如需了解详情,请参阅配置 OAuth 权限请求页面

classroom.coursework.students 作用域允许对评分准则进行读写访问(以及对 CourseWork 的访问权限),而 classroom.courses 作用域允许读取和写入课程。

如需了解指定方法所需的范围,请参阅该方法的参考文档。如需查看示例,请参阅 courses.courseWork.rubrics.create 授权范围。您可以在适用于 Google API 的 OAuth 2.0 范围中查看所有 Google 课堂范围。由于此 API 仍处于预览版阶段,因此此处未提及评分准则。

配置示例

在您的工作目录中,安装适用于 Python 的 Google 客户端库:

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

创建一个名为 main.py 的文件,用于构建客户端库并使用您的 API 密钥(代替 YOUR_API_KEY)向用户授权:

import json
import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/classroom.courses',
          'https://www.googleapis.com/auth/classroom.coursework.students']

def build_authenticated_service(api_key):
    """Builds the Classroom service."""
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run.
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    try:
        # Build the Classroom service.
        service = build(
            serviceName="classroom",
            version="v1",
            credentials=creds,
            discoveryServiceUrl=f"https://classroom.googleapis.com/$discovery/rest?labels=DEVELOPER_PREVIEW&key={api_key}")

        return service

    except HttpError as error:
        print('An error occurred: %s' % error)

if __name__ == '__main__':
    service = build_authenticated_service(YOUR_API_KEY)

使用 python main.py 运行脚本。系统会提示您登录并同意 OAuth 范围。

创建作业

评分准则与作业(即 CourseWork)相关联,并且仅在该 CourseWork 上下文中有意义。评分准则只能由创建父级 CourseWork 项的 Google Cloud 项目创建。在本指南中,请使用脚本创建新的 CourseWork 赋值。

将以下内容添加到 main.py 中:

def get_latest_course(service):
    """Retrieves the last created course."""
    try:
        response = service.courses().list(pageSize=1).execute()
        courses = response.get("courses", [])
        if not courses:
            print("No courses found. Did you remember to create one in the UI?")
            return
        course = courses[0]
        return course

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

def create_coursework(service, course_id):
    """Creates and returns a sample coursework."""
    try:
        coursework = {
            "title": "Romeo and Juliet analysis.",
            "description": """Write a paper arguing that Romeo and Juliet were
                                time travelers from the future.""",
            "workType": "ASSIGNMENT",
            "state": "PUBLISHED",
        }
        coursework = service.courses().courseWork().create(
            courseId=course_id, body=coursework).execute()
        return coursework

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

现在,更新 main.py 以检索您刚刚创建的测试类的 course_id,然后创建新的示例分配,并检索该作业的 coursework_id

if __name__ == '__main__':
    service = build_authenticated_service(YOUR_API_KEY)

    course = get_latest_course(service)
    course_id = course.get("id")
    course_name = course.get("name")
    print(f"'{course_name}' course ID: {course_id}")

    coursework = create_coursework(service, course_id)
    coursework_id = coursework.get("id")
    print(f"Assignment created with ID {coursework_id}")

    #TODO(developer): Save the printed course and coursework IDs.

保存 course_idcoursework_id。所有评分准则 CRUD 操作都需要这些过滤器。

现在,您在 Google 课堂中应该已经有一个 CourseWork 样例了。

在 Google 课堂界面中查看作业 图 2. Google 课堂中的示例作业视图。

创建评分准则

现在,您可以开始管理评分准则了。

您可以通过包含完整评分准则对象的 Create 调用在 CourseWork 上创建评分准则,其中省略了条件和级别的 ID 属性(这些属性在创建时生成)。

将以下函数添加到 main.py

def create_rubric(service, course_id, coursework_id):
    """Creates an example rubric on a coursework."""
    try:
        body = {
            "criteria": [
                {
                    "title": "Argument",
                    "description": "How well structured your argument is.",
                    "levels": [
                        {"title": "Convincing",
                         "description": "A compelling case is made.", "points": 30},
                        {"title": "Passable",
                         "description": "Missing some evidence.", "points": 20},
                        {"title": "Needs Work",
                         "description": "Not enough strong evidence..", "points": 0},
                    ]
                },
                {
                    "title": "Spelling",
                    "description": "How well you spelled all the words.",
                    "levels": [
                        {"title": "Perfect",
                         "description": "No mistakes.", "points": 20},
                        {"title": "Great",
                         "description": "A mistake or two.", "points": 15},
                        {"title": "Needs Work",
                         "description": "Many mistakes.", "points": 5},
                    ]
                },
                {
                    "title": "Grammar",
                    "description": "How grammatically correct your sentences are.",
                    "levels": [
                        {"title": "Perfect",
                         "description": "No mistakes.", "points": 20},
                        {"title": "Great",
                         "description": "A mistake or two.", "points": 15},
                        {"title": "Needs Work",
                         "description": "Many mistakes.", "points": 5},
                    ]
                },
            ]
        }

        rubric = service.courses().courseWork().rubrics().create(
            courseId=course_id, courseWorkId=coursework_id, body=body,
            # Specify the preview version. Rubrics CRUD capabilities are
            # supported in V1_20231110_PREVIEW and later.
            previewVersion="V1_20231110_PREVIEW"
            ).execute()
        print(f"Rubric created with ID {rubric.get('id')}")
        return rubric

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

然后,使用之前的 CourseCourseWork ID 更新并运行 main.py 以创建评分准则示例:

if __name__ == '__main__':
    service = build_authenticated_service(YOUR_API_KEY)

    rubric = create_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
    print(json.dumps(rubric, indent=4))

关于评分准则表示法的一些要点:

  • 条件和等级顺序会反映在 Google 课堂界面中。
  • 评分级别(具有 points 属性的评分级别)必须按点以升序或降序排序(不能随机排序)。
  • 教师可以在界面中对评分标准和评分等级(而非未计分等级)重新排序,这将会改变他们在数据中的顺序。

如需详细了解评分准则的结构,请参阅限制

返回界面后,您应该会看到作业上的评分准则。

Google 课堂界面中的评分准则视图 图 3. 查看 Google 课堂作业中的评分准则示例。

阅读评分准则

您可以使用标准的 ListGet 方法读取评分准则。

一个作业中最多只能有一个评分准则,因此 List 可能不太直观,但如果您还没有评分准则 ID,这样做会很有帮助。如果没有与 CourseWork 相关联的评分准则,则 List 响应为空。

将以下函数添加到 main.py

def get_rubric(service, course_id, coursework_id):
    """
    Get the rubric on a coursework. There can only be at most one.
    Returns null if there is no rubric.
    """
    try:
        response = service.courses().courseWork().rubrics().list(
            courseId=course_id, courseWorkId=coursework_id,
            # Specify the preview version. Rubrics CRUD capabilities are
            # supported in V1_20231110_PREVIEW and later.
            previewVersion="V1_20231110_PREVIEW"
            ).execute()

        rubrics = response.get("rubrics", [])
        if not rubrics:
            print("No rubric found for this assignment.")
            return
        rubric = rubrics[0]
        return rubric

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

更新并运行 main.py 以获取您添加的评分准则:

if __name__ == '__main__':
    service = build_authenticated_service(YOUR_API_KEY)

    rubric = get_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
    print(json.dumps(rubric, indent=4))

    #TODO(developer): Save the printed rubric ID.

请记下评分准则中的 id 属性,以备后续步骤使用。

如果您有评分准则 ID,则 Get 可以正常运行。在函数中使用 Get 可能如下所示:

def get_rubric(service, course_id, coursework_id, rubric_id):
    """
    Get the rubric on a coursework. There can only be at most one.
    Returns a 404 if there is no rubric.
    """
    try:
        rubric = service.courses().courseWork().rubrics().get(
            courseId=course_id,
            courseWorkId=coursework_id,
            id=rubric_id,
            # Specify the preview version. Rubrics CRUD capabilities are
            # supported in V1_20231110_PREVIEW and later.
            previewVersion="V1_20231110_PREVIEW"
        ).execute()

        return rubric

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

如果没有评分准则,此实现会返回 404。

更新评分准则

更新评分准则是通过 Patch 调用完成的。由于评分准则的结构较为复杂,必须使用读取-修改-写入模式完成更新,在这种模式下,整个 criteria 属性会被替换。

更新规则如下:

  1. 添加而没有 ID 的条件或级别被视为添加。
  2. 之前缺少的条件或级别被视为“删除”
  3. 具有现有 ID 但数据被修改的条件或级别被视为“修改”。未修改的属性会保持不变。
  4. 新 ID 或未知 ID 提供的条件或级别被视为错误
  5. 新条件和级别的顺序会被视为新的界面顺序(存在上述限制)。

添加一个用于更新评分准则的函数:

def update_rubric(service, course_id, coursework_id, rubric_id, body):
    """
    Updates the rubric on a coursework.
    """
    try:
        rubric = service.courses().courseWork().rubrics().patch(
            courseId=course_id,
            courseWorkId=coursework_id,
            id=rubric_id,
            body=body,
            updateMask='criteria',
            # Specify the preview version. Rubrics CRUD capabilities are
            # supported in V1_20231110_PREVIEW and later.
            previewVersion="V1_20231110_PREVIEW"
        ).execute()

        return rubric

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

在此示例中,criteria 字段通过 updateMask 指定进行修改。

然后修改 main.py,对上述每条更新规则进行更改:

if __name__ == '__main__':
    service = build_authenticated_service(YOUR_API_KEY)

    # Get the latest rubric.
    rubric = get_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
    criteria = rubric.get("criteria")
    """
    The "criteria" property should look like this:
    [
        {
            "id": "NkEyMdMyMzM2Nxkw",
            "title": "Argument",
            "description": "How well structured your argument is.",
            "levels": [
                {
                    "id": "NkEyMdMyMzM2Nxkx",
                    "title": "Convincing",
                    "description": "A compelling case is made.",
                    "points": 30
                },
                {
                    "id": "NkEyMdMyMzM2Nxky",
                    "title": "Passable",
                    "description": "Missing some evidence.",
                    "points": 20
                },
                {
                    "id": "NkEyMdMyMzM2Nxkz",
                    "title": "Needs Work",
                    "description": "Not enough strong evidence..",
                    "points": 0
                }
            ]
        },
        {
            "id": "NkEyMdMyMzM2Nxk0",
            "title": "Spelling",
            "description": "How well you spelled all the words.",
            "levels": [...]
        },
        {
            "id": "NkEyMdMyMzM2Nxk4",
            "title": "Grammar",
            "description": "How grammatically correct your sentences are.",
            "levels": [...]
        }
    ]
    """

    # Make edits. This example will make one of each type of change.

    # Add a new level to the first criteria. Levels must remain sorted by
    # points.
    new_level = {
        "title": "Profound",
        "description": "Truly unique insight.",
        "points": 50
    }
    criteria[0]["levels"].insert(0, new_level)

    # Remove the last criteria.
    del criteria[-1]

    # Update the criteria titles with numeric prefixes.
    for index, criterion in enumerate(criteria):
        criterion["title"] = f"{index}: {criterion['title']}"

    # Resort the levels from descending to ascending points.
    for criterion in criteria:
        criterion["levels"].sort(key=lambda level: level["points"])

    # Update the rubric with a patch call.
    new_rubric = update_rubric(
        service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID, YOUR_RUBRIC_ID, rubric)

    print(json.dumps(new_rubric, indent=4))

现在,教师应该就能在 Google 课堂中看到这些更改了。

在 Google 课堂界面中查看更新后的评分准则 图 4. 更新后的评分准则的视图。

查看按评分准则评分的提交内容

目前,该 API 无法使用评分准则为学生提交的作业评分,但您可以在 Google 课堂界面中查看使用评分准则进行评分的提交作业的成绩。

以学生的身份在 Google 课堂界面中完成并上交示例作业。 然后,教师可以手动使用评分准则为作业评分

Google 课堂界面中的评分准则成绩 图 5. 教师在评分期间查看评分准则。

使用评分准则评分的学生提交内容有两个新属性:draftRubricGradesassignedRubricGrades,分别表示教师在草稿和已分配评分状态期间选择的分数和级别。

此外,即使学生提交的作业包含相关评分准则,它也会在评分前包含 rubricId 字段。该值表示与 CourseWork 关联的最新评分准则,如果教师删除并重新创建评分准则,此值可能会发生变化。

您可以使用现有的 studentSubmissions.GetstudentSubmissions.List 方法查看已评分的提交内容。

将以下函数添加到 main.py 以列出学生提交的作业:

def get_latest_submission(service, course_id, coursework_id):
    """Retrieves the last submission for an assignment."""
    try:
        response = service.courses().courseWork().studentSubmissions().list(
            courseId = course_id,
            courseWorkId = coursework_id,
            pageSize=1,
            # Specify the preview version. Rubrics CRUD capabilities are
            # supported in V1_20231110_PREVIEW and later.
            previewVersion="V1_20231110_PREVIEW"
        ).execute()
        submissions = response.get("studentSubmissions", [])
        if not submissions:
            print(
                """No submissions found. Did you remember to turn in and grade
                   the assignment in the UI?""")
            return
        submission = submissions[0]
        return submission

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

然后,更新并运行 main.py 以查看提交的成绩。

if __name__ == '__main__':
    service = build_authenticated_service(YOUR_API_KEY)

    submission = get_latest_submission(
        service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
    print(json.dumps(submission, indent=4))

draftRubricGradesassignedRubricGrades 包含:

  • 相应评分准则的 criterionId
  • 教师为每个条件分配的 points。它可以从所选级别开始,但老师也可以覆盖它。
  • 为每个条件选择的等级的 levelId。如果教师没有选择等级,但仍为评分标准分配了分数,则此字段不会显示。

这些列表仅包含与教师选择等级或设置分数的标准相匹配的条目。例如,如果教师在评分期间选择仅与一个条件交互,则 draftRubricGradesassignedRubricGrades 将只有一个项,即使评分准则中有多个条件也是如此。

删除评分准则

您可以通过标准 Delete 请求删除评分准则。以下代码展示了一个用于确保完整性的示例函数,但由于评分已开始,因此您无法删除当前的评分准则:

def delete_rubric(service, course_id, coursework_id, rubric_id):
    """Deletes the rubric on a coursework."""
    try:
        service.courses().courseWork().rubrics().delete(
            courseId=course_id,
            courseWorkId=coursework_id,
            id=rubric_id,
            # Specify the preview version. Rubrics CRUD capabilities are
            # supported in V1_20231110_PREVIEW and later.
            previewVersion="V1_20231110_PREVIEW"
        ).execute()

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

导出和导入评分准则

您可以手动将评分准则导出到 Google 电子表格,以供教师重复使用。

除了在代码中指定评分准则标准外,您还可以通过在评分准则正文(而非 criteria)中指定 sourceSpreadsheetId,基于这些导出的表格创建和更新评分准则:

def create_rubric_from_sheet(service, course_id, coursework_id, sheet_id):
    """Creates an example rubric on a coursework."""
    try:
        body = {
            "sourceSpreadsheetId": sheet_id
        }

        rubric = service.courses().courseWork().rubrics().create(
            courseId=course_id, courseWorkId=coursework_id, body=body,
            # Specify the preview version. Rubrics CRUD capabilities are
            # supported in V1_20231110_PREVIEW and later.
            previewVersion="V1_20231110_PREVIEW"
            ).execute()

        print(f"Rubric created with ID {rubric.get('id')}")
        return rubric

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

反馈

如果您发现任何问题或有任何意见,欢迎分享反馈