import os import pandas as pd from dotenv import load_dotenv from calculate_personal_scores import get_discord_username load_dotenv() # Constants DATA_DIR = "data" PARTICIPANTS_CSV = os.path.join(DATA_DIR, "participants.csv") EQUIPOS_CSV = os.path.join(DATA_DIR, "equipos.csv") LEADERBOARD_PERSONAL_CSV = "leaderboard_personal.csv" LEADERBOARD_EQUIPOS_CSV = "leaderboard_equipos.csv" # Column mappings for teams info TEAM_COLUMNS = { "team_name": "Nombre del equipo", "email_1": "Email 1", "email_2": "Email 2", "email_3": "Email 3", "email_4": "Email 4", "email_5": "Email 5", } # INCLUDE: Cada 100 preguntas validadas extraídas por equipo = 0.5 ptos (máx 1 pto) # Estereotipos: Cada 10 estereotipos validados por equipo = 0.1 ptos (máx 1 pto) # BLEND: Cada 50 preguntas por equipo = 0.5 ptos (máx 2 ptos) # Arena: Cada 50 prompts por equipo = 0.5 ptos (máx 2 ptos) POINTS = { "INCLUDE": {"points": 0.5, "max_points": 1, "questions": 100}, "ESTEREOTIPOS": {"points": 0.1, "max_points": 1, "questions": 10}, "BLEND": {"points": 0.5, "max_points": 2, "questions": 50}, "ARENA": {"points": 0.5, "max_points": 2, "questions": 50}, } def calculate_challenge_points(total_score, challenge_name): """Calculate points for a specific challenge based on the POINTS rules.""" if challenge_name not in POINTS: return 0 challenge_rules = POINTS[challenge_name] points_per_unit = challenge_rules["points"] max_points = challenge_rules["max_points"] questions_per_unit = challenge_rules["questions"] calculated_points = (total_score / questions_per_unit) * points_per_unit final_points = min(calculated_points, max_points) return round(final_points, 2) def get_team_leaderboard(personal_leaderboard_df): """Calculate team leaderboard based on personal scores.""" if not os.path.exists(EQUIPOS_CSV): return pd.DataFrame() try: teams_df = pd.read_csv(EQUIPOS_CSV) team_leaderboard = [] for _, team_row in teams_df.iterrows(): team_name = team_row.get(TEAM_COLUMNS["team_name"], "") if not team_name: continue # Get team member emails team_emails = [] for i in range(1, 6): email_col = TEAM_COLUMNS[f"email_{i}"] email = team_row.get(email_col, "") if pd.notna(email) and email.strip(): team_emails.append(email.lower()) if not team_emails: continue # Map emails to Discord usernames and get scores discord_usernames = [] team_scores = {"arena": 0, "blend_es": 0, "estereotipos": 0, "include": 0} for email in team_emails: # Get Discord username from email discord_username = get_discord_username(email) discord_usernames.append(discord_username) # Find this user in the personal leaderboard user_scores = personal_leaderboard_df[ personal_leaderboard_df["Username"].str.lower() == discord_username.lower() ] if not user_scores.empty: team_scores["arena"] += user_scores.iloc[0]["Arena"] team_scores["blend_es"] += user_scores.iloc[0]["Blend-ES"] team_scores["estereotipos"] += user_scores.iloc[0]["Estereotipos"] team_scores["include"] += user_scores.iloc[0]["INCLUDE"] # Pad Discord usernames list to 5 elements while len(discord_usernames) < 5: discord_usernames.append("") # Calculate points for each challenge ptos_arena = calculate_challenge_points(team_scores["arena"], "ARENA") ptos_blend_es = calculate_challenge_points(team_scores["blend_es"], "BLEND") ptos_estereotipos = calculate_challenge_points( team_scores["estereotipos"], "ESTEREOTIPOS" ) ptos_include = calculate_challenge_points(team_scores["include"], "INCLUDE") # Calculate total points ptos_total = ptos_arena + ptos_blend_es + ptos_estereotipos + ptos_include # Create team row team_row_data = { "team_name": team_name, "discord_1": discord_usernames[0], "discord_2": discord_usernames[1], "discord_3": discord_usernames[2], "discord_4": discord_usernames[3], "discord_5": discord_usernames[4], "total_arena": team_scores["arena"], "ptos_arena": ptos_arena, "total_blend_es": team_scores["blend_es"], "ptos_blend_es": ptos_blend_es, "total_estereotipos": team_scores["estereotipos"], "ptos_estereotipos": ptos_estereotipos, "total_include": team_scores["include"], "ptos_include": ptos_include, "ptos_total": ptos_total, } team_leaderboard.append(team_row_data) # Create DataFrame and sort by total points (ptos_total) instead of just arena if team_leaderboard: team_df = pd.DataFrame(team_leaderboard) team_df.sort_values("ptos_total", ascending=False, inplace=True) return team_df else: return pd.DataFrame() except Exception as e: print(f"Error calculating team leaderboard: {e}") return pd.DataFrame() def calculate_team_scores(): personal_leaderboard_df = pd.read_csv(LEADERBOARD_PERSONAL_CSV) team_leaderboard_df = get_team_leaderboard(personal_leaderboard_df) team_leaderboard_df.to_csv(LEADERBOARD_EQUIPOS_CSV, index=False, encoding="utf-8") print("Team scores calculated and saved successfully!") print(f"Generated leaderboard with {len(team_leaderboard_df)} teams") if __name__ == "__main__": calculate_team_scores()