Standardize formatting with black and apply ruff auto-fixes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
142 lines
3.8 KiB
Python
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
|