""" Rarity threshold configurations for card creation. This module defines OPS thresholds for assigning rarity tiers to player cards. Different seasons may have different thresholds based on league-wide performance. """ from dataclasses import dataclass @dataclass class PitcherRarityThresholds: """OPS-against thresholds for pitcher rarity assignment.""" # Starter thresholds (OPS-against, lower is better) starter_hof: float # Hall of Fame (99) starter_diamond: float # Diamond (1) starter_gold: float # Gold (2) starter_silver: float # Silver (3) starter_bronze: float # Bronze (4) # Reliever thresholds (OPS-against, lower is better) reliever_hof: float # Hall of Fame (99) reliever_diamond: float # Diamond (1) reliever_gold: float # Gold (2) reliever_silver: float # Silver (3) reliever_bronze: float # Bronze (4) def get_rarity_for_starter(self, total_ops: float) -> int: """Returns rarity ID for a starting pitcher based on OPS-against.""" if total_ops <= self.starter_hof: return 99 elif total_ops <= self.starter_diamond: return 1 elif total_ops <= self.starter_gold: return 2 elif total_ops <= self.starter_silver: return 3 elif total_ops <= self.starter_bronze: return 4 else: return 5 # Common def get_rarity_for_reliever(self, total_ops: float) -> int: """Returns rarity ID for a relief pitcher based on OPS-against.""" if total_ops <= self.reliever_hof: return 99 elif total_ops <= self.reliever_diamond: return 1 elif total_ops <= self.reliever_gold: return 2 elif total_ops <= self.reliever_silver: return 3 elif total_ops <= self.reliever_bronze: return 4 else: return 5 # Common @dataclass class BatterRarityThresholds: """OPS thresholds for batter rarity assignment.""" # Batter thresholds (OPS, higher is better) hof: float # Hall of Fame (99) diamond: float # Diamond (1) gold: float # Gold (2) silver: float # Silver (3) bronze: float # Bronze (4) def get_rarity(self, total_ops: float) -> int: """Returns rarity ID for a batter based on OPS.""" # For batters, higher OPS is better, so we check >= instead of <= if total_ops >= self.hof: return 99 elif total_ops >= self.diamond: return 1 elif total_ops >= self.gold: return 2 elif total_ops >= self.silver: return 3 elif total_ops >= self.bronze: return 4 else: return 5 # Common # 2024 Season Thresholds (Original values) PITCHER_THRESHOLDS_2024 = PitcherRarityThresholds( starter_hof=0.4, starter_diamond=0.475, starter_gold=0.53, starter_silver=0.6, starter_bronze=0.675, reliever_hof=0.325, reliever_diamond=0.4, reliever_gold=0.475, reliever_silver=0.55, reliever_bronze=0.625, ) BATTER_THRESHOLDS_2024 = BatterRarityThresholds( hof=1.2, diamond=1.0, gold=0.9, silver=0.8, bronze=0.7, ) # 2025 Season Thresholds (Adjusted based on data analysis) PITCHER_THRESHOLDS_2025 = PitcherRarityThresholds( starter_hof=0.300, # Top 5% starter_diamond=0.354, # Top 15% starter_gold=0.384, # Top 30% starter_silver=0.441, # Top 50% starter_bronze=0.487, # Top 70% reliever_hof=0.270, # Top 5% reliever_diamond=0.319, # Top 15% reliever_gold=0.370, # Top 30% reliever_silver=0.436, # Top 50% reliever_bronze=0.503, # Top 70% ) BATTER_THRESHOLDS_2025 = BatterRarityThresholds( hof=1.2, diamond=1.0, gold=0.9, silver=0.8, bronze=0.7, ) def get_pitcher_thresholds(season: int) -> PitcherRarityThresholds: """Get pitcher rarity thresholds for a specific season.""" if season >= 2025: return PITCHER_THRESHOLDS_2025 else: return PITCHER_THRESHOLDS_2024 def get_batter_thresholds(season: int) -> BatterRarityThresholds: """Get batter rarity thresholds for a specific season.""" if season >= 2025: return BATTER_THRESHOLDS_2025 else: return BATTER_THRESHOLDS_2024