Full pitching run successful
This commit is contained in:
parent
b3c98e3c6e
commit
d4167b2b0c
171
calcs_pitcher.py
171
calcs_pitcher.py
@ -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):
|
||||
|
||||
@ -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))
|
||||
@ -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:]))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user