إدارة مهام الدورة الدراسية والدرجات

تتوافق واجهة مستخدم Classroom مع خمسة أنواع من الواجبات الدراسية: المهام الدراسية، ومهام الاختبار، والأسئلة ذات الإجابات القصيرة، والأسئلة متعددة الخيارات، والمواد. تتيح Classroom API حاليًا استخدام ثلاثة من هذه الأنواع، المعروفة باسم CourseWorkType لواجهة برمجة التطبيقات: المهام الدراسية، والأسئلة ذات الإجابات القصيرة، والأسئلة متعددة الخيارات.

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

بالإضافة إلى مورد CourseWork، يمكنك إدارة المهام المكتملة باستخدام مورد StudentSubmission. تصف الأقسام التالية هذه بمزيد من التفصيل.

إنشاء مهام

يمكن إنشاء المهام الدراسية فقط بالنيابة عن معلِّمي الدورة التدريبية، وسيؤدي محاولة إنشاء مهام في دورة تدريبية بالنيابة عن أحد الطلاب إلى حدوث الخطأ 403 PERMISSION_DENIED. وبالمثل، لا يمكن لمشرفي النطاق أيضًا إنشاء مهام للدورات التدريبية التي لا يعلمونها، وسيؤدي محاولة إجراء ذلك من خلال واجهة برمجة التطبيقات إلى ظهور خطأ 403 PERMISSION_DENIED.

عند إنشاء مهام باستخدام طريقة courses.courseWork.create، يمكنك إرفاق الروابط بتنسيق materials، كما هو موضّح في الرمز النموذجي أدناه:

Java

classroom/snippets/src/main/java/CreateCourseWork.java
CourseWork courseWork = null;
try {
  // Create a link to add as a material on course work.
  Link articleLink =
      new Link()
          .setTitle("SR-71 Blackbird")
          .setUrl("https://www.lockheedmartin.com/en-us/news/features/history/blackbird.html");

  // Create a list of Materials to add to course work.
  List<Material> materials = Arrays.asList(new Material().setLink(articleLink));

  /* Create new CourseWork object with the material attached.
  Set workType to `ASSIGNMENT`. Possible values of workType can be found here:
  https://developers.google.com/classroom/reference/rest/v1/CourseWorkType
  Set state to `PUBLISHED`. Possible values of state can be found here:
  https://developers.google.com/classroom/reference/rest/v1/courses.courseWork#courseworkstate */
  CourseWork content =
      new CourseWork()
          .setTitle("Supersonic aviation")
          .setDescription(
              "Read about how the SR-71 Blackbird, the world’s fastest and "
                  + "highest-flying manned aircraft, was built.")
          .setMaterials(materials)
          .setWorkType("ASSIGNMENT")
          .setState("PUBLISHED");

  courseWork = service.courses().courseWork().create(courseId, content).execute();

  /* Prints the created courseWork. */
  System.out.printf("CourseWork created: %s\n", courseWork.getTitle());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf("The courseId does not exist: %s.\n", courseId);
  } else {
    throw e;
  }
  throw e;
} catch (Exception e) {
  throw e;
}
return courseWork;

Python

Classroom/snippets/classroom_create_coursework.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_create_coursework(course_id):
  """
  Creates the coursework the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member

  try:
    service = build("classroom", "v1", credentials=creds)
    coursework = {
        "title": "Ant colonies",
        "description": """Read the article about ant colonies
                              and complete the quiz.""",
        "materials": [
            {"link": {"url": "http://example.com/ant-colonies"}},
            {"link": {"url": "http://example.com/ant-quiz"}},
        ],
        "workType": "ASSIGNMENT",
        "state": "PUBLISHED",
    }
    coursework = (
        service.courses()
        .courseWork()
        .create(courseId=course_id, body=coursework)
        .execute()
    )
    print(f"Assignment created with ID {coursework.get('id')}")
    return coursework

  except HttpError as error:
    print(f"An error occurred: {error}")
    return error


if __name__ == "__main__":
  # Put the course_id of course whose coursework needs to be created,
  # the user has access to.
  classroom_create_coursework(453686957652)

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

لتضمين المواد المرتبطة في مهمة تم إنشاؤها عبر Classroom API، استخدِم مرجع رابط، مع تحديد عنوان URL المستهدف. تجلب خدمة Classroom العنوان والصورة المصغّرة تلقائيًا. تتوافق واجهة برمجة التطبيقات Classroom API في الأساس مع Google Drive ومواد YouTube، والتي يمكن تضمينها مع مورد DriveFile أو مورد YouTubeVideo بطريقة مماثلة.

لتحديد تاريخ تسليم، اضبط الحقلَين dueDate وdueTime على التوقيت العالمي المنسَّق (UTC) المقابل. يجب أن يكون تاريخ التسليم في المستقبل.

استرداد المهام والأسئلة

يمكنك استرداد المهام والأسئلة للطلاب والمعلمين في الدورة التدريبية المقابلة أو من قبل مشرف النطاق. لاسترداد مهمة أو سؤال معين، استخدم courses.courseWork.get. لاسترداد جميع المهام أو الأسئلة (تتطابق مع بعض المعايير اختياريًا)، استخدم courses.courseWork.list.

يعتمد النطاق المطلوب على دور المستخدم الذي قدّم الطلب في الدورة. إذا كان المستخدم طالبًا، استخدِم أحد النطاقات التالية:

  • https://www.googleapis.com/auth/classroom.coursework.me.readonly
  • https://www.googleapis.com/auth/classroom.coursework.me

إذا كان المستخدم مدرسًا أو مشرف نطاق، استخدِم أحد النطاقات التالية:

  • https://www.googleapis.com/auth/classroom.coursework.students.readonly
  • https://www.googleapis.com/auth/classroom.coursework.students

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

إدارة ردود الطلاب

يمثل مورد StudentSubmission العمل المنجز ودرجة الطالب في مَهمة دراسية أو سؤال. يتم إنشاء مورد StudentSubmission بشكل ضمني لكل طالب عند إنشاء سؤال أو مهمة جديدة.

توضّح الأقسام التالية الإجراءات الشائعة التي تدير ردود الطلاب.

استرداد إجابات الطلاب

يمكن للطلاب استرداد المهام الدراسية التابعة لهم، كما يمكن للمعلمين استرداد عمليات الإرسال لجميع الطلاب في دوراتهم التدريبية، ويمكن لمشرفي النطاق استرداد جميع عمليات الإرسال لجميع الطلاب في نطاقهم. يتم تخصيص معرّف لكل عملية إرسال من الطالب، وإذا كنت تعرف المعرّف، يمكنك استخدام courses.courseWork.studentSubmissions.get لاسترداده.

استخدِم طريقة courses.courseWork.studentSubmissions.list للحصول على موارد StudentSubmission تتطابق مع بعض المعايير، كما هو موضّح في العيّنة التالية:

Java

classroom/snippets/src/main/java/ListSubmissions.java
List<StudentSubmission> studentSubmissions = new ArrayList<>();
String pageToken = null;

try {
  do {
    ListStudentSubmissionsResponse response =
        service
            .courses()
            .courseWork()
            .studentSubmissions()
            .list(courseId, courseWorkId)
            .setPageToken(pageToken)
            .execute();

    /* Ensure that the response is not null before retrieving data from it to avoid errors. */
    if (response.getStudentSubmissions() != null) {
      studentSubmissions.addAll(response.getStudentSubmissions());
      pageToken = response.getNextPageToken();
    }
  } while (pageToken != null);

  if (studentSubmissions.isEmpty()) {
    System.out.println("No student submission found.");
  } else {
    for (StudentSubmission submission : studentSubmissions) {
      System.out.printf(
          "Student id (%s), student submission id (%s)\n",
          submission.getUserId(), submission.getId());
    }
  }
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s) or courseWorkId (%s) does not exist.\n", courseId, courseWorkId);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmissions;

Python

Classroom/snippets/classroom_list_submissions.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_list_submissions(course_id, coursework_id):
  """
  Creates the courses the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  submissions = []
  page_token = None

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      response = (
          coursework.studentSubmissions()
          .list(
              pageToken=page_token,
              courseId=course_id,
              courseWorkId=coursework_id,
              pageSize=10,
          )
          .execute()
      )
      submissions.extend(response.get("studentSubmissions", []))
      page_token = response.get("nextPageToken", None)
      if not page_token:
        break

    if not submissions:
      print("No student submissions found.")

    print("Student Submissions:")
    for submission in submissions:
      print(
          "Submitted at:"
          f"{(submission.get('id'), submission.get('creationTime'))}"
      )

  except HttpError as error:
    print(f"An error occurred: {error}")
    submissions = None
  return submissions


if __name__ == "__main__":
  # Put the course_id and coursework_id of course whose list needs to be
  # submitted.
  classroom_list_submissions(453686957652, 466086979658)

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

Java

classroom/snippets/src/main/java/ListStudentSubmissions.java
List<StudentSubmission> studentSubmissions = new ArrayList<>();
String pageToken = null;

try {
  do {
    // Set the userId as a query parameter on the request.
    ListStudentSubmissionsResponse response =
        service
            .courses()
            .courseWork()
            .studentSubmissions()
            .list(courseId, courseWorkId)
            .setPageToken(pageToken)
            .set("userId", userId)
            .execute();

    /* Ensure that the response is not null before retrieving data from it to avoid errors. */
    if (response.getStudentSubmissions() != null) {
      studentSubmissions.addAll(response.getStudentSubmissions());
      pageToken = response.getNextPageToken();
    }
  } while (pageToken != null);

  if (studentSubmissions.isEmpty()) {
    System.out.println("No student submission found.");
  } else {
    for (StudentSubmission submission : studentSubmissions) {
      System.out.printf("Student submission: %s.\n", submission.getId());
    }
  }

Python

classroom/snippets/classroom_list_student_submissions.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_list_student_submissions(course_id, coursework_id, user_id):
  """
  Creates the courses the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  submissions = []
  page_token = None

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      response = (
          coursework.studentSubmissions()
          .list(
              pageToken=page_token,
              courseId=course_id,
              courseWorkId=coursework_id,
              userId=user_id,
          )
          .execute()
      )
      submissions.extend(response.get("studentSubmissions", []))
      page_token = response.get("nextPageToken", None)
      if not page_token:
        break

    if not submissions:
      print("No student submissions found.")

    print("Student Submissions:")
    for submission in submissions:
      print(
          "Submitted at:"
          f"{(submission.get('id'), submission.get('creationTime'))}"
      )

  except HttpError as error:
    print(f"An error occurred: {error}")
  return submissions


if __name__ == "__main__":
  # Put the course_id, coursework_id and user_id of course whose list needs
  # to be submitted.
  classroom_list_student_submissions(453686957652, 466086979658, "me")

يتم تحديد الطلاب من خلال المعرّف الفريد أو عنوان البريد الإلكتروني الفريد للمستخدم، على النحو الذي يتم إرجاعه من خلال حزمة تطوير البرامج (SDK) لوحدة تحكُّم المشرف في Google. قد يشير المستخدم الحالي أيضًا إلى رقم تعريفه باستخدام الاختصار "me".

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

Java

service.courses().courseWork().studentSubmissions()
    .list(courseId, "-")
    .set("userId", userId)
    .execute();

Python

service.courses().courseWork().studentSubmissions().list(
    courseId=<course ID or alias>,
    courseWorkId='-',
    userId=<user ID>).execute()

يعتمد النطاق المطلوب على دور المستخدم الذي قدّم الطلب في الدورة. استخدِم النطاق التالي إذا كان المستخدم معلِّمًا أو مشرفًا في نطاق:

  • https://www.googleapis.com/auth/classroom.coursework.students.readonly
  • https://www.googleapis.com/auth/classroom.coursework.students

يمكنك استخدام النطاق التالي إذا كان المستخدم طالبًا:

  • https://www.googleapis.com/auth/classroom.coursework.me.readonly
  • https://www.googleapis.com/auth/classroom.coursework.me

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

إضافة مرفقات إلى ردّ الطالب

يمكنك إرفاق روابط إلى عناصر أرسلها الطالب من خلال إرفاق مورد Link أو DriveFile أو YouTubeVideo. يتم ذلك باستخدام courses.courseWork.studentSubmissions.modifyAttachments، كما هو موضح في النموذج التالي:

Java

classroom/snippets/src/main/java/ModifyAttachmentsStudentSubmission.java
StudentSubmission studentSubmission = null;
try {
  // Create ModifyAttachmentRequest object that includes a new attachment with a link.
  Link link = new Link().setUrl("https://en.wikipedia.org/wiki/Irrational_number");
  Attachment attachment = new Attachment().setLink(link);
  ModifyAttachmentsRequest modifyAttachmentsRequest =
      new ModifyAttachmentsRequest().setAddAttachments(Arrays.asList(attachment));

  // The modified studentSubmission object is returned with the new attachment added to it.
  studentSubmission =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .modifyAttachments(courseId, courseWorkId, id, modifyAttachmentsRequest)
          .execute();

  /* Prints the modified student submission. */
  System.out.printf(
      "Modified student submission attachments: '%s'.\n",
      studentSubmission.getAssignmentSubmission().getAttachments());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s), courseWorkId (%s), or studentSubmissionId (%s) does "
            + "not exist.\n",
        courseId, courseWorkId, id);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmission;

Python

Classroom/snippets/classroom_add_attachment.py
def classroom_add_attachment(course_id, coursework_id, submission_id):
  """
  Adds attachment to existing course with specific course_id.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  request = {
      "addAttachments": [
          {"link": {"url": "http://example.com/quiz-results"}},
          {"link": {"url": "http://example.com/quiz-reading"}},
      ]
  }

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      coursework.studentSubmissions().modifyAttachments(
          courseId=course_id,
          courseWorkId=coursework_id,
          id=submission_id,
          body=request,
      ).execute()

  except HttpError as error:
    print(f"An error occurred: {error}")


if __name__ == "__main__":
  # Put the course_id, coursework_id and submission_id of course in which
  # attachment needs to be added.
  classroom_add_attachment("course_id", "coursework_id", "me")

يتم تحديد مرفق الرابط من خلال عنوان URL المستهدف، وستعمل خدمة Classroom تلقائيًا على جلب العنوان والصورة المصغّرة. يمكنك التعرف على المواد الأخرى في الصفحات المرجعية الخاصة بها.

لا يمكن تعديل StudentSubmission إلا من قِبل معلِّم الدورة التدريبية أو الطالب الذي يملكه. لا يمكنك إرفاق Materials إلا إذا كانت قيمة CourseWorkType التي أرسلها الطالب هي ASSIGNMENT.

يعتمد النطاق المطلوب على دور المستخدم الذي قدّم الطلب في الدورة. يمكنك استخدام النطاق التالي إذا كان المستخدم مُعلّمًا:

  • https://www.googleapis.com/auth/classroom.coursework.students

يمكنك استخدام النطاق التالي إذا كان المستخدم طالبًا:

  • https://www.googleapis.com/auth/classroom.coursework.me

إدارة حالة استجابة الطالب

قد يتم إلغاء إرسال ردّ الطالب أو تسليمه أو إرجاعه. حقل الولاية في StudentSubmission يشير إلى الحالة الحالية. لتغيير الحالة، يمكنك استدعاء إحدى الطرق التالية:

تستغرق كل هذه الطرق نصًا فارغًا. مثال:

Java

classroom/snippets/src/main/java/ReturnStudentSubmission.java
try {
  service
      .courses()
      .courseWork()
      .studentSubmissions()
      .classroomReturn(courseId, courseWorkId, id, null)
      .execute();
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s), courseWorkId (%s), or studentSubmissionId (%s) does "
            + "not exist.\n",
        courseId, courseWorkId, id);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}

Python

service.courses().courseWork().studentSubmission().turnIn(
    courseId=<course ID or alias>,
    courseWorkId=<courseWork ID>,
    id=<studentSubmission ID>,
    body={}).execute()

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

ردود الطلاب

يتضمن المورد StudentSubmission حقلين لتخزين الدرجات: assignedGrade، وهو الدرجة التي يتم إبلاغ الطلاب بها، وdraftGrade، وهو صف مبدئي مرئي للمعلّمين فقط. يتم تعديل هذه الحقول باستخدام courses.courseWork.studentSubmissions.patch مع إضافة قناع حقل يحتوي على الحقول المناسبة، كما هو موضَّح في النموذج التالي.

Java

classroom/snippets/src/main/java/PatchStudentSubmission.java
StudentSubmission studentSubmission = null;
try {
  // Updating the draftGrade and assignedGrade fields for the specific student submission.
  StudentSubmission content =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .get(courseId, courseWorkId, id)
          .execute();
  content.setAssignedGrade(90.00);
  content.setDraftGrade(80.00);

  // The updated studentSubmission object is returned with the new draftGrade and assignedGrade.
  studentSubmission =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .patch(courseId, courseWorkId, id, content)
          .set("updateMask", "draftGrade,assignedGrade")
          .execute();

  /* Prints the updated student submission. */
  System.out.printf(
      "Updated student submission draft grade (%s) and assigned grade (%s).\n",
      studentSubmission.getDraftGrade(), studentSubmission.getAssignedGrade());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s), courseWorkId (%s), or studentSubmissionId (%s) does "
            + "not exist.\n",
        courseId, courseWorkId, id);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmission;

Python

studentSubmission = {
  'assignedGrade': 99,
  'draftGrade': 80
}
service.courses().courseWork().studentSubmissions().patch(
    courseId=<course ID or alias>,
    courseWorkId=<courseWork ID>,
    id=<studentSubmission ID>,
    updateMask='assignedGrade,draftGrade',
    body=studentSubmission).execute()

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

  • تخصيص draftGrade فقط. وهذا مفيد، على سبيل المثال، السماح للمعلم بمراجعة الدرجات يدويًا قبل الانتهاء منها. لا يمكن للطلاب الاطّلاع على الدرجات الأولية.

  • يمكنك تعيين كل من draftGrade وassignedGrade لوضع الدرجات على إحدى المهام الدراسية بالكامل.

إدراج الدرجات التي تم تخصيصها

يمكنك إدراج جميع الدرجات لعنصر معيّن من مهام الدورة الدراسية من خلال الاطّلاع على كائن الاستجابة لطريقة courses.courseWork.studentSubmissions.list:

Java

classroom/snippets/src/main/java/ListStudentSubmissions.java
  ListStudentSubmissionsResponse response =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .list(courseId, courseWorkId)
          .setPageToken(pageToken)
          .execute();

  /* Ensure that the response is not null before retrieving data from it to avoid errors. */
  if (response.getStudentSubmissions() != null) {
    studentSubmissions.addAll(response.getStudentSubmissions());
    pageToken = response.getNextPageToken();
  }
} while (pageToken != null);

if (studentSubmissions.isEmpty()) {
  System.out.println("No student submissions found.");
} else {
  for (StudentSubmission submission : studentSubmissions) {
    System.out.printf(
        "User ID %s, Assigned grade: %s\n",
        submission.getUserId(), submission.getAssignedGrade());
  }
}

Python

response = coursework.studentSubmissions().list(
    courseId=course_id,
    courseWorkId=coursework_id,
    pageSize=10).execute()
submissions.extend(response.get('studentSubmissions', []))

if not submissions:
    print('No student submissions found.')

print('Student Submissions:')
for submission in submissions:
    print(f"Submitted at:"
          f"{(submission.get('userId'), submission.get('assignedGrade'))}")