""" Utility Functions Module Provides background color calculation, style generation, and other auxiliary functions. """ from typing import Tuple def calculate_bg_color(player_score: int, ai_score: int) -> str: """ Calculate background color based on player and AI scores Rules: - Player leading: Green gradient (light green to dark green) - AI leading: Red gradient (light red to dark red) - Tie: White Args: player_score: Player score ai_score: AI score Returns: RGB color string in format "rgb(r, g, b)" """ # Return white for tie if player_score == ai_score: return "rgb(255, 255, 255)" # Calculate score difference score_diff = player_score - ai_score # Player leading - green gradient if score_diff > 0: # Higher difference, darker green # Lightest: rgb(230, 255, 230) - difference of 1 # Darkest: rgb(144, 238, 144) - difference of 5+ intensity = min(score_diff, 5) # Limit max difference to 5 # Linear interpolation for RGB values r = int(230 - (86 * intensity / 5)) # 230 -> 144 g = int(255 - (17 * intensity / 5)) # 255 -> 238 b = int(230 - (86 * intensity / 5)) # 230 -> 144 return f"rgb({r}, {g}, {b})" # AI leading - red gradient else: # Higher difference, darker red # Lightest: rgb(255, 230, 230) - difference of 1 # Darkest: rgb(255, 182, 193) - difference of 5+ intensity = min(abs(score_diff), 5) # Limit max difference to 5 # Linear interpolation for RGB values r = 255 # Keep red channel at maximum g = int(230 - (48 * intensity / 5)) # 230 -> 182 b = int(230 - (37 * intensity / 5)) # 230 -> 193 return f"rgb({r}, {g}, {b})" def get_background_style(player_score: int, ai_score: int) -> str: """ Generate complete background style CSS string Args: player_score: Player score ai_score: AI score Returns: CSS style string including background color and transition effect """ bg_color = calculate_bg_color(player_score, ai_score) return f""" background-color: {bg_color}; transition: background-color 0.5s ease; """ def format_confidence(confidence: float) -> str: """ Format confidence as percentage string Args: confidence: Confidence value between 0.0-1.0 Returns: Formatted percentage string, e.g. "85.3%" """ return f"{confidence * 100:.1f}%" def validate_image_path(path: str) -> bool: """ Validate if image path is valid Args: path: Image file path Returns: True if path is valid and file exists, otherwise False """ import os from pathlib import Path if not path: return False file_path = Path(path) # Check if file exists if not file_path.exists() or not file_path.is_file(): return False # Check file extension valid_extensions = {'.jpg', '.jpeg', '.png', '.webp', '.bmp'} if file_path.suffix.lower() not in valid_extensions: return False return True def get_score_diff_description(player_score: int, ai_score: int) -> str: """ Get text description of score difference Args: player_score: Player score ai_score: AI score Returns: Text describing score status, e.g. "You're ahead by 3 points" """ diff = player_score - ai_score if diff == 0: return "Tie" elif diff > 0: return f"You're ahead by {diff} point{'s' if diff > 1 else ''}" else: return f"AI is ahead by {abs(diff)} point{'s' if abs(diff) > 1 else ''}"