105 lines
3.4 KiB
Python
105 lines
3.4 KiB
Python
import csv
|
|
import json
|
|
import os
|
|
from datetime import datetime
|
|
from typing import Any, Dict
|
|
|
|
from joint_teapot.utils.logger import logger
|
|
|
|
|
|
def generate_scoreboard(
|
|
score_file_path: str, student_name: str, student_id: str, scoreboard_file_path: str
|
|
) -> None:
|
|
if not scoreboard_file_path.endswith(".csv"):
|
|
logger.error(
|
|
f"Scoreboard file should be a .csv file, but now it is {scoreboard_file_path}"
|
|
)
|
|
return
|
|
|
|
# Load the csv file if it already exists
|
|
if os.path.exists(scoreboard_file_path):
|
|
with open(scoreboard_file_path, newline="") as file:
|
|
reader = csv.reader(file)
|
|
rows = list(reader)
|
|
columns = rows[0]
|
|
data = rows[1:]
|
|
else:
|
|
columns = [
|
|
"",
|
|
"last_edit", # FIXME:
|
|
# This is just to make changes in the file so that it can be pushed.
|
|
# Only used in development stage. Will be removed in the future.
|
|
"total",
|
|
]
|
|
data = []
|
|
|
|
column_updated = [False] * len(columns) # Record wether a score has been updated
|
|
# Update data
|
|
with open(score_file_path) as json_file:
|
|
scorefile: Dict[str, Any] = json.load(json_file)
|
|
|
|
student = f"{student_name} {student_id}"
|
|
student_found = False
|
|
for row in data:
|
|
if row[0] == student:
|
|
student_row = row # This is a reference of the original data
|
|
student_found = True
|
|
break
|
|
if not student_found:
|
|
student_row = [student, "", "0"] + [""] * (
|
|
len(columns) - 3
|
|
) # FIXME: In formal version should be -2
|
|
data.append(student_row)
|
|
|
|
for stagerecord in scorefile["stagerecords"]:
|
|
stagename = stagerecord["stagename"]
|
|
for stageresult in stagerecord["stageresults"]:
|
|
name = stageresult["name"]
|
|
for i, result in enumerate(stageresult["results"]):
|
|
score = result["score"]
|
|
colname = f"{stagename}/{name}"
|
|
if len(stageresult["results"]) != 1:
|
|
colname = f"{colname}/{i}"
|
|
if colname not in columns:
|
|
columns.append(colname)
|
|
column_updated.append(True)
|
|
for row in data:
|
|
row.append("")
|
|
student_row[columns.index(colname)] = score
|
|
column_updated[columns.index(colname)] = True
|
|
# Score of any unupdated columns should be cleared
|
|
for i, column in enumerate(columns):
|
|
if column in ["", "last_edit", "total"]:
|
|
continue
|
|
if column_updated[i] == False:
|
|
student_row[i] = ""
|
|
|
|
total = 0
|
|
for col in columns:
|
|
if col in ["", "total", "last_edit"]:
|
|
continue
|
|
idx = columns.index(col)
|
|
if (student_row[idx] is not None) and (student_row[idx] != ""):
|
|
total += int(student_row[idx])
|
|
|
|
student_row[columns.index("total")] = str(total)
|
|
|
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
student_row[
|
|
columns.index("last_edit")
|
|
] = now # FIXME: Delete this in formal version
|
|
|
|
# Sort data by total
|
|
data.sort(key=lambda x: int(x[columns.index("total")]), reverse=True)
|
|
|
|
# Write back to the csv file:
|
|
with open(scoreboard_file_path, mode="w", newline="") as file:
|
|
writer = csv.writer(file)
|
|
writer.writerow(columns)
|
|
writer.writerows(data)
|
|
|
|
|
|
def generate_comment(score_file_path: str) -> str:
|
|
# TODO
|
|
return ""
|