Erste Schritte mit Bewertungsschemas

Ein rubric ist eine Vorlage, die Lehrkräfte verwenden können, wenn sie von Schülern und Studenten eingereichte Aufgaben benoten. Mit der Classroom API können Sie im Namen der Lehrkraft agieren, um diese Bewertungsschemas zu verwalten und Noten für eingereichte Aufgaben abzurufen.

Ansicht eines Bewertungsschemas in der Classroom-Benutzeroberfläche Abbildung 1 Beispiel für ein Bewertungsschema für eine Classroom-Aufgabe.

In dieser Anleitung werden die grundlegenden Konzepte und Funktionen der Rubrics API erläutert. In diesen Hilfeartikeln erfahren Sie mehr über die allgemeine Struktur eines Bewertungsschemas und wie die Benotung mit Bewertungsschemas in der Classroom-Benutzeroberfläche funktioniert.

Vorbereitung

Für diese Anleitung benötigen Sie Folgendes:

Anmeldedaten für eine Desktopanwendung autorisieren

Für die Authentifizierung als Endnutzer und für den Zugriff auf Nutzerdaten in Ihrer Anwendung müssen Sie mindestens eine OAuth 2.0-Client-ID erstellen. Eine Client-ID wird zur Identifizierung einer einzelnen Anwendung bei den OAuth-Servern von Google verwendet. Wenn Ihre Anwendung auf mehreren Plattformen ausgeführt wird, müssen Sie für jede Plattform eine separate Client-ID erstellen.

  1. Rufen Sie in der Google Cloud Console die Seite „Google Cloud Anmeldedaten“ auf.
  2. Klicken Sie auf Anmeldedaten erstellen > OAuth-Client-ID.
  3. Klicken Sie auf Anwendungstyp > Desktopanwendung.
  4. Geben Sie im Feld Name einen Namen für die Anmeldedaten ein. Dieser Name wird nur in der Google Cloud Console angezeigt. Beispiel: „Bewertungsschema-Client“.
  5. Klicken Sie auf Erstellen. Der Bildschirm „OAuth-Client erstellt“ wird angezeigt und enthält Ihre neue Client-ID und Ihren neuen Clientschlüssel.
  6. Klicken Sie auf JSON herunterladen und dann auf OK. Die neu erstellten Anmeldedaten werden unter „OAuth 2.0-Client-IDs“ angezeigt.
  7. Speichern Sie die heruntergeladene JSON-Datei als credentials.json und verschieben Sie sie in Ihr Arbeitsverzeichnis.
  8. Klicken Sie auf Anmeldedaten erstellen > API-Schlüssel und notieren Sie sich den API-Schlüssel.

Weitere Informationen finden Sie unter Anmeldedaten für den Zugriff erstellen.

OAuth-Bereiche konfigurieren

Je nach den vorhandenen OAuth-Bereichen Ihres Projekts müssen Sie möglicherweise zusätzliche Bereiche konfigurieren.

  1. Öffnen Sie den OAuth-Zustimmungsbildschirm.
  2. Klicken Sie auf App bearbeiten > Speichern und fortfahren , um zum Bildschirm „Bereiche“ zu gelangen.
  3. Klicken Sie auf Bereiche hinzufügen oder entfernen.
  4. Fügen Sie die folgenden Bereiche hinzu, falls sie noch nicht vorhanden sind:
    • https://www.googleapis.com/auth/classroom.coursework.students
    • https://www.googleapis.com/auth/classroom.courses
  5. Klicken Sie dann auf Aktualisieren > Speichern und fortfahren > Speichern und fortfahren > Zurück zum Dashboard.

Weitere Informationen finden Sie unter OAuth-Zustimmungsbildschirm konfigurieren.

Mit dem Bereich classroom.coursework.students können Sie Bewertungsschemas lesen und schreiben (zusammen mit dem Zugriff auf CourseWork). Mit dem Bereich classroom.courses können Sie Kurse lesen und schreiben.

Die für eine bestimmte Methode erforderlichen Bereiche sind in der Referenzdokumentation für die Methode aufgeführt. Ein Beispiel sind die courses.courseWork.rubrics.create Autorisierungsbereiche. Alle Classroom-Bereiche finden Sie unter OAuth 2.0-Bereiche für Google APIs.

Beispiel konfigurieren

Installieren Sie im Arbeitsverzeichnis die Google-Clientbibliothek für Python:

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
finden Sie unter Auf Vorschau-APIs zugreifen.

Erstellen Sie eine Datei namens main.py, die die Clientbibliothek erstellt und den Nutzer autorisiert. Verwenden Sie dabei Ihren API-Schlüssel anstelle von 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)

Führen Sie das Skript mit python main.py aus. Sie werden aufgefordert, sich anzumelden und den OAuth-Bereichen zuzustimmen.

Aufgabe erstellen

Ein Bewertungsschema ist mit einer Aufgabe oder CourseWork verknüpft und ist nur im Kontext dieser CourseWork sinnvoll. Bewertungsschemas können nur von dem Google Cloud-Projekt erstellt werden, das das übergeordnete CourseWork Element erstellt hat. Erstellen Sie für diese Anleitung mit einem Skript eine neue CourseWork-Aufgabe.

Fügen Sie main.py Folgendes hinzu:

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

Aktualisieren Sie jetzt main.py, um die course_id des gerade erstellten Testkurses abzurufen, eine neue Beispielaufgabe zu erstellen und die coursework_id der Aufgabe abzurufen:

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.

Speichern Sie die course_id und coursework_id. Diese sind für alle CRUD-Vorgänge für Bewertungsschemas erforderlich.

Sie sollten jetzt eine Beispiel-CourseWork in Classroom haben.

Ansicht einer Aufgabe in der Classroom-Benutzeroberfläche Abbildung 2 Beispiel für eine Aufgabe in Classroom.

Berechtigung des Nutzers prüfen

Für das Erstellen und Aktualisieren von Bewertungsschemas müssen sowohl der Nutzer, der die Anfrage stellt, als auch der entsprechende Kurseigentümer eine Google Workspace for Education Plus-Lizenz haben. Classroom unterstützt einen Endpunkt für die Nutzer berechtigung, mit dem Entwickler die Funktionen ermitteln können, auf die ein Nutzer Zugriff hat.

Aktualisieren und führen Sie main.py aus, um zu bestätigen, dass Ihr Testkonto Zugriff auf die Funktion für Bewertungsschemas hat:

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

Bewertungsschema erstellen

Jetzt können Sie Bewertungsschemas verwalten.

Ein Bewertungsschema kann für eine CourseWork mit einem create()-Aufruf erstellt werden, der das vollständige Bewertungsschema-Objekt enthält. Die ID-Attribute für Kriterien und Stufen werden dabei weggelassen (sie werden bei der Erstellung generiert).

Fügen Sie main.py die folgende Funktion hinzu:

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

Aktualisieren und führen Sie dann main.py aus, um das Beispielbewertungsschema zu erstellen. Verwenden Sie dabei die Course und CourseWork IDs von zuvor:

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

Einige Punkte zur Darstellung des Bewertungsschemas:

  • Die Reihenfolge der Kriterien und Stufen wird in der Classroom-Benutzeroberfläche berücksichtigt.
  • Bewertete Stufen (mit dem Attribut points) müssen aufsteigend oder absteigend nach Punkten sortiert werden (eine zufällige Reihenfolge ist nicht möglich).
  • Lehrkräfte können Kriterien und bewertete Stufen (aber keine unbewerteten Stufen) in der Benutzeroberfläche neu sortieren. Dadurch ändert sich ihre Reihenfolge in den Daten.

Weitere Hinweise zur Struktur von Bewertungsschemas finden Sie unter Einschränkungen.

In der Benutzeroberfläche sollte das Bewertungsschema jetzt in der Aufgabe angezeigt werden.

Ansicht eines Bewertungsschemas in der Classroom-Benutzeroberfläche Abbildung 3 Beispiel für ein Bewertungsschema für eine Classroom-Aufgabe.

Bewertungsschema lesen

Bewertungsschemas können mit den Standardmethoden list() und get() gelesen werden.

In einer Aufgabe kann es höchstens ein Bewertungsschema geben. Daher ist list() möglicherweise nicht intuitiv, aber hilfreich, wenn Sie die Bewertungsschema-ID noch nicht haben. Wenn einer CourseWork kein Bewertungsschema zugeordnet ist, ist die Antwort von list() leer.

Fügen Sie main.py die folgende Funktion hinzu:

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

Aktualisieren und führen Sie main.py aus, um das hinzugefügte Bewertungsschema abzurufen:

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.

Notieren Sie sich das Attribut id im Bewertungsschema für spätere Schritte.

Get() ist gut geeignet, wenn Sie die Bewertungsschema-ID haben. Wenn Sie stattdessen get() in der Funktion verwenden, sieht das so aus:

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

Diese Implementierung gibt einen 404-Fehler zurück, wenn kein Bewertungsschema vorhanden ist.

Bewertungsschema aktualisieren

Aktualisierungen an einem Bewertungsschema werden mit patch()-Aufrufen vorgenommen. Aufgrund der komplexen Struktur eines Bewertungsschemas müssen Aktualisierungen mit einem Lese‑, Änderungs‑ und Schreibmuster erfolgen, bei dem das gesamte Attribut criteria ersetzt wird.

Die Aktualisierungsregeln sind wie folgt:

  1. Kriterien oder Stufen, die ohne ID hinzugefügt werden, gelten als Hinzufügungen.
  2. Kriterien oder Stufen, die vorher vorhanden waren, jetzt aber fehlen , gelten als Löschungen.
  3. Kriterien oder Stufen mit einer vorhandenen ID, aber geänderten Daten gelten als Bearbeitungen. Unveränderte Attribute bleiben unverändert.
  4. Kriterien oder Stufen mit neuen oder unbekannten IDs gelten als Fehler.
  5. Die Reihenfolge der neuen Kriterien und Stufen gilt als neue Reihenfolge in der Benutzeroberfläche (mit den oben genannten Einschränkungen).

Fügen Sie eine Funktion zum Aktualisieren eines Bewertungsschemas hinzu:

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

In diesem Beispiel wird das Feld criteria mit einer updateMask zur Änderung angegeben.

Ändern Sie dann main.py, um für jede der oben genannten Aktualisierungsregeln eine Änderung vorzunehmen:

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

Die Änderungen sollten jetzt für die Lehrkraft in Classroom sichtbar sein.

Aktualisiertes Bewertungsschema in der Classroom-Benutzeroberfläche Abbildung 4 Ansicht des aktualisierten Bewertungsschemas.

Mit Bewertungsschema benotete Aufgaben ansehen

Derzeit können von Schülern und Studenten eingereichte Aufgaben nicht mit einem Bewertungsschema über die API benotet werden. Sie können aber Noten für Aufgaben abrufen, die in der Classroom-Benutzeroberfläche mit einem Bewertungsschema benotet wurden.

Erledigen Sie als Schüler oder Student in der Classroom-Benutzeroberfläche die Beispielaufgabe und geben Sie sie ab. Benoten Sie die Aufgabe dann als Lehrkraft manuell mit dem Bewertungsschema.

Ansicht einer Bewertungsschema-Note in der Classroom-Benutzeroberfläche Abbildung 5 Ansicht des Bewertungsschemas für die Lehrkraft während der Benotung.

StudentSubmissions , die mit einem Bewertungsschema benotet wurden, haben zwei neue Attribute: draftRubricGrades und assignedRubricGrades. Diese stellen die Punkte und Stufen dar, die die Lehrkraft während der Benotung im Entwurfs- bzw. zugewiesenen Zustand ausgewählt hat.

Sie können die vorhandenen studentSubmissions.get() und studentSubmissions.list() Methoden verwenden, um benotete Aufgaben anzusehen.

Fügen Sie main.py die folgende Funktion hinzu, um die von Schülern und Studenten eingereichten Aufgaben aufzulisten:

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

Aktualisieren und führen Sie dann main.py aus, um die Noten für die eingereichten Aufgaben anzusehen.

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

draftRubricGrades und assignedRubricGrades enthalten Folgendes:

  • Die criterionId der entsprechenden Bewertungsschema-Kriterien.
  • Die points, die die Lehrkraft für jedes Kriterium zugewiesen hat. Diese können aus der ausgewählten Stufe stammen, aber die Lehrkraft kann sie auch überschrieben haben.
  • Die levelId der für jedes Kriterium ausgewählten Stufe. Wenn die Lehrkraft keine Stufe ausgewählt, aber trotzdem Punkte für das Kriterium zugewiesen hat, ist dieses Feld nicht vorhanden.

Diese Listen enthalten nur Einträge für die Kriterien, bei denen eine Lehrkraft entweder eine Stufe ausgewählt oder Punkte festgelegt hat. Wenn eine Lehrkraft beispielsweise bei der Benotung nur mit einem Kriterium interagiert, enthalten draftRubricGrades und assignedRubricGrades nur ein Element, auch wenn das Bewertungsschema viele Kriterien hat.

Bewertungsschema löschen

Ein Bewertungsschema kann mit einer Standardanfrage delete() gelöscht werden. Der folgende Code zeigt zur Vollständigkeit eine Beispielfunktion. Da die Benotung aber bereits begonnen hat, können Sie das aktuelle Bewertungsschema nicht löschen:

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

Bewertungsschemas exportieren und importieren

Bewertungsschemas können manuell exportiert in Google Tabellen exportiert werden, damit sie von Lehrkräften wiederverwendet werden können.

Neben dem Angeben von Bewertungsschema-Kriterien im Code ist es auch möglich, Bewertungsschemas aus diesen exportierten Tabellen zu erstellen und zu aktualisieren. Geben Sie dazu im Bewertungsschema-Text sourceSpreadsheetId anstelle von criteria an:

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