Initial commit

This commit is contained in:
Cal Corum 2023-02-22 15:40:02 -06:00
parent 80a9282cb3
commit 17ef692d18
8 changed files with 1093 additions and 0 deletions

32
README.txt Normal file
View File

@ -0,0 +1,32 @@
#######
DATA REQUIREMENTS
#######
- Add any new players to players.csv for import
- Create directory in /data-input in format `XXXX Season Cardset`
- Upload the following csv files:
- baserunning-data.csv
- https://www.baseball-reference.com/leagues/majors/2022-baserunning-batting.shtml
- batter-stats.csv
- https://www.fangraphs.com/leaders/splits-leaderboards
- defense-X.csv (each position)
- https://www.baseball-reference.com/leagues/majors/2022-specialpos_p-fielding.shtml
- replace the `p` in `p-fielding` with 1b/2b/lf
- defense-of.csv (don't forget combined OF)
- https://www.baseball-reference.com/leagues/majors/2022-specialpos_p-fielding.shtml
- replace the `p` in `p-fielding` with of
- pitcher-data.csv
- https://www.baseball-reference.com/leagues/majors/2022-standard-pitching.shtml
- pitcher-stats.csv
- https://www.fangraphs.com/leaders/splits-leaderboards
#######
CARD CREATION PROCESS
#######
1) Import new players for sba_id with `1. Import Players`
2) Confirm cardset exists; if not, create now
3) Create cards with `3. Card Creation`
4) Generate csv output with `4. Card Output`
5) Upload output files into Sheets for Component Studio import
6) Upload ratings output files into Sheets for PD Ratings Guide

255
calcs_batter.py Normal file
View File

@ -0,0 +1,255 @@
from creation_helpers import mround
def total_chances(chance_data):
sum_chances = 0
for key in chance_data:
if key not in ['id', 'player_id', 'cardset_id', 'vs_hand', 'is_prep']:
sum_chances += chance_data[key]
return mround(sum_chances)
def bp_singles(all_singles):
if all_singles < 6:
return 0
else:
return 5
def wh_singles(rem_singles, hard_rate):
if rem_singles == 0 or hard_rate < .2:
return 0
elif hard_rate > .4:
return mround(rem_singles * .666)
else:
return mround(rem_singles * .333)
def one_singles(rem_singles, ifh_rate, force_rem):
if force_rem:
return mround(rem_singles)
elif rem_singles == 0 or ifh_rate < .05:
return 0
else:
return mround(rem_singles * ifh_rate * 3)
def all_homeruns(rem_hits, all_hits, hrs, hits, singles):
if rem_hits == 0 or all_hits == 0 or hrs == 0 or hits - singles == 0:
return 0
else:
return mround(min(rem_hits, all_hits * ((hrs * 1.15) / hits)))
def nd_homeruns(all_hr, hr_rate):
if all_hr == 0 or hr_rate == 0:
return 0
elif hr_rate > .2:
return mround(all_hr * .6)
else:
return mround(all_hr * .25)
def triples(all_xbh, tr_count, do_count):
if all_xbh == 0 or tr_count == 0:
return 0
else:
return mround(all_xbh * (tr_count / (tr_count + do_count)))
def two_doubles(all_doubles, soft_rate):
if all_doubles == 0 or soft_rate == 0:
return 0
elif soft_rate > .2:
return mround(all_doubles / 2)
else:
return mround(all_doubles / 4)
def hit_by_pitch(other_ob, hbps, walks):
if hbps == 0 or other_ob * (hbps / (hbps + walks)) < 1:
return 0
else:
return mround(other_ob * (hbps / (hbps + walks)), base=1.0)
def strikeouts(all_outs, k_rate):
if all_outs == 0 or k_rate == 0:
return 0
else:
return mround(all_outs * k_rate)
def flyout_a(all_flyouts, hard_rate):
if all_flyouts == 0 or hard_rate < .4:
return 0
else:
return 1
def flyout_bq(rem_flyouts, soft_rate):
if rem_flyouts == 0 or soft_rate < .1:
return 0
else:
return mround(rem_flyouts * soft_rate * 3)
def flyout_b(rem_flyouts, pull_rate, cent_rate):
if rem_flyouts == 0 or pull_rate == 0:
return 0
else:
return mround(rem_flyouts * (pull_rate + cent_rate / 2))
def popouts(rem_outs, iffb_rate):
if rem_outs == 0 or iffb_rate * rem_outs < 1:
return 0
else:
return mround(rem_outs * iffb_rate)
def groundball_a(all_groundouts, gidps, abs):
if all_groundouts == 0 or gidps == 0:
return 0
else:
return mround((min(gidps ** 2.5, abs) / abs) * all_groundouts)
def groundball_c(rem_groundouts, med_rate):
if rem_groundouts == 0 or med_rate < .4:
return 0
elif med_rate > .6:
return mround(rem_groundouts)
else:
return mround(rem_groundouts * med_rate)
def stealing(chances: int, sb2s: int, cs2s: int, sb3s: int, cs3s: int, season_pct: float):
if chances == 0 or sb2s + cs2s == 0:
return 0, 0, False, 0
total_attempts = sb2s + cs2s + sb3s + cs3s
attempt_pct = total_attempts / chances
if attempt_pct >= .08:
st_auto = True
else:
st_auto = False
# chance_odds = [x / 36 for x in range(1, 36)]
st_jump = 0
for x in range(1, 37):
if attempt_pct * 1.5 <= x / 36:
st_jump = x / 36
break
st_high = mround(20 * (sb2s / (sb2s + cs2s + cs2s)))
if sb3s + cs3s < (3 * season_pct):
st_low = 3
else:
st_low = mround(16 * ((sb2s + sb3s) / (sb2s + sb3s + cs2s * 2 + cs3s * 2)))
if st_low >= st_high:
if st_high == 0:
st_low = 0
elif st_high <= 3:
st_low = 1
else:
st_low = st_high - 3
if ((st_high - 7) > st_low) and st_high > 7:
st_low = st_high - 7
return round(st_low), round(st_high), st_auto, st_jump
def stealing_line(steal_data: dict):
sd = steal_data
jump_chances = round(sd[3] * 36)
if jump_chances == 0:
good_jump = '-'
elif jump_chances <= 6:
if jump_chances == 6:
good_jump = 7
elif jump_chances == 5:
good_jump = 6
elif jump_chances == 4:
good_jump = 5
elif jump_chances == 3:
good_jump = 4
elif jump_chances == 2:
good_jump = 3
elif jump_chances == 1:
good_jump = 2
elif jump_chances == 7:
good_jump = '4,5'
elif jump_chances == 8:
good_jump = '4,6'
elif jump_chances == 9:
good_jump = '3-5'
elif jump_chances == 10:
good_jump = '2-5'
elif jump_chances == 11:
good_jump = '6,7'
elif jump_chances == 12:
good_jump = '4-6'
elif jump_chances == 13:
good_jump = '2,4-6'
elif jump_chances == 14:
good_jump = '3-6'
elif jump_chances == 15:
good_jump = '2-6'
elif jump_chances == 16:
good_jump = '2,5-6'
elif jump_chances == 17:
good_jump = '3,5-6'
elif jump_chances == 18:
good_jump = '4-6'
elif jump_chances == 19:
good_jump = '2,4-7'
elif jump_chances == 20:
good_jump = '3-7'
elif jump_chances == 21:
good_jump = '2-7'
elif jump_chances == 22:
good_jump = '2-7,12'
elif jump_chances == 23:
good_jump = '2-7,11'
elif jump_chances == 24:
good_jump = '2,4-8'
elif jump_chances == 25:
good_jump = '3-8'
elif jump_chances == 26:
good_jump = '2-8'
elif jump_chances == 27:
good_jump = '2-8,12'
elif jump_chances == 28:
good_jump = '2-8,11'
elif jump_chances == 29:
good_jump = '3-9'
elif jump_chances == 30:
good_jump = '2-9'
elif jump_chances == 31:
good_jump = '2-9,12'
elif jump_chances == 32:
good_jump = '2-9,11'
elif jump_chances == 33:
good_jump = '2-10'
elif jump_chances == 34:
good_jump = '3-11'
elif jump_chances == 35:
good_jump = '2-11'
else:
good_jump = '2-12'
return f'{"*" if sd[2] else ""}{good_jump}/- ({sd[1] if sd[1] else "-"}-{sd[0] if sd[0] else "-"})'
def running(extra_base_pct: str):
if extra_base_pct == '':
return 8
xb_pct = float(extra_base_pct.strip("%")) / 100
return round(8 + (10 * xb_pct))

330
calcs_defense.py Normal file
View File

@ -0,0 +1,330 @@
import math
def range_pitcher(rs_value: int, season_pct: float):
if rs_value >= (3 * season_pct):
return 1
elif rs_value >= (0 * season_pct):
return 2
elif rs_value >= (-1 * season_pct):
return 3
elif rs_value >= (-100 * season_pct):
return 4
else:
return 5
def range_catcher(rs_value: int, season_pct: float):
if rs_value >= 7 * season_pct:
return 1
elif rs_value >= 3 * season_pct:
return 2
elif rs_value >= -1 * season_pct:
return 3
elif rs_value >= -5 * season_pct:
return 4
else:
return 5
def range_first_base(r_range: int, r_dp: int, season_pct: float):
if (r_range + r_dp) >= (4 * season_pct):
return 1
elif (r_range + r_dp) >= (1 * season_pct):
return 2
elif (r_range + r_dp) >= (0 * season_pct):
return 3
elif (r_range + r_dp) >= (-2 * season_pct):
return 4
else:
return 5
def range_second_base(r_range: int, r_dp: int, season_pct: float):
# print(f'r_range ({r_range}) + r_dp ({r_dp}) = {r_range + r_dp}')
if (r_range + r_dp) >= (5 * season_pct):
return 1
elif (r_range + r_dp) >= (2 * season_pct):
return 2
elif (r_range + r_dp) >= (0 * season_pct):
return 3
elif (r_range + r_dp) >= (-2 * season_pct):
return 4
else:
return 5
def range_third_base(r_range: int, r_dp: int, season_pct: float):
if (r_range + r_dp) >= (5 * season_pct):
return 1
elif (r_range + r_dp) >= (2 * season_pct):
return 2
elif (r_range + r_dp) >= (0 * season_pct):
return 3
elif (r_range + r_dp) >= (-2 * season_pct):
return 4
else:
return 5
def range_shortstop(r_range: int, r_dp: int, season_pct: float):
if (r_range + r_dp) >= (6 * season_pct):
return 1
elif (r_range + r_dp) >= (2 * season_pct):
return 2
elif (r_range + r_dp) >= (0 * season_pct):
return 3
elif (r_range + r_dp) >= (-3 * season_pct):
return 4
else:
return 5
def range_center_field(r_range: int, season_pct: float):
if r_range >= 9 * season_pct:
return 1
elif r_range >= 2 * season_pct:
return 2
elif r_range >= -2 * season_pct:
return 3
elif r_range >= -5 * season_pct:
return 4
else:
return 5
def range_left_field(r_range: int, season_pct: float):
return range_center_field(r_range, season_pct)
def range_right_field(r_range: int, season_pct: float):
return range_center_field(r_range, season_pct)
def valid_error_ratings(err_num: int, position: str) -> int:
if position.lower() == 'p':
valid_err = [
0, 4, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 30, 31, 33, 34,
35, 36, 38, 39, 40, 42, 43, 44, 46, 47, 48, 50, 51
]
elif position.lower() == 'c':
valid_err = list(range(17))
elif position.lower() == '1b':
valid_err = list(range(31))
elif position.lower() == '2b':
valid_err = [
0, 1, 2, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
32, 34, 37, 39, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71
]
elif position.lower() == '3b':
valid_err = [
0, 1, 2, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 37, 39, 41, 44, 47, 50, 53, 56, 59, 62, 65
]
elif position.lower() == 'ss':
valid_err = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 36, 38, 40, 42, 44, 48, 52, 56, 60, 64, 68, 72
]
# Outfielders
else:
valid_err = list(range(26))
if err_num in valid_err:
return err_num
elif err_num > valid_err[len(valid_err) - 1]:
return valid_err[len(valid_err) - 1]
else:
for x in valid_err:
if err_num <= x:
return x
def raw_error(errors: int, chances: int, season_pct: float, chance_max: int):
if errors == 0 or chances == 0:
return 0
c_max = chance_max * season_pct
return errors * c_max / chances
def error_pitcher(errors: int, chances: int, season_pct: float):
return valid_error_ratings(int(raw_error(errors, chances, season_pct, 50)), 'p')
def error_catcher(errors: int, chances: int, season_pct: float):
return valid_error_ratings(int(raw_error(errors, chances, season_pct, 500)), 'c')
def error_first_base(errors: int, chances: int, season_pct: float):
return valid_error_ratings(int(raw_error(errors, chances, season_pct, 1300)), '1b')
def error_second_base(errors: int, chances: int, season_pct: float):
return valid_error_ratings(int(raw_error(errors, chances, season_pct, 700)), '2b')
def error_third_base(errors: int, chances: int, season_pct: float):
return valid_error_ratings(int(raw_error(errors, chances, season_pct, 500)), '3b')
def error_shortstop(errors: int, chances: int, season_pct: float):
return valid_error_ratings(int(raw_error(errors, chances, season_pct, 700)), 'ss')
def error_outfield(errors: int, chances: int, season_pct: float):
return valid_error_ratings(int(raw_error(errors, chances, season_pct, 250)), 'of')
def arm_outfield(all_arms: list):
if not all_arms:
return '+5'
if max(all_arms) > 8:
return '-6'
elif max(all_arms) > 4:
return '-5'
elif max(all_arms) < -4:
return '+5'
else:
final_arm = max(all_arms) * -1
return f'{"+" if final_arm >= 0 else ""}{final_arm}'
def arm_catcher(cs_pct: str, raa: int, season_pct: float) -> str:
if cs_pct == '':
return '+3'
cs_pct = float(cs_pct.strip("%")) / 100
if raa > 5 * season_pct:
max_arm = -4
elif raa > 2 * season_pct:
max_arm = -2
elif raa > -1 * season_pct:
max_arm = 0
elif raa > -2 * season_pct:
max_arm = 3
else:
max_arm = 5
if cs_pct > .6:
raw_arm = -5
elif cs_pct > .5:
raw_arm = -4
elif cs_pct > .4:
raw_arm = -3
elif cs_pct > .3:
raw_arm = -2
elif cs_pct > .25:
raw_arm = -1
elif cs_pct > .2:
raw_arm = 0
elif cs_pct > .16:
raw_arm = 1
elif cs_pct > .12:
raw_arm = 2
elif cs_pct > .1:
raw_arm = 3
elif cs_pct > .05:
raw_arm = 4
else:
raw_arm = 5
final_arm = min(max_arm, raw_arm)
return f'{"+" if final_arm >= 0 else ""}{final_arm}'
def pb_catcher(pb: int, innings: int, season_pct: float):
if pb == 0 or innings == 0:
return 0
return min(pb * 1000 * season_pct / innings, 20)
def ot_catcher(errors: int, chances: int, season_pct: float):
if errors == 0 or chances == 0:
return 0
c_max = 3000 * season_pct
return min(errors * c_max / chances / 3, 20)
def hold_pitcher(raw_cs: str, picks: int, season_pct: float) -> str:
if raw_cs == '':
return '+9'
cs_pct = float(raw_cs.strip("%")) / 100
if picks > 5 * season_pct:
pick_cap = -3
elif picks > 3 * season_pct:
pick_cap = -2
elif picks > 0 * season_pct:
pick_cap = 5
else:
pick_cap = 9
if cs_pct > .667:
hold_num = -5
elif cs_pct > .6:
hold_num = -4
elif cs_pct > .48:
hold_num = -3
elif cs_pct > .34:
hold_num = -2
elif cs_pct > .26:
hold_num = -1
elif cs_pct > .22:
hold_num = 0
elif cs_pct > .2:
hold_num = 1
elif cs_pct > .18:
hold_num = 3
elif cs_pct > .16:
hold_num = 4
elif cs_pct > .14:
hold_num = 5
elif cs_pct > .12:
hold_num = 6
elif cs_pct > .1:
hold_num = 7
elif cs_pct > .06:
hold_num = 8
else:
hold_num = 9
final_hold = min(pick_cap, hold_num)
return f'{"+" if final_hold >= 0 else ""}{final_hold}'
def pow_ratings(innings: float, gs: int, games: int) -> (int, int):
if innings <= 1 or games <= 1:
return 1, 1
s_innings = int(innings * gs / games)
r_innings = int(innings * (games - gs) / games)
if gs == 0:
s_pow = 1
else:
s_pow = round(s_innings / gs)
if r_innings == 0:
r_pow = 1
else:
r_pow = round(r_innings / (games - gs))
if r_innings / max(s_innings, 1) < .1:
r_pow = 1
elif r_pow >= s_pow > 1:
r_pow = s_pow - 1
return s_pow, r_pow
def innings_float(innings: str) -> float:
if '.' in innings:
whole, decimal = innings.split('.')
else:
whole = innings
decimal = "0"
return float(int(whole) + int(decimal) * .333)

209
calcs_pitcher.py Normal file
View File

@ -0,0 +1,209 @@
from creation_helpers import mround
def total_chances(chance_data):
sum_chances = 0
for key in chance_data:
if key not in ['id', 'player_id', 'cardset_id', 'vs_hand', 'is_prep']:
sum_chances += chance_data[key]
return sum_chances
def soft_rate(pct):
if pct > .2:
return 'high'
elif pct < .1:
return 'low'
else:
return 'avg'
def med_rate(pct):
if pct > .65:
return 'high'
elif pct < .4:
return 'low'
else:
return 'avg'
def hard_rate(pct):
if pct > .4:
return 'high'
elif pct < .2:
return 'low'
else:
return 'avg'
def hr_per_fb_rate(pct):
if pct > .18:
return 'high'
elif pct < .08:
return 'low'
else:
return 'avg'
def all_singles(row, hits_vl, hits_vr):
tot_singles_vl = hits_vl * ((int(row[7]) - int(row[8]) - int(row[9]) - int(row[12]))
/ int(row[7]))
tot_singles_vr = hits_vr * ((int(row[40]) - int(row[41]) - int(row[42]) - int(row[45]))
/ int(row[40]))
return mround(tot_singles_vl), mround(tot_singles_vr)
def bp_singles(singles_vl, singles_vr):
bpsi_vl = 5 if singles_vl >= 5 else 0
bpsi_vr = 5 if singles_vr >= 5 else 0
return mround(bpsi_vl), mround(bpsi_vr)
def wh_singles(rem_si_vl, rem_si_vr, hard_rate_vl, hard_rate_vr):
if hard_rate_vl == 'low':
whs_vl = 0
else:
whs_vl = rem_si_vl / 2
if hard_rate_vr == 'low':
whs_vr = 0
else:
whs_vr = rem_si_vr / 2
return mround(whs_vl), mround(whs_vr)
def one_singles(rem_si_vl, rem_si_vr, soft_rate_vl, soft_rate_vr):
if soft_rate_vl == 'high':
oss_vl = rem_si_vl
else:
oss_vl = 0
if soft_rate_vr == 'high':
oss_vr = rem_si_vr
else:
oss_vr = 0
return mround(oss_vl), mround(oss_vr)
def bp_homerun(hr_vl, hr_vr, hr_rate_vl, hr_rate_vr):
if hr_rate_vl == 'low':
bphr_vl = hr_vl
elif hr_rate_vl == 'avg':
bphr_vl = hr_vl * .75
else:
bphr_vl = hr_vl * .4
if hr_rate_vr == 'low':
bphr_vr = hr_vr
elif hr_rate_vr == 'avg':
bphr_vr = hr_vr * .75
else:
bphr_vr = hr_vr * .4
return mround(bphr_vl), mround(bphr_vr)
def triples(all_xbh_vl, all_xbh_vr, triple_rate_vl, triple_rate_vr):
tr_vl = all_xbh_vl * triple_rate_vl if all_xbh_vl > 0 else 0
tr_vr = all_xbh_vr * triple_rate_vr if all_xbh_vr > 0 else 0
return mround(tr_vl), mround(tr_vr)
def two_doubles(all_doubles_vl, all_doubles_vr, soft_rate_vl, soft_rate_vr):
two_doubles_vl = all_doubles_vl if soft_rate_vl == 'high' else 0
two_doubles_vr = all_doubles_vr if soft_rate_vr == 'high' else 0
return mround(two_doubles_vl), mround(two_doubles_vr)
def hbp_rate(hbp, bb):
if hbp == 0:
return 0
elif bb == 0:
return 1
else:
return hbp / bb
def hbps(all_ob, this_hbp_rate):
if all_ob == 0 or this_hbp_rate == 0:
return 0
else:
return mround(all_ob * this_hbp_rate)
def xchecks(pos, all_chances=True):
if pos.lower() == 'p':
return 1 if all_chances else 0
elif pos.lower() == 'c':
return 3 if all_chances else 2
elif pos.lower() == '1b':
return 2 if all_chances else 1
elif pos.lower() == '2b':
return 6 if all_chances else 5
elif pos.lower() == '3b':
return 3 if all_chances else 2
elif pos.lower() == 'ss':
return 7 if all_chances else 6
elif pos.lower() == 'lf':
return 2 if all_chances else 1
elif pos.lower() == 'cf':
return 3 if all_chances else 2
else:
return 2 if all_chances else 1
def oppo_fly(all_fly, oppo_rate):
if all_fly == 0 or oppo_rate == 0:
return 0
else:
return mround(all_fly * oppo_rate)
def groundball_a(all_gb, dp_rate):
if all_gb == 0 or dp_rate == 0:
return 0
elif dp_rate > .6:
return all_gb
else:
return mround(all_gb * (dp_rate * 1.5))
def balks(total_balks: int, innings: float, season_pct):
if innings == 0:
return 0
return min(round((total_balks * 290 * season_pct) / innings), 20)
def wild_pitches(total_wps: int, innings: float, season_pct):
if innings == 0:
return 0
return min(round((total_wps * 200 * season_pct) / innings), 20)
def closer_rating(gf: int, saves: int, games: int) -> str:
if gf == 0 or games == 0 or saves == 0:
return 'N'
if gf / games >= .875:
return '6'
elif gf / games >= .8:
return '5'
elif gf / games >= .7:
return '4'
elif gf / games >= .55:
return '3'
elif gf / games >= .4:
return '2'
elif gf / games >= .25:
return '1'
elif gf / games >= .1:
return '0'
else:
return 'N'

176
db_calls_card_creation.py Normal file
View File

@ -0,0 +1,176 @@
from peewee import *
from playhouse.shortcuts import model_to_dict
db = SqliteDatabase(
'storage/card_creation.db',
pragmas={
'journal_mode': 'wal',
'cache_size': -1 * 64000,
'synchronous': 0
}
)
class BaseModel(Model):
class Meta:
database = db
class Cardset(BaseModel):
set_title = CharField()
set_subtitle = CharField(null=True)
class Player(BaseModel):
sba_id = IntegerField(primary_key=True)
name = CharField()
fg_id = IntegerField()
br_id = CharField()
offense_col = IntegerField()
hand = CharField(default='R')
db.create_tables([Cardset, Player])
class BatterRatings(BaseModel):
id = CharField(unique=True, primary_key=True)
player = ForeignKeyField(Player)
cardset = ForeignKeyField(Cardset)
vs_hand = FloatField()
is_prep = BooleanField()
homerun = FloatField()
bp_homerun = FloatField()
triple = FloatField()
double_three = FloatField()
double_two = FloatField()
double_pull = FloatField()
single_two = FloatField()
single_one = FloatField()
single_center = FloatField()
bp_single = FloatField()
hbp = FloatField()
walk = FloatField()
strikeout = FloatField()
lineout = FloatField()
popout = FloatField()
flyout_a = FloatField()
flyout_bq = FloatField()
flyout_lf_b = FloatField()
flyout_rf_b = FloatField()
groundout_a = FloatField()
groundout_b = FloatField()
groundout_c = FloatField()
avg = FloatField(null=True)
obp = FloatField(null=True)
slg = FloatField(null=True)
class PitcherRatings(BaseModel):
id = CharField(unique=True, primary_key=True)
player = ForeignKeyField(Player)
cardset = ForeignKeyField(Cardset)
vs_hand = CharField()
is_prep = BooleanField()
homerun = FloatField()
bp_homerun = FloatField()
triple = FloatField()
double_three = FloatField()
double_two = FloatField()
double_cf = FloatField()
single_two = FloatField()
single_one = FloatField()
single_center = FloatField()
bp_single = FloatField()
hbp = FloatField()
walk = FloatField()
strikeout = FloatField()
fo_slap = FloatField()
fo_center = FloatField()
groundout_a = FloatField()
groundout_b = FloatField()
xcheck_p = FloatField()
xcheck_c = FloatField()
xcheck_1b = FloatField()
xcheck_2b = FloatField()
xcheck_3b = FloatField()
xcheck_ss = FloatField()
xcheck_lf = FloatField()
xcheck_cf = FloatField()
xcheck_rf = FloatField()
avg = FloatField(null=True)
obp = FloatField(null=True)
slg = FloatField(null=True)
db.create_tables([BatterRatings, PitcherRatings])
class CardColumns(BaseModel):
id = CharField(unique=True, primary_key=True)
player = ForeignKeyField(Player)
hand = CharField()
b_ratings = ForeignKeyField(BatterRatings, null=True)
p_ratings = ForeignKeyField(PitcherRatings, null=True)
one_dice = CharField()
one_results = CharField()
one_splits = CharField()
two_dice = CharField()
two_results = CharField()
two_splits = CharField()
three_dice = CharField()
three_results = CharField()
three_splits = CharField()
class Position(BaseModel):
player = ForeignKeyField(Player)
cardset = ForeignKeyField(Cardset)
position = CharField()
innings = IntegerField()
range = IntegerField()
error = IntegerField()
arm = CharField(null=True)
pb = IntegerField(null=True)
overthrow = IntegerField(null=True)
class BatterData(BaseModel):
player = ForeignKeyField(Player)
cardset = ForeignKeyField(Cardset)
stealing = CharField()
st_low = IntegerField()
st_high = IntegerField()
st_auto = BooleanField()
st_jump = FloatField()
bunting = CharField(null=True)
hit_and_run = CharField(null=True)
running = CharField()
class PitcherData(BaseModel):
player = ForeignKeyField(Player)
cardset = ForeignKeyField(Cardset)
balk = IntegerField(null=True)
wild_pitch = IntegerField(null=True)
hold = CharField()
starter_rating = IntegerField()
relief_rating = IntegerField()
closer_rating = IntegerField(null=True)
batting = CharField(null=True)
db.create_tables([CardColumns, Position, BatterData, PitcherData])
class CardOutput(BaseModel):
name = CharField()
hand = CharField()
positions = CharField()
stealing = CharField()
bunting = CharField()
hitandrun = CharField()
running = CharField()
db.close()

42
import_players.py Normal file
View File

@ -0,0 +1,42 @@
import sys
import csv
from db_calls_card_creation import *
def clean_name(name):
return name.replace('.', '').replace("'", '').replace('-', ' ').replace('í', 'i').replace('é', 'e')\
.replace('ñ', 'n').replace('á', 'a')
def main(argv):
# Importing: https://docs.google.com/spreadsheets/d/1Gcgk4P8rJqX7mHO-OKPuM2FXBWNkDNZ8LNFA6DeaNck/edit#gid=72732162
# Player Database from Columns tab
file_name = 'data-input/players.csv'
with open(file_name, 'r') as file:
reader = csv.reader(file)
all_players = []
for row in reader:
if row[0] != 'sba-id':
all_players.append({
'name': clean_name(row[3]),
'fg_id': row[2],
'br_id': row[1],
'sba_id': row[0],
'offense_col': row[4],
'hand': row[5]
})
# TODO: will want to update this to check for existing reocrd; get_or_create ?
with db.atomic():
for batch in chunked(all_players, 50):
Player.insert_many(batch).on_conflict_ignore().execute()
db.close()
print(f'Processed {len(all_players)} players')
if __name__ == '__main__':
main(sys.argv[1:])

33
manual_updates.py Normal file
View File

@ -0,0 +1,33 @@
import asyncio
import csv
import datetime
import logging
import pathlib
import sys
from db_calls import *
async def main(argv):
with open('manual-updates.csv', 'r') as file:
reader = csv.reader(file)
count = 0
for row in reader:
p_query = db_get('players', params=[('name', row[0]), ('cardset_id', 3)])
if p_query:
this_player = p_query['players'][0]
pos_1 = row[1]
pos_2 = row[2] if row[2] else False
pos_3 = row[3] if row[3] else False
db_patch('players', object_id=this_player['player_id'], params=[
('pos_1', pos_1), ('pos_2', pos_2), ('pos_3', pos_3)
])
count += 1
print(f'Just updated {count} record{"s" if count != 1 else ""}')
if __name__ == '__main__':
asyncio.run(main(sys.argv[1:]))

16
pit_chance_to_output.py Normal file
View File

@ -0,0 +1,16 @@
import datetime
import logging
from db_calls_card_creation import *
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
log_level = logging.INFO
logging.basicConfig(
filename=f'{date}.log',
format='%(asctime)s - create-pitchers - %(levelname)s - %(message)s',
level=log_level
)
def process_pitcher_csv(filename: str, cardset: str, testing: bool = False):
cardset = Cardset.get_or_none(Cardset.set_title == cardset)