First commit (idw)

This commit is contained in:
2025-06-10 21:17:51 +02:00
commit 2b9c84fb87
6 changed files with 376 additions and 0 deletions

129
src/__main__.py Normal file
View File

@@ -0,0 +1,129 @@
from pathlib import Path
import time
import typer
from rich import print
from rich.table import Table
from rich.console import Console
from rich.prompt import Prompt, Confirm
from rich.spinner import Spinner
from rich.panel import Panel
from rich.live import Live
app = typer.Typer()
def parse_jury_file(file_path: Path) -> dict[str, int]:
with file_path.open("r", encoding="utf-8") as file:
jury_data: dict[str, int] = {}
for line in file:
parts = line.strip().split()
if len(parts) >= 2:
name = " ".join(parts[:-1])
score = parts[-1]
jury_data[name] = int(score)
else:
print(f"[red]Invalid line format in [bold]{file_path}[/bold]: {line.strip()}[/red]")
return jury_data
def render_table(jury_data: dict[str, int], televoting_data: dict[str, int]) -> Table:
table = Table("Name", "Jury Score", "Televoting Score", title="Scores")
for name in sorted(jury_data.keys()):
jury_score = jury_data.get(name, 0)
televoting_score = televoting_data.get(name, 0)
table.add_row(name, str(jury_score), str(televoting_score))
return table
def render_table_final(final_scores: dict[str, int], jury_data: dict[str, int], televoting_data: dict[str, int]) -> Table:
table = Table("Name", "Jury Score", "Televoting Score", "Final Score", title="Final Scores")
for name in final_scores.keys():
jury_score = jury_data.get(name, 0)
televoting_score = televoting_data.get(name, 0)
final_score = final_scores[name]
table.add_row(name, str(jury_score), str(televoting_score), str(final_score))
return table
def sort_dict[A, B](d: dict[A, B], reverse: bool = True) -> dict[A, B]:
"""Sorts a dictionary by its values in descending order."""
return dict(sorted(d.items(), key=lambda item: item[1], reverse=reverse)) # pyright: ignore [reportCallIssue, reportUnknownArgumentType, reportArgumentType]
@app.command()
def run(jury_path: Path = "jury.txt"): # pyright: ignore [reportArgumentType]
jury_file = Path(jury_path)
if not jury_file.exists():
print(f"[red]File [bold]{jury_path}[bold/] does not exist.[/red]")
raise typer.Exit(code=1)
print(f"Parsing jury file: [bold]{jury_file}[/bold]")
console = Console()
jury_scores = parse_jury_file(jury_file)
jury_scores = sort_dict(jury_scores, reverse=False)
televoting_data: dict[str, int] = {}
table = render_table(jury_scores, televoting_data)
console.print(table)
i = 0
while i < (len(jury_scores) - 1):
name = list(jury_scores.keys())[i]
r: str = Prompt.ask(f"Enter televoting score for [bold]{name}[/bold] (go back with b):", default="0")
if r.lower() == "b":
if i > 0:
i -= 1
continue
try:
score: int = int(r)
except ValueError:
print(f"[red]Invalid score for [bold]{name}[/bold]. Please enter a valid integer.[/red]")
continue
if score < 0:
print(f"[red]Score for [bold]{name}[/bold] cannot be negative.[/red]")
continue
televoting_data[name] = score
i += 1
table = render_table(jury_scores, televoting_data)
console.clear()
console.print(table)
if i == (len(jury_scores) - 1):
c = Confirm.ask("Final score entered! Please review the scores. Do you want to continue?", default=True)
if not c:
i -= 1
del televoting_data[name]
console.clear()
table = render_table(jury_scores, televoting_data)
console.print(table)
continue
console.clear()
print("[green]Televoting scores have been successfully entered![/green]")
spinner = Spinner("material", text="Calculating final scores...")
with Live(spinner, console=console, refresh_per_second=10):
for _ in range(20):
time.sleep(0.1) # Our own dramatic pause :)
televoting_scores_sum: int = sum(televoting_data.values())
# We should be doing -1 below but it's being compensated by the "rest of the world" score
televoting_scores_total: int = sum((12, 10, 8, 7, 6, 5, 4, 3, 2, 1)) * len(jury_scores)
predicted_score = televoting_scores_total - televoting_scores_sum
country_to_predict = list(jury_scores.keys())[i]
televoting_data[country_to_predict] = predicted_score
televoting_data = sort_dict(televoting_data)
jury_scores = sort_dict(jury_scores)
final_scores: dict[str, int] = {}
for name in jury_scores.keys():
final_scores[name] = jury_scores[name] + televoting_data.get(name, 0)
final_scores = dict(sorted(final_scores.items(), key=lambda item: item[1], reverse=True))
final_table = render_table_final(final_scores, jury_scores, televoting_data)
console.print(final_table)
print("[green]Final scores have been calculated![/green]")
panel = Panel(
f"[bold]This year's winner is: :tada: [red]{list(final_scores.keys())[0]} :tada:[/red][/bold]",
title="Winner Announcement",
subtitle="Congratulations!",
style="green",
)
console.print(panel)
if __name__ == "__main__":
app()