# education.weighted-grade The overall percentage for a module or course made of weighted components: coursework worth 40% marked out of 60, an exam worth 60% marked out of 120, and so on. Each component contributes `mark / outOf x weight`, the sum is kept as an exact fraction (`percent`), and it is rounded once, at the end, to the places and rounding mode the caller names (`scaled`). ## Why exact, then one rounding Component percentages are usually repeating decimals (45 out of 60 is fine; 88 out of 120 is 73.333...). Adding them as floats can land a hair under a .5 and round the wrong way: 10/30 at 50% plus 29/300 at 50% is exactly 21.5, which floats compute as 21.4999999..., so a half-up round to whole marks gives 21 instead of 22. A vector pins that case. Rounding each component before adding is a second, commoner source of drift and is not done here. ## Decisions - **Weights are basis points and must total 10000.** A table that adds up to 99.99% is almost always a typo, so it is refused rather than normalised. Equal thirds are 3333, 3333, 3334: say which component carries the extra basis point. - A weight of 0 is allowed (a formative piece recorded alongside), and adds nothing. - `scaled` is an integer so no float ever carries the answer: 74.3% at one decimal place is `743`. Grade the student with `education.grade-boundaries` on the scaled value if your boundaries are in percent. - Components not yet sat, capped resits and compensation rules are the institution's regulations and are out of scope: pass only marks that count. ## Errors An empty list, a mark outside 0 to `outOf`, `outOf` below 1, a negative weight, weights not totalling 10000, `decimals` outside 0 to 6, or an unknown rounding mode all raise.