Mulai menggunakan rubrik

rubric adalah template yang dapat digunakan pengajar saat menilai siswa kiriman. Classroom API memungkinkan Anda bertindak atas nama pengajar untuk mengelola rubrik ini.

Melihat rubrik di UI Classroom Gambar 1. Melihat contoh rubrik pada tugas Classroom.

Panduan ini menjelaskan konsep dasar dan fungsi Rubrics API. Lihat artikel Pusat Bantuan ini untuk mempelajari sejumlah struktur rubrik dan seberapa rubrik penilaian dilakukan di UI Classroom.

Prasyarat

Tutorial ini mengasumsikan bahwa Anda memiliki hal berikut:

Memberi otorisasi kredensial untuk aplikasi desktop

Untuk mengautentikasi sebagai pengguna akhir dan mengakses data pengguna di aplikasi, Anda harus buat satu atau beberapa ID Klien OAuth 2.0. Client ID digunakan untuk mengidentifikasi aplikasi tunggal ke server OAuth Google. Jika aplikasi Anda berjalan di beberapa platform, Anda harus membuat ID klien terpisah untuk setiap platform.

  1. Buka halaman Credentials Google Cloud di Konsol Google Cloud Anda.
  2. Klik Create Credentials > Client ID OAuth.
  3. Klik Jenis aplikasi > Aplikasi desktop.
  4. Di kolom Name, ketik nama untuk kredensial tersebut. Nama ini hanya yang ditampilkan di Konsol Google Cloud. Misalnya, "Klien Pratinjau Rubrik".
  5. Klik Buat. Layar yang dibuat klien OAuth akan muncul, yang menunjukkan Client ID dan Rahasia klien.
  6. Klik Download JSON, lalu klik OK. Kredensial yang baru dibuat akan muncul di ID Klien OAuth 2.0.
  7. Simpan file JSON yang didownload sebagai credentials.json, lalu pindahkan file tersebut ke pada direktori kerja Anda.
  8. Klik Create Credentials > Kunci API dan catat kunci API-nya.

Lihat Membuat kredensial akses untuk mempelajari lebih lanjut.

Mengonfigurasi cakupan OAuth

Bergantung pada cakupan OAuth proyek yang ada, Anda mungkin perlu mengonfigurasi tambahan.

  1. Buka Layar izin OAuth.
  2. Klik Edit Aplikasi > Simpan dan Lanjutkan untuk membuka layar Cakupan.
  3. Klik Add or Remove Scopes.
  4. Tambahkan cakupan berikut jika Anda belum memilikinya:
    • https://www.googleapis.com/auth/classroom.coursework.students
    • https://www.googleapis.com/auth/classroom.courses
  5. Lalu Klik Update > Simpan dan Lanjutkan > Simpan dan Lanjutkan > Kembali ke Dasbor.

Lihat Mengonfigurasi layar izin OAuth untuk mempelajari lainnya.

Cakupan classroom.coursework.students memungkinkan akses baca dan tulis ke rubrik (beserta akses ke CourseWork), dan cakupan classroom.courses mengizinkan kursus membaca dan menulis.

Cakupan yang diperlukan untuk metode tertentu tercantum dalam dokumentasi referensi untuk metode tersebut. Lihat courses.courseWork.rubrics.create cakupan otorisasi sebagai contoh. Anda dapat melihat semua cakupan Classroom di Cakupan OAuth 2.0 untuk Google Google Cloud API. Rubrik tidak disebutkan di sini karena API masih dalam versi pratinjau.

Mengonfigurasi contoh

Di direktori kerja Anda, instal library klien Google untuk Python:

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

Buat file bernama main.py yang membangun library klien dan memberikan otorisasi pengguna, dengan menggunakan kunci API Anda sebagai pengganti 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)

Jalankan skrip menggunakan python main.py. Anda akan diminta untuk login dan menyetujui cakupan OAuth.

Membuat tugas

Rubrik dikaitkan dengan tugas, atau CourseWork, dan hanya bermakna dalam konteks CourseWork tersebut. Rubrik hanya dapat dibuat oleh project Google Cloud yang membuat item CourseWork induk. Untuk tujuan berdasarkan panduan ini, buat tugas CourseWork baru dengan skrip.

Tambahkan kode berikut ke 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

Sekarang update main.py untuk mengambil course_id dari class pengujian yang baru saja Anda dibuat, membuat contoh tugas baru, dan mengambil 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.

Simpan course_id dan coursework_id. Hal ini diperlukan untuk semua CRUD rubrik operasional bisnis.

Sekarang Anda akan memiliki contoh CourseWork di Classroom.

Melihat tugas di UI Classroom Gambar 2. Lihat contoh tugas di Classroom.

Membuat rubrik

Sekarang Anda siap untuk mulai mengelola rubrik.

Rubrik dapat dibuat di CourseWork dengan panggilan Create yang berisi objek rubrik lengkap, dengan properti ID untuk kriteria dan tingkat dihilangkan (ini dibuat saat pembuatan).

Tambahkan fungsi berikut ke 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

Kemudian, perbarui dan jalankan main.py untuk membuat contoh rubrik, menggunakan Course dan CourseWork ID sebelumnya:

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

Beberapa poin tentang representasi rubrik:

  • Kriteria dan urutan tingkat ditampilkan di UI Classroom.
  • Level yang diberi skor (level dengan properti points), harus diurutkan berdasarkan poin dalam urutan menaik atau menurun (tidak dapat diurutkan secara acak).
  • Pengajar dapat mengurutkan ulang kriteria dan skor level (tetapi tidak dapat dinilai level) di UI, dan itu mengubah urutannya dalam data.

Lihat batasan untuk peringatan lainnya tentang struktur rubrik.

Kembali ke UI, Anda akan melihat rubrik pada tugas.

Melihat rubrik di UI Classroom Gambar 3. Melihat contoh rubrik pada tugas Classroom.

Membaca rubrik

Rubrik dapat dibaca dengan metode List dan Get standar.

Hanya boleh ada maksimal satu rubrik dalam tugas, jadi List mungkin tampak tidak intuitif, tetapi akan sangat membantu jika Anda belum memiliki ID rubrik. Jika ada tidak ada rubrik yang terkait dengan CourseWork, respons List kosong.

Tambahkan fungsi berikut ke 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

Perbarui dan jalankan main.py untuk mengambil rubrik yang Anda tambahkan:

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.

Perhatikan properti id dalam rubrik untuk mengetahui langkah-langkah berikutnya.

Get berfungsi dengan baik jika Anda memiliki ID rubrik. Menggunakan Get dalam fungsi mungkin akan terlihat seperti:

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

Penerapan ini akan menampilkan 404 jika tidak ada rubrik.

Memperbarui rubrik

Pembaruan pada rubrik dilakukan dengan panggilan Patch. Karena struktur yang kompleks suatu rubrik, pembaruan harus dilakukan dengan pola baca-ubah-tulis, dengan seluruh properti criteria diganti.

Aturan updatenya adalah sebagai berikut:

  1. Kriteria atau tingkat yang ditambahkan tanpa ID akan dianggap penambahan.
  2. Kriteria atau tingkat yang tidak ada dari sebelumnya akan dipertimbangkan penghapusan.
  3. Kriteria atau tingkat dengan ID yang ada, tetapi data yang diubah dipertimbangkan edit. Properti yang tidak diubah dibiarkan apa adanya.
  4. Kriteria atau tingkat yang disediakan dengan ID baru atau tidak diketahui akan dipertimbangkan error.
  5. Urutan kriteria dan level baru dianggap sebagai urutan UI baru (dengan batasan yang disebutkan di atas).

Tambahkan fungsi untuk memperbarui rubrik:

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

Dalam contoh ini, kolom criteria ditentukan untuk dimodifikasi dengan updateMask.

Kemudian, ubah main.py untuk melakukan perubahan bagi setiap update yang disebutkan di atas aturan:

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

Perubahan sekarang akan terlihat untuk pengajar di Classroom.

Melihat rubrik yang diperbarui di UI Classroom Gambar 4. Tampilan rubrik yang diperbarui.

Melihat kiriman yang dinilai rubrik

Untuk saat ini, kiriman siswa tidak dapat dinilai dengan rubrik oleh API, tetapi Anda dapat membaca nilai rubrik untuk kiriman yang telah dinilai dengan rubrik di UI Classroom.

Sebagai siswa di UI Classroom, lengkapi dan serahkan contoh tugas Anda. Kemudian sebagai pengajar, nilai tugas menggunakan rubrik secara manual.

Melihat nilai rubrik di UI Classroom Gambar 5. Tampilan rubrik untuk pengajar selama penilaian.

Pengiriman siswa yang telah dinilai dengan rubrik memiliki dua properti: draftRubricGrades dan assignedRubricGrades, yang mewakili poin dan level yang dipilih oleh pengajar selama draf dan penilaian yang ditetapkan masing-masing.

Selain itu, kiriman siswa dengan rubrik terkait berisi rubricId kolom, bahkan sebelum melakukan penilaian. Ini mewakili rubrik terbaru yang terkait dengan CourseWork, dan nilai ini dapat berubah jika pengajar menghapus dan membuat ulang rubrik tugas.

Anda dapat menggunakan studentSubmissions.Get yang ada dan Metode studentSubmissions.List untuk melihat kiriman yang telah dinilai.

Tambahkan fungsi berikut ke main.py untuk mencantumkan tugas yang dikirimkan siswa:

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

Kemudian, update dan jalankan main.py untuk melihat nilai kiriman.

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 dan assignedRubricGrades berisi:

  • criterionId kriteria rubrik yang sesuai.
  • points yang ditetapkan pengajar untuk setiap kriteria. Data ini bisa berasal dari tingkat yang dipilih, tetapi pengajar juga dapat menimpanya.
  • levelId tingkat yang dipilih untuk tiap kriteria. Jika pengajar tidak memilih tingkat, tetapi masih menetapkan poin untuk kriteria, kolom ini tidak ada.

Daftar ini hanya berisi entri untuk kriteria yang digunakan pengajar memilih level atau menentukan poin. Misalnya, jika pengajar memilih untuk hanya berinteraksi dengan satu kriteria selama penilaian, draftRubricGrades dan assignedRubricGrades hanya akan memiliki satu item, meskipun rubrik memiliki banyak kriteria.

Menghapus rubrik

Rubrik dapat dihapus dengan permintaan Delete standar. Kode berikut menunjukkan contoh fungsi untuk kelengkapan, tetapi karena penilaian sudah dimulai, Anda tidak dapat menghapus rubrik yang ada:

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

Mengekspor dan mengimpor rubrik

Rubrik dapat diekspor secara manual ke Google Spreadsheet untuk digunakan kembali oleh guru.

Selain menentukan kriteria rubrik dalam kode, dimungkinkan untuk membuat dan memperbarui rubrik dari sheet yang diekspor ini dengan menentukan sourceSpreadsheetId dalam isi rubrik, bukan 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

Masukan

Jika Anda menemukan masalah atau memiliki masukan, bagikan masukan Anda.