Skip to content

Commit 9291e17

Browse files
committed
Fix(analysis): Tolerate floats that are almost ints in p value calc
1 parent d1c4fca commit 9291e17

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

codeclash/ratings/significance.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1+
import math
2+
13
from scipy.stats import binomtest
24

35
from codeclash.constants import RESULT_TIE
46

57

6-
def calculate_p_value(scores: dict[str, int]) -> float:
8+
def calculate_p_value(scores: dict[str, int | float]) -> float:
79
"""Calculate the p-value for the statistical significance of the winner.
810
911
Input: scores as a dictionary of player names and number of games won.
1012
Special case: 'Tie' (constants.RESULT_TIE) is a tie between all players.
1113
14+
Score values must be whole numbers (integers or floats close to integers).
15+
1216
Ties (RESULT_TIE) are excluded by conditioning on decisive games.
1317
1418
Uses an exact one-sided binomial test for the top player's share vs 1/K,
1519
Bonferroni-corrected for choosing the winner post hoc among K players.
1620
Returns 1.0 if there is no unique winner or no decisive games.
1721
"""
18-
player_wins = {p: c for p, c in scores.items() if p != RESULT_TIE}
22+
# Convert scores to integers, but only if they're close to whole numbers
23+
player_wins = {}
24+
for p, c in scores.items():
25+
if p == RESULT_TIE:
26+
continue
27+
if isinstance(c, float) and not math.isclose(c, round(c)):
28+
raise ValueError(f"Score for player '{p}' is {c}, but game wins must be whole numbers")
29+
player_wins[p] = int(round(c))
1930
decisive_games = sum(player_wins.values())
2031
n_players = len(player_wins)
2132
assert n_players > 1, "At least two players are required to calculate significance"

0 commit comments

Comments
 (0)