-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #63 from dbosk/adds-more-summary-modules
Refactors grades summary modules, adds disjunctive maximum
- Loading branch information
Showing
12 changed files
with
343 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
SUBDIR+= cli | ||
SUBDIR+= grades | ||
SUBDIR+= hacks | ||
|
||
INCLUDE_MAKEFILES=../../makefiles | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,3 @@ login.py | |
login.tex | ||
results.py | ||
results.tex | ||
summary.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
grades.tex | ||
mysum.py | ||
conjunctavg.tex | ||
conjunctavg.py | ||
disjunctmax.tex | ||
disjunctmax.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
NOWEAVEFLAGS.tex= -n -delay -t2 | ||
NOTANGLEFLAGS.py= | ||
|
||
|
||
.PHONY: all | ||
all: grades.tex | ||
all: conjunctavg.py conjunctavg.tex | ||
all: disjunctmax.py disjunctmax.tex | ||
|
||
grades.tex: conjunctavg.tex | ||
grades.tex: disjunctmax.tex | ||
|
||
|
||
.PHONY: clean | ||
clean: | ||
${RM} grades.tex | ||
${RM} conjunctavg.py conjunctavg.tex | ||
${RM} disjunctmax.py disjunctmax.tex | ||
|
||
|
||
INCLUDE_MAKEFILES=../../../makefiles | ||
include ${INCLUDE_MAKEFILES}/tex.mk | ||
include ${INCLUDE_MAKEFILES}/noweb.mk | ||
include ${INCLUDE_MAKEFILES}/pkg.mk | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
""" | ||
Package containing modules to summarize assignment groups in different ways. | ||
For a module to be used with the `canvaslms results -S module` option, the | ||
module must fulfil the following: | ||
1) It must contain a function named `summarize_group`. | ||
2) `summarize_group` must take two arguments: | ||
I) `assignment_list`, a list of `canvasapi.assignment.Assignment` | ||
objects. | ||
II) `users_list`, a list of `canvasapi.user.User` objects. | ||
3) The return value should be a list of tuples. Each tuple should have the | ||
form `(user, grade, grade date)`. | ||
See the built-in modules below. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
\section{Conjunctive average} | ||
|
||
We have one requirement on the summary module: it must contain a function | ||
[[summarize_group]] that takes two arguments; | ||
the first being a list of assignments, | ||
the second being a list of users. | ||
The [[summarize_group]] function is the function that the above code will call. | ||
This gives the following outline of the module. | ||
<<conjunctavg.py>>= | ||
""" | ||
Module that summarizes an assignment group by conjunctive average. | ||
|
||
Conjunctive average means: | ||
|
||
1) We need all assignments to have a non-F grade. | ||
2) If there are A--F assignments present, we will compute the average of | ||
those grades. For instance; an A and a C will result in a B; an A and a B | ||
will result in an A, but an A with two Bs will become a B (standard | ||
rounding). | ||
""" | ||
|
||
import datetime as dt | ||
|
||
<<helper functions>> | ||
|
||
def summarize_group(assignments_list, users_list): | ||
"""Summarizes a particular set of assignments (assignments_list) for all | ||
users in users_list""" | ||
|
||
for user in users_list: | ||
grade, grade_date = summarize(user, assignments_list) | ||
yield (user, grade, grade_date) | ||
@ | ||
|
||
|
||
\subsection{Summarizing grades: assignment grades to component grade} | ||
|
||
Now we will describe the [[summarize]] helper function. | ||
We want to establish two things: the most recent date and a suitable grade. | ||
|
||
For the most recent date, we just check the dates as we iterate through the | ||
submissions. | ||
|
||
For the grade, as we iterate through we look for P/F and A--E grades. | ||
We can then check for Fs among the P/F grades, if we find an F the summarized | ||
grade will be an F. | ||
If we find no Fs, then we can compute the average over all A--E grades and use | ||
that as the final grade. | ||
<<helper functions>>= | ||
def summarize(user, assignments_list): | ||
"""Extracts user's submissions for assignments in assingments_list to | ||
summarize results into one grade and a grade date. Summarize by conjunctive | ||
average.""" | ||
|
||
pf_grades = [] | ||
a2e_grades = [] | ||
recent_date = dt.date(year=1970, month=1, day=1) | ||
|
||
for assignment in assignments_list: | ||
submission = assignment.get_submission(user) | ||
grade = submission.grade | ||
|
||
if grade is None: | ||
grade = "F" | ||
|
||
if grade in "ABCDE": | ||
a2e_grades.append(grade) | ||
else: | ||
pf_grades.append(grade) | ||
|
||
grade_date = submission.submitted_at or submission.graded_at | ||
|
||
if not grade_date: | ||
grade_date = recent_date | ||
else: | ||
grade_date = dt.date.fromisoformat(grade_date.split("T")[0]) | ||
|
||
if grade_date > recent_date: | ||
recent_date = grade_date | ||
|
||
if not all(map(lambda x: x == "P", pf_grades)): | ||
return ("F", recent_date) | ||
|
||
if a2e_grades: | ||
return (a2e_average(a2e_grades), recent_date) | ||
return ("P", recent_date) | ||
@ | ||
|
||
\subsection{Computing averages} | ||
|
||
To compute the average for the A--E grades; we will convert the grades into | ||
integers, compute the average, round the value to an integer and convert back. | ||
<<helper functions>>= | ||
def a2e_average(grades): | ||
"""Takes a list of A--E grades, returns the average.""" | ||
num_grades = map(grade_to_int, grades) | ||
avg_grade = round(sum(num_grades)/len(grades)) | ||
return int_to_grade(avg_grade) | ||
|
||
def grade_to_int(grade): | ||
grade_map = {"E": 1, "D": 2, "C": 3, "B": 4, "A": 5} | ||
return grade_map[grade] | ||
|
||
def int_to_grade(int_grade): | ||
grade_map_inv = {1: "E", 2: "D", 3: "C", 4: "B", 5: "A"} | ||
return grade_map_inv[int_grade] | ||
@ | ||
|
Oops, something went wrong.