Skip to content
nicfreeman1209 edited this page Jan 8, 2021 · 97 revisions

pdf-marker


This software is aimed at efficient bare-bones style marking of pdfs, with few annotations needed beyond the scores.

Instructions for use

I assume you have a functional Python 3 installation (https://www.python.org/downloads/) and a command line. The code should be fully portable between Windows/Linux/Mac. It was tested against Python 3.8, less recent Pythons might also work.

Here is the workflow, for a single batch of marking:

  1. Run python pdf-marker.py.
    • Any error messages will be shown on the command line.
    • You may need to pip install -r requirements.txt.
  2. Navigate as prompted to the folder containing your raw scripts.
    • Your folder should contain precisely one pdf script per candidate.
    • Once the scripts are loaded in, your current page will be remembered.
  3. Annotate your pdfs - see below for annotation controls.
  4. Press "Output scripts", and choose your output dir.
    • New outputs are generated for all scripts whenever 'output scripts' is pressed.

To enable scoring, you place a file called fullmarks.json in the same folder as your scripts. This file contains your mark scheme in a json format. When present it enables extra features related to marking and automated tallying/checking. See below for details.

Annotation controls

keybind / mouse function modifiers
D next page + shift: skip to next candidate
+ control: skip 5 pages or 5 candidates
A previous page + shift: skip to previous candidate
+ control: skip 5 pages or 5 candidates
S toggle strike mark
Left mouse add circle on existing circle, left/right mouse: increase/decrease size
Right mouse
(empty space)
add 'justify'
Right mouse
(on annotation)
remove or shrink existing annotation
Mouse buttons 4/5 add forwards/backwards arrow suggested usage: to indicate if work is out of order
C clear all annotations on current page

When automated tallying is enabled, a margin is displayed. Within that margin:

Left mouse place part-mark on existing part-mark:
left/right mouse: increase/decrease part-marks
+ shift: add/increase/decrease by 5 marks
Middle mouse place a tally point
Right mouse
(empty space)
add a zero part-mark
Right mouse
(on annotation)
decrease/remove part-marks and tally points
+ shift: decrease/remove by 5 marks
W jump to first candidate for which
checking currently fails

Stylus is supported, to draw or write onto the page. Each 'connected' use of the stylus is treated as a single annotation. Pressure sensitivity is currently not supported.

Mark schemes and automated tallying

When a valid fullmarks.json file is present, additional features are enabled. A margin appears on each page, into which part-marks can be recorded, alongside tally points.

The important bit: Part-marks will now be checked against the mark scheme, to ensure that:

  1. the correct number of questions are marked per script;
  2. the correct number of parts are marked per question;
  3. no part-mark exceeds the available total for the corresponding part-question;
  4. all pages have been marked.

Now, when you click 'Output scripts', each script will be checked against the above criteria. If they do not all pass, you will automatically be taken to the first script that does not pass. If they do all pass, the annotated pdfs will be output, alongside various csv files containing candidate marks, part-marks and other useful information.

When there is space on the screen (i.e. if your screen is not in portrait mode), text will display the current status of the current candidates marks, against the above criteria. If the checks do not pass, a message will explain why not.

Part-marks and tally points must be entered into the margin in the correct order. Precisely one tally point is expected for each question in the mark scheme, after all its part-marks. Each tally point automatically adds up all part-marks awarded since the previous tally point. In between tally points, the number of times that part-marks are awarded should match the number of parts of the corresponding question.

Json format for mark schemes

The json format required for the mark scheme is best illustrated by example. The example in the repository has the structure:

[
	["a.i 2", "a.ii 1", "b 5"],
	[". 2"],	
	["a 2", "b 3"]
]

This corresponds to 3 questions, one per line.

  • Q1 has three parts: a.i, a.ii and b, with part-marks 2, 1 and 5 available respectively.
  • Q2 has one part and has 2 marks available (you might think of this as "no" parts).
  • Q3 has two parts: a and b, with 2 and 3 marks available respectively.

Each part-question must be in the form "xyz n" where xyz is the name of the part-question (no whitespaces allowed) and n is the number of part-marks available for this part-question. Each line corresponds to a question. Note that the final question does not have a comma at the end of its line, but all other questions do - json is fussy.

Formally: its a json list of lists of strings, top level index is the question number, second level index is question part, each string describes a part-question as explained above.

More complicated use cases

  • If extra candidates need to be added mid-way through marking, simply place their pdfs into the same scripts folder, and use the "Input Scripts" button to reload the folder. Your existing work will not be overwritten.
  • You can work through multiple independent sets of marking simultaneously. Use the "Input Scripts" button to switch between the directories in which your sets of scripts are stored.
  • If there are multiple markers (e.g. one for each question) just pass the whole scripts dir, including the sub-directory _pdf-marker-internal/, manually between markers as appropriate. Currently, such markers must work in series (and not in parallel), although this feature could be added.

Troubleshooting

Report bugs to the this repository, for anything non-trivial please attach the pdf-marker.log file.

Loading scripts will create the subfolder ./_pdf-marker-internal/ where the program keeps all its internal data. In normal usage, leave that folder alone!

To restart the process for a single candidate, close pdf-marker, go into ./_pdfmarker-internal/ and delete the subfolder corresponding to the candidate. Then run pdf-marker and load in the scripts again - existing work is not overwritten, but the deleted folder will be regenerated into a clean unannotated copy. To fully restart the process delete the whole ./_pdfmarker-internal/ folder.