پیوست های نوع فعالیت

این پنجمین راهنمای گام به گام از مجموعه راهنمای افزونه‌های Classroom است.

در این راهنمای گام به گام، شما مثال گام قبلی را اصلاح می‌کنید تا یک پیوست از نوع فعالیت ایجاد کنید. این پیوست‌ها شامل هرگونه پیوستی هستند که نیاز به ارسال توسط دانش‌آموز دارند، مانند پاسخ کتبی، آزمون یا سایر مصنوعات تولید شده توسط دانش‌آموز.

تمایز بین پیوست‌های نوع محتوا و نوع فعالیت مهم است. پیوست‌های نوع فعالیت از نظر موارد زیر با نوع محتوا متفاوت هستند:

  • دکمه‌ی «ورود» در سمت راست بالای iframe نمای دانش‌آموز ظاهر می‌شود.
  • آنها یک شناسه منحصر به فرد برای کار دانش آموزان ارائه می دهند.
  • کارت پیوست آنها در رابط کاربری کلاس درس نمایش داده می‌شود.
  • آنها می‌توانند برای تکلیفی که به آن تعلق دارند، نمره تعیین کنند.

برای بحث در مورد درجه‌بندی، به راهنمای بعدی مراجعه کنید. در طول این راهنما، موارد زیر را تکمیل می‌کنید:

  • درخواست‌های قبلی ایجاد پیوست به Classroom API را برای ایجاد یک پیوست از نوع فعالیت تغییر دهید.
  • پیاده‌سازی فضای ذخیره‌سازی پایدار برای مطالب ارسالی دانشجویان.
  • مسیر قبلی Student View را برای پذیرش ورودی دانشجو تغییر دهید.
  • مسیری برای ارائه iframe مربوط به بررسی کار دانش‌آموز ارائه دهید.

پس از اتمام، می‌توانید از طریق رابط کاربری Google Classroom و هنگام ورود به سیستم به عنوان معلم، پیوست‌هایی از نوع فعالیت را برای تکالیف ایجاد کنید. دانش‌آموزان کلاس نیز می‌توانند فعالیت را در iframe انجام داده و پاسخی ارسال کنند. معلم می‌تواند ارسال دانش‌آموز را در رابط کاربری نمره‌دهی Classroom مشاهده کند.

برای اهداف این مثال، از الگوی پیوست از راهنمای قبلی که تصویری از یک بنای تاریخی معروف و شرحی با نام آن بنا را نشان می‌دهد، دوباره استفاده کنید. فعالیت شامل وادار کردن دانش‌آموز به ارائه نام آن بنا است.

درخواست ایجاد پیوست را اصلاح کنید

به بخشی از کد خود که در راهنمای قبلی یک پیوست از نوع محتوا ایجاد کرده‌اید، بروید. مورد کلیدی در اینجا نمونه‌ای از شیء AddOnAttachment است که در آن قبلاً teacherViewUri ، studentViewUri و title برای پیوست مشخص کرده‌ایم.

در حالی که همه پیوست‌های افزونه به این سه فیلد نیاز دارند، وجود یا عدم وجود studentWorkReviewUri تعیین می‌کند که آیا پیوست از نوع فعالیت است یا محتوا. یک درخواست CREATE با studentWorkReviewUri پر شده، به یک پیوست از نوع فعالیت تبدیل می‌شود، در حالی که یک درخواست CREATE بدون studentWorkReviewUri به یک پیوست از نوع محتوا تبدیل می‌شود.

تنها تغییری که باید در این درخواست ایجاد شود، پر کردن فیلد studentWorkReviewUri است. یک مسیر با نام مناسب اینجا اضافه کنید؛ آن را در مرحله بعد پیاده‌سازی خواهید کرد.

پایتون

در مثال ارائه شده ما، این در متد 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 : پاسخی که توسط دانشجو ارائه شده است.

پایتون

پیاده‌سازی 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 جدید را به همراه مسیرهای مدیریت پیوست خود در فایل سرور وارد کنید.

مسیر نمای دانش‌آموز را تغییر دهید

در مرحله بعد، مسیر قبلی Student View را تغییر دهید تا یک فرم کوچک نمایش داده شود و ورودی را از دانش‌آموز بپذیرد. می‌توانید از بیشتر کدهای راهنمای قبلی دوباره استفاده کنید.

کد سروری که مسیر نمای دانشجویی شما را فراهم می‌کند، پیدا کنید. این همان مسیری است که هنگام ایجاد پیوست در فیلد studentViewUri مشخص شده است. اولین تغییری که باید ایجاد کنید، استخراج submissionId از پاسخ getAddOnContext است.

پایتون

در مثال ارائه شده ما، این در متد 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 است که نشان دهنده حالت‌هایی مانند باز کردن یا تحویل دادن پیوست توسط دانشجو است. این می‌تواند در صورتی مفید باشد که بخواهید ویرایش‌های یک فایل ارسالی را غیرفعال کنید، یا اگر علاقه‌مند به ارائه بینش به معلم در مورد پیشرفت دانش‌آموزان خود هستید:

پایتون

در مثال ارائه شده ما، این ادامه متد 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()

در نهایت، اطلاعات پیوست را از پایگاه داده خود دریافت کرده و یک فرم ورودی ارائه دهید. فرم در مثال ارائه شده ما شامل یک فیلد ورودی رشته‌ای و یک دکمه ارسال است. تصویر برجسته را نشان دهید و از دانش‌آموز بخواهید نام خود را وارد کند. پس از ارائه پاسخ، آن را در پایگاه داده ما ثبت کنید.

پایتون

در مثال ارائه شده ما، این ادامه متد 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 ارائه شده است، مطابقت داشته باشد. این مسیر زمانی باز می‌شود که معلم، کار ارسالی دانش‌آموز را در رابط کاربری کلاس درس مشاهده کند.

شما پارامتر کوئری submissionId را زمانی دریافت می‌کنید که Classroom، iframe مربوط به بررسی کار دانش‌آموز را باز کند. از آن برای بازیابی کار دانش‌آموز از پایگاه داده محلی خود استفاده کنید:

پایتون

در مثال ارائه شده ما، این در فایل 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 را ببندید. در صورت تمایل، روی دکمه‌ی «ورود» کلیک کنید.

بعد از انجام فعالیت، نباید هیچ تغییری در کلاس درس ببینید. حالا iframe مربوط به بررسی کار دانش‌آموز را امتحان کنید:

  • به عنوان کاربر آزمون معلم وارد کلاس درس شوید.
  • ستون مربوط به تکلیف آزمون خود را در برگه نمرات پیدا کنید. روی نام تکلیف آزمون خود کلیک کنید.
  • کارت مربوط به کاربر دانشجوی آزمایشی را پیدا کنید. روی پیوست روی کارت کلیک کنید.

تأیید کنید که فرم ارسالی صحیح برای دانش‌آموز نمایش داده شده است.

تبریک می‌گوییم! شما آماده‌اید تا به مرحله بعدی بروید: همگام‌سازی نمرات پیوست .