Per-question score is now a float in [0.0, 1.0] snapped to a 21-level 0.05 grid, replacing the previous 0-1000 integer scale. Easier to read on a leaderboard, ties become acceptable rather than vanishingly rare, and small clock-skew differences no longer split rankings. DB schema: score is REAL now (SQLite type affinity is loose enough that existing rows still read fine, but new inserts go in as floats). Frontend: added fmtScore() helpers in admin.js and quiz.js to render two decimal places consistently (0.85, 1.20, 5.00) so float-arithmetic sums never display as 0.8500000000000001. Tests: linear_decay/flat/exponential_decay assertions updated; added a snap-to-grid invariant test.
38 lines
1.3 KiB
Python
38 lines
1.3 KiB
Python
from app.scoring import SCORE_FNS
|
|
|
|
|
|
def test_linear_decay_values():
|
|
fn = SCORE_FNS["linear_decay"]
|
|
assert fn(True, 0, 60_000) == 1.0
|
|
assert fn(True, 30_000, 60_000) == 0.75
|
|
assert fn(True, 60_000, 60_000) == 0.5
|
|
# Past the deadline the score floors at 0.5 (still correct, fully decayed).
|
|
assert fn(True, 90_000, 60_000) == 0.5
|
|
assert fn(False, 0, 60_000) == 0.0
|
|
|
|
|
|
def test_linear_decay_snaps_to_grid():
|
|
"""Every score is on the 0.05 grid (21 distinct values)."""
|
|
fn = SCORE_FNS["linear_decay"]
|
|
for elapsed in range(0, 60_001, 137): # arbitrary irrational-ish step
|
|
s = fn(True, elapsed, 60_000)
|
|
# multiplied by 20, must be an integer
|
|
assert abs(s * 20 - round(s * 20)) < 1e-9, (elapsed, s)
|
|
|
|
|
|
def test_flat_values():
|
|
fn = SCORE_FNS["flat"]
|
|
assert fn(True, 0, 60_000) == 1.0
|
|
assert fn(True, 60_000, 60_000) == 1.0
|
|
assert fn(True, 90_000, 60_000) == 1.0
|
|
assert fn(False, 0, 60_000) == 0.0
|
|
|
|
|
|
def test_exponential_decay_values():
|
|
fn = SCORE_FNS["exponential_decay"]
|
|
assert fn(True, 0, 60_000) == 1.0
|
|
# At deadline: 0.5 + 0.5 * e^-2 ≈ 0.5677 → snaps to 0.55
|
|
assert fn(True, 60_000, 60_000) == 0.55
|
|
assert fn(True, 90_000, 60_000) == fn(True, 60_000, 60_000)
|
|
assert fn(False, 0, 60_000) == 0.0
|