"""Failure mode: one sign slip in one value. This routine keeps the first few Bernoulli numbers in a table and computes the rest with the binomial recurrence. The table was typed in by hand, and one minus sign did not make it: the entry for ``B4`` reads ``1/30`` where the value is ``-1/30``. Every other index, in the table and beyond it, is right. The magnitude is right and the type is right, so the wrong value looks like any other. ``1/30`` and ``-1/30`` are equally plausible strings to anyone with no reference of their own; Unit 6 has you derive it by hand so that ``1/30`` reads as a fault rather than as something you may have misremembered (Unit 10). Expected checker diagnosis: a first divergence at ``n=4`` (expected ``-1/30``, got ``1/30``) and no named failure mode. Only one value disagrees, so none of the patterns the checker names fits: the comparison locates the fault and does not classify it. """ from fractions import Fraction from math import comb # The first values, typed in from a table. The entry for 4 has lost its sign. _TABLE = { 0: Fraction(1), 1: Fraction(-1, 2), 2: Fraction(1, 6), 3: Fraction(0), 4: Fraction(1, 30), } def _recurrence(n: int) -> Fraction: values = [Fraction(0)] * (n + 1) for m in range(n + 1): values[m] = Fraction(1) for k in range(m): values[m] -= Fraction(comb(m, k) * values[k], m - k + 1) if n == 1: return -values[n] return values[n] def bernoulli(n: int) -> Fraction: """Return B_n under the first convention (B1 = -1/2).""" if n < 0: raise ValueError("n must be >= 0") if n in _TABLE: return _TABLE[n] return _recurrence(n)