From 6580c1b431059139fdb6125d7d7aee06ffbeda40 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Tue, 17 Mar 2026 09:49:33 -0500 Subject: [PATCH] refactor: deduplicate pitcher formula and test constants Extract shared pitcher value computation into _pitcher_value() helper. Consolidate duplicated column lists and index helper in season stats tests. Co-Authored-By: Claude Opus 4.6 (1M context) --- app/services/formula_engine.py | 8 +- tests/test_season_stats_model.py | 180 +++++++++++++------------------ 2 files changed, 80 insertions(+), 108 deletions(-) diff --git a/app/services/formula_engine.py b/app/services/formula_engine.py index c2ae125..c863051 100644 --- a/app/services/formula_engine.py +++ b/app/services/formula_engine.py @@ -37,14 +37,18 @@ def compute_batter_value(stats) -> float: return float(stats.pa + tb * 2) +def _pitcher_value(stats) -> float: + return stats.outs / 3 + stats.strikeouts + + def compute_sp_value(stats) -> float: """IP + K where IP = outs / 3.""" - return stats.outs / 3 + stats.strikeouts + return _pitcher_value(stats) def compute_rp_value(stats) -> float: """IP + K (same formula as SP; thresholds differ).""" - return stats.outs / 3 + stats.strikeouts + return _pitcher_value(stats) # --------------------------------------------------------------------------- diff --git a/tests/test_season_stats_model.py b/tests/test_season_stats_model.py index 3876964..8ef3f6c 100644 --- a/tests/test_season_stats_model.py +++ b/tests/test_season_stats_model.py @@ -97,33 +97,75 @@ def make_pitching_stats(player, team, season=10, **kwargs): return PitchingSeasonStats.create(player=player, team=team, season=season, **kwargs) +# ── Shared column-list constants ───────────────────────────────────────────── + +_BATTING_STAT_COLS = [ + "games", + "pa", + "ab", + "hits", + "doubles", + "triples", + "hr", + "rbi", + "runs", + "bb", + "strikeouts", + "hbp", + "sac", + "ibb", + "gidp", + "sb", + "cs", +] + +_PITCHING_STAT_COLS = [ + "games", + "games_started", + "outs", + "strikeouts", + "bb", + "hits_allowed", + "runs_allowed", + "earned_runs", + "hr_allowed", + "hbp", + "wild_pitches", + "balks", + "wins", + "losses", + "holds", + "saves", + "blown_saves", +] + +_KEY_COLS = ["player", "team", "season"] +_META_COLS = ["last_game", "last_updated_at"] + + +# ── Shared index helper ─────────────────────────────────────────────────────── + + +def _get_index_columns(db_conn, table: str) -> set: + """Return a set of frozensets, each being the column set of one index.""" + indexes = db_conn.execute_sql(f"PRAGMA index_list({table})").fetchall() + result = set() + for idx in indexes: + idx_name = idx[1] + cols = db_conn.execute_sql(f"PRAGMA index_info({idx_name})").fetchall() + result.add(frozenset(col[2] for col in cols)) + return result + + # ── Unit: column completeness ──────────────────────────────────────────────── class TestBattingColumnCompleteness: """All required columns are present in BattingSeasonStats.""" - EXPECTED_COLS = [ - "games", - "pa", - "ab", - "hits", - "doubles", - "triples", - "hr", - "rbi", - "runs", - "bb", - "strikeouts", - "hbp", - "sac", - "ibb", - "gidp", - "sb", - "cs", - ] - KEY_COLS = ["player", "team", "season"] - META_COLS = ["last_game", "last_updated_at"] + EXPECTED_COLS = _BATTING_STAT_COLS + KEY_COLS = _KEY_COLS + META_COLS = _META_COLS def test_stat_columns_present(self): """All batting aggregate columns are present.""" @@ -147,27 +189,9 @@ class TestBattingColumnCompleteness: class TestPitchingColumnCompleteness: """All required columns are present in PitchingSeasonStats.""" - EXPECTED_COLS = [ - "games", - "games_started", - "outs", - "strikeouts", - "bb", - "hits_allowed", - "runs_allowed", - "earned_runs", - "hr_allowed", - "hbp", - "wild_pitches", - "balks", - "wins", - "losses", - "holds", - "saves", - "blown_saves", - ] - KEY_COLS = ["player", "team", "season"] - META_COLS = ["last_game", "last_updated_at"] + EXPECTED_COLS = _PITCHING_STAT_COLS + KEY_COLS = _KEY_COLS + META_COLS = _META_COLS def test_stat_columns_present(self): """All pitching aggregate columns are present.""" @@ -194,25 +218,7 @@ class TestPitchingColumnCompleteness: class TestBattingDefaultValues: """All integer stat columns default to 0; nullable meta fields default to None.""" - INT_STAT_COLS = [ - "games", - "pa", - "ab", - "hits", - "doubles", - "triples", - "hr", - "rbi", - "runs", - "bb", - "strikeouts", - "hbp", - "sac", - "ibb", - "gidp", - "sb", - "cs", - ] + INT_STAT_COLS = _BATTING_STAT_COLS def test_all_int_columns_default_to_zero(self): """Every integer stat column defaults to 0 on an unsaved instance.""" @@ -235,25 +241,7 @@ class TestBattingDefaultValues: class TestPitchingDefaultValues: """All integer stat columns default to 0; nullable meta fields default to None.""" - INT_STAT_COLS = [ - "games", - "games_started", - "outs", - "strikeouts", - "bb", - "hits_allowed", - "runs_allowed", - "earned_runs", - "hr_allowed", - "hbp", - "wild_pitches", - "balks", - "wins", - "losses", - "holds", - "saves", - "blown_saves", - ] + INT_STAT_COLS = _PITCHING_STAT_COLS def test_all_int_columns_default_to_zero(self): """Every integer stat column defaults to 0 on an unsaved instance.""" @@ -428,56 +416,36 @@ class TestPitchingDeltaUpdate: class TestBattingIndexExistence: """Required indexes exist on batting_season_stats.""" - def _get_index_columns(self, db_conn, table): - """Return a set of frozensets, each being the column set of one index.""" - indexes = db_conn.execute_sql(f"PRAGMA index_list({table})").fetchall() - result = set() - for idx in indexes: - idx_name = idx[1] - cols = db_conn.execute_sql(f"PRAGMA index_info({idx_name})").fetchall() - result.add(frozenset(col[2] for col in cols)) - return result - def test_unique_index_on_player_team_season(self, setup_test_db): """A unique index covering (player_id, team_id, season) exists.""" - index_sets = self._get_index_columns(setup_test_db, "batting_season_stats") + index_sets = _get_index_columns(setup_test_db, "batting_season_stats") assert frozenset({"player_id", "team_id", "season"}) in index_sets def test_index_on_team_season(self, setup_test_db): """An index covering (team_id, season) exists.""" - index_sets = self._get_index_columns(setup_test_db, "batting_season_stats") + index_sets = _get_index_columns(setup_test_db, "batting_season_stats") assert frozenset({"team_id", "season"}) in index_sets def test_index_on_player_season(self, setup_test_db): """An index covering (player_id, season) exists.""" - index_sets = self._get_index_columns(setup_test_db, "batting_season_stats") + index_sets = _get_index_columns(setup_test_db, "batting_season_stats") assert frozenset({"player_id", "season"}) in index_sets class TestPitchingIndexExistence: """Required indexes exist on pitching_season_stats.""" - def _get_index_columns(self, db_conn, table): - """Return a set of frozensets, each being the column set of one index.""" - indexes = db_conn.execute_sql(f"PRAGMA index_list({table})").fetchall() - result = set() - for idx in indexes: - idx_name = idx[1] - cols = db_conn.execute_sql(f"PRAGMA index_info({idx_name})").fetchall() - result.add(frozenset(col[2] for col in cols)) - return result - def test_unique_index_on_player_team_season(self, setup_test_db): """A unique index covering (player_id, team_id, season) exists.""" - index_sets = self._get_index_columns(setup_test_db, "pitching_season_stats") + index_sets = _get_index_columns(setup_test_db, "pitching_season_stats") assert frozenset({"player_id", "team_id", "season"}) in index_sets def test_index_on_team_season(self, setup_test_db): """An index covering (team_id, season) exists.""" - index_sets = self._get_index_columns(setup_test_db, "pitching_season_stats") + index_sets = _get_index_columns(setup_test_db, "pitching_season_stats") assert frozenset({"team_id", "season"}) in index_sets def test_index_on_player_season(self, setup_test_db): """An index covering (player_id, season) exists.""" - index_sets = self._get_index_columns(setup_test_db, "pitching_season_stats") + index_sets = _get_index_columns(setup_test_db, "pitching_season_stats") assert frozenset({"player_id", "season"}) in index_sets