paper-dynasty-card-creation/.claude/ops-rework/analyze_hof_ops.py
2025-11-08 16:57:35 -06:00

126 lines
5.7 KiB
Python

import asyncio
from db_calls import db_get
import pandas as pd
async def main():
"""Analyze OPS values for Hall of Fame cards"""
# Get cardset
c_query = await db_get('cardsets', params=[('name', '2025 Season')])
cardset_id = c_query['cardsets'][0]['id']
print(f'Analyzing cardset: 2025 Season (ID: {cardset_id})\n')
# Get HOF players
p_query = await db_get('players', params=[('cardset_id', cardset_id)])
players_df = pd.DataFrame(p_query['players'])
if isinstance(players_df['rarity'].iloc[0], dict):
players_df['rarity_id'] = players_df['rarity'].apply(lambda x: x['id'] if isinstance(x, dict) else x)
else:
players_df['rarity_id'] = players_df['rarity']
hof_df = players_df[players_df['rarity_id'] == 99]
# Get batting cards and ratings
print('Analyzing HOF Batters:')
print('=' * 80)
bc_query = await db_get('battingcards', params=[('cardset_id', cardset_id), ('short_output', True)])
batting_cards = pd.DataFrame(bc_query['cards'])
vl_query = await db_get('battingcardratings', params=[('cardset_id', cardset_id), ('vs_hand', 'L'), ('short_output', True), ('team_id', 31), ('ts', 's37136685556r6135248705')], timeout=30)
vr_query = await db_get('battingcardratings', params=[('cardset_id', cardset_id), ('vs_hand', 'R'), ('short_output', True), ('team_id', 31), ('ts', 's37136685556r6135248705')], timeout=30)
vl = pd.DataFrame(vl_query['ratings'])
vr = pd.DataFrame(vr_query['ratings'])
# Calculate OPS for each hand
vl['ops_vL'] = vl['obp'] + vl['slg']
vr['ops_vR'] = vr['obp'] + vr['slg']
# Merge
bat_ratings = pd.merge(vl[['battingcard', 'ops_vL']], vr[['battingcard', 'ops_vR']], on='battingcard')
bat_ratings = pd.merge(batting_cards[['id', 'player']], bat_ratings, left_on='id', right_on='battingcard')
# Calculate total_OPS using min (as in the code)
bat_ratings['total_OPS'] = (bat_ratings['ops_vR'] + bat_ratings['ops_vL'] + bat_ratings[['ops_vL', 'ops_vR']].min(axis=1)) / 3
# Get HOF batters
hof_batters = pd.merge(hof_df, bat_ratings, left_on='player_id', right_on='player')
hof_batters = hof_batters.sort_values('total_OPS', ascending=False)
print(f'\nSample of HOF Batters (showing 15):')
print(f'{"Player Name":30} {"OPS vL":>10} {"OPS vR":>10} {"Total OPS":>10}')
print('-' * 80)
for idx, (_, row) in enumerate(hof_batters.head(15).iterrows()):
print(f'{row["p_name"]:30} {row["ops_vL"]:10.3f} {row["ops_vR"]:10.3f} {row["total_OPS"]:10.3f}')
print(f'\nHOF Batter OPS Statistics:')
print(f' Min: {hof_batters["total_OPS"].min():.3f}')
print(f' Max: {hof_batters["total_OPS"].max():.3f}')
print(f' Mean: {hof_batters["total_OPS"].mean():.3f}')
print(f' Median: {hof_batters["total_OPS"].median():.3f}')
print(f' Threshold for HOF: >= 1.2')
# Get pitching cards and ratings
print('\n' + '=' * 80)
print('Analyzing HOF Pitchers:')
print('=' * 80)
pc_query = await db_get('pitchingcards', params=[('cardset_id', cardset_id), ('short_output', True)])
pitching_cards = pd.DataFrame(pc_query['cards'])
vl_query = await db_get('pitchingcardratings', params=[('cardset_id', cardset_id), ('vs_hand', 'L'), ('short_output', True)], timeout=30)
vr_query = await db_get('pitchingcardratings', params=[('cardset_id', cardset_id), ('vs_hand', 'R'), ('short_output', True)], timeout=30)
vl = pd.DataFrame(vl_query['ratings'])
vr = pd.DataFrame(vr_query['ratings'])
# Calculate OPS for each hand
vl['ops_vL'] = vl['obp'] + vl['slg']
vr['ops_vR'] = vr['obp'] + vr['slg']
# Merge
pit_ratings = pd.merge(vl[['pitchingcard', 'ops_vL']], vr[['pitchingcard', 'ops_vR']], on='pitchingcard')
pit_ratings = pd.merge(pitching_cards[['id', 'player', 'starter_rating']], pit_ratings, left_on='id', right_on='pitchingcard')
# Calculate total_OPS using max (as in the code)
pit_ratings['total_OPS'] = (pit_ratings['ops_vR'] + pit_ratings['ops_vL'] + pit_ratings[['ops_vL', 'ops_vR']].max(axis=1)) / 3
# Get HOF pitchers
hof_pitchers = pd.merge(hof_df, pit_ratings, left_on='player_id', right_on='player')
hof_pitchers = hof_pitchers.sort_values('total_OPS')
# Split by starter/reliever
hof_starters = hof_pitchers[hof_pitchers['starter_rating'] > 3]
hof_relievers = hof_pitchers[hof_pitchers['starter_rating'] <= 3]
print(f'\nSample of HOF Starters (showing 15):')
print(f'{"Player Name":30} {"OPS vL":>10} {"OPS vR":>10} {"Total OPS":>10} {"Starter":>7}')
print('-' * 80)
for _, row in hof_starters.head(15).iterrows():
print(f'{row["p_name"]:30} {row["ops_vL"]:10.3f} {row["ops_vR"]:10.3f} {row["total_OPS"]:10.3f} {row["starter_rating"]:7}')
print(f'\nHOF Starter OPS Statistics:')
print(f' Min: {hof_starters["total_OPS"].min():.3f}')
print(f' Max: {hof_starters["total_OPS"].max():.3f}')
print(f' Mean: {hof_starters["total_OPS"].mean():.3f}')
print(f' Median: {hof_starters["total_OPS"].median():.3f}')
print(f' Threshold for HOF: <= 0.4')
print(f'\nSample of HOF Relievers (showing 15):')
print(f'{"Player Name":30} {"OPS vL":>10} {"OPS vR":>10} {"Total OPS":>10} {"Starter":>7}')
print('-' * 80)
for _, row in hof_relievers.head(15).iterrows():
print(f'{row["p_name"]:30} {row["ops_vL"]:10.3f} {row["ops_vR"]:10.3f} {row["total_OPS"]:10.3f} {row["starter_rating"]:7}')
print(f'\nHOF Reliever OPS Statistics:')
print(f' Min: {hof_relievers["total_OPS"].min():.3f}')
print(f' Max: {hof_relievers["total_OPS"].max():.3f}')
print(f' Mean: {hof_relievers["total_OPS"].mean():.3f}')
print(f' Median: {hof_relievers["total_OPS"].median():.3f}')
print(f' Threshold for HOF: <= 0.325')
if __name__ == '__main__':
asyncio.run(main())