mirror of
https://github.com/Paillat-dev/esc-dramatic-unpause.git
synced 2026-01-02 09:16:21 +00:00
First commit (idw)
This commit is contained in:
129
src/__main__.py
Normal file
129
src/__main__.py
Normal 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()
|
||||
Reference in New Issue
Block a user