Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
scripts
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CSCE 361
scripts
Commits
91fa7ddd
Commit
91fa7ddd
authored
Oct 17, 2019
by
Christopher Bohn
Browse files
Options
Downloads
Patches
Plain Diff
added code to review peer evaluations
parent
aaa69d09
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
api/canvas_classes.py
+370
-19
370 additions, 19 deletions
api/canvas_classes.py
grade_team_contribution.py
+71
-0
71 additions, 0 deletions
grade_team_contribution.py
prep_assignment.py
+1
-1
1 addition, 1 deletion
prep_assignment.py
with
442 additions
and
20 deletions
api/canvas_classes.py
+
370
−
19
View file @
91fa7ddd
...
...
@@ -12,6 +12,9 @@ class CanvasSession:
return
CanvasSession
.
__instance
# PEOPLE CLASSES
class
CanvasUser
:
def
__init__
(
self
,
user
):
super
().
__init__
()
...
...
@@ -102,7 +105,7 @@ class CanvasUser:
"""
class
CanvasGroupSet
:
# aka, group_category
class
Canvas
User
GroupSet
:
# aka, group_category
def
__init__
(
self
,
group_category
):
super
().
__init__
()
self
.
canvas_group_category
=
group_category
...
...
@@ -114,19 +117,19 @@ class CanvasGroupSet: # aka, group_category
canvas_groups
=
self
.
canvas_group_category
.
get_groups
()
groups
=
[]
for
group
in
canvas_groups
:
groups
.
append
(
CanvasGroup
(
group
))
groups
.
append
(
Canvas
User
Group
(
group
))
return
groups
def
create_group
(
self
,
group_name
):
canvas_group
=
self
.
canvas_group_category
.
create_group
(
name
=
group_name
)
return
CanvasGroup
(
canvas_group
)
return
Canvas
User
Group
(
canvas_group
)
def
create_groups
(
self
,
number_of_groups
):
base_name
=
self
.
get_name
()
groups
=
[]
for
group_number
in
range
(
1
,
number_of_groups
+
1
):
canvas_group
=
self
.
create_group
(
f
'
{
base_name
}
{
group_number
}
'
)
groups
.
append
(
CanvasGroup
(
canvas_group
))
groups
.
append
(
Canvas
User
Group
(
canvas_group
))
return
groups
def
__repr__
(
self
):
...
...
@@ -178,26 +181,26 @@ class CanvasGroupSet: # aka, group_category
"""
class
CanvasGroup
:
class
Canvas
User
Group
:
def
__init__
(
self
,
group
):
super
().
__init__
()
self
.
canvas_group
=
group
self
.
canvas_
user_
group
=
group
def
get_name
(
self
):
return
self
.
canvas_group
.
name
return
self
.
canvas_
user_
group
.
name
def
get_number_of_students
(
self
):
return
self
.
canvas_group
.
members_count
return
self
.
canvas_
user_
group
.
members_count
def
get_students
(
self
):
canvas_users
=
self
.
canvas_group
.
get_users
()
canvas_users
=
self
.
canvas_
user_
group
.
get_users
()
students
=
[]
for
student
in
canvas_users
:
students
.
append
(
CanvasUser
(
student
))
return
students
def
add_student
(
self
,
user
):
self
.
canvas_group
.
create_membership
(
user
.
get_canvas_id
())
self
.
canvas_
user_
group
.
create_membership
(
user
.
get_canvas_id
())
def
__repr__
(
self
):
return
self
.
get_name
()
...
...
@@ -261,6 +264,341 @@ class CanvasGroup:
"""
# ASSIGNMENT-RELATED CLASSES
class
CanvasAssignment
:
def
__init__
(
self
,
assignment
):
super
().
__init__
()
self
.
canvas_assignment
=
assignment
def
get_name
(
self
):
return
self
.
canvas_assignment
.
name
def
is_quiz
(
self
):
return
'
online_quiz
'
in
self
.
canvas_assignment
.
submission_types
def
get_submission_text
(
self
,
canvas_user
):
submission
=
self
.
canvas_assignment
.
get_submission
(
canvas_user
.
get_canvas_id
())
if
submission
.
submission_type
==
'
online_text_entry
'
:
return
submission
.
body
elif
submission
.
submission_type
==
'
online_url
'
:
return
submission
.
url
elif
self
.
is_quiz
():
return
'
online quiz
'
else
:
return
None
def
get_quiz_response
(
self
,
canvas_user
):
questions_and_answers
=
[]
questions
=
[]
answers
=
[]
if
self
.
is_quiz
():
quiz_id
=
self
.
canvas_assignment
.
quiz_id
course_id
=
self
.
canvas_assignment
.
course_id
quiz_submissions
=
CanvasCourse
(
course_id
).
canvas_course
.
get_quiz
(
quiz_id
).
get_submissions
()
# breaking encapsulation
candidate_submission
=
list
(
filter
(
lambda
q
:
q
.
user_id
==
canvas_user
.
get_canvas_id
(),
quiz_submissions
))
if
len
(
candidate_submission
)
>
0
:
full_questions
=
candidate_submission
[
0
].
get_submission_questions
()
for
question
in
full_questions
:
questions
.
append
(
question
.
question_text
)
submission
=
self
.
canvas_assignment
.
get_submission
(
canvas_user
.
get_canvas_id
(),
include
=
[
'
submission_history
'
])
history
=
sorted
(
list
(
submission
.
submission_history
),
key
=
lambda
s
:
s
[
'
submitted_at
'
],
reverse
=
True
)
if
len
(
history
)
>
0
:
submission_data
=
history
[
0
][
'
submission_data
'
]
for
datum
in
submission_data
:
answers
.
append
(
datum
[
'
text
'
])
if
len
(
questions
)
==
len
(
answers
):
for
i
in
range
(
len
(
questions
)):
questions_and_answers
.
append
({
'
question
'
:
questions
[
i
],
'
answer
'
:
answers
[
i
]})
else
:
questions_and_answers
=
None
else
:
questions_and_answers
=
None
return
questions_and_answers
def
__repr__
(
self
):
return
self
.
get_name
()
"""
{
// the ID of the assignment
"
id
"
: 4,
// the name of the assignment
"
name
"
:
"
some assignment
"
,
// the assignment description, in an HTML fragment
"
description
"
:
"
<p>Do the following:</p>...
"
,
// The time at which this assignment was originally created
"
created_at
"
:
"
2012-07-01T23:59:00-06:00
"
,
// The time at which this assignment was last modified in any way
"
updated_at
"
:
"
2012-07-01T23:59:00-06:00
"
,
// the due date for the assignment. returns null if not present. NOTE: If this
// assignment has assignment overrides, this field will be the due date as it
// applies to the user requesting information from the API.
"
due_at
"
:
"
2012-07-01T23:59:00-06:00
"
,
// the lock date (assignment is locked after this date). returns null if not
// present. NOTE: If this assignment has assignment overrides, this field will
// be the lock date as it applies to the user requesting information from the
// API.
"
lock_at
"
:
"
2012-07-01T23:59:00-06:00
"
,
// the unlock date (assignment is unlocked after this date) returns null if not
// present NOTE: If this assignment has assignment overrides, this field will be
// the unlock date as it applies to the user requesting information from the
// API.
"
unlock_at
"
:
"
2012-07-01T23:59:00-06:00
"
,
// whether this assignment has overrides
"
has_overrides
"
: true,
// (Optional) all dates associated with the assignment, if applicable
"
all_dates
"
: null,
// the ID of the course the assignment belongs to
"
course_id
"
: 123,
// the URL to the assignment
'
s web page
"
html_url
"
:
"
https://...
"
,
// the URL to download all submissions as a zip
"
submissions_download_url
"
:
"
https://example.com/courses/:course_id/assignments/:id/submissions?zip=1
"
,
// the ID of the assignment
'
s group
"
assignment_group_id
"
: 2,
// Boolean flag indicating whether the assignment requires a due date based on
// the account level setting
"
due_date_required
"
: true,
// Allowed file extensions, which take effect if submission_types includes
//
'
online_upload
'
.
"
allowed_extensions
"
: [
"
docx
"
,
"
ppt
"
],
// An integer indicating the maximum length an assignment
'
s name may be
"
max_name_length
"
: 15,
// Boolean flag indicating whether or not Turnitin has been enabled for the
// assignment. NOTE: This flag will not appear unless your account has the
// Turnitin plugin available
"
turnitin_enabled
"
: true,
// Boolean flag indicating whether or not VeriCite has been enabled for the
// assignment. NOTE: This flag will not appear unless your account has the
// VeriCite plugin available
"
vericite_enabled
"
: true,
// Settings to pass along to turnitin to control what kinds of matches should be
// considered. originality_report_visibility can be
'
immediate
'
,
//
'
after_grading
'
,
'
after_due_date
'
, or
'
never
'
exclude_small_matches_type can
// be null,
'
percent
'
,
'
words
'
exclude_small_matches_value: - if type is null,
// this will be null also - if type is
'
percent
'
, this will be a number between
// 0 and 100 representing match size to exclude as a percentage of the document
// size. - if type is
'
words
'
, this will be number > 0 representing how many
// words a match must contain for it to be considered NOTE: This flag will not
// appear unless your account has the Turnitin plugin available
"
turnitin_settings
"
: null,
// If this is a group assignment, boolean flag indicating whether or not
// students will be graded individually.
"
grade_group_students_individually
"
: false,
// (Optional) assignment
'
s settings for external tools if submission_types
// include
'
external_tool
'
. Only url and new_tab are included (new_tab defaults
// to false). Use the
'
External Tools
'
API if you need more information about
// an external tool.
"
external_tool_tag_attributes
"
: null,
// Boolean indicating if peer reviews are required for this assignment
"
peer_reviews
"
: false,
// Boolean indicating peer reviews are assigned automatically. If false, the
// teacher is expected to manually assign peer reviews.
"
automatic_peer_reviews
"
: false,
// Integer representing the amount of reviews each user is assigned. NOTE: This
// key is NOT present unless you have automatic_peer_reviews set to true.
"
peer_review_count
"
: 0,
// String representing a date the reviews are due by. Must be a date that occurs
// after the default due date. If blank, or date is not after the assignment
'
s
// due date, the assignment
'
s due date will be used. NOTE: This key is NOT
// present unless you have automatic_peer_reviews set to true.
"
peer_reviews_assign_at
"
:
"
2012-07-01T23:59:00-06:00
"
,
// Boolean representing whether or not members from within the same group on a
// group assignment can be assigned to peer review their own group
'
s work
"
intra_group_peer_reviews
"
: false,
// The ID of the assignment’s group set, if this is a group assignment. For
// group discussions, set group_category_id on the discussion topic, not the
// linked assignment.
"
group_category_id
"
: 1,
// if the requesting user has grading rights, the number of submissions that
// need grading.
"
needs_grading_count
"
: 17,
// if the requesting user has grading rights and the
//
'
needs_grading_count_by_section
'
flag is specified, the number of submissions
// that need grading split out by section. NOTE: This key is NOT present unless
// you pass the
'
needs_grading_count_by_section
'
argument as true. ANOTHER
// NOTE: it
'
s possible to be enrolled in multiple sections, and if a student is
// setup that way they will show an assignment that needs grading in multiple
// sections (effectively the count will be duplicated between sections)
"
needs_grading_count_by_section
"
: [{
"
section_id
"
:
"
123456
"
,
"
needs_grading_count
"
:5},
// {
"
section_id
"
:
"
654321
"
,
"
needs_grading_count
"
:0}],
// the sorting order of the assignment in the group
"
position
"
: 1,
// (optional, present if Sync Grades to SIS feature is enabled)
"
post_to_sis
"
: true,
// (optional, Third Party unique identifier for Assignment)
"
integration_id
"
:
"
12341234
"
,
// (optional, Third Party integration data for assignment)
"
integration_data
"
:
"
12341234
"
,
// For courses using Old Gradebook, indicates whether the assignment is muted.
// For courses using New Gradebook, true if the assignment has any unposted
// submissions, otherwise false. To see the posted status of submissions, check
// the
'
posted_attribute
'
on Submission.
"
muted
"
: null,
// the maximum points possible for the assignment
"
points_possible
"
: 12,
// the types of submissions allowed for this assignment list containing one or
// more of the following:
'
discussion_topic
'
,
'
online_quiz
'
,
'
on_paper
'
,
'
none
'
,
//
'
external_tool
'
,
'
online_text_entry
'
,
'
online_url
'
,
'
online_upload
'
//
'
media_recording
'
"
submission_types
"
: [
"
online_text_entry
"
],
// If true, the assignment has been submitted to by at least one student
"
has_submitted_submissions
"
: true,
// The type of grading the assignment receives; one of
'
pass_fail
'
,
'
percent
'
,
//
'
letter_grade
'
,
'
gpa_scale
'
,
'
points
'
"
grading_type
"
:
"
points
"
,
// The id of the grading standard being applied to this assignment. Valid if
// grading_type is
'
letter_grade
'
or
'
gpa_scale
'
.
"
grading_standard_id
"
: null,
// Whether the assignment is published
"
published
"
: true,
// Whether the assignment
'
s
'
published
'
state can be changed to false. Will be
// false if there are student submissions for the assignment.
"
unpublishable
"
: false,
// Whether the assignment is only visible to overrides.
"
only_visible_to_overrides
"
: false,
// Whether or not this is locked for the user.
"
locked_for_user
"
: false,
// (Optional) Information for the user about the lock. Present when
// locked_for_user is true.
"
lock_info
"
: null,
// (Optional) An explanation of why this is locked for the user. Present when
// locked_for_user is true.
"
lock_explanation
"
:
"
This assignment is locked until September 1 at 12:00am
"
,
// (Optional) id of the associated quiz (applies only when submission_types is
// [
'
online_quiz
'
])
"
quiz_id
"
: 620,
// (Optional) whether anonymous submissions are accepted (applies only to quiz
// assignments)
"
anonymous_submissions
"
: false,
// (Optional) the DiscussionTopic associated with the assignment, if applicable
"
discussion_topic
"
: null,
// (Optional) Boolean indicating if assignment will be frozen when it is copied.
// NOTE: This field will only be present if the AssignmentFreezer plugin is
// available for your account.
"
freeze_on_copy
"
: false,
// (Optional) Boolean indicating if assignment is frozen for the calling user.
// NOTE: This field will only be present if the AssignmentFreezer plugin is
// available for your account.
"
frozen
"
: false,
// (Optional) Array of frozen attributes for the assignment. Only account
// administrators currently have permission to change an attribute in this list.
// Will be empty if no attributes are frozen for this assignment. Possible
// frozen attributes are: title, description, lock_at, points_possible,
// grading_type, submission_types, assignment_group_id, allowed_extensions,
// group_category_id, notify_of_update, peer_reviews NOTE: This field will only
// be present if the AssignmentFreezer plugin is available for your account.
"
frozen_attributes
"
: [
"
title
"
],
// (Optional) If
'
submission
'
is included in the
'
include
'
parameter, includes a
// Submission object that represents the current user
'
s (user who is requesting
// information from the api) current submission for the assignment. See the
// Submissions API for an example response. If the user does not have a
// submission, this key will be absent.
"
submission
"
: null,
// (Optional) If true, the rubric is directly tied to grading the assignment.
// Otherwise, it is only advisory. Included if there is an associated rubric.
"
use_rubric_for_grading
"
: true,
// (Optional) An object describing the basic attributes of the rubric, including
// the point total. Included if there is an associated rubric.
"
rubric_settings
"
:
"
{
"
points_possible
"
=>12}
"
,
// (Optional) A list of scoring criteria and ratings for each rubric criterion.
// Included if there is an associated rubric.
"
rubric
"
: null,
// (Optional) If
'
assignment_visibility
'
is included in the
'
include
'
parameter,
// includes an array of student IDs who can see this assignment.
"
assignment_visibility
"
: [137, 381, 572],
// (Optional) If
'
overrides
'
is included in the
'
include
'
parameter, includes an
// array of assignment override objects.
"
overrides
"
: null,
// (Optional) If true, the assignment will be omitted from the student
'
s final
// grade
"
omit_from_final_grade
"
: true,
// Boolean indicating if the assignment is moderated.
"
moderated_grading
"
: true,
// The maximum number of provisional graders who may issue grades for this
// assignment. Only relevant for moderated assignments. Must be a positive
// value, and must be set to 1 if the course has fewer than two active
// instructors. Otherwise, the maximum value is the number of active instructors
// in the course minus one, or 10 if the course has more than 11 active
// instructors.
"
grader_count
"
: 3,
// The user ID of the grader responsible for choosing final grades for this
// assignment. Only relevant for moderated assignments.
"
final_grader_id
"
: 3,
// Boolean indicating if provisional graders
'
comments are visible to other
// provisional graders. Only relevant for moderated assignments.
"
grader_comments_visible_to_graders
"
: true,
// Boolean indicating if provisional graders
'
identities are hidden from other
// provisional graders. Only relevant for moderated assignments with
// grader_comments_visible_to_graders set to true.
"
graders_anonymous_to_graders
"
: true,
// Boolean indicating if provisional grader identities are visible to the final
// grader. Only relevant for moderated assignments.
"
grader_names_visible_to_final_grader
"
: true,
// Boolean indicating if the assignment is graded anonymously. If true, graders
// cannot see student identities.
"
anonymous_grading
"
: true,
// The number of submission attempts a student can make for this assignment. -1
// is considered unlimited.
"
allowed_attempts
"
: 2,
// Whether the assignment has manual posting enabled. Only relevant for courses
// using New Gradebook.
"
post_manually
"
: true
}
"""
class
CanvasAssignmentGroup
:
# from canvasapi.assignment import Assignment
def
__init__
(
self
,
group
):
super
().
__init__
()
self
.
canvas_assignment_group
=
group
def
get_name
(
self
):
return
self
.
canvas_assignment_group
.
name
def
get_assignments
(
self
):
course_id
=
self
.
canvas_assignment_group
.
course_id
all_assignments
=
CanvasCourse
(
course_id
).
get_assignments
()
assignments
=
list
(
filter
(
lambda
a
:
a
.
canvas_assignment
.
assignment_group_id
==
self
.
canvas_assignment_group
.
id
,
all_assignments
))
# breaking encapsulation
return
assignments
def
__repr__
(
self
):
return
self
.
get_name
()
"""
{
// the id of the Assignment Group
"
id
"
: 1,
// the name of the Assignment Group
"
name
"
:
"
group2
"
,
// the position of the Assignment Group
"
position
"
: 7,
// the weight of the Assignment Group
"
group_weight
"
: 20,
// the sis source id of the Assignment Group
"
sis_source_id
"
:
"
1234
"
,
// the integration data of the Assignment Group
"
integration_data
"
: {
"
5678
"
:
"
0954
"
},
// the assignments in this Assignment Group (see the Assignment API for a
// detailed list of fields)
"
assignments
"
: [],
// the grading rules that this Assignment Group has
"
rules
"
: null
}
"""
# THE COURSE ITSELF
class
CanvasCourse
:
def
__init__
(
self
,
course_id
):
self
.
canvas_course
=
CanvasSession
.
get_session
().
get_course
(
course_id
)
...
...
@@ -286,23 +624,37 @@ class CanvasCourse:
instructors
.
append
(
CanvasUser
(
user
))
return
instructors
def
get_all_groups
(
self
):
def
get_all_
user_
groups
(
self
):
canvas_groups
=
self
.
canvas_course
.
get_groups
()
groups
=
[]
for
group
in
canvas_groups
:
groups
.
append
(
CanvasGroup
(
group
))
groups
.
append
(
Canvas
User
Group
(
group
))
return
groups
def
get_group
_
sets
(
self
):
def
get_
user_
groupsets
(
self
):
canvas_group_categories
=
self
.
canvas_course
.
get_group_categories
()
group_sets
=
[]
for
group_category
in
canvas_group_categories
:
group_sets
.
append
(
CanvasGroupSet
(
group_category
))
group_sets
.
append
(
Canvas
User
GroupSet
(
group_category
))
return
group_sets
def
create_groupset
(
self
,
groupset_name
):
def
create_
user_
groupset
(
self
,
groupset_name
):
group_category
=
self
.
canvas_course
.
create_group_category
(
groupset_name
)
return
CanvasGroupSet
(
group_category
)
return
CanvasUserGroupSet
(
group_category
)
def
get_assignment_groups
(
self
):
canvas_assignment_groups
=
self
.
canvas_course
.
get_assignment_groups
(
include
=
[
'
assignments
'
])
assignment_groups
=
[]
for
assignment_group
in
canvas_assignment_groups
:
assignment_groups
.
append
(
CanvasAssignmentGroup
(
assignment_group
))
return
assignment_groups
def
get_assignments
(
self
):
canvas_assignments
=
self
.
canvas_course
.
get_assignments
()
assignments
=
[]
for
assignment
in
canvas_assignments
:
assignments
.
append
(
CanvasAssignment
(
assignment
))
return
assignments
def
__repr__
(
self
):
return
f
'
{
self
.
canvas_course
.
course_code
}
:
{
self
.
canvas_course
.
name
}
'
...
...
@@ -409,6 +761,5 @@ class CanvasCourse:
}
"""
if
__name__
==
'
__main__
'
:
pass
This diff is collapsed.
Click to expand it.
grade_team_contribution.py
0 → 100644
+
71
−
0
View file @
91fa7ddd
import
textwrap
from
api.canvas_classes
import
*
from
course
import
Course
def
structure_text
(
text
):
import
re
return
textwrap
.
wrap
(
re
.
sub
(
re
.
compile
(
'
<.*?>
'
),
''
,
text
))
def
select_from_list
(
choices
,
choice_name
):
print
(
f
'
Choose the
{
choice_name
}
from this list:
'
)
for
i
in
range
(
len
(
choices
)):
print
(
f
'
{
i
+
1
}
)
\t
{
choices
[
i
]
}
'
.
expandtabs
(
4
))
selection
=
input
(
'
Enter selection:
'
)
return
choices
[
int
(
selection
)
-
1
]
def
display_peer_reviews
(
assignment
,
students
):
for
student
in
students
:
text
=
[]
print
(
f
'
\n\n\t
{
student
.
get_name
()
}
'
.
expandtabs
(
4
))
if
assignment
.
is_quiz
():
response
=
assignment
.
get_quiz_response
(
student
)
if
response
is
not
None
:
for
entry
in
response
:
text
=
text
+
structure_text
(
entry
[
'
question
'
])
+
structure_text
(
entry
[
'
answer
'
])
else
:
response
=
assignment
.
get_submission_text
(
student
)
if
response
is
not
None
:
text
=
structure_text
(
response
)
for
line
in
text
:
print
(
f
'
\t\t
{
line
}
'
.
expandtabs
(
4
))
def
display_git_contributions
():
print
(
'
Review git contributions offline
'
)
def
grade
(
assignment1
,
assignment2
,
students
):
pass
if
__name__
==
'
__main__
'
:
course
=
CanvasCourse
(
Course
.
canvas_course_id
)
print
(
'
First, select the Canvas assignment to review and grade.
\n
'
)
assignment_groups
=
course
.
get_assignment_groups
()
assignment_group
=
select_from_list
(
assignment_groups
,
'
assignment group
'
)
print
()
assignments
=
assignment_group
.
get_assignments
()
peer_review_assignment
=
select_from_list
(
assignments
,
'
assignment
'
)
print
(
f
'
\n
Selected
{
peer_review_assignment
}
.
'
)
print
(
'
Now select the student groupset with the teams.
\n
'
)
student_groupsets
=
course
.
get_user_groupsets
()
student_groupset
=
select_from_list
(
student_groupsets
,
'
groupset
'
)
print
(
f
'
\n
Selected
{
student_groupset
}
.
\n
'
)
student_groups
=
student_groupset
.
get_groups
()
print
(
'
Are you grading all groups, or are you revisiting a specific group?
'
)
options
=
[
'
All groups
'
,
'
Specific group
'
]
option
=
select_from_list
(
options
,
'
option
'
)
if
option
is
options
[
1
]:
print
(
'
Which group?
'
)
student_groups
=
[
select_from_list
(
student_groups
,
'
student group
'
)]
for
student_group
in
student_groups
:
input
(
f
'
\n\n
Press any key to grade
{
student_group
}
'
)
display_peer_reviews
(
peer_review_assignment
,
student_group
.
get_students
())
display_git_contributions
()
# TODO: Ask if you want to grade (keep track of groups that you don't grade)
if
True
:
grade
(
peer_review_assignment
,
None
,
student_group
.
get_students
())
This diff is collapsed.
Click to expand it.
prep_assignment.py
+
1
−
1
View file @
91fa7ddd
...
...
@@ -73,7 +73,7 @@ def create_repositories(assignment_number, student_pairs, verbose):
def
create_groups
(
assignment_number
,
student_pairs
):
course
=
CanvasCourse
(
Course
.
canvas_course_id
)
group_set
=
course
.
create_groupset
(
f
'
{
assignment_number
}
pairs
'
)
group_set
=
course
.
create_
user_
groupset
(
f
'
{
assignment_number
}
pairs
'
)
for
pair
in
student_pairs
:
group
=
group_set
.
create_group
(
f
'
{
assignment_number
}
pair
{
pair
[
0
]
}
'
)
group
.
add_student
(
pair
[
1
].
get_canvas_user
())
...
...
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment