Bắt đầu sử dụng tiêu chí chấm điểm

rubric là một mẫu mà giáo viên có thể sử dụng khi chấm điểm bài tập đã nộp của học viên. API Lớp học cho phép bạn thay mặt giáo viên quản lý các bảng điểm này, cũng như đọc điểm của bảng điểm trong bài nộp của học viên.

Giao diện người dùng Lớp học khi xem tiêu chí chấm điểm Hình 1. Hình ảnh minh hoạ một tiêu chí chấm điểm mẫu trong bài tập trên lớp.

Hướng dẫn này giải thích các khái niệm và chức năng cơ bản của Rubrics API. Hãy xem các bài viết này trên Trung tâm trợ giúp để tìm hiểu về cấu trúc chung của một tiêu chí chấm điểm và cách chấm điểm bằng tiêu chí trong giao diện người dùng của Lớp học.

Điều kiện tiên quyết

Hướng dẫn này giả định rằng bạn đáp ứng các điều kiện sau:

Uỷ quyền thông tin đăng nhập cho một ứng dụng máy tính

Để xác thực với tư cách là người dùng cuối và truy cập vào dữ liệu người dùng trong ứng dụng của bạn, bạn cần tạo một hoặc nhiều Mã ứng dụng OAuth 2.0. Mã ứng dụng khách được dùng để xác định một ứng dụng duy nhất cho các máy chủ OAuth của Google. Nếu ứng dụng của bạn chạy trên nhiều nền tảng, bạn phải tạo một mã nhận dạng ứng dụng riêng cho mỗi nền tảng.

  1. Chuyển đến trang Thông tin đăng nhập của Google Cloud trong bảng điều khiển Google Cloud.
  2. Nhấp vào Tạo thông tin xác thực > Mã ứng dụng OAuth.
  3. Nhấp vào Loại ứng dụng > Ứng dụng dành cho máy tính.
  4. Trong trường Name (Tên), hãy nhập tên cho thông tin đăng nhập. Tên này chỉ xuất hiện trong bảng điều khiển Google Cloud. Ví dụ: "Rubrics client".
  5. Nhấp vào Tạo. Màn hình Ứng dụng OAuth đã tạo sẽ xuất hiện, cho biết Mã ứng dụng và Khoá bí mật của ứng dụng mới.
  6. Nhấp vào Tải tệp JSON xuống, rồi nhấp vào OK. Thông tin xác thực mới tạo sẽ xuất hiện trong phần Mã ứng dụng OAuth 2.0.
  7. Lưu tệp JSON đã tải xuống dưới dạng credentials.json rồi di chuyển tệp đó vào thư mục làm việc của bạn.
  8. Nhấp vào Tạo thông tin xác thực > Khoá API rồi ghi lại khoá API.

Hãy xem bài viết Tạo thông tin đăng nhập để truy cập để tìm hiểu thêm.

Định cấu hình phạm vi OAuth

Tuỳ thuộc vào các phạm vi OAuth hiện có của dự án, bạn có thể cần định cấu hình các phạm vi bổ sung.

  1. Chuyển đến màn hình đồng ý OAuth.
  2. Nhấp vào Chỉnh sửa ứng dụng > Lưu và tiếp tục để chuyển đến màn hình Phạm vi.
  3. Nhấp vào Thêm hoặc xoá phạm vi.
  4. Thêm các phạm vi sau nếu bạn chưa có:
    • https://www.googleapis.com/auth/classroom.coursework.students
    • https://www.googleapis.com/auth/classroom.courses
  5. Sau đó, Nhấp vào Cập nhật > Lưu và tiếp tục > Lưu và tiếp tục > Quay lại trang tổng quan.

Hãy xem phần Định cấu hình màn hình đồng ý OAuth để tìm hiểu thêm.

Phạm vi classroom.coursework.students cho phép truy cập đọc và ghi vào bảng điểm (cùng với quyền truy cập vào CourseWork), còn phạm vi classroom.courses cho phép đọc và ghi các khoá học.

Các phạm vi bắt buộc đối với một phương thức nhất định được liệt kê trong tài liệu tham khảo cho phương thức đó. Hãy xem các phạm vi uỷ quyền courses.courseWork.rubrics.create làm ví dụ. Bạn có thể xem tất cả các phạm vi của Lớp học trong phần Phạm vi OAuth 2.0 cho các API của Google.

Định cấu hình mẫu

Trong thư mục làm việc, hãy cài đặt thư viện ứng dụng Google cho Python:

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

Tạo một tệp có tên là main.py để tạo thư viện ứng dụng và uỷ quyền cho người dùng, bằng cách sử dụng khoá API của bạn thay cho 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)

Chạy tập lệnh bằng cách dùng python main.py. Bạn sẽ được nhắc đăng nhập và đồng ý với các phạm vi OAuth.

Tạo bài tập

Thang điểm được liên kết với một bài tập hoặc CourseWork và chỉ có ý nghĩa trong ngữ cảnh của CourseWork đó. Chỉ dự án Google Cloud đã tạo mục CourseWork mẹ mới có thể tạo thang điểm. Để phục vụ mục đích của hướng dẫn này, hãy tạo một chỉ định CourseWork mới bằng một tập lệnh.

Thêm nội dung sau vào 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

Bây giờ, hãy cập nhật main.py để truy xuất course_id của lớp kiểm thử mà bạn vừa tạo, tạo một mẫu mới cho bài tập và truy xuất coursework_id của bài tập:

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.

Lưu course_idcoursework_id. Đây là những thao tác cần thiết cho tất cả các thao tác CRUD về bảng điểm.

Giờ đây, bạn sẽ có một CourseWork mẫu trong Lớp học.

Giao diện người dùng Lớp học khi xem một bài tập Hình 2. Hình ảnh cho thấy một bài tập mẫu trong Lớp học.

Kiểm tra điều kiện sử dụng của người dùng

Để tạo và cập nhật bảng điểm, cả người dùng đưa ra yêu cầu và chủ sở hữu khoá học tương ứng đều phải có giấy phép Google Workspace for Education Plus được chỉ định cho họ. Lớp học hỗ trợ một điểm cuối về điều kiện sử dụng của người dùng để cho phép nhà phát triển xác định những chức năng mà người dùng có quyền truy cập.

Cập nhật và chạy main.py để xác nhận rằng tài khoản kiểm thử của bạn có quyền truy cập vào chức năng bảng điểm:

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

    capability = service.userProfiles().checkUserCapability(
        userId='me',
        # Specify the preview version. checkUserCapability is
        # supported in V1_20240930_PREVIEW and later.
        previewVersion="V1_20240930_PREVIEW",
        capability="CREATE_RUBRIC").execute()

    if not capability.get('allowed'):
      print('User ineligible for rubrics creation.')
      # TODO(developer): in a production app, this signal could be used to
      # proactively hide any rubrics related features from users or encourage
      # them to upgrade to the appropriate license.
    else:
      print('User eligible for rubrics creation.')

Tạo tiêu chí chấm điểm

Giờ đây, bạn đã sẵn sàng bắt đầu quản lý bảng điểm.

Bạn có thể tạo một bảng điểm trên CourseWork bằng lệnh gọi create() chứa toàn bộ đối tượng bảng điểm, trong đó các thuộc tính mã nhận dạng cho tiêu chí và cấp độ sẽ bị bỏ qua (các thuộc tính này được tạo khi tạo).

Thêm hàm sau vào 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
            ).execute()
        print(f"Rubric created with ID {rubric.get('id')}")
        return rubric

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

Sau đó, hãy cập nhật và chạy main.py để tạo bảng chấm điểm mẫu, sử dụng mã nhận dạng CourseCourseWork của bạn từ trước:

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

    capability = service.userProfiles().checkUserCapability(
        userId='me',
        # Specify the preview version. checkUserCapability is
        # supported in V1_20240930_PREVIEW and later.
        previewVersion="V1_20240930_PREVIEW",
        capability="CREATE_RUBRIC").execute()

    if not capability.get('allowed'):
      print('User ineligible for rubrics creation.')
      # TODO(developer): in a production app, this signal could be used to
      # proactively hide any rubrics related features from users or encourage
      # them to upgrade to the appropriate license.
    else:
      rubric = create_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
      print(json.dumps(rubric, indent=4))

Một số điểm về cách trình bày tiêu chí chấm điểm:

  • Thứ tự tiêu chí và cấp độ được phản ánh trong giao diện người dùng của Lớp học.
  • Các cấp độ được tính điểm (những cấp độ có thuộc tính points) phải được sắp xếp theo điểm theo thứ tự tăng dần hoặc giảm dần (không thể sắp xếp ngẫu nhiên).
  • Giáo viên có thể sắp xếp lại các tiêu chí và cấp độ được chấm điểm (nhưng không thể sắp xếp lại các cấp độ không được chấm điểm) trong giao diện người dùng, và điều này sẽ thay đổi thứ tự của các tiêu chí và cấp độ trong dữ liệu.

Hãy xem các điểm hạn chế để biết thêm các lưu ý về cấu trúc của bảng điểm.

Quay lại giao diện người dùng, bạn sẽ thấy bảng điểm trên bài tập.

Giao diện người dùng Lớp học khi xem tiêu chí chấm điểm Hình 3. Hình ảnh minh hoạ một tiêu chí chấm điểm mẫu trong bài tập trên lớp.

Đọc tiêu chí chấm điểm

Bạn có thể đọc bảng tiêu chí bằng các phương thức list()get() tiêu chuẩn.

Có thể có tối đa một bảng điểm trong một bài tập, vì vậy, list() có thể không trực quan, nhưng sẽ hữu ích nếu bạn chưa có mã bảng điểm. Nếu không có thang điểm nào liên kết với CourseWork, thì phản hồi list() sẽ trống.

Thêm hàm sau vào 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
            ).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

Cập nhật và chạy main.py để tìm nạp tiêu chí chấm điểm mà bạn đã thêm:

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.

Hãy lưu ý thuộc tính id trong bảng tiêu chí cho các bước sau.

Get() hoạt động hiệu quả khi bạn có mã chấm điểm. Việc sử dụng get() trong hàm có thể có dạng như sau:

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

        return rubric

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

Cách triển khai này trả về lỗi 404 nếu không có bảng điểm.

Cập nhật tiêu chí chấm điểm

Bạn có thể cập nhật một bảng điểm bằng các lệnh gọi patch(). Do cấu trúc phức tạp của bảng tiêu chí, bạn phải cập nhật theo mẫu đọc-sửa đổi-ghi, trong đó toàn bộ thuộc tính criteria sẽ được thay thế.

Các quy tắc cập nhật như sau:

  1. Những tiêu chí hoặc cấp độ được thêm mà không có mã nhận dạng được coi là nội dung bổ sung.
  2. Những tiêu chí hoặc cấp độ bị thiếu so với trước đây được coi là nội dung bị xoá.
  3. Các tiêu chí hoặc cấp độ có mã nhận dạng hiện có nhưng dữ liệu đã được sửa đổi được coi là nội dung chỉnh sửa. Các thuộc tính không được sửa đổi sẽ giữ nguyên.
  4. Các tiêu chí hoặc cấp độ được cung cấp bằng mã nhận dạng mới hoặc không xác định được coi là lỗi.
  5. Thứ tự của các tiêu chí và cấp độ mới được coi là thứ tự của giao diện người dùng mới (với các hạn chế nêu trên).

Thêm một hàm để cập nhật tiêu chí chấm điểm:

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'
        ).execute()

        return rubric

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

Trong ví dụ này, trường criteria được chỉ định để sửa đổi bằng updateMask.

Sau đó, sửa đổi main.py để thay đổi từng quy tắc cập nhật nêu trên:

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

    capability = service.userProfiles().checkUserCapability(
        userId='me',
        # Specify the preview version. checkUserCapability is
        # supported in V1_20240930_PREVIEW and later.
        previewVersion="V1_20240930_PREVIEW",
        capability="CREATE_RUBRIC").execute()

    if not capability.get('allowed'):
      print('User ineligible for rubrics creation.')
      # TODO(developer): in a production app, this signal could be used to
      # proactively hide any rubrics related features from users or encourage
      # them to upgrade to the appropriate license.
    else:
        # 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))

Giờ đây, những thay đổi này sẽ được áp dụng cho giáo viên trong Lớp học.

Giao diện người dùng Lớp học cho thấy một tiêu chí chấm điểm mới cập nhật Hình 4. Xem tiêu chí chấm điểm đã cập nhật.

Xem bài nộp được chấm điểm theo tiêu chí chấm điểm

Hiện tại, API không thể chấm điểm bài tập mà học viên đã nộp bằng tiêu chí chấm điểm, nhưng bạn có thể đọc điểm theo tiêu chí chấm điểm cho những bài tập đã được chấm điểm theo tiêu chí chấm điểm trong giao diện người dùng Lớp học.

Là học viên trong giao diện người dùng Lớp học, hãy hoàn thành và nộp bài tập mẫu. Sau đó, với tư cách là giáo viên, hãy chấm điểm bài tập theo cách thủ công bằng tiêu chí chấm điểm.

Chế độ xem điểm theo tiêu chí chấm điểm trong giao diện người dùng của Lớp học Hình 5. Chế độ xem tiêu chí chấm điểm của giáo viên trong quá trình chấm điểm.

StudentSubmissions đã được chấm điểm bằng một bảng điểm có 2 thuộc tính mới: draftRubricGradesassignedRubricGrades, lần lượt biểu thị điểm và cấp độ mà giáo viên đã chọn trong trạng thái chấm điểm nháp và được giao.

Bạn có thể sử dụng các phương thức studentSubmissions.get()studentSubmissions.list() hiện có để xem bài tập đã chấm điểm.

Thêm hàm sau vào main.py để liệt kê bài nộp của học viên:

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

Sau đó, hãy cập nhật và chạy main.py để xem điểm của bài tập đã gửi.

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 chứa:

  • criterionId của tiêu chí chấm điểm tương ứng.
  • points mà giáo viên đã chỉ định cho từng tiêu chí. Đây có thể là cấp độ được chọn, nhưng giáo viên cũng có thể đã ghi đè cấp độ này.
  • levelId của cấp độ được chọn cho từng tiêu chí. Nếu giáo viên không chọn cấp độ nhưng vẫn chỉ định điểm cho tiêu chí, thì trường này sẽ không xuất hiện.

Các danh sách này chỉ chứa những mục cho tiêu chí mà giáo viên đã chọn một cấp độ hoặc đặt điểm. Ví dụ: nếu giáo viên chỉ chọn tương tác với một tiêu chí trong quá trình chấm điểm, thì draftRubricGradesassignedRubricGrades sẽ chỉ có một mục, ngay cả khi bảng điểm có nhiều tiêu chí.

Xoá tiêu chí chấm điểm

Bạn có thể xoá một bảng điểm bằng yêu cầu delete() tiêu chuẩn. Đoạn mã sau đây cho thấy một hàm ví dụ để hoàn tất, nhưng vì quá trình chấm điểm đã bắt đầu, nên bạn không thể xoá tiêu chí chấm điểm hiện tại:

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

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

Xuất và nhập tiêu chí chấm điểm

Giáo viên có thể xuất tiêu chí chấm điểm sang Google Trang tính theo cách thủ công để sử dụng lại.

Ngoài việc chỉ định tiêu chí chấm điểm trong mã, bạn có thể tạo và cập nhật tiêu chí chấm điểm từ các trang tính đã xuất này bằng cách chỉ định sourceSpreadsheetId trong nội dung tiêu chí chấm điểm thay vì criteria:

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

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

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