Plays/pitching is functional
This commit is contained in:
parent
edde7a1b82
commit
25be95090a
@ -1,10 +1,11 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Response
|
||||
from typing import List, Optional, Literal
|
||||
import logging
|
||||
import pandas as pd
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from ..db_engine import db, StratPlay, StratGame, Team, Player, model_to_dict, chunked, fn, SQL, \
|
||||
complex_data_to_csv
|
||||
complex_data_to_csv, Decision
|
||||
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
|
||||
|
||||
logging.basicConfig(
|
||||
@ -128,7 +129,7 @@ async def get_plays(
|
||||
offense_team_id: list = Query(default=None), defense_team_id: list = Query(default=None),
|
||||
hit: Optional[int] = None, double: Optional[int] = None, triple: Optional[int] = None,
|
||||
homerun: Optional[int] = None, play_num: list = Query(default=None), game_type: list = Query(default=None),
|
||||
sb: Optional[int] = None, cs: Optional[int] = None, manager_id: list = Query(default=None),
|
||||
sb: Optional[int] = None, cs: Optional[int] = None, csv: Optional[bool] = False,
|
||||
run: Optional[int] = None, e_run: Optional[int] = None, rbi: list = Query(default=None),
|
||||
outs: list = Query(default=None), wild_pitch: Optional[int] = None, is_final_out: Optional[bool] = None,
|
||||
is_go_ahead: Optional[bool] = None, is_tied: Optional[bool] = None, is_new_inning: Optional[bool] = None,
|
||||
@ -204,11 +205,6 @@ async def get_plays(
|
||||
all_plays = all_plays.where(StratPlay.rbi << rbi)
|
||||
if outs is not None:
|
||||
all_plays = all_plays.where(StratPlay.outs << outs)
|
||||
if manager_id is not None:
|
||||
all_games = StratGame.select().where(
|
||||
(StratGame.away_manager_id << manager_id) | (StratGame.home_manager_id << manager_id)
|
||||
)
|
||||
all_plays = all_plays.where(StratPlay.game << all_games)
|
||||
if is_final_out is not None:
|
||||
all_plays = all_plays.where(StratPlay.starting_outs + StratPlay.outs == 3)
|
||||
if is_go_ahead is not None:
|
||||
@ -255,6 +251,67 @@ async def get_plays(
|
||||
|
||||
all_plays = all_plays.paginate(page_num, limit)
|
||||
|
||||
if csv:
|
||||
return_vals = [model_to_dict(x) for x in all_plays]
|
||||
for x in return_vals:
|
||||
x['game_id'] = x['game']['id']
|
||||
x['game_type'] = x['game']['game_type']
|
||||
x['batter_id'] = x['batter']['player_id']
|
||||
x['batter_name'] = x['batter']['p_name']
|
||||
x['batter_cardset'] = x['batter']['cardset']['name']
|
||||
x['batter_team_id'] = x['batter_team']['id']
|
||||
x['batter_team_abbrev'] = x['batter_team']['abbrev']
|
||||
x['pitcher_id'] = x['pitcher']['player_id']
|
||||
x['pitcher_name'] = x['pitcher']['p_name']
|
||||
x['pitcher_cardset'] = x['pitcher']['cardset']['name']
|
||||
x['pitcher_team_id'] = x['pitcher_team']['id']
|
||||
x['pitcher_team_abbrev'] = x['pitcher_team']['abbrev']
|
||||
|
||||
if x['catcher'] is not None:
|
||||
x['catcher_id'] = x['catcher']['player_id']
|
||||
x['catcher_name'] = x['catcher']['p_name']
|
||||
x['catcher_cardset'] = x['catcher']['cardset']['name']
|
||||
x['catcher_team_id'] = x['catcher_team']['id']
|
||||
x['catcher_team_abbrev'] = x['catcher_team']['abbrev']
|
||||
else:
|
||||
x['catcher_id'] = None
|
||||
x['catcher_name'] = None
|
||||
x['catcher_cardset'] = None
|
||||
x['catcher_team_id'] = None
|
||||
x['catcher_team_abbrev'] = None
|
||||
|
||||
if x['defender'] is not None:
|
||||
x['defender_id'] = x['defender']['player_id']
|
||||
x['defender_name'] = x['defender']['p_name']
|
||||
x['defender_cardset'] = x['defender']['cardset']['name']
|
||||
x['defender_team_id'] = x['defender_team']['id']
|
||||
x['defender_team_abbrev'] = x['defender_team']['abbrev']
|
||||
else:
|
||||
x['defender_id'] = None
|
||||
x['defender_name'] = None
|
||||
x['defender_cardset'] = None
|
||||
x['defender_team_id'] = None
|
||||
x['defender_team_abbrev'] = None
|
||||
|
||||
if x['runner'] is not None:
|
||||
x['runner_id'] = x['runner']['player_id']
|
||||
x['runner_name'] = x['runner']['p_name']
|
||||
x['runner_cardset'] = x['runner']['cardset']['name']
|
||||
x['runner_team_id'] = x['runner_team']['id']
|
||||
x['runner_team_abbrev'] = x['runner_team']['abbrev']
|
||||
else:
|
||||
x['runner_id'] = None
|
||||
x['runner_name'] = None
|
||||
x['runner_cardset'] = None
|
||||
x['runner_team_id'] = None
|
||||
x['runner_team_abbrev'] = None
|
||||
|
||||
del x['game'], x['batter'], x['batter_team'], x['pitcher'], x['pitcher_team'], x['catcher'], \
|
||||
x['catcher_team'], x['defender'], x['defender_team'], x['runner'], x['runner_team']
|
||||
|
||||
db.close()
|
||||
return Response(content=pd.DataFrame(return_vals).to_csv(index=False), media_type='text/csv')
|
||||
|
||||
return_plays = {
|
||||
'count': all_plays.count(),
|
||||
'plays': [model_to_dict(x, recurse=not short_output) for x in all_plays]
|
||||
@ -263,6 +320,507 @@ async def get_plays(
|
||||
return return_plays
|
||||
|
||||
|
||||
@router.get('/batting')
|
||||
async def get_batting_totals(
|
||||
season: list = Query(default=None), week: list = Query(default=None), position: list = Query(default=None),
|
||||
player_id: list = Query(default=None), min_wpa: Optional[float] = -999, max_wpa: Optional[float] = 999,
|
||||
group_by: Literal['team', 'player', 'playerteam', 'playergame', 'teamgame', 'league', 'gametype'] = 'player',
|
||||
min_pa: Optional[int] = 1, team_id: list = Query(default=None), inning: list = Query(default=None),
|
||||
obc: list = Query(default=None), risp: Optional[bool] = None, game_type: list = Query(default=None),
|
||||
page_num: Optional[int] = 1, sort: Optional[str] = None, limit: Optional[int] = 500,
|
||||
short_output: Optional[bool] = False, csv: Optional[bool] = False):
|
||||
season_games = StratGame.select()
|
||||
if season is not None:
|
||||
season_games = season_games.where(StratGame.season << season)
|
||||
if week is not None:
|
||||
season_games = season_games.where(StratGame.week << week)
|
||||
|
||||
bat_plays = (
|
||||
StratPlay
|
||||
.select(StratPlay.batter, StratPlay.game, fn.SUM(StratPlay.pa).alias('sum_pa'),
|
||||
fn.SUM(StratPlay.ab).alias('sum_ab'), fn.SUM(StratPlay.run).alias('sum_run'),
|
||||
fn.SUM(StratPlay.hit).alias('sum_hit'), fn.SUM(StratPlay.rbi).alias('sum_rbi'),
|
||||
fn.SUM(StratPlay.double).alias('sum_double'), fn.SUM(StratPlay.triple).alias('sum_triple'),
|
||||
fn.SUM(StratPlay.homerun).alias('sum_hr'), fn.SUM(StratPlay.bb).alias('sum_bb'),
|
||||
fn.SUM(StratPlay.so).alias('sum_so'), StratPlay.batter_team,
|
||||
fn.SUM(StratPlay.hbp).alias('sum_hbp'), fn.SUM(StratPlay.sac).alias('sum_sac'),
|
||||
fn.SUM(StratPlay.ibb).alias('sum_ibb'), fn.SUM(StratPlay.gidp).alias('sum_gidp'),
|
||||
fn.SUM(StratPlay.sb).alias('sum_sb'), fn.SUM(StratPlay.cs).alias('sum_cs'),
|
||||
fn.SUM(StratPlay.bphr).alias('sum_bphr'), fn.SUM(StratPlay.bpfo).alias('sum_bpfo'),
|
||||
fn.SUM(StratPlay.bp1b).alias('sum_bp1b'), fn.SUM(StratPlay.bplo).alias('sum_bplo'),
|
||||
fn.SUM(StratPlay.wpa).alias('sum_wpa'),
|
||||
fn.COUNT(StratPlay.on_first_final).filter(
|
||||
StratPlay.on_first_final.is_null(False) & (StratPlay.on_first_final != 4)).alias('count_lo1'),
|
||||
fn.COUNT(StratPlay.on_second_final).filter(
|
||||
StratPlay.on_second_final.is_null(False) & (StratPlay.on_second_final != 4)).alias('count_lo2'),
|
||||
fn.COUNT(StratPlay.on_third_final).filter(
|
||||
StratPlay.on_third_final.is_null(False) & (StratPlay.on_third_final != 4)).alias('count_lo3'),
|
||||
fn.COUNT(StratPlay.on_first).filter(StratPlay.on_first.is_null(False)).alias('count_runner1'),
|
||||
fn.COUNT(StratPlay.on_second).filter(StratPlay.on_second.is_null(False)).alias('count_runner2'),
|
||||
fn.COUNT(StratPlay.on_third).filter(StratPlay.on_third.is_null(False)).alias('count_runner3'),
|
||||
fn.COUNT(StratPlay.on_first_final).filter(
|
||||
StratPlay.on_first_final.is_null(False) & (StratPlay.on_first_final != 4) &
|
||||
(StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_lo1_3out'),
|
||||
fn.COUNT(StratPlay.on_second_final).filter(
|
||||
StratPlay.on_second_final.is_null(False) & (StratPlay.on_second_final != 4) &
|
||||
(StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_lo2_3out'),
|
||||
fn.COUNT(StratPlay.on_third_final).filter(
|
||||
StratPlay.on_third_final.is_null(False) & (StratPlay.on_third_final != 4) &
|
||||
(StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_lo3_3out')
|
||||
# fn.COUNT(StratPlay.on_first).filter(StratPlay.on_first.is_null(False) &
|
||||
# (StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_runner1_3out'),
|
||||
# fn.COUNT(StratPlay.on_second).filter(StratPlay.on_second.is_null(False) &
|
||||
# (StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_runner2_3out'),
|
||||
# fn.COUNT(StratPlay.on_third).filter(StratPlay.on_third.is_null(False) &
|
||||
# (StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_runner3_3out')
|
||||
)
|
||||
.where((StratPlay.game << season_games) & (StratPlay.batter.is_null(False)))
|
||||
.having(fn.SUM(StratPlay.pa) >= min_pa)
|
||||
)
|
||||
run_plays = (
|
||||
StratPlay
|
||||
.select(StratPlay.runner, StratPlay.runner_team, fn.SUM(StratPlay.sb).alias('sum_sb'),
|
||||
fn.SUM(StratPlay.cs).alias('sum_cs'), fn.SUM(StratPlay.pick_off).alias('sum_pick'),
|
||||
fn.SUM(StratPlay.wpa).alias('sum_wpa'))
|
||||
.where((StratPlay.game << season_games) & (StratPlay.runner.is_null(False)))
|
||||
)
|
||||
|
||||
if player_id is not None:
|
||||
all_players = Player.select().where(Player.id << player_id)
|
||||
bat_plays = bat_plays.where(StratPlay.batter << all_players)
|
||||
run_plays = run_plays.where(StratPlay.runner << all_players)
|
||||
if team_id is not None:
|
||||
all_teams = Team.select().where(Team.id << team_id)
|
||||
bat_plays = bat_plays.where(StratPlay.batter_team << all_teams)
|
||||
run_plays = run_plays.where(StratPlay.runner_team << all_teams)
|
||||
if position is not None:
|
||||
bat_plays = bat_plays.where(StratPlay.batter_pos << position)
|
||||
|
||||
if obc is not None:
|
||||
bat_plays = bat_plays.where(StratPlay.on_base_code << obc)
|
||||
if risp is not None:
|
||||
bat_plays = bat_plays.where(StratPlay.on_base_code << ['100', '101', '110', '111', '010', '011'])
|
||||
if inning is not None:
|
||||
bat_plays = bat_plays.where(StratPlay.inning_num << inning)
|
||||
if game_type is not None:
|
||||
all_types = [x.lower() for x in game_type]
|
||||
all_games = StratGame.select().where(fn.Lower(StratGame.game_type) << all_types)
|
||||
bat_plays = bat_plays.where(StratPlay.game << all_games)
|
||||
run_plays = run_plays.where(StratPlay.game << all_games)
|
||||
|
||||
if group_by is not None:
|
||||
if group_by == 'player':
|
||||
bat_plays = bat_plays.group_by(StratPlay.batter)
|
||||
run_plays = run_plays.group_by(StratPlay.runner)
|
||||
elif group_by == 'team':
|
||||
bat_plays = bat_plays.group_by(StratPlay.batter_team)
|
||||
run_plays = run_plays.group_by(StratPlay.runner_team)
|
||||
elif group_by == 'playerteam':
|
||||
bat_plays = bat_plays.group_by(StratPlay.batter, StratPlay.batter_team)
|
||||
run_plays = run_plays.group_by(StratPlay.runner, StratPlay.runner_team)
|
||||
elif group_by == 'playergame':
|
||||
bat_plays = bat_plays.group_by(StratPlay.batter, StratPlay.game)
|
||||
run_plays = run_plays.group_by(StratPlay.runner, StratPlay.game)
|
||||
elif group_by == 'teamgame':
|
||||
bat_plays = bat_plays.group_by(StratPlay.batter_team, StratPlay.game)
|
||||
run_plays = run_plays.group_by(StratPlay.runner_team, StratPlay.game)
|
||||
elif group_by == 'league':
|
||||
bat_plays = bat_plays.join(StratGame)
|
||||
bat_plays = bat_plays.group_by(StratPlay.game.season)
|
||||
run_plays = run_plays.join(StratGame)
|
||||
run_plays = run_plays.group_by(StratPlay.game.season)
|
||||
elif group_by == 'gametype':
|
||||
bat_plays = bat_plays.join(StratGame)
|
||||
bat_plays = bat_plays.group_by(StratPlay.game.game_type)
|
||||
run_plays = run_plays.join(StratGame)
|
||||
run_plays = run_plays.group_by(StratPlay.game.game_type)
|
||||
elif group_by == 'playerteamgametype':
|
||||
bat_plays = bat_plays.join(StratGame)
|
||||
bat_plays = bat_plays.group_by(StratPlay.batter, StratPlay.batter_team, StratPlay.game.game_type)
|
||||
run_plays = run_plays.join(StratGame)
|
||||
run_plays = run_plays.group_by(StratPlay.runner, StratPlay.runner_team, StratPlay.game.game_type)
|
||||
|
||||
if sort is not None:
|
||||
if sort == 'player':
|
||||
bat_plays = bat_plays.order_by(StratPlay.batter)
|
||||
run_plays = run_plays.order_by(StratPlay.runner)
|
||||
elif sort == 'team':
|
||||
bat_plays = bat_plays.order_by(StratPlay.batter_team)
|
||||
run_plays = run_plays.order_by(StratPlay.runner_team)
|
||||
elif sort == 'wpa-desc':
|
||||
bat_plays = bat_plays.order_by(SQL('sum_wpa').desc())
|
||||
elif sort == 'wpa-asc':
|
||||
bat_plays = bat_plays.order_by(SQL('sum_wpa').asc())
|
||||
elif sort == 'pa-desc':
|
||||
bat_plays = bat_plays.order_by(SQL('sum_pa').desc())
|
||||
elif sort == 'pa-asc':
|
||||
bat_plays = bat_plays.order_by(SQL('sum_pa').asc())
|
||||
elif sort == 'newest':
|
||||
bat_plays = bat_plays.order_by(StratPlay.game_id.desc(), StratPlay.play_num.desc())
|
||||
run_plays = run_plays.order_by(StratPlay.game_id.desc(), StratPlay.play_num.desc())
|
||||
elif sort == 'oldest':
|
||||
bat_plays = bat_plays.order_by(StratPlay.game_id, StratPlay.play_num)
|
||||
run_plays = run_plays.order_by(StratPlay.game_id, StratPlay.play_num)
|
||||
|
||||
if limit < 1:
|
||||
limit = 1
|
||||
elif limit > 500:
|
||||
limit = 500
|
||||
bat_plays = bat_plays.paginate(page_num, limit)
|
||||
|
||||
logging.info(f'bat_plays query: {bat_plays}')
|
||||
logging.info(f'run_plays query: {run_plays}')
|
||||
|
||||
return_stats = {
|
||||
'count': bat_plays.count(),
|
||||
'stats': []
|
||||
}
|
||||
|
||||
for x in bat_plays:
|
||||
this_run = run_plays.order_by(StratPlay.id)
|
||||
if 'player' in group_by:
|
||||
this_run = this_run.where(StratPlay.runner == x.batter)
|
||||
if 'game' in group_by:
|
||||
this_run = this_run.where(StratPlay.game == x.game)
|
||||
|
||||
if this_run.count() > 0:
|
||||
sum_sb = this_run[0].sum_sb
|
||||
sum_cs = this_run[0].sum_cs
|
||||
run_wpa = this_run[0].sum_wpa
|
||||
else:
|
||||
sum_sb = 0
|
||||
sum_cs = 0
|
||||
run_wpa = 0
|
||||
this_wpa = bat_plays.where(
|
||||
(StratPlay.wpa >= min_wpa) & (StratPlay.wpa <= max_wpa) & (StratPlay.batter == x.batter)
|
||||
)
|
||||
if this_wpa.count() > 0:
|
||||
sum_wpa = this_wpa[0].sum_wpa
|
||||
else:
|
||||
sum_wpa = 0
|
||||
|
||||
tot_ab = x.sum_ab if x.sum_ab > 0 else 1
|
||||
obp = (x.sum_hit + x.sum_bb + x.sum_hbp + x.sum_ibb) / x.sum_pa
|
||||
slg = (x.sum_hr * 4 + x.sum_triple * 3 + x.sum_double * 2 +
|
||||
(x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr)) / tot_ab
|
||||
|
||||
this_game = 'TOT'
|
||||
if group_by in ['playergame', 'teamgame']:
|
||||
this_game = x.game_id if short_output else model_to_dict(x.game, recurse=False)
|
||||
|
||||
lob_all_rate, lob_2outs_rate, rbi_rate = 0, 0, 0
|
||||
if x.count_runner1 + x.count_runner2 + x.count_runner3 > 0:
|
||||
lob_all_rate = (x.count_lo1 + x.count_lo2 + x.count_lo3) / \
|
||||
(x.count_runner1 + x.count_runner2 + x.count_runner3)
|
||||
rbi_rate = (x.sum_rbi - x.sum_hr) / (x.count_runner1 + x.count_runner2 + x.count_runner3)
|
||||
|
||||
return_stats['stats'].append({
|
||||
'player': x.batter_id if short_output else model_to_dict(x.batter, recurse=True, max_depth=1),
|
||||
'team': x.batter_team_id if short_output else model_to_dict(x.batter_team, recurse=True, max_depth=1),
|
||||
'pa': x.sum_pa,
|
||||
'ab': x.sum_ab,
|
||||
'run': x.sum_run,
|
||||
'hit': x.sum_hit,
|
||||
'rbi': x.sum_rbi,
|
||||
'double': x.sum_double,
|
||||
'triple': x.sum_triple,
|
||||
'hr': x.sum_hr,
|
||||
'bb': x.sum_bb,
|
||||
'so': x.sum_so,
|
||||
'hbp': x.sum_hbp,
|
||||
'sac': x.sum_sac,
|
||||
'ibb': x.sum_ibb,
|
||||
'gidp': x.sum_gidp,
|
||||
'sb': sum_sb,
|
||||
'cs': sum_cs,
|
||||
'bphr': x.sum_bphr,
|
||||
'bpfo': x.sum_bpfo,
|
||||
'bp1b': x.sum_bp1b,
|
||||
'bplo': x.sum_bplo,
|
||||
'wpa': sum_wpa + run_wpa,
|
||||
'avg': x.sum_hit / tot_ab,
|
||||
'obp': obp,
|
||||
'slg': slg,
|
||||
'ops': obp + slg,
|
||||
'woba': (.69 * x.sum_bb + .72 * x.sum_hbp + .89 * (x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr) +
|
||||
1.27 * x.sum_double + 1.62 * x.sum_triple + 2.1 * x.sum_hr) / max(x.sum_pa - x.sum_ibb, 1),
|
||||
'game': this_game,
|
||||
'lob_all': x.count_lo1 + x.count_lo2 + x.count_lo3,
|
||||
'lob_all_rate': lob_all_rate,
|
||||
'lob_2outs': x.count_lo1_3out + x.count_lo2_3out + x.count_lo3_3out,
|
||||
'rbi%': rbi_rate
|
||||
})
|
||||
|
||||
if csv:
|
||||
return_vals = return_stats['stats']
|
||||
if len(return_vals) == 0:
|
||||
return Response(content=pd.DataFrame().to_csv(index=False), media_type='text/csv')
|
||||
|
||||
for x in return_vals:
|
||||
x['player_id'] = x['player']['player_id']
|
||||
x['player_name'] = x['player']['p_name']
|
||||
x['player_cardset'] = x['player']['cardset']['name']
|
||||
x['team_id'] = x['team']['id']
|
||||
x['team_abbrev'] = x['team']['abbrev']
|
||||
del x['player'], x['team']
|
||||
|
||||
output = pd.DataFrame(return_vals)
|
||||
first = ['player_id', 'player_name', 'player_cardset', 'team_id', 'team_abbrev']
|
||||
exclude = first + ['lob_all', 'lob_all_rate', 'lob_2outs', 'rbi%']
|
||||
output = output[first + [col for col in output.columns if col not in exclude]]
|
||||
|
||||
db.close()
|
||||
return Response(content=pd.DataFrame(output).to_csv(index=False), media_type='text/csv')
|
||||
|
||||
db.close()
|
||||
return return_stats
|
||||
|
||||
|
||||
@router.get('/pitching')
|
||||
async def get_pitching_totals(
|
||||
season: list = Query(default=None), week: list = Query(default=None),
|
||||
s_type: Literal['regular', 'post', 'total', None] = None, player_id: list = Query(default=None),
|
||||
group_by: Literal['team', 'player', 'playerteam', 'playergame', 'teamgame', 'league', 'gametype'] = 'player',
|
||||
min_pa: Optional[int] = 1, team_id: list = Query(default=None), manager_id: list = Query(default=None),
|
||||
obc: list = Query(default=None), risp: Optional[bool] = None, inning: list = Query(default=None),
|
||||
page_num: Optional[int] = 1, game_type: list = Query(default=None), sort: Optional[str] = None,
|
||||
limit: Optional[int] = 500, short_output: Optional[bool] = False, csv: Optional[bool] = False):
|
||||
season_games = StratGame.select()
|
||||
if season is not None:
|
||||
season_games = season_games.where(StratGame.season << season)
|
||||
if week is not None and s_type is not None:
|
||||
raise HTTPException(status_code=400, detail=f'Week and s_type parameters cannot be used in the same query')
|
||||
if week is not None:
|
||||
season_games = season_games.where(StratGame.week << week)
|
||||
if s_type is not None:
|
||||
if s_type == 'regular':
|
||||
season_games = season_games.where(StratGame.week <= 18)
|
||||
elif s_type == 'post':
|
||||
season_games = season_games.where(StratGame.week > 18)
|
||||
if manager_id is not None:
|
||||
season_games = season_games.where(
|
||||
(StratGame.away_manager_id << manager_id) | (StratGame.home_manager_id << manager_id)
|
||||
)
|
||||
|
||||
pit_plays = (
|
||||
StratPlay
|
||||
.select(StratPlay.pitcher, StratPlay.pitcher_team, StratPlay.game, fn.SUM(StratPlay.pa).alias('sum_pa'),
|
||||
fn.SUM(StratPlay.ab).alias('sum_ab'), fn.SUM(StratPlay.run).alias('sum_run'),
|
||||
fn.SUM(StratPlay.hit).alias('sum_hit'), fn.SUM(StratPlay.rbi).alias('sum_rbi'),
|
||||
fn.SUM(StratPlay.double).alias('sum_double'), fn.SUM(StratPlay.triple).alias('sum_triple'),
|
||||
fn.SUM(StratPlay.homerun).alias('sum_hr'), fn.SUM(StratPlay.bb).alias('sum_bb'),
|
||||
fn.SUM(StratPlay.so).alias('sum_so'), fn.SUM(StratPlay.wpa).alias('sum_wpa'),
|
||||
fn.SUM(StratPlay.hbp).alias('sum_hbp'), fn.SUM(StratPlay.sac).alias('sum_sac'),
|
||||
fn.SUM(StratPlay.ibb).alias('sum_ibb'), fn.SUM(StratPlay.gidp).alias('sum_gidp'),
|
||||
fn.SUM(StratPlay.sb).alias('sum_sb'), fn.SUM(StratPlay.cs).alias('sum_cs'),
|
||||
fn.SUM(StratPlay.bphr).alias('sum_bphr'), fn.SUM(StratPlay.bpfo).alias('sum_bpfo'),
|
||||
fn.SUM(StratPlay.bp1b).alias('sum_bp1b'), fn.SUM(StratPlay.bplo).alias('sum_bplo'),
|
||||
fn.SUM(StratPlay.wild_pitch).alias('sum_wp'), fn.SUM(StratPlay.balk).alias('sum_balk'),
|
||||
fn.SUM(StratPlay.outs).alias('sum_outs'), fn.SUM(StratPlay.e_run).alias('sum_erun'),
|
||||
fn.SUM(StratPlay.re24).alias('sum_re24'),
|
||||
fn.COUNT(StratPlay.on_first_final).filter(
|
||||
StratPlay.on_first_final.is_null(False) & (StratPlay.on_first_final != 4)).alias('count_lo1'),
|
||||
fn.COUNT(StratPlay.on_second_final).filter(
|
||||
StratPlay.on_second_final.is_null(False) & (StratPlay.on_second_final != 4)).alias('count_lo2'),
|
||||
fn.COUNT(StratPlay.on_third_final).filter(
|
||||
StratPlay.on_third_final.is_null(False) & (StratPlay.on_third_final != 4)).alias('count_lo3'),
|
||||
fn.COUNT(StratPlay.on_first).filter(StratPlay.on_first.is_null(False)).alias('count_runner1'),
|
||||
fn.COUNT(StratPlay.on_second).filter(StratPlay.on_second.is_null(False)).alias('count_runner2'),
|
||||
fn.COUNT(StratPlay.on_third).filter(StratPlay.on_third.is_null(False)).alias('count_runner3'),
|
||||
fn.COUNT(StratPlay.on_first_final).filter(
|
||||
StratPlay.on_first_final.is_null(False) & (StratPlay.on_first_final != 4) &
|
||||
(StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_lo1_3out'),
|
||||
fn.COUNT(StratPlay.on_second_final).filter(
|
||||
StratPlay.on_second_final.is_null(False) & (StratPlay.on_second_final != 4) &
|
||||
(StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_lo2_3out'),
|
||||
fn.COUNT(StratPlay.on_third_final).filter(
|
||||
StratPlay.on_third_final.is_null(False) & (StratPlay.on_third_final != 4) &
|
||||
(StratPlay.starting_outs + StratPlay.outs == 3)).alias('count_lo3_3out'))
|
||||
.where((StratPlay.game << season_games) & (StratPlay.pitcher.is_null(False)))
|
||||
.having(fn.SUM(StratPlay.pa) >= min_pa)
|
||||
)
|
||||
all_dec = (
|
||||
Decision
|
||||
.select(Decision.pitcher, fn.SUM(Decision.win).alias('sum_win'), fn.SUM(Decision.loss).alias('sum_loss'),
|
||||
fn.SUM(Decision.hold).alias('sum_hold'), fn.SUM(Decision.is_save).alias('sum_save'),
|
||||
fn.SUM(Decision.b_save).alias('sum_b_save'), fn.SUM(Decision.irunners).alias('sum_irunners'),
|
||||
fn.SUM(Decision.irunners_scored).alias('sum_irun_scored'),
|
||||
fn.SUM(Decision.is_start).alias('sum_gs'), fn.COUNT(Decision.game).alias('sum_game'))
|
||||
.where(Decision.game << season_games)
|
||||
)
|
||||
|
||||
if player_id is not None:
|
||||
all_players = Player.select().where(Player.id << player_id)
|
||||
pit_plays = pit_plays.where(StratPlay.pitcher << all_players)
|
||||
if team_id is not None:
|
||||
all_teams = Team.select().where(Team.id << team_id)
|
||||
pit_plays = pit_plays.where(StratPlay.pitcher_team << all_teams)
|
||||
|
||||
if obc is not None:
|
||||
pit_plays = pit_plays.where(StratPlay.on_base_code << obc)
|
||||
if risp is not None:
|
||||
pit_plays = pit_plays.where(StratPlay.on_base_code << ['100', '101', '110', '111', '010', '011'])
|
||||
if inning is not None:
|
||||
pit_plays = pit_plays.where(StratPlay.inning_num << inning)
|
||||
if game_type is not None:
|
||||
all_types = [x.lower() for x in game_type]
|
||||
all_games = StratGame.select().where(fn.Lower(StratGame.game_type) << all_types)
|
||||
pit_plays = pit_plays.where(StratPlay.game << all_games)
|
||||
|
||||
if group_by is not None:
|
||||
if group_by == 'player':
|
||||
pit_plays = pit_plays.group_by(StratPlay.pitcher)
|
||||
elif group_by == 'team':
|
||||
pit_plays = pit_plays.group_by(StratPlay.pitcher_team)
|
||||
elif group_by == 'playerteam':
|
||||
pit_plays = pit_plays.group_by(StratPlay.pitcher, StratPlay.pitcher_team)
|
||||
elif group_by == 'playergame':
|
||||
pit_plays = pit_plays.group_by(StratPlay.pitcher, StratPlay.game)
|
||||
elif group_by == 'teamgame':
|
||||
pit_plays = pit_plays.group_by(StratPlay.pitcher_team, StratPlay.game)
|
||||
elif group_by == 'league':
|
||||
pit_plays = pit_plays.join(StratGame)
|
||||
pit_plays = pit_plays.group_by(StratPlay.game.season)
|
||||
elif group_by == 'gametype':
|
||||
pit_plays = pit_plays.join(StratGame)
|
||||
pit_plays = pit_plays.group_by(StratPlay.game.game_type)
|
||||
elif group_by == 'playerteamgametype':
|
||||
pit_plays = pit_plays.join(StratGame)
|
||||
pit_plays = pit_plays.group_by(StratPlay.pitcher, StratPlay.pitcher_team, StratPlay.game.game_type)
|
||||
if sort is not None:
|
||||
if sort == 'player':
|
||||
pit_plays = pit_plays.order_by(StratPlay.pitcher)
|
||||
elif sort == 'team':
|
||||
pit_plays = pit_plays.order_by(StratPlay.pitcher_team)
|
||||
elif sort == 'wpa-desc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_wpa').asc()) # functions seem reversed since pitcher plays negative
|
||||
elif sort == 'wpa-asc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_wpa').desc())
|
||||
elif sort == 're24-desc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_re24').asc()) # functions seem reversed since pitcher plays negative
|
||||
elif sort == 're24-asc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_re24').desc())
|
||||
elif sort == 'ip-desc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_outs').desc())
|
||||
elif sort == 'ip-asc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_outs').asc())
|
||||
elif sort == 'game-desc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_game').desc())
|
||||
elif sort == 'game-asc':
|
||||
pit_plays = pit_plays.order_by(SQL('sum_game').asc())
|
||||
elif sort == 'newest':
|
||||
pit_plays = pit_plays.order_by(StratPlay.game_id.desc(), StratPlay.play_num.desc())
|
||||
elif sort == 'oldest':
|
||||
pit_plays = pit_plays.order_by(StratPlay.game_id, StratPlay.play_num)
|
||||
|
||||
if limit < 1:
|
||||
limit = 1
|
||||
elif limit > 500:
|
||||
limit = 500
|
||||
pit_plays = pit_plays.paginate(page_num, limit)
|
||||
|
||||
return_stats = {
|
||||
'count': pit_plays.count(),
|
||||
'stats': []
|
||||
}
|
||||
|
||||
for x in pit_plays:
|
||||
this_dec = all_dec.where(Decision.pitcher == x.pitcher)
|
||||
tot_outs = x.sum_outs if x.sum_outs > 0 else 1
|
||||
obp = (x.sum_hit + x.sum_bb + x.sum_hbp + x.sum_ibb) / x.sum_pa
|
||||
slg = (x.sum_hr * 4 + x.sum_triple * 3 + x.sum_double * 2 +
|
||||
(x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr)) / max(x.sum_ab, 1)
|
||||
tot_bb = 0.1 if x.sum_bb == 0 else x.sum_bb
|
||||
|
||||
this_game = 'TOT'
|
||||
if group_by in ['playergame', 'teamgame']:
|
||||
this_game = x.game_id if short_output else model_to_dict(x.game, recurse=False)
|
||||
this_dec = all_dec.where((Decision.pitcher == x.pitcher) & (Decision.game == x.game))
|
||||
|
||||
lob_all_rate, lob_2outs_rate, rbi_rate = 0, 0, 0
|
||||
if x.count_runner1 + x.count_runner2 + x.count_runner3 > 0:
|
||||
lob_all_rate = (x.count_lo1 + x.count_lo2 + x.count_lo3) / \
|
||||
(x.count_runner1 + x.count_runner2 + x.count_runner3)
|
||||
rbi_rate = (x.sum_rbi - x.sum_hr) / (x.count_runner1 + x.count_runner2 + x.count_runner3)
|
||||
|
||||
return_stats['stats'].append({
|
||||
'player': x.pitcher_id if short_output else model_to_dict(x.pitcher),
|
||||
'team': x.pitcher_team_id if short_output else model_to_dict(x.pitcher_team),
|
||||
'tbf': x.sum_pa,
|
||||
'outs': x.sum_outs,
|
||||
'games': this_dec[0].sum_game,
|
||||
'gs': this_dec[0].sum_gs,
|
||||
'win': this_dec[0].sum_win,
|
||||
'loss': this_dec[0].sum_loss,
|
||||
'hold': this_dec[0].sum_hold,
|
||||
'save': this_dec[0].sum_save,
|
||||
'bsave': this_dec[0].sum_b_save,
|
||||
'ir': this_dec[0].sum_irunners,
|
||||
'ir_sc': this_dec[0].sum_irun_scored,
|
||||
'ab': x.sum_ab,
|
||||
'run': x.sum_run,
|
||||
'e_run': x.sum_erun,
|
||||
'hits': x.sum_hit,
|
||||
'double': x.sum_double,
|
||||
'triple': x.sum_triple,
|
||||
'hr': x.sum_hr,
|
||||
'bb': x.sum_bb,
|
||||
'so': x.sum_so,
|
||||
'hbp': x.sum_hbp,
|
||||
'sac': x.sum_sac,
|
||||
'ibb': x.sum_ibb,
|
||||
'gidp': x.sum_gidp,
|
||||
'sb': x.sum_sb,
|
||||
'cs': x.sum_cs,
|
||||
'bphr': x.sum_bphr,
|
||||
'bpfo': x.sum_bpfo,
|
||||
'bp1b': x.sum_bp1b,
|
||||
'bplo': x.sum_bplo,
|
||||
'wp': x.sum_wp,
|
||||
'balk': x.sum_balk,
|
||||
'wpa': x.sum_wpa * -1,
|
||||
're24': x.sum_re24 * -1,
|
||||
'era': (x.sum_erun * 27) / tot_outs,
|
||||
'whip': ((x.sum_bb + x.sum_hit + x.sum_ibb) * 3) / tot_outs,
|
||||
'avg': x.sum_hit / max(x.sum_ab, 1),
|
||||
'obp': obp,
|
||||
'slg': slg,
|
||||
'ops': obp + slg,
|
||||
'woba': (.69 * x.sum_bb + .72 * x.sum_hbp + .89 * (x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr) +
|
||||
1.27 * x.sum_double + 1.62 * x.sum_triple + 2.1 * x.sum_hr) / max(x.sum_pa - x.sum_ibb, 1),
|
||||
'k/9': x.sum_so * 9 / (tot_outs / 3),
|
||||
'bb/9': x.sum_bb * 9 / (tot_outs / 3),
|
||||
'k/bb': x.sum_so / tot_bb,
|
||||
'game': this_game,
|
||||
'lob_2outs': x.count_lo1_3out + x.count_lo2_3out + x.count_lo3_3out,
|
||||
'rbi%': rbi_rate
|
||||
})
|
||||
db.close()
|
||||
|
||||
if csv:
|
||||
return_vals = return_stats['stats']
|
||||
if len(return_vals) == 0:
|
||||
return Response(content=pd.DataFrame().to_csv(index=False), media_type='text/csv')
|
||||
|
||||
for x in return_vals:
|
||||
x['player_id'] = x['player']['player_id']
|
||||
x['player_name'] = x['player']['p_name']
|
||||
x['player_cardset'] = x['player']['cardset']['name']
|
||||
x['team_id'] = x['team']['id']
|
||||
x['team_abbrev'] = x['team']['abbrev']
|
||||
del x['player'], x['team']
|
||||
|
||||
output = pd.DataFrame(return_vals)
|
||||
first = ['player_id', 'player_name', 'player_cardset', 'team_id', 'team_abbrev']
|
||||
exclude = first + ['lob_2outs', 'rbi%']
|
||||
output = output[first + [col for col in output.columns if col not in exclude]]
|
||||
|
||||
db.close()
|
||||
return Response(content=pd.DataFrame(output).to_csv(index=False), media_type='text/csv')
|
||||
|
||||
return return_stats
|
||||
|
||||
|
||||
@router.get('/{play_id}')
|
||||
async def get_one_play(play_id: int):
|
||||
if StratPlay.get_or_none(StratPlay.id == play_id) is None:
|
||||
|
||||
@ -208,6 +208,7 @@ async def get_team_lineup(team_id: int, difficulty_name: str, pitcher_name: str,
|
||||
vr_ops = vr_ratings.obp + vr_ratings.slg
|
||||
return model_to_dict(vl_ratings), model_to_dict(vr_ratings), (vl_ops + vr_ops + min(vl_ops, vr_ops)) / 3
|
||||
|
||||
# IDEA: Rank guys by their bat per-position and take the best one that meets a threshold of defensive ability
|
||||
for position in starting_nine.keys():
|
||||
if position == 'DH':
|
||||
# all_bcards = BattingCard.select().where(BattingCard.player << legal_players)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user