finalgrade
Final grades from a Gradescope or Canvas csv export — category weights, dropped lowests, late penalties, per-student waivers.
→ matthigger.github.io/finalgrade
Build your grading policy in the browser. Drop in your gradebook, click through the policy, watch every grade move as you change it, and download the results. Nothing to install.
Your grades never leave your computer. The page downloads a Python interpreter and runs this package inside the tab — there is no server to send anything to. Once it has loaded you can disconnect from the network and it keeps working.
The policy you build downloads as a policy.yaml. Keep it: drop it back in
next time to pick up where you left off, hand it to a TA, or run it from the
command line. Nothing is stored between visits, so that file is the thing to
save.
What it does
- Category weights — homework 50%, exams 50%. Assignments match categories
by substring, so
hw1…hw9land inhwwithout listing them. - Drop lowest — the n worst scores in a category, never the extra credit.
- Late penalties — a rate per day, a bank of excused days per student, and a grace period so nobody emails you about 90 seconds. Per-student adjustments for DRC accommodations.
- Waivers — click a score to waive the assignment, click a late submission to forgive just the penalty. Computed as if the work was never assigned.
- Extra credit — points that count towards what a student earned but not towards what was available.
- Best of two — drag one score onto another for the makeup only one student sat, without inventing a course-wide rule for it.
- Work you haven't set yet — write a whole term's policy in one sitting; planned assignments count for nobody until the real column arrives.
- Letter grades — editable cutoffs, sensible defaults.
- Per-student breakdowns — a csv per student that ends with how the grade was reached: what was waived, what was late and what it cost, which scores were dropped, how the categories combined. It's the attachment for the email asking why a grade is what it is.
- Notes — free text on a student, stored beside the waiver it explains, so the reason outlives the email thread.
- Inspect — the distribution of any category or assignment, before and after your policy, where hovering a bar names the students in it. Not "what is the shape of the class" but "who is sitting just under the A− line?"
- Exports —
grade_full.csv, a Canvas upload merged by SIS id, and a Banner.xlsx.
It refuses to guess. Grades are hard to eyeball, so a policy that can't
mean what you intended is an error rather than plausible-looking numbers: a
category matching no assignment, a misspelled setting nothing reads, a
threshold written 93 where .93 was meant, a waiver on an email nobody has.
The error names the closest real setting or student.
Command line
The same code, same policy file, same results.
pip install finalgrade
finalgrade grade scope.csv # grades, and seeds a policy.yaml
finalgrade check scope.csv # what does this policy actually do?
finalgrade grade scope.csv --policy policy.yaml # with your edits
check answers "what will this do?" without computing any grades, reports
every problem at once, and exits non-zero when grading would fail — so it
works in a script:
$ finalgrade check scope.csv
assignment points submitted category
---------- ------ --------- ------------------------------------
hw1 1 1/5 hw
quiz1 4 5/5 (none) <- not graded in any category
category weight drop late assignments
-------- ------ ---- ------------------ -------------------------------
hw 50.0% 1 15%/day, 3 excused hw1, hw2, hw3
exam 50.0% - - (none) <- matches no assignment
error: category matches no assignment: exam
warn : assignment not in any category: quiz1
Other flags: -o output path, --late_csv late days per student-assignment,
--per_student a csv each, --new-policy a fresh one, -q quiet. Run
finalgrade grade --help for the full list.
Grading from Canvas
grade also takes a Canvas export (Grades > Export), told apart by its
columns. Two differences are forced by what Canvas puts in the file: there are
no submission times, so late penalties are refused rather than silently
computing to zero; and students may be keyed by SIS ID rather than email.
Excused (EX) becomes a waiver. In exchange, a policy seeded from a Canvas
export takes its suggested categories from your Canvas assignment groups
rather than guessing from names.
Uploading grades
finalgrade canvas grade_full.csv canvas.csv --scale100
finalgrade banner grade_full.csv 202310 -c 12345 -c 67890
See doc/upload_canvas.md and doc/upload_banner.md.
Policy reference
doc/policy.md — every setting a policy.yaml can hold, and
everything that gets checked.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file finalgrade-0.2.0.tar.gz.
File metadata
- Download URL: finalgrade-0.2.0.tar.gz
- Upload date:
- Size: 56.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acb3b7b78d94d91b7435600c214110b74f814c74f2f2bdabdc1b7d6b093e353e
|
|
| MD5 |
7006cefed5a989cf7197c1b25abdfdfc
|
|
| BLAKE2b-256 |
26ef2ea55891326d1a3e55875195566fa5e445fcf381a81049dca8e2b30feccb
|
File details
Details for the file finalgrade-0.2.0-py3-none-any.whl.
File metadata
- Download URL: finalgrade-0.2.0-py3-none-any.whl
- Upload date:
- Size: 63.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fadb49ad20f0398fe1ff2be427204768094689c6e351cf1403115bacf0d5a25
|
|
| MD5 |
81e4e59f99aab3e6eca171d602042f03
|
|
| BLAKE2b-256 |
36016a889f5c62637319c4b7e315a8fd7c734915c681ae40bb96b7d6b24c07b9
|