Spaces:
Running
Running
File size: 1,993 Bytes
67acd34 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | from __future__ import annotations
from dataclasses import dataclass
from statistics import mean, median
from typing import Any
ALLOWED_PUZZLES = [
"bridges",
"flow_free",
"galaxies",
"loopy",
"pattern",
"undead",
]
ALLOWED_DIFFICULTIES = ["easy", "medium", "hard"]
SESSION_STATUSES = ["assigned", "ready", "attempted", "solved"]
def normalize_player_name(value: str) -> str:
parts = value.strip().split()
return " ".join(parts).lower()
def engine_for_puzzle(puzzle_type: str) -> str:
return f"{puzzle_type}_ascii"
@dataclass(frozen=True)
class DatasetRow:
filename: str
puzzlename: str
args: str
problem: str
solution: str
difficulty: str
image_base64: str | None = None
@classmethod
def from_payload(cls, payload: dict[str, Any]) -> "DatasetRow":
return cls(
filename=str(payload["filename"]),
puzzlename=str(payload["puzzlename"]),
args=str(payload.get("args") or ""),
problem=str(payload["problem"]),
solution=str(payload["solution"]),
difficulty=str(payload["difficulty"]),
image_base64=payload.get("image_base64"),
)
@dataclass(frozen=True)
class SolveAggregate:
player_name_norm: str
puzzle_type: str
difficulty: str
solve_count: int
avg_ms: float
median_ms: float
min_ms: int
max_ms: int
@classmethod
def from_rows(
cls,
*,
player_name_norm: str,
puzzle_type: str,
difficulty: str,
elapsed_values: list[int],
) -> "SolveAggregate":
return cls(
player_name_norm=player_name_norm,
puzzle_type=puzzle_type,
difficulty=difficulty,
solve_count=len(elapsed_values),
avg_ms=float(mean(elapsed_values)),
median_ms=float(median(elapsed_values)),
min_ms=min(elapsed_values),
max_ms=max(elapsed_values),
)
|