Oceny załączników i przebieg zwrotny

Oto szósty przewodnik po dodatkach do Classroom. które zrecenzować w naszym serwisie.

W tym przewodniku zmodyfikujesz przykład z poprzedniego kroku przewodnika aby utworzyć załącznik typu aktywności z oceną. Dodatkowo zdasz ocenę. do Google Classroom, która jest widoczna w ocenie nauczyciela. zapisz je jako ocenę roboczą.

Przewodnik nieco się różni od innych w tej serii tym, przedstawiają dwa sposoby przekazywania ocen Classroom. Każda z nich wpływa w różny sposób na dewelopera i użytkownika. doświadczenia; weź pod uwagę je podczas projektowania dodatku do Classroom. Więcej informacji na ten temat znajdziesz na stronie Korzystanie z załączników. oraz opcje implementacji.

Pamiętaj, że funkcje oceniania w interfejsie API są opcjonalne. Można ich używać z: załącznik typu działania.

W tym przewodniku wykonasz te czynności:

  • Zmodyfikuj poprzednie żądania utworzenia załączników do interfejsu API Classroom do ustawiania mianownika ocen załącznika.
  • Programowo oceniaj zadania przesłane przez uczniów i ustawiaj wartości załączników. licznika ocen.
  • Zastosuj 2 sposoby, aby zdać ocenę projektu. Classroom przy użyciu zalogowanych lub offline danych logowania nauczyciela.

Gdy skończysz, oceny pojawią się w dzienniku ocen Classroom po jest wyzwalane zachowanie przebiegu zwrotnego. Dokładny moment zależy od metody wdrażania.

Na potrzeby tego przykładu wykorzystaj ponownie aktywność z poprzedniej przewodnik, w którym uczeń pokazuje obraz znanego punktu orientacyjnego. pojawi się prośba o podanie nazwy. Przypisz pełne oceny do załącznika, jeśli uczeń wpisujesz prawidłową nazwę. W przeciwnym razie zostanie wpisana wartość zero.

Informacje o funkcji oceniania dodatków w interfejsie API dodatków w Classroom

Dodatek może ustawić zarówno licznik, jak i mianownik ocen dla załącznik. Są one ustawiane odpowiednio za pomocą funkcji pointsEarned i maxPoints w interfejsie API. Karta załącznika w interfejsie Classroom pokazuje: ustaw wartość maxPoints.

Przykład wielu załączników z atrybutem maxPoints w jednym z nich
przypisanie udziału w konwersji

Rysunek 1. interfejs tworzenia projektów, z 3 kartami załączników dodatków, Ustawiono maxPoints.

Interfejs API dodatków w Classroom pozwala skonfigurować ustawienia wynik uzyskany za oceny załączników. To nie to samo co projekt. Ustawienia ocen za projekt są jednak zgodne z ustawienia oceny załącznika, który ma włączoną etykietę Synchronizacja ocen. jej kartę załącznika. Kiedy „Synchronizacja ocen” załącznik ustawia pointsEarned dla przesłania projektu przez ucznia, ale ustawia też ocenę roboczą za ten projekt.

Zazwyczaj pierwszy załącznik dodany do projektu ustawia maxPoints otrzymuje funkcję „Synchronizacja ocen” . Zobacz interfejs tworzenia projektów na Rys. 1 można zobaczyć przykład funkcji „Synchronizacja ocen” . Pamiętaj, że „Załącznik 1” na karcie jest „Synchronizacja ocen”. i że projekt ocenia, w czerwonym polu został zmieniony na 50 punktów. Mimo że rys. 1 widać 3 karty załączników, tylko jedna ma opcję „Synchronizacja ocen”. . To jest Kluczowe ograniczenie obecnej implementacji: tylko jeden załącznik może mieć ekran „Synchronizacja ocen” etykieta.

Jeśli istnieje wiele załączników, w których ustawiono atrybut maxPoints, usuń załącznik z funkcją „Synchronizacja ocen” nie włącza „synchronizacji ocen”. na dowolnym pozostałe załączniki. Dodanie kolejnego przyłącza, który ustawia ustawienie maxPoints umożliwia synchronizacji ocen za nowy załącznik, a maksymalna ocena za projekt będzie zmieniana na wartość dopasowania. Nie ma mechanizmu automatycznego sprawdzania, który załącznik ma „Synchronizacja ocen” etykiety ani liczby załączników do projektu.

Ustawianie maksymalnej oceny załącznika

W tej sekcji opisano ustawianie mianownika oceny załącznika. które jest to maksymalny możliwy wynik, jaki wszyscy uczniowie mogą osiągnąć przesłanych treści. Aby to zrobić, ustaw wartość maxPoints załącznika.

Wymagana jest tylko niewielka zmiana w obecnej implementacji, funkcje oceniania. Podczas tworzenia załącznika dodaj wartość maxPoints w: ten sam obiekt AddOnAttachment, który zawiera studentWorkReviewUri, teacherViewUri i inne pola załączników.

Pamiętaj, że domyślna maksymalna liczba punktów dla nowego projektu to 100. Sugerujemy ustawiając maxPoints na wartość inną niż 100, aby można było sprawdzić, czy oceny są ustawiane prawidłowo. Ustaw maxPoints na 50 w ramach demonstracji:

Python

Podczas tworzenia obiektu attachment dodaj pole maxPoints, po prostu przed wysłaniem prośby CREATE do courses.courseWork.addOnAttachments punkt końcowy. Znajdziesz go w webapp/attachment_routes.py, jeśli korzystasz z podanego przykładu.

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}",
}

Na potrzeby tej prezentacji wartość maxPoints zapisuje się również w lokalną bazę danych załączników; w ten sposób unikniesz konieczności dodatkowego wywołania interfejsu API podczas oceniania prac uczniów. Pamiętaj jednak, że jest możliwe, nauczyciele mogą zmieniać ustawienia ocen za projekt niezależnie od Twojego dodatku. Wyślij żądanie GET do punktu końcowego courses.courseWork, aby wyświetlić wartość maxPoints na poziomie przypisania. Aby to zrobić, przekaż itemId w CourseWork.id.

Teraz zaktualizuj model bazy danych, tak aby zawierał także wartość maxPoints załącznika. Zalecamy użycie wartości maxPoints z odpowiedzi CREATE:

Python

Najpierw dodaj pole max_points do tabeli Attachment. Znajdziesz to w pliku webapp/models.py, jeśli korzystasz z podanego przez nas przykładu.

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

Wróć do żądania courses.courseWork.addOnAttachments CREATE. Sklep wartość maxPoints zwrócona w odpowiedzi.

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

Załącznik ma teraz maksymalną ocenę. Powinniście być w stanie przetestować to zachowanie teraz; dodaj załącznik do nowego projektu. Zobaczysz też, że karta załącznika w którym jest wyświetlana funkcja synchronizacji ocen. etykieta i „Punkty” projektu zmian wartości.

Ustawianie oceny przesłanej przez ucznia w Classroom

W tej sekcji opisano ustawianie licznika do oceny załącznika. czyli ocenę poszczególnych uczniów związaną z załącznikiem. Aby to zrobić, ustaw ucznia wartości pointsEarned przesyłania.

Teraz musisz podjąć ważną decyzję: jak Twój dodatek powinien prosić o ustawienie: pointsEarned?

Problem polega na tym, że ustawienie pointsEarned wymaga zakresu protokołu OAuth teacher. Nie przyznawaj użytkownikom zakresu teacher. może to spowodować nieoczekiwane zachowanie uczniów podczas korzystania z dodatku, takie jak wczytywanie Element iframe widoku nauczyciela zamiast elementu iframe widoku ucznia. W związku z tym masz 2 opcje konfiguracji pointsEarned:

  • za pomocą danych logowania zalogowanego nauczyciela.
  • Korzystanie z zapisanych danych logowania nauczyciela (offline).

W sekcjach poniżej omówiono wady poszczególnych metod zademonstrowanie każdej implementacji. Zaprezentowane przez nas przykłady pokazują, oba sposoby na zaliczenie oceny w Classroom; zobacz instrukcje dla poszczególnych języków, aby dowiedzieć się, jak wybrać metodę, gdy z podanymi przykładami:

Python

Na górze znajdź deklarację SET_GRADE_WITH_LOGGED_IN_USER_CREDENTIALS. z webapp/attachment_routes.py pliku. Ustaw tę wartość na True, aby przekazać ją z powrotem ocen z użyciem danych logowania zalogowanego nauczyciela. Ustaw tę wartość na False przekazywać oceny przy użyciu zapisanych danych logowania, gdy uczeń przesyła działania.

Wyznaczanie ocen za pomocą danych logowania zalogowanego nauczyciela

Użyj danych logowania zalogowanego użytkownika, aby wysłać prośbę o ustawienie pointsEarned. Może to wydawać się całkiem intuicyjne, ponieważ odzwierciedla pozostałą część implementacji i nie wymaga dużego nakładu pracy.

Pamiętaj jednak, że nauczyciel komunikuje się wyłącznie z pracą ucznia umieszczonego w elemencie iframe Przegląd pracy ucznia. Wiąże się to z konsekwencje:

  • Oceny nie są wypełniane w Classroom, dopóki nauczyciel nie ukończy lekcji. w interfejsie Classroom.
  • Nauczyciel musi otworzyć wszystkie zadania przesłane przez ucznia, oceny uczniów.
  • Występuje niewielkie opóźnienie między otrzymaniem oceny w Classroom i jak wygląda w interfejsie Classroom. Opóźnienie wynosi zwykle 5–10 sekund, ale może trwać nawet 30 sekund.

Połączenie tych czynników oznacza, że nauczyciele mogą mieć obowiązek żmudnego i czasochłonnego uzupełnienia ocen uczniów.

Aby wdrożyć to podejście, dodaj jedno dodatkowe wywołanie interfejsu API do istniejącego ucznia Trasa weryfikacji pracy.

Po pobraniu danych przesłanych przez ucznia oraz rekordów załączników oceń zadanie przesłane przez ucznia i zapisze ocenę. Ustaw ocenę w Pole pointsEarned obiektu AddOnAttachmentStudentSubmission. I na koniec, wyślij prośbę o PATCH do Punkt końcowy courses.courseWork.addOnAttachments.studentSubmissions z AddOnAttachmentStudentSubmission instancję w treści żądania. Pamiętaj, że należy również określić pointsEarned w updateMask w żądaniu 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()

Określanie ocen przy użyciu danych logowania nauczyciela offline

Drugi sposób określania ocen wymaga użycia zapisanych danych logowania dla nauczyciela, który utworzył załącznik. Ta implementacja wymaga: podczas tworzenia danych logowania za pomocą funkcji odświeżania autoryzowanego wcześniej nauczyciela a następnie użyj tych danych logowania do skonfigurowania pointsEarned.

Kluczową zaletą tego podejścia jest to, że oceny są wypełniane bez konieczności działania nauczyciela w interfejsie Classroom, co pozwala uniknąć problemów. wspomnianych powyżej. Dzięki temu użytkownicy postrzegają proces oceniania płynnie i skutecznie. Dodatkowo ta metoda pozwala wybrać moment zwracania ocen, na przykład kiedy uczniowie realizują zadania lub asynchronicznie.

Aby wdrożyć tę metodę, wykonaj te czynności:

  1. Zmodyfikuj rekordy bazy danych użytkowników, aby przechowywać token dostępu.
  2. Zmodyfikuj rekordy bazy danych załączników, aby przechowywać identyfikator nauczyciela.
  3. Pobierz dane logowania nauczyciela i (opcjonalnie) utwórz nowe Instancja usługi Classroom.
  4. wystawić ocenę za zadanie.

Na potrzeby tej prezentacji ustaw ocenę za ukończenie przez ucznia aktywność; czyli gdy uczeń przesyła formularz w Widoku ucznia .

Zmodyfikuj rekordy bazy danych użytkowników, aby przechowywać token dostępu

Do wykonywania wywołań interfejsu API są wymagane 2 unikalne tokeny: token odświeżania i token dostępu. Jeśli do tej pory udało Ci się obejrzeć całą serię poradników, Schemat tabeli User powinien już przechowywać token odświeżania. Przechowywanie odświeżania wystarczy, aby wykonać wywołania interfejsu API wyłącznie z zalogowanym użytkownikiem, otrzymasz token dostępu w ramach procesu uwierzytelniania.

Teraz musisz jednak dzwonić jako inna osoba niż zalogowany użytkownik. co oznacza, że proces uwierzytelniania jest niedostępny. Musisz więc przechowywać wraz z tokenem odświeżania. Zaktualizuj schemat tabeli User do dodaj token dostępu:

Python

W naszym przykładzie znajduje się to w pliku 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())

Następnie zaktualizuj dowolny kod, który tworzy lub aktualizuje rekord User, aby przechowywać w nim token dostępu:

Python

W naszym przykładzie znajduje się to w pliku 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()

Zmodyfikuj rekordy bazy danych załączników, aby przechowywać identyfikator nauczyciela

Aby ustawić ocenę za aktywność, wywołaj funkcję pointsEarned jako na zajęciach. Możesz to zrobić na kilka sposobów:

  • Przechowuj lokalne mapowanie danych logowania nauczycieli na identyfikatory zajęć. Pamiętaj jednak, ten sam nauczyciel nie zawsze może być powiązany z konkretnymi zajęciami.
  • Wyślij żądania GET do punktu końcowego courses interfejsu Classroom API, aby uzyskać obecnych nauczycieli. Następnie poproś o lokalne rekordy użytkowników, aby je zlokalizować pasujących danych logowania nauczyciela.
  • Podczas tworzenia załącznika dodatku zapisz identyfikator nauczyciela w lokalnym bazy danych przyłączy. Następnie pobierz dane logowania nauczyciela z Element attachmentId został przekazany do elementu iframe widoku ucznia.

Ten przykład przedstawia ostatnią opcję, ponieważ ustawiasz oceny podczas uczeń wykonuje załącznik z ćwiczeniem.

Dodaj pole identyfikatora nauczyciela do tabeli Attachment w bazie danych:

Python

W naszym przykładzie znajduje się to w pliku 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))

Następnie zaktualizuj kod, który tworzy lub aktualizuje rekord Attachment, tak aby zawierał również zapisz identyfikator twórcy:

Python

W podanym przykładzie jest to metoda create_attachments w kluczu 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()

Pobieranie danych logowania nauczyciela

Odszukaj trasę, która korzysta z elementu iframe widoku ucznia. Natychmiast po zapisaniu odpowiedzi ucznia w lokalnej bazie danych, pobierz odpowiedź nauczyciela dane logowania z pamięci lokalnej. To powinno być proste, biorąc pod uwagę w ramach przygotowań w poprzednich 2 krokach. Można również użyć ich do utworzenia nowego wystąpienie usługi Classroom dla użytkownika:

Python

W podanym przykładzie jest to metoda load_activity_attachment w argumencie pliku 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,
    credentials=teacher_credentials)

Ustawianie oceny zadania

Procedura jest taka sama jak w przypadku korzystania z metod dane logowania. Pamiętaj jednak, aby skontaktować się z nauczycielem. dane logowania pobrane w poprzednim kroku:

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

Testowanie dodatku

Podobnie jak w poprzednim przewodniku, utwórz projekt z typem działania. jako nauczyciel, prześlij odpowiedź jako uczeń, a następnie otwórz umieszczonego w elemencie iframe Przegląd pracy ucznia. Powinno być widoczne ocena pojawia się w różnych momentach w zależności od metody implementacji:

  • Jeśli zdecydujesz się zwrócić ocenę po wykonaniu przez ucznia zadania, powinna być już widoczna w interfejsie użytkownika, zanim otworzysz ocenę roboczą. Element iframe z recenzją zadania ucznia. Możesz je też zobaczyć na liście uczniów, gdy otwórz projekt i w sekcji „Ocena” obok pola Zadania uczniów. Sprawdź element iframe.
  • Jeśli zdecydujesz się przekazać ocenę, gdy nauczyciel otworzy Zadania uczniów Sprawdź element iframe; ocena powinna pojawić się w obszarze „Ocena” zaraz za Element iframe wczytuje się. Jak wspomniano powyżej, może to potrwać do 30 sekund. Ocena danego ucznia powinna także pojawić się w innych widoków dziennika ocen Classroom.

Sprawdź, czy uczeń widzi właściwy wynik.

Gratulacje! Możesz już przejść do następnego kroku: tworzenia załączników poza Google Classroom.