Bu, Classroom eklentileriyle ilgili altıncı adım adım açıklama videosudur.
Bu adım adım açıklama kılavuzunda, önceki adım adım açıklama kılavuzundaki örneği değiştirerek puanlı etkinlik türünde bir ek oluşturacaksınız. Ayrıca, notu programlı olarak Google Classroom'a geri geçirirsiniz. Bu not, öğretmenin not defterinde taslak not olarak görünür.
Bu kılavuz, notları Classroom'a geri aktarmak için iki olası yaklaşım sunması nedeniyle serideki diğer kılavuzlardan biraz farklıdır. Her ikisi de geliştirici ve kullanıcı deneyimleri üzerinde farklı etkilere sahiptir. Classroom eklentinizi tasarlarken her ikisini de göz önünde bulundurun. Uygulama seçenekleriyle ilgili daha fazla bilgi için Eklerle etkileşim kurma rehber sayfamızı inceleyin.
API'deki notlandırma özelliklerinin isteğe bağlı olduğunu unutmayın. Bunlar herhangi bir etkinlik türü ekiyle kullanılabilir.
Bu kılavuzda aşağıdaki işlemleri yapacaksınız:
- Önceki ek oluşturma isteklerini, ek notunun paydasını da ayarlayacak şekilde Classroom API'de değiştirin.
- Öğrencinin gönderisine programatik olarak puan verin ve eklerin not payını ayarlayın.
- Gönderimin notunu, oturum açmış veya çevrimdışı öğretmen kimlik bilgilerini kullanarak Classroom'a aktarmak için iki yaklaşım uygulayın.
İşlem tamamlandıktan sonra, geri gönderme davranışı tetiklendiğinde notlar Classroom not defterinde görünür. Bu durumun tam olarak ne zaman gerçekleşeceği, uygulama yaklaşımına bağlıdır.
Bu örnekte, önceki adım adım açıklamadaki etkinliği yeniden kullanın. Bu etkinlikte, öğrenciye ünlü bir yerin resmi gösterilir ve adını girmesi istenir. Öğrenci doğru adı girerse ek için tam puan, aksi takdirde sıfır puan verin.
Classroom Eklentileri API'sindeki notlandırma özelliğini anlama
Eklentiniz, bir ek için hem not payını hem de not paydasını ayarlayabilir. Bunlar sırasıyla API'deki pointsEarned
ve maxPoints
değerleri kullanılarak ayarlanır. Classroom kullanıcı arayüzündeki bir ek kartında, ayarlandığında maxPoints
değeri gösterilir.
1.şekil maxPoints
ayarlanmış üç eklenti eki kartı içeren ödev oluşturma kullanıcı arayüzü.
Classroom eklentileri API'si, ek notları için ayarları yapılandırmanıza ve kazanılan puanı belirlemenize olanak tanır. Bunlar ödev notlarıyla aynı değildir. Ancak ödev notu ayarları, ek kartında Not senkronizasyonu etiketi bulunan ekin not ayarlarını takip eder. "Not senkronizasyonu" eki, öğrenci gönderimi için pointsEarned
ayarlandığında öğrencinin ödevle ilgili taslak notunu da ayarlar.
Genellikle, ödeve eklenen ve maxPoints
ayarını yapan ilk ek, "Not senkronizasyonu" etiketini alır. "Not senkronizasyonu" etiketinin bir örneği için Şekil 1'de gösterilen ödev oluşturma kullanıcı arayüzü örneğine bakın. "Ek 1" kartında "Not senkronizasyonu" etiketinin bulunduğunu ve kırmızı kutudaki ödev notunun 50 puan olarak güncellendiğini unutmayın. Ayrıca, Şekil 1'de üç ek kartı gösterilmesine rağmen yalnızca bir kartta "Not senkronizasyonu" etiketinin bulunduğunu unutmayın. Bu, mevcut uygulamanın temel sınırlamalarından biridir: Yalnızca bir ekte "Not senkronizasyonu" etiketi olabilir.
maxPoints
ayarı yapılmış birden fazla ek varsa "Not senkronizasyonu" ayarı yapılmış eki kaldırmak, kalan eklerde "Not senkronizasyonu"nu etkinleştirmez. maxPoints
ayarını yapan başka bir ekleme yaptığınızda yeni ekte not senkronizasyonu etkinleştirilir ve maksimum ödev notu buna göre ayarlanır. Hangi ekte "Not senkronizasyonu" etiketinin olduğunu programatik olarak görme veya belirli bir ödevde kaç ek olduğunu görme mekanizması yoktur.
Ekin maksimum notunu ayarlama
Bu bölümde, bir ek notu için paydanın (yani tüm öğrencilerin gönderileri için alabileceği maksimum puan) nasıl ayarlanacağı açıklanmaktadır. Bunu yapmak için ekin maxPoints
değerini ayarlayın.
Notlandırma özelliklerini etkinleştirmek için mevcut uygulamamızda yalnızca küçük bir değişiklik yapılması gerekir. Ek oluştururken maxPoints
değerini, studentWorkReviewUri
, teacherViewUri
ve diğer ek alanlarını içeren aynı AddOnAttachment
nesnesine ekleyin.
Yeni bir ödevin varsayılan maksimum puanının 100 olduğunu unutmayın. Notların doğru şekilde ayarlandığını doğrulayabilmeniz için maxPoints
değerini 100'den farklı bir değere ayarlamanızı öneririz. Gösteri için maxPoints
değerini 50 olarak ayarlayın:
Python
maxPoints
nesnesini oluştururken maxPoints
alanını ekleyin. Bu işlem, courses.courseWork.addOnAttachments
uç noktasına CREATE
isteği göndermeden hemen önce yapılmalıdır.attachment
Sağlanan örneği takip ediyorsanız bunu webapp/attachment_routes.py
dosyasında bulabilirsiniz.
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}",
}
Bu gösterim amacıyla, maxPoints
değerini yerel Ek veritabanınızda da saklarsınız. Bu sayede, öğrenci gönderimlerini notlandırırken daha sonra ek bir API çağrısı yapmanız gerekmez. Ancak öğretmenlerin ödev notu ayarlarını eklentinizden bağımsız olarak değiştirebileceğini unutmayın. Ödev düzeyindeki maxPoints
değerini görmek için courses.courseWork
uç noktasına bir GET
isteği gönderin. Bu işlemi yaparken itemId
değerini CourseWork.id
alanına iletin.
Şimdi veritabanı modelinizi, eklerin maxPoints
değerini de içerecek şekilde güncelleyin.
CREATE
yanıtındaki maxPoints
değerini kullanmanızı öneririz:
Python
Öncelikle Attachment
tablosuna bir max_points
alanı ekleyin. Sağladığımız örneği takip ediyorsanız bu bilgiyi webapp/models.py
dosyasında bulabilirsiniz.
# 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)
courses.courseWork.addOnAttachments
CREATE
isteğine dönün. Yanıtta döndürülen maxPoints
değerini saklayın.
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()
Ek artık maksimum not alabilir. Bu davranışı şimdi test edebilirsiniz. Yeni bir ödeve ek ekleyin ve ek kartında "Not senkronizasyonu" etiketinin gösterildiğini ve ödevin "Puan" değerinin değiştiğini gözlemleyin.
Classroom'da öğrenci gönderimine not verme
Bu bölümde, bir ek notu için pay ayarlanması açıklanmaktadır. Bu, ekin öğrenciye ait notudur. Bunu yapmak için öğrenci eki gönderiminin pointsEarned
değerini ayarlayın.
Şimdi önemli bir karar vermeniz gerekiyor: Eklentiniz, pointsEarned
ayarlama isteğini nasıl göndermeli?
Sorun, pointsEarned
ayarının teacher
OAuth kapsamını gerektirmesidir.
Öğrenci kullanıcılara teacher
kapsamı vermemelisiniz. Bu, öğrencilerin eklentinizle etkileşimde bulunurken beklenmedik davranışlara (ör. öğrenci görünümü iFrame'i yerine öğretmen görünümü iFrame'inin yüklenmesi) neden olabilir. Bu nedenle, pointsEarned
öğesini ayarlamak için iki seçeneğiniz vardır:
- Giriş yapmış olan öğretmenin kimlik bilgilerini kullanma
- Depolanmış (çevrimdışı) öğretmen kimlik bilgilerini kullanma
Aşağıdaki bölümlerde, her bir uygulama gösterilmeden önce her yaklaşımın avantaj ve dezavantajları ele alınmaktadır. Sağladığımız örneklerin, Classroom'a not iletme konusunda her iki yaklaşımı da gösterdiğini unutmayın. Sağlanan örnekleri çalıştırırken nasıl bir yaklaşım seçeceğinizi görmek için aşağıdaki dile özgü talimatlara bakın:
Python
SET_GRADE_WITH_LOGGED_IN_USER_CREDENTIALS
beyanını webapp/attachment_routes.py
dosyasının en üstünde bulun. Oturum açmış öğretmenin kimlik bilgilerini kullanarak notları geri aktarmak için bu değeri True
olarak ayarlayın. Öğrenci etkinliği gönderdiğinde depolanan kimlik bilgilerini kullanarak notları geri iletmek için bu değeri False
olarak ayarlayın.
Oturum açmış öğretmenin kimlik bilgilerini kullanarak notları ayarlama
pointsEarned
ayarlanması isteğini göndermek için oturum açmış kullanıcının kimlik bilgilerini kullanın.
Bu, şu ana kadar yapılan uygulamanın geri kalanını yansıttığı için oldukça sezgisel olmalı ve gerçekleştirilmesi için çok az çaba gerektirir.
Ancak öğretmenin, Öğrenci Çalışması İnceleme iFrame'inde yalnızca öğrencinin gönderimiyle etkileşimde bulunduğunu unutmayın. Bunun bazı önemli sonuçları vardır:
- Öğretmen Classroom kullanıcı arayüzünde işlem yapana kadar Classroom'da notlar doldurulmaz.
- Öğretmenlerin, tüm öğrenci notlarını doldurmak için her öğrenci gönderimini açması gerekebilir.
- Classroom'un notu alması ile Classroom kullanıcı arayüzünde görünmesi arasında kısa bir gecikme olur. Gecikme genellikle beş ila on saniye sürer ancak 30 saniyeyi de bulabilir.
Bu faktörlerin birleşimi, öğretmenlerin bir sınıfın notlarını tam olarak doldurmak için önemli ve zaman alıcı manuel çalışmalar yapması gerekebileceği anlamına gelir.
Bu yaklaşımı uygulamak için mevcut StudentWork Review rotanıza ek bir API çağrısı ekleyin.
Öğrenci gönderimi ve ek kayıtları getirildikten sonra öğrencinin gönderimini değerlendirin ve ortaya çıkan notu saklayın. AddOnAttachmentStudentSubmission
nesnesinin pointsEarned
alanında notu ayarlayın. Son olarak, istek gövdesinde AddOnAttachmentStudentSubmission
örneğiyle courses.courseWork.addOnAttachments.studentSubmissions
uç noktasına bir PATCH
isteği gönderin. PATCH
talebimizde pointsEarned
değerini updateMask
içinde de belirtmemiz gerektiğini unutmayın:
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()
Çevrimdışı öğretmen kimlik bilgilerini kullanarak not verme
Notları ayarlamak için ikinci yaklaşımda, eki oluşturan öğretmenin kayıtlı kimlik bilgilerinin kullanılması gerekir. Bu uygulama, daha önce yetkilendirilmiş bir öğretmenin yenileme ve erişim jetonlarını kullanarak kimlik bilgileri oluşturmanızı ve ardından bu kimlik bilgilerini kullanarak pointsEarned
ayarını yapmanızı gerektirir.
Bu yaklaşımın en önemli avantajı, notların Classroom kullanıcı arayüzünde öğretmen işlemi gerektirmeden doldurulmasıdır. Bu sayede yukarıda bahsedilen sorunlar önlenir. Sonuç olarak, son kullanıcılar derecelendirme deneyimini sorunsuz ve verimli olarak algılar. Ayrıca bu yaklaşım, notları geri verme zamanını (ör. öğrenciler etkinliği tamamladığında veya eşzamansız olarak) seçmenize olanak tanır.
Bu yaklaşımı uygulamak için aşağıdaki görevleri tamamlayın:
- Erişim jetonu depolamak için kullanıcı veritabanı kayıtlarını değiştirin.
- Öğretmen kimliğini depolamak için Ek veritabanı kayıtlarını değiştirin.
- Öğretmenin kimlik bilgilerini alın ve (isteğe bağlı olarak) yeni bir Classroom hizmeti örneği oluşturun.
- Gönderimin notunu ayarlama
Bu gösterim için notu, öğrenci etkinliği tamamladığında (yani öğrenci formu Öğrenci Görünümü rotasında gönderdiğinde) ayarlayın.
Erişim jetonunu depolamak için kullanıcı veritabanı kayıtlarını değiştirme
API çağrıları yapmak için iki benzersiz jeton gerekir: yenileme jetonu ve erişim jetonu. Şu ana kadar adım adım açıklama serisini takip ettiyseniz User
tablo şemanızda yenileme jetonu zaten depolanıyor olmalıdır. Yalnızca oturum açmış kullanıcıyla API çağrıları yaptığınızda yenileme jetonunu saklamanız yeterlidir. Kimlik doğrulama akışının bir parçası olarak erişim jetonu alırsınız.
Ancak artık oturum açmış kullanıcı dışında biri olarak arama yapmanız gerekiyor. Bu nedenle kimlik doğrulama akışı kullanılamaz. Bu nedenle, erişim jetonunu yenileme jetonuyla birlikte saklamanız gerekir. User
tablo şemanızı erişim jetonu içerecek şekilde güncelleyin:
Python
Sağladığımız örnekte bu, webapp/models.py
dosyasındadır.
# 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())
Ardından, User
kaydı oluşturan veya güncelleyen tüm kodları, erişim jetonunu da depolayacak şekilde güncelleyin:
Python
Sağladığımız örnekte bu, webapp/credential_handler.py
dosyasındadır.
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()
Öğretmen kimliği depolamak için Ek veritabanı kayıtlarını değiştirme
Bir etkinliğe not vermek için pointsEarned
kullanıcısını kursta öğretmen olarak ayarlayın. Bunu yapmanın birkaç yolu vardır:
- Öğretmen kimlik bilgilerinin kurs kimlikleriyle yerel eşlemesini saklayın. Ancak aynı öğretmenin her zaman belirli bir kursla ilişkilendirilmeyebileceğini unutmayın.
- Mevcut öğretmenleri almak için Classroom API
courses
uç noktasınaGET
istekleri gönderin. Ardından, eşleşen öğretmen kimlik bilgilerini bulmak için yerel kullanıcı kayıtlarını sorgulayın. - Eklenti eki oluştururken yerel ekler veritabanında bir öğretmen kimliği saklayın. Ardından, öğrenci görünümü iFrame'ine iletilen
attachmentId
öğesinden öğretmen kimlik bilgilerini alın.
Bu örnekte, öğrenci bir etkinlik ekini tamamladığında not verdiğiniz için son seçenek gösterilmektedir.
Veritabanınızın Attachment
tablosuna öğretmen kimliği alanı ekleyin:
Python
Sağladığımız örnekte bu, webapp/models.py
dosyasındadır.
# 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))
Ardından, Attachment
kaydı oluşturan veya güncelleyen tüm kodları, oluşturucunun kimliğini de saklayacak şekilde güncelleyin:
Python
Sağladığımız örnekte bu, create_attachments
dosyasındaki webapp/attachment_routes.py
yöntemindedir.
# 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()
Öğretmenin kimlik bilgilerini alma
Öğrenci Görünümü iFrame'ine hizmet veren rotayı bulun. Öğrencinin yanıtını yerel veritabanınızda sakladıktan hemen sonra, öğretmenin kimlik bilgilerini yerel depolama alanınızdan alın. Önceki iki adımda yapılan hazırlıklar göz önüne alındığında bu işlem kolay olmalıdır. Ayrıca, öğretmen kullanıcısı için Classroom hizmetinin yeni bir örneğini oluşturmak üzere bunları da kullanabilirsiniz:
Python
Sağladığımız örnekte bu, webapp/attachment_routes.py
dosyasındaki load_activity_attachment
yöntemindedir.
# 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)
Gönderime not verme
Bundan sonraki prosedür, oturum açmış öğretmenin kimlik bilgilerini kullanma prosedürüyle aynıdır. Ancak, aramayı önceki adımda alınan öğretmen kimlik bilgileriyle yapmanız gerektiğini unutmayın:
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()
Eklentiyi test etme
Önceki adım adım açıklama bölümünde olduğu gibi, öğretmen olarak etkinlik türünde bir ek içeren ödev oluşturun, öğrenci olarak yanıt gönderin, ardından gönderimi Öğrenci Çalışması İnceleme iFrame'inde açın. Uygulama yaklaşımınıza bağlı olarak notun farklı zamanlarda gösterildiğini görebilirsiniz:
- Öğrenci etkinliği tamamladığında notu geri vermeyi seçtiyseniz Öğrenci Çalışması İnceleme iFrame'ini açmadan önce kullanıcı arayüzünde öğrencinin taslak notunu görmeniz gerekir. Ödevi açtığınızda öğrenci listesinde ve Öğrenci Çalışması İnceleme iFrame'inin yanındaki "Not" kutusunda da görebilirsiniz.
- Öğretmen, Öğrenci Çalışması İnceleme iFrame'ini açtığında notu geri vermeyi seçerseniz iFrame yüklendikten kısa süre sonra not, "Not" kutusunda görünür. Yukarıda belirtildiği gibi bu işlem 30 saniye kadar sürebilir. Bundan sonra, ilgili öğrencinin notu diğer Classroom not defteri görünümlerinde de görünür.
Öğrenci için doğru puanın göründüğünü onaylayın.
Tebrikler! Google Classroom dışında ekler oluşturma ile ilgili bir sonraki adıma geçmeye hazırsınız.