JCL Grading

Free open-source exam grading for convention or classroom use: build the answer sheet, write the key, print and scan, grade, and fix unclear marks.

How this works

  1. Connect to the grading server. You only do this once per browser.
  2. Design and print the answer sheet.
  3. List the tests that go on it.
  4. Enter the answer keys. This can wait until after the exam if you would rather.
  5. Advanced settings, which most people can skip.
  6. Scan the completed sheets and upload them here.
  7. Fix anything unclear, and download the results.

Where data is stored: Your setup, answer keys, thresholds, and results are saved locally in this browser on this device. Uploaded scan PDFs are temporarily sent to the grading server for processing, then deleted; they are not retained on the server.

1 Connect to the grading server Not connected

Ask whoever set the server up.

An invite link fills these two boxes in for whoever opens it. The passphrase is inside the link — anyone who has it can grade, so send it the way you would send the passphrase itself, and not somewhere public. Step 2 has a second button that adds your sheet design to the link.

2 Design and print the answer sheet Default wording

You can change the wording and Latin levels. The bubbles and corner marks are fixed. Reprint after any change.

Latin levels

Allowed or excluded tests use these names, so renaming one here renames it everywhere.

Write-in lines

These are not read by the software — only the bubbles are. They exist in case the Student ID goes wrong.

Directions

That link contains the invite from step 1 as well as everything in this step. Send this link rather than the plain invite if you have customized any wording.

Bubble darkness

How dark the bubbles themselves are printed. An empty bubble is not blank paper — it is a printed ring with a letter inside it — so this is the floor every reading sits on, and printing it lighter leaves more room between an untouched bubble and a lightly-pencilled one. Every sheet in a batch must be printed at the same setting.

Note to students

The sheet already shows a filled bubble beside the three ways it is usually got wrong — a cross, a tick, and a half-scribble — which is read without reading. This adds a line of your own underneath. Most sheets do not need one.

Printing

  • Print double-sided (your printer may call this duplex).
  • Use 100% scale if possible. ‘Fit to page’ is acceptable if your printer requires it, but it makes the bubbles smaller.
  • Do not print two pages to a sheet.
3 List the tests No tests yet

Test ID: the 4-digit number for this test. Print this number on the test booklet.

Levels: who may take the test. Two tests may share a Test ID as long as the levels do not overlap.

Test name Test ID Levels that may take it
4 Enter the answers No answers yet

Enter the correct answer for questions 1–80 for each test.

Pick one of the two options.

  • A. Type or paste directly (easiest).
  • B. Upload a spreadsheet.

A. Type or paste the answers

Paste directly into each box, and it will try to parse whatever you have.

Rewrites every box as one space-separated line, so you can see what the page made of a paste.
or
B. Upload a spreadsheet

Download the template, type the answers, then bring the file back.

Review answers (optional)

Every answer is editable here. Edited cells are shown in bold.

What goes in a cell

C The answer is C.
ABD The answer is A, B and D. The student must bubble all three.
A|BD Either is accepted: A on its own, or B and D together.
X Exclude this question from scoring. Use if you discover after the test that a question should not count.
- You have not entered this answer yet (placeholder).

X means the question is finished and will not be scored, while - just means you have not typed it in yet.

Technical notes
  • Case does not matter. abd and ABD are the same answer, and so are x and X.
  • Order does not matter. BD and DB are the same answer.
  • More than two alternatives are fine. A|B|CD accepts A, or B, or C and D together. There is no limit on how many you list.
  • A repeated letter is an error. AA is rejected, as is a stray | such as A|, and any letter outside A–E.
  • Options A and B can be mixed. They write to the same answers, and the grid shows whatever is there.
  • Uploading merges, instead of replacing. A column whose Test ID matches a test you already have updates that test; anything else is added. Tests not mentioned in the file are left alone, and Undo upload puts everything back.
  • The file is Keys.csv. The first column has headers Name, Test ID, Excluded, then 1 to 80, with one further column per test.
  • Excluded may be written as Allowed instead, naming the levels that may sit each test rather than the ones that may not. Use one row or the other, not both. Excluded is left blank by default, which bars nobody and stays right when you add or rename a Latin level later.
5 Advanced Defaults

You don’t need to change this for most runs.

Which tests to grade

Every test on the sheet is graded by default. An unticked test is not read at all: no results, no answer key needed, and nothing on the review sheets. Useful when a test is scored elsewhere, or when its key is not ready yet.

Which sides were scanned

Scanning one side only is for when a test is being re-marked on its own: the pages are then read one at a time instead of in front-and-back pairs, and a page of the other side is set aside rather than read. The front carries Test 1 and the back carries Tests 2 and 3, so a side you leave out takes its tests with it.

Marked-up scans

Marked-up scans show which bubbles were read as filled, along with the correct answer. They make a run noticeably slower, so leave this off unless you are demoing or debugging.

Thresholds

Every bubble is measured for darkness on a scale from 0 (blank paper) to 1 (solid black). A bubble darker than the cutoff counts as filled. One that lands between the review threshold and the cutoff goes to step 7 for a person to decide. Anything fainter is ignored.

Where those two cutoffs fall depends on the scanner, the paper, and how hard the students pressed. So the server measures them from each batch of scans rather than using fixed numbers.

6 Scan and grade Nothing graded

At the scanner: required

  • Scan each sheet as two consecutive PDF pages: front first, back second. Do not scan all fronts first and all backs afterward. The run stops if the pages do not alternate, rather than grade the wrong back against the wrong front.
  • Turn off blank page removal. It will quietly drop a lightly-marked page, and a page dropped there is a page nobody knows is missing. Blank pages are counted and reported here instead.
  • Do not crop into the four corner marks. The reader finds the grid from them, so a tight auto-crop can make a page unreadable.

At the scanner: recommended

  • 200–300 dpi. Color, grayscale or black and white all work; grayscale keeps the files small.
  • Deskew and auto-rotate can be left on or off. The reader straightens the page itself and corrects one that comes through sideways or upside down, so neither setting will break a batch.
  • Save one PDF per batch of about 25 sheets — your scanner can usually start a new file every 50 pages for you. This keeps each upload small enough for the server to handle; the hard limit is 40 MB. If a scan is too big, break it into smaller pieces and add each as its own batch.

Grading

A batch is one PDF from the scanner, holding whole sheets. Each is graded on its own and keeps its own results, so you can start grading the first stack while the rest is still being scanned.

If a mark was read wrong or the key was wrong, fix it in step 7: that re-scores from the results already here, without re-reading the scans. If the paper itself needs re-reading, scan it again and add it as a new batch — a batch that has been graded stays as it was.

7 Fix unclear marks Nothing to review

An unclear bubble is too faint to be definitively filled. A missing bubble is a required field it could not read at all. A question left blank is not an error: that is the student’s choice.

Each file asks for one correction per row. Open it, check the paper, fill in the answer, mark the row Done, and upload it below. The Done column should read TRUE. A row you have not ticked is left exactly as it was and comes back as a shorter file to finish next time, so you can do half now and half later.

Correcting something that was never flagged

You can add rows too. A student whose answer was read confidently wrong never reaches these files, and a row you write by hand is how to fix it.

A row needs enough of File, Page, Test, Test ID and Student ID to pick out exactly one test. The Student ID and the Test ID normally do it. Then the question number and the answer:

Student IDTest IDQuestion ABCDE Done
06767106717 FALSETRUEFALSEFALSE FALSETRUE

That says: on student 06767’s test 1067, question 17 is B. Leave every option FALSE to record that the student answered nothing. If a row names no test, or names more than one, it is reported back rather than guessed at.

In Google Sheets, CAJCL → Add a correction row sets one up with the checkboxes already in place.

Google Sheets is optional

Any editor that saves CSV will do, even a text editor. Nothing here needs Google Sheets.

Sheets is worth setting up when several people are correcting at once. Everyone opens the same file and works through different rows at the same time, and you download it once at the end. The script below is a convenience on top of that — it adds checkboxes so nobody has to type TRUE, restores the leading zeros on Student IDs that a spreadsheet would otherwise eat, fits the columns, and trims the blank rows.

  1. Create a Google Sheet shared with whoever is helping.
  2. Extensions → Apps Script, paste in Sheet.gs, and Save. It carries the Latin levels from step 2, so the dropdown it adds matches the sheet you printed.
  3. Click the Triggers (clock) icon → Add Trigger.
    • function — onSpreadsheetChange
    • source — From spreadsheet
    • type — On change
    • Save and accept the prompt.
  4. For each file: File → Import → Insert new sheet(s). It has to create a new sheet — ‘Replace current sheet’ will not trigger the script.
  5. When the sheet is finished, File → Download → Comma-separated values.