From 8852492aef7729284c0593ee614856e18ee21b62 Mon Sep 17 00:00:00 2001 From: maeries <8ij4neqiu@mozmail.com> Date: Mon, 24 Mar 2025 16:12:58 +0100 Subject: [PATCH] added world ranking info to team page --- main.py | 69 ++++++++++++++++++++++++++++++++-------------------- team_page.py | 20 ++++++++++----- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/main.py b/main.py index 988983b..e1e0abb 100644 --- a/main.py +++ b/main.py @@ -77,7 +77,7 @@ class EloSystem: def get_competition_date(self, competition_id): date_string = self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['date'].values[0] return datetime.strptime(date_string, "%Y-%m-%d") - + def get_competition_type(self, competition_id): return self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['kind'].values[0].strip() @@ -155,6 +155,9 @@ class EloSystem: # For each team, compare with teams ranked below them date = self.get_competition_date(competition_id) # Use current date as competition date + old_world_ranking = sorted(self.teams.items(), key=lambda x: x[1]['elo'], reverse=True) + old_world_ranking = tuple(name for name, _ in old_world_ranking) + for i in range(len(teams_in_order)): for j in range(i + 1, len(teams_in_order)): team_a = teams_in_order[i] @@ -165,29 +168,41 @@ class EloSystem: # Store post-competition Elo ratings and changes for team in teams_in_order: - rank = teams_in_order.index(team) + 1 + placement = teams_in_order.index(team) + 1 previous_elo = self.teams[team]['elo'] elo_change = self.teams[team]['delta_elo'] + old_rank = old_world_ranking.index(team) + 1 + new_rank = 0 # Store in team history self.teams[team]['history'].append({ 'date': date.strftime("%Y-%m-%d"), 'competition': self.get_competition_name(competition_id), 'competition_id': competition_id, - 'rank': rank, + 'placement': placement, 'participants': len(teams_in_order), 'previous_elo': previous_elo, 'new_elo': self.teams[team]['elo'] + self.teams[team]['delta_elo'], - 'elo_change': elo_change + 'elo_change': elo_change, + 'old_rank': old_rank, + 'new_rank': new_rank, + 'rank_change': new_rank - old_rank }) # Store in competition history - self.competition_history[competition_id]['results'][rank-1][2] = previous_elo - self.competition_history[competition_id]['results'][rank-1][3] = elo_change + self.competition_history[competition_id]['results'][placement-1][2] = previous_elo + self.competition_history[competition_id]['results'][placement-1][3] = elo_change self.teams[team]['elo'] = self.teams[team]['elo'] + self.teams[team]['delta_elo'] self.teams[team]['delta_elo'] = 0 + for team in teams_in_order: + new_world_ranking = sorted(self.teams.items(), key=lambda x: x[1]['elo'], reverse=True) + new_world_ranking = tuple(name for name, _ in new_world_ranking) + new_rank = new_world_ranking.index(team) + 1 + self.teams[team]['history'][-1]['new_rank'] = new_rank + self.teams[team]['history'][-1]['rank_change'] = new_rank - self.teams[team]['history'][-1]['old_rank'] + def update_elo_pair(self, team_a, team_b, score_a, score_b, competition_id, date): """Update Elo ratings for a pair of teams based on their match outcome""" # Get current Elo ratings @@ -306,36 +321,36 @@ class EloSystem: for i, bar in enumerate(bars): plt.text(bar.get_width() + 5, bar.get_y() + bar.get_height() / 2, f"{int(elo_ratings[i])}", va='center') - + # Create custom colormap colors = [hex_to_normalized_rgb(self.LINK_COLOR), hex_to_normalized_rgb(self.BORDER_COLOR)] # RGB values for #ffff1e and #ffc400 custom_yellow_cmap = LinearSegmentedColormap.from_list('custom_yellow', colors) - + for bar in bars: # Get the coordinates of the bar x0, y0 = bar.get_xy() width = bar.get_width() height = bar.get_height() - + # Create a gradient for the bar gradient = np.linspace(0, 1, 100).reshape(1, -1) - + # Get colors from the colormap colors = custom_yellow_cmap(gradient) - + # Set the bar's face color to the gradient bar.set_facecolor('none') # Remove default color - + # Add the gradient rectangle - gradient_rect = patches.Rectangle((x0, y0), width, height, - linewidth=0, - fill=True, - facecolor=custom_yellow_cmap(0.5)) - + gradient_rect = patches.Rectangle((x0, y0), width, height, + linewidth=0, + fill=True, + facecolor=custom_yellow_cmap(0.5)) + # To create a gradient, add an axial gradient transform gradient_rect.set_facecolor('none') ax.add_patch(gradient_rect) - + # Create multiple thin rectangles to simulate a gradient steps = 50 for i in range(steps): @@ -343,8 +358,8 @@ class EloSystem: rect_width = width/steps color = custom_yellow_cmap(i/steps) rect = patches.Rectangle((left, y0), rect_width, height, - linewidth=0, - color=color) + linewidth=0, + color=color) ax.add_patch(rect) plt.xlabel('Elo Rating') @@ -368,7 +383,7 @@ class EloSystem: # Create histogram counts, bin_edges, _ = plt.hist(elo_ratings, bins=20, alpha=0) - + # Draw bars with gradients bin_width = bin_edges[1] - bin_edges[0] for i in range(len(counts)): @@ -377,7 +392,7 @@ class EloSystem: bottom = 0 width = bin_width height = counts[i] - + # Create the gradient effect by stacking multiple thin rectangles gradient_steps = 50 for step in range(gradient_steps): @@ -387,10 +402,10 @@ class EloSystem: # Calculate height of this piece of the gradient rect_bottom = bottom + (step / gradient_steps) * height rect_height = height / gradient_steps - + # Get color from our custom colormap color = custom_yellow_cmap(step / gradient_steps) - + # Add the rectangle patch rect = patches.Rectangle( (rect_left, rect_bottom), @@ -401,7 +416,7 @@ class EloSystem: edgecolor=None ) plt.gca().add_patch(rect) - + # Add black edges to each bar for i in range(len(counts)): left = bin_edges[i] @@ -416,7 +431,7 @@ class EloSystem: linewidth=1 ) plt.gca().add_patch(rect) - + # Set axis limits to make sure the entire histogram is visible plt.xlim(bin_edges[0], bin_edges[-1]) plt.ylim(0, max(counts) * 1.1) @@ -448,7 +463,7 @@ class EloSystem: # Add competition labels for i, entry in enumerate(team_history): - plt.annotate(entry['competition'] + f" (#{entry['rank']})", + plt.annotate(entry['competition'] + f" (#{entry['placement']})", (i, entry['new_elo']), textcoords="offset points", xytext=(0, 10), diff --git a/team_page.py b/team_page.py index 0bc195a..2529757 100644 --- a/team_page.py +++ b/team_page.py @@ -149,8 +149,8 @@ def get_team_page_html(self, team_name, team_data, team_competitions): # Calculate average ranking if available if team_competitions: - avg_rank = sum(comp['rank'] for comp in team_competitions) / len(team_competitions) - best_rank = min(comp['rank'] for comp in team_competitions) + avg_rank = sum(comp['placement'] for comp in team_competitions) / len(team_competitions) + best_rank = min(comp['placement'] for comp in team_competitions) html_content += f""" <div class="stat-box"> @@ -175,8 +175,11 @@ def get_team_page_html(self, team_name, team_data, team_competitions): <table> <tr> <th>Date</th> - <th>Competition</th> + <th>Comp</th> <th>Placement</th> + <th>Rank Before</th> + <th>Rank After</th> + <th>Rank Change</th> <th>Elo Before</th> <th>Elo After</th> <th>Elo Change</th> @@ -186,16 +189,21 @@ def get_team_page_html(self, team_name, team_data, team_competitions): # Add rows for each competition for comp in team_competitions: elo_change = comp['elo_change'] - change_class = "positive" if elo_change > 0 else "negative" if elo_change < 0 else "" + elo_change_class = "positive" if elo_change > 0 else "negative" if elo_change < 0 else "" + rank_change = comp['rank_change'] + rank_change_class = "positive" if rank_change < 0 else "negative" if rank_change > 0 else "" html_content += f""" <tr> <td>{comp['date']}</td> <td><a href=../comp/{comp['competition_id']}.html>{comp['competition']}</a></td> - <td>{comp['rank']} / {comp['participants']}</td> + <td>{comp['placement']} / {comp['participants']}</td> + <td>{comp['old_rank']}</td> + <td>{comp['new_rank']}</td> + <td class="{rank_change_class}">{'+' if rank_change > 0 else ''}{comp['rank_change']}</td> <td>{int(comp['previous_elo'])}</td> <td>{int(comp['new_elo'])}</td> - <td class="{change_class}">{'+' if elo_change > 0 else ''}{elo_change:.1f}</td> + <td class="{elo_change_class}">{'+' if elo_change > 0 else ''}{elo_change:.1f}</td> </tr>""" html_content += """ -- GitLab