Full pitching run successful

This commit is contained in:
Cal Corum 2023-10-03 12:06:11 -05:00
parent b3c98e3c6e
commit d4167b2b0c
3 changed files with 439 additions and 53 deletions

View File

@ -21,7 +21,7 @@ def get_pitcher_ratings(df_data) -> List[dict]:
vr = PitchingCardRatingsModel(
pitchingcard_id=df_data.pitchingcard_id,
pit_hand=df_data.hand,
vs_hand='L',
vs_hand='R',
all_hits=sanitize_chance_output((df_data['AVG_vR'] - 0.05) * 108), # Subtracting chances from BP results
all_other_ob=sanitize_chance_output(108 * (df_data['BB_vR'] + df_data['HBP_vR']) / df_data['TBF_vR']),
hard_rate=df_data['Hard%_vR'],
@ -48,6 +48,38 @@ def get_pitcher_ratings(df_data) -> List[dict]:
logging.info(f'vR: All Hits: {vr.all_hits} / BP Singles: {vr.bp_single} / Single 2: {vr.single_two} / '
f'Single 1: {vr.single_one} / Single CF: {vr.single_center}')
vl.calculate_xbh(df_data['2B_vL'], df_data['3B_vL'], df_data['HR_vL'], df_data['HR/FB_vL'])
vr.calculate_xbh(df_data['2B_vR'], df_data['3B_vR'], df_data['HR_vR'], df_data['HR/FB_vR'])
logging.debug(f'vL: All XBH: {vl.all_hits - vl.single_one - vl.single_two - vl.single_center - vl.bp_single} / '
f'Double**: {vl.double_two} / Double(cf): {vl.double_cf} / Triple: {vl.triple} / '
f'BP HR: {vl.bp_homerun} / ND HR: {vl.homerun}')
logging.debug(f'vR: All XBH: {vr.all_hits - vr.single_one - vr.single_two - vr.single_center - vr.bp_single} / '
f'Double**: {vr.double_two} / Double(cf): {vr.double_cf} / Triple: {vr.triple} / '
f'BP HR: {vr.bp_homerun} / ND HR: {vr.homerun}')
vl.calculate_other_ob(df_data['BB_vL'], df_data['HBP_vL'])
vr.calculate_other_ob(df_data['BB_vR'], df_data['HBP_vR'])
logging.info(f'vL: All other OB: {vl.all_other_ob} / HBP: {vl.hbp} / BB: {vl.walk} / '
f'Total Chances: {vl.total_chances()}')
logging.info(f'vR: All other OB: {vr.all_other_ob} / HBP: {vr.hbp} / BB: {vr.walk} / '
f'Total Chances: {vr.total_chances()}')
vl.calculate_strikouts(
df_data['SO_vL'], df_data['TBF_vL'] - df_data['BB_vL'] - df_data['IBB_vL'] - df_data['HBP_vL'], df_data['H_vL'])
vr.calculate_strikouts(
df_data['SO_vR'], df_data['TBF_vR'] - df_data['BB_vR'] - df_data['IBB_vR'] - df_data['HBP_vR'], df_data['H_vR'])
logging.info(f'vL: All Outs: {vl.all_outs} / Ks: {vl.strikeout} / Current Outs: {vl.total_outs()}')
logging.info(f'vR: All Outs: {vr.all_outs} / Ks: {vr.strikeout} / Current Outs: {vr.total_outs()}')
vl.calculate_other_outs(df_data['FB%_vL'], df_data['GB%_vL'], df_data['Oppo%_vL'])
vr.calculate_other_outs(df_data['FB%_vR'], df_data['GB%_vR'], df_data['Oppo%_vR'])
logging.info(f'vL: Total chances: {vl.total_chances()}')
logging.info(f'vR: Total chances: {vr.total_chances()}')
return [vl.custom_to_dict(), vr.custom_to_dict()]
@ -183,7 +215,142 @@ class PitchingCardRatingsModel(pydantic.BaseModel):
self.rem_singles -= self.single_center
self.rem_xbh = self.all_hits - self.single_center - self.single_one - self.single_two - self.bp_single
logging.info(f'remaining singles: {self.rem_singles}')
logging.info(f'remaining singles: {self.rem_singles} / total xbh: {self.rem_xbh}')
def calculate_xbh(self, szn_doubles, szn_triples, szn_homeruns, hr_per_fb_rate):
szn_xbh = szn_doubles + szn_triples + szn_homeruns
if szn_xbh == 0:
return
hr_rate = Decimal(szn_homeruns / szn_xbh)
tr_rate = Decimal(szn_triples / szn_xbh)
do_rate = Decimal(szn_doubles / szn_xbh)
logging.info(f'hr%: {hr_rate:.2f} / tr%: {tr_rate:.2f} / do%: {do_rate:.2f}')
raw_do_chances = sanitize_chance_output(Decimal(self.rem_xbh * do_rate))
logging.info(f'raw do chances: {raw_do_chances}')
self.double_two = raw_do_chances if self.soft_rate > .2 else Decimal(0)
self.double_cf = raw_do_chances - self.double_two
self.rem_xbh -= (self.double_two + self.double_cf + self.double_three)
logging.info(f'Double**: {self.double_two} / Double(cf): {self.double_cf} / rem xbh: {self.rem_xbh}')
self.triple = sanitize_chance_output(Decimal(self.rem_xbh * tr_rate))
self.rem_xbh -= self.triple
logging.info(f'Triple: {self.triple} / rem xbh: {self.rem_xbh}')
raw_hr_chances = self.rem_xbh
logging.info(f'raw hr chances: {raw_hr_chances}')
if hr_per_fb_rate < .08:
self.bp_homerun = sanitize_chance_output(raw_hr_chances, rounding=1.0)
elif hr_per_fb_rate > .28:
self.homerun = raw_hr_chances
elif hr_per_fb_rate > .18:
self.bp_homerun = sanitize_chance_output(raw_hr_chances * Decimal(0.4), rounding=1.0)
self.homerun = self.rem_xbh - self.bp_homerun
else:
self.bp_homerun = sanitize_chance_output(raw_hr_chances * Decimal(.75), rounding=1.0)
self.homerun = self.rem_xbh - self.bp_homerun
logging.info(f'BP HR: {self.bp_homerun} / ND HR: {self.homerun}')
self.rem_xbh -= (self.bp_homerun + self.homerun)
logging.info(f'excess xbh: {self.rem_xbh}')
if self.rem_xbh > 0:
if self.triple > 1:
logging.info(f'Passing {self.rem_xbh} xbh to triple')
self.triple += self.rem_xbh
self.rem_xbh = Decimal(0)
elif self.double_cf > 1:
logging.info(f'Passing {self.rem_xbh} xbh to double(cf)')
self.double_cf += self.rem_xbh
self.rem_xbh = Decimal(0)
elif self.double_two > 1:
logging.info(f'Passing {self.rem_xbh} xbh to double**')
self.double_two += self.rem_xbh
self.rem_xbh = Decimal(0)
elif self.single_two > 1:
logging.info(f'Passing {self.rem_xbh} xbh to single**')
self.single_two += self.rem_xbh
self.rem_xbh = Decimal(0)
elif self.single_center > 1:
logging.info(f'Passing {self.rem_xbh} xbh to single(cf)')
self.single_center += self.rem_xbh
self.rem_xbh = Decimal(0)
elif self.single_one > 1:
logging.info(f'Passing {self.rem_xbh} xbh to single*')
self.single_one += self.rem_xbh
self.rem_xbh = Decimal(0)
else:
logging.info(f'Passing {self.rem_xbh} xbh to other_ob')
self.all_other_ob += self.rem_xbh
def calculate_other_ob(self, szn_walks, szn_hbp):
if szn_walks + szn_hbp == 0:
return
self.hbp = sanitize_chance_output(self.all_other_ob * Decimal(szn_hbp / (szn_walks + szn_hbp)), rounding=1.0)
self.walk = self.all_other_ob - self.hbp
def calculate_strikouts(self, szn_strikeouts, szn_ab, szn_hits):
self.strikeout = sanitize_chance_output(self.all_outs * Decimal((szn_strikeouts * 1.2) / (szn_ab - szn_hits)))
def calculate_other_outs(self, fb_pct, gb_pct, oppo_pct):
rem_outs = Decimal(108) - self.total_chances()
all_fo = sanitize_chance_output(rem_outs * Decimal(fb_pct))
if self.pit_hand == 'L':
self.flyout_lf_b = sanitize_chance_output(all_fo * Decimal(oppo_pct))
else:
self.flyout_rf_b = sanitize_chance_output(all_fo * Decimal(oppo_pct))
self.flyout_cf_b = all_fo - self.flyout_lf_b - self.flyout_rf_b
rem_outs -= (self.flyout_lf_b + self.flyout_cf_b + self.flyout_rf_b)
all_gb = rem_outs
self.groundout_a = sanitize_chance_output(all_gb * self.soft_rate)
self.groundout_b = sanitize_chance_output(all_gb - self.groundout_a)
rem_chances = Decimal(108) - self.total_chances()
logging.info(f'Remaining outs: {rem_chances}')
if self.strikeout > 1:
logging.info(f'Passing {rem_chances} outs to strikeouts')
self.strikeout += rem_chances
elif self.flyout_cf_b > 1:
logging.info(f'Passing {rem_chances} outs to fly(cf)')
self.flyout_cf_b += rem_chances
elif self.flyout_rf_b > 1:
logging.info(f'Passing {rem_chances} outs to fly(rf)')
self.flyout_rf_b += rem_chances
elif self.flyout_lf_b > 1:
logging.info(f'Passing {rem_chances} outs to fly(lf)')
self.flyout_lf_b += rem_chances
elif self.groundout_a > 1:
logging.info(f'Passing {rem_chances} outs to gbA')
self.groundout_a += rem_chances
elif self.single_one > 1:
logging.info(f'Passing {rem_chances} outs to single*')
self.single_one += rem_chances
elif self.single_center > 1:
logging.info(f'Passing {rem_chances} outs to single(cf)')
self.single_center += rem_chances
elif self.single_two > 1:
logging.info(f'Passing {rem_chances} outs to single**')
self.single_two += rem_chances
elif self.double_two > 1:
logging.info(f'Passing {rem_chances} outs to double**')
self.double_two += rem_chances
elif self.double_cf > 1:
logging.info(f'Passing {rem_chances} outs to double(cf)')
self.double_cf += rem_chances
elif self.triple > 1:
logging.info(f'Passing {rem_chances} outs to triple')
self.triple += rem_chances
elif self.homerun > 1:
logging.info(f'Passing {rem_chances} outs to homerun')
self.homerun += rem_chances
else:
raise ValueError(f'Could not complete card')
def total_chances(chance_data):

View File

@ -1,6 +1,7 @@
import csv
import datetime
import logging
import math
from decimal import Decimal
import pandas as pd
@ -478,6 +479,42 @@ async def pd_battingcardratings_df(cardset_id: int):
# return pd.DataFrame(bcr_query['ratings']).rename(columns={'battingcard': 'battingcard_id'})
async def pd_pitchingcardratings_df(cardset_id: int):
vl_query = await db_get(
'pitchingcardratings', params=[('cardset_id', cardset_id), ('vs_hand', 'L'), ('short_output', True)])
vr_query = await db_get(
'pitchingcardratings', params=[('cardset_id', cardset_id), ('vs_hand', 'R'), ('short_output', True)])
if 0 in [vl_query['count'], vr_query['count']]:
raise ValueError(f'No pitching card ratings returned from Paper Dynasty API')
vl = pd.DataFrame(vl_query['ratings'])
vr = pd.DataFrame(vr_query['ratings'])
ratings = (pd.merge(vl, vr, on='pitchingcard', suffixes=('_vL', '_vR'))
.rename(columns={'pitchingcard': 'pitchingcard_id'}))
def get_total_ops(df_data):
ops_vl = df_data['obp_vL'] + df_data['slg_vL']
ops_vr = df_data['obp_vR'] + df_data['slg_vR']
return (ops_vr + ops_vl + min(ops_vl, ops_vr)) / 3
ratings['total_OPS'] = ratings.apply(get_total_ops, axis=1)
return ratings
def new_rarity_id(df_data):
if df_data['total_OPS'] >= 1.2:
return 99
elif df_data['total_OPS'] >= 1:
return 1
elif df_data['total_OPS'] >= .9:
return 2
elif df_data['total_OPS'] >= .8:
return 3
elif df_data['total_OPS'] >= .7:
return 4
else:
return 5
ratings['new_rarity_id'] = ratings.apply(new_rarity_id, axis=1)
def get_batting_stats(file_path: str = None, start_date: datetime.datetime = None, end_date: datetime.datetime = None):
if file_path is not None:
vl_basic = pd.read_csv(f'{file_path}vlhp-basic.csv').query('PA >= 20')
@ -863,5 +900,5 @@ def sanitize_chance_output(total_chances, min_chances=1.0, rounding=0.05):
# r_val = mround(total_chances) if total_chances >= min_chances else 0
r_val = Decimal(total_chances) if total_chances >= min_chances else Decimal(0)
logging.debug(f'r_val: {r_val}')
return Decimal(float(round(r_val / Decimal(rounding)) * Decimal(rounding))).quantize(Decimal("0.05"))
return Decimal(float(math.floor(r_val / Decimal(rounding)) * Decimal(rounding))).quantize(Decimal("0.05"))
# return r_val.quantize(Decimal(rounding))

View File

@ -6,6 +6,7 @@ import html5lib
import logging
import random
import requests
import urllib.parse
import calcs_batter as cba
import calcs_defense as cde
@ -16,7 +17,7 @@ import pydantic
import sys
from creation_helpers import pd_players_df, get_batting_stats, pd_battingcards_df, pd_battingcardratings_df, \
get_pitching_stats, get_pitching_peripherals, pd_pitchingcards_df
get_pitching_stats, get_pitching_peripherals, pd_pitchingcards_df, pd_pitchingcardratings_df
from db_calls import db_get, db_put, db_post, db_patch
from typing import Literal
from bs4 import BeautifulSoup
@ -28,7 +29,7 @@ logging.basicConfig(
format='%(asctime)s - card-creation - %(levelname)s - %(message)s',
level=log_level
)
CARD_BASE_URL = 'https://pd.manticorum.com/api/players'
CARD_BASE_URL = 'https://pddev.manticorum.com/api/players'
def sanitize_name(start_name: str) -> str:
@ -164,7 +165,8 @@ async def main(args):
new_players.append({
'p_name': f'{f_name} {l_name}',
'cost': 99999,
'image': f'{CARD_BASE_URL}/{df_data["player_id"]}/battingcard?d={release_directory}',
'image': f'{CARD_BASE_URL}/{df_data["player_id"]}/battingcard'
f'{urllib.parse.quote("?d=")}{release_directory}',
'mlbclub': 'None',
'franchise': 'None',
'cardset_id': cardset['id'],
@ -254,7 +256,7 @@ async def main(args):
print(f'Calculating batting cards...')
offense_stats.apply(create_batting_card, axis=1)
print(f'Cards are complete.\n\nPosting cards now...')
if 'post_updates' not in arg_data or arg_data['post_updates'].lower() == 'true':
if 'post_batters' not in arg_data or arg_data['post_batters'].lower() == 'true':
resp = await db_put('battingcards', payload={'cards': batting_cards}, timeout=30)
print(f'Response: {resp}\n\nMatching batting card database IDs to player stats...')
offense_stats = pd.merge(
@ -264,22 +266,22 @@ async def main(args):
def create_positions(df_data):
for pos_data in [(df_1b, '1b'), (df_2b, '2b'), (df_3b, '3b'), (df_ss, 'ss')]:
if df_data.name in pos_data[0].index:
logging.debug(f'Running {pos_data[1]} stats for {player_data.at[df_data.name, "p_name"]}')
if df_data['key_bbref'] in pos_data[0].index:
logging.debug(f'Running {pos_data[1]} stats for {player_data.at[df_data["key_bbref"], "p_name"]}')
position_payload.append({
"player_id": int(player_data.at[df_data.name, 'player_id']),
"player_id": int(player_data.at[df_data["key_bbref"], 'player_id']),
"position": pos_data[1].upper(),
"innings": float(pos_data[0].at[df_data.name, 'Inn_def']),
"innings": float(pos_data[0].at[df_data["key_bbref"], 'Inn_def']),
"range": cde.get_if_range(
pos_code=pos_data[1],
tz_runs=int(pos_data[0].at[df_data.name, 'tz_runs_total']),
tz_runs=int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']),
r_dp=0,
season_pct=season_pct
),
"error": cde.get_any_error(
pos_code=pos_data[1],
errors=int(pos_data[0].at[df_data.name, 'E_def']),
chances=int(pos_data[0].at[df_data.name, 'chances']),
errors=int(pos_data[0].at[df_data["key_bbref"], 'E_def']),
chances=int(pos_data[0].at[df_data["key_bbref"], 'chances']),
season_pct=season_pct
)
})
@ -287,24 +289,24 @@ async def main(args):
of_arms = []
of_payloads = []
for pos_data in [(df_lf, 'lf'), (df_cf, 'cf'), (df_rf, 'rf')]:
if df_data.name in pos_data[0].index:
if df_data["key_bbref"] in pos_data[0].index:
of_payloads.append({
"player_id": int(player_data.at[df_data.name, 'player_id']),
"player_id": int(player_data.at[df_data["key_bbref"], 'player_id']),
"position": pos_data[1].upper(),
"innings": float(pos_data[0].at[df_data.name, 'Inn_def']),
"innings": float(pos_data[0].at[df_data["key_bbref"], 'Inn_def']),
"range": cde.get_of_range(
pos_code=pos_data[1],
tz_runs=int(pos_data[0].at[df_data.name, 'tz_runs_total']),
tz_runs=int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']),
season_pct=season_pct
)
})
of_arms.append(int(pos_data[0].at[df_data.name, 'bis_runs_outfield']))
of_arms.append(int(pos_data[0].at[df_data["key_bbref"], 'bis_runs_outfield']))
if df_data.name in df_of.index and len(of_arms) > 0 and len(of_payloads) > 0:
if df_data["key_bbref"] in df_of.index and len(of_arms) > 0 and len(of_payloads) > 0:
error_rating = cde.get_any_error(
pos_code=pos_data[1],
errors=int(df_of.at[df_data.name, 'E_def']),
chances=int(df_of.at[df_data.name, 'chances']),
errors=int(df_of.at[df_data["key_bbref"], 'E_def']),
chances=int(df_of.at[df_data["key_bbref"], 'chances']),
season_pct=season_pct
)
arm_rating = cde.arm_outfield(of_arms)
@ -313,38 +315,38 @@ async def main(args):
f['arm'] = arm_rating
position_payload.append(f)
if df_data.name in df_c.index:
if df_c.at[df_data.name, 'SB'] + df_c.at[df_data.name, 'CS'] == 0:
if df_data["key_bbref"] in df_c.index:
if df_c.at[df_data["key_bbref"], 'SB'] + df_c.at[df_data["key_bbref"], 'CS'] == 0:
arm_rating = 3
else:
arm_rating = cde.arm_catcher(
cs_pct=df_c.at[df_data.name, 'caught_stealing_perc'],
raa=int(df_c.at[df_data.name, 'bis_runs_catcher_sb']),
cs_pct=df_c.at[df_data["key_bbref"], 'caught_stealing_perc'],
raa=int(df_c.at[df_data["key_bbref"], 'bis_runs_catcher_sb']),
season_pct=season_pct
)
position_payload.append({
"player_id": int(player_data.at[df_data.name, 'player_id']),
"player_id": int(player_data.at[df_data["key_bbref"], 'player_id']),
"position": 'C',
"innings": float(df_c.at[df_data.name, 'Inn_def']),
"innings": float(df_c.at[df_data["key_bbref"], 'Inn_def']),
"range": cde.range_catcher(
rs_value=int(df_c.at[df_data.name, 'tz_runs_catcher']),
rs_value=int(df_c.at[df_data["key_bbref"], 'tz_runs_catcher']),
season_pct=season_pct
),
"error": cde.get_any_error(
pos_code='c',
errors=int(df_c.at[df_data.name, 'E_def']),
chances=int(df_c.at[df_data.name, 'chances']),
errors=int(df_c.at[df_data["key_bbref"], 'E_def']),
chances=int(df_c.at[df_data["key_bbref"], 'chances']),
season_pct=season_pct
),
"arm": arm_rating,
"pb": cde.pb_catcher(
pb=int(df_c.at[df_data.name, 'PB']),
innings=int(float(df_c.at[df_data.name, 'Inn_def'])),
pb=int(df_c.at[df_data["key_bbref"], 'PB']),
innings=int(float(df_c.at[df_data["key_bbref"], 'Inn_def'])),
season_pct=season_pct
),
"overthrow": cde.ot_catcher(
errors=int(df_c.at[df_data.name, 'E_def']),
chances=int(df_c.at[df_data.name, 'chances']),
errors=int(df_c.at[df_data["key_bbref"], 'E_def']),
chances=int(df_c.at[df_data["key_bbref"], 'chances']),
season_pct=season_pct
)
})
@ -366,7 +368,7 @@ async def main(args):
print(f'Calculating card ratings...')
offense_stats.apply(create_batting_card_ratings, axis=1)
print(f'Ratings are complete\n\nPosting ratings now...')
if 'post_updates' not in arg_data or arg_data['post_updates'].lower() == 'true':
if 'post_batters' not in arg_data or arg_data['post_batters'].lower() == 'true':
resp = await db_put('battingcardratings', payload={'ratings': batting_ratings}, timeout=30)
print(f'Response: {resp}\n\nPulling fresh PD player data...')
@ -410,10 +412,11 @@ async def main(args):
5: 10,
99: 2400
}
params = []
params = [('description', f'{player_desc_prefix} {df_data["p_name"]}')]
if release_directory not in df_data['image']:
params.extend([('image', f'{CARD_BASE_URL}/{df_data["player_id"]}/card?d={release_directory}')])
params.extend([('image', f'{CARD_BASE_URL}/{df_data["player_id"]}/battingcard'
f'{urllib.parse.quote("?d=")}{release_directory}')])
if df_data['cost'] == 99999:
params.extend([
@ -505,7 +508,7 @@ async def main(args):
player_data.apply(get_player_updates, axis=1)
print(f'Sending {len(player_updates)} player updates to PD database...')
if 'post_updates' not in arg_data or arg_data['post_updates'].lower() == 'true':
if 'post_batters' not in arg_data or arg_data['post_batters'].lower() == 'true':
for x in player_updates:
await db_patch('players', object_id=x, params=player_updates[x])
@ -535,7 +538,8 @@ async def main(args):
new_players.append({
'p_name': f'{f_name} {l_name}',
'cost': 99999,
'image': f'{CARD_BASE_URL}/{df_data["player_id"]}/pitchingcard?d={release_directory}',
'image': f'{CARD_BASE_URL}/{df_data["player_id"]}/'
f'pitchingcard{urllib.parse.quote("?d=")}{release_directory}',
'mlbclub': 'None',
'franchise': 'None',
'cardset_id': cardset['id'],
@ -559,7 +563,7 @@ async def main(args):
).set_index('key_bbref', drop=False)
final_pitching = step_pitching.join(df_p, rsuffix='_r')
del ids_and_names, all_pitching, p_data, step_pitching
print(f'Player IDs linked to batting stats.\n{len(final_pitching.values)} players remain\n')
print(f'Player IDs linked to pitching stats.\n{len(final_pitching.values)} players remain\n')
print(f'Reading pitching peripheral stats...')
pit_data = (pd.read_csv(f'{input_path}pitching.csv')
@ -588,13 +592,14 @@ async def main(args):
"starter_rating": pow_data[0],
"relief_rating": pow_data[1],
"closer_rating": cpi.closer_rating(int(df_data['GF']), int(df_data['SV']), int(df_data['G'])),
"hand": df_data['pitch_hand']
"hand": df_data['pitch_hand'],
"batting": f'#1W{df_data["pitch_hand"]}-C'
})
print(f'Calculating pitching cards...')
pitching_stats.apply(create_pitching_card, axis=1)
print(f'Cards are complete.\n\nPosting cards now...')
if 'post_updates' not in arg_data or arg_data['post_updates'].lower() == 'true':
if 'post_pitchers' not in arg_data or arg_data['post_pitchers'].lower() == 'true':
resp = await db_put('pitchingcards', payload={'cards': pitching_cards}, timeout=30)
print(f'Response: {resp}\n\nMatching batting card database IDs to player stats...')
# final_pitching_stats = pd.merge(
@ -607,26 +612,26 @@ async def main(args):
pit_positions = []
def create_pit_position(df_data):
if df_data.name in df_p.index:
if df_data["key_bbref"] in df_p.index:
logging.debug(f'Running P stats for {df_data["p_name"]}')
pit_positions.append({
"player_id": int(player_data.at[df_data.name, 'player_id']),
"player_id": int(player_data.at[df_data["key_bbref"], 'player_id']),
"position": 'P',
"innings": float(df_p.at[df_data.name, 'Inn_def']),
"innings": float(df_p.at[df_data["key_bbref"], 'Inn_def']),
"range": cde.range_pitcher(
rs_value=int(df_p.at[df_data.name, 'bis_runs_total']),
rs_value=int(df_p.at[df_data["key_bbref"], 'bis_runs_total']),
season_pct=season_pct
),
"error": cde.get_any_error(
pos_code='p',
errors=int(df_p.at[df_data.name, 'E_def']),
chances=int(df_p.at[df_data.name, 'chances']),
errors=int(df_p.at[df_data["key_bbref"], 'E_def']),
chances=int(df_p.at[df_data["key_bbref"], 'chances']),
season_pct=season_pct
)
})
else:
pit_positions.append({
"player_id": int(player_data.at[df_data.name, 'player_id']),
"player_id": int(player_data.at[df_data["key_bbref"], 'player_id']),
"position": 'P',
"innings": 1,
"range": 5,
@ -636,7 +641,7 @@ async def main(args):
print(f'Calculating pitcher fielding lines now...')
pitching_stats.apply(create_pit_position, axis=1)
print(f'Fielding is complete.\n\nPosting positions now...')
if 'post_updates' not in arg_data or arg_data['post_updates'].lower() == 'true':
if 'post_pitchers' not in arg_data or arg_data['post_pitchers'].lower() == 'true':
resp = await db_put('cardpositions', payload={'positions': position_payload}, timeout=30)
print(f'Response: {resp}\n')
@ -647,12 +652,189 @@ async def main(args):
pitching_ratings.extend(cpi.get_pitcher_ratings(df_data))
print(f'Calculating card ratings...')
pitching_stats.apply(create_pitching_card_ratings, axis=1) # LOOK AT SINGLES
pitching_stats.apply(create_pitching_card_ratings, axis=1)
print(f'Ratings are complete\n\nPosting ratings now...')
if 'post_updates' not in arg_data or arg_data['post_updates'].lower() == 'true':
if 'post_pitchers' not in arg_data or arg_data['post_pitchers'].lower() == 'true':
resp = await db_put('pitchingcardratings', payload={'ratings': pitching_ratings}, timeout=30)
print(f'Response: {resp}\n\nPulling all positions to set player positions...')
"""
Pull fresh pd_players and set_index to player_id
Pull fresh battingcards and set_index to player
Pull fresh battingcardratings one hand at a time and join on battingcard (suffixes _vl and vR)
Join battingcards (left) with battingcardratings (right) as total_ratings on id (left) and battingcard (right)
Join pd_players (left) with total_ratings (right) on indeces
Output: PD player list with batting card, ratings vL, and ratings vR
Calculate Total OPS as OPSvL + OPSvR + min(OPSvL, OPSvR) / 3 and assign rarity_id
For players with cost of 99999, set cost to <Rarity Base Cost> * Total OPS / <Rarity Avg OPS>
"""
def new_rarity_id(df_data):
if df_data['starter_rating'] > 3:
if df_data['total_OPS'] <= 0.4:
return 99
elif df_data['total_OPS'] <= 0.475:
return 1
elif df_data['total_OPS'] <= 0.53:
return 2
elif df_data['total_OPS'] <= 0.6:
return 3
elif df_data['total_OPS'] <= 0.675:
return 4
else:
return 5
else:
if df_data['total_OPS'] <= 0.325:
return 99
elif df_data['total_OPS'] <= 0.4:
return 1
elif df_data['total_OPS'] <= 0.475:
return 2
elif df_data['total_OPS'] <= 0.55:
return 3
elif df_data['total_OPS'] <= 0.625:
return 4
else:
return 5
p_data = await pd_players_df(cardset['id'])
p_data.set_index('player_id', drop=False)
total_ratings = pd.merge(
await pd_pitchingcards_df(cardset['id']),
await pd_pitchingcardratings_df(cardset['id']),
on='pitchingcard_id'
)
total_ratings['new_rarity_id'] = total_ratings.apply(new_rarity_id, axis=1)
player_data = pd.merge(
p_data,
total_ratings,
on='player_id'
).set_index('player_id', drop=False)
# del total_ratings, pitching_stats
player_updates = {} # { <player_id> : [ (param pairs) ] }
rarity_group = player_data.query('rarity == new_rarity_id').groupby('rarity')
average_ops = rarity_group['total_OPS'].mean().to_dict()
# cost_groups = rarity_group['cost'].mean()
def get_player_updates(df_data):
base_costs = {
1: 810,
2: 270,
3: 90,
4: 30,
5: 10,
99: 2400
}
params = [('description', f'{player_desc_prefix} {df_data["p_name"]}')]
if release_directory not in df_data['image']:
params.extend([('image', f'{CARD_BASE_URL}/{df_data["player_id"]}/pitchingcard'
f'{urllib.parse.quote("?d=")}{release_directory}')])
if df_data['cost'] == 99999:
params.extend([
('cost',
round(base_costs[df_data['new_rarity_id']] * df_data['total_OPS'] /
average_ops[df_data['new_rarity_id']])),
('rarity_id', df_data['new_rarity_id'])
])
elif df_data['rarity'] != df_data['new_rarity_id']:
old_rarity = df_data['rarity']
new_rarity = df_data['new_rarity_id']
old_cost = df_data['cost']
new_cost = 0
if old_rarity == 1:
if new_rarity == 2:
new_cost = max(old_cost - 540, 100)
elif new_rarity == 3:
new_cost = max(old_cost - 720, 50)
elif new_rarity == 4:
new_cost = max(old_cost - 780, 15)
elif new_rarity == 5:
new_cost = max(old_cost - 800, 5)
elif new_rarity == 99:
new_cost = old_cost + 1600
elif old_rarity == 2:
if new_rarity == 1:
new_cost = old_cost + 540
elif new_rarity == 3:
new_cost = max(old_cost - 180, 50)
elif new_rarity == 4:
new_cost = max(old_cost - 240, 15)
elif new_rarity == 5:
new_cost = max(old_cost - 260, 5)
elif new_rarity == 99:
new_cost = old_cost + 2140
elif old_rarity == 3:
if new_rarity == 1:
new_cost = old_cost + 720
elif new_rarity == 2:
new_cost = old_cost + 180
elif new_rarity == 4:
new_cost = max(old_cost - 60, 15)
elif new_rarity == 5:
new_cost = max(old_cost - 80, 5)
elif new_rarity == 99:
new_cost = old_cost + 2320
elif old_rarity == 4:
if new_rarity == 1:
new_cost = old_cost + 780
elif new_rarity == 2:
new_cost = old_cost + 240
elif new_rarity == 3:
new_cost = old_cost + 60
elif new_rarity == 5:
new_cost = max(old_cost - 20, 5)
elif new_rarity == 99:
new_cost = old_cost + 2380
elif old_rarity == 5:
if new_rarity == 1:
new_cost = old_cost + 800
elif new_rarity == 2:
new_cost = old_cost + 260
elif new_rarity == 3:
new_cost = old_cost + 80
elif new_rarity == 4:
new_cost = old_cost + 20
elif new_rarity == 99:
new_cost = old_cost + 2400
elif old_rarity == 99:
if new_rarity == 1:
new_cost = max(old_cost - 1600, 800)
elif new_rarity == 2:
new_cost = max(old_cost - 2140, 100)
elif new_rarity == 3:
new_cost = max(old_cost - 2320, 50)
elif new_rarity == 4:
new_cost = max(old_cost - 2380, 15)
elif new_rarity == 5:
new_cost = max(old_cost - 2400, 5)
if new_cost != 0:
params.extend([('cost', new_cost), ('rarity_id', new_rarity)])
if len(params) > 0:
player_updates[df_data.name] = params
player_data.apply(get_player_updates, axis=1)
print(f'Sending {len(player_updates)} player updates to PD database...')
if 'post_pitchers' not in arg_data or arg_data['post_pitchers'].lower() == 'true':
for x in player_updates:
await db_patch('players', object_id=x, params=player_updates[x])
print(f'Pitcher updates are complete')
p_run_time = datetime.datetime.now() - start_time_two
t_run_time = datetime.datetime.now() - start_time
print(f'Total pitching cards: {len(pitching_cards)}\nNew cardset pitchers: {len(new_players)}\n'
f'Pitcher runtime: {round(p_run_time.total_seconds())} seconds\n')
print(f'Total runtime: {round(t_run_time.total_seconds())} seconds')
if __name__ == '__main__':
asyncio.run(main(sys.argv[1:]))