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

זהו המדריך החמישי בסדרת המדריכים בנושא תוספים ל-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 בתור משתמש הבדיקה מורה.
  • מוצאים את העמודה של מטלת הבחינה בכרטיסייה ציונים. לוחצים על השם של מטלת המבחן.
  • מאתרים את הכרטיס של משתמש התלמיד לבדיקה. לוחצים על הקובץ המצורף בכרטיס.

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

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