Spaces:
Runtime error
Runtime error
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() | |