from __future__ import annotations from typing import Dict, List, Literal, Optional import numpy as np import pandas as pd class Leaderboard: def __init__(self, data_loader): self.data_loader = data_loader self.metric_better: Dict[str, Literal["min", "max"]] = { metric: "min" if metric in data_loader.lower_better else "max" for metric in data_loader.ALL_METRICS } self.dimension_metrics = list(data_loader.DIMENSION_METRICS) def update_leaderboard( self, metric: str, top_k: int, model_filter: str, entry_type_filter: str, sort_mode: str, selected_metrics: Optional[List[str]], ) -> pd.DataFrame: if self.data_loader.df_all is None or self.data_loader.df_all.empty: return pd.DataFrame() df = self.data_loader.df_all.copy() if metric not in df.columns: return pd.DataFrame() if model_filter and model_filter.strip(): df = df[df["Model"].str.contains(model_filter, case=False, na=False)] if entry_type_filter and entry_type_filter != "All": df = df[df["entry_type"] == entry_type_filter] better = self.metric_better.get(metric, "max") if sort_mode == "Auto": ascending = better == "min" elif sort_mode == "Ascending (low → high)": ascending = True else: ascending = False df_sorted = df.dropna(subset=[metric]).sort_values(metric, ascending=ascending).copy() df_sorted["Rank"] = range(1, len(df_sorted) + 1) df_top = df_sorted.head(top_k).copy() fixed_cols = ["Model", "entry_type", metric, "Rank"] selected_metrics = selected_metrics or [] filtered_selected_metrics = [metric_name for metric_name in selected_metrics if metric_name not in fixed_cols] existing_cols = [col for col in fixed_cols + filtered_selected_metrics if col in df_top.columns] table_df = df_top[existing_cols].copy() for col in table_df.columns: if col in {"Model", "entry_type"}: continue if col == "Rank": table_df[col] = table_df[col].apply(lambda value: f"{int(value)}" if pd.notna(value) else "N/A") else: table_df[col] = table_df[col].apply(lambda value: f"{value:.2f}" if pd.notna(value) else "N/A") return self._add_styling_to_dataframe(table_df) def _add_styling_to_dataframe(self, df: pd.DataFrame) -> pd.DataFrame: styled_df = df.copy() numeric_cols = [col for col in df.columns if col not in ["Model", "entry_type", "Rank"]] for col in numeric_cols: try: numeric_values = df[col].apply(lambda value: float(value) if value != "N/A" and pd.notna(value) else np.nan) except Exception: continue valid_values = numeric_values.dropna() if len(valid_values) < 1: continue better = self.metric_better.get(col, "max") sorted_values = valid_values.sort_values(ascending=(better == "min")) try: best_idx = sorted_values.index[0] best_val = df.loc[best_idx, col] if pd.notna(best_val) and best_val != "N/A": styled_df.loc[best_idx, col] = f"**{best_val}**" if len(sorted_values) >= 2: second_idx = sorted_values.index[1] second_val = df.loc[second_idx, col] if pd.notna(second_val) and second_val != "N/A": styled_df.loc[second_idx, col] = f"{second_val}" except (IndexError, KeyError, ValueError): continue return styled_df