""" Pydantic models for value reading results. These models represent the outputs of reading values from detected regions: play clock readings, template match results, etc. """ from typing import Optional from pydantic import BaseModel, Field class PlayClockReading(BaseModel): """Result from play clock reading (used by both OCR and template-based methods).""" detected: bool = Field(..., description="Whether a valid play clock value was detected") value: Optional[int] = Field(..., description="Play clock value (0-40 seconds), None if unreadable") confidence: float = Field(..., description="Confidence score (0.0 to 1.0)") raw_text: str = Field(..., description="Source identifier for debugging (e.g., 'TEMPLATE_40', 'BACKFILLED_25', 'NO_SCOREBUG')") class TemplateMatchResult(BaseModel): """Result from template matching for a single digit.""" digit_value: int = Field(..., description="Matched digit value (-1 for blank, 0-9 for digits)") confidence: float = Field(..., description="Match confidence (0.0 to 1.0)") is_valid: bool = Field(..., description="Whether match confidence exceeds threshold") class TemplatePlayClockReading(BaseModel): """Result from template-based play clock reading.""" detected: bool = Field(..., description="Whether a valid clock value was read") value: Optional[int] = Field(..., description="Clock value (0-40), None if unreadable") confidence: float = Field(..., description="Overall confidence score") tens_match: Optional[TemplateMatchResult] = Field(..., description="Tens digit match result") ones_match: Optional[TemplateMatchResult] = Field(..., description="Ones digit match result") method: str = Field(..., description="'template_single', 'template_double', or 'template'") class FlagReading(BaseModel): """Result from FLAG indicator reading.""" detected: bool = Field(..., description="Whether FLAG indicator is detected (yellow present AND valid hue)") yellow_ratio: float = Field(..., description="Ratio of yellow pixels in FLAG region (0.0 to 1.0)") mean_hue: float = Field(..., description="Mean hue of yellow pixels (0-180 in OpenCV HSV)") is_valid_yellow: bool = Field(..., description="True if mean_hue >= threshold (not orange)")