איך מתחילים לעבוד עם קריטריונים להערכה

rubric היא תבנית שמורים יכולים להשתמש בה למתן ציונים לתלמידים. של משפטים יחידים, ה-API של Classroom מאפשר לכם לפעול בשם כדי לנהל את קריטריוני ההערכה האלה.

תצוגה של קריטריון הערכה בממשק המשתמש של Classroom איור 1. תצוגה של קריטריון הערכה לדוגמה במטלה ב-Classroom.

במדריך הזה מוסבר על המושגים הבסיסיים והפונקציונליות של ה-Rubrics API. צפייה לקבלת מידע נוסף על הנושאים הבאים במרכז העזרה את המבנה של קריטריון ההערכה והאיך קריטריון ההערכה למתן ציונים בממשק המשתמש של Classroom.

דרישות מוקדמות

המדריך הזה מבוסס על ההנחה שיש לכם:

אישור פרטי כניסה לאפליקציה בשולחן העבודה

כדי לבצע אימות כמשתמש קצה ולגשת לנתוני המשתמשים באפליקציה: ליצור מזהה לקוח אחד או יותר של OAuth 2.0. מזהה לקוח משמש לזיהוי אפליקציה יחידה לשרתי OAuth של Google. אם האפליקציה שלכם פועלת בכמה פלטפורמות, צריך ליצור מזהה לקוח נפרד לכל פלטפורמה.

  1. נכנסים לדף Google Cloud Credentials מסוף Google Cloud.
  2. לוחצים על Create Credentials > מזהה הלקוח ב-OAuth
  3. לוחצים על Application type (סוג אפליקציה) > אפליקציה למחשב.
  4. בשדה Name, מקלידים שם לפרטי הכניסה. השם הזה הוא רק שמוצגת במסוף Google Cloud. לדוגמה, 'לקוח התצוגה המקדימה של הקריטריונים להערכה'.
  5. לוחצים על יצירה. יופיע המסך שנוצר על ידי לקוח OAuth ומוצג בו Client-ID ו-Client Secret.
  6. לוחצים על הורדת JSON ואז על אישור. פרטי הכניסה החדשים שנוצרו מופיעה בקטע 'מזהי לקוחות של OAuth 2.0'.
  7. שומרים את קובץ ה-JSON שהורדתם בתור credentials.json ומעבירים אותו אל ספריית העבודה שלכם.
  8. לוחצים על Create Credentials > מפתח API ורושמים את מפתח ה-API.

אפשר לקרוא מידע נוסף במאמר יצירת פרטי כניסה.

הגדרת היקפי ההרשאות של OAuth

בהתאם להיקפי ההרשאות הקיימים של OAuth בפרויקט, יכול להיות שתצטרכו להגדיר להוסיף היקפים.

  1. עוברים למסך ההסכמה של OAuth.
  2. לוחצים על עריכת האפליקציה > שמירה והמשך כדי להגיע למסך 'היקפים'.
  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 שמאפשר לקרוא ולכתוב קורסים.

היקפי ההרשאות הנדרשים לשיטה מסוימת מפורטים במסמכי התיעוד ל-method. לעיון ב-courses.courseWork.rubrics.create היקפי הרשאות כדוגמה. במאמר היקפי OAuth 2.0 ל-Google אפשר לראות את כל ההיקפים של Classroom ממשקי API. קריטריונים להערכה לא מוזכרים כאן כי ה-API עדיין נמצא בתצוגה מקדימה.

הגדרת הדוגמה

בספריית העבודה, מתקינים את ספריית הלקוח של Google ל-Python:

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. ניתן ליצור קריטריונים להערכה רק על ידי הפרויקט ב-Google Cloud שבו נוצר פריט ההורה CourseWork. למטרות במדריך הזה, צריך ליצור מטלה חדשה מסוג 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_id ואת coursework_id. הערכים האלה נדרשים לכל ה-CRUD של הקריטריונים להערכה ב-AI.

עכשיו אמורה להיות לכם דוגמה CourseWork ב-Classroom.

צפייה במטלה בממשק המשתמש של Classroom איור 2. תצוגה של מטלה לדוגמה ב-Classroom.

יצירת קריטריון הערכה

עכשיו הכול מוכן ואפשר להתחיל לנהל את קריטריונים להערכה.

אפשר ליצור קריטריון הערכה בCourseWork באמצעות קריאה ל-Create שמכילה את אובייקט קריטריון הערכה מלא, שבו מושמטים מאפייני המזהה לקריטריונים ולרמות (הקישורים האלה נוצרים בזמן היצירה).

מוסיפים את הפונקציה הבאה אל 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

אחר כך מעדכנים ומריצים את הפקודה main.py כדי ליצור את קריטריון ההערכה לדוגמה, באמצעות Course ו-CourseWork מזהים מתאריכים קודמים:

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

כמה נקודות על הייצוג של קריטריון ההערכה:

  • סדר הקריטריון והרמות משתקפים בממשק המשתמש של Classroom.
  • רמות עם ציון (אלה שיש להן את הנכס points), חייבות להיות ממוינות לפי נקודות בסדר עולה או יורד (לא ניתן לסדר אותם בצורה אקראית).
  • מורים יכולים למיין מחדש קריטריונים ורמות עם ציון (אבל לא ניתן ציון ללא ציון) ).

אזהרות נוספות לגבי המבנה של קריטריוני ההערכה מופיעים במגבלות.

בממשק המשתמש, אתם אמורים לראות את קריטריון ההערכה במטלה.

תצוגה של קריטריון הערכה בממשק המשתמש של Classroom איור 3. תצוגה של קריטריון הערכה לדוגמה במטלה ב-Classroom.

קריאת קריטריון הערכה

אפשר לקרוא את הקריטריונים להערכה באמצעות השיטות הסטנדרטיות של List ו-Get.

למטלה יכול להיות קריטריון הערכה אחד לכל היותר, כך שנראה שהמטלה List זה לא אינטואיטיבי, אבל זה יעזור אם אין לכם עדיין את מזהה קריטריון ההערכה. אם יש אין קריטריון הערכה שמשויך ל-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 בקריטריון ההערכה לגבי השלבים הבאים.

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. נלקחים בחשבון קריטריונים או רמות שנוספו ללא מזהה תוספות.
  2. קריטריונים או רמות שחסרים קודם לכן נלקחים בחשבון מחיקות.
  3. נלקחים בחשבון קריטריונים או רמות עם מזהה קיים אבל עם נתונים ששונו עריכות. נכסים שלא בוצעו בהם שינויים יישארו כפי שהם.
  4. קריטריונים או רמות שמסופקים עם מזהים חדשים או לא מוכרים שגיאות.
  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))

השינויים אמורים לבוא לידי ביטוי אצל המורה ב-Classroom.

תצוגה של קריטריון הערכה מעודכן בממשק המשתמש של Classroom איור 4. תצוגה של קריטריון ההערכה המעודכן.

הצגת מטלות עם ציון לפי קריטריון הערכה

נכון לעכשיו, לא ניתן לתת ציון להגשות של תלמידים באמצעות קריטריון הערכה באמצעות ה-API, אבל יכול לקרוא ציונים של קריטריוני הערכה בהגשה שקיבלו ציון באמצעות קריטריון הערכה ממשק המשתמש של Classroom.

כתלמידים בממשק המשתמש של Classroom, משלימים את המטלה לדוגמה ומגישים אותה. כמורים, תוכלו לתת ציון למטלה ידנית באמצעות קריטריון ההערכה.

תצוגת קריטריון הערכה בממשק המשתמש של Classroom איור 5. תצוגת מורה של קריטריון ההערכה במהלך מתן ציונים.

להגשות של תלמידים שקיבלו ציון באמצעות קריטריון הערכה יש שני מטלות חדשות draftRubricGrades ו-assignedRubricGrades, שמייצגים הנקודות והרמות שהמורה בחר/ה במהלך הטיוטה והציונים שהוקצו בהתאמה אישית,

בנוסף, ההגשות של התלמידים עם קריטריון הערכה משויך מכילות rubricId אפילו לפני מתן ציונים. הנתון הזה מייצג את קריטריון ההערכה האחרון שמשויך אל CourseWork, והערך הזה עשוי להשתנות אם מורים ימחקו ויצרו מחדש קריטריון הערכה.

אפשר להשתמש ב-studentSubmissions.Get הקיים studentSubmissions.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))

הערכים draftRubricGrades ו-assignedRubricGrades מכילים:

  • הערך criterionId של הקריטריונים המתאימים לקריטריון הערכה.
  • points שהמורה הקצתה לכל קריטריון. המקור יכול להיות ברמה שנבחרה, אבל יכול להיות גם שהמורה החליף/ה את המשפט הזה.
  • levelId של הרמה שנבחרה לכל קריטריון. אם המורה לא לבחור רמה, אבל עדיין יוקצו נקודות לקריטריון, השדה הזה לא קיים.

הרשימות האלה מכילות רק ערכים של הקריטריונים שבהם המורים בחרת רמה או הגדרת נקודות. לדוגמה אם מורה בוחר/ת רק לקיים אינטראקציה עם קריטריון אחד במהלך מתן הציונים, draftRubricGrades ל-assignedRubricGrades יהיה רק פריט אחד, גם אם בקריטריון ההערכה יש הרבה פריטים קריטריונים.

מחיקה של קריטריון הערכה

אפשר למחוק קריטריון הערכה באמצעות בקשה רגילה של 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 באופן ידני קריטריונים של הערכה גיליונות אלקטרוניים לשימוש חוזר של מורים.

בנוסף לציון קריטריונים של קריטריון הערכה בקוד, ניתן ליצור לעדכן את קריטריוני ההערכה בגיליונות המיוצאים האלה על ידי ציון sourceSpreadsheetId בגוף של קריטריון הערכה במקום 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,
            # 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

משוב

אם נתקלתם בבעיות או אם אתם רוצים לספק לנו משוב, נשמח לקבל משוב.