22import argparse
33import json
44from collections import defaultdict
5+ from datetime import datetime
56from pathlib import Path
67from typing import Literal , TypeAlias , get_args
78
1415
1516from codeclash .analysis .metrics .elo_broken import get_scores
1617from codeclash .analysis .significance import calculate_p_value
17- from codeclash .analysis .viz .utils import FONT_BOLD , MODEL_TO_DISPLAY_NAME
18+ from codeclash .analysis .viz .utils import ASSETS_DIR , FONT_BOLD , MODEL_TO_DISPLAY_NAME
1819from codeclash .constants import LOCAL_LOG_DIR , RESULT_TIE
1920from codeclash .utils .log import add_file_handler , get_logger
2021
@@ -1350,20 +1351,21 @@ def write_website_results(results: dict[str, dict], output_dir: Path) -> None:
13501351 Format:
13511352 {
13521353 "ArenaName": [
1353- {"rank": 1, "model": "model_name", "elo": 1500},
1354+ {"rank": 1, "model": "model_name", "elo": 1500, "elo_std": 50 },
13541355 ...
13551356 ],
13561357 "Overall": [...]
13571358 }
13581359 """
13591360 output_dir .mkdir (parents = True , exist_ok = True )
1360- output_file = output_dir / "leaderboard .json"
1361+ output_file = output_dir / "leaderboards .json"
13611362
13621363 leaderboard = {}
13631364
13641365 for game_name , game_result in results .items ():
13651366 players = game_result ["players" ]
13661367 strengths = game_result ["strengths" ]
1368+ elo_std = game_result .get ("elo_std" )
13671369
13681370 # Convert Bradley-Terry strengths to Elo ratings
13691371 elos = {p : BradleyTerryFitter .bt_to_elo (s ) for p , s in zip (players , strengths )}
@@ -1372,10 +1374,19 @@ def write_website_results(results: dict[str, dict], output_dir: Path) -> None:
13721374 sorted_players = sorted (elos .items (), key = lambda x : x [1 ], reverse = True )
13731375
13741376 # Create leaderboard entries
1375- leaderboard [game_name ] = [
1376- {"rank" : rank + 1 , "model" : MODEL_TO_DISPLAY_NAME .get (player , player ), "elo" : round (elo , 1 )}
1377- for rank , (player , elo ) in enumerate (sorted_players )
1378- ]
1377+ board = []
1378+ for rank , (player , elo ) in enumerate (sorted_players ):
1379+ entry = {"rank" : rank + 1 , "model" : MODEL_TO_DISPLAY_NAME .get (player , player ), "elo" : int (round (elo ))}
1380+ # Add confidence interval if available
1381+ if elo_std is not None :
1382+ player_idx = players .index (player )
1383+ entry ["elo_std" ] = int (round (elo_std [player_idx ]))
1384+ board .append (entry )
1385+
1386+ leaderboard [game_name ] = {
1387+ "board" : board ,
1388+ "last_updated" : datetime .utcnow ().isoformat () + "Z" ,
1389+ }
13791390
13801391 # Write to file
13811392 with open (output_file , "w" ) as f :
@@ -1530,8 +1541,8 @@ def write_latex_table_plain(results: dict[str, dict], output_dir: Path) -> None:
15301541 parser .add_argument (
15311542 "--output-dir" ,
15321543 type = Path ,
1533- default = Path ( "elo2_plots" ) ,
1534- help = "Directory to save plots (default: elo2_plots)" ,
1544+ default = ASSETS_DIR / "elo2_plots" ,
1545+ help = "Directory to save plots (default: assets/ elo2_plots)" ,
15351546 )
15361547 args = parser .parse_args ()
15371548
0 commit comments