""" Shared coverage calculation utilities for digit templates. This module provides utilities for calculating template coverage status, shared between DigitTemplateBuilder and DigitTemplateLibrary. """ from typing import Any, Dict, Iterable, Set, Tuple # Standard digit sets for play clock displays ONES_DIGITS = set(range(10)) # 0-9 TENS_DIGITS = {1, 2, 3, 4} # 10, 20, 30, 40 def categorize_template_keys(keys: Iterable[Tuple[bool, int, str]]) -> Tuple[Set[int], Set[int], Set[int], bool]: """ Categorize template keys into digit sets. Args: keys: Iterable of (is_tens, digit, position) tuples Returns: Tuple of (ones_center_have, ones_right_have, tens_have, has_blank) """ ones_center_have: Set[int] = set() ones_right_have: Set[int] = set() tens_have: Set[int] = set() has_blank = False for is_tens, digit, position in keys: if is_tens: if digit == -1: has_blank = True else: tens_have.add(digit) else: if position == "center": ones_center_have.add(digit) elif position == "right": ones_right_have.add(digit) return ones_center_have, ones_right_have, tens_have, has_blank def calculate_coverage_status( ones_center_have: Set[int], ones_right_have: Set[int], tens_have: Set[int], has_blank: bool, total_items: int = 0, ) -> Dict[str, Any]: """ Calculate coverage status from digit sets. Args: ones_center_have: Set of ones digits that have center templates ones_right_have: Set of ones digits that have right templates tens_have: Set of tens digits that have templates has_blank: Whether blank template exists total_items: Total number of items (templates or samples) Returns: Dictionary with coverage information """ ones_center_missing = ONES_DIGITS - ones_center_have ones_right_missing = ONES_DIGITS - ones_right_have tens_missing = TENS_DIGITS - tens_have # Total needed: 10 ones_center + 10 ones_right + 4 tens + 1 blank = 25 total_needed = 25 return { "total_needed": total_needed, "total_have": total_items, "is_complete": total_items >= total_needed, "ones_center_have": sorted(ones_center_have), "ones_center_missing": sorted(ones_center_missing), "ones_right_have": sorted(ones_right_have), "ones_right_missing": sorted(ones_right_missing), "tens_have": sorted(tens_have), "tens_missing": sorted(tens_missing), "has_blank": has_blank, }