paper-dynasty-card-creation/custom_cards/submit_kalin_young.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

241 lines
6.6 KiB
Python

"""
Submit Kalin Young updates to Paper Dynasty Database
Updates:
- BattingCardRatings: +1.55 walks/singles, -3.10 strikeouts (both splits)
- CardPositions: RF Range 2/Error 6, LF Range 4/Error 6
- Target OPS: 0.880 (from 0.837)
Does NOT upload to AWS - user will review first.
"""
import asyncio
from db_calls import db_put
from datetime import datetime
# Player info
PLAYER_ID = 13009
BATTINGCARD_ID = 6072
CARDSET_ID = 29
# New ratings (from kalin_young_preview.py)
NEW_RATINGS = {
"L": { # vs LHP
"battingcard_id": BATTINGCARD_ID,
"vs_hand": "L",
"homerun": 2.05,
"bp_homerun": 2.00,
"triple": 0.00,
"double_three": 0.00,
"double_two": 6.00,
"double_pull": 2.35,
"single_two": 5.05,
"single_one": 5.10,
"single_center": 5.80, # +1.55
"bp_single": 5.00,
"walk": 16.05, # +1.55
"hbp": 1.00,
"strikeout": 15.40, # -3.10
"lineout": 15.00,
"popout": 0.00,
"flyout_a": 0.00,
"flyout_bq": 0.75,
"flyout_lf_b": 3.65,
"flyout_rf_b": 3.95,
"groundout_a": 3.95,
"groundout_b": 10.00,
"groundout_c": 4.90,
"pull_rate": 0.33,
"center_rate": 0.37,
"slap_rate": 0.30,
},
"R": { # vs RHP
"battingcard_id": BATTINGCARD_ID,
"vs_hand": "R",
"homerun": 2.10,
"bp_homerun": 1.00,
"triple": 1.25,
"double_three": 0.00,
"double_two": 6.35,
"double_pull": 1.80,
"single_two": 5.40,
"single_one": 4.95,
"single_center": 6.05, # +1.55
"bp_single": 5.00,
"walk": 14.55, # +1.55
"hbp": 2.00,
"strikeout": 17.90, # -3.10
"lineout": 12.00,
"popout": 1.00,
"flyout_a": 0.00,
"flyout_bq": 0.50,
"flyout_lf_b": 4.10,
"flyout_rf_b": 4.00,
"groundout_a": 4.00,
"groundout_b": 5.00,
"groundout_c": 9.05,
"pull_rate": 0.25,
"center_rate": 0.40,
"slap_rate": 0.35,
},
}
# New defensive positions
NEW_POSITIONS = [
{
"player_id": PLAYER_ID,
"position": "RF",
"range": 2, # was 3
"error": 6, # was 7
"arm": 0,
"fielding_pct": None,
},
{
"player_id": PLAYER_ID,
"position": "LF",
"range": 4,
"error": 6, # was 7
"arm": 0,
"fielding_pct": None,
},
]
def calc_ops(r):
"""Calculate OPS from ratings dict."""
avg = (
r["homerun"]
+ r["bp_homerun"] / 2
+ r["triple"]
+ r["double_three"]
+ r["double_two"]
+ r["double_pull"]
+ r["single_two"]
+ r["single_one"]
+ r["single_center"]
+ r["bp_single"] / 2
) / 108
obp = avg + (r["hbp"] + r["walk"]) / 108
slg = (
r["homerun"] * 4
+ r["bp_homerun"] * 2
+ r["triple"] * 3
+ (r["double_three"] + r["double_two"] + r["double_pull"]) * 2
+ r["single_two"]
+ r["single_one"]
+ r["single_center"]
+ r["bp_single"] / 2
) / 108
return obp + slg
def verify_total(r):
"""Verify ratings sum to 108."""
return sum(
[
r["homerun"],
r["bp_homerun"],
r["triple"],
r["double_three"],
r["double_two"],
r["double_pull"],
r["single_two"],
r["single_one"],
r["single_center"],
r["bp_single"],
r["walk"],
r["hbp"],
r["strikeout"],
r["lineout"],
r["popout"],
r["flyout_a"],
r["flyout_bq"],
r["flyout_lf_b"],
r["flyout_rf_b"],
r["groundout_a"],
r["groundout_b"],
r["groundout_c"],
]
)
async def main():
"""Update Kalin Young's batting card ratings and defensive positions."""
print("\n" + "=" * 70)
print("UPDATING KALIN YOUNG IN DATABASE")
print("=" * 70)
print(f"\nPlayer ID: {PLAYER_ID}")
print(f"BattingCard ID: {BATTINGCARD_ID}")
# Verify totals
print("\nVerifying ratings totals...")
for hand, ratings in NEW_RATINGS.items():
total = verify_total(ratings)
ops = calc_ops(ratings)
print(f" vs {hand}HP: Total={total:.2f}, OPS={ops:.3f}")
if abs(total - 108.0) > 0.01:
print(" ⚠ WARNING: Total is not 108!")
return
# Calculate combined OPS
ops_vl = calc_ops(NEW_RATINGS["L"])
ops_vr = calc_ops(NEW_RATINGS["R"])
total_ops = (ops_vl + ops_vr + min(ops_vl, ops_vr)) / 3
print(f" Combined OPS: {total_ops:.3f}")
# Step 1: Update BattingCardRatings
print("\nUpdating BattingCardRatings...")
ratings_list = [NEW_RATINGS["L"], NEW_RATINGS["R"]]
ratings_payload = {"ratings": ratings_list}
try:
result = await db_put("battingcardratings", payload=ratings_payload, timeout=10)
print(f" ✓ Updated ratings: {result}")
except Exception as e:
print(f" ✗ Error updating ratings: {e}")
return
# Step 2: Update CardPositions
print("\nUpdating CardPositions...")
positions_payload = {"positions": NEW_POSITIONS}
try:
result = await db_put("cardpositions", payload=positions_payload, timeout=10)
print(f" ✓ Updated positions: {result}")
except Exception as e:
print(f" ✗ Error updating positions: {e}")
return
# Summary
print("\n" + "=" * 70)
print("✓ KALIN YOUNG UPDATED SUCCESSFULLY!")
print("=" * 70)
print(f"\nPlayer ID: {PLAYER_ID}")
print(f"Cardset: 2005 Custom (ID: {CARDSET_ID})")
print("\nRating Changes:")
print(" Walk vL: 14.50 → 16.05 (+1.55)")
print(" Walk vR: 13.00 → 14.55 (+1.55)")
print(" Single (Center) vL: 4.25 → 5.80 (+1.55)")
print(" Single (Center) vR: 4.50 → 6.05 (+1.55)")
print(" Strikeout vL: 18.50 → 15.40 (-3.10)")
print(" Strikeout vR: 21.00 → 17.90 (-3.10)")
print(f"\nOPS: 0.837 → {total_ops:.3f}")
print("\nDefensive Updates:")
print(" RF: Range 3→2, Error 7→6, Arm 0")
print(" LF: Range 4, Error 7→6, Arm 0")
print("\n⚠️ AWS upload skipped - review card first:")
now = datetime.now()
release_date = f"{now.year}-{now.month}-{now.day}"
print(
f" PNG: https://pd.manticorum.com/api/v2/players/{PLAYER_ID}/battingcard?d={release_date}"
)
print(
f" HTML: https://pd.manticorum.com/api/v2/players/{PLAYER_ID}/battingcard?d={release_date}&html=true"
)
print("")
if __name__ == "__main__":
asyncio.run(main())