Skip to main content

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 hw1hw9 land in hw without 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?"
  • Exportsgrade_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
$EDITOR policy.yaml                               # weights, drops, late rules
finalgrade check scope.csv --policy policy.yaml   # what will that policy do?
finalgrade grade scope.csv --policy policy.yaml   # grade with it

The seeded policy.yaml lists your assignments by the names a policy has to use and suggests a category split, commented out. Editing it is the middle step — until you do, every assignment counts in proportion to its own points.

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. It wants the policy named outright and will not write one for you: a report on a file finalgrade just seeded tells you only what finalgrade guessed.

$ finalgrade check scope.csv --policy policy.yaml
grade source : scope.csv (gradescope)
students     : 5
assignments  : 4 graded, 0 excluded

assignment  points  submitted  category
----------  ------  ---------  ------------------------------------
hw1         1       1/5        hw
hw2         2       2/5        hw
hw3         3       5/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 (assignments are: hw1, hw2, hw3, quiz1)

policy has an error, grading would stop here

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

finalgrade-0.2.1.tar.gz (57.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

finalgrade-0.2.1-py3-none-any.whl (64.6 kB view details)

Uploaded Python 3

File details

Details for the file finalgrade-0.2.1.tar.gz.

File metadata

  • Download URL: finalgrade-0.2.1.tar.gz
  • Upload date:
  • Size: 57.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for finalgrade-0.2.1.tar.gz
Algorithm Hash digest
SHA256 8e0545599789aef08efb8a4b80dcbcc3b37488069c8d860c68c17284936e600e
MD5 1cb310d1bf81df8316bc5c82de4469df
BLAKE2b-256 5ae17ca90f49358a92b08b2f62b50f3b165fc05e31dc3c82478e553b316d95f9

See more details on using hashes here.

File details

Details for the file finalgrade-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: finalgrade-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 64.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for finalgrade-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 fbf4ae51e69a5c999a23ec68376fde7705288aed97f3961c4b67dcda6dbbf548
MD5 191e5ce3ff68543c7383b84dcd80093c
BLAKE2b-256 0c59d5cc6b77f17b775cc433b06cd3dd248bb8a641836a700dc7a9202262cdd5

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

This release

0.2.1 This release

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page