Source code for nhl_scrabble.reports.base

"""Base reporter class for all report types."""

from abc import ABC, abstractmethod
from collections.abc import Callable, Iterable, Iterator
from typing import Any, TypeVar

T = TypeVar("T")


[docs] class BaseReporter(ABC): """Abstract base class for all reporters. All report generators should inherit from this class and implement the generate() method to produce their specific output format. The base class provides common utilities for: - Header and subheader formatting - Sorting and filtering data - Pagination and limiting results - Number formatting (scores, averages) - Team and player listing """
[docs] @abstractmethod def generate(self, data: Any) -> str: """Generate report output. Args: data: The data to generate a report from Returns: Formatted report string """
def _format_header(self, title: str, width: int = 80) -> str: """Format a section header. Args: title: Header title width: Total width of the header line Returns: Formatted header string """ separator = "=" * width return f"\n{separator}\n\n{title}\n{separator}" def _format_subheader(self, title: str, width: int = 80) -> str: """Format a subsection header. Args: title: Subheader title width: Total width of the subheader line Returns: Formatted subheader string """ separator = "-" * width return f"\n{title}\n{separator}" def _sort_by_key( self, items: Iterable[T], key: Callable[[T], Any], reverse: bool = False, ) -> list[T]: """Sort items by a key function. Args: items: Items to sort key: Function to extract sort key from each item reverse: If True, sort in descending order (default: False) Returns: Sorted list of items """ return sorted(items, key=key, reverse=reverse) def _take_top(self, items: list[T], n: int) -> list[T]: """Take the top N items from a list. Args: items: List of items (assumed to be already sorted) n: Number of items to take Returns: List containing up to N items """ return items[:n] def _paginate(self, items: list[T], page_size: int) -> Iterator[list[T]]: """Paginate items into chunks. Args: items: List of items to paginate page_size: Number of items per page Yields: Pages containing up to page_size items """ for i in range(0, len(items), page_size): yield items[i : i + page_size] def _format_score(self, value: int, width: int = 4) -> str: """Format a score value. Args: value: Score value to format width: Minimum field width (default: 4) Returns: Formatted score string """ return f"{value:{width}}" def _format_average(self, value: float, width: int = 5, decimals: int = 2) -> str: """Format an average value. Args: value: Average value to format width: Minimum field width (default: 5) decimals: Number of decimal places (default: 2) Returns: Formatted average string """ return f"{value:{width}.{decimals}f}" def _format_team_list(self, teams: list[str]) -> str: """Format a list of team abbreviations. Args: teams: List of team abbreviations Returns: Formatted team list string (sorted, comma-separated) """ return ", ".join(sorted(teams))