Skip to content
Snippets Groups Projects
Commit f7ea4409 authored by maeries's avatar maeries
Browse files

added an overview page for every competition

parent 0a621ae8
Branches
No related tags found
No related merge requests found
Pipeline #278001 passed
from datetime import datetime
from tools import clean_filename
def get_competition_page_html(self, competition_id):
competition_data = self.competition_history[competition_id]
full_competition_name = self.get_full_competition_name(competition_id)
html_content = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{full_competition_name} - Results</title>
{self.header_snippet}
<style>
body {{
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}}
h1, h2 {{
color: #333;
animation: fadeInUp 0.5s ease-out forwards;
}}
table {{
border-collapse: collapse;
width: 100%;
margin-top: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 5px;
overflow: hidden;
animation: fadeInUp 0.5s ease-out forwards;
opacity: 0;
}}
th, td {{
padding: 12px 15px;
text-align: left;
}}
th {{
background-color: #f2f2f2;
color: #333;
font-weight: bold;
text-transform: uppercase;
border-bottom: 2px solid {self.BORDER_COLOR};
}}
tr {{
background-color: white;
transition: background-color 0.3s ease;
}}
tr:nth-child(even) {{
background-color: #f9f9f9;
}}
tr:hover {{
background-color: #f5f5f5;
}}
p {{
animation: fadeInUp 0.5s ease-out forwards;
}}
.chart-container {{
margin-top: 30px;
display: flex;
justify-content: center;
width: 100%;
animation: fadeInUp 0.5s ease-out forwards;
opacity: 0;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
border-radius: 5px;
overflow: hidden;
background-color: white;
padding: 20px;
box-sizing: border-box;
}}
.chart-container img {{
max-width: 100%;
height: auto;
}}
a {{
color: {self.LINK_COLOR};
text-decoration: none;
transition: color 0.3s ease;
}}
a:hover {{
color: {self.LINK_COLOR_HOVER};
text-decoration: none;
}}
.summary-stats {{
display: flex;
justify-content: space-around;
margin: 20px 0;
flex-wrap: wrap;
animation: fadeInUp 0.5s ease-out forwards;
}}
.stat-box {{
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
margin: 10px;
flex: 1;
min-width: 150px;
text-align: center;
background-color: #f9f9f9;
}}
.stat-value {{
font-size: 24px;
font-weight: bold;
color: #333;
}}
.stat-label {{
font-size: 14px;
color: #666;
}}
.positive {{
color: green;
}}
.negative {{
color: red;
}}
@keyframes fadeInUp {{
from {{
opacity: 0;
transform: translateY(20px);
}}
to {{
opacity: 1;
transform: translateY(0);
}}
}}
</style>
</head>
<body>
<h1>{full_competition_name} - Results</h1>
<p><a href="../index.html">← Back to World Ranking</a></p>
"""
html_content += """
</div>
<!--
<div class="chart-container">
fancy diagram here
</div>
-->
<h2>Results</h2>
<table>
<tr>
<th>Placement</th>
<th>Team</th>
<th>Elo Before</th>
<th>Elo Change</th>
</tr>
"""
# Add rows for each competition
for team in competition_data['results']:
elo_change = team[3]
change_class = "positive" if elo_change > 0 else "negative" if elo_change < 0 else ""
html_content += f"""
<tr>
<td>{team[0]}</td>
<td><a href="../team/{clean_filename(team[1])}.html">{team[1]}</a></td>
<td>{int(team[2])}</td>
<td class="{change_class}">{'+' if elo_change > 0 else ''}{elo_change:.1f}</td>
</tr>"""
html_content += """
</table>
<p><small>Generated on {}</small></p>
</body>
</html>
""".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
return html_content
\ No newline at end of file
...@@ -10,6 +10,7 @@ import numpy as np ...@@ -10,6 +10,7 @@ import numpy as np
import pandas as pd import pandas as pd
from matplotlib.colors import LinearSegmentedColormap from matplotlib.colors import LinearSegmentedColormap
from competition_page import get_competition_page_html
from team_page import get_team_page_html from team_page import get_team_page_html
from tools import * from tools import *
from world_ranking_list import get_world_ranking_html from world_ranking_list import get_world_ranking_html
...@@ -62,16 +63,21 @@ class EloSystem: ...@@ -62,16 +63,21 @@ class EloSystem:
"""Create output directory if it doesn't exist""" """Create output directory if it doesn't exist"""
os.makedirs(self.output_directory, exist_ok=True) os.makedirs(self.output_directory, exist_ok=True)
os.makedirs(os.path.join(self.output_directory, 'images'), exist_ok=True) os.makedirs(os.path.join(self.output_directory, 'images'), exist_ok=True)
os.makedirs(os.path.join(self.output_directory, 'team'), exist_ok=True)
os.makedirs(os.path.join(self.output_directory, 'comp'), exist_ok=True)
def get_competition_name(self, id): def get_competition_name(self, competition_id):
return self.competition_meta_data[self.competition_meta_data["id"] == int(id)]['abbr'].values[0].strip() return self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['abbr'].values[0].strip()
def get_competition_date(self, id): def get_full_competition_name(self, competition_id):
date_string = self.competition_meta_data[self.competition_meta_data["id"] == int(id)]['date'].values[0] return self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['name'].values[0].strip()
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") return datetime.strptime(date_string, "%Y-%m-%d")
def get_competition_type(self, id): def get_competition_type(self, competition_id):
return self.competition_meta_data[self.competition_meta_data["id"] == int(id)]['kind'].values[0].strip() return self.competition_meta_data[self.competition_meta_data["id"] == int(competition_id)]['kind'].values[0].strip()
def load_and_process_csv_files(self): def load_and_process_csv_files(self):
"""Load all CSV files and process them to calculate Elo ratings""" """Load all CSV files and process them to calculate Elo ratings"""
...@@ -117,7 +123,7 @@ class EloSystem: ...@@ -117,7 +123,7 @@ class EloSystem:
'history': [], 'history': [],
'delta_elo': 0 'delta_elo': 0
} }
teams_in_competition.append((rank, team_name)) teams_in_competition.append([rank, team_name, None, None])
except FileNotFoundError: except FileNotFoundError:
print(f"file {csv_file} not found: skipping") print(f"file {csv_file} not found: skipping")
continue continue
...@@ -158,18 +164,25 @@ class EloSystem: ...@@ -158,18 +164,25 @@ class EloSystem:
# Store post-competition Elo ratings and changes # Store post-competition Elo ratings and changes
for team in teams_in_order: for team in teams_in_order:
rank = teams_in_order.index(team) + 1 rank = teams_in_order.index(team) + 1
previous_elo = self.teams[team]['elo']
elo_change = self.teams[team]['delta_elo']
# Store in team history # Store in team history
self.teams[team]['history'].append({ self.teams[team]['history'].append({
'date': date.strftime("%Y-%m-%d"), 'date': date.strftime("%Y-%m-%d"),
'competition': self.get_competition_name(competition_id), 'competition': self.get_competition_name(competition_id),
'competition_id': competition_id,
'rank': rank, 'rank': rank,
'participants': len(teams_in_order), 'participants': len(teams_in_order),
'previous_elo': self.teams[team]['elo'], 'previous_elo': previous_elo,
'new_elo': self.teams[team]['elo'] + self.teams[team]['delta_elo'], 'new_elo': self.teams[team]['elo'] + self.teams[team]['delta_elo'],
'elo_change': self.teams[team]['delta_elo'] 'elo_change': elo_change
}) })
# 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.teams[team]['elo'] = self.teams[team]['elo'] + self.teams[team]['delta_elo'] self.teams[team]['elo'] = self.teams[team]['elo'] + self.teams[team]['delta_elo']
self.teams[team]['delta_elo'] = 0 self.teams[team]['delta_elo'] = 0
...@@ -208,22 +221,19 @@ class EloSystem: ...@@ -208,22 +221,19 @@ class EloSystem:
def generate_website(self): def generate_website(self):
"""Generate static HTML website with Elo ratings and visualizations""" """Generate static HTML website with Elo ratings and visualizations"""
# Create main index page
self.create_world_ranking()
# # Create team-specific pages
# for team_name in self.teams:
# self.create_team_page(team_name)
# If num_processes not specified, use number of CPU cores # If num_processes not specified, use number of CPU cores
num_processes = int(mp.cpu_count() / 2) num_processes = int(mp.cpu_count() / 2)
print(f"staring computation on {num_processes} cores") print(f"staring computation on {num_processes} cores")
# Create a pool of workers
pool = mp.Pool(processes=num_processes) pool = mp.Pool(processes=num_processes)
self.create_world_ranking()
for competition in self.competition_history:
self.create_competition_page(competition)
pool.map(self.create_team_page, self.teams) pool.map(self.create_team_page, self.teams)
# Create visualizations
self.create_visualizations() self.create_visualizations()
print(f"Website generated in {self.output_directory}") print(f"Website generated in {self.output_directory}")
...@@ -253,7 +263,18 @@ class EloSystem: ...@@ -253,7 +263,18 @@ class EloSystem:
html_content = get_team_page_html(self, team_name, team_data, team_competitions) html_content = get_team_page_html(self, team_name, team_data, team_competitions)
# Write the HTML file # Write the HTML file
with open(os.path.join(self.output_directory, f'team_{clean_filename(team_name)}.html'), 'w', with open(os.path.join(self.output_directory, 'team', f'{clean_filename(team_name)}.html'), 'w',
encoding='utf-8') as f:
f.write(html_content)
def create_competition_page(self, competition_id):
"""Create a dedicated page for a specific team"""
print(f"Generating Competition site for {competition_id}")
html_content = get_competition_page_html(self, competition_id)
# Write the HTML file
with open(os.path.join(self.output_directory, 'comp', f'{str(competition_id)}.html'), 'w',
encoding='utf-8') as f: encoding='utf-8') as f:
f.write(html_content) f.write(html_content)
......
...@@ -134,7 +134,7 @@ def get_team_page_html(self, team_name, team_data, team_competitions): ...@@ -134,7 +134,7 @@ def get_team_page_html(self, team_name, team_data, team_competitions):
</head> </head>
<body> <body>
<h1>{team_name} - Elo Profile</h1> <h1>{team_name} - Elo Profile</h1>
<p><a href="index.html">← Back to Rankings</a></p> <p><a href="../index.html">← Back to World Ranking</a></p>
<div class="summary-stats"> <div class="summary-stats">
<div class="stat-box"> <div class="stat-box">
...@@ -167,7 +167,7 @@ def get_team_page_html(self, team_name, team_data, team_competitions): ...@@ -167,7 +167,7 @@ def get_team_page_html(self, team_name, team_data, team_competitions):
</div> </div>
<div class="chart-container"> <div class="chart-container">
<img src="images/{}_history.png" alt="{} Elo History"> <img src="../images/{}_history.png" alt="{} Elo History">
</div> </div>
<h2>Competition History</h2> <h2>Competition History</h2>
...@@ -190,7 +190,7 @@ def get_team_page_html(self, team_name, team_data, team_competitions): ...@@ -190,7 +190,7 @@ def get_team_page_html(self, team_name, team_data, team_competitions):
html_content += f""" html_content += f"""
<tr> <tr>
<td>{comp['date']}</td> <td>{comp['date']}</td>
<td>{comp['competition']}</td> <td><a href=../comp/{comp['competition_id']}.html>{comp['competition']}</a></td>
<td>{comp['rank']} / {comp['participants']}</td> <td>{comp['rank']} / {comp['participants']}</td>
<td>{int(comp['previous_elo'])}</td> <td>{int(comp['previous_elo'])}</td>
<td>{int(comp['new_elo'])}</td> <td>{int(comp['new_elo'])}</td>
......
...@@ -216,7 +216,7 @@ def get_world_ranking_html(self, sorted_teams): ...@@ -216,7 +216,7 @@ def get_world_ranking_html(self, sorted_teams):
html_content += f""" html_content += f"""
<tr> <tr>
<td>{rank}</td> <td>{rank}</td>
<td><a href="team_{clean_filename(team_name)}.html">{team_name}</a></td> <td><a href="team/{clean_filename(team_name)}.html">{team_name}</a></td>
<td>{int(team_data['elo'])}</td> <td>{int(team_data['elo'])}</td>
<td>{team_data['competitions']}</td> <td>{team_data['competitions']}</td>
</tr>""" </tr>"""
...@@ -233,7 +233,7 @@ def get_world_ranking_html(self, sorted_teams): ...@@ -233,7 +233,7 @@ def get_world_ranking_html(self, sorted_teams):
</div> </div>
<div style="display: flex; justify-content: center;"> <div style="display: flex; justify-content: center;">
<a href="index.html"><button class="nav-button">Back to Home</button></a> <a href="../index.html"><button class="nav-button">Back to Home</button></a>
</div> </div>
</div> </div>
</body> </body>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment