Functional Weave
Code in Rust

education.grade-boundaries@1.0.0

README.md

1,548 bytes · view raw

# education.grade-boundaries

Turns a raw mark into a grade using a boundary table the caller supplies:
each grade starts at its `minMark`, inclusive, and a mark below the lowest
boundary is ungraded (`grade` is null). It also says which grade is next and
how many marks short the candidate is, which is what a results page or a
"marks to the next grade" report shows.

## Why the table is an argument

Grade boundaries are not rules in force: they are set per paper, per series,
after marking (AQA, Pearson, OCR and WJEC publish a fresh table for every
exam series), so there is nothing a registry could carry as dated data that
would be right for your paper. Pass the published table for the paper and
series you are grading.

## Decisions

- **Inclusive lower bounds.** A mark exactly on a boundary earns that grade:
  boundaries are published as "the minimum mark for grade X".
- **Any order.** Tables are usually printed highest grade first; the rows are
  sorted by `minMark` here, so the order you pass does not matter.
- **Ungraded is null, not "U".** Different specifications call it U, X, Fail
  or "not classified"; label it yourself. A table whose lowest row has
  `minMark` 0 has no ungraded marks at all.
- Integer marks only. A paper marked in halves should be doubled (mark and
  maxMark and boundaries) before calling.

## Errors

A mark outside 0 to `maxMark`, a non-integer mark, an empty table, a boundary
outside 0 to `maxMark`, a grade named twice, or two grades sharing one
boundary (the table would be ambiguous) all raise.