diff --git a/app/routers_v3/stratplay.py b/app/routers_v3/stratplay.py index e23ac8c..5d56667 100644 --- a/app/routers_v3/stratplay.py +++ b/app/routers_v3/stratplay.py @@ -130,6 +130,7 @@ async def get_plays( 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, + min_wpa: Optional[float] = None, max_wpa: Optional[float] = None, short_output: Optional[bool] = False, sort: Optional[str] = None, limit: Optional[int] = 200): all_plays = StratPlay.select() @@ -217,6 +218,10 @@ async def get_plays( (StratPlay.on_first_final == 4) | (StratPlay.on_second_final == 4) | (StratPlay.on_third_final == 4) | (StratPlay.batter_final == 4) ) + if min_wpa is not None: + all_plays = all_plays.where(StratPlay.wpa >= min_wpa) + if max_wpa is not None: + all_plays = all_plays.where(StratPlay.wpa <= max_wpa) if limit > 5000: limit = 5000 @@ -225,8 +230,12 @@ async def get_plays( if sort == 'wpa-desc': all_plays = all_plays.order_by(-fn.ABS(StratPlay.wpa)) - if sort == 'wpa-asc': + elif sort == 'wpa-asc': all_plays = all_plays.order_by(fn.ABS(StratPlay.wpa)) + elif sort == 'newest': + all_plays = all_plays.order_by(StratPlay.game_id.desc(), StratPlay.play_num.desc()) + elif sort == 'oldest': + all_plays = all_plays.order_by(StratPlay.game_id, StratPlay.play_num) all_plays = all_plays.limit(limit) @@ -242,7 +251,8 @@ async def get_plays( async def get_batting_totals( season: list = Query(default=None), week: list = Query(default=None), s_type: Literal['regular', 'post', 'total', None] = None, position: list = Query(default=None), - player_id: list = Query(default=None), group_by: Literal['team', 'player', 'playerteam'] = 'player', + player_id: list = Query(default=None), min_wpa: Optional[float] = -999, max_wpa: Optional[float] = 999, + group_by: Literal['team', 'player', 'playerteam', 'playergame', 'teamgame'] = '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, sort: Optional[str] = None, limit: Optional[int] = None, short_output: Optional[bool] = False): @@ -258,7 +268,7 @@ async def get_batting_totals( bat_plays = ( StratPlay - .select(StratPlay.batter, fn.SUM(StratPlay.pa).alias('sum_pa'), + .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'), @@ -319,6 +329,14 @@ async def get_batting_totals( bat_plays = bat_plays.group_by(StratPlay.batter, StratPlay.batter_team) run_plays = run_plays.group_by(StratPlay.runner, StratPlay.runner_team) def_plays = def_plays.group_by(StratPlay.defender, StratPlay.defender_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) + def_plays = def_plays.group_by(StratPlay.defender, 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) + def_plays = def_plays.group_by(StratPlay.defender_team, StratPlay.game) if sort is not None: if sort == 'player': bat_plays = bat_plays.order_by(StratPlay.batter) @@ -336,6 +354,10 @@ async def get_batting_totals( 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()) + elif sort == 'oldest': + bat_plays = bat_plays.order_by(StratPlay.game_id, StratPlay.play_num) if limit is not None: if limit < 1: limit = 1 @@ -354,16 +376,28 @@ async def get_batting_totals( if this_run.count() > 0: sum_sb = this_run[0].sum_sb sum_cs = this_run[0].sum_cs - sum_wpa = this_run[0].sum_wpa + 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) + return_stats['stats'].append({ 'player': x.batter_id if short_output else model_to_dict(x.batter, recurse=False), 'team': x.batter_team_id if short_output else model_to_dict(x.batter_team, recurse=False), @@ -387,13 +421,14 @@ async def get_batting_totals( 'bpfo': x.sum_bpfo, 'bp1b': x.sum_bp1b, 'bplo': x.sum_bplo, - 'wpa': x.sum_wpa + sum_wpa, + '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) / (x.sum_pa - x.sum_ibb) + 1.27 * x.sum_double + 1.62 * x.sum_triple + 2.1 * x.sum_hr) / (x.sum_pa - x.sum_ibb), + 'game': this_game }) # Get Running Stats @@ -407,8 +442,8 @@ async def get_batting_totals( @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'] = 'player', + s_type: Literal['regular', 'post', 'total', None] = None, player_id: list = Query(default=None), + group_by: Literal['team', 'player', 'playerteam', 'playergame', 'teamgame'] = '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, sort: Optional[str] = None, limit: Optional[int] = None, short_output: Optional[bool] = False): @@ -424,7 +459,7 @@ async def get_pitching_totals( pit_plays = ( StratPlay - .select(StratPlay.pitcher, StratPlay.pitcher_team, fn.SUM(StratPlay.pa).alias('sum_pa'), + .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.double).alias('sum_double'), fn.SUM(StratPlay.triple).alias('sum_triple'), @@ -469,6 +504,10 @@ async def get_pitching_totals( 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) if sort is not None: if sort == 'player': pit_plays = pit_plays.order_by(StratPlay.pitcher) @@ -486,6 +525,10 @@ async def get_pitching_totals( 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 is not None: if limit < 1: limit = 1 @@ -503,6 +546,12 @@ async def get_pitching_totals( 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)) / x.sum_ab 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)) + return_stats['stats'].append({ 'player': x.pitcher_id if short_output else model_to_dict(x.pitcher, recurse=False), 'team': x.pitcher_team_id if short_output else model_to_dict(x.pitcher_team, recurse=False), @@ -549,7 +598,8 @@ async def get_pitching_totals( 1.27 * x.sum_double + 1.62 * x.sum_triple + 2.1 * x.sum_hr) / (x.sum_pa - x.sum_ibb), '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 + 'k/bb': x.sum_so / tot_bb, + 'game': this_game }) db.close() return return_stats