קבצים מצורפים מסוג פעילות

זהו המדריך החמישי בסדרת המדריכים בנושא תוספים ל-Classroom.

במדריך הזה, תשנו את הדוגמה מהשלב הקודם במדריך כדי ליצור קובץ מצורף מסוג פעילות. אלה קבצים מצורפים שדורשים הגשה של תלמיד, כמו תשובה כתובה, חידון או פריט מידע אחר שנוצר על ידי התלמיד.

חשוב להבחין בין קבצים מצורפים מסוג תוכן לבין קבצים מצורפים מסוג פעילות. ההבדלים בין קבצים מצורפים מסוג פעילות לבין קבצים מצורפים מסוג תוכן הם:

  • לחצן 'שליחה' מופיע בפינה השמאלית העליונה של ה-iframe של תצוגת התלמיד.
  • הם מספקים מזהה ייחודי לעבודת התלמידים.
  • כרטיס הקובץ המצורף שלהם יופיע בממשק המשתמש של כלי הציונים ב-Classroom.
  • הם יכולים להגדיר ציון למטלה שאליה הם משויכים.

במדריך הבא מוסבר על מתן ציונים. במהלך ההסבר המפורט הזה תבצעו את הפעולות הבאות:

  • משנים את בקשות היצירה הקודמות של קבצים מצורפים ל-Classroom API כדי ליצור קובץ מצורף מסוג פעילות.
  • הטמעת אחסון מתמיד להגשות של תלמידים.
  • לשנות את המסלול הקודם של תצוגת התלמיד כדי לקבל קלט מהתלמיד.
  • צריך לספק נתיב להצגת ה-iframe של הכלי לבדיקת עבודות של תלמידים.

אחרי שמסיימים, אפשר ליצור קבצים מצורפים מסוג פעילות במטלות דרך ממשק המשתמש של Google Classroom כשמחוברים בתור מורה. תלמידים בכיתה יכולים גם להשלים את הפעילות ב-iframe ולשלוח תשובה. המורה יכול לראות את העבודה שהתלמיד הגיש בממשק המשתמש למתן ציונים ב-Classroom.

לצורך הדוגמה הזו, נשתמש שוב בתבנית הקובץ המצורף מההסבר הקודם, שבה מוצגת תמונה של ציון דרך מפורסם וכיתוב עם שם ציון הדרך. הפעילות כוללת הנחיה לתלמיד לספק את שם ציון הדרך.

שינוי הבקשה ליצירת קובץ מצורף

עוברים לקטע בקוד שבו יצרתם קובץ מצורף עם סוג תוכן בהדרכה הקודמת. הפריט המרכזי כאן הוא מופע של אובייקט AddOnAttachment, שבו ציינו קודם את teacherViewUri, studentViewUri ו-title של הקובץ המצורף.

כל הקבצים המצורפים לתוספים צריכים לכלול את שלושת השדות האלה, אבל הנוכחות או ההיעדר של studentWorkReviewUri קובעים אם הקובץ המצורף הוא מסוג פעילות או מסוג תוכן. בקשת CREATE עם studentWorkReviewUri מלא הופכת לקובץ מצורף מסוג פעילות, ובקשת CREATE בלי studentWorkReviewUri הופכת לקובץ מצורף מסוג תוכן.

השינוי היחיד שצריך לבצע בבקשה הזו הוא מילוי השדה studentWorkReviewUri. מוסיפים כאן מסלול עם שם מתאים. מיישמים אותו בשלב מאוחר יותר.

Python

בדוגמה שסיפקנו, זה נמצא במתודה create_attachments בקובץ 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.
    # The presence of this field marks this as an activity-type attachment.
    "studentWorkReviewUri": {
        "uri":
            flask.url_for(
                "view_submission", _scheme='https', _external=True)
    },
    # The title of the attachment.
    "title": f"Attachment {attachment_count}",
}

הוספת אחסון מתמיד לקבצים מצורפים מסוג תוכן

להקליט את התשובה של התלמיד/ה לפעילות שלנו. אפשר לחפש אותו מאוחר יותר כשהמורה צופה בהגשה ב-iframe של הכלי לבדיקת עבודות של תלמידים.

הגדרה של סכימת מסד נתונים ל-Submission. בדוגמה שסיפקנו, התלמידים צריכים להזין את שם ציון הדרך שמופיע בתמונה. לכן, Submission כולל את המאפיינים הבאים:

  • attachment_id: מזהה ייחודי של קובץ מצורף. הערך הזה מוקצה על ידי Classroom ומוחזר בתגובה כשיוצרים קובץ מצורף.
  • submission_id: מזהה של עבודה שהוגשה על ידי תלמיד או תלמידה. הציון מוקצה על ידי Classroom ומוחזר בתגובה getAddOnContext בתצוגת התלמיד.
  • student_response: התשובה שסיפק התלמיד.

Python

מרחיבים את ההטמעה של SQLite ושל flask_sqlalchemy מהשלבים הקודמים.

עוברים לקובץ שבו הגדרתם את הטבלאות הקודמות (models.py אם אתם פועלים לפי הדוגמה שסיפקנו). מוסיפים את השורות הבאות לתחתית הקובץ.

# Database model to represent a student submission.
class Submission(db.Model):
    # The attachmentId is the unique identifier for the attachment.
    submission_id = db.Column(db.String(120), primary_key=True)

    # The unique identifier for the student's submission.
    attachment_id = db.Column(db.String(120), primary_key=True)

    # The student's response to the question prompt.
    student_response = db.Column(db.String(120))

מייבאים את הכיתה החדשה Submission לקובץ השרת עם נתיבי הטיפול בקבצים המצורפים.

שינוי הנתיב של התצוגה לתלמידים

בשלב הבא, משנים את המסלול הקודם של תצוגת התלמיד כדי להציג טופס קטן ולקבל קלט מהתלמיד. אפשר לעשות שימוש חוזר ברוב הקוד מההסבר המפורט הקודם.

מאתרים את קוד השרת שמספק את הנתיב לתצוגת התלמיד. זהו המסלול שמצוין בשדה studentViewUri כשיוצרים קובץ מצורף. השינוי הראשון שצריך לבצע הוא חילוץ של submissionId מהתשובה getAddOnContext.

Python

בדוגמה שסיפקנו, זה נמצא בשיטה load_activity_attachment בקובץ webapp/attachment_routes.py.

# Issue a request to the courseWork.getAddOnContext endpoint
addon_context_response = classroom_service.courses().courseWork(
).getAddOnContext(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"]).execute()

# One of studentContext or teacherContext will be populated.
user_context = "student" if addon_context_response.get(
    "studentContext") else "teacher"

# If the user is a student...
if user_context == "student":
    # Extract the submissionId from the studentContext object.
    # This value is provided by Google Classroom.
    flask.session["submissionId"] = addon_context_response.get(
            "studentContext").get("submissionId")

אפשר גם לשלוח בקשה כדי לקבל את סטטוס ההגשה של התלמיד. התשובה מכילה את הערך SubmissionState, שמציין מצבים כמו אם התלמיד פתח את הקובץ המצורף או הגיש אותו. האפשרות הזו יכולה להיות שימושית אם רוצים למנוע עריכה של מטלה שהוגשה, או אם רוצים לספק למורים תובנות לגבי ההתקדמות של התלמידים:

Python

בדוגמה שסיפקנו, מדובר בהמשך של המתודה load_activity_attachment שלמעלה.

# Issue a request to get the status of the student submission.
submission_response = classroom_service.courses().courseWork(
).addOnAttachments().studentSubmissions().get(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"],
    attachmentId=flask.session["attachmentId"],
    submissionId=flask.session["submissionId"]).execute()

לבסוף, מאחזרים את פרטי הקובץ המצורף מהמסד הנתונים ומציגים טופס קלט. הטופס בדוגמה שסיפקנו מורכב משדה להזנת קלט מחרוזת ומלחצן שליחה. מציגים את התמונה של ציון הדרך ומבקשים מהתלמיד/ה להזין את השם שלו. אחרי שהם מספקים תשובה, צריך לתעד אותה במסד הנתונים שלנו.

Python

בדוגמה שסיפקנו, מדובר בהמשך של המתודה load_activity_attachment שלמעלה.

# Look up the attachment in the database.
attachment = Attachment.query.get(flask.session["attachmentId"])

message_str = f"I see that you're a {user_context}! "
message_str += (
    f"I've loaded the attachment with ID {attachment.attachment_id}. "
    if user_context == "teacher" else
    "Please complete the activity below.")

form = activity_form_builder()

if form.validate_on_submit():
    # Record the student's response in our database.

    # Check if the student has already submitted a response.
    # If so, update the response stored in the database.
    student_submission = Submission.query.get(flask.session["submissionId"])

    if student_submission is not None:
        student_submission.student_response = form.student_response.data
    else:
        # Store the student's response by the submission ID.
        new_submission = Submission(
            submission_id=flask.session["submissionId"],
            attachment_id=flask.session["attachmentId"],
            student_response=form.student_response.data)
        db.session.add(new_submission)

    db.session.commit()

    return flask.render_template(
        "acknowledge-submission.html",
        message="Your response has been recorded. You can close the " \
            "iframe now.",
        instructions="Please Turn In your assignment if you have " \
            "completed all tasks."
    )

# Show the activity.
return flask.render_template(
    "show-activity-attachment.html",
    message=message_str,
    image_filename=attachment.image_filename,
    image_caption=attachment.image_caption,
    user_context=user_context,
    form=form,
    responses=response_strings)

כדי להבדיל בין משתמשים, כדאי להשבית את פונקציית השליחה ולהציג את התשובה הנכונה בתצוגת המורה.

הוספת נתיב ל-iframe של כלי לבדיקת עבודות תלמידים

לבסוף, מוסיפים נתיב להצגת ה-iframe של כלי לבדיקת עבודות של תלמידים. השם של המסלול הזה צריך להיות זהה לשם שצוין עבור studentWorkReviewUri כשיוצרים קובץ מצורף. הנתיב הזה נפתח כשהמורה צופה בעבודה שהתלמיד או התלמידה הגישו בממשק המשתמש של כלי הציונים ב-Classroom.

פרמטר השאילתה submissionId מתקבל כש-Classroom פותח את ה-iframe של הכלי לבדיקת עבודות של תלמידים. אפשר להשתמש בו כדי לאחזר את העבודה של התלמיד או התלמידה ממסד הנתונים המקומי:

Python

בדוגמה שסיפקנו, זה נמצא בקובץ webapp/attachment_routes.py.

@app.route("/view-submission")
def view_submission():
    """
    Render a student submission using the show-student-submission.html template.
    """

    # Save the query parameters passed to the iframe in the session, just as we did
    # in previous routes. Abbreviated here for readability.
    add_iframe_query_parameters_to_session(flask.request.args)

    # For the sake of brevity in this example, we'll skip the conditional logic
    # to see if we need to authorize the user as we have done in previous steps.
    # We can assume that the user that reaches this route is a teacher that has
    # already authorized and created an attachment using the add-on.

    # In production, we recommend fully validating the user's authorization at
    # this stage as well.

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

    # Render the student's response alongside the correct answer.
    return flask.render_template(
        "show-student-submission.html",
        message=f"Loaded submission {student_submission.submission_id} for "\
            f"attachment {attachment.attachment_id}.",
        student_response=student_submission.student_response,
        correct_answer=attachment.image_caption)

בדיקת התוסף

חוזרים על השלבים לבדיקת התוסף מההסבר המפורט הקודם. צריך להיות קובץ מצורף שהתלמיד או התלמידה יכולים לפתוח.

כדי לבדוק את הקובץ המצורף של הפעילות:

  • נכנסים ל-Google Classroom בתור אחד מחשבונות למטרות בדיקה של התלמידים באותה כיתה שבה נמצא חשבון למטרות בדיקה של המורה.
  • מנווטים לכרטיסייה סביבת הלמידה ומרחיבים את המטלה של המבחן.
  • לוחצים על כרטיס התוסף כדי לפתוח את תצוגת התלמיד ולשלוח תשובה לפעילות.
  • בסיום הפעילות, סוגרים את ה-iframe. אפשר גם ללחוץ על הלחצן שליחה.

אחרי שתשלימו את הפעילות, לא אמורים להיות שינויים ב-Classroom. עכשיו בודקים את ה-iframe של בדיקת עבודות של תלמידים:

  • נכנסים ל-Classroom בתור חשבון למטרות בדיקה teacher.
  • בכרטיסייה ציונים, מחפשים את העמודה של מטלת המבחן. לוחצים על השם של מטלת הבדיקה.
  • מאתרים את הכרטיס של משתמש התלמיד לבדיקה. לוחצים על הקובץ המצורף בכרטיס.

מוודאים שהעבודה הנכונה מופיעה לתלמיד/ה.

מעולה! אפשר לעבור לשלב הבא: סנכרון ציונים של קבצים מצורפים.