diff --git a/pyproject.toml b/pyproject.toml index 2f7febb..f7876de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lottery-tui" -version = "0.2.6" +version = "0.2.7" description = "A terminal user interface for lottery games." authors = [{ name = "onyx-and-iris", email = "code@onyxandiris.online" }] dependencies = ["textual>=8.0.0", "loguru>=0.7.3"] diff --git a/src/lottery_tui/lottery.py b/src/lottery_tui/lottery.py index 3c37d81..0ae13ac 100644 --- a/src/lottery_tui/lottery.py +++ b/src/lottery_tui/lottery.py @@ -1,18 +1,30 @@ import random from abc import ABC, abstractmethod -from typing import NamedTuple +from dataclasses import dataclass + +from loguru import logger -class Result(NamedTuple): - """A named tuple to hold the results of a lottery draw.""" +@dataclass(frozen=True) +class Result: + """A dataclass to hold the results of a lottery draw with auto-sorted numbers.""" kind: str numbers: list[int] bonus: list[int] | None + def __post_init__(self): + """Sort the numbers after initialization. + + We use super().__setattr__ to bypass the frozen nature of the dataclass for sorting. + """ + super().__setattr__('numbers', sorted(self.numbers)) + if self.bonus: + super().__setattr__('bonus', sorted(self.bonus)) + def __str__(self) -> str: """Return a string representation of the lottery result.""" - out = f'Numbers: {", ".join(str(n) for n in sorted(self.numbers))}' + out = f'Numbers: {", ".join(str(n) for n in self.numbers)}' if self.bonus: match self.kind: case 'EuroMillions': @@ -23,7 +35,7 @@ class Result(NamedTuple): bonus_name = 'Thunderball' case _: bonus_name = 'Bonus Numbers' - out += f'\n{bonus_name}: {", ".join(str(n) for n in sorted(self.bonus))}' + out += f'\n{bonus_name}: {", ".join(str(n) for n in self.bonus)}' return out @@ -116,5 +128,7 @@ def request_lottery_obj(lottery_name: str) -> Lottery: """Return a lottery object based on the provided lottery name.""" lottery_cls = registry.get(lottery_name.lower()) if lottery_cls is None: - raise ValueError(f"Lottery '{lottery_name}' not found.") + ERR_MSG = f"Lottery '{lottery_name}' not found. Available lotteries: {', '.join(registry.keys())}" + logger.error(ERR_MSG) + raise ValueError(ERR_MSG) return lottery_cls() diff --git a/src/lottery_tui/tui.py b/src/lottery_tui/tui.py index 77bda3d..a7de257 100644 --- a/src/lottery_tui/tui.py +++ b/src/lottery_tui/tui.py @@ -1,4 +1,3 @@ -from loguru import logger from rich.text import Text from textual.app import App, ComposeResult from textual.containers import Container @@ -49,15 +48,7 @@ class LotteryTUI(App): ) return - selected_lottery = self.query_one('#lottery-select').value - - try: - lottery_obj = request_lottery_obj(selected_lottery) - except ValueError: - ERR_MSG = f'Invalid lottery selection: {selected_lottery}' - logger.exception(ERR_MSG) - raise - + lottery_obj = request_lottery_obj(self.query_one('#lottery-select').value) result = lottery_obj.draw() self._update_result_label(str(result))