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

360 lines
11 KiB
Python

"""
Submit Tony Smehrik to Paper Dynasty Database
Custom pitcher with:
- Hand: Left
- Position: SP/RP (starter_rating: 5, relief_rating: 5)
- Combined OPS: 0.585
- OPS vs L: 0.465 (dominant same-side)
- OPS vs R: 0.645 (weaker opposite-side)
- K-rate vs L: ~20% (average)
- K-rate vs R: ~8% (very low)
- FB% vs L: ~44% (average)
- FB% vs R: ~56% (high)
- Team: Custom Ballplayers
- Cardset ID: 29
NO AWS UPLOAD - preview via PD API first
"""
import asyncio
from datetime import datetime
from db_calls import db_get, db_post, db_patch, db_put
from custom_cards.tony_smehrik_preview import calculate_pitcher_rating
# Configuration
CARDSET_ID = 29
CARDSET_NAME = "2005 Custom"
SEASON = 2005
PLAYER_DESCRIPTION = "2005 Custom"
# Player info
PLAYER_NAME_FIRST = "Tony"
PLAYER_NAME_LAST = "Smehrik"
HAND = "L"
STARTER_RATING = 5
RELIEF_RATING = 5
CLOSER_RATING = None
async def main():
"""Create Tony Smehrik pitcher card in database."""
print("\n" + "=" * 70)
print("SUBMITTING TONY SMEHRIK TO DATABASE")
print("=" * 70)
# Step 1: Calculate ratings (same as preview)
print("\nCalculating ratings...")
pit_hand = "L"
vl = calculate_pitcher_rating(
vs_hand="L",
pit_hand=pit_hand,
avg=0.185,
obp=0.240,
slg=0.225,
bb_pct=0.055,
k_pct=0.20,
hr_per_hit=0.04,
triple_per_hit=0.02,
double_per_hit=0.22,
fb_pct=0.35,
gb_pct=0.45,
hard_pct=0.30,
med_pct=0.50,
soft_pct=0.20,
oppo_pct=0.26,
hr_fb_pct=0.06,
)
vr = calculate_pitcher_rating(
vs_hand="R",
pit_hand=pit_hand,
avg=0.245,
obp=0.305,
slg=0.340,
bb_pct=0.075,
k_pct=0.08,
hr_per_hit=0.07,
triple_per_hit=0.02,
double_per_hit=0.24,
fb_pct=0.45,
gb_pct=0.35,
hard_pct=0.34,
med_pct=0.46,
soft_pct=0.20,
oppo_pct=0.26,
hr_fb_pct=0.09,
)
# Apply same manual adjustments as preview
# HR adjustments: half of all OB chances go to HR
vl_total_hits = (
vl["homerun"]
+ vl["bp_homerun"]
+ vl["triple"]
+ vl["double_three"]
+ vl["double_two"]
+ vl["double_cf"]
+ vl["single_two"]
+ vl["single_one"]
+ vl["single_center"]
+ vl["bp_single"]
)
vl_total_ob = vl_total_hits + vl["walk"] + vl["hbp"]
vl_hr_total = vl_total_ob / 2
vl["bp_homerun"] = round(vl_hr_total / 2)
vl["homerun"] = round((vl_hr_total - vl["bp_homerun"]) * 20) / 20
vl["hbp"] = 1.0
vr_total_hits = (
vr["homerun"]
+ vr["bp_homerun"]
+ vr["triple"]
+ vr["double_three"]
+ vr["double_two"]
+ vr["double_cf"]
+ vr["single_two"]
+ vr["single_one"]
+ vr["single_center"]
+ vr["bp_single"]
)
vr_total_ob = vr_total_hits + vr["walk"] + vr["hbp"]
vr_hr_total = vr_total_ob / 2
vr["bp_homerun"] = round(vr_hr_total / 2)
vr["homerun"] = round((vr_hr_total - vr["bp_homerun"]) * 20) / 20
vr["hbp"] = 1.0
# Reduce singles to compensate for HR increase
vl_new_hr_total = vl["homerun"] + vl["bp_homerun"]
vl_hr_increase = vl_new_hr_total
vl_singles_to_reduce = vl_hr_increase
reduce_from_one = min(vl["single_one"], vl_singles_to_reduce)
vl["single_one"] -= reduce_from_one
vl_singles_to_reduce -= reduce_from_one
reduce_from_two = min(vl["single_two"], vl_singles_to_reduce)
vl["single_two"] -= reduce_from_two
vl_singles_to_reduce -= reduce_from_two
reduce_from_bp = min(vl["bp_single"], vl_singles_to_reduce)
vl["bp_single"] -= reduce_from_bp
vl_singles_to_reduce -= reduce_from_bp
if vl_singles_to_reduce > 0:
vl["double_cf"] = max(0, vl["double_cf"] - vl_singles_to_reduce)
vr_new_hr_total = vr["homerun"] + vr["bp_homerun"]
vr_old_hr_total = 0.80 + 1.00
vr_hr_increase = vr_new_hr_total - vr_old_hr_total
vr_singles_to_reduce = vr_hr_increase
reduce_from_one = min(vr["single_one"], vr_singles_to_reduce)
vr["single_one"] -= reduce_from_one
vr_singles_to_reduce -= reduce_from_one
reduce_from_two = min(vr["single_two"], vr_singles_to_reduce)
vr["single_two"] -= reduce_from_two
vr_singles_to_reduce -= reduce_from_two
reduce_from_bp = min(vr["bp_single"], vr_singles_to_reduce)
vr["bp_single"] -= reduce_from_bp
vr_singles_to_reduce -= reduce_from_bp
if vr_singles_to_reduce > 0:
vr["double_cf"] = max(0, vr["double_cf"] - vr_singles_to_reduce)
# Force BP-SI values
vl["bp_single"] = 5.0
vr["bp_single"] = 3.0
# Adjust strikeouts to hit 108
for rating in [vl, vr]:
total = sum(
[
rating["homerun"],
rating["bp_homerun"],
rating["triple"],
rating["double_three"],
rating["double_two"],
rating["double_cf"],
rating["single_two"],
rating["single_one"],
rating["single_center"],
rating["bp_single"],
rating["hbp"],
rating["walk"],
rating["strikeout"],
rating["flyout_lf_b"],
rating["flyout_cf_b"],
rating["flyout_rf_b"],
rating["groundout_a"],
rating["groundout_b"],
rating["xcheck_p"],
rating["xcheck_c"],
rating["xcheck_1b"],
rating["xcheck_2b"],
rating["xcheck_3b"],
rating["xcheck_ss"],
rating["xcheck_lf"],
rating["xcheck_cf"],
rating["xcheck_rf"],
]
)
diff = 108 - total
rating["strikeout"] = round((rating["strikeout"] + diff) * 20) / 20
# Calculate OPS for verification
ops_vl = vl["obp"] + vl["slg"]
ops_vr = vr["obp"] + vr["slg"]
combined_ops = (ops_vr + ops_vl + max(ops_vl, ops_vr)) / 3
print(f" OPS vs L: {ops_vl:.3f}")
print(f" OPS vs R: {ops_vr:.3f}")
print(f" Combined OPS: {combined_ops:.3f}")
# Step 2: Verify cardset exists
print(f"\nVerifying cardset '{CARDSET_NAME}' (ID: {CARDSET_ID})...")
c_query = await db_get("cardsets", params=[("id", CARDSET_ID)])
if c_query["count"] == 0:
print(f" ERROR: Cardset ID {CARDSET_ID} not found!")
return
print(" ✓ Cardset verified")
# Step 3: Create Player record
print("\nCreating Player record...")
now = datetime.now()
release_date = f"{now.year}-{now.month}-{now.day}"
bbref_id = f"custom_{PLAYER_NAME_LAST.lower()}{PLAYER_NAME_FIRST[0].lower()}01"
player_payload = {
"p_name": f"{PLAYER_NAME_FIRST} {PLAYER_NAME_LAST}",
"cost": "100", # Default cost
"image": "change-me",
"mlbclub": "Custom Ballplayers",
"franchise": "Custom Ballplayers",
"cardset_id": CARDSET_ID,
"set_num": 99999,
"rarity_id": 3, # Starter rarity
"pos_1": "SP",
"pos_2": "RP",
"description": PLAYER_DESCRIPTION,
"bbref_id": bbref_id,
"fangr_id": 0,
"mlbplayer_id": None,
"is_custom": True,
}
player = await db_post("players", payload=player_payload)
player_id = player["player_id"]
print(f" ✓ Created Player ID: {player_id}")
# Update player with API image URL for preview
api_image_url = f"https://pd.manticorum.com/api/v2/players/{player_id}/pitchingcard?d={release_date}"
await db_patch("players", object_id=player_id, params=[("image", api_image_url)])
print(" ✓ Updated Player with API image URL")
# Step 4: Create PitchingCard
print("\nCreating PitchingCard...")
pitching_card_payload = {
"cards": [
{
"player_id": player_id,
"key_bbref": bbref_id,
"key_fangraphs": 0,
"key_mlbam": 0,
"key_retro": "",
"name_first": PLAYER_NAME_FIRST,
"name_last": PLAYER_NAME_LAST,
"hand": HAND,
"starter_rating": STARTER_RATING,
"relief_rating": RELIEF_RATING,
"closer_rating": CLOSER_RATING,
}
]
}
await db_put("pitchingcards", payload=pitching_card_payload, timeout=10)
# Get the created card ID
pc_query = await db_get("pitchingcards", params=[("player_id", player_id)])
pitchingcard_id = pc_query["cards"][0]["id"]
print(f" ✓ Created PitchingCard ID: {pitchingcard_id}")
# Step 5: Create PitchingCardRatings
print("\nCreating PitchingCardRatings...")
# Build ratings payload (remove display-only fields)
def build_rating_payload(rating, pitchingcard_id):
return {
"pitchingcard_id": pitchingcard_id,
"vs_hand": rating["vs_hand"],
"homerun": rating["homerun"],
"bp_homerun": rating["bp_homerun"],
"triple": rating["triple"],
"double_three": rating["double_three"],
"double_two": rating["double_two"],
"double_cf": rating["double_cf"],
"single_two": rating["single_two"],
"single_one": rating["single_one"],
"single_center": rating["single_center"],
"bp_single": rating["bp_single"],
"hbp": rating["hbp"],
"walk": rating["walk"],
"strikeout": rating["strikeout"],
"flyout_lf_b": rating["flyout_lf_b"],
"flyout_cf_b": rating["flyout_cf_b"],
"flyout_rf_b": rating["flyout_rf_b"],
"groundout_a": rating["groundout_a"],
"groundout_b": rating["groundout_b"],
"xcheck_p": rating["xcheck_p"],
"xcheck_c": rating["xcheck_c"],
"xcheck_1b": rating["xcheck_1b"],
"xcheck_2b": rating["xcheck_2b"],
"xcheck_3b": rating["xcheck_3b"],
"xcheck_ss": rating["xcheck_ss"],
"xcheck_lf": rating["xcheck_lf"],
"xcheck_cf": rating["xcheck_cf"],
"xcheck_rf": rating["xcheck_rf"],
}
ratings_payload = {
"ratings": [
build_rating_payload(vl, pitchingcard_id),
build_rating_payload(vr, pitchingcard_id),
]
}
await db_put("pitchingcardratings", payload=ratings_payload, timeout=10)
print(" ✓ Created ratings for vs L and vs R")
# Step 6: Create CardPositions
print("\nCreating CardPositions...")
positions_payload = {
"positions": [
{
"player_id": player_id,
"position": "P",
}
]
}
await db_put("cardpositions", payload=positions_payload, timeout=10)
print(" ✓ Created position record: P")
# Summary
print("\n" + "=" * 70)
print("✓ TONY SMEHRIK CREATED SUCCESSFULLY!")
print("=" * 70)
print(f"\nPlayer ID: {player_id}")
print(f"PitchingCard ID: {pitchingcard_id}")
print(f"Cardset: {CARDSET_NAME} (ID: {CARDSET_ID})")
print(f"Hand: {HAND}")
print(f"Starter Rating: {STARTER_RATING} | Relief Rating: {RELIEF_RATING}")
print("\nOffensive Profile (OPS Against):")
print(f" vs LHB: .185/.240/.225 ({ops_vl:.3f} OPS)")
print(f" vs RHB: .245/.305/.340 ({ops_vr:.3f} OPS)")
print(f" Combined: {combined_ops:.3f}")
print("\nPreview card (NO S3 upload yet):")
print(f" PNG: {api_image_url}")
print(f" HTML: {api_image_url}&html=true")
print("")
if __name__ == "__main__":
asyncio.run(main())