import copy import math import pathlib import sys import csv import logging import datetime import asyncio from db_calls_card_creation import * from creation_helpers import * import calcs_pitcher as p import calcs_batter as b import calcs_defense as d date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' log_level = logging.INFO logging.basicConfig( filename=f'logs/{date}.log', format='%(asctime)s - card-creation - %(levelname)s - %(message)s', level=log_level ) """ Data Links: Baserunning: https://www.baseball-reference.com/leagues/majors/2022-baserunning-batting.shtml Defense: https://www.baseball-reference.com/leagues/majors/2022-specialpos_p-fielding.shtml All 9 positions plus OF Pitcher Peripherals: https://www.baseball-reference.com/leagues/majors/2022-standard-pitching.shtml Pitching & Batting: https://www.fangraphs.com/leaders/splits-leaderboards """ async def main(argv): cardset_name = input(f'What is the name of this Cardset? ') # cardset_name = '2022 Live' cardset = ScoutCardset.get_or_none(fn.Lower(ScoutCardset.set_title) == cardset_name.lower()) testing = False if not cardset: create_cardset = input(f'There is no cardset named **{cardset_name}**. Should I create it (y/n)? ') if create_cardset.lower() in YES: cardset = ScoutCardset(set_title=cardset_name) cardset.save() print(f'Got it! Now on to the cards.') else: print(f'Okay, see you next time.') return now = datetime.datetime.now() output_path = pathlib.Path(f'card-output/{cardset.set_title} Cardset/') input_path = f'data-input/{cardset.set_title} Cardset/' game_count = 0 while (game_count <= 0) or (game_count > 162): game_count = int(input(f'How many games out of 162 have been played? ')) season_pct = game_count / 162 print(f'season_pct: {season_pct}') # Get stat csv print(f'Your input files should be located in data-input/{cardset.set_title} Cardset/') await asyncio.sleep(1) lets_go = input(f'Should I run pitchers (y/n)? ') if lets_go in YES: existing_columns = CardColumns.delete().where( CardColumns.id.endswith(f'-{cardset.id}') & CardColumns.p_ratings.is_null(False) ).execute() existing_pitchers = PitcherRatings.delete().where(PitcherRatings.cardset == cardset).execute() # ratings_guide = [[ # 'name', 'sba-id', 'hr-vL', 'bp-hr-vL', 'tr-vL', 'do***-vL', 'do**-vL', 'do-cf-vL', 'si**-vL', 'si*-vL', # 'si-cf-vL', 'bp-si-vL', 'hbp-vL', 'bb-vL', 'so-vL', 'fo-b-cf-vL', 'fo-b-slap-vL', 'gb-a-vL', 'gb-c-vL', # 'gb-x-p-vL', 'gb-x-c-vL', 'gb-x-1b-vL', 'gb-x-2b-vL', 'gb-x-3b-vL', 'gb-x-ss-vL', 'gb-x-lf-vL', # 'gb-x-cf-vL', 'gb-x-rf-vL', # 'hr-vR', 'bp-hr-vR', 'tr-vR', 'do***-vR', 'do**-vR', 'do-cf-vR', 'si**-vR', 'si*-vR', # 'si-cf-vR', 'bp-si-vR', 'hbp-vR', 'bb-vR', 'so-vR', 'fo-b-cf-vR', 'fo-b-slap-vR', 'gb-a-vR', 'gb-c-vR', # 'gb-x-p-vR', 'gb-x-c-vR', 'gb-x-1b-vR', 'gb-x-2b-vR', 'gb-x-3b-vR', 'gb-x-ss-vR', 'gb-x-lf-vR', # 'gb-x-cf-vR', 'gb-x-rf-vR' # ]] # card_columns = [[ # 'name', 'sba_id', 'hand', 'vl_one_2d6', 'vl_one_results', 'vl_one_splits', 'vl_two_2d6', 'vl_two_results', # 'vl_two_splits', 'vl_three_2d6', 'vl_three_results', 'vl_three_splits', 'vr_one_2d6', 'vr_one_results', # 'vr_one_splits', 'vr_two_2d6', 'vr_two_results', 'vr_two_splits', 'vr_three_2d6', 'vr_three_results', # 'vr_three_splits' # ]] # rg_headers = ['name', 'hand', 'hr', 'bp-hr', 'tr', 'do***', 'do**', 'do-cf', 'si**', 'si*', 'si-cf', 'bp-si', # 'hbp', 'bb', 'so', 'fo-cf', 'fo-slap', 'gb-a', 'gb-c', 'gb-x-p', 'gb-x-c', 'gb-x-1b', 'gb-x-2b', # 'gb-x-3b', 'gb-x-ss', 'gb-x-lf', 'gb-x-cf', 'gb-x-rf'] """ Process pitcher stats into raw chances """ count_pitchers = 0 with open(f'{input_path}pitcher-stats.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) for row in reader: try: player = ScoutPlayer.get_or_none(ScoutPlayer.fg_id == int(row[0])) if testing: print(f'player fg_id: {int(row[0])} / player: {player}') # Standard limits # if player is not None and (('Promo' in cardset.set_title) or (int(row[5]) >= 30 and int(row[38]) >= 45)): if player is not None: chance_data_vl = { 'id': f'{player.sba_id}-vL-{cardset.id}', 'player_id': player.sba_id, 'cardset_id': cardset.id, 'vs_hand': 'vL', 'is_prep': True, 'homerun': 0, 'bp_homerun': 0, 'triple': 0, 'double_three': 0, 'double_two': 0, 'double_cf': 0, 'single_two': 0, 'single_one': 0, 'single_center': 0, 'bp_single': 0, 'hbp': 0, 'walk': 0, 'strikeout': 0, 'fo_slap': 0, 'fo_center': 0, 'groundout_a': 0, 'groundout_b': 0, 'xcheck_p': 0, 'xcheck_c': 0, 'xcheck_1b': 0, 'xcheck_2b': 0, 'xcheck_3b': 0, 'xcheck_ss': 0, 'xcheck_lf': 0, 'xcheck_cf': 0, 'xcheck_rf': 0, } chance_data_vr = { 'id': f'{player.sba_id}-vR-{cardset.id}', 'player_id': player.sba_id, 'cardset_id': cardset.id, 'vs_hand': 'vR', 'is_prep': True, 'homerun': 0, 'bp_homerun': 0, 'triple': 0, 'double_three': 0, 'double_two': 0, 'double_cf': 0, 'single_two': 0, 'single_one': 0, 'single_center': 0, 'bp_single': 0, 'hbp': 0, 'walk': 0, 'strikeout': 0, 'fo_slap': 0, 'fo_center': 0, 'groundout_a': 0, 'groundout_b': 0, 'xcheck_p': 0, 'xcheck_c': 0, 'xcheck_1b': 0, 'xcheck_2b': 0, 'xcheck_3b': 0, 'xcheck_ss': 0, 'xcheck_lf': 0, 'xcheck_cf': 0, 'xcheck_rf': 0, } # Get total num hits v both total_hit_mod = 5 # originally 9 to account for x-hits raw_hits_vl = mround(float(row[17]) * 108) raw_hits_vr = mround(float(row[50]) * 108) hits_vl = max(raw_hits_vl - total_hit_mod, 5) hits_vr = max(raw_hits_vr - total_hit_mod, 5) soft_rate_vl = p.soft_rate(float(row[34])) soft_rate_vr = p.soft_rate(float(row[67])) med_rate_vl = p.med_rate(float(row[35])) med_rate_vr = p.med_rate(float(row[68])) hard_rate_vl = p.hard_rate(float(row[36])) hard_rate_vr = p.hard_rate(float(row[69])) # Get Singles tot_singles_vl, tot_singles_vr = p.all_singles(row, hits_vl, hits_vr) total_xbh_vl = mround(hits_vl - tot_singles_vl) total_xbh_vr = mround(hits_vr - tot_singles_vr) # BPSI bpsi_vl, bpsi_vr = p.bp_singles(tot_singles_vl, tot_singles_vr) chance_data_vl['bp_single'] = bpsi_vl chance_data_vr['bp_single'] = bpsi_vr tot_singles_vl = mround(tot_singles_vl - bpsi_vl) tot_singles_vr = mround(tot_singles_vr - bpsi_vr) # SI** si2_vl, si2_vr = p.wh_singles(tot_singles_vl, tot_singles_vr, hard_rate_vl, hard_rate_vr) chance_data_vl['single_two'] = si2_vl chance_data_vr['single_two'] = si2_vr tot_singles_vl = mround(tot_singles_vl - si2_vl) tot_singles_vr = mround(tot_singles_vr - si2_vr) # SI* si1_vl, si1_vr = p.one_singles(tot_singles_vl, tot_singles_vr, soft_rate_vl, soft_rate_vr) chance_data_vl['single_one'] = si1_vl chance_data_vr['single_one'] = si1_vr tot_singles_vl = mround(tot_singles_vl - si1_vl) tot_singles_vr = mround(tot_singles_vr - si1_vr) # SI(cf) chance_data_vl['single_center'] = tot_singles_vl chance_data_vr['single_center'] = tot_singles_vr # Home Runs hr_rate_vl = p.hr_per_fb_rate(float(row[28])) hr_rate_vr = p.hr_per_fb_rate(float(row[61])) try: hr_vl = mround(hits_vl * (float(row[12]) / float(row[7]))) except ZeroDivisionError: hr_vl = 0 try: hr_vr = mround(hits_vr * (float(row[45]) / float(row[40]))) except ZeroDivisionError: hr_vr = 0 bphr_vl, bphr_vr = p.bp_homerun(hr_vl, hr_vr, hr_rate_vl, hr_rate_vr) chance_data_vl['bp_homerun'] = bphr_vl chance_data_vr['bp_homerun'] = bphr_vr chance_data_vl['homerun'] = mround(hr_vl - bphr_vl) chance_data_vr['homerun'] = mround(hr_vr - bphr_vr) total_xbh_vl = mround(total_xbh_vl - hr_vl) total_xbh_vr = mround(total_xbh_vr - hr_vr) non_hrs_vl = float(row[8]) + float(row[9]) non_hrs_vr = float(row[41]) + float(row[42]) triple_per_23b_vl = (float(row[9]) / non_hrs_vl) if non_hrs_vl > 0 else 0 triple_per_23b_br = (float(row[42]) / non_hrs_vr) if non_hrs_vr > 0 else 0 tr_vl, tr_vr = p.triples(total_xbh_vl, total_xbh_vr, triple_per_23b_vl, triple_per_23b_br) chance_data_vl['triple'] = tr_vl chance_data_vr['triple'] = tr_vr doubles_vl = mround(total_xbh_vl - tr_vl) doubles_vr = mround(total_xbh_vr - tr_vr) ts_doubles_vl, ts_doubles_vr = p.two_doubles(doubles_vl, doubles_vr, soft_rate_vl, soft_rate_vr) chance_data_vl['double_two'] = ts_doubles_vl chance_data_vr['double_two'] = ts_doubles_vr chance_data_vl['double_cf'] = mround(doubles_vl - ts_doubles_vl) chance_data_vr['double_cf'] = mround(doubles_vr - ts_doubles_vr) if testing: print(f'vl hits: {hits_vl} / vr hits: {hits_vr}') print(f'xbh vl: {total_xbh_vl}\nxbh vr: {total_xbh_vr}') print(f'final hits vl: {p.total_chances(chance_data_vl)} / ' f'final hits vr: {p.total_chances(chance_data_vr)}') other_ob_vl = mround((float(row[18]) - float(row[17])) * 108) other_ob_vr = mround((float(row[51]) - float(row[50])) * 108) hbp_per_walk_vl = p.hbp_rate(float(row[15]), float(row[13])) hbp_per_walk_vr = p.hbp_rate(float(row[48]), float(row[46])) chance_data_vl['hbp'] = p.hbps(other_ob_vl, hbp_per_walk_vl) chance_data_vr['hbp'] = p.hbps(other_ob_vr, hbp_per_walk_vr) chance_data_vl['walk'] = mround(other_ob_vl - chance_data_vl['hbp']) chance_data_vr['walk'] = mround(other_ob_vr - chance_data_vr['hbp']) if testing: print(f'ob vl: {p.total_chances(chance_data_vl)}\nob vr: {p.total_chances(chance_data_vr)}') chance_data_vl['xcheck_p'] = p.xchecks('p') chance_data_vl['xcheck_c'] = p.xchecks('c') chance_data_vl['xcheck_1b'] = p.xchecks('1b') chance_data_vl['xcheck_2b'] = p.xchecks('2b') chance_data_vl['xcheck_3b'] = p.xchecks('3b') chance_data_vl['xcheck_ss'] = p.xchecks('ss') chance_data_vl['xcheck_lf'] = p.xchecks('lf') chance_data_vl['xcheck_cf'] = p.xchecks('cf') chance_data_vl['xcheck_rf'] = p.xchecks('rf') chance_data_vr['xcheck_p'] = p.xchecks('p') chance_data_vr['xcheck_c'] = p.xchecks('c') chance_data_vr['xcheck_1b'] = p.xchecks('1b') chance_data_vr['xcheck_2b'] = p.xchecks('2b') chance_data_vr['xcheck_3b'] = p.xchecks('3b') chance_data_vr['xcheck_ss'] = p.xchecks('ss') chance_data_vr['xcheck_lf'] = p.xchecks('lf') chance_data_vr['xcheck_cf'] = p.xchecks('cf') chance_data_vr['xcheck_rf'] = p.xchecks('rf') all_outs_vl = mround(108 - p.total_chances(chance_data_vl)) all_outs_vr = mround(108 - p.total_chances(chance_data_vr)) if testing: print(f'total vl: {p.total_chances(chance_data_vl)}\ntotal vr: {p.total_chances(chance_data_vr)}\n' f'outs vl: {all_outs_vl}\nouts vr: {all_outs_vr}') so_pct_vl = float(row[16]) / ( float(row[5]) - float(row[7]) - float(row[13]) - float(row[14]) - float(row[15]) ) so_pct_vr = float(row[49]) / ( float(row[38]) - float(row[40]) - float(row[46]) - float(row[47]) - float(row[48]) ) # so_vl = mround(all_outs_vl * so_pct_vl * 1.2) # so_vr = mround(all_outs_vr * so_pct_vr * 1.2) so_vl = mround(all_outs_vl * so_pct_vl) so_vr = mround(all_outs_vr * so_pct_vr) chance_data_vl['strikeout'] = so_vl chance_data_vr['strikeout'] = so_vr rem_outs_vl = mround(all_outs_vl - so_vl) rem_outs_vr = mround(all_outs_vr - so_vr) fly_pct_vl = float(row[26]) / (float(row[26]) + float(row[25])) fly_pct_vr = float(row[59]) / (float(row[59]) + float(row[58])) all_fly_vl = mround(rem_outs_vl * fly_pct_vl) all_fly_vr = mround(rem_outs_vr * fly_pct_vr) opp_fly_vl = float(row[33]) / (float(row[33]) + float(row[32])) opp_fly_vr = float(row[66]) / (float(row[66]) + float(row[65])) chance_data_vl['fo_slap'] = p.oppo_fly(all_fly_vl, opp_fly_vl) chance_data_vr['fo_slap'] = p.oppo_fly(all_fly_vr, opp_fly_vr) chance_data_vl['fo_center'] = mround(all_fly_vl - chance_data_vl['fo_slap']) chance_data_vr['fo_center'] = mround(all_fly_vr - chance_data_vr['fo_slap']) go_vl = mround(rem_outs_vl - all_fly_vl) go_vr = mround(rem_outs_vr - all_fly_vr) chance_data_vl['groundout_a'] = p.groundball_a(go_vl, float(row[35])) chance_data_vr['groundout_a'] = p.groundball_a(go_vr, float(row[68])) chance_data_vl['groundout_b'] = mround(go_vl - chance_data_vl['groundout_a']) chance_data_vr['groundout_b'] = mround(go_vr - chance_data_vr['groundout_a']) if testing: print(f'total vl: {p.total_chances(chance_data_vl)}\ntotal vr: {p.total_chances(chance_data_vr)}') print(f'{row[2]}\nvl: {chance_data_vl}\nvr: {chance_data_vr}') this_line = PitcherRatings.create(**chance_data_vl) this_line.save() this_line = PitcherRatings.create(**chance_data_vr) this_line.save() """ Process pitcher chances into card output and ratings guide """ bat_hand = player.hand tba = { 'vL': { 'bp-si': { 'value': chance_data_vl['bp_single'], 'string': '▼BP-SI', 'bold': True, 'actual': 0 }, 'si-cf': { 'value': chance_data_vl['single_center'], 'string': 'SINGLE (cf)', 'sm-string': 'SI (cf)', 'bold': True, 'actual': 0 }, 'si*': { 'value': chance_data_vl['single_one'], 'string': 'SINGLE*', 'sm-string': 'SI*', 'bold': True, 'actual': 0 }, 'si**': { 'value': chance_data_vl['single_two'], 'string': 'SINGLE**', 'sm-string': 'SI**', 'bold': True, 'actual': 0 }, 'bp-hr': { 'value': chance_data_vl['bp_homerun'], 'string': '◆BP-HR', 'bold': True, 'actual': 0 }, 'hr': { 'value': chance_data_vl['homerun'], 'string': 'HOMERUN', 'sm-string': 'HR', 'bold': True, 'actual': 0 }, 'tr': { 'value': chance_data_vl['triple'], 'string': 'TRIPLE', 'sm-string': 'TR', 'bold': True, 'actual': 0 }, 'do**': { 'value': chance_data_vl['double_two'], 'string': 'DOUBLE**', 'sm-string': 'DO**', 'bold': True, 'actual': 0 }, 'do***': { 'value': chance_data_vl['double_three'], 'string': 'DOUBLE***', 'sm-string': 'DO***', 'bold': True, 'actual': 0 }, 'do-cf': { 'value': chance_data_vl['double_cf'], 'string': f'DOUBLE (cf)', 'sm-string': f'DO (cf)', 'bold': True, 'actual': 0 }, 'hbp': { 'value': chance_data_vl['hbp'], 'string': 'HBP', 'bold': True, 'actual': 0 }, 'bb': { 'value': chance_data_vl['walk'], 'string': 'WALK', 'bold': True, 'actual': 0 }, 'so': { 'value': chance_data_vl['strikeout'], 'string': 'strikeout', # 'sm-string': 'so', 'bold': False, 'actual': 0, }, 'fo-slap': { 'value': chance_data_vl['fo_slap'], 'string': f'fly (lf) B', 'sm-string': f'fly (lf) B', 'bold': False, 'actual': 0 }, 'fo-cf': { 'value': chance_data_vl['fo_center'], 'string': f'fly (cf) B', 'sm-string': f'fly (cf) B', 'bold': False, 'actual': 0 }, 'gb-a': { 'value': chance_data_vl['groundout_a'], 'string': f'gb (2b) A', 'bold': False, 'actual': 0 }, 'gb-c': { 'value': chance_data_vl['groundout_b'], 'string': f'gb (3b) C', 'bold': False, 'actual': 0 }, 'gb-x-p': { 'value': chance_data_vl['xcheck_p'], 'string': 'GB (p) X', 'bold': False, 'actual': 0 }, 'gb-x-c': { 'value': chance_data_vl['xcheck_c'], 'string': 'CATCH-X', 'bold': False, 'actual': 0 }, 'gb-x-1b': { 'value': chance_data_vl['xcheck_1b'], 'string': 'GB (1b) X', 'bold': False, 'actual': 0 }, 'gb-x-2b': { 'value': chance_data_vl['xcheck_2b'], 'string': 'GB (2b) X', 'bold': False, 'actual': 0 }, 'gb-x-3b': { 'value': chance_data_vl['xcheck_3b'], 'string': 'GB (3b) X', 'bold': False, 'actual': 0 }, 'gb-x-ss': { 'value': chance_data_vl['xcheck_ss'], 'string': 'GB (ss) X', 'bold': False, 'actual': 0 }, 'gb-x-lf': { 'value': chance_data_vl['xcheck_lf'], 'string': 'FLY (lf) X', 'bold': False, 'actual': 0 }, 'gb-x-cf': { 'value': chance_data_vl['xcheck_cf'], 'string': 'FLY (cf) X', 'bold': False, 'actual': 0 }, 'gb-x-rf': { 'value': chance_data_vl['xcheck_rf'], 'string': 'FLY (rf) X', 'bold': False, 'actual': 0 }, 'fatigue': 0 }, 'vR': { 'bp-si': { 'value': chance_data_vr['bp_single'], 'string': '▼BP-SI', 'bold': True, 'actual': 0 }, 'si-cf': { 'value': chance_data_vr['single_center'], 'string': 'SINGLE (cf)', 'sm-string': 'SI (cf)', 'bold': True, 'actual': 0 }, 'si*': { 'value': chance_data_vr['single_one'], 'string': 'SINGLE*', 'sm-string': 'SI*', 'bold': True, 'actual': 0 }, 'si**': { 'value': chance_data_vr['single_two'], 'string': 'SINGLE**', 'sm-string': 'SI**', 'bold': True, 'actual': 0 }, 'bp-hr': { 'value': chance_data_vr['bp_homerun'], 'string': '◆BP-HR', 'bold': True, 'actual': 0 }, 'hr': { 'value': chance_data_vr['homerun'], 'string': 'HOMERUN', 'sm-string': 'HR', 'bold': True, 'actual': 0 }, 'tr': { 'value': chance_data_vr['triple'], 'string': 'TRIPLE', 'sm-string': 'TR', 'bold': True, 'actual': 0 }, 'do**': { 'value': chance_data_vr['double_two'], 'string': 'DOUBLE**', 'sm-string': 'DO**', 'bold': True, 'actual': 0 }, 'do***': { 'value': chance_data_vr['double_three'], 'string': 'DOUBLE***', 'sm-string': 'DO***', 'bold': True, 'actual': 0 }, 'do-cf': { 'value': chance_data_vr['double_cf'], 'string': f'DOUBLE (cf)', 'sm-string': f'DO (cf)', 'bold': True, 'actual': 0 }, 'hbp': { 'value': chance_data_vr['hbp'], 'string': 'HBP', 'bold': True, 'actual': 0 }, 'bb': { 'value': chance_data_vr['walk'], 'string': 'WALK', 'bold': True, 'actual': 0 }, 'so': { 'value': chance_data_vr['strikeout'], 'string': 'strikeout', # 'sm-string': 'so', 'bold': False, 'actual': 0, }, 'fo-slap': { 'value': chance_data_vr['fo_slap'], 'string': f'fly (rf) B', 'sm-string': f'fly (rf) B', 'bold': False, 'actual': 0 }, 'fo-cf': { 'value': chance_data_vr['fo_center'], 'string': f'fly (cf) B', 'bold': False, 'actual': 0 }, 'gb-a': { 'value': chance_data_vr['groundout_a'], 'string': f'gb (ss) A', 'bold': False, 'actual': 0 }, 'gb-c': { 'value': chance_data_vr['groundout_b'], 'string': f'gb (1b) C', 'bold': False, 'actual': 0 }, 'gb-x-p': { 'value': chance_data_vr['xcheck_p'], 'string': 'GB (p) X', 'bold': False, 'actual': 0 }, 'gb-x-c': { 'value': chance_data_vr['xcheck_c'], 'string': 'CATCH-X', 'bold': False, 'actual': 0 }, 'gb-x-1b': { 'value': chance_data_vr['xcheck_1b'], 'string': 'GB (1b) X', 'bold': False, 'actual': 0 }, 'gb-x-2b': { 'value': chance_data_vr['xcheck_2b'], 'string': 'GB (2b) X', 'bold': False, 'actual': 0 }, 'gb-x-3b': { 'value': chance_data_vr['xcheck_3b'], 'string': 'GB (3b) X', 'bold': False, 'actual': 0 }, 'gb-x-ss': { 'value': chance_data_vr['xcheck_ss'], 'string': 'GB (ss) X', 'bold': False, 'actual': 0 }, 'gb-x-lf': { 'value': chance_data_vr['xcheck_lf'], 'string': 'FLY (lf) X', 'bold': False, 'actual': 0 }, 'gb-x-cf': { 'value': chance_data_vr['xcheck_cf'], 'string': 'FLY (cf) X', 'bold': False, 'actual': 0 }, 'gb-x-rf': { 'value': chance_data_vr['xcheck_rf'], 'string': 'FLY (rf) X', 'bold': False, 'actual': 0 }, 'fatigue': 0 } } results = copy.deepcopy(BLANK_RESULTS) def column_output(): card_output = {} for hand in ['vL', 'vR']: for col in ['1', '2', '3']: card_output[f'{hand.lower()}_{get_col(col)}_2d6'] = '' card_output[f'{hand.lower()}_{get_col(col)}_results'] = '' card_output[f'{hand.lower()}_{get_col(col)}_splits'] = '' for hand in ['vL', 'vR']: for col in ['1', '2', '3']: int_results = {} for x in results[hand][col]: try: int_results[int(x)] = results[hand][col][x] except ValueError as e: if testing: print(f'skipping {x} in column_output') if testing: print(f'{int_results}') sorted_results = { row_num: int_results[row_num] for row_num in sorted(int_results.keys()) } for line in sorted_results: if testing: print(f'\nsorted_results: {sorted_results}\nline: {line}') if sorted_results[line]["result"]: card_output[f'{hand.lower()}_{get_col(col)}_2d6'] += \ f'{results[hand][col][str(line)]["2d6"]}\n' card_output[f'{hand.lower()}_{get_col(col)}_results'] += \ f'{results[hand][col][str(line)]["result"]}\n' card_output[f'{hand.lower()}_{get_col(col)}_splits'] += \ f'{results[hand][col][str(line)]["splits"]}\n' return card_output def add_full_result(vs_hand, tba_data, is_good, chances, plus_fatigue=False): all_cols = [] good_col = player.offense_col if is_good: if good_col == 1: second = random.choice([2, 3]) all_cols = [1, second, 3 if second == 2 else 2] elif good_col == 2: second = random.choice([1, 3]) all_cols = [2, second, 3 if second == 1 else 1] elif good_col == 3: second = random.choice([1, 2]) all_cols = [3, second, 1 if second == 1 else 2] else: if good_col == 1: f_col = random.choice([2, 3]) all_cols = [f_col, 3 if f_col == 2 else 2, 1] elif good_col == 2: f_col = random.choice([1, 3]) all_cols = [f_col, 3 if f_col == 1 else 1, 2] elif good_col == 3: f_col = random.choice([1, 2]) all_cols = [f_col, 1 if f_col == 1 else 2, 3] if chances == 6: for column in all_cols: if not results[vs_hand][f'{column}']['7']['result']: results[vs_hand][f'{column}']['7'] = result_data(tba_data, 7, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['6']['result'] and not \ results[vs_hand][f'{column}']['2']['result']: results[vs_hand][f'{column}']['6'] = result_data(tba_data, 6, fatigue=plus_fatigue) results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['8']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['8'] = result_data(tba_data, 8, fatigue=plus_fatigue) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['6']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['6'] = result_data(tba_data, 6, fatigue=plus_fatigue) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['8']['result'] and not \ results[vs_hand][f'{column}']['2']['result']: results[vs_hand][f'{column}']['8'] = result_data(tba_data, 8, fatigue=plus_fatigue) results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) return chances # No matches return 0 elif chances == 5: for column in all_cols: if not results[vs_hand][f'{column}']['6']['result']: results[vs_hand][f'{column}']['6'] = result_data(tba_data, 6, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['8']['result']: results[vs_hand][f'{column}']['8'] = result_data(tba_data, 8, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['3']['result'] and not \ results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3, fatigue=plus_fatigue) results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['3']['result'] and not \ results[vs_hand][f'{column}']['10']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3, fatigue=plus_fatigue) results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['4']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4, fatigue=plus_fatigue) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['10']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10, fatigue=plus_fatigue) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11, fatigue=plus_fatigue) return chances # No matches return 0 elif chances == 4: for column in all_cols: if not results[vs_hand][f'{column}']['5']['result']: results[vs_hand][f'{column}']['5'] = result_data(tba_data, 5, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['9']['result']: results[vs_hand][f'{column}']['9'] = result_data(tba_data, 9, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['3']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3, fatigue=plus_fatigue) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['10']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10, fatigue=plus_fatigue) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['10']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['10']['result'] and not \ results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10, fatigue=plus_fatigue) results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4, fatigue=plus_fatigue) return chances return 0 elif chances == 3: for column in all_cols: if not results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['10']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['3']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['12']['result'] and not \ results[vs_hand][f'{column}']['3']['result']: results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12, fatigue=plus_fatigue) results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['12']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12, fatigue=plus_fatigue) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11, fatigue=plus_fatigue) return chances return 0 elif chances == 2: for column in all_cols: if not results[vs_hand][f'{column}']['3']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12, fatigue=plus_fatigue) return chances return 0 elif chances == 1: for column in all_cols: if not results[vs_hand][f'{column}']['2']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2, fatigue=plus_fatigue) return chances if not results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12, fatigue=plus_fatigue) return chances return 0 def add_split_result(vs_hand, tba_data_top, tba_data_bottom, chances_top, is_good=None): all_cols = [] good_col = player.offense_col if is_good is None: if good_col == 1: f_col = random.choice([2, 3]) all_cols = [f_col, 1, 3 if f_col == 2 else 2] elif good_col == 2: f_col = random.choice([1, 3]) all_cols = [f_col, 2, 3 if f_col == 1 else 1] elif good_col == 3: f_col = random.choice([1, 2]) all_cols = [f_col, 3, 1 if f_col == 1 else 2] elif is_good: if good_col == 1: second = random.choice([2, 3]) all_cols = [1, second, 3 if second == 2 else 2] elif good_col == 2: second = random.choice([1, 3]) all_cols = [2, second, 3 if second == 1 else 1] elif good_col == 3: second = random.choice([1, 2]) all_cols = [3, second, 1 if second == 1 else 2] else: if good_col == 1: f_col = random.choice([2, 3]) all_cols = [f_col, 3 if f_col == 2 else 2, 1] elif good_col == 2: f_col = random.choice([1, 3]) all_cols = [f_col, 3 if f_col == 1 else 1, 2] elif good_col == 3: f_col = random.choice([1, 2]) all_cols = [f_col, 1 if f_col == 1 else 2, 3] legal_2d6 = legal_splits(chances_top) for column in all_cols: if results[vs_hand][f'{column}']['splits'] < 3: for y in legal_2d6: if tba_data_bottom['value'] >= y['bad_chances'] and not \ results[vs_hand][f'{column}'][f'{y["2d6"]}']['result']: results[vs_hand][f'{column}'][f'{y["2d6"]}'] = \ result_data(tba_data_top, y["2d6"], tba_data_bottom, y["incs"]) results[vs_hand][f'{column}']['splits'] += 1 return y['bad_chances'] if testing: print(f'Legal 2d6: {legal_2d6}') if testing: print(f'Could not find a legal spot for:\n{tba_data_top}\n{tba_data_bottom}') return None def assign_chances( res_key: str, vs_hand: str, remainder_keys: list[str], allow_retry: bool, rollover_key: str, is_good: bool, force_whole: bool = False): retries = 0 if allow_retry else 1 if testing: print(f'starting {res_key}: {tba[vs_hand][res_key]["value"]}') # If not even int, add_split_result with less than half of total chances total_chances = mround(tba[vs_hand][res_key]['value']) # chance_remainder = mround(total_chances - math.floor(total_chances)) # If total chance is a whole number, do easy assignments first if int(total_chances) - total_chances == 0 or force_whole or tba[vs_hand][res_key]['value'] > 2: if testing: print(f'{tba[vs_hand][res_key]["value"]} {res_key}s being placed') if (res_key == 'so' or res_key == 'gb-a' or res_key == 'gb-c' or 'fo' in res_key) and \ tba[vs_hand]['fatigue'] < 10: num_added = add_full_result( vs_hand, tba[vs_hand][res_key], is_good, min(math.floor(tba[vs_hand][res_key]['value']), min(6, 10 - tba[vs_hand]['fatigue'])), plus_fatigue=True ) tba[vs_hand]['fatigue'] += num_added if num_added else 0 elif tba[vs_hand][res_key]['value'] > 9.5: num_added = add_full_result(vs_hand, tba[vs_hand][res_key], is_good, 6) elif tba[vs_hand][res_key]['value'] > 7.5: num_added = add_full_result(vs_hand, tba[vs_hand][res_key], is_good, 5) elif res_key == 'bp-si' and tba[vs_hand]['bp-si']['value'] > 4.5: num_added = add_full_result(vs_hand, tba[vs_hand][res_key], is_good, random.randint(3, 5)) elif tba[vs_hand][res_key]['value'] > 5.5: num_added = add_full_result(vs_hand, tba[vs_hand][res_key], is_good, 4) else: num_added = add_full_result( vs_hand, tba[vs_hand][res_key], is_good, int(tba[vs_hand][res_key]['value']) ) if not num_added and int(tba[vs_hand][res_key]['value']) > 1: num_added = add_full_result( vs_hand, tba[vs_hand][res_key], is_good, int(tba[vs_hand][res_key]['value'] - 1) ) if not num_added and int(tba[vs_hand][res_key]['value']) > 2: num_added = add_full_result( vs_hand, tba[vs_hand][res_key], is_good, int(tba[vs_hand][res_key]['value'] - 2) ) if not num_added and int(tba[vs_hand][res_key]['value']) > 3: num_added = add_full_result( vs_hand, tba[vs_hand][res_key], is_good, int(tba[vs_hand][res_key]['value'] - 3) ) if not num_added and int(tba[vs_hand][res_key]['value']) > 4: num_added = add_full_result( vs_hand, tba[vs_hand][res_key], is_good, int(tba[vs_hand][res_key]['value'] - 4) ) if num_added: tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - num_added) tba[vs_hand][res_key]['actual'] = mround(tba[vs_hand][res_key]['actual'] + num_added) return elif retries == 0: if testing: print(f'retry # {retries} for {res_key} for {player.name} {vs_hand}') return else: if tba[vs_hand][rollover_key]['value'] >= 1: t_value = 1 else: t_value = .05 if testing: print(f'Transferring {t_value} {res_key} to {rollover_key}') tba[vs_hand][rollover_key]['value'] = mround( tba[vs_hand][rollover_key]['value'] + t_value) tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - t_value) return # Else start dicing up the chances else: # if retries == 0 and total_chances > 3: # chance_remainder = mround( # math.ceil(total_chances / 2) - (total_chances - math.floor(total_chances)) # ) # else: # chance_remainder = mround(total_chances - math.floor(total_chances)) chance_remainder = mround(total_chances - math.floor(total_chances)) if testing: print(f'chance_remainder: {chance_remainder}') # if mround(chance_remainder) != 0 and mround(chance_remainder) > .5: # TO ROLL BACK, UNDO ABOVE COMMEND AND TAB ALL BELOW CODE IN ONCE top_chances = None bottom_key = None bottom_result = None """ If this result cannot take any splits (but has extra results pass the remainder to the rollover and come back to assign_chances with a whole number """ if len(remainder_keys) == 0: # print(f'in the remainder_keys check for {res_key} / rounding down from ' # f'{tba[vs_hand][res_key]["value"]} to ' # f'{mround(math.floor(tba[vs_hand][res_key]["value"]))}') tba[vs_hand][res_key]['value'] = mround(math.floor(tba[vs_hand][res_key]['value'])) # print(f'confirming end val: {tba[vs_hand][res_key]["value"]}') tba[vs_hand][rollover_key]['value'] = mround( tba[vs_hand][rollover_key]['value'] + chance_remainder ) return for rem_key in remainder_keys: if mround(tba[vs_hand][rem_key]['value']) >= mround(1 - chance_remainder): bottom_key = rem_key bottom_result = tba[vs_hand][rem_key] break if not bottom_key: if tba[vs_hand][rollover_key]['value'] > 1: t_value = 1 else: t_value = .05 if testing: print(f'Transferring {t_value} {res_key} to {rollover_key}') tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - t_value) tba[vs_hand][rollover_key]['value'] = mround( tba[vs_hand][rollover_key]['value'] + t_value ) return # raise ValueError( # f'Could not find a second result for a {res_key} split for {player.name} {vHand}') bottom_chances = None if tba[vs_hand][res_key]['value'] > 4: top_chances = mround(3 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) elif tba[vs_hand][res_key]['value'] > 3: top_chances = mround(2 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) elif tba[vs_hand][res_key]['value'] > 2: top_chances = mround(1 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances: top_chances = mround(chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and tba[vs_hand][res_key]['value'] > 3: top_chances = mround(.5 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and tba[vs_hand][res_key]['value'] > 3: top_chances = mround(.7 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and chance_remainder > 0.15: top_chances = mround(chance_remainder - 0.15) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and chance_remainder > 0.05: top_chances = mround(chance_remainder - 0.05) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if testing: print(f'{res_key} chances: {mround(top_chances)} / split with {bottom_result}') if bottom_chances: tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - top_chances) tba[vs_hand][res_key]['actual'] = mround(tba[vs_hand][res_key]['actual'] + top_chances) tba[vs_hand][bottom_key]['value'] = mround( tba[vs_hand][bottom_key]['value'] - bottom_chances) tba[vs_hand][bottom_key]['actual'] = mround( tba[vs_hand][bottom_key]['actual'] + bottom_chances ) if testing: print( f'placed {top_chances} {res_key}s and {bottom_chances} {bottom_result["string"]}s for ' f'{player.name} {vs_hand}\n\n') return elif retries == 0: retries += 1 if testing: print(f'retry # {retries} for {res_key} for {player.name} {vs_hand}') return else: if tba[vs_hand][rollover_key]['value'] > 1: t_value = 1 else: t_value = .05 if testing: print(f'Transferring {t_value} {res_key} to {rollover_key}') tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - t_value) tba[vs_hand][rollover_key]['value'] = mround( tba[vs_hand][rollover_key]['value'] + t_value ) return def gap_filler(vs_hand, res_key: str): for col in ['1', '2', '3']: total_filler = 0 for b_row in ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']: # print(f'checking {col}-{b_row} {vs_hand} for a None: {results[vs_hand][col][b_row]["result"]}') if not results[vs_hand][col][b_row]['result']: chances = chances_from_row(b_row) total_filler += chances tba[vs_hand][res_key]['actual'] = mround( tba[vs_hand][res_key]['actual'] + chances ) results[vs_hand][col][b_row] = result_data(tba[vs_hand][res_key], b_row) if testing: print(f'total filler: {total_filler}') # Build vl results then vR for vHand in ['vL', 'vR']: # Refactored bp-hr retries = False while tba[vHand]['bp-hr']['value'] > 0: assign_chances( res_key='bp-hr', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='do-cf', is_good=True ) retries = False # Fatigue results retries = False while tba[vHand]['so']['value'] >= 1 and tba[vHand]['fatigue'] < 10: assign_chances( res_key='so', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False, force_whole=True ) if tba[vHand]['fatigue'] < 10 and tba[vHand]['gb-a']['value'] >= 1: assign_chances( res_key='gb-a', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False, force_whole=True ) if tba[vHand]['fatigue'] < 10 and tba[vHand]['gb-c']['value'] >= 1: assign_chances( res_key='gb-c', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False, force_whole=True ) if tba[vHand]['fatigue'] < 10 and tba[vHand]['fo-slap']['value'] >= 1: assign_chances( res_key='fo-slap', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'fo-cf', is_good=False ) if tba[vHand]['fatigue'] <= 10 and tba[vHand]['fo-cf']['value'] >= 1: assign_chances( res_key='fo-cf', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'gb-c', is_good=False ) # Refactored gb-x-p retries = False while tba[vHand]['gb-x-p']['value'] > 0: assign_chances( res_key='gb-x-p', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-c retries = False while tba[vHand]['gb-x-c']['value'] > 0: assign_chances( res_key='gb-x-c', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-1b retries = False while tba[vHand]['gb-x-1b']['value'] > 0: assign_chances( res_key='gb-x-1b', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-2b retries = False while tba[vHand]['gb-x-2b']['value'] > 0: assign_chances( res_key='gb-x-2b', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-3b retries = False while tba[vHand]['gb-x-3b']['value'] > 0: assign_chances( res_key='gb-x-3b', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-ss retries = False while tba[vHand]['gb-x-ss']['value'] > 0: assign_chances( res_key='gb-x-ss', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-lf retries = False while tba[vHand]['gb-x-lf']['value'] > 0: assign_chances( res_key='gb-x-lf', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-cf retries = False while tba[vHand]['gb-x-cf']['value'] > 0: assign_chances( res_key='gb-x-cf', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored gb-x-rf retries = False while tba[vHand]['gb-x-rf']['value'] > 0: assign_chances( res_key='gb-x-rf', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='', is_good=False ) retries = False # Refactored bp-si retries = True while tba[vHand]['bp-si']['value'] > 0: assign_chances( res_key='bp-si', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'si*', is_good=False ) retries = False # Refactored so retries = False while tba[vHand]['so']['value'] > 0: assign_chances( res_key='so', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='gb-c', is_good=False ) retries = False # Refactored hbp retries = False while tba[vHand]['hbp']['value'] > 0: assign_chances( res_key='hbp', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'bb', is_good=True ) retries = False # Refactored hr retries = True while tba[vHand]['hr']['value'] > 0: assign_chances( res_key='hr', vs_hand=vHand, remainder_keys=['tr', 'do-cf', 'fo-slap', 'fo-cf'], allow_retry=retries, rollover_key=f'do-cf', is_good=True ) retries = False # Refactored si-cf retries = False while tba[vHand]['si-cf']['value'] > 0: assign_chances( res_key='si-cf', vs_hand=vHand, remainder_keys=['gb-c', 'gb-a'], allow_retry=retries, rollover_key=f'si*', is_good=True ) retries = False # Refactored tr retries = False while tba[vHand]['tr']['value'] > 0: assign_chances( res_key='tr', vs_hand=vHand, remainder_keys=['do-cf', 'si**', 'fo-cf', 'fo-slap'], allow_retry=retries, rollover_key=f'do-cf', is_good=True ) retries = False # Refactored do*** retries = True while tba[vHand]['do***']['value'] > 0: assign_chances( res_key='do***', vs_hand=vHand, remainder_keys=['do-cf', 'si**', 'fo-cf', 'fo-slap'], allow_retry=retries, rollover_key=f'do-cf', is_good=True ) retries = False # Refactored do** retries = True while tba[vHand]['do**']['value'] > 0: assign_chances( res_key='do**', vs_hand=vHand, remainder_keys=['si**', 'fo-cf', 'fo-slap', 'gb-c'], allow_retry=retries, rollover_key=f'do-cf', is_good=True ) retries = False # Refactored do-cf retries = True while tba[vHand]['do-cf']['value'] > 0: assign_chances( res_key='do-cf', vs_hand=vHand, remainder_keys=[f'fo-slap', 'fo-cf', 'gb-c'], allow_retry=retries, rollover_key=f'si**', is_good=True ) retries = False # Refactored si** retries = True while tba[vHand]['si**']['value'] > 0: assign_chances( res_key='si**', vs_hand=vHand, remainder_keys=['gb-a', 'gb-c'], allow_retry=retries, rollover_key=f'si*', is_good=True ) retries = False # Refactored si* retries = True while tba[vHand]['si*']['value'] > 0: assign_chances( res_key='si*', vs_hand=vHand, remainder_keys=['gb-c', 'gb-a'], allow_retry=retries, rollover_key=f'bb', is_good=False ) retries = False # Refactored bb retries = False while tba[vHand]['bb']['value'] > 0: assign_chances( res_key='bb', vs_hand=vHand, remainder_keys=['so'], allow_retry=retries, rollover_key=f'gb-c', is_good=True ) retries = False # Refactored fo-slap retries = False while tba[vHand]['fo-slap']['value'] > 0: assign_chances( res_key='fo-slap', vs_hand=vHand, remainder_keys=['fo-cf'], allow_retry=retries, rollover_key=f'fo-cf', is_good=False ) retries = False # Refactored fo-cf retries = False while tba[vHand]['fo-cf']['value'] > 0: assign_chances( res_key='fo-cf', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'gb-c', is_good=False ) retries = False # Refactored gb-b retries = False while tba[vHand]['gb-c']['value'] > 0: assign_chances( res_key='gb-c', vs_hand=vHand, remainder_keys=['gb-a'], allow_retry=retries, rollover_key=f'gb-a', is_good=False ) retries = False # Refactored gb-a retries = False while tba[vHand]['gb-a']['value'] > 0: assign_chances( res_key='gb-a', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'so', is_good=False ) retries = False """ Whatever result is last should be run through the gap_filler() """ if testing: print(f'filling in gaps with gb-a') gap_filler(vHand, 'fo-cf') if testing: print(f'\n\n******\n\n{player.name} Results:\n{results}\n{tba}') else: print(f'Completed {player.name}') col_output = column_output() if testing: print(f'\n\ncol_output:\n{col_output}\n\n') # # Prep csv pitcher lines # logging.info(f'prepping pitcher lines') # card_columns.append( # [player.name, player.sba_id, bat_hand, # col_output['vl_one_2d6'], col_output['vl_one_results'], col_output['vl_one_splits'], # col_output['vl_two_2d6'], col_output['vl_two_results'], col_output['vl_two_splits'], # col_output['vl_three_2d6'], col_output['vl_three_results'], col_output['vl_three_splits'], # col_output['vr_one_2d6'], col_output['vr_one_results'], col_output['vr_one_splits'], # col_output['vr_two_2d6'], col_output['vr_two_results'], col_output['vr_two_splits'], # col_output['vr_three_2d6'], col_output['vr_three_results'], col_output['vr_three_splits']] # ) for hand in ['vL', 'vR']: logging.info(f'inserting pitcher ratings') p_ratings = { 'id': f'{player.sba_id}-{hand}-{cardset.id}', 'player': player, 'cardset': cardset, 'vs_hand': hand, 'is_prep': False, 'homerun': mround(tba[hand]['hr']['actual']), 'bp_homerun': mround(tba[hand]['bp-hr']['actual']), 'triple': mround(tba[hand]['tr']['actual']), 'double_three': mround(tba[hand]['do***']['actual']), 'double_two': mround(tba[hand]['do**']['actual']), 'double_cf': mround(tba[hand]['do-cf']['actual']), 'single_two': mround(tba[hand]['si**']['actual']), 'single_one': mround(tba[hand]['si*']['actual']), 'single_center': mround(tba[hand]['si-cf']['actual']), 'bp_single': mround(tba[hand]['bp-si']['actual']), 'hbp': mround(tba[hand]['hbp']['actual']), 'walk': mround(tba[hand]['bb']['actual']), 'strikeout': mround(tba[hand]['so']['actual']), 'fo_slap': mround(tba[hand]['fo-slap']['actual']), 'fo_center': mround(tba[hand]['fo-cf']['actual']), 'groundout_a': mround(tba[hand]['gb-a']['actual']), 'groundout_b': mround(tba[hand]['gb-c']['actual']), 'xcheck_p': mround(tba[hand]['gb-x-p']['actual']), 'xcheck_c': mround(tba[hand]['gb-x-c']['actual']), 'xcheck_1b': mround(tba[hand]['gb-x-1b']['actual']), 'xcheck_2b': mround(tba[hand]['gb-x-2b']['actual']), 'xcheck_3b': mround(tba[hand]['gb-x-3b']['actual']), 'xcheck_ss': mround(tba[hand]['gb-x-ss']['actual']), 'xcheck_lf': mround(tba[hand]['gb-x-lf']['actual']), 'xcheck_cf': mround(tba[hand]['gb-x-cf']['actual']), 'xcheck_rf': mround(tba[hand]['gb-x-rf']['actual']) } count_hits = ( p_ratings['homerun'] + p_ratings['bp_homerun'] / 2 + p_ratings['triple'] + p_ratings['double_three'] + p_ratings['double_two'] + p_ratings['double_cf'] + p_ratings['single_two'] + p_ratings['single_one'] + p_ratings['single_center'] + p_ratings['bp_single'] ) p_ratings['avg'] = count_hits / 108 p_ratings['obp'] = ( count_hits + p_ratings['hbp'] + p_ratings['walk'] + (p_ratings['xcheck_p'] + p_ratings['xcheck_c'] + p_ratings['xcheck_1b'] + p_ratings['xcheck_2b'] + p_ratings['xcheck_3b'] + p_ratings['xcheck_ss'] + p_ratings['xcheck_lf'] + p_ratings['xcheck_cf'] + p_ratings['xcheck_rf']) * .3 ) / 108 p_ratings['slg'] = ( ((p_ratings['homerun'] + p_ratings['bp_homerun']) * 4) + (p_ratings['triple'] * 3) + ((p_ratings['double_three'] + p_ratings['double_two'] + p_ratings['double_cf']) * 2) + p_ratings['single_two'] + p_ratings['single_one'] + p_ratings['single_center'] + p_ratings['bp_single'] / 2 ) / 108 PitcherRatings.insert(p_ratings).on_conflict_replace().execute() logging.info(f'inserting pitcher columns') this_columns = { 'id': f'{player.sba_id}-{hand}-{cardset.id}', 'player': player, 'hand': bat_hand, 'p_ratings_id': f'{player.sba_id}-{hand}-{cardset.id}', 'one_dice': col_output[f'{hand.lower()}_one_2d6'], 'one_results': col_output[f'{hand.lower()}_one_results'], 'one_splits': col_output[f'{hand.lower()}_one_splits'], 'two_dice': col_output[f'{hand.lower()}_two_2d6'], 'two_results': col_output[f'{hand.lower()}_two_results'], 'two_splits': col_output[f'{hand.lower()}_two_splits'], 'three_dice': col_output[f'{hand.lower()}_three_2d6'], 'three_results': col_output[f'{hand.lower()}_three_results'], 'three_splits': col_output[f'{hand.lower()}_three_splits'] } CardColumns.insert(this_columns).on_conflict_replace().execute() # # Prep csv ratings guide # logging.info(f'prepping pitcher ratings guide') # rg_line = [player.name, bat_hand] # for hand in ['vL', 'vR']: # for x in rg_headers: # if x not in ['name', 'hand']: # rg_line.append(mround(tba[hand][x]['actual'])) # ratings_guide.append(rg_line) logging.info(f'completed {player.name}') count_pitchers += 1 # No player match else: logging.error(f'Could not match fangraph player id {row[0]}') print(f'Could not match fangraph player id {row[0]}') except Exception as e: logging.error(f'Failed to process pitcher {row[0]} ({row[2]}): {type(e)}: {e}') print(f'Failed to process pitcher {row[0]} ({row[2]})') print(f'Processed {count_pitchers} pitcher stat lines into chances...') """ Export card output to csv for Component Studio """ # # Removed since output has own script now # try: # output_path.mkdir(parents=True) # except FileExistsError as e: # print(f'Directory {output_path} already exists') # write_to_csv(output_path, f'pitcher-ratings-guide-{now.strftime("%Y-%m-%d-%f")}', ratings_guide) # write_to_csv(output_path, f'pitcher-card-columns-{now.strftime("%Y-%m-%d-%f")}', card_columns) """ END OF PITCHERS """ lets_go = input(f'Should I run batters (y/n)? ') if lets_go in YES: # https://www.baseball-reference.com/leagues/majors/2022-baserunning-batting.shtml with open(f'{input_path}baserunning-data.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) for row in reader: try: player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[36]) if player: dupe = BatterData.delete().where( (BatterData.player == player) & (BatterData.cardset == cardset) ).execute() stealing = b.stealing( int(row[8]), int(row[12]), int(row[13]), int(row[14]), int(row[15]), season_pct ) this_data = BatterData( player=player, cardset=cardset, stealing=b.stealing_line(stealing), st_low=stealing[0], st_high=stealing[1], st_auto=stealing[2], st_jump=stealing[3], running=b.running(row[26]), hit_and_run='C', bunting='C' ) this_data.save() else: logging.error(f'Could not match bbref id {row[36]}') print(f'Could not match bbref id {row[36]}') except Exception as e: logging.error(f'Failed to process runner {row[0]} ({row[2]}): {type(e)}: {e}') print(f'Failed to process runner {row[0]} ({row[2]})') existing_columns = CardColumns.delete().where( CardColumns.id.endswith(f'-{cardset.id}') & CardColumns.b_ratings.is_null(False) ).execute() existing_batters = BatterRatings.delete().where(BatterRatings.cardset == cardset).execute() # rg_headers = ['name', 'hand', 'hr', 'bp-hr', 'tr', 'do***', 'do**', 'do-pull', 'si**', 'si*', 'si-cf', 'bp-si', # 'hbp', 'bb', 'so', 'lo', 'po', 'fo-a', 'fo-bq', 'fo-lf-b', 'fo-rf-b', 'gb-a', 'gb-b', 'gb-c'] # ratings_guide = [[ # 'name', 'hand', 'hr-vL', 'bp-hr-vL', 'tr-vL', 'do***-vL', 'do**-vL', 'do-pull-vL', 'si**-vL', 'si*-vL', # 'si-cf-vL', 'bp-si-vL', 'hbp-vL', 'bb-vL', 'so-vL', 'lo-vL', 'po-vL', 'fo-a-vL', 'fo-bq-vL', 'fo-lf-b-vL', # 'fo-rf-b-vL', 'gb-a-vL', 'gb-b-vL', 'gb-c-vL', 'hr-vR', 'bp-hr-vR', 'tr-vR', 'do***-vR', 'do**-vR', # 'do-pull-vR', 'si**-vR', 'si*-vR', 'si-cf-vR', 'bp-si-vR', 'hbp-vR', 'bb-vR', 'so-vR', 'lo-vR', 'po-vR', # 'fo-a-vR', 'fo-bq-vR', 'fo-lf-b-vR', 'fo-rf-b-vR', 'gb-a-vR', 'gb-b-vR', 'gb-c-vR' # ]] # all_results = [['name', 'sba_id', 'hand', 'vl_one_2d6', 'vl_one_results', 'vl_one_splits', # 'vl_two_2d6', 'vl_two_results', 'vl_two_splits', # 'vl_three_2d6', 'vl_three_results', 'vl_three_splits', # 'vr_one_2d6', 'vr_one_results', 'vr_one_splits', # 'vr_two_2d6', 'vr_two_results', 'vr_two_splits', # 'vr_three_2d6', 'vr_three_results', 'vr_three_splits']] with open(f'{input_path}batter-stats.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) for row in reader: player = ScoutPlayer.get_or_none(ScoutPlayer.fg_id == int(row[0])) # Standard limits # if player and (('Promo' in cardset.set_title) or ('Major League' in cardset.set_title) or # (int(row[5]) >= 28 and int(row[39]) >= 58)): if player is not None: chance_data_vl = { 'id': f'{player.sba_id}-vL-{cardset.id}-bat', 'player_id': player.sba_id, 'cardset_id': cardset.id, 'vs_hand': 'vL', 'is_prep': True, 'homerun': 0, 'bp_homerun': 0, 'triple': 0, 'double_three': 0, 'double_two': 0, 'double_pull': 0, 'single_two': 0, 'single_one': 0, 'single_center': 0, 'bp_single': 0, 'hbp': 0, 'walk': 0, 'strikeout': 0, 'lineout': 0, 'popout': 0, 'flyout_a': 0, 'flyout_bq': 0, 'flyout_lf_b': 0, 'flyout_rf_b': 0, 'groundout_a': 0, 'groundout_b': 0, 'groundout_c': 0, } chance_data_vr = { 'id': f'{player.sba_id}-vR-{cardset.id}-bat', 'player_id': player.sba_id, 'cardset_id': cardset.id, 'vs_hand': 'vR', 'is_prep': True, 'homerun': 0, 'bp_homerun': 0, 'triple': 0, 'double_three': 0, 'double_two': 0, 'double_pull': 0, 'single_two': 0, 'single_one': 0, 'single_center': 0, 'bp_single': 0, 'hbp': 0, 'walk': 0, 'strikeout': 0, 'lineout': 0, 'popout': 0, 'flyout_a': 0, 'flyout_bq': 0, 'flyout_lf_b': 0, 'flyout_rf_b': 0, 'groundout_a': 0, 'groundout_b': 0, 'groundout_c': 0, } bat_hand = player.hand # Turn sheets workflow into code here offense_mod = 1.2 all_hits_vl = mround(108 * offense_mod * float(row[23])) all_hits_vr = mround(108 * offense_mod * float(row[57])) hard_rate_vl = float(row[38]) hard_rate_vr = float(row[72]) med_rate_vl = float(row[37]) med_rate_vr = float(row[71]) soft_rate_vl = float(row[36]) soft_rate_vr = float(row[70]) if int(row[7]) == 0: all_singles_vl = 0.0 else: all_singles_vl = mround(all_hits_vl * (float(row[8]) / float(row[7]))) if int(row[41]) == 0: all_singles_vr = 0.0 else: all_singles_vr = mround(all_hits_vr * (float(row[42]) / float(row[41]))) chance_data_vl['bp_single'] = b.bp_singles(all_singles_vl) chance_data_vr['bp_single'] = b.bp_singles(all_singles_vr) chance_data_vl['single_two'] = b.wh_singles( mround(all_singles_vl - chance_data_vl['bp_single']), hard_rate_vl ) chance_data_vr['single_two'] = b.wh_singles( mround(all_singles_vr - chance_data_vr['bp_single']), hard_rate_vr ) chance_data_vl['single_one'] = b.one_singles( mround(all_singles_vl - chance_data_vl['bp_single'] - chance_data_vl['single_two']), ifh_rate=float(row[31]), force_rem=True if chance_data_vl['single_two'] == 0 else False ) chance_data_vr['single_one'] = b.one_singles( mround(all_singles_vr - chance_data_vr['bp_single'] - chance_data_vr['single_two']), ifh_rate=float(row[65]), force_rem=True if chance_data_vr['single_two'] == 0 else False ) chance_data_vl['single_center'] = mround( all_singles_vl - chance_data_vl['bp_single'] - chance_data_vl['single_two'] - chance_data_vl['single_one'] ) chance_data_vr['single_center'] = mround( all_singles_vr - chance_data_vr['bp_single'] - chance_data_vr['single_two'] - chance_data_vr['single_one'] ) total_singles_vl = ( chance_data_vl['bp_single'] + chance_data_vl['single_two'] + chance_data_vl['single_one'] + chance_data_vl['single_center'] ) total_singles_vr = ( chance_data_vr['bp_single'] + chance_data_vr['single_two'] + chance_data_vr['single_one'] + chance_data_vr['single_center'] ) rem_hits_vl = all_hits_vl - total_singles_vl rem_hits_vr = all_hits_vr - total_singles_vr all_hr_vl = b.all_homeruns(rem_hits_vl, all_hits_vl, float(row[11]), float(row[7]), float(row[8])) all_hr_vr = b.all_homeruns( rem_hits_vr, all_hits_vr, float(row[45]), float(row[41]), float(row[42]) ) chance_data_vl['homerun'] = b.nd_homeruns(all_hr_vl, float(row[30])) chance_data_vr['homerun'] = b.nd_homeruns(all_hr_vr, float(row[64])) chance_data_vl['bp_homerun'] = mround(all_hr_vl - chance_data_vl['homerun'], base=1) chance_data_vr['bp_homerun'] = mround(all_hr_vr - chance_data_vr['homerun'], base=1) chance_data_vl['homerun'] += (all_hr_vl - chance_data_vl['homerun'] - chance_data_vl['bp_homerun']) chance_data_vr['homerun'] += (all_hr_vr - chance_data_vr['homerun'] - chance_data_vr['bp_homerun']) total_hr_vl = mround(chance_data_vl['homerun'] + chance_data_vl['bp_homerun']) total_hr_vr = mround(chance_data_vr['homerun'] + chance_data_vr['bp_homerun']) all_xbh_vl = mround(all_hits_vl - total_singles_vl - total_hr_vl) all_xbh_vr = mround(all_hits_vr - total_singles_vr - total_hr_vr) chance_data_vl['triple'] = b.triples( all_xbh_vl, float(row[10]), float(row[9]) ) chance_data_vr['triple'] = b.triples( all_xbh_vr, float(row[44]), float(row[43]) ) all_doubles_vl = mround(all_xbh_vl - chance_data_vl['triple']) all_doubles_vr = mround(all_xbh_vr - chance_data_vr['triple']) chance_data_vl['double_two'] = b.two_doubles(all_doubles_vl, soft_rate_vl) chance_data_vr['double_two'] = b.two_doubles(all_doubles_vr, soft_rate_vr) chance_data_vl['double_pull'] = mround(all_doubles_vl - chance_data_vl['double_two']) chance_data_vr['double_pull'] = mround(all_doubles_vr - chance_data_vr['double_two']) total_doubles_vl = mround(chance_data_vl['double_two'] + chance_data_vl['double_pull']) total_doubles_vr = mround(chance_data_vr['double_two'] + chance_data_vr['double_pull']) other_ob_vl = mround(108 * offense_mod * ((float(row[14]) + float(row[17])) / float(row[5]))) other_ob_vr = mround(108 * offense_mod * ((float(row[48]) + float(row[51])) / float(row[39]))) chance_data_vl['hbp'] = b.hit_by_pitch(other_ob_vl, float(row[17]), float(row[14])) chance_data_vr['hbp'] = b.hit_by_pitch(other_ob_vr, float(row[51]), float(row[48])) chance_data_vl['walk'] = mround(other_ob_vl - chance_data_vl['hbp']) chance_data_vr['walk'] = mround(other_ob_vr - chance_data_vr['hbp']) all_outs_vl = mround(108 - all_hits_vl - other_ob_vl) all_outs_vr = mround(108 - all_hits_vr - other_ob_vr) chance_data_vl['strikeout'] = b.strikeouts(all_outs_vl, float(row[16]) / float(row[5])) chance_data_vr['strikeout'] = b.strikeouts(all_outs_vr, float(row[50]) / float(row[39])) rem_outs_vl = mround(all_outs_vl - chance_data_vl['strikeout']) rem_outs_vr = mround(all_outs_vr - chance_data_vr['strikeout']) lineouts_vl = max(mround(rem_outs_vl * float(row[26])), 1) lineouts_vr = max(mround(rem_outs_vr * float(row[60])), 1) chance_data_vl['popout'] = b.popouts(lineouts_vl - 1, float(row[29])) chance_data_vr['popout'] = b.popouts(lineouts_vr - 1, float(row[63])) chance_data_vl['lineout'] = mround(lineouts_vl - chance_data_vl['popout']) chance_data_vr['lineout'] = mround(lineouts_vr - chance_data_vr['popout']) rem_outs_vl = mround(rem_outs_vl - chance_data_vl['lineout'] - chance_data_vl['popout']) rem_outs_vr = mround(rem_outs_vr - chance_data_vr['lineout'] - chance_data_vr['popout']) flyouts_vl = mround(rem_outs_vl * float(row[28])) flyouts_vr = mround(rem_outs_vr * float(row[62])) chance_data_vl['flyout_a'] = b.flyout_a(flyouts_vl, hard_rate_vl) chance_data_vr['flyout_a'] = b.flyout_a(flyouts_vr, hard_rate_vr) rem_flyouts_vl = mround(flyouts_vl - chance_data_vl['flyout_a']) rem_flyouts_vr = mround(flyouts_vr - chance_data_vr['flyout_a']) chance_data_vl['flyout_bq'] = b.flyout_bq(rem_flyouts_vl, soft_rate_vl) chance_data_vr['flyout_bq'] = b.flyout_bq(rem_flyouts_vr, soft_rate_vr) rem_flyouts_vl = mround(flyouts_vl - chance_data_vl['flyout_bq']) rem_flyouts_vr = mround(flyouts_vr - chance_data_vr['flyout_bq']) chance_data_vl['flyout_lf_b'] = b.flyout_b( rem_flyouts_vl, float(row[33]) if bat_hand.lower() == 'r' else float(row[35]), float(row[34]) ) chance_data_vr['flyout_lf_b'] = b.flyout_b( rem_flyouts_vr, float(row[67]) if bat_hand.lower() == 'r' else float(row[69]), float(row[68]) ) chance_data_vl['flyout_rf_b'] = mround(rem_flyouts_vl - chance_data_vl['flyout_lf_b']) chance_data_vr['flyout_rf_b'] = mround(rem_flyouts_vr - chance_data_vr['flyout_lf_b']) rem_outs_vl = mround(rem_outs_vl - flyouts_vl) rem_outs_vr = mround(rem_outs_vr - flyouts_vr) groundouts_vl = mround(rem_outs_vl) groundouts_vr = mround(rem_outs_vr) chance_data_vl['groundout_a'] = b.groundball_a(groundouts_vl, float(row[20]), float(row[6])) chance_data_vr['groundout_a'] = b.groundball_a(groundouts_vr, float(row[54]), float(row[40])) chance_data_vl['groundout_c'] = b.groundball_c( groundouts_vl - chance_data_vl['groundout_a'], med_rate_vl ) chance_data_vr['groundout_c'] = b.groundball_c( groundouts_vr - chance_data_vr['groundout_a'], med_rate_vr ) chance_data_vl['groundout_b'] = mround( groundouts_vl - chance_data_vl['groundout_a'] - chance_data_vl['groundout_c'] ) chance_data_vr['groundout_b'] = mround( groundouts_vr - chance_data_vr['groundout_a'] - chance_data_vr['groundout_c'] ) if testing: print(f'vL: {chance_data_vl}\nvR: {chance_data_vr}') print(f'total chances vL: {b.total_chances(chance_data_vl)} / ' f'vR: {b.total_chances(chance_data_vr)}') BatterRatings.insert(chance_data_vl).on_conflict_replace().execute() BatterRatings.insert(chance_data_vr).on_conflict_replace().execute() b_data = BatterData.select().where( (BatterData.player == player) & (BatterData.cardset == cardset) ).limit(1) if b_data.count() == 1: babip = (all_hits_vl + all_hits_vr - all_hr_vl - all_hr_vr) / \ (216 - chance_data_vl['strikeout'] - chance_data_vr['strikeout'] + chance_data_vl['flyout_lf_b'] + chance_data_vr['flyout_lf_b'] - all_hr_vl - all_hr_vr) if babip >= .35: hnr = 'A' elif babip >= .3: hnr = 'B' elif babip >= .225: hnr = 'C' else: hnr = 'D' b_data[0].hit_and_run = hnr b_data[0].save() else: print(f'No BatterData for {player.name}') """ Process batter chances into card output """ bat_hand = player.hand tba = { 'vL': { 'bp-si': { 'value': chance_data_vl['bp_single'], 'string': '▼BP-SI', 'bold': True, 'actual': 0 }, 'si-cf': { 'value': chance_data_vl['single_center'], 'string': 'SINGLE (cf)', 'sm-string': 'SI (cf)', 'bold': True, 'actual': 0 }, 'si*': { 'value': chance_data_vl['single_one'], 'string': 'SINGLE*', 'sm-string': 'SI*', 'bold': True, 'actual': 0 }, 'si**': { 'value': chance_data_vl['single_two'], 'string': 'SINGLE**', 'sm-string': 'SI**', 'bold': True, 'actual': 0 }, 'bp-hr': { 'value': chance_data_vl['bp_homerun'], 'string': '◆BP-HR', 'bold': True, 'actual': 0 }, 'hr': { 'value': chance_data_vl['homerun'], 'string': 'HOMERUN', 'sm-string': 'HR', 'bold': True, 'actual': 0 }, 'tr': { 'value': chance_data_vl['triple'], 'string': 'TRIPLE', 'sm-string': 'TR', 'bold': True, 'actual': 0 }, 'do**': { 'value': chance_data_vl['double_two'], 'string': 'DOUBLE**', 'sm-string': 'DO**', 'bold': True, 'actual': 0 }, 'do***': { 'value': chance_data_vl['double_three'], 'string': 'DOUBLE***', 'sm-string': 'DO***', 'bold': True, 'actual': 0 }, 'do-pull': { 'value': chance_data_vl['double_pull'], 'string': f'DOUBLE ({"rf" if bat_hand == "L" else "lf"})', 'sm-string': f'DO ({"rf" if bat_hand == "L" else "lf"})', 'bold': True, 'actual': 0 }, 'hbp': { 'value': chance_data_vl['hbp'], 'string': 'HBP', 'bold': True, 'actual': 0 }, 'bb': { 'value': chance_data_vl['walk'], 'string': 'WALK', 'bold': True, 'actual': 0 }, 'so': { 'value': chance_data_vl['strikeout'], 'string': 'strikeout', 'bold': False, 'actual': 0 }, 'lo': { 'value': chance_data_vl['lineout'], 'string': f'lineout ({"ss" if bat_hand == "L" else "2b"})', 'sm-string': f'lo ({"ss" if bat_hand == "L" else "2b"})', 'bold': False, 'actual': 0 }, 'po': { 'value': chance_data_vl['popout'], 'string': f'popout ({"2b" if bat_hand == "L" else "ss"})', 'bold': False, 'actual': 0 }, 'fo-a': { 'value': chance_data_vl['flyout_a'], 'string': f'fly (cf) A', 'bold': False, 'actual': 0 }, 'fo-bq': { 'value': chance_data_vl['flyout_bq'], 'string': f'fly (cf) B?', 'bold': False, 'actual': 0 }, 'fo-lf-b': { 'value': chance_data_vl['flyout_lf_b'], 'string': f'fly (lf) B', 'bold': False, 'actual': 0 }, 'fo-rf-b': { 'value': chance_data_vl['flyout_rf_b'], 'string': f'fly (rf) B', 'bold': False, 'actual': 0 }, 'gb-a': { 'value': chance_data_vl['groundout_a'], 'string': f'gb ({"2b" if bat_hand == "L" else "ss"}) A', 'bold': False, 'actual': 0 }, 'gb-b': { 'value': chance_data_vl['groundout_b'], 'string': f'gb ({"ss" if bat_hand == "L" else "2b"}) B', 'bold': False, 'actual': 0 }, 'gb-c': { 'value': chance_data_vl['groundout_c'], 'string': f'gb ({"3b" if bat_hand == "L" else "1b"}) C', 'bold': False, 'actual': 0 } }, 'vR': { 'bp-si': { 'value': chance_data_vr['bp_single'], 'string': '▼BP-SI', 'bold': True, 'actual': 0 }, 'si-cf': { 'value': chance_data_vr['single_center'], 'string': 'SINGLE (cf)', 'sm-string': 'SI (cf)', 'bold': True, 'actual': 0 }, 'si*': { 'value': chance_data_vr['single_one'], 'string': 'SINGLE*', 'sm-string': 'SI*', 'bold': True, 'actual': 0 }, 'si**': { 'value': chance_data_vr['single_two'], 'string': 'SINGLE**', 'sm-string': 'SI**', 'bold': True, 'actual': 0 }, 'bp-hr': { 'value': chance_data_vr['bp_homerun'], 'string': '◆BP-HR', 'bold': True, 'actual': 0 }, 'hr': { 'value': chance_data_vr['homerun'], 'string': 'HOMERUN', 'sm-string': 'HR', 'bold': True, 'actual': 0 }, 'tr': { 'value': chance_data_vr['triple'], 'string': 'TRIPLE', 'sm-string': 'TR', 'bold': True, 'actual': 0 }, 'do**': { 'value': chance_data_vr['double_two'], 'string': 'DOUBLE**', 'sm-string': 'DO**', 'bold': True, 'actual': 0 }, 'do***': { 'value': chance_data_vr['double_three'], 'string': 'DOUBLE***', 'sm-string': 'DO***', 'bold': True, 'actual': 0 }, 'do-pull': { 'value': chance_data_vr['double_pull'], 'string': f'DOUBLE ({"rf" if bat_hand == "L" else "lf"})', 'sm-string': f'DO ({"rf" if bat_hand == "L" else "lf"})', 'bold': True, 'actual': 0 }, 'hbp': { 'value': chance_data_vr['hbp'], 'string': 'HBP', 'bold': True, 'actual': 0 }, 'bb': { 'value': chance_data_vr['walk'], 'string': 'WALK', 'bold': True, 'actual': 0 }, 'so': { 'value': chance_data_vr['strikeout'], 'string': 'strikeout', 'bold': False, 'actual': 0 }, 'lo': { 'value': chance_data_vr['lineout'], 'string': f'lineout ({"ss" if bat_hand == "L" else "2b"})', 'sm-string': f'lo ({"ss" if bat_hand == "L" else "2b"})', 'bold': False, 'actual': 0 }, 'po': { 'value': chance_data_vr['popout'], 'string': f'popout ({"2b" if bat_hand == "L" else "ss"})', 'bold': False, 'actual': 0 }, 'fo-a': { 'value': chance_data_vr['flyout_a'], 'string': f'fly (cf) A', 'bold': False, 'actual': 0 }, 'fo-bq': { 'value': chance_data_vr['flyout_bq'], 'string': f'fly (cf) B?', 'bold': False, 'actual': 0 }, 'fo-lf-b': { 'value': chance_data_vr['flyout_lf_b'], 'string': f'fly (lf) B', 'bold': False, 'actual': 0 }, 'fo-rf-b': { 'value': chance_data_vr['flyout_rf_b'], 'string': f'fly (rf) B', 'bold': False, 'actual': 0 }, 'gb-a': { 'value': chance_data_vr['groundout_a'], 'string': f'gb ({"2b" if bat_hand == "L" else "ss"}) A', 'bold': False, 'actual': 0 }, 'gb-b': { 'value': chance_data_vr['groundout_b'], 'string': f'gb ({"ss" if bat_hand == "L" else "2b"}) B', 'bold': False, 'actual': 0 }, 'gb-c': { 'value': chance_data_vr['groundout_c'], 'string': f'gb ({"3b" if bat_hand == "L" else "1b"}) C', 'bold': False, 'actual': 0 } } } results = copy.deepcopy(BLANK_RESULTS) def column_output(): card_output = {} for hand in ['vL', 'vR']: for col in ['1', '2', '3']: card_output[f'{hand.lower()}_{get_col(col)}_2d6'] = '' card_output[f'{hand.lower()}_{get_col(col)}_results'] = '' card_output[f'{hand.lower()}_{get_col(col)}_splits'] = '' for hand in ['vL', 'vR']: for col in ['1', '2', '3']: int_results = {} for x in results[hand][col]: try: int_results[int(x)] = results[hand][col][x] except ValueError as e: if testing: print(f'skipping {x} in column_output') if testing: print(f'{int_results}') sorted_results = { row_num: int_results[row_num] for row_num in sorted(int_results.keys()) } for line in sorted_results: if testing: print(f'\nsorted_results: {sorted_results}\nline: {line}') if sorted_results[line]["result"]: card_output[f'{hand.lower()}_{get_col(col)}_2d6'] += \ f'{results[hand][col][str(line)]["2d6"]}\n' card_output[f'{hand.lower()}_{get_col(col)}_results'] += \ f'{results[hand][col][str(line)]["result"]}\n' card_output[f'{hand.lower()}_{get_col(col)}_splits'] += \ f'{results[hand][col][str(line)]["splits"]}\n' return card_output def add_full_result(vs_hand, tba_data, is_good, chances): all_cols = [] good_col = player.offense_col if is_good: if good_col == 1: second = random.choice([2, 3]) all_cols = [1, second, 3 if second == 2 else 2] elif good_col == 2: second = random.choice([1, 3]) all_cols = [2, second, 3 if second == 1 else 1] elif good_col == 3: second = random.choice([1, 2]) all_cols = [3, second, 1 if second == 1 else 2] else: if good_col == 1: f_col = random.choice([2, 3]) all_cols = [f_col, 3 if f_col == 2 else 2, 1] elif good_col == 2: f_col = random.choice([1, 3]) all_cols = [f_col, 3 if f_col == 1 else 1, 2] elif good_col == 3: f_col = random.choice([1, 2]) all_cols = [f_col, 1 if f_col == 1 else 2, 3] if chances == 6: for column in all_cols: if not results[vs_hand][f'{column}']['7']['result']: results[vs_hand][f'{column}']['7'] = result_data(tba_data, 7) return chances if not results[vs_hand][f'{column}']['6']['result'] and not \ results[vs_hand][f'{column}']['2']['result']: results[vs_hand][f'{column}']['6'] = result_data(tba_data, 6) results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) return chances if not results[vs_hand][f'{column}']['8']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['8'] = result_data(tba_data, 8) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12) return chances if not results[vs_hand][f'{column}']['6']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['6'] = result_data(tba_data, 6) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12) return chances if not results[vs_hand][f'{column}']['8']['result'] and not \ results[vs_hand][f'{column}']['2']['result']: results[vs_hand][f'{column}']['8'] = result_data(tba_data, 8) results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) return chances # No matches return 0 elif chances == 5: for column in all_cols: if not results[vs_hand][f'{column}']['6']['result']: results[vs_hand][f'{column}']['6'] = result_data(tba_data, 6) return chances if not results[vs_hand][f'{column}']['8']['result']: results[vs_hand][f'{column}']['8'] = result_data(tba_data, 8) return chances if not results[vs_hand][f'{column}']['3']['result'] and not \ results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3) results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4) return chances if not results[vs_hand][f'{column}']['3']['result'] and not \ results[vs_hand][f'{column}']['10']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3) results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10) return chances if not results[vs_hand][f'{column}']['4']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11) return chances if not results[vs_hand][f'{column}']['10']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11) return chances # No matches return 0 elif chances == 4: for column in all_cols: if not results[vs_hand][f'{column}']['5']['result']: results[vs_hand][f'{column}']['5'] = result_data(tba_data, 5) return chances if not results[vs_hand][f'{column}']['9']['result']: results[vs_hand][f'{column}']['9'] = result_data(tba_data, 9) return chances if not results[vs_hand][f'{column}']['3']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4) return chances if not results[vs_hand][f'{column}']['10']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['10']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10) return chances if not results[vs_hand][f'{column}']['10']['result'] and not \ results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10) results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4) return chances return 0 elif chances == 3: for column in all_cols: if not results[vs_hand][f'{column}']['4']['result']: results[vs_hand][f'{column}']['4'] = result_data(tba_data, 4) return chances if not results[vs_hand][f'{column}']['10']['result']: results[vs_hand][f'{column}']['10'] = result_data(tba_data, 10) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['3']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11) return chances if not results[vs_hand][f'{column}']['12']['result'] and not \ results[vs_hand][f'{column}']['3']['result']: results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12) results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3) return chances if not results[vs_hand][f'{column}']['12']['result'] and not \ results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12) results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11) return chances return 0 elif chances == 2: for column in all_cols: if not results[vs_hand][f'{column}']['3']['result']: results[vs_hand][f'{column}']['3'] = result_data(tba_data, 3) return chances if not results[vs_hand][f'{column}']['11']['result']: results[vs_hand][f'{column}']['11'] = result_data(tba_data, 11) return chances if not results[vs_hand][f'{column}']['2']['result'] and not \ results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12) return chances return 0 elif chances == 1: for column in all_cols: if not results[vs_hand][f'{column}']['2']['result']: results[vs_hand][f'{column}']['2'] = result_data(tba_data, 2) return chances if not results[vs_hand][f'{column}']['12']['result']: results[vs_hand][f'{column}']['12'] = result_data(tba_data, 12) return chances return 0 def add_split_result(vs_hand, tba_data_top, tba_data_bottom, chances_top, is_good=None): all_cols = [] good_col = player.offense_col if is_good is None: if good_col == 1: f_col = random.choice([2, 3]) all_cols = [f_col, 1, 3 if f_col == 2 else 2] elif good_col == 2: f_col = random.choice([1, 3]) all_cols = [f_col, 2, 3 if f_col == 1 else 1] elif good_col == 3: f_col = random.choice([1, 2]) all_cols = [f_col, 3, 1 if f_col == 1 else 2] elif is_good: if good_col == 1: second = random.choice([2, 3]) all_cols = [1, second, 3 if second == 2 else 2] elif good_col == 2: second = random.choice([1, 3]) all_cols = [2, second, 3 if second == 1 else 1] elif good_col == 3: second = random.choice([1, 2]) all_cols = [3, second, 1 if second == 1 else 2] else: if good_col == 1: f_col = random.choice([2, 3]) all_cols = [f_col, 3 if f_col == 2 else 2, 1] elif good_col == 2: f_col = random.choice([1, 3]) all_cols = [f_col, 3 if f_col == 1 else 1, 2] elif good_col == 3: f_col = random.choice([1, 2]) all_cols = [f_col, 1 if f_col == 1 else 2, 3] legal_2d6 = legal_splits(chances_top) for column in all_cols: if results[vs_hand][f'{column}']['splits'] < 3: for y in legal_2d6: if tba_data_bottom['value'] >= y['bad_chances'] and not \ results[vs_hand][f'{column}'][f'{y["2d6"]}']['result']: results[vs_hand][f'{column}'][f'{y["2d6"]}'] = \ result_data(tba_data_top, y["2d6"], tba_data_bottom, y["incs"]) results[vs_hand][f'{column}']['splits'] += 1 return y['bad_chances'] if testing: print(f'Legal 2d6: {legal_2d6}') if testing: print(f'Could not find a legal spot for:\n{tba_data_top}\n{tba_data_bottom}') return None def assign_chances( res_key: str, vs_hand: str, remainder_keys: list[str], allow_retry: bool, rollover_key: str, is_good: bool, force_whole: bool = False): retries = 0 if allow_retry else 1 if testing: print(f'starting {res_key}: {tba[vs_hand][res_key]["value"]}') # If not even int, add_split_result with less than half of total chances total_chances = mround(tba[vs_hand][res_key]['value']) # chance_remainder = mround(total_chances - math.floor(total_chances)) # If total chance is a whole number, do easy assignments first if int(total_chances) - total_chances == 0 or force_whole or tba[vs_hand][res_key]['value'] > 2: if testing: print(f'{tba[vs_hand][res_key]["value"]} {res_key}s being placed') if tba[vs_hand][res_key]['value'] > 9.5: num_added = add_full_result(vs_hand, tba[vs_hand][res_key], is_good, 6) elif tba[vs_hand][res_key]['value'] > 7.5: num_added = add_full_result(vs_hand, tba[vs_hand][res_key], is_good, 5) elif tba[vs_hand][res_key]['value'] > 5.5: num_added = add_full_result(vs_hand, tba[vs_hand][res_key], is_good, 4) else: num_added = add_full_result( vs_hand, tba[vs_hand][res_key], is_good, int(tba[vs_hand][res_key]['value']) ) if num_added: tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - num_added) tba[vs_hand][res_key]['actual'] = mround(tba[vs_hand][res_key]['actual'] + num_added) return elif retries == 0: if testing: print(f'retry # {retries} for {res_key} for {player.name} {vs_hand}') return else: if tba[vs_hand][rollover_key]['value'] >= 1: t_value = 1 else: t_value = .05 if testing: print(f'Transferring {t_value} {res_key} to {rollover_key}') tba[vs_hand][rollover_key]['value'] = mround(tba[vs_hand][rollover_key]['value'] + t_value) tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - t_value) return # Else start dicing up the chances else: # if retries == 0 and total_chances > 3: # chance_remainder = mround( # math.ceil(total_chances / 2) - (total_chances - math.floor(total_chances)) # ) # else: # chance_remainder = mround(total_chances - math.floor(total_chances)) chance_remainder = mround(total_chances - math.floor(total_chances)) if testing: print(f'chance_remainder: {chance_remainder}') # if mround(chance_remainder) != 0 and mround(chance_remainder) > .5: # TO ROLL BACK, UNDO ABOVE COMMEND AND TAB ALL BELOW CODE IN ONCE top_chances = None bottom_key = None bottom_result = None """ If this result cannot take any splits (but has extra results pass the remainder to the rollover and come back to assign_chances with a whole number """ if len(remainder_keys) == 0: tba[vs_hand][res_key]['value'] = mround(math.floor(tba[vs_hand][res_key]['value'])) tba[vs_hand][rollover_key]['value'] = mround( tba[vs_hand][rollover_key]['value'] + chance_remainder ) return for rem_key in remainder_keys: if mround(tba[vs_hand][rem_key]['value']) >= mround(1 - chance_remainder): bottom_key = rem_key bottom_result = tba[vs_hand][rem_key] break if not bottom_key: if tba[vs_hand][rollover_key]['value'] > 1: t_value = 1 else: t_value = .05 if testing: print(f'Transferring {t_value} {res_key} to {rollover_key}') tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - t_value) tba[vs_hand][rollover_key]['value'] = mround( tba[vs_hand][rollover_key]['value'] + t_value ) return # raise ValueError( # f'Could not find a second result for a {res_key} split for {player.name} {vHand}') bottom_chances = None if tba[vs_hand][res_key]['value'] > 4: top_chances = mround(3 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) elif tba[vs_hand][res_key]['value'] > 3: top_chances = mround(2 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) elif tba[vs_hand][res_key]['value'] > 2: top_chances = mround(1 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances: top_chances = mround(chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and tba[vs_hand][res_key]['value'] > 3: top_chances = mround(.5 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and tba[vs_hand][res_key]['value'] > 3: top_chances = mround(.7 + chance_remainder) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and chance_remainder > 0.15: top_chances = mround(chance_remainder - 0.15) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if not bottom_chances and chance_remainder > 0.05: top_chances = mround(chance_remainder - 0.05) if testing: print(f'checking top_chances: {top_chances}') bottom_chances = add_split_result( vs_hand, tba[vs_hand][res_key], bottom_result, top_chances, is_good ) if testing: print(f'{res_key} chances: {mround(top_chances)} / split with {bottom_result}') if bottom_chances: tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - top_chances) tba[vs_hand][res_key]['actual'] = mround(tba[vs_hand][res_key]['actual'] + top_chances) tba[vs_hand][bottom_key]['value'] = mround( tba[vs_hand][bottom_key]['value'] - bottom_chances) tba[vs_hand][bottom_key]['actual'] = mround( tba[vs_hand][bottom_key]['actual'] + bottom_chances ) if testing: print( f'placed {top_chances} {res_key}s and {bottom_chances} {bottom_result["string"]}s for ' f'{player.name} {vs_hand}\n\n') return elif retries == 0: retries += 1 if testing: print(f'retry # {retries} for {res_key} for {player.name} {vs_hand}') return else: if tba[vs_hand][rollover_key]['value'] > 1: t_value = 1 else: t_value = .05 if testing: print(f'Transferring {t_value} {res_key} to {rollover_key}') tba[vs_hand][res_key]['value'] = mround(tba[vs_hand][res_key]['value'] - t_value) tba[vs_hand][rollover_key]['value'] = mround( tba[vs_hand][rollover_key]['value'] + t_value ) return def gap_filler(vs_hand, res_key: str): for col in ['1', '2', '3']: for b_row in ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']: # print(f'checking {col}-{b_row} {vs_hand} for a None: {results[vs_hand][col][b_row]["result"]}') if not results[vs_hand][col][b_row]['result']: chances = chances_from_row(b_row) tba[vs_hand][res_key]['actual'] = mround( tba[vs_hand][res_key]['actual'] + chances ) results[vs_hand][col][b_row] = result_data(tba[vs_hand][res_key], b_row) # Build vl results then vR for vHand in ['vL', 'vR']: # Refactored bp-hr retries = False while tba[vHand]['bp-hr']['value'] > 0: assign_chances( res_key='bp-hr', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='do-pull', is_good=True ) retries = False # Refactored fo-a retries = False while tba[vHand]['fo-a']['value'] > 0: assign_chances( res_key='fo-a', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'{"fo-lf-b" if bat_hand == "R" else "fo-rf-b"}', is_good=False ) retries = False # Refactored si-cf retries = False while tba[vHand]['si-cf']['value'] > 0: assign_chances( res_key='si-cf', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'si*', is_good=True ) retries = False # Refactored bp-si retries = True while tba[vHand]['bp-si']['value'] > 0: assign_chances( res_key='bp-si', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'si*', is_good=False ) retries = False # Refactored hbp retries = False while tba[vHand]['hbp']['value'] > 0: assign_chances( res_key='hbp', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'bb', is_good=True ) retries = False # Refactored hr retries = True while tba[vHand]['hr']['value'] > 0: assign_chances( res_key='hr', vs_hand=vHand, remainder_keys=['tr', 'do-pull', f'fo-{get_of(bat_hand, vHand)}-b', f'fo-{get_of(bat_hand, vHand, pull_side=False)}-b'], allow_retry=retries, rollover_key=f'do-pull', is_good=True ) retries = False # Refactored tr retries = False while tba[vHand]['tr']['value'] > 0: assign_chances( res_key='tr', vs_hand=vHand, remainder_keys=['do-pull', 'si**', f'fo-{get_of(bat_hand, vHand)}-b', f'fo-{get_of(bat_hand, vHand, pull_side=False)}-b'], allow_retry=retries, rollover_key=f'do-pull', is_good=True ) retries = False # Refactored do*** retries = True while tba[vHand]['do***']['value'] > 0: assign_chances( res_key='do***', vs_hand=vHand, remainder_keys=['si**', f'fo-{get_of(bat_hand, vHand, pull_side=False)}-b', f'fo-{get_of(bat_hand, vHand)}-b', 'lo', 'gb-c'], allow_retry=retries, rollover_key=f'do-pull', is_good=True ) retries = False # Refactored do** retries = True while tba[vHand]['do**']['value'] > 0: assign_chances( res_key='do**', vs_hand=vHand, remainder_keys=['si**', f'fo-{get_of(bat_hand, vHand, pull_side=False)}-b', f'fo-{get_of(bat_hand, vHand)}-b', 'lo', 'gb-c'], allow_retry=retries, rollover_key=f'do-pull', is_good=True ) retries = False # Refactored do** retries = True while tba[vHand]['do-pull']['value'] > 0: assign_chances( res_key='do-pull', vs_hand=vHand, remainder_keys=[f'fo-{get_of(bat_hand, vHand)}-b', 'lo', 'gb-c'], allow_retry=retries, rollover_key=f'si**', is_good=True ) retries = False # Refactored si** retries = True while tba[vHand]['si**']['value'] > 0: assign_chances( res_key='si**', vs_hand=vHand, remainder_keys=['lo', 'gb-a', 'gb-b', 'gb-c', 'po'], allow_retry=retries, rollover_key=f'si*', is_good=True ) retries = False # Refactored si* retries = True while tba[vHand]['si*']['value'] > 0: assign_chances( res_key='si*', vs_hand=vHand, remainder_keys=['gb-c', 'gb-b', 'gb-a', 'lo', 'po'], allow_retry=retries, rollover_key=f'gb-c', is_good=False ) retries = False # Refactored bb retries = False while tba[vHand]['bb']['value'] > 0: assign_chances( res_key='bb', vs_hand=vHand, remainder_keys=['so'], allow_retry=retries, rollover_key=f'gb-c', is_good=True ) retries = False # Refactored so retries = False while tba[vHand]['so']['value'] > 0: assign_chances( res_key='so', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key='po', is_good=False ) retries = False # TODO: Add support for the lomax # Refactored lo # retries = False # assign_chances( # res_key='lo', # vHand=vHand, # remainder_keys=['gb-a'], # allow_retry=retries, # rollover_key=f'po', # is_good=False # ) while tba[vHand]['lo']['value'] > 0: assign_chances( res_key='lo', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'po', is_good=False ) retries = False # Refactored po retries = False while tba[vHand]['po']['value'] > 0: assign_chances( res_key='po', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'so', is_good=False ) retries = False # Refactored fo-lf-b retries = False while tba[vHand]['fo-lf-b']['value'] > 0: assign_chances( res_key='fo-lf-b', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'fo-rf-b', is_good=False ) retries = False # Refactored fo-rf-b retries = False while tba[vHand]['fo-rf-b']['value'] > 0: assign_chances( res_key='fo-rf-b', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'fo-bq', is_good=False ) retries = False # Refactored fo-bq retries = False while tba[vHand]['fo-bq']['value'] > 0: assign_chances( res_key='fo-bq', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'gb-c', is_good=False ) retries = False # Refactored gb-c retries = False while tba[vHand]['gb-c']['value'] > 0: assign_chances( res_key='gb-c', vs_hand=vHand, remainder_keys=[], allow_retry=retries, rollover_key=f'gb-b', is_good=False ) retries = False # Refactored gb-b retries = False while tba[vHand]['gb-b']['value'] > 0: assign_chances( res_key='gb-b', vs_hand=vHand, remainder_keys=['gb-a'], allow_retry=retries, rollover_key=f'gb-a', is_good=False ) retries = False # # Refactored gb-a # retries = False # while tba[vHand]['gb-a']['value'] > 0: # assign_chances( # res_key='gb-a', # vs_hand=vHand, # remainder_keys=[], # allow_retry=retries, # rollover_key=f'so', # is_good=False # ) # retries = False """ Whatever result is last should be run through the gap_filler() """ if testing: print(f'filling in gaps with gb-a') gap_filler(vHand, 'gb-a') if testing: print(f'\n\n******\n\n{player.name} Results:\n{results}\n{tba}') # else: # print(f'Completed {player.name}') col_output = column_output() if testing: print(f'\n\ncol_output:\n{col_output}\n\n') # # Prep csv batter lines # all_results.append( # [player.name, player.sba_id, bat_hand, # col_output['vl_one_2d6'], col_output['vl_one_results'], col_output['vl_one_splits'], # col_output['vl_two_2d6'], col_output['vl_two_results'], col_output['vl_two_splits'], # col_output['vl_three_2d6'], col_output['vl_three_results'], col_output['vl_three_splits'], # col_output['vr_one_2d6'], col_output['vr_one_results'], col_output['vr_one_splits'], # col_output['vr_two_2d6'], col_output['vr_two_results'], col_output['vr_two_splits'], # col_output['vr_three_2d6'], col_output['vr_three_results'], col_output['vr_three_splits']] # ) for hand in ['vL', 'vR']: b_ratings = { 'id': f'{player.sba_id}-{hand}-{cardset.id}', 'player': player, 'cardset': cardset, 'vs_hand': hand, 'is_prep': False, 'homerun': mround(tba[hand]['hr']['actual']), 'bp_homerun': mround(tba[hand]['bp-hr']['actual']), 'triple': mround(tba[hand]['tr']['actual']), 'double_three': mround(tba[hand]['do***']['actual']), 'double_two': mround(tba[hand]['do**']['actual']), 'double_pull': mround(tba[hand]['do-pull']['actual']), 'single_two': mround(tba[hand]['si**']['actual']), 'single_one': mround(tba[hand]['si*']['actual']), 'single_center': mround(tba[hand]['si-cf']['actual']), 'bp_single': mround(tba[hand]['bp-si']['actual']), 'hbp': mround(tba[hand]['hbp']['actual']), 'walk': mround(tba[hand]['bb']['actual']), 'strikeout': mround(tba[hand]['so']['actual']), 'lineout': mround(tba[hand]['lo']['actual']), 'popout': mround(tba[hand]['po']['actual']), 'flyout_a': mround(tba[hand]['fo-a']['actual']), 'flyout_bq': mround(tba[hand]['fo-bq']['actual']), 'flyout_lf_b': mround(tba[hand]['fo-lf-b']['actual']), 'flyout_rf_b': mround(tba[hand]['fo-rf-b']['actual']), 'groundout_a': mround(tba[hand]['gb-a']['actual']), 'groundout_b': mround(tba[hand]['gb-b']['actual']), 'groundout_c': mround(tba[hand]['gb-c']['actual']) } count_hits = ( b_ratings['homerun'] + b_ratings['bp_homerun'] / 2 + b_ratings['triple'] + b_ratings['double_three'] + b_ratings['double_two'] + b_ratings['double_pull'] + b_ratings['single_two'] + b_ratings['single_one'] + b_ratings['single_center'] + b_ratings['bp_single'] / 2 ) b_ratings['avg'] = count_hits / 108 b_ratings['obp'] = ( count_hits + b_ratings['hbp'] + b_ratings['walk'] ) / 108 b_ratings['slg'] = ( (b_ratings['homerun'] * 4) + (b_ratings['triple'] * 3) + ((b_ratings['bp_homerun'] + b_ratings['double_three'] + b_ratings['double_two'] + b_ratings['double_pull']) * 2) + b_ratings['single_two'] + b_ratings['single_one'] + b_ratings['single_center'] + b_ratings['bp_single'] / 2 ) / 108 BatterRatings.insert(b_ratings).on_conflict_replace().execute() this_columns = { 'id': f'{player.sba_id}-{hand}-{cardset.id}', 'player': player, 'hand': player.hand, 'b_ratings_id': f'{player.sba_id}-{hand}-{cardset.id}', 'one_dice': col_output[f'{hand.lower()}_one_2d6'], 'one_results': col_output[f'{hand.lower()}_one_results'], 'one_splits': col_output[f'{hand.lower()}_one_splits'], 'two_dice': col_output[f'{hand.lower()}_two_2d6'], 'two_results': col_output[f'{hand.lower()}_two_results'], 'two_splits': col_output[f'{hand.lower()}_two_splits'], 'three_dice': col_output[f'{hand.lower()}_three_2d6'], 'three_results': col_output[f'{hand.lower()}_three_results'], 'three_splits': col_output[f'{hand.lower()}_three_splits'] } CardColumns.insert(this_columns).on_conflict_replace().execute() # # Prep csv ratings guide # rg_line = [player.name, bat_hand] # for hand in ['vL', 'vR']: # for x in rg_headers: # if x not in ['name', 'hand']: # rg_line.append(mround(tba[hand][x]['actual'])) # ratings_guide.append(rg_line) # No player match else: logging.error(f'Could not match player id {row[0]}') print(f'Could not match player id {row[0]}') # # https://www.baseball-reference.com/leagues/majors/2021-standard-batting.shtml # with open('baserunning-data.csv', 'r') as file: # reader = csv.reader(file) # # for row in reader: # player = Player.get_or_none(Player.br_id == row[36]) # if player: """ Export card output to csv for Component Studio """ # # Removed since output has own script now # write_to_csv(output_path, f'batter-ratings-guide-{now.strftime("%Y-%m-%d-%f")}', ratings_guide) # write_to_csv(output_path, f'batter-card-columns-{now.strftime("%Y-%m-%d-%f")}', all_results) lets_go = input(f'Should I run fielders (y/n)? ') if lets_go in YES: # https://www.baseball-reference.com/leagues/majors/2022-specialpos_p-fielding.shtml with open(f'{input_path}defense-p.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) for row in reader: try: if int(cardset_name[:4]) > 2012: br_id_col = 29 cs_col = 27 pick_col = 28 else: br_id_col = 26 cs_col = 24 pick_col = 25 player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[br_id_col]) if player and row[15] != '' and row[12] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position='P', innings=int(float(row[8])), range=d.range_pitcher(int(row[15]), season_pct), error=d.error_pitcher(int(row[12]), int(row[9]), season_pct=season_pct), ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) ).execute() this_pos.save() spow, rpow = d.pow_ratings(d.innings_float(row[8]), int(row[6]), int(row[5])) this_pit = PitcherData( player=player, cardset=cardset, hold=d.hold_pitcher(row[cs_col], int(row[pick_col]), season_pct), starter_rating=spow, relief_rating=rpow ) dupe = PitcherData.delete().where( (PitcherData.player == player) & (PitcherData.cardset == cardset) ).execute() this_pit.save() if int(row[6]) >= int(row[5]) * .1: sp_pos = Position( player=player, cardset=cardset, position='SP', innings=int(float(row[8])) * (int(row[6]) / int(row[5])), range=69, error=420 ) sp_pos.save() if int(row[6]) <= int(row[5]) * .8: rp_pos = Position( player=player, cardset=cardset, position='RP', innings=int(float(row[8])) * (1 - (int(row[6]) / int(row[5]))), range=69, error=420 ) rp_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[br_id_col]}') except Exception as e: logging.error(f'Failed to process fielder {row[1]}: {type(e)}: {e}') # https://www.baseball-reference.com/leagues/majors/2022-standard-pitching.shtml with open(f'{input_path}pitcher-data.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) for row in reader: player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[35]) if player: all_data = PitcherData.select().where( (PitcherData.player == player) & (PitcherData.cardset == cardset) ).limit(1) this_data = None try: this_data = all_data[0] except Exception as e: logging.error(f'Could not find existing PitcherData for {player.name}') if this_data is not None: closer_rating = p.closer_rating(int(row[11]), int(row[14]), int(row[9])) this_data.balk = p.balks(int(row[24]), int(float(row[15])), season_pct) this_data.wild_pitch = p.wild_pitches(int(row[25]), int(float(row[15])), season_pct) this_data.closer_rating = closer_rating this_data.batting = f'1W{player.hand}-C' this_data.save() if closer_rating != 'N': cp_pos = Position( player=player, cardset=cardset, position='CP', innings=1, range=69, error=420 ) cp_pos.save() else: logging.error(f'Could not match bbref id {row[35]}') with open(f'{input_path}defense-c.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = 'C' for row in reader: if int(cardset_name[:4]) > 2012: br_id_col = 34 else: br_id_col = 31 player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[br_id_col]) if player: # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_catcher(int(row[17]), season_pct), error=d.error_catcher(int(row[12]), int(row[9]), season_pct), arm=d.arm_catcher(row[30], int(row[22]), season_pct), pb=d.pb_catcher(int(row[26]), int(float(row[8])), season_pct), overthrow=d.ot_catcher(int(row[12]), int(row[9]), season_pct) ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[br_id_col]}') print(f'CATCHER - Could not match bbref id {row[br_id_col]} - {row[1]}') with open(f'{input_path}defense-1b.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = '1B' for row in reader: br_id_col = 29 # if int(cardset_name[:4]) > 2012: # br_id_col = 29 # else: # br_id_col = 26 player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[br_id_col]) if player and row[19] != '' and row[22] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_first_base(int(row[19]), int(row[22]), season_pct), error=d.error_first_base(int(row[12]), int(row[9]), season_pct), ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[br_id_col]}') print(f'FIRST BASE - Could not match bbref id {row[br_id_col]} - {row[1]}') with open(f'{input_path}defense-2b.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = '2B' for row in reader: br_id_col = 29 # if int(cardset_name[:4]) > 2012: # br_id_col = 29 # else: # br_id_col = 26 logging.info(f'br_id: {row[br_id_col]} / type: {type(row[br_id_col])}') player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[br_id_col]) if player and row[19] != '' and row[22] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_second_base(int(row[19]), int(row[22]), season_pct), error=d.error_second_base(int(row[12]), int(row[9]), season_pct), ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: p_err = f'{player.name if player else "player not found"}' logging.error(f'Could not match bbref id {row[br_id_col]}') print(f'SECOND BASE - Could not match bbref id {row[br_id_col]} - {row[1]}') with open(f'{input_path}defense-3b.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = '3B' for row in reader: br_id_col = 29 # if int(cardset_name[:4]) > 2012: # br_id_col = 29 # else: # br_id_col = 26 player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[br_id_col]) if player and row[19] != '' and row[22] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_third_base(int(row[19]), int(row[22]), season_pct), error=d.error_third_base(int(row[12]), int(row[9]), season_pct), ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[br_id_col]}') print(f'THIRD BASE - Could not match bbref id {row[br_id_col]} - {row[1]}') with open(f'{input_path}defense-ss.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = 'SS' for row in reader: br_id_col = 29 # if int(cardset_name[:4]) > 2012: # br_id_col = 29 # else: # br_id_col = 26 player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[br_id_col]) if player and row[19] != '' and row[22] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_shortstop(int(row[19]), int(row[22]), season_pct), error=d.error_shortstop(int(row[12]), int(row[9]), season_pct), ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[br_id_col]}') print(f'SHORTSTOP - Could not match bbref id {row[br_id_col]} - {row[1]}') with open(f'{input_path}defense-lf.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = 'LF' for row in reader: player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[26]) if player and row[22] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_left_field(int(row[19]), season_pct), error='69', arm=row[22] ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[26]}') with open(f'{input_path}defense-cf.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = 'CF' for row in reader: player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[26]) if player and row[22] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_center_field(int(row[19]), season_pct), error='69', arm=row[22] ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[26]}') with open(f'{input_path}defense-rf.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) curr_pos = 'RF' for row in reader: player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[26]) if player and row[22] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position=curr_pos, innings=int(float(row[8])), range=d.range_right_field(int(row[19]), season_pct), error='69', arm=row[22] ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == curr_pos) ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[26]}') with open(f'{input_path}defense-of.csv', 'r', encoding='utf8') as file: reader = csv.reader(file) for row in reader: player = ScoutPlayer.get_or_none(ScoutPlayer.br_id == row[26]) all_of = Position.select().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position.contains("F")) ) all_arms = [int(x.arm) for x in all_of] if player and row[25] != '' and row[18] != '': # Build Position object and save this_pos = Position( player=player, cardset=cardset, position='OF', innings=int(float(row[8])), range=69, error=d.error_outfield(int(row[12]), int(row[9]), season_pct), arm=d.arm_outfield(all_arms) ) dupe = Position.delete().where( (Position.player == player) & (Position.cardset == cardset) & (Position.position == 'OF') ).execute() this_pos.save() # No player match else: logging.error(f'Could not match bbref id {row[26]}') if __name__ == '__main__': asyncio.run(main(sys.argv[1:]))