63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import math
|
|
from typing import Any
|
|
|
|
import lvpwb as app
|
|
|
|
def base_match_rating(match_type: str) -> float:
|
|
return app.MATCH_BASE_RATINGS.get(match_type, 4.5)
|
|
|
|
|
|
def calculate_match_rating(match: dict[str, Any]) -> float | None:
|
|
minutes = match.get("match_time_minutes")
|
|
if minutes is None:
|
|
return None
|
|
time_bonus = min(math.floor(max(0.0, float(minutes))) * app.MATCH_TIME_BONUS_PER_MINUTE,
|
|
app.MATCH_TIME_BONUS_CAP)
|
|
raw_action = (time_bonus
|
|
+ max(0, int(match.get("near_falls", 0))) * app.NEAR_FALL_BONUS
|
|
+ max(0, int(match.get("finishers", 0))) * app.FINISHER_BONUS)
|
|
action_bonus = min(raw_action, app.MATCH_ACTION_BONUS_CAP)
|
|
base_value = match.get("base_rating")
|
|
if not isinstance(base_value, (int, float)) or isinstance(base_value, bool):
|
|
base_value = app.base_match_rating(match.get("type", ""))
|
|
earned = float(base_value) + action_bonus
|
|
if match.get("title_defense"):
|
|
earned *= app.TITLE_MATCH_MULTIPLIER
|
|
return round(min(100.0, earned), 1)
|
|
|
|
|
|
def calculate_ppv_rating(card: dict[str, Any]) -> float | None:
|
|
if not app.is_ppv_card(card):
|
|
return None
|
|
matches = card.get("matches", [])
|
|
if len(matches) != 3 or any(match.get("rating") is None for match in matches):
|
|
return None
|
|
return round(sum(float(match["rating"]) * weight
|
|
for match, weight in zip(matches, app.PPV_MATCH_WEIGHTS)), 1)
|
|
|
|
|
|
def parse_match_minutes(raw: str) -> float | None:
|
|
try:
|
|
value = float(raw)
|
|
except ValueError:
|
|
return None
|
|
return value if math.isfinite(value) and value >= 0 else None
|
|
|
|
|
|
def parse_action_count(raw: str) -> int | None:
|
|
if not raw.isdigit():
|
|
return None
|
|
return int(raw)
|
|
|
|
|
|
def allowed_match_outcomes(match_type: str | dict[str, Any]) -> tuple[str, ...]:
|
|
if isinstance(match_type, dict):
|
|
outcomes = match_type.get("valid_outcomes")
|
|
if isinstance(outcomes, list) and outcomes:
|
|
return tuple(outcomes)
|
|
match_type = str(match_type.get("type", ""))
|
|
return app.MATCH_OUTCOME_OPTIONS.get(match_type, app.STANDARD_MATCH_OUTCOMES)
|
|
|
|
__all__ = ['allowed_match_outcomes', 'base_match_rating', 'calculate_match_rating', 'calculate_ppv_rating', 'parse_action_count', 'parse_match_minutes']
|