paper-dynasty-card-creation/batters/stat_prep.py
Cal Corum 0a17745389 Run black and ruff across entire codebase
Standardize formatting with black and apply ruff auto-fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:24:33 -05:00

142 lines
3.8 KiB
Python

import pydantic
from typing import Literal, Optional
from pydantic import model_validator
class DataMismatchError(Exception):
pass
class BattingCardModel(pydantic.BaseModel):
player_id: Optional[int] = None
variant: int = 0
steal_low: int = 3
steal_high: int = 20
steal_auto: bool = False
steal_jump: float = 0
bunting: str = "C"
hit_and_run: str = "C"
running: int = 10
offense_col: int = None
hand: Literal["R", "L", "S"] = "R"
class CardPositionModel(pydantic.BaseModel):
player_id: int
variant: int = 0
position: Literal["P", "C", "1B", "2B", "3B", "SS", "LF", "CF", "RF", "DH"]
innings: int = 1
range: int = 5
error: int = 0
arm: Optional[int] = None
pb: Optional[int] = None
overthrow: Optional[int] = None
@model_validator(mode="after")
def position_validator(self):
if self.position in ["C", "LF", "CF", "RF"] and self.arm is None:
raise ValueError(
f"player_id: {self.player_id} - {self.position} must have an arm rating"
)
if self.position == "C" and (self.pb is None or self.overthrow is None):
raise ValueError(
f"player_id: {self.player_id} - Catchers must have a pb and overthrow rating"
)
return self
class BattingCardRatingsModel(pydantic.BaseModel):
battingcard_id: int
vs_hand: Literal["R", "L", "vR", "vL"]
homerun: float = 0.0
bp_homerun: float = 0.0
triple: float = 0.0
double_three: float = 0.0
double_two: float = 0.0
double_pull: float = 0.0
single_two: float = 0.0
single_one: float = 0.0
single_center: float = 0.0
bp_single: float = 0.0
hbp: float = 0.0
walk: float = 0.0
strikeout: float = 0.0
lineout: float = 0.0
popout: float = 0.0
flyout_a: float = 0.0
flyout_bq: float = 0.0
flyout_lf_b: float = 0.0
flyout_rf_b: float = 0.0
groundout_a: float = 0.0
groundout_b: float = 0.0
groundout_c: float = 0.0
avg: float = 0.0
obp: float = 0.0
slg: float = 0.0
pull_rate: float = 0.0
center_rate: float = 0.0
slap_rate: float = 0.0
@model_validator(mode="after")
def avg(self):
self.avg = (
self.homerun
+ self.bp_homerun / 2
+ self.triple
+ self.double_three
+ self.double_two
+ self.double_pull
+ self.single_two
+ self.single_one
+ self.single_center
+ self.bp_single / 2
) / 108
self.obp = ((self.hbp + self.walk) / 108) + self.avg
self.slg = (
self.homerun * 4
+ self.bp_homerun * 2
+ self.triple * 3
+ self.double_three * 2
+ self.double_two * 2
+ self.double_pull * 2
+ self.single_two
+ self.single_one
+ self.single_center
+ self.bp_single / 2
) / 108
total_chances = (
self.homerun
+ self.bp_homerun
+ self.triple
+ self.double_three
+ self.double_two
+ self.double_pull
+ self.single_two
+ self.single_one
+ self.single_center
+ self.bp_single
+ self.hbp
+ self.walk
+ self.strikeout
+ self.lineout
+ self.popout
+ self.flyout_a
+ self.flyout_bq
+ self.flyout_lf_b
+ self.flyout_rf_b
+ self.groundout_a
+ self.groundout_b
+ self.groundout_c
)
if total_chances != 108:
raise ValueError(
f"BC {self.battingcard_id} has {total_chances} chances listed; must be 108"
)
return self