คะแนนไฟล์แนบและคะแนนเกรด

นี่เป็นคำแนะนำแบบทีละขั้นรายการที่ 6 ในซีรีส์คำแนะนำแบบทีละขั้นเกี่ยวกับส่วนเสริมของ Classroom

ในคำแนะนำแบบทีละขั้นนี้ คุณได้แก้ไขตัวอย่างจากขั้นตอนคำแนะนำแบบทีละขั้นก่อนหน้านี้เพื่อสร้างไฟล์แนบประเภทกิจกรรมที่มีการให้คะแนน นอกจากนี้คุณยังส่งคะแนนกลับไปที่ Google Classroom แบบเป็นโปรแกรมได้ ซึ่งจะปรากฏเป็นคะแนนฉบับร่างในสมุดพกของครู

คำแนะนำแบบทีละขั้นนี้แตกต่างจากคนอื่นๆ ในซีรีส์เล็กน้อยตรงที่มีวิธีที่เป็นไปได้ 2 วิธีในการส่งเกรดกลับไปที่ Classroom ทั้ง 2 อย่างนี้ส่งผลที่ต่างกันต่อนักพัฒนาซอฟต์แวร์และประสบการณ์ของผู้ใช้ ดังนั้นให้พิจารณาทั้ง 2 อย่างในขณะออกแบบส่วนเสริม Classroom อ่านหน้าคำแนะนำในการดำเนินการกับไฟล์แนบสำหรับการอภิปรายเพิ่มเติมเกี่ยวกับตัวเลือกการใช้งาน

โปรดทราบว่าฟีเจอร์การให้คะแนนใน API เป็นฟีเจอร์ไม่บังคับ โดยจะใช้ได้กับไฟล์แนบประเภทกิจกรรมใดก็ได้

ระหว่างคำแนะนำแบบทีละขั้นนี้ คุณได้ทำตามขั้นตอนต่อไปนี้

  • แก้ไขคำขอสร้างไฟล์แนบก่อนหน้านี้ไปยัง Classroom API เพื่อตั้งค่าตัวส่วนคะแนนของไฟล์แนบด้วย
  • ให้คะแนนงานของนักเรียนโดยอัตโนมัติและตั้งค่าตัวเศษของไฟล์แนบ
  • ใช้ 2 วิธีในการส่งเกรดของงานไปยัง Classroom โดยใช้ข้อมูลเข้าสู่ระบบของครูที่ลงชื่อเข้าใช้หรือออฟไลน์

เมื่อทำเสร็จแล้ว คะแนนจะปรากฏในสมุดพกของ Classroom หลังจากทริกเกอร์การทำงานของรายการส่งคืน ซึ่งช่วงเวลาที่เหมาะสมจะขึ้นอยู่กับ แนวทางการนำไปใช้

สำหรับวัตถุประสงค์ของตัวอย่างนี้ ให้นำกิจกรรมจากคำแนะนำแบบทีละขั้นซ้ำอีกครั้ง ซึ่งมีนักเรียนแสดงรูปภาพจุดสังเกตที่มีชื่อเสียงและได้รับแจ้งให้ป้อนชื่อ กำหนดคะแนนเต็มของไฟล์แนบหากนักเรียน ป้อนชื่อที่ถูกต้อง หากไม่มี

ทำความเข้าใจฟีเจอร์การให้คะแนน API ของส่วนเสริมของ Classroom

ส่วนเสริมจะตั้งค่าได้ทั้งตัวเศษและตัวส่วนของเกรดสำหรับการแนบ พารามิเตอร์เหล่านี้จะกำหนดโดยใช้ค่า pointsEarned และ maxPoints ใน API ตามลำดับ การ์ดไฟล์แนบใน UI ของ Classroom จะแสดงค่า maxPoints เมื่อตั้งค่า

ตัวอย่างไฟล์แนบหลายรายการที่มี maxPoints ในงานเดียว

รูปที่ 1 UI การสร้างงานที่มีการ์ดไฟล์แนบของส่วนเสริม 3 ใบที่มีการตั้งค่า maxPoints

API ส่วนเสริมของ Classroom ช่วยให้คุณกำหนดการตั้งค่าและกำหนดคะแนนที่จะได้จากไฟล์แนบเกรด ซึ่งไม่เหมือนกับคะแนนงาน แต่การตั้งค่าคะแนนของงานจะเป็นไปตามการตั้งค่าคะแนนไฟล์แนบของไฟล์แนบที่มีป้ายกำกับว่าการซิงค์เกรดในการ์ดไฟล์แนบ เมื่อไฟล์แนบ "ซิงค์เกรด" ตั้งค่า pointsEarned สำหรับงานที่นักเรียนส่ง จะเป็นการกำหนดคะแนนคร่าวๆ ให้กับงานของนักเรียนด้วย

โดยปกติแล้ว ไฟล์แนบแรกที่เพิ่มในงานซึ่งตั้งค่า maxPoints จะได้รับป้ายกำกับ "การซิงค์เกรด" ดูตัวอย่าง UI การสร้างงานที่แสดงในรูปที่ 1 สำหรับตัวอย่างของป้ายกำกับ "การซิงค์เกรด" โปรดทราบว่าการ์ด "ไฟล์แนบ 1" จะมีป้ายกำกับ "การซิงค์คะแนน" และคะแนนงานในกล่องสีแดงได้รับการอัปเดตเป็น 50 คะแนน โปรดทราบว่าถึงแม้รูปที่ 1 จะแสดงการ์ดไฟล์แนบ 3 ใบ แต่มีเพียงการ์ดเดียวที่มีป้ายกำกับ "การซิงค์เกรด" นี่คือข้อจำกัดสำคัญของการใช้งานปัจจุบัน กล่าวคือมีเพียงไฟล์แนบเดียวเท่านั้นที่จะมีป้ายกำกับ "การซิงค์เกรด" ได้

หากมีไฟล์แนบหลายรายการที่ตั้งค่า maxPoints แล้ว การนำไฟล์แนบออกโดยใช้ตัวเลือก "การซิงค์เกรด" จะไม่เปิดใช้ "การซิงค์เกรด" ในไฟล์แนบที่เหลืออยู่ การเพิ่มไฟล์แนบอื่นที่ตั้งค่า maxPoints จะเปิดใช้การซิงค์เกรดในไฟล์แนบใหม่ และระบบจะปรับคะแนนของงานสูงสุดให้ตรงกัน ไม่มีกลไกที่จะใช้ดูโดยอัตโนมัติว่าไฟล์แนบใดที่มีป้ายกำกับ "การซิงค์เกรด" หรือจะดูจำนวนไฟล์แนบในงานหนึ่งๆ ได้

ตั้งค่าคะแนนสูงสุดของไฟล์แนบ

ส่วนนี้จะอธิบายการตั้งค่าตัวส่วนของเกรดในไฟล์แนบ ซึ่งก็คือคะแนนสูงสุดที่เป็นไปได้ที่นักเรียนทุกคนจะได้รับเมื่อส่งงาน ในการดำเนินการดังกล่าว ให้ตั้งค่า maxPoints ของไฟล์แนบ

มีเพียงการปรับเปลี่ยนการใช้งานที่มีอยู่เล็กน้อยเท่านั้นที่จำเป็นต่อการเปิดใช้ฟีเจอร์การให้คะแนน เมื่อสร้างไฟล์แนบ ให้เพิ่มค่า maxPoints ในออบเจ็กต์ AddOnAttachment เดียวกันกับที่มีช่อง studentWorkReviewUri,teacherViewUri และช่องไฟล์แนบอื่นๆ

โปรดทราบว่าคะแนนสูงสุดเริ่มต้นสำหรับงานใหม่คือ 100 เราขอแนะนำให้ตั้งค่า maxPoints เป็นค่าอื่นที่ไม่ใช่ 100 เพื่อยืนยันว่าได้ตั้งค่าคะแนนอย่างถูกต้อง ตั้งค่า maxPoints เป็น 50 เป็นการสาธิต

Python

เพิ่มช่อง maxPoints เมื่อสร้างออบเจ็กต์ attachment ก่อนที่จะออกคำขอ CREATE ไปยังปลายทาง courses.courseWork.addOnAttachments ซึ่งจะอยู่ในไฟล์ webapp/attachment_routes.py หากทำตามตัวอย่างที่ให้ไว้

attachment = {
    # Specifies the route for a teacher user.
    "teacherViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True),
    },
    # Specifies the route for a student user.
    "studentViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True)
    },
    # Specifies the route for a teacher user when the attachment is
    # loaded in the Classroom grading view.
    "studentWorkReviewUri": {
        "uri":
            flask.url_for(
                "view_submission", _scheme='https', _external=True)
    },
    # Sets the maximum points that a student can earn for this activity.
    # This is the denominator in a fractional representation of a grade.
    "maxPoints": 50,
    # The title of the attachment.
    "title": f"Attachment {attachment_count}",
}

ในการสาธิตนี้ คุณยังจัดเก็บค่า maxPoints ในฐานข้อมูลไฟล์แนบในเครื่องได้ด้วย ซึ่งจะช่วยให้ไม่ต้องเรียก API เพิ่มเติมในภายหลังเมื่อให้คะแนนงานที่นักเรียนส่ง อย่างไรก็ตาม โปรดทราบว่าครูอาจเปลี่ยนการตั้งค่าคะแนนของงานแยกจากส่วนเสริมได้ ส่งคำขอ GET ไปยังปลายทาง courses.courseWork เพื่อดูค่า maxPoints ระดับการมอบหมาย เมื่อดำเนินการดังกล่าว ให้ส่ง itemId ในช่อง CourseWork.id

ในตอนนี้ ให้อัปเดตโมเดลฐานข้อมูลให้เก็บค่า maxPoints ของไฟล์แนบด้วย เราขอแนะนำให้ใช้ค่า maxPoints จากการตอบกลับ CREATE:

Python

ก่อนอื่น ให้เพิ่มช่อง max_points ลงในตาราง Attachment ซึ่งจะอยู่ในไฟล์ webapp/models.py หากทำตามตัวอย่างที่ให้ไว้

# Database model to represent an attachment.
class Attachment(db.Model):
    # The attachmentId is the unique identifier for the attachment.
    attachment_id = db.Column(db.String(120), primary_key=True)

    # The image filename to store.
    image_filename = db.Column(db.String(120))

    # The image caption to store.
    image_caption = db.Column(db.String(120))

    # The maximum number of points for this activity.
    max_points = db.Column(db.Integer)

กลับไปที่คำขอCREATE "courses.courseWork.addOnAttachments" จัดเก็บค่า maxPoints ที่แสดงในคำตอบ

new_attachment = Attachment(
    # The new attachment's unique ID, returned in the CREATE response.
    attachment_id=resp.get("id"),
    image_filename=key,
    image_caption=value,
    # Store the maxPoints value returned in the response.
    max_points=int(resp.get("maxPoints")))
db.session.add(new_attachment)
db.session.commit()

ขณะนี้ไฟล์แนบมีเกรดสูงสุดแล้ว คุณควรทดสอบลักษณะการทำงานนี้ได้เลย โดยเพิ่มไฟล์แนบในงานใหม่และสังเกตว่าการ์ดไฟล์แนบแสดงป้ายกำกับ "การซิงค์คะแนน" และค่า "คะแนน" ของงานมีการเปลี่ยนแปลง

ตั้งค่าคะแนนที่นักเรียนส่งใน Classroom

ส่วนนี้จะอธิบายการตั้งค่าตัวเลขของคะแนนในไฟล์แนบ ซึ่งก็คือคะแนนของนักเรียนแต่ละคนสำหรับไฟล์แนบ ในการดำเนินการนี้ ให้ตั้งค่า pointsEarned ของการส่งงานของนักเรียน

ตอนนี้คุณมีการตัดสินใจครั้งสำคัญที่ต้องทำแล้ว: ส่วนเสริมควรออกคำขอให้ตั้งค่า pointsEarned อย่างไร

ปัญหาคือการตั้งค่า pointsEarned ต้องใช้ขอบเขต OAuth teacher คุณไม่ควรให้สิทธิ์ teacher แก่ผู้ใช้ที่เป็นนักเรียน เพราะอาจทำให้เกิดลักษณะการทำงานที่ไม่คาดคิดเมื่อนักเรียนโต้ตอบกับส่วนเสริม เช่น การโหลด iframe มุมมองของครูแทน iframe มุมมองของนักเรียน คุณมี 2 ทางเลือกสำหรับวิธีตั้งค่า pointsEarned ดังนี้

  • ใช้ข้อมูลเข้าสู่ระบบของครูที่เข้าสู่ระบบ
  • ใช้ข้อมูลเข้าสู่ระบบของครูที่จัดเก็บไว้ (ออฟไลน์)

ส่วนต่อไปนี้จะอธิบายข้อดีของแต่ละวิธีก่อนที่จะสาธิตการใช้งานแต่ละวิธี โปรดทราบว่าตัวอย่างที่ให้ไว้จะสาธิตวิธีส่งคะแนนไปยัง Classroom ทั้ง 2 วิธี โปรดดูวิธีการเฉพาะภาษาด้านล่าง สำหรับวิธีเลือกแนวทางเมื่อเรียกใช้ตัวอย่างที่มีให้

Python

ค้นหาการประกาศ SET_GRADE_WITH_LOGGED_IN_USER_CREDENTIALS ที่ด้านบนของไฟล์ webapp/attachment_routes.py ตั้งค่านี้เป็น True เพื่อส่งคืนคะแนนโดยใช้ข้อมูลเข้าสู่ระบบของครูที่ลงชื่อเข้าใช้ ตั้งค่านี้เป็น False เพื่อส่งคืนคะแนนโดยใช้ข้อมูลเข้าสู่ระบบที่จัดเก็บไว้เมื่อนักเรียนส่งกิจกรรม

กำหนดคะแนนโดยใช้ข้อมูลเข้าสู่ระบบของครูที่ลงชื่อเข้าใช้

ใช้ข้อมูลเข้าสู่ระบบของผู้ใช้ที่ลงชื่อเข้าใช้ในการออกคำขอเพื่อตั้งค่า pointsEarned วิธีนี้น่าจะดูง่ายเพราะจะเหมือนกับการดำเนินการที่เหลือทั้งหมดจนถึงปัจจุบัน และแทบไม่ต้องใช้ความพยายามที่จะคำนึง

อย่างไรก็ตาม ให้พิจารณาว่าครูจะโต้ตอบกับการส่งที่นักเรียนใน iframe ตรวจงานของนักเรียนเท่านั้น ซึ่งมีนัยสำคัญบางประการดังนี้

  • Classroom จะไม่แสดงคะแนนจนกว่าครูจะดำเนินการใน UI ของ Classroom
  • ครูอาจต้องเปิดการส่งงานของนักเรียนทุกคนเพื่อป้อนข้อมูลคะแนนทั้งหมดของนักเรียน
  • อาจมีความล่าช้าเล็กน้อยระหว่างที่ Classroom ได้รับคะแนนและก่อนที่คะแนนจะปรากฏใน UI ของ Classroom ปกติแล้วการหน่วงเวลาจะอยู่ที่ 5-10 วินาที แต่ก็อาจยาวได้ถึง 30 วินาที

เมื่อพิจารณาปัจจัยเหล่านี้ร่วมกัน ครูอาจต้องพิจารณาและใช้เวลานานในการกรอกข้อมูลเกรดของชั้นเรียน

หากต้องการใช้วิธีนี้ ให้เพิ่มการเรียก API อีก 1 รายการไปยังเส้นทางการตรวจสอบงานของนักเรียนที่มีอยู่

หลังจากดึงข้อมูลงานที่นักเรียนส่งและบันทึกไฟล์แนบแล้ว ให้ประเมินงานที่นักเรียนส่งและจัดเก็บคะแนนที่ได้ กำหนดคะแนนในช่อง pointsEarned ของออบเจ็กต์ AddOnAttachmentStudentSubmission สุดท้าย ให้ออกคำขอ PATCH ไปยังปลายทาง courses.courseWork.addOnAttachments.studentSubmissions ที่มีอินสแตนซ์ AddOnAttachmentStudentSubmission ในเนื้อหาคำขอ โปรดทราบว่าเราต้องระบุ pointsEarned ใน updateMask ในคำขอ PATCH ของเราด้วย

Python

# Look up the student's submission in our database.
student_submission = Submission.query.get(flask.session["submissionId"])

# Look up the attachment in the database.
attachment = Attachment.query.get(student_submission.attachment_id)

grade = 0

# See if the student response matches the stored name.
if student_submission.student_response.lower(
) == attachment.image_caption.lower():
    grade = attachment.max_points

# Create an instance of the Classroom service.
classroom_service = ch._credential_handler.get_classroom_service()

# Build an AddOnAttachmentStudentSubmission instance.
add_on_attachment_student_submission = {
    # Specifies the student's score for this attachment.
    "pointsEarned": grade,
}

# Issue a PATCH request to set the grade numerator for this attachment.
patch_grade_response = classroom_service.courses().courseWork(
).addOnAttachments().studentSubmissions().patch(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"],
    attachmentId=flask.session["attachmentId"],
    submissionId=flask.session["submissionId"],
    # updateMask is a list of fields being modified.
    updateMask="pointsEarned",
    body=add_on_attachment_student_submission).execute()

ตั้งค่าคะแนนโดยใช้ข้อมูลเข้าสู่ระบบของครูแบบออฟไลน์

วิธีที่ 2 ในการตั้งค่าคะแนนจะต้องใช้ข้อมูลเข้าสู่ระบบที่จัดเก็บไว้สำหรับครูที่สร้างไฟล์แนบ ในการใช้งานนี้ คุณต้องสร้างข้อมูลเข้าสู่ระบบโดยใช้โทเค็นเพื่อการเข้าถึงและการรีเฟรชของครูที่ได้รับสิทธิ์ก่อนหน้านี้ จากนั้นใช้ข้อมูลเข้าสู่ระบบเหล่านี้เพื่อตั้งค่า pointsEarned

ข้อดีสำคัญของวิธีนี้คือระบบจะป้อนข้อมูลคะแนนได้โดยไม่ต้องมีการดำเนินการจากครูใน UI ของ Classroom โดยหลีกเลี่ยงปัญหาที่พูดถึงข้างต้นได้ ผลที่ได้คือผู้ใช้ปลายทางมองว่าประสบการณ์การให้คะแนนที่ราบรื่นและมีประสิทธิภาพ นอกจากนี้ วิธีนี้ยังให้คุณเลือกช่วงที่จะส่งงานคืนได้ เช่น เวลาที่นักเรียนทำกิจกรรมเสร็จหรือไม่เรียลไทม์

ทำงานต่อไปนี้ให้เสร็จสิ้นเพื่อใช้งานวิธีนี้

  1. แก้ไขระเบียนฐานข้อมูลผู้ใช้เพื่อจัดเก็บโทเค็นเพื่อการเข้าถึง
  2. แก้ไขระเบียนฐานข้อมูลไฟล์แนบเพื่อจัดเก็บรหัสครู
  3. ดึงข้อมูลเข้าสู่ระบบของครูและ (ไม่บังคับ) สร้างอินสแตนซ์บริการ Classroom ใหม่
  4. กำหนดคะแนนของงานที่ส่ง

ในการสาธิตนี้ ให้ตั้งค่าคะแนนเมื่อนักเรียนทำกิจกรรมเสร็จ นั่นคือเมื่อนักเรียนส่งแบบฟอร์มในเส้นทางมุมมองของนักเรียน

แก้ไขระเบียนฐานข้อมูลผู้ใช้เพื่อจัดเก็บโทเค็นเพื่อการเข้าถึง

ต้องมีโทเค็นที่ไม่ซ้ำกัน 2 ตัวในการเรียก API ได้แก่ โทเค็นการรีเฟรชและโทเค็นเพื่อการเข้าถึง หากคุณทำตามชุดคำแนะนำแบบทีละขั้นมาจนถึงขณะนี้ สคีมาตาราง User ควรจัดเก็บโทเค็นการรีเฟรชไว้แล้ว การจัดเก็บโทเค็นการรีเฟรชจะเพียงพอเมื่อคุณเรียก API กับผู้ใช้ที่ลงชื่อเข้าใช้เท่านั้น เนื่องจากคุณได้รับโทเค็นเพื่อการเข้าถึงซึ่งเป็นส่วนหนึ่งของขั้นตอนการตรวจสอบสิทธิ์

อย่างไรก็ตาม ตอนนี้คุณต้องโทรออกโดยเป็นบุคคลอื่นที่ไม่ใช่ผู้ใช้ที่ลงชื่อเข้าใช้ ซึ่งหมายความว่าขั้นตอนการตรวจสอบสิทธิ์จะไม่พร้อมใช้งาน คุณจึงต้องจัดเก็บโทเค็นเพื่อการเข้าถึง ไว้ข้างโทเค็นการรีเฟรช อัปเดตสคีมาตาราง User ให้รวมโทเค็นเพื่อการเข้าถึง ดังนี้

Python

ในตัวอย่างที่เราให้ไว้ ไฟล์นี้อยู่ในไฟล์ webapp/models.py

# Database model to represent a user.
class User(db.Model):
    # The user's identifying information:
    id = db.Column(db.String(120), primary_key=True)
    display_name = db.Column(db.String(80))
    email = db.Column(db.String(120), unique=True)
    portrait_url = db.Column(db.Text())

    # The user's refresh token, which will be used to obtain an access token.
    # Note that refresh tokens will become invalid if:
    # - The refresh token has not been used for six months.
    # - The user revokes your app's access permissions.
    # - The user changes passwords.
    # - The user belongs to a Google Cloud organization
    #   that has session control policies in effect.
    refresh_token = db.Column(db.Text())

    # An access token for this user.
    access_token = db.Column(db.Text())

จากนั้นอัปเดตรหัสที่สร้างหรืออัปเดตระเบียน User เพื่อจัดเก็บโทเค็นเพื่อการเข้าถึงด้วย ดังนี้

Python

ในตัวอย่างที่เราให้ไว้ ไฟล์นี้อยู่ในไฟล์ webapp/credential_handler.py

def save_credentials_to_storage(self, credentials):
    # Issue a request for the user's profile details.
    user_info_service = googleapiclient.discovery.build(
        serviceName="oauth2", version="v2", credentials=credentials)
    user_info = user_info_service.userinfo().get().execute()
    flask.session["username"] = user_info.get("name")
    flask.session["login_hint"] = user_info.get("id")

    # See if we have any stored credentials for this user. If they have used
    # the add-on before, we should have received login_hint in the query
    # parameters.
    existing_user = self.get_credentials_from_storage(user_info.get("id"))

    # If we do have stored credentials, update the database.
    if existing_user:
        if user_info:
            existing_user.id = user_info.get("id")
            existing_user.display_name = user_info.get("name")
            existing_user.email = user_info.get("email")
            existing_user.portrait_url = user_info.get("picture")

        if credentials and credentials.refresh_token is not None:
            existing_user.refresh_token = credentials.refresh_token
            # Update the access token.
            existing_user.access_token = credentials.token

    # If not, this must be a new user, so add a new entry to the database.
    else:
        new_user = User(
            id=user_info.get("id"),
            display_name=user_info.get("name"),
            email=user_info.get("email"),
            portrait_url=user_info.get("picture"),
            refresh_token=credentials.refresh_token,
            # Store the access token as well.
            access_token=credentials.token)

        db.session.add(new_user)

    db.session.commit()

แก้ไขระเบียนฐานข้อมูลไฟล์แนบเพื่อจัดเก็บรหัสครู

หากต้องการตั้งค่าคะแนนสำหรับกิจกรรม โปรดโทรกำหนดให้ pointsEarned เป็นครูในหลักสูตร ซึ่งทำได้หลายวิธี ดังนี้

  • จัดเก็บการจับคู่ข้อมูลเข้าสู่ระบบของครูในเครื่องกับรหัสหลักสูตร อย่างไรก็ตาม โปรดทราบว่าครูคนเดียวกันอาจไม่ได้เชื่อมโยงกับหลักสูตรใดหลักสูตรหนึ่งเสมอไป
  • ส่งคำขอ GET ไปยังปลายทาง courses ของ Classroom API เพื่อรับครูคนปัจจุบัน จากนั้นค้นหาบันทึกผู้ใช้ในเครื่องเพื่อค้นหาข้อมูลเข้าสู่ระบบของครูที่ตรงกัน
  • เมื่อสร้างไฟล์แนบของส่วนเสริม ให้เก็บรหัสครูไว้ในฐานข้อมูลไฟล์แนบในเครื่อง จากนั้นดึงข้อมูลเข้าสู่ระบบของครูจาก attachmentId ที่ส่งไปยัง iframe มุมมองของนักเรียน

ตัวอย่างนี้แสดงตัวเลือกสุดท้ายเนื่องจากคุณจะกำหนดคะแนนเมื่อนักเรียนแนบไฟล์กิจกรรมเสร็จแล้ว

เพิ่มช่องรหัสครูในตาราง Attachment ของฐานข้อมูล ดังนี้

Python

ในตัวอย่างที่เราให้ไว้ ไฟล์นี้อยู่ในไฟล์ webapp/models.py

# Database model to represent an attachment.
class Attachment(db.Model):
    # The attachmentId is the unique identifier for the attachment.
    attachment_id = db.Column(db.String(120), primary_key=True)

    # The image filename to store.
    image_filename = db.Column(db.String(120))

    # The image caption to store.
    image_caption = db.Column(db.String(120))

    # The maximum number of points for this activity.
    max_points = db.Column(db.Integer)

    # The ID of the teacher that created the attachment.
    teacher_id = db.Column(db.String(120))

จากนั้นอัปเดตโค้ดที่สร้างหรืออัปเดตระเบียน Attachment เพื่อจัดเก็บรหัสของครีเอเตอร์ด้วย ดังนี้

Python

ในตัวอย่างที่ให้ไว้ ไฟล์นี้อยู่ในเมธอด create_attachments ในไฟล์ webapp/attachment_routes.py

# Store the attachment by id.
new_attachment = Attachment(
    # The new attachment's unique ID, returned in the CREATE response.
    attachment_id=resp.get("id"),
    image_filename=key,
    image_caption=value,
    max_points=int(resp.get("maxPoints")),
    teacher_id=flask.session["login_hint"])
db.session.add(new_attachment)
db.session.commit()

ดึงข้อมูลเข้าสู่ระบบของครู

ค้นหาเส้นทางที่แสดง iframe มุมมองของนักเรียน หลังจากจัดเก็บคำตอบของนักเรียนไว้ในฐานข้อมูลภายในเครื่องแล้ว ให้เรียกข้อมูลเข้าสู่ระบบของครูจากพื้นที่เก็บข้อมูลในเครื่องทันที ซึ่งน่าจะตรงไปตรงมา เนื่องจากได้มีการเตรียมตัวใน 2 ขั้นตอนข้างต้น นอกจากนี้ คุณยังสามารถใช้แท็กเหล่านี้เพื่อสร้างอินสแตนซ์ใหม่ของบริการ Classroom ให้กับผู้ใช้ที่เป็นครูได้ด้วย

Python

ในตัวอย่างที่ให้ไว้ ค่านี้อยู่ในเมธอด load_activity_attachment ในไฟล์ webapp/attachment_routes.py

# Create an instance of the Classroom service using the tokens for the
# teacher that created the attachment.

# We're assuming that there are already credentials in the session, which
# should be true given that we are adding this within the Student View
# route; we must have had valid credentials for the student to reach this
# point. The student credentials will be valid to construct a Classroom
# service for another user except for the tokens.
if not flask.session.get("credentials"):
    raise ValueError(
        "No credentials found in session for the requested user.")

# Make a copy of the student credentials so we don't modify the original.
teacher_credentials_dict = deepcopy(flask.session.get("credentials"))

# Retrieve the requested user's stored record.
teacher_record = User.query.get(attachment.teacher_id)

# Apply the user's tokens to the copied credentials.
teacher_credentials_dict["refresh_token"] = teacher_record.refresh_token
teacher_credentials_dict["token"] = teacher_record.access_token

# Construct a temporary credentials object.
teacher_credentials = google.oauth2.credentials.Credentials(
    **teacher_credentials_dict)

# Refresh the credentials if necessary; we don't know when this teacher last
# made a call.
if teacher_credentials.expired:
    teacher_credentials.refresh(Request())

# Request the Classroom service for the specified user.
teacher_classroom_service = googleapiclient.discovery.build(
    serviceName=CLASSROOM_API_SERVICE_NAME,
    version=CLASSROOM_API_VERSION,
    discoveryServiceUrl=f"https://classroom.googleapis.com/$discovery/rest?labels=ADD_ONS_ALPHA&key={GOOGLE_API_KEY}",
    credentials=teacher_credentials)

กำหนดคะแนนของงานที่ส่ง

ขั้นตอนในส่วนนี้จะเหมือนกับขั้นตอนการใช้ข้อมูลเข้าสู่ระบบของครูที่ลงชื่อเข้าใช้ อย่างไรก็ตาม โปรดทราบว่าคุณควรเรียกใช้ข้อมูลเข้าสู่ระบบของครูที่ดึงมาในขั้นตอนก่อนหน้า

Python

# Issue a PATCH request as the teacher to set the grade numerator for this
# attachment.
patch_grade_response = teacher_classroom_service.courses().courseWork(
).addOnAttachments().studentSubmissions().patch(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"],
    attachmentId=flask.session["attachmentId"],
    submissionId=flask.session["submissionId"],
    # updateMask is a list of fields being modified.
    updateMask="pointsEarned",
    body=add_on_attachment_student_submission).execute()

ทดสอบส่วนเสริม

เช่นเดียวกับคำแนะนำแบบทีละขั้น สร้างงานที่มีไฟล์แนบประเภทกิจกรรมในฐานะครู ส่งคำตอบในฐานะนักเรียน จากนั้นเปิดการส่งงานใน iframe การตรวจดูงานของนักเรียน คุณควรเห็นคะแนนปรากฏขึ้นในเวลาที่ต่างกันตามแนวทางการติดตั้งใช้งาน ดังนี้

  • หากคุณเลือกที่จะส่งคืนคะแนนเมื่อนักเรียนทำกิจกรรมเสร็จ คุณควรจะเห็นคะแนนคร่าวๆ ของนักเรียนใน UI ก่อนที่จะเปิด iframe การตรวจสอบงานของนักเรียน และคุณจะเห็นนักเรียนในรายชื่อนักเรียนเมื่อเปิดงานและในช่อง "คะแนน" ข้าง iframe การตรวจสอบงานของนักเรียน
  • หากคุณเลือกที่จะส่งคืนคะแนนเมื่อครูเปิด iframe การตรวจสอบงานของนักเรียน คะแนนจะปรากฏในช่อง "คะแนน" หลังจากที่ iframe โหลดขึ้นมาไม่นาน ดังที่กล่าวไว้ข้างต้น ขั้นตอนนี้อาจใช้เวลาสูงสุด 30 วินาที หลังจากนั้น คะแนนของนักเรียนคนใดคนหนึ่งควรปรากฏในมุมมองสมุดพกของ Classroom รายการอื่นๆ ด้วย

ยืนยันว่าคะแนนที่ถูกต้องจะปรากฏต่อนักเรียน

ยินดีด้วย คุณพร้อมดำเนินการขั้นตอนถัดไปแล้ว ซึ่งก็คือการสร้างไฟล์แนบนอก Google Classroom