Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
formula student elo
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
GET racing FOSS
formula student elo
Commits
f7ea4409
Commit
f7ea4409
authored
2 months ago
by
maeries
Browse files
Options
Downloads
Patches
Plain Diff
added an overview page for every competition
parent
0a621ae8
Branches
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#278001
passed
2 months ago
Stage: test
Stage: deploy
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
competition_page.py
+182
-0
182 additions, 0 deletions
competition_page.py
main.py
+40
-19
40 additions, 19 deletions
main.py
team_page.py
+3
-3
3 additions, 3 deletions
team_page.py
world_ranking_list.py
+2
-2
2 additions, 2 deletions
world_ranking_list.py
with
227 additions
and
24 deletions
competition_page.py
0 → 100644
+
182
−
0
View file @
f7ea4409
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
:
.
1
f
}
</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
This diff is collapsed.
Click to expand it.
main.py
+
40
−
19
View file @
f7ea4409
...
@@ -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
'
:
s
el
f
.
teams
[
team
][
'
delta_elo
'
]
'
elo_change
'
:
el
o_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
)
...
...
This diff is collapsed.
Click to expand it.
team_page.py
+
3
−
3
View file @
f7ea4409
...
@@ -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 Ranking
s
</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>
...
...
This diff is collapsed.
Click to expand it.
world_ranking_list.py
+
2
−
2
View file @
f7ea4409
...
@@ -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>
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment