File size: 6,057 Bytes
8b57f56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a9ef5d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8b57f56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a9ef5d
 
 
 
 
 
 
 
 
 
 
8b57f56
 
 
 
 
 
 
 
 
8a9ef5d
8b57f56
8a9ef5d
8b57f56
8a9ef5d
8b57f56
8a9ef5d
 
8b57f56
 
 
 
8a9ef5d
8b57f56
 
8a9ef5d
8b57f56
 
 
 
 
 
 
 
 
 
 
 
 
8a9ef5d
 
8b57f56
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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()