Skip to content

Commit 3ed7b92

Browse files
authored
Refactor scoreboard to use Jinja templates (#534)
- add Jinja2 to requirements - move HTML to `templates/index.html.j2` - refactor `scoreboard/main.py` to render via Jinja2
1 parent 164869c commit 3ed7b92

File tree

3 files changed

+88
-70
lines changed

3 files changed

+88
-70
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ numpy==2.2.3
22
XlsxWriter==3.2.5
33
PyYAML==6.0.2
44
pre-commit==4.2.0
5+
Jinja2==3.1.6

scoreboard/main.py

Lines changed: 38 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import argparse
44
import yaml
55
import csv
6+
from jinja2 import Environment, FileSystemLoader
67

78
task_types = ['all', 'mpi', 'omp', 'seq', 'stl', 'tbb']
89

@@ -33,40 +34,7 @@
3334
plagiarism_cfg = yaml.safe_load(file)
3435
assert plagiarism_cfg, "Plagiarism configuration is empty"
3536

36-
columns = ''.join(['<th colspan=5 style="text-align: center;">' + task_type + '</th>' for task_type in task_types])
37-
html_content = f"""
38-
<!DOCTYPE html>
39-
<html>
40-
<head>
41-
<title>Task Directories</title>
42-
<link rel="stylesheet" type="text/css" href="static/main.css">
43-
</head>
44-
<body>
45-
<h1>Scoreboard</h1>
46-
<h3 style="color: red;">Note:</b> This is experimental and results are for reference only!</h3>
47-
<p>
48-
<b>(S)olution</b> - The correctness and completeness of the implemented solution.<br/>
49-
<b>(A)cceleration</b> - The process of speeding up software to improve performance.
50-
Speedup = T(seq) / T(parallel)<br/>
51-
<b>(E)fficiency</b> - Optimizing software speed-up by improving CPU utilization and resource management.
52-
Efficiency = Speedup / NumProcs * 100%<br/>
53-
<b>(D)eadline</b> - The timeliness of the submission in relation to the given deadline.<br/>
54-
<b>(P)lagiarism</b> - The originality of the work, ensuring no copied content from external sources.<br/>
55-
</p>
56-
<table>
57-
<tr>
58-
<th rowspan=2>Tasks</th>
59-
{columns}
60-
<th rowspan=2>Total</th>
61-
</tr>
62-
<tr>
63-
{''.join([
64-
f'<th style="text-align: center;">{letter}</th>'
65-
for _ in range(len(task_types))
66-
for letter in ('S', 'A', 'E', 'D', 'P')
67-
])}
68-
</tr>
69-
"""
37+
env = Environment(loader=FileSystemLoader(Path(__file__).parent / "templates"))
7038

7139

7240
perf_stat_file_path = Path(__file__).parent.parent / "build" / "perf_stat_dir" / "task_run_perf_table.csv"
@@ -88,48 +56,48 @@
8856
else:
8957
print(f"Warning: Performance stats CSV not found at {perf_stat_file_path}")
9058

91-
59+
rows = []
9260
for dir in sorted(directories.keys()):
93-
html_content += f"<tr><td>{dir}</td>"
61+
row_types = []
9462
total_count = 0
9563
for task_type in task_types:
9664
max_sol_points = int(cfg["scoreboard"]["task"][task_type]["solution"]["max"])
97-
task_count = 0
98-
if directories[dir].get(task_type) == "done":
99-
html_content += f'<td style="text-align: center;background-color: lightgreen;">{max_sol_points}</td>'
100-
task_count += max_sol_points
101-
elif directories[dir].get(task_type) == "disabled":
102-
html_content += f'<td style="text-align: center;background-color: #6495ED;">{max_sol_points}</td>'
103-
task_count += max_sol_points
104-
else:
105-
html_content += '<td style="text-align: center;">0</td>'
106-
html_content += '<td style="text-align: center;background-color: lavender;">'
107-
if dir in perf_stats.keys():
108-
html_content += perf_stats[dir][task_type]
109-
else:
110-
html_content += '?'
111-
html_content += '</td>'
112-
html_content += '<td style="text-align: center;background-color: lavender;">0</td>'
113-
html_content += '<td style="text-align: center;">0</td>'
114-
is_cheated = \
115-
dir in plagiarism_cfg["plagiarism"][task_type] or \
116-
dir[:-len("_disabled")] in plagiarism_cfg["plagiarism"][task_type]
65+
status = directories[dir].get(task_type)
66+
sol_points = max_sol_points if status in ("done", "disabled") else 0
67+
solution_style = ""
68+
if status == "done":
69+
solution_style = "background-color: lightgreen;"
70+
elif status == "disabled":
71+
solution_style = "background-color: #6495ED;"
72+
73+
task_points = sol_points
74+
is_cheated = (
75+
dir in plagiarism_cfg["plagiarism"][task_type]
76+
or dir.rstrip("_disabled") in plagiarism_cfg["plagiarism"][task_type]
77+
)
78+
plagiarism_points = 0
11779
if is_cheated:
11880
plag_coeff = float(cfg["scoreboard"]["plagiarism"]["coefficient"])
119-
plagiarism_points = -plag_coeff * task_count
120-
task_count += plagiarism_points
121-
html_content += f'<td style="text-align: center; background-color: pink;">{plagiarism_points}</td>'
122-
else:
123-
html_content += '<td style="text-align: center;">0</td>'
124-
total_count += task_count
125-
html_content += f'<td style="text-align: center;">{total_count}</td>'
126-
html_content += "</tr>"
127-
128-
html_content += """
129-
</table>
130-
</body>
131-
</html>
132-
"""
81+
plagiarism_points = -plag_coeff * task_points
82+
task_points += plagiarism_points
83+
84+
perf_val = perf_stats.get(dir, {}).get(task_type, "?")
85+
86+
row_types.append(
87+
{
88+
"solution_points": sol_points,
89+
"solution_style": solution_style,
90+
"perf": perf_val,
91+
"plagiarised": is_cheated,
92+
"plagiarism_points": plagiarism_points,
93+
}
94+
)
95+
total_count += task_points
96+
97+
rows.append({"task": dir, "types": row_types, "total": total_count})
98+
99+
template = env.get_template("index.html.j2")
100+
html_content = template.render(task_types=task_types, rows=rows)
133101

134102
parser = argparse.ArgumentParser(description='Generate HTML scoreboard.')
135103
parser.add_argument('-o', '--output', type=str, required=True, help='Output file path')

scoreboard/templates/index.html.j2

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Task Directories</title>
5+
<link rel="stylesheet" type="text/css" href="static/main.css">
6+
</head>
7+
<body>
8+
<h1>Scoreboard</h1>
9+
<h3 style="color: red;">Note:</b> This is experimental and results are for reference only!</h3>
10+
<p>
11+
<b>(S)olution</b> - The correctness and completeness of the implemented solution.<br/>
12+
<b>(A)cceleration</b> - The process of speeding up software to improve performance.
13+
Speedup = T(seq) / T(parallel)<br/>
14+
<b>(E)fficiency</b> - Optimizing software speed-up by improving CPU utilization and resource management.
15+
Efficiency = Speedup / NumProcs * 100%<br/>
16+
<b>(D)eadline</b> - The timeliness of the submission in relation to the given deadline.<br/>
17+
<b>(P)lagiarism</b> - The originality of the work, ensuring no copied content from external sources.<br/>
18+
</p>
19+
<table>
20+
<tr>
21+
<th rowspan="2">Tasks</th>
22+
{% for type in task_types %}
23+
<th colspan="5" style="text-align: center;">{{ type }}</th>
24+
{% endfor %}
25+
<th rowspan="2">Total</th>
26+
</tr>
27+
<tr>
28+
{% for type in task_types %}
29+
{% for letter in ('S', 'A', 'E', 'D', 'P') %}
30+
<th style="text-align: center;">{{ letter }}</th>
31+
{% endfor %}
32+
{% endfor %}
33+
</tr>
34+
{% for row in rows %}
35+
<tr>
36+
<td>{{ row.task }}</td>
37+
{% for cell in row.types %}
38+
<td style="text-align: center{% if cell.solution_style %};{{ cell.solution_style }}{% endif %}">{{ cell.solution_points }}</td>
39+
<td style="text-align: center;background-color: lavender;">{{ cell.perf }}</td>
40+
<td style="text-align: center;background-color: lavender;">0</td>
41+
<td style="text-align: center;">0</td>
42+
<td style="text-align: center{% if cell.plagiarised %}; background-color: pink{% endif %}">{{ cell.plagiarism_points }}</td>
43+
{% endfor %}
44+
<td style="text-align: center;">{{ row.total }}</td>
45+
</tr>
46+
{% endfor %}
47+
</table>
48+
</body>
49+
</html>

0 commit comments

Comments
 (0)