علامات المرفقات ودرجات التراجع عن الظهور

هذه هي الجولة السادسة ضمن سلسلة الجولات التفصيلية حول إضافات Classroom.

في هذه الجولة التفصيلية، يمكنك تعديل المثال من خطوة الجولة التفصيلية السابقة لإنتاج مرفق من نوع نشاط مقيّم. يمكنك أيضًا اجتياز الدرجات مرة أخرى إلى Google Classroom آليًا، وتظهر هذه الدرجة في دفتر العلامات الخاص بالمعلّم كدرجة أولية.

تختلف هذه الجولة التفصيلية قليلاً عن غيرها في السلسلة في أن هناك طريقتين محتملتين لإعادة الدرجات إلى Classroom. ولكل منهما تأثير واضح على تجارب المستخدمين ومطوّري البرامج، لذا يجب وضعهما في الاعتبار عند تصميم إضافة Classroom. اقرأ صفحة دليل التفاعل مع المرفقات لمزيد من المناقشة حول خيارات التنفيذ.

يُرجى العلم أنّ ميزات وضع الدرجات في واجهة برمجة التطبيقات اختيارية. ويمكن استخدامها مع أي مرفق نوع نشاط.

خلال هذه الجولة التفصيلية، يمكنك إكمال ما يلي:

  • عدِّل طلبات إنشاء المرفقات السابقة إلى Classroom API لضبط محدِّد الدرجة للمرفق أيضًا.
  • حدِّد الدرجات التي أرسلها الطالب برمجيًا واضبط بسط درجة المرفق.
  • نفِّذ نهجين لتمرير درجة التسليم إلى Classroom باستخدام بيانات اعتماد المعلّم بعد تسجيل الدخول أو عدم الاتصال بالإنترنت.

بعد الانتهاء، تظهر الدرجات في دفتر العلامات في Classroom بعد تفعيل سلوك التراجع عن الظهور. تعتمد اللحظة الدقيقة التي يحدث فيها هذا على نهج التنفيذ.

لأغراض هذا المثال، يُرجى إعادة استخدام النشاط من الجولة التفصيلية السابقة، والتي يظهر فيها للطالب صورة لمعلم شهير ويُطلب منه إدخال اسمه. قم بتعيين درجات كاملة للمرفق إذا أدخل الطالب الاسم الصحيح، وصفر في الحالات الأخرى.

التعرّف على ميزة وضع الدرجات في واجهات برمجة التطبيقات لإضافات Classroom

يمكن لإضافتك ضبط كل من بسط الدرجة ومقام الدرجة لمرفق. ويتم ضبط هذه القيم على التوالي باستخدام القيمتَين pointsEarned وmaxPoints في واجهة برمجة التطبيقات. تعرض بطاقة المرفقات في واجهة مستخدم Classroom القيمة maxPoints عند ضبطها.

مثال على عدة مرفقات تحتوي على maxPoints
على مهمة واحدة

الشكل 1. واجهة المستخدم لإنشاء المهام الدراسية التي تحتوي على ثلاث بطاقات مرفقات إضافية تم ضبط maxPoints عليها.

تتيح لك واجهة برمجة التطبيقات للإضافات في Classroom ضبط الإعدادات الخاصة بدرجات المرفقات وضبط النتيجة التي تم الحصول عليها. وهي تختلف عن درجات المهام الدراسية. ومع ذلك، تتّبع إعدادات درجة المهام الدراسية إعدادات درجة المرفقات للمرفق الذي يتضمن التصنيف مزامنة الدرجات على بطاقة المرفق. عندما يضبط مرفق "مزامنة الدرجات" pointsEarned على المهمة التي أرسلها الطالب، يتم أيضًا ضبط الدرجة الأولية للطالب للمهمة.

يتلقّى عادةً المرفق الأول الذي تمت إضافته إلى المهمة التي تضبط "maxPoints" التصنيف "مزامنة الدرجات". اطّلع على مثال واجهة المستخدم لإنشاء المهمة المعروض في الشكل 1 للحصول على مثال على التصنيف "مزامنة الدرجات". لاحظ أن بطاقة "المرفق 1" تحتوي على التصنيف "مزامنة الدرجات" وأن درجة المهمة في المربع الأحمر قد تم تحديثها إلى 50 نقطة. لاحظ أيضًا أنه على الرغم من أن الشكل 1 يعرض ثلاث بطاقات مرفقات، فإن بطاقة واحدة فقط لها التصنيف "مزامنة الدرجات". ويشكّل ذلك قيدًا رئيسيًا لعملية التنفيذ الحالية: يمكن لمرفق واحد فقط أن يحمل التصنيف "مزامنة الدرجات".

في حال وجود عدة مرفقات تم ضبط السمة 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 في قاعدة بيانات المرفقات المحلية، ما يوفر الحاجة إلى إجراء طلب بيانات إضافي من واجهة برمجة التطبيقات في وقت لاحق عند وضع الدرجات على المهام المرسَلة من الطلاب. ومع ذلك، لاحظ أنه من الممكن أن يغيّر المعلمون إعدادات وضع درجات المهمة بشكل مستقل عن الإضافة. يمكنك إرسال طلب 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 يتطلّب نطاق teacher OAuth. يجب عدم منح نطاق teacher للمستخدمين من الطلاب، لأنّ ذلك قد يؤدي إلى حدوث سلوك غير متوقّع عند تفاعل الطلاب مع إضافتك، مثل تحميل إطار iframe لميزة "عرض المعلّمين" بدلاً من إطار iframe لعرض الطلاب. لذلك، لديك خياران لكيفية ضبط pointsEarned:

  • باستخدام بيانات اعتماد المعلّم الذي سجّل الدخول
  • باستخدام بيانات اعتماد المعلّم المخزّنة (بلا إنترنت)

تناقش الأقسام التالية المفاضلات لكل نهج قبل توضيح كل تنفيذ. تجدر الإشارة إلى أن الأمثلة المقدَّمة توضح كلا الأسلوبين لاجتياز درجة إلى Classroom، ويمكنك الاطّلاع على التعليمات الخاصة باللغة أدناه لمعرفة كيفية اختيار أسلوب عند تنفيذ الأمثلة المقدَّمة:

Python

ابحث عن بيان SET_GRADE_WITH_LOGGED_IN_USER_CREDENTIALS في أعلى ملف webapp/attachment_routes.py. يمكنك ضبط هذه القيمة على True لتمرير الدرجات باستخدام بيانات اعتماد المعلّم الذي سجّل الدخول. اضبط هذه القيمة على False لتمرير الدرجات باستخدام بيانات الاعتماد المخزّنة عندما يرسل الطالب النشاط.

ضبط الدرجات باستخدام بيانات اعتماد المعلّم الذي سجّل الدخول

استخدِم بيانات اعتماد المستخدم الذي سجَّل الدخول لإصدار الطلب لضبط pointsEarned. وهذا يجب أن يبدو بديهيًا إلى حد ما لأنه يعكس بقية التنفيذ حتى الآن، ويتطلب القليل من الجهد لإدراكه.

ومع ذلك، ضع في اعتبارك أنّ المعلّم يتفاعل فقط مع المحتوى الذي أرسله الطالب في إطار iframe لمراجعة عمل الطالب. وهذا له بعض الآثار المهمة:

  • لا تتم تعبئة أي درجات في Classroom حتى يتخذ المعلم إجراءً في واجهة مستخدم Classroom.
  • قد يضطر المعلم إلى فتح كل المهام التي أرسلها الطالب من أجل تعبئة جميع درجات الطلاب.
  • هناك تأخير قصير بين تلقي Classroom للدرجة وظهورها في واجهة مستخدم Classroom. يتراوح التأخير عادةً من خمس إلى عشر ثوانٍ، لكن يمكن أن يصل إلى 30 ثانية.

يعني الجمع بين هذه العوامل أنه قد يضطر المعلمون إلى إجراء عمل يدوي كبير ويستغرق وقتًا طويلاً لملء درجات الفصل بالكامل.

لتنفيذ هذا النهج، يمكنك إضافة طلب بيانات إضافي واحد من واجهة برمجة التطبيقات إلى مسار مراجعة عمل الطلاب الحالي.

بعد جلب المهام التي أرسلها الطالب وسجلات المرفقات، قم بتقييم تقديم الطالب وتخزين الدرجة الناتجة. حدِّد الدرجة في الحقل 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()

ضبط الدرجات باستخدام بيانات اعتماد المعلّم بلا إنترنت

تتطلب الطريقة الثانية لإعداد الدرجات استخدام بيانات الاعتماد المخزّنة للمعلّم الذي أنشأ المرفق. يتطلّب هذا التنفيذ إنشاء بيانات اعتماد باستخدام رموز الدخول وإعادة التحميل ورموز الدخول الخاصة بالمعلّم المعتمَد سابقًا، ثم استخدام بيانات الاعتماد هذه لضبط pointsEarned.

من أهم المزايا التي يوفّرها هذا المنهج أنّه تتم تعبئة الدرجات بدون الحاجة إلى اتّخاذ أي إجراء من المعلّمين في واجهة مستخدم Classroom، ما يؤدي إلى تجنُّب المشاكل المذكورة أعلاه. والنتيجة هي أن المستخدمين النهائيين يرون أن تجربة الدرجات سلسة وفعالة. بالإضافة إلى ذلك، يتيح لك هذا المنهج اختيار اللحظة التي تتراجع فيها عن الدرجات، مثل إكمال الطلاب للنشاط أو بشكل غير متزامن.

أكمل المهام التالية لتنفيذ هذا النهج:

  1. تعديل سجلات قاعدة بيانات المستخدم لتخزين رمز دخول
  2. قم بتعديل سجلات قاعدة بيانات المرفقات لتخزين معرّف مدرس.
  3. استرجع بيانات اعتماد المعلّم و (اختياريًا) أنشئ مثيلاً جديدًا لخدمة Classroom.
  4. ضبط درجة أحد المهام

لأغراض هذا العرض التوضيحي، حدد الدرجة التي يكمل فيها الطالب النشاط؛ أي عندما يرسل الطالب النموذج في مسار عرض الطالب.

تعديل سجلات قاعدة بيانات المستخدم لتخزين رمز الدخول المميز

يجب إدخال رمزَين مميزَين فريدَين لإجراء طلبات بيانات من واجهة برمجة التطبيقات، وهما الرمز المميّز لإعادة التحميل ورمز الدخول. إذا كنت قد اتّبعت الخطوات التفصيلية حتى الآن، من المفترض أن يخزِّن مخطّط جدول User رمزًا مميّزًا لإعادة التحميل. ويكفي تخزين الرمز المميّز للتحديث عند إجراء طلبات بيانات من واجهة برمجة التطبيقات مع المستخدم الذي سجّل الدخول فقط، حيث تتلقى رمز الدخول كجزء من عملية المصادقة.

ومع ذلك، تحتاج الآن إلى إجراء المكالمات كشخص آخر غير المستخدم الذي سجّل الدخول، مما يعني أن مسار المصادقة غير متاح. وبالتالي، تحتاج إلى تخزين رمز الدخول بجانب الرمز المميز للتحديث. يمكنك تعديل مخطط جدول 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 لعرض الطلاب. بعد تخزين رد الطالب في قاعدة البيانات المحلية مباشرةً، استرجع بيانات اعتماد المعلم من مساحة التخزين المحلية. ينبغي أن يكون هذا مباشرًا نظرًا للتحضير في الخطوتين السابقتين. يمكنك أيضًا استخدام هذه العناصر لإنشاء مثيل جديد لخدمة 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 لمراجعة عمل الطلاب. من المفترض أن ترى الدرجة تظهر في أوقات مختلفة حسب نهج التنفيذ الذي تتبعه:

  • إذا اخترت إرجاع درجة عندما يكمل الطالب النشاط، من المفترض أن ترى بالفعل درجته الأولية في واجهة المستخدم قبل فتح إطار iframe لمراجعة عمل الطالب. كما يمكنك الاطلاع عليه في قائمة الطلاب عند فتح المهمة، وفي مربع "الدرجة" بجوار إطار iframe لمراجعة عمل الطالب.
  • إذا اخترت إرجاع درجة عندما يفتح المعلم إطار iframe لمراجعة عمل الطالب، يجب أن تظهر الدرجة في مربع "الدرجة" بعد وقت قصير من تحميل iframe. كما ذكرنا أعلاه، يمكن أن يستغرق ذلك مدة تصل إلى 30 ثانية. بعد ذلك، يجب أن تظهر الدرجة للطالب المحدَّد أيضًا في طرق العرض الأخرى لدفتر العلامات في Classroom.

تأكَّد من ظهور الدرجة الصحيحة للطالب.

تهانينا! يمكنك الآن الانتقال إلى الخطوة التالية: إنشاء مرفقات خارج Google Classroom.