-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmissing_assignments.py
134 lines (100 loc) · 3.53 KB
/
missing_assignments.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from config import PROD_URL, PROD_KEY
from canvasapi import Canvas
import csv
import concurrent.futures
import re
from functools import partial
canvas = Canvas(PROD_URL, PROD_KEY)
course = canvas.get_course(000000) # set your course ID
assignments = len(list(course.get_assignments()))
writer = csv.writer(open("your_report.csv", "w"))
# Set a conditional filter on assignments returend.
filter_results = True
"""
Create a CSV report of missing assignments for all users in a course.
"""
def main():
sections = course.get_sections()
writer.writerow(
["Name", "Email", "Building", "Last Activity", "# Missing", "Missing"]
)
for section in sections:
enrollments = section.get_enrollments(state="active", type="StudentEnrollment")
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
data = []
job = partial(process_user, section=section)
results = [executor.submit(job, enrollment) for enrollment in enrollments]
for f in concurrent.futures.as_completed(results):
data.append(f.result())
print(f"Processed {len(data)} in {len(list(enrollments))} at {section}")
writer.writerows(data)
def process_user(enrollment, section):
"""Handle getting assignments for a single user
Args:
enrollment (canvasapi.enrollment.Enrollment): Canvas <Enrollment> object
section (canvasapi.section.Section): Canvas <Section> object
Returns:
[list]: formatted list for writing to the CSV
"""
missing = get_user_missing(section, enrollment.user["id"])
login = course.get_user(enrollment.user["id"]).login_id
regex = re.compile("@")
if regex.search(login) is None:
email = f"{login}@elkhart.k12.in.us"
else:
email = login
return [
enrollment.user["sortable_name"],
email,
section.name,
enrollment.last_activity_at,
len(missing),
", ".join(missing),
]
def get_user_missing(section, user_id):
"""Get the missing assignments for the user in a section
Args:
section (canvasapi.section.Section): Canvas <Section> object
user_id (int): user ID to request assignments for
Returns:
[type]: [description]
"""
submissions = section.get_multiple_submissions(
student_ids=[user_id],
include=["assignment", "submission_history"],
workflow_state="unsubmitted",
)
if filter_results:
filtered = filter(submissions)
missing_list = [
item.assignment["name"]
for item in filtered
if item.workflow_state == "unsubmitted" and item.excused is not True
]
else:
missing_list = [
item.assignment["name"]
for item in submissions
if item.workflow_state == "unsubmitted" and item.excused is not True
]
return missing_list
def filter(submissions):
"""Filter submission in the assignment list based on a criteria.
As written, this looks at the assignment title
Args:
submissions (list): List of Canvas assignments
Returns:
[list]
"""
# Filter based on any criteria.
allowed = ["Criteria 1", "Criteria 2"]
# Check for the criteria in the assignment name.
# You can filter based on any key in the assignment object
filtered = [
item
for item in submissions
if any(word in item.assignment["name"] for word in allowed)
]
return filtered
if __name__ == "__main__":
main()