Gradebook

Column Semantics
In the Pawtograder gradebook system, columns represent individual grade components that collectively form a student’s overall course performance. Each column is defined by a unique slug identifier, a human-readable name, and a maximum score, but their power lies in their flexibility for grade calculation and data sources. Columns can be:- Manually entered by instructors who directly input grades cell-by-cell (supporting both whole numbers and decimal values)
- Imported from CSV files to bulk-load grades from external systems (with full metadata tracking of the import source and date)
- Linked to programming assignments through the assignment reference system
assignment-<assignment-slug>, takes its maximum score from the assignment’s total points, starts unreleased, and gets the score expression assignments("<assignment-slug>"). You cannot edit that expression from the column editor.
Expressions: The most flexible column type uses score expressions that reference other columns or assignments, building a dependency graph for calculated grades. Using MathJS syntax, you can write formulas like (mean(gradebook_columns("homework-*")) + mean(gradebook_columns("project-*"))) / 2 to compute weighted averages, drop lowest scores, or apply curve adjustments. Score expressions can define functions and use MathJS’s math and utility functions, except that import, createUnit, reviver, and resolve are blocked and the arithmetic and comparison operators are replaced with gradebook-aware versions. Any grade that is automatically calculated can also be manually overridden on a case-by-case basis.
Student Visibility of Grades
The “released” status in the gradebook determines whether students can see a particular column and its grades. For imported or manually-entered columns, instructors have direct control over this visibility — they can release columns to make them visible to students or unrelease them to hide grades during grading periods or for sensitive assessments. This setting is at the column level only (you can’t release or unrelease individual grades). For columns that are automatically calculated by Pawtograder (via an expression), students always see the current calculation based only on what they can see. For example, a column defined as the average of all homeworks shows each student the average of the homework columns you have released to them.Staff-Only Columns
When creating or editing a column, you can check Staff-only column (hidden from students until you release it). These columns are hidden from students until you release them. While unreleased, students cannot see the column definition or their grades. When you release a staff-only column, Pawtograder does two things in a single transaction: it copies the current private scores into the students’ public rows, and it clears the staff-only flag so the column behaves like a normal column from then on. Release is blocked while any cell in the column is still recalculating. If you try, you get a “Column is recalculating” error and nothing changes; wait and retry. Unreleasing a column clears the students’ public score, but only for manually-entered columns and for columns still marked staff-only. Unreleasing a released calculated column does not clear anything. Staff-only columns are useful for internal grading calculations, curve adjustments, bonus calculations, or draft grade formulas you want to finalize before sharing with students.Automatic Recalculation of Dependent Columns
When you release or unrelease a gradebook column, Pawtograder automatically enqueues recalculation for all columns that depend on it. This ensures that calculated columns (those using expressions) always reflect the current visibility state and scores of their source columns. For example, if you have a “Final Grade” column that references “Homework Average,” releasing the homework average will trigger the final grade to recalculate for all students, ensuring they see accurate totals based on what’s now visible to them.Managing Columns
Reordering Columns
You can reorder gradebook columns to organize them logically:- Drag and drop: Click and drag the grip handle in any column header to reorder columns
- Move left/right: Open the column menu (the chevron in the column header) and select Move Left or Move Right to shift a column one position
- Auto-layout: Click the Auto-layout columns button (grid icon) in the toolbar. Auto-layout first sorts every column by slug using a natural alphanumeric sort, so
lab-2comes beforelab-10. It then makes a second pass that moves each calculated column after the columns it depends on, so dependencies always appear to the left of the columns that use them.
The Column Menu
The chevron in each column header opens a menu with:- Show Filter / Hide Filter: toggle the per-column filter input
- Sort Ascending, Sort Descending, Clear Sort
- Edit Column: open the column editor (name, maximum score, score expression, render expression, and staff-only)
- Move Left, Move Right
- Release Column, Unrelease Column: shown only for manually-entered columns and for staff-only columns
- Convert Missing to 0: shown only for manually-entered columns and for columns whose score expression starts with
assignments( - Delete Column
Manual Grade Entry
You can manually enter or edit grades directly in the gradebook by clicking on any cell. The gradebook accepts both whole numbers and decimal values, so you can enter grades like8.5 or 92.75. This is useful for assignments with partial credit or weighted scoring.
The cell editor also carries three per-grade flags:
- Droppable: this grade is eligible to be dropped by
drop_lowest - Excused: the student is excused from this item
- Missing: the grade has not been entered (see below)
Missing Grades
Missing is a distinct state from a score of 0. A missing grade does not count as a zero: a calculated column that depends on one is marked “not final” rather than silently computing a lower score. When you have finished grading an item and want the missing entries to count as zeros, open the column menu and choose Convert Missing to 0. This setsscore = 0, clears the missing flag, and stamps the note Missing value converted to 0 on every affected grade in the column. It cannot be undone, and it is only offered for manually-entered columns and for columns whose score expression starts with assignments(.
Gradebook Recalculation
When gradebook columns use expressions that reference other columns, Pawtograder automatically recalculates affected grades when dependencies change. This recalculation process runs asynchronously in the background to maintain performance for large courses.- When a grade changes, the system enqueues a recalculation job for each affected gradebook row and marks that row dirty and recalculating.
- Each enqueue also bumps a per-row version counter, which invalidates any worker already computing that row.
- A background worker takes each job, computes the row, and writes the result back only if nothing has changed in the meantime. A result computed from inputs that have since moved is discarded rather than overwriting the fresher value.
- Mismatched rows are re-enqueued with an attempt counter and exponential backoff. Past a retry ceiling the row goes to a dead letter queue instead of cycling forever.
”What If” Grade Calculations
What-If is a student-facing mode that lets students explore hypothetical grade scenarios by temporarily adjusting their own scores. It answers questions like “What grade do I need on the final exam to get an A?” or “How will my grade change if I skip this assignment?” When a student uses What-If:- They can click any grade card that is not itself calculated from other gradebook columns and type a hypothetical score. Columns that depend on other columns are read-only, since those are the ones What-If recomputes.
- Calculated columns update immediately to reflect the hypothetical scenario.
- All changes are temporary and client-side only. No actual grades are modified.
- Simulated cards are highlighted with an info background so they stand out from real grades.
- To undo a simulation, clear the input for that grade. There is no bulk reset control.
- A grade that has a staff override is never replaced by a simulation.
What-If does not apply to the staff gradebook. The instructor view renders the same student grade components read-only, so there is no staff-side scenario modeling.
Importing Grades
To import grades, instructors use a 3-step wizard:- File Selection: Click the Import Columns button and select a CSV file from your computer, which the system parses client-side to extract tabular data.
- Column Mapping: Choose which CSV column contains student identifiers and select whether they are email addresses or student IDs. For each remaining CSV column, decide whether to map it to an existing gradebook column for updates, create a new column (requiring you to set the maximum score), or ignore the column entirely. The system automatically detects email columns if present.
- Preview & Confirm: Review a comprehensive preview table that shows exactly what changes will occur, highlighting grade updates with strikethrough old values and bold new values, warning about students in the CSV who aren’t enrolled in the course, and providing alerts when attempting to override calculated column scores. Only after reviewing this detailed preview can you click Confirm Import to execute the changes.
Expression Builder
When creating or editing a column with a score expression, Pawtograder provides an Expression Builder interface with live validation and debugging tools:- Live validation: As you type, the expression is parsed and validated in real-time. Parse errors and dependency errors (unknown column slugs, cycles) are shown immediately.
- Full-screen mode: Click Expression Builder to expand to a full-screen Monaco editor with additional features:
- Syntax highlighting and autocomplete: The editor provides syntax highlighting for the gradebook expression language, with autocomplete for built-in functions and column slugs. Typing inside
gradebook_columns("…")shows matching column slugs from your gradebook. - Hover documentation: Hover over any sub-expression to see its current evaluated value for the selected student.
- Student picker: Select a student to test the expression against their actual gradebook data.
- Per-line evaluation: See the intermediate value of each statement in your expression, displayed as inline annotations (e.g.
= 42) next to each line. - Result badges: A Score badge shows the numeric result, and a Rendered badge shows the rendered form when a render expression is set.
- Incomplete dependencies: A panel listing which dependency slugs are Missing and which are Not released for the selected student.
- Syntax highlighting and autocomplete: The editor provides syntax highlighting for the gradebook expression language, with autocomplete for built-in functions and column slugs. Typing inside
- Save blocking: The Save button is disabled while the expression fails to parse, references an unknown column slug, or would create a cycle. An evaluation error for the selected student does not block saving.
Expression Syntax
The gradebook expression system is built on MathJS, with added functions for grade calculations. The value of the last line is the student’s score for that column. If that value isundefined or null, the score is stored as null rather than as 0.
Comments start with #. MathJS has no // comment syntax, so a // comment is a parse error.
Core Syntax
Expressions follow standard mathematical notation with variables, operators, and functions:Every gradebook has an optional expression prefix. Pawtograder prepends it, followed by a newline, to every score expression and every render expression in that gradebook before evaluating. Use it for shared helper function definitions and constants you do not want to repeat in each column. There is no screen for editing it, so setting one takes a Pawtograder administrator.
Data Access Functions
gradebook_columns("slug-pattern")
Retrieves gradebook column data for the student being calculated. With a single slug it returns one object; with a pattern containing * it returns an array of objects, one per matching column.
The object carries the student’s whole grade record for that column, plus computed fields. The ones you will use:
score:number | null- The student’s score, with any override already appliedmax_score:number- The maximum score for the columnis_missing:boolean- Whether the grade is missing or not yet enteredis_excused:boolean- Whether the student is excused from this itemis_droppable:boolean- Whetherdrop_lowestmay drop this itemis_private:boolean- Whether this is the staff-visible row or the student-visible rowcolumn_slug:string- The slug of the source columnreleased:boolean- Whether the column is released to the studentscore_override,score_override_note,is_recalculating,incomplete_values,id
assignments("assignment-slug"[, "review-round"])
Returns the student’s total score for one review round on the assignment, not the assignment’s point value. The second argument selects the round and defaults to "grading-review". The valid rounds are self-review, grading-review, meta-grading-review, and code-walk.
As with gradebook_columns, a slug containing * returns an array. Unlike gradebook_columns, the values are plain numbers rather than objects, so they work with sum but not with mean or drop_lowest, both of which need a max_score per entry.
Array Processing Functions
countif(array, predicate)
Counts array elements matching a condition using lambda syntax. Returns undefined for an empty array.
sum(array)
Sums numeric values or the scores of gradebook objects, skipping null and undefined entries. Returns undefined for an empty array. A gradebook object with a null score contributes 0.
mean(array, weighted)
Calculates a weighted or unweighted average. weighted is a positional second argument that defaults to true; there are no named arguments in MathJS.
is_missing count as 0 points, unless they are also marked is_excused, in which case they are excluded from the average. Marking a grade excused on its own does not exclude it; the grade must be both missing and excused.
mean also silently drops entries it cannot average: undefined and null array entries, entries whose max_score is missing, null, or not greater than zero, and entries whose score is null while is_missing is false. If nothing is left, mean returns undefined.
mean returns a percentage on a 0-100 scale, not a raw point total. If your column’s maximum score is 100, the two happen to coincide; otherwise they do not.drop_lowest(array, count)
Returns the array with up to count of the lowest items removed.
score / max_score), not by raw score. Given a 10-point quiz scored 6/10 and a 100-point exam scored 70/100, the quiz ranks lower and is dropped first, even though 6 is the smaller number.
Only grades with the droppable flag set are eligible to be dropped, which is the default for new grades.
min(...) and max(...)
min and max accept any mix of numbers, gradebook objects, and arrays, flatten them, and use each gradebook object’s score. Entries that are null or undefined are skipped. With no usable values left, both return undefined.
Several functions return
undefined rather than 0 when they have nothing to work with: sum and countif on an empty array, mean with no averageable entries, min and max with no values, and case_when with no matching row. If that undefined reaches the last line of the expression, the column’s score is stored as null, and the cell renders as -.Conditional Logic
case_when([condition, value; ...])
Convenience function for multi-condition branching using matrix syntax:
case_when returns undefined, which stores as a null score. Include a true row as a default.
Comparison Functions
==, !=, >, >=, <, and <= are available and are replaced with gradebook-aware versions.
They return 1 or 0, not true or false. That is what makes them work inside case_when matrices, and/or chains, and arithmetic.
Complete Examples
Simple Counting Example
Complex Grade Calculation
Render Expressions
A render expression controls how a column’s score is displayed. It does not change the stored score. Set it in the Render Expression field of the column editor, next to the score expression. A render expression sees exactly two variables:score: the stored score, with any override already appliedmax_score: the column’s maximum score
round(score, 2). The gradebook’s expression prefix is prepended to render expressions too, so helpers defined there are available here. As with score expressions, import, createUnit, reviver, and resolve are blocked. If the expression produces multiple statements, only the last one is displayed.
Two states bypass the expression entirely: a grade flagged Missing renders as Missing, and a grade with no score at all renders as -.
Built-In Display Helpers
letter uses fixed breakpoints: 93 A, 90 A-, 87 B+, 83 B, 80 B-, 77 C+, 73 C, 70 C-, 67 D+, 63 D, 60 D-, and F below 60. You cannot change them; use customLabel for a different scale.
All three of letter, check, and checkOrX return (N/A) when score is undefined.
Exporting Grades
You can export gradebook data to CSV for external analysis or record-keeping. The export is built in the browser from data already loaded, so it downloads immediately.How to Export
- Click the Download Gradebook button at the bottom of the gradebook page
- Optionally check Use render expressions in CSV
- Click Download CSV
Export Options
Both options export the same set of students and columns; they differ only in how each cell is formatted.- Default: every cell is the stored numeric score, with any manual override applied. Score expressions are never exported; only their results.
- Use render expressions in CSV: for columns that have a render expression, the cell holds the rendered string that the gradebook displays, such as
Aor✔️, rather than a number. Columns without a render expression still export their numeric score.
The rendered export produces text, not numbers. Pick it when you want a human-readable transcript; leave it unchecked when the file feeds a spreadsheet formula or another grading system.
Export Contents
The first row is a header:Name, Email, SID, Course Section, Lab Section, Tags, then one column per gradebook column, in the gradebook’s display order.
One row follows per enrolled student. Students who have dropped the course are skipped.
The file is written with a UTF-8 byte-order mark so Excel opens it as UTF-8 instead of mangling non-ASCII characters. Every cell is quoted with internal quotes doubled, and any cell starting with =, +, @, or - is prefixed with an apostrophe to prevent spreadsheet formula injection.