rubric
は、教師が生徒の採点を行う際に使用できるテンプレートです。
提出します。Classroom API を使用すると、Google Classroom の
教師がルーブリックを管理します。
図 1. Classroom の課題のサンプル ルーブリック。
このガイドでは、ルーブリック API の基本概念と機能について説明します。詳しくは、 これらについて詳しくは、 ルーブリックの構成と 採点は Classroom UI で行います。
前提条件
このガイドは、次のものがあることを前提としています。
- Python 3.8.6 以降
- pip パッケージ管理ツール
- Google Cloud プロジェクト。
- Google Workspace for Education アカウントとその Google Classroom 有効にする必要があります。
- 少なくとも 1 つのテスト用生徒アカウントを含むテストクラス。まだ設定していない場合は、 テストに使用できる Google Classroom のクラスです。 UI で作成し、 テスト生徒を追加する。
デスクトップ アプリケーションの認証情報を承認する
エンドユーザーとして認証を行い、アプリ内でユーザーデータにアクセスするには、1 つ以上の OAuth 2.0 クライアント ID を作成する必要があります。クライアント ID は Google の OAuth サーバーに送信します。アプリが複数のプラットフォームで動作する場合 プラットフォームごとに個別のクライアント ID を作成する必要があります。
- Google Cloud の [認証情報] ページ( Google Cloud コンソール。
- [認証情報を作成] をクリックします。OAuth クライアント ID。
- [アプリケーションの種類] >デスクトップ アプリ。
- [名前] フィールドに、認証情報の名前を入力します。この名前は 表示されます。例: 「ルーブリック プレビュー クライアント」。
- [作成] をクリックします。[OAuth クライアントの作成] 画面が表示され、新しい クライアント ID とクライアント シークレット。
- [JSON をダウンロード] をクリックし、[OK] をクリックします。新しく作成された認証情報 [OAuth 2.0 クライアント ID] に表示されます。
- ダウンロードした JSON ファイルを
credentials.json
として保存し、ファイルを次の場所に移動します。 作業ディレクトリに移ります。 - [認証情報を作成] をクリックします。API キー] に移動し、API キーをメモしておきます。
詳細については、アクセス認証情報を作成するをご覧ください。
OAuth スコープを構成する
プロジェクトの既存の OAuth スコープによっては、 あります。
- OAuth 同意画面に移動します。
- [アプリを編集] をクリックします。[Save and Continue] をクリックして [Scopes] 画面に移動します。
- [スコープを追加または削除] をクリックします。
- 次のスコープを追加します(まだ追加していない場合)。
<ph type="x-smartling-placeholder">
- </ph>
https://www.googleapis.com/auth/classroom.coursework.students
https://www.googleapis.com/auth/classroom.courses
- 次に、[更新] をクリック >保存して次へ >保存して次へ > ダッシュボードに戻る
詳しくは、OAuth 同意画面を構成するをご覧ください。 できます。
classroom.coursework.students
スコープは、以下に対する読み取りと書き込みのアクセスを可能にします。
ルーブリック(CourseWork
へのアクセスを含む)、classroom.courses
のスコープ
読み書きのコースを使用できます。
特定のメソッドに必要なスコープは、リファレンス ドキュメントに記載されています。
メソッドの引数。courses.courseWork.rubrics.create
認可スコープをご覧ください。
できます。Classroom のスコープについては、Google 向け OAuth 2.0 スコープ、
API。API はまだプレビュー版のため、ここではルーブリックについては触れません。
サンプルを構成する
作業ディレクトリに Python 用の Google クライアント ライブラリをインストールします。
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
クライアント ライブラリをビルドして承認する main.py
というファイルを作成します。
YOUR_API_KEY
の代わりに API キーを使用します。
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
を使用してスクリプトを実行します。ログインと有効化を求めるメッセージが表示されます
同意します。
課題を作成
ルーブリックは課題または CourseWork
に関連付けられており、
その CourseWork
のコンテキストで意味のあるものになります。ルーブリックを作成できるのは
親 CourseWork
アイテムを作成した Google Cloud プロジェクト。目的
スクリプトを使用して新しい 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 に必要です
必要があります。
これで、Classroom に CourseWork
のサンプルが準備できました。
図 2. Classroom の課題のサンプルの表示。
ルーブリックを作成する
これで、ルーブリックの管理を開始する準備が整いました。
CourseWork
でルーブリックを作成するには、Create
呼び出しに
完全なルーブリック オブジェクト。条件とレベルの ID プロパティは省略
(これらは作成時に生成されます)。
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
ID は次のとおりです。
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 の UI に反映されている。
- スコア付きのレベル(
points
プロパティを持つレベル)はポイントで並べ替える必要があります 昇順か降順のいずれかになります(ランダムに並べ替えることはできません)。 - 教師は、基準とスコア付けされたレベルを並べ替えることができる(ただし、スコアリングされないレベルに並べ替えられない) 含まれており、データ内の順序が変わります。
ルーブリックの構造に関する注意事項については、制限事項をご覧ください。
UI に戻ると、課題のルーブリックが表示されます。
図 3. Classroom の課題のサンプル ルーブリック。
ルーブリックを読む
ルーブリックは、標準の List
メソッドと Get
メソッドを使用して読み取ることができます。
1 つの課題に含めることのできるルーブリックは 1 つまでであるため、「List
」は
直感的ではありませんが、ルーブリック ID がないと便利です。もし
に 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
は、ルーブリック ID があれば適切に機能します。関数での 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
プロパティ全体が置き換えられます。
更新ルールは次のとおりです。
- ID なしで追加された条件またはレベルが考慮されます 追加機能。
- これまでに不足している基準またはレベルが考慮されます 削除。
- 既存の ID であってもデータは変更されている条件またはレベルは考慮されます 編集。変更されていないプロパティはそのまま残ります。
- 新しい ID または不明な ID で指定された条件やレベルは考慮されます エラーです。
- 新しい条件とレベルの順序は、新しい UI の順序とみなされます。 (前述の制限事項があります)。
ルーブリックを更新する関数を追加します。
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 の教師に反映されます。
図 4. 更新されたルーブリックの表示。
ルーブリックで採点された提出物を表示する
現在のところ、生徒の提出物を API でルーブリックを使って採点することはできませんが、 提出物のルーブリックの成績を確認できます。 Classroom の UI。
Classroom の UI で、生徒として課題のサンプルを提出します。 次に、教師が手動でルーブリックを使用して課題を採点します。
図 5. 採点中に教師に表示されるルーブリック。
ルーブリックで採点された生徒の提出物には、新たに 2 つの提出物が
プロパティ: draftRubricGrades
と assignedRubricGrades
。
下書き段階と割り当てられた採点時に教師が選択した点とレベル
構成されます。
また、関連するルーブリックと生徒の提出物には rubricId
が含まれます。
できます。これは Google Workspace に関連付けられた
最新のルーブリックで
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
。教師が レベルを選択しているものの、その評価基準の点数がまだ割り当てられている場合、このフィールドには ありません。
これらのリストには、教師が次のいずれかの条件に該当する項目のみが含まれます。
選択します。たとえば、教師が
採点中に 1 つの基準(draftRubricGrades
と
ルーブリックが多数あっても、assignedRubricGrades
には 1 つの項目しか含まれません。
できます。
ルーブリックを削除する
ルーブリックは、標準の 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 に手動でエクスポート可能 教師がスプレッドシートを再利用できる。
コード内でルーブリックの条件を指定するだけでなく、
エクスポートしたシートからルーブリックを更新するには、
criteria
ではなくルーブリック本文の sourceSpreadsheetId
:
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
フィードバック
問題が見つかった場合や、ご意見がある場合は、フィードバックをお寄せください。