Puan anahtarlarını kullanmaya başlama

rubric, öğretmenlerin öğrenci gönderimlerine not verirken kullanabileceği bir şablondur. Classroom API, bu derecelendirme ölçeklerini yönetmek ve öğrenci gönderimlerindeki derecelendirme ölçeği notlarını okumak için öğretmen adına işlem yapmanıza olanak tanır.

Classroom kullanıcı arayüzünde puan anahtarının görünümü 1. Şekil. Classroom ödevindeki örnek puan anahtarının görünümü.

Bu kılavuzda, Rubrics API'nin temel kavramları ve işlevleri açıklanmaktadır. Puanlama anahtarının genel yapısı ve Classroom kullanıcı arayüzünde puanlama anahtarıyla notlandırma hakkında bilgi edinmek için bu Yardım Merkezi makalelerine göz atın.

Ön koşullar

Bu rehberde, aşağıdakilere sahip olduğunuz varsayılmaktadır:

Bir masaüstü uygulaması için kimlik bilgilerini yetkilendirme

Son kullanıcı olarak kimlik doğrulamak ve uygulamanızdaki kullanıcı verilerine erişmek için bir veya daha fazla OAuth 2.0 istemci kimliği oluşturmanız gerekir. İstemci kimliği, tek bir uygulamanın Google OAuth sunucularına tanıtılması için kullanılır. Uygulamanız birden fazla platformda çalışıyorsa her platform için ayrı bir istemci kimliği oluşturmanız gerekir.

  1. Google Cloud Console'da Google Cloud Kimlik Bilgileri sayfasına gidin.
  2. Kimlik Bilgileri Oluştur > OAuth istemci kimliği'ni tıklayın.
  3. Uygulama türü > Masaüstü uygulaması'nı tıklayın.
  4. Ad alanına, kimliğin adını yazın. Bu ad yalnızca Google Cloud Console'da gösterilir. Örneğin, "Rubrics client".
  5. Oluştur'u tıklayın. Yeni istemci kimliğinizi ve istemci gizli anahtarınızı gösteren OAuth istemcisi oluşturuldu ekranı görünür.
  6. JSON'ı indir'i ve ardından Tamam'ı tıklayın. Yeni oluşturulan kimlik bilgisi, OAuth 2.0 istemci kimlikleri altında görünür.
  7. İndirilen JSON dosyasını credentials.json olarak kaydedin ve dosyayı çalışma dizininize taşıyın.
  8. Kimlik bilgileri oluştur > API anahtarı'nı tıklayın ve API anahtarını not edin.

Daha fazla bilgi edinmek için Erişim kimlik bilgileri oluşturma başlıklı makaleye bakın.

OAuth kapsamlarını yapılandırma

Projenizin mevcut OAuth kapsamlarına bağlı olarak ek kapsamlar yapılandırmanız gerekebilir.

  1. OAuth izin ekranı'na gidin.
  2. Kapsamlar ekranına gitmek için Uygulamayı Düzenle > Kaydet ve Devam Et'i tıklayın.
  3. Kapsam Ekle veya Kaldır'ı tıklayın.
  4. Henüz yoksa aşağıdaki kapsamları ekleyin:
    • https://www.googleapis.com/auth/classroom.coursework.students
    • https://www.googleapis.com/auth/classroom.courses
  5. Ardından Güncelle'yi tıklayın > Kaydet ve Devam Et > Kaydet ve Devam Et > Kontrol Paneline Dön'ü tıklayın.

Daha fazla bilgi için OAuth kullanıcı rızası ekranını yapılandırma başlıklı makaleyi inceleyin.

classroom.coursework.students kapsamı, derecelendirme ölçeklerine (CourseWork erişimiyle birlikte) okuma ve yazma erişimi sağlar. classroom.courses kapsamı ise kursların okunmasına ve yazılmasına olanak tanır.

Belirli bir yöntem için gereken kapsamlar, yöntemin referans belgelerinde listelenir. Örnek olarak courses.courseWork.rubrics.create yetkilendirme kapsamlarına bakın. Tüm Classroom kapsamlarını Google API'leri için OAuth 2.0 Kapsamları bölümünde görebilirsiniz.

Örneği yapılandırma

Çalışma dizininizde Python için Google istemci kitaplığını yükleyin:

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

İstemci kitaplığını oluşturan ve YOUR_API_KEY yerine API anahtarınızı kullanarak kullanıcıyı yetkilendiren main.py adlı bir dosya oluşturun:

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 kullanarak komut dosyasını çalıştırın. Oturum açmanız ve OAuth kapsamlarını onaylamanız istenir.

Ödev oluşturma

Derecelendirme ölçeği bir ödevle veya CourseWork ile ilişkilendirilir ve yalnızca bu CourseWork bağlamında anlamlıdır. Rubrikler yalnızca üst CourseWork öğesini oluşturan Google Cloud projesi tarafından oluşturulabilir. Bu rehberin amaçları doğrultusunda, komut dosyası içeren yeni bir CourseWork ödevi oluşturun.

main.py alanına aşağıdakileri ekleyin:

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

Şimdi, yeni oluşturduğunuz test sınıfının main.py değerini almak, yeni bir örnek ödev oluşturmak ve ödevin course_id değerini almak için coursework_id değerini güncelleyin:

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 ve coursework_id öğelerini kaydedin. Bunlar tüm derecelendirme ölçeği CRUD işlemleri için gereklidir.

Classroom'da artık bir örnek CourseWork olmalıdır.

Classroom kullanıcı arayüzünde ödev görünümü Şekil 2. Classroom'da örnek bir ödevin görünümü.

Kullanıcı uygunluğunu kontrol etme

Puanlama anahtarı oluşturmak ve güncellemek için hem isteği gönderen kullanıcının hem de ilgili kurs sahibinin Google Workspace for Education Plus lisansına sahip olması gerekir. Classroom, geliştiricilerin kullanıcıların erişebileceği özellikleri belirlemesini sağlamak için kullanıcı uygunluk uç noktasını destekler.

Test hesabınızın puanlama anahtarı özelliğine erişimi olduğunu onaylamak için main.py komutunu güncelleyin ve çalıştırı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:
      print('User eligible for rubrics creation.')

Puan anahtarı oluşturma

Artık derecelendirme ölçeklerini yönetmeye başlayabilirsiniz.

Ölçütler ve düzeyler için kimlik özelliklerinin atlandığı (oluşturma sırasında oluşturulur) tam puan anahtarı nesnesini içeren bir create() çağrısıyla CourseWork üzerinde puan anahtarı oluşturulabilir.

main.py alanına aşağıdaki işlevi ekleyin:

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

Ardından, önceki Course ve CourseWork kimliklerinizi kullanarak örnek değerlendirme ölçeğini oluşturmak için main.py öğesini güncelleyin ve çalıştırı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:
      rubric = create_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
      print(json.dumps(rubric, indent=4))

Puan anahtarı gösterimiyle ilgili bazı noktalar:

  • Ölçüt ve düzey sırası, Classroom kullanıcı arayüzüne yansıtılır.
  • Puanlı seviyeler (points özelliğine sahip olanlar), artan veya azalan düzende puanlara göre sıralanmalıdır (rastgele sıralanamazlar).
  • Öğretmenler, kullanıcı arayüzünde ölçütleri ve puan verilen düzeyleri (puan verilmeyen düzeyler hariç) yeniden sıralayabilir. Bu işlem, verilerdeki sıralamayı değiştirir.

Puan anahtarı yapısıyla ilgili daha fazla uyarı için sınırlamalar bölümüne bakın.

Kullanıcı arayüzüne döndüğünüzde, ödevde rubriği görürsünüz.

Classroom kullanıcı arayüzünde puan anahtarının görünümü 3.Şekil Classroom ödevindeki örnek puan anahtarının görünümü.

Puan anahtarını okuma

Puan anahtarları, standart list() ve get() yöntemleriyle okunabilir.

Bir ödevde en fazla bir puan anahtarı olabilir. Bu nedenle list() işareti sezgisel görünmeyebilir ancak puan anahtarı kimliğiniz yoksa yararlıdır. CourseWork ile ilişkili bir değerlendirme ölçütü yoksa list() yanıtı boştur.

main.py alanına aşağıdaki işlevi ekleyin:

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

Eklediğiniz puan anahtarını getirmek için main.py öğesini güncelleyip çalıştırın:

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.

Sonraki adımlarda kullanmak üzere değerlendirme ölçütlerindeki id mülkünü not edin.

Get(), değerlendirme ölçeği kimliğiniz olduğunda iyi çalışır. İşlevde get() kullanmak aşağıdaki gibi görünebilir:

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

Bu uygulama, değerlendirme ölçütü yoksa 404 hatası döndürür.

Puan anahtarını güncelleme

Puan anahtarı güncellemeleri patch() çağrılarıyla yapılır. Rubriklerin karmaşık yapısı nedeniyle, güncellemeler okuma-değiştirme-yazma modeliyle yapılmalıdır. Bu modelde, tüm criteria özelliği değiştirilir.

Güncelleme kuralları aşağıdaki gibidir:

  1. Kimlik olmadan eklenen ölçütler veya düzeyler ekleme olarak kabul edilir.
  2. Önceden olmayan ölçütler veya seviyeler silme işlemi olarak kabul edilir.
  3. Mevcut bir kimliğe sahip ancak verileri değiştirilmiş ölçütler veya seviyeler düzenleme olarak kabul edilir. Değiştirilmeyen özellikler olduğu gibi bırakılır.
  4. Yeni veya bilinmeyen kimliklerle sağlanan ölçütler ya da düzeyler hata olarak kabul edilir.
  5. Yeni ölçütlerin ve seviyelerin sırası, yeni kullanıcı arayüzü sırası olarak kabul edilir (yukarıda belirtilen sınırlamalarla birlikte).

Puan anahtarını güncellemek için bir işlev ekleyin:

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

Bu örnekte, criteria alanı updateMask ile değiştirilmek üzere belirtilmiştir.

Ardından, yukarıda belirtilen güncelleme kurallarının her birinde değişiklik yapmak için main.py öğesini değiştirin:

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

Değişiklikler artık Classroom'da öğretmene yansıtılmalıdır.

Classroom kullanıcı arayüzünde güncellenmiş bir puan anahtarının görünümü Şekil 4. Güncellenen puan anahtarının görünümü.

Puan anahtarıyla notlandırılmış gönderimleri görüntüleme

Şu an için öğrenci gönderimleri API tarafından puan anahtarıyla notlandırılamaz ancak puan anahtarıyla notlandırılmış gönderimlerin puan anahtarı notlarını Classroom kullanıcı arayüzünde okuyabilirsiniz.

Classroom kullanıcı arayüzünde öğrenci olarak örnek ödevinizi tamamlayıp teslim edin. Ardından öğretmen olarak puan anahtarını kullanarak ödevi manuel olarak notlandırın.

Classroom kullanıcı arayüzünde puan anahtarı notunun görünümü 5.Şekil Not verme sırasında puan anahtarının öğretmen görünümü.

StudentSubmissions, derecelendirme ölçeğiyle notlandırılmış iki yeni özelliğe sahiptir: draftRubricGrades ve assignedRubricGrades. Bu özellikler, sırasıyla taslak ve atanmış notlandırma durumlarında öğretmen tarafından seçilen puanları ve seviyeleri temsil eder.

Notlandırılmış gönderimleri görüntülemek için mevcut studentSubmissions.get() ve studentSubmissions.list() yöntemlerini kullanabilirsiniz.

Öğrenci gönderimlerini listelemek için main.py'ya aşağıdaki işlevi ekleyin:

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

Ardından, gönderim notlarını görüntülemek için main.py uygulamasını güncelleyip çalıştırın.

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 ve assignedRubricGrades şunları içerir:

  • İlgili puan anahtarı ölçütlerinin criterionId.
  • pointsÖğretmenin her ölçüt için atadığı puan. Bu, seçilen seviyeden kaynaklanabilir ancak öğretmen de bu seviyeyi geçersiz kılmış olabilir.
  • Her ölçüt için seçilen düzeyin levelId. Öğretmen bir seviye seçmediyse ancak ölçüt için puan atadıysa bu alan gösterilmez.

Bu listelerde yalnızca öğretmenin bir seviye seçtiği veya puan belirlediği ölçütlere ait girişler yer alır. Örneğin, bir öğretmen notlandırma sırasında yalnızca bir ölçütle etkileşim kurmayı seçerse derecelendirme ölçeğinde birçok ölçüt olsa bile draftRubricGrades ve assignedRubricGrades yalnızca bir öğe içerir.

Puan anahtarı silme

Rubrikler, standart bir delete() isteğiyle silinebilir. Aşağıdaki kod, eksiksiz bir işlev örneği gösterir ancak not verme işlemi zaten başladığından mevcut puan anahtarını silemezsiniz:

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

Puan anahtarlarını dışa ve içe aktarma

Puan anahtarları, öğretmenlerin yeniden kullanabilmesi için Google E-Tablolar'a manuel olarak aktarılabilir.

Puan anahtarı ölçütlerini kodda belirtmenin yanı sıra, puan anahtarı gövdesinde criteria yerine sourceSpreadsheetId belirterek bu dışa aktarılan sayfalardan puan anahtarları oluşturup güncelleyebilirsiniz:

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