hockey-blast-common-lib 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,229 @@
1
+ import sys, os
2
+ from datetime import datetime, timedelta
3
+ import sqlalchemy
4
+ from models import Game, Penalty
5
+ from stats_models import OrgStatsReferee, DivisionStatsReferee,OrgStatsWeeklyReferee, OrgStatsDailyReferee, DivisionStatsWeeklyReferee, DivisionStatsDailyReferee
6
+ from db_connection import create_session
7
+ from sqlalchemy.sql import func, case
8
+ from options import parse_args, MIN_GAMES_FOR_ORG_STATS, MIN_GAMES_FOR_DIVISION_STATS, not_human_names
9
+ from utils import get_org_id_from_alias, get_human_ids_by_names, get_division_ids_for_last_season_in_all_leagues
10
+
11
+ def aggregate_referee_stats(session, aggregation_type, aggregation_id, names_to_filter_out, aggregation_window=None):
12
+ human_ids_to_filter = get_human_ids_by_names(session, names_to_filter_out)
13
+
14
+ if aggregation_type == 'org':
15
+ if aggregation_window == 'Daily':
16
+ StatsModel = OrgStatsDailyReferee
17
+ elif aggregation_window == 'Weekly':
18
+ StatsModel = OrgStatsWeeklyReferee
19
+ else:
20
+ StatsModel = OrgStatsReferee
21
+ min_games = MIN_GAMES_FOR_ORG_STATS
22
+ filter_condition = Game.org_id == aggregation_id
23
+ elif aggregation_type == 'division':
24
+ if aggregation_window == 'Daily':
25
+ StatsModel = DivisionStatsDailyReferee
26
+ elif aggregation_window == 'Weekly':
27
+ StatsModel = DivisionStatsWeeklyReferee
28
+ else:
29
+ StatsModel = DivisionStatsReferee
30
+ min_games = MIN_GAMES_FOR_DIVISION_STATS
31
+ filter_condition = Game.division_id == aggregation_id
32
+ else:
33
+ raise ValueError("Invalid aggregation type")
34
+
35
+ # Apply aggregation window filter
36
+ if aggregation_window:
37
+ last_game_datetime = session.query(func.max(func.concat(Game.date, ' ', Game.time))).filter(filter_condition, Game.status.like('Final%')).scalar()
38
+ if last_game_datetime:
39
+ last_game_datetime = datetime.strptime(last_game_datetime, '%Y-%m-%d %H:%M:%S')
40
+ if aggregation_window == 'Daily':
41
+ start_datetime = last_game_datetime - timedelta(days=1)
42
+ elif aggregation_window == 'Weekly':
43
+ start_datetime = last_game_datetime - timedelta(weeks=1)
44
+ else:
45
+ start_datetime = None
46
+ if start_datetime:
47
+ game_window_filter = func.cast(func.concat(Game.date, ' ', Game.time), sqlalchemy.types.TIMESTAMP).between(start_datetime, last_game_datetime)
48
+ filter_condition = filter_condition & game_window_filter
49
+
50
+ # Delete existing items from the stats table
51
+ session.query(StatsModel).filter(StatsModel.aggregation_id == aggregation_id).delete()
52
+ session.commit()
53
+
54
+ # Aggregate games reffed for each referee
55
+ games_reffed_stats = session.query(
56
+ Game.referee_1_id.label('human_id'),
57
+ func.count(Game.id).label('games_reffed'),
58
+ func.array_agg(Game.id).label('game_ids')
59
+ ).filter(filter_condition).group_by(Game.referee_1_id).all()
60
+
61
+ games_reffed_stats_2 = session.query(
62
+ Game.referee_2_id.label('human_id'),
63
+ func.count(Game.id).label('games_reffed'),
64
+ func.array_agg(Game.id).label('game_ids')
65
+ ).filter(filter_condition).group_by(Game.referee_2_id).all()
66
+
67
+ # Aggregate penalties given for each referee
68
+ penalties_given_stats = session.query(
69
+ Game.id.label('game_id'),
70
+ Game.referee_1_id,
71
+ Game.referee_2_id,
72
+ func.count(Penalty.id).label('penalties_given'),
73
+ func.sum(case((func.lower(Penalty.penalty_minutes) == 'gm', 1), else_=0)).label('gm_given')
74
+ ).join(Game, Game.id == Penalty.game_id).filter(filter_condition).group_by(Game.id, Game.referee_1_id, Game.referee_2_id).all()
75
+
76
+ # Combine the results
77
+ stats_dict = {}
78
+ for stat in games_reffed_stats:
79
+ if stat.human_id in human_ids_to_filter:
80
+ continue
81
+ key = (aggregation_id, stat.human_id)
82
+ stats_dict[key] = {
83
+ 'games_reffed': stat.games_reffed,
84
+ 'penalties_given': 0,
85
+ 'gm_given': 0,
86
+ 'penalties_per_game': 0.0,
87
+ 'gm_per_game': 0.0,
88
+ 'game_ids': stat.game_ids,
89
+ 'first_game_id': None,
90
+ 'last_game_id': None
91
+ }
92
+
93
+ for stat in games_reffed_stats_2:
94
+ if stat.human_id in human_ids_to_filter:
95
+ continue
96
+ key = (aggregation_id, stat.human_id)
97
+ if key not in stats_dict:
98
+ stats_dict[key] = {
99
+ 'games_reffed': stat.games_reffed,
100
+ 'penalties_given': 0,
101
+ 'gm_given': 0,
102
+ 'penalties_per_game': 0.0,
103
+ 'gm_per_game': 0.0,
104
+ 'game_ids': stat.game_ids,
105
+ 'first_game_id': None,
106
+ 'last_game_id': None
107
+ }
108
+ else:
109
+ stats_dict[key]['games_reffed'] += stat.games_reffed
110
+ stats_dict[key]['game_ids'].extend(stat.game_ids)
111
+
112
+ for stat in penalties_given_stats:
113
+ if stat.referee_1_id and stat.referee_1_id not in human_ids_to_filter:
114
+ key = (aggregation_id, stat.referee_1_id)
115
+ if key not in stats_dict:
116
+ stats_dict[key] = {
117
+ 'games_reffed': 0,
118
+ 'penalties_given': stat.penalties_given / 2,
119
+ 'gm_given': stat.gm_given / 2,
120
+ 'penalties_per_game': 0.0,
121
+ 'gm_per_game': 0.0,
122
+ 'game_ids': [stat.game_id],
123
+ 'first_game_id': None,
124
+ 'last_game_id': None
125
+ }
126
+ else:
127
+ stats_dict[key]['penalties_given'] += stat.penalties_given / 2
128
+ stats_dict[key]['gm_given'] += stat.gm_given / 2
129
+ stats_dict[key]['game_ids'].append(stat.game_id)
130
+
131
+ if stat.referee_2_id and stat.referee_2_id not in human_ids_to_filter:
132
+ key = (aggregation_id, stat.referee_2_id)
133
+ if key not in stats_dict:
134
+ stats_dict[key] = {
135
+ 'games_reffed': 0,
136
+ 'penalties_given': stat.penalties_given / 2,
137
+ 'gm_given': stat.gm_given / 2,
138
+ 'penalties_per_game': 0.0,
139
+ 'gm_per_game': 0.0,
140
+ 'game_ids': [stat.game_id],
141
+ 'first_game_id': None,
142
+ 'last_game_id': None
143
+ }
144
+ else:
145
+ stats_dict[key]['penalties_given'] += stat.penalties_given / 2
146
+ stats_dict[key]['gm_given'] += stat.gm_given / 2
147
+ stats_dict[key]['game_ids'].append(stat.game_id)
148
+
149
+ # Calculate per game stats
150
+ for key, stat in stats_dict.items():
151
+ if stat['games_reffed'] > 0:
152
+ stat['penalties_per_game'] = stat['penalties_given'] / stat['games_reffed']
153
+ stat['gm_per_game'] = stat['gm_given'] / stat['games_reffed']
154
+
155
+ # Ensure all keys have valid human_id values
156
+ stats_dict = {key: value for key, value in stats_dict.items() if key[1] is not None}
157
+
158
+ # Populate first_game_id and last_game_id
159
+ for key, stat in stats_dict.items():
160
+ all_game_ids = stat['game_ids']
161
+ if all_game_ids:
162
+ first_game = session.query(Game).filter(Game.id.in_(all_game_ids)).order_by(Game.date, Game.time).first()
163
+ last_game = session.query(Game).filter(Game.id.in_(all_game_ids)).order_by(Game.date.desc(), Game.time.desc()).first()
164
+ stat['first_game_id'] = first_game.id if first_game else None
165
+ stat['last_game_id'] = last_game.id if last_game else None
166
+
167
+ # Calculate total_in_rank
168
+ total_in_rank = len(stats_dict)
169
+
170
+ # Assign ranks
171
+ def assign_ranks(stats_dict, field):
172
+ sorted_stats = sorted(stats_dict.items(), key=lambda x: x[1][field], reverse=True)
173
+ for rank, (key, stat) in enumerate(sorted_stats, start=1):
174
+ stats_dict[key][f'{field}_rank'] = rank
175
+
176
+ assign_ranks(stats_dict, 'games_reffed')
177
+ assign_ranks(stats_dict, 'penalties_given')
178
+ assign_ranks(stats_dict, 'penalties_per_game')
179
+ assign_ranks(stats_dict, 'gm_given')
180
+ assign_ranks(stats_dict, 'gm_per_game')
181
+
182
+ # Insert aggregated stats into the appropriate table with progress output
183
+ total_items = len(stats_dict)
184
+ batch_size = 1000
185
+ for i, (key, stat) in enumerate(stats_dict.items(), 1):
186
+ aggregation_id, human_id = key
187
+ if stat['games_reffed'] < min_games:
188
+ continue
189
+ referee_stat = StatsModel(
190
+ aggregation_id=aggregation_id,
191
+ human_id=human_id,
192
+ games_reffed=stat['games_reffed'],
193
+ penalties_given=stat['penalties_given'],
194
+ penalties_per_game=stat['penalties_per_game'],
195
+ gm_given=stat['gm_given'],
196
+ gm_per_game=stat['gm_per_game'],
197
+ games_reffed_rank=stat['games_reffed_rank'],
198
+ penalties_given_rank=stat['penalties_given_rank'],
199
+ penalties_per_game_rank=stat['penalties_per_game_rank'],
200
+ gm_given_rank=stat['gm_given_rank'],
201
+ gm_per_game_rank=stat['gm_per_game_rank'],
202
+ total_in_rank=total_in_rank,
203
+ first_game_id=stat['first_game_id'],
204
+ last_game_id=stat['last_game_id']
205
+ )
206
+ session.add(referee_stat)
207
+ # Commit in batches
208
+ if i % batch_size == 0:
209
+ session.commit()
210
+ print(f"\r{i}/{total_items} ({(i/total_items)*100:.2f}%)", end="")
211
+ session.commit()
212
+ print(f"\r{total_items}/{total_items} (100.00%)")
213
+ print("\nDone.")
214
+
215
+ # Example usage
216
+ if __name__ == "__main__":
217
+ args = parse_args()
218
+ org_alias = args.org
219
+ session = create_session("boss")
220
+ org_id = get_org_id_from_alias(session, org_alias)
221
+ division_ids = get_division_ids_for_last_season_in_all_leagues(session, org_id)
222
+ print(f"Aggregating referee stats for {len(division_ids)} divisions in {org_alias}...")
223
+ for division_id in division_ids:
224
+ aggregate_referee_stats(session, aggregation_type='division', aggregation_id=division_id, names_to_filter_out=not_human_names)
225
+ aggregate_referee_stats(session, aggregation_type='division', aggregation_id=division_id, names_to_filter_out=not_human_names, aggregation_window='Weekly')
226
+ aggregate_referee_stats(session, aggregation_type='division', aggregation_id=division_id, names_to_filter_out=not_human_names, aggregation_window='Daily')
227
+ aggregate_referee_stats(session, aggregation_type='org', aggregation_id=org_id, names_to_filter_out=not_human_names)
228
+ aggregate_referee_stats(session, aggregation_type='org', aggregation_id=org_id, names_to_filter_out=not_human_names, aggregation_window='Weekly')
229
+ aggregate_referee_stats(session, aggregation_type='org', aggregation_id=org_id, names_to_filter_out=not_human_names, aggregation_window='Daily')
@@ -0,0 +1,323 @@
1
+ import sys, os
2
+ from datetime import datetime, timedelta
3
+ import sqlalchemy
4
+ from options import not_human_names
5
+
6
+ from models import Game, Goal, Penalty, GameRoster
7
+ from stats_models import OrgStatsSkater, DivisionStatsSkater, OrgStatsWeeklySkater, OrgStatsDailySkater, DivisionStatsWeeklySkater, DivisionStatsDailySkater
8
+ from db_connection import create_session
9
+ from sqlalchemy.sql import func, case
10
+ from options import parse_args, MIN_GAMES_FOR_ORG_STATS, MIN_GAMES_FOR_DIVISION_STATS
11
+ from utils import get_org_id_from_alias, get_human_ids_by_names, get_division_ids_for_last_season_in_all_leagues
12
+ from sqlalchemy import func, case, and_
13
+
14
+ def aggregate_skater_stats(session, aggregation_type, aggregation_id, names_to_filter_out, filter_human_id=None, aggregation_window=None):
15
+ human_ids_to_filter = get_human_ids_by_names(session, names_to_filter_out)
16
+
17
+ if aggregation_type == 'org':
18
+ if aggregation_window == 'Daily':
19
+ StatsModel = OrgStatsDailySkater
20
+ elif aggregation_window == 'Weekly':
21
+ StatsModel = OrgStatsWeeklySkater
22
+ else:
23
+ StatsModel = OrgStatsSkater
24
+ min_games = MIN_GAMES_FOR_ORG_STATS
25
+ filter_condition = Game.org_id == aggregation_id
26
+ elif aggregation_type == 'division':
27
+ if aggregation_window == 'Daily':
28
+ StatsModel = DivisionStatsDailySkater
29
+ elif aggregation_window == 'Weekly':
30
+ StatsModel = DivisionStatsWeeklySkater
31
+ else:
32
+ StatsModel = DivisionStatsSkater
33
+ min_games = MIN_GAMES_FOR_DIVISION_STATS
34
+ filter_condition = Game.division_id == aggregation_id
35
+ else:
36
+ raise ValueError("Invalid aggregation type")
37
+
38
+ # Apply aggregation window filter
39
+ if aggregation_window:
40
+ last_game_datetime = session.query(func.max(func.concat(Game.date, ' ', Game.time))).filter(filter_condition, Game.status.like('Final%')).scalar()
41
+ if last_game_datetime:
42
+ last_game_datetime = datetime.strptime(last_game_datetime, '%Y-%m-%d %H:%M:%S')
43
+ if aggregation_window == 'Daily':
44
+ start_datetime = last_game_datetime - timedelta(days=1)
45
+ elif aggregation_window == 'Weekly':
46
+ start_datetime = last_game_datetime - timedelta(weeks=1)
47
+ else:
48
+ start_datetime = None
49
+ if start_datetime:
50
+ game_window_filter = func.cast(func.concat(Game.date, ' ', Game.time), sqlalchemy.types.TIMESTAMP).between(start_datetime, last_game_datetime)
51
+ filter_condition = filter_condition & game_window_filter
52
+
53
+ # Delete existing items from the stats table
54
+ session.query(StatsModel).filter(StatsModel.aggregation_id == aggregation_id).delete()
55
+ session.commit()
56
+
57
+ # Filter for specific human_id if provided
58
+ human_filter = []
59
+ if filter_human_id:
60
+ human_filter = [GameRoster.human_id == filter_human_id]
61
+
62
+ # Aggregate games played for each human in each division, excluding goalies
63
+ games_played_stats = session.query(
64
+ Game.org_id,
65
+ GameRoster.human_id,
66
+ func.count(Game.id).label('games_played'),
67
+ func.array_agg(Game.id).label('game_ids')
68
+ ).join(GameRoster, Game.id == GameRoster.game_id).filter(filter_condition, ~GameRoster.role.ilike('g'), *human_filter).group_by(Game.org_id, GameRoster.human_id).all()
69
+
70
+ # Aggregate goals for each human in each division, excluding goalies
71
+ goals_stats = session.query(
72
+ Game.org_id,
73
+ Goal.goal_scorer_id.label('human_id'),
74
+ func.count(Goal.id).label('goals'),
75
+ func.array_agg(Goal.game_id).label('goal_game_ids')
76
+ ).join(Game, Game.id == Goal.game_id).join(GameRoster, and_(Game.id == GameRoster.game_id, Goal.goal_scorer_id == GameRoster.human_id)).filter(filter_condition, ~GameRoster.role.ilike('g'), *human_filter).group_by(Game.org_id, Goal.goal_scorer_id).all()
77
+
78
+ # Aggregate assists for each human in each division, excluding goalies
79
+ assists_stats = session.query(
80
+ Game.org_id,
81
+ Goal.assist_1_id.label('human_id'),
82
+ func.count(Goal.id).label('assists'),
83
+ func.array_agg(Goal.game_id).label('assist_game_ids')
84
+ ).join(Game, Game.id == Goal.game_id).join(GameRoster, and_(Game.id == GameRoster.game_id, Goal.assist_1_id == GameRoster.human_id)).filter(filter_condition, ~GameRoster.role.ilike('g'), *human_filter).group_by(Game.org_id, Goal.assist_1_id).all()
85
+
86
+ assists_stats_2 = session.query(
87
+ Game.org_id,
88
+ Goal.assist_2_id.label('human_id'),
89
+ func.count(Goal.id).label('assists'),
90
+ func.array_agg(Goal.game_id).label('assist_2_game_ids')
91
+ ).join(Game, Game.id == Goal.game_id).join(GameRoster, and_(Game.id == GameRoster.game_id, Goal.assist_2_id == GameRoster.human_id)).filter(filter_condition, ~GameRoster.role.ilike('g'), *human_filter).group_by(Game.org_id, Goal.assist_2_id).all()
92
+
93
+ # Aggregate penalties for each human in each division, excluding goalies
94
+ penalties_stats = session.query(
95
+ Game.org_id,
96
+ Penalty.penalized_player_id.label('human_id'),
97
+ func.count(Penalty.id).label('penalties'),
98
+ func.array_agg(Penalty.game_id).label('penalty_game_ids')
99
+ ).join(Game, Game.id == Penalty.game_id).join(GameRoster, and_(Game.id == GameRoster.game_id, Penalty.penalized_player_id == GameRoster.human_id)).filter(filter_condition, ~GameRoster.role.ilike('g'), *human_filter).group_by(Game.org_id, Penalty.penalized_player_id).all()
100
+
101
+ # Combine the results
102
+ stats_dict = {}
103
+ for stat in games_played_stats:
104
+ if stat.human_id in human_ids_to_filter:
105
+ continue
106
+ key = (aggregation_id, stat.human_id)
107
+ stats_dict[key] = {
108
+ 'games_played': stat.games_played,
109
+ 'goals': 0,
110
+ 'assists': 0,
111
+ 'penalties': 0,
112
+ 'points': 0, # Initialize points
113
+ 'goals_per_game': 0.0,
114
+ 'points_per_game': 0.0,
115
+ 'assists_per_game': 0.0,
116
+ 'penalties_per_game': 0.0,
117
+ 'game_ids': stat.game_ids,
118
+ 'first_game_id': None,
119
+ 'last_game_id': None
120
+ }
121
+
122
+ for stat in goals_stats:
123
+ if stat.human_id in human_ids_to_filter:
124
+ continue
125
+ key = (aggregation_id, stat.human_id)
126
+ if key not in stats_dict:
127
+ stats_dict[key] = {
128
+ 'games_played': 0,
129
+ 'goals': stat.goals,
130
+ 'assists': 0,
131
+ 'penalties': 0,
132
+ 'points': stat.goals, # Initialize points with goals
133
+ 'goals_per_game': 0.0,
134
+ 'points_per_game': 0.0,
135
+ 'assists_per_game': 0.0,
136
+ 'penalties_per_game': 0.0,
137
+ 'game_ids': [],
138
+ 'first_game_id': None,
139
+ 'last_game_id': None
140
+ }
141
+ else:
142
+ stats_dict[key]['goals'] += stat.goals
143
+ stats_dict[key]['points'] += stat.goals # Update points
144
+
145
+ for stat in assists_stats:
146
+ if stat.human_id in human_ids_to_filter:
147
+ continue
148
+ key = (aggregation_id, stat.human_id)
149
+ if key not in stats_dict:
150
+ stats_dict[key] = {
151
+ 'games_played': 0,
152
+ 'goals': 0,
153
+ 'assists': stat.assists,
154
+ 'penalties': 0,
155
+ 'points': stat.assists, # Initialize points with assists
156
+ 'goals_per_game': 0.0,
157
+ 'points_per_game': 0.0,
158
+ 'assists_per_game': 0.0,
159
+ 'penalties_per_game': 0.0,
160
+ 'game_ids': [],
161
+ 'first_game_id': None,
162
+ 'last_game_id': None
163
+ }
164
+ else:
165
+ stats_dict[key]['assists'] += stat.assists
166
+ stats_dict[key]['points'] += stat.assists # Update points
167
+
168
+ for stat in assists_stats_2:
169
+ if stat.human_id in human_ids_to_filter:
170
+ continue
171
+ key = (aggregation_id, stat.human_id)
172
+ if key not in stats_dict:
173
+ stats_dict[key] = {
174
+ 'games_played': 0,
175
+ 'goals': 0,
176
+ 'assists': stat.assists,
177
+ 'penalties': 0,
178
+ 'points': stat.assists, # Initialize points with assists
179
+ 'goals_per_game': 0.0,
180
+ 'points_per_game': 0.0,
181
+ 'assists_per_game': 0.0,
182
+ 'penalties_per_game': 0.0,
183
+ 'game_ids': [],
184
+ 'first_game_id': None,
185
+ 'last_game_id': None
186
+ }
187
+ else:
188
+ stats_dict[key]['assists'] += stat.assists
189
+ stats_dict[key]['points'] += stat.assists # Update points
190
+
191
+ for stat in penalties_stats:
192
+ if stat.human_id in human_ids_to_filter:
193
+ continue
194
+ key = (aggregation_id, stat.human_id)
195
+ if key not in stats_dict:
196
+ stats_dict[key] = {
197
+ 'games_played': 0,
198
+ 'goals': 0,
199
+ 'assists': 0,
200
+ 'penalties': stat.penalties,
201
+ 'points': 0, # Initialize points
202
+ 'goals_per_game': 0.0,
203
+ 'points_per_game': 0.0,
204
+ 'assists_per_game': 0.0,
205
+ 'penalties_per_game': 0.0,
206
+ 'game_ids': [],
207
+ 'first_game_id': None,
208
+ 'last_game_id': None
209
+ }
210
+ else:
211
+ stats_dict[key]['penalties'] += stat.penalties
212
+
213
+ # Calculate per game stats
214
+ for key, stat in stats_dict.items():
215
+ if stat['games_played'] > 0:
216
+ stat['goals_per_game'] = stat['goals'] / stat['games_played']
217
+ stat['points_per_game'] = stat['points'] / stat['games_played']
218
+ stat['assists_per_game'] = stat['assists'] / stat['games_played']
219
+ stat['penalties_per_game'] = stat['penalties'] / stat['games_played']
220
+
221
+ # Ensure all keys have valid human_id values
222
+ stats_dict = {key: value for key, value in stats_dict.items() if key[1] is not None}
223
+
224
+ # Populate first_game_id and last_game_id
225
+ for key, stat in stats_dict.items():
226
+ all_game_ids = stat['game_ids']
227
+ if all_game_ids:
228
+ first_game = session.query(Game).filter(Game.id.in_(all_game_ids)).order_by(Game.date, Game.time).first()
229
+ last_game = session.query(Game).filter(Game.id.in_(all_game_ids)).order_by(Game.date.desc(), Game.time.desc()).first()
230
+ stat['first_game_id'] = first_game.id if first_game else None
231
+ stat['last_game_id'] = last_game.id if last_game else None
232
+
233
+ # Debug output for totals if filter_human_id is provided
234
+ if filter_human_id:
235
+ for key, stat in stats_dict.items():
236
+ if key[1] == filter_human_id:
237
+ print(f"Human ID: {filter_human_id}")
238
+ print(f"Total Games Played: {stat['games_played']}")
239
+ print(f"Total Goals: {stat['goals']}")
240
+ print(f"Total Assists: {stat['assists']}")
241
+ print(f"Total Penalties: {stat['penalties']}")
242
+
243
+ # Calculate total_in_rank
244
+ total_in_rank = len(stats_dict)
245
+
246
+ # Assign ranks
247
+ def assign_ranks(stats_dict, field):
248
+ sorted_stats = sorted(stats_dict.items(), key=lambda x: x[1][field], reverse=True)
249
+ for rank, (key, stat) in enumerate(sorted_stats, start=1):
250
+ stats_dict[key][f'{field}_rank'] = rank
251
+
252
+ assign_ranks(stats_dict, 'games_played')
253
+ assign_ranks(stats_dict, 'goals')
254
+ assign_ranks(stats_dict, 'assists')
255
+ assign_ranks(stats_dict, 'points')
256
+ assign_ranks(stats_dict, 'penalties')
257
+ assign_ranks(stats_dict, 'goals_per_game')
258
+ assign_ranks(stats_dict, 'points_per_game')
259
+ assign_ranks(stats_dict, 'assists_per_game')
260
+ assign_ranks(stats_dict, 'penalties_per_game')
261
+
262
+ # Insert aggregated stats into the appropriate table with progress output
263
+ total_items = len(stats_dict)
264
+ batch_size = 1000
265
+ for i, (key, stat) in enumerate(stats_dict.items(), 1):
266
+ aggregation_id, human_id = key
267
+ if stat['games_played'] < min_games:
268
+ continue
269
+ goals_per_game = stat['goals'] / stat['games_played'] if stat['games_played'] > 0 else 0.0
270
+ points_per_game = (stat['goals'] + stat['assists']) / stat['games_played'] if stat['games_played'] > 0 else 0.0
271
+ assists_per_game = stat['assists'] / stat['games_played'] if stat['games_played'] > 0 else 0.0
272
+ penalties_per_game = stat['penalties'] / stat['games_played'] if stat['games_played'] > 0 else 0.0
273
+ skater_stat = StatsModel(
274
+ aggregation_id=aggregation_id,
275
+ human_id=human_id,
276
+ games_played=stat['games_played'],
277
+ goals=stat['goals'],
278
+ assists=stat['assists'],
279
+ points=stat['goals'] + stat['assists'],
280
+ penalties=stat['penalties'],
281
+ goals_per_game=goals_per_game,
282
+ points_per_game=points_per_game,
283
+ assists_per_game=assists_per_game,
284
+ penalties_per_game=penalties_per_game,
285
+ games_played_rank=stat['games_played_rank'],
286
+ goals_rank=stat['goals_rank'],
287
+ assists_rank=stat['assists_rank'],
288
+ points_rank=stat['points_rank'],
289
+ penalties_rank=stat['penalties_rank'],
290
+ goals_per_game_rank=stat['goals_per_game_rank'],
291
+ points_per_game_rank=stat['points_per_game_rank'],
292
+ assists_per_game_rank=stat['assists_per_game_rank'],
293
+ penalties_per_game_rank=stat['penalties_per_game_rank'],
294
+ total_in_rank=total_in_rank,
295
+ first_game_id=stat['first_game_id'],
296
+ last_game_id=stat['last_game_id']
297
+ )
298
+ session.add(skater_stat)
299
+ # Commit in batches
300
+ if i % batch_size == 0:
301
+ session.commit()
302
+ print(f"\r{i}/{total_items} ({(i/total_items)*100:.2f}%)", end="")
303
+ session.commit()
304
+ print(f"\r{total_items}/{total_items} (100.00%)")
305
+ print("\nDone.")
306
+
307
+ # Example usage
308
+ if __name__ == "__main__":
309
+ args = parse_args()
310
+ org_alias = args.org
311
+ session = create_session("boss")
312
+ org_id = get_org_id_from_alias(session, org_alias)
313
+
314
+ division_ids = get_division_ids_for_last_season_in_all_leagues(session, org_id)
315
+ print(f"Aggregating skater stats for {len(division_ids)} divisions in {org_alias}...")
316
+ for division_id in division_ids:
317
+ aggregate_skater_stats(session, aggregation_type='division', aggregation_id=division_id, names_to_filter_out=not_human_names, filter_human_id=None)
318
+ aggregate_skater_stats(session, aggregation_type='division', aggregation_id=division_id, names_to_filter_out=not_human_names, filter_human_id=None, aggregation_window='Weekly')
319
+ aggregate_skater_stats(session, aggregation_type='division', aggregation_id=division_id, names_to_filter_out=not_human_names, filter_human_id=None, aggregation_window='Daily')
320
+
321
+ aggregate_skater_stats(session, aggregation_type='org', aggregation_id=org_id, names_to_filter_out=not_human_names, filter_human_id=None)
322
+ aggregate_skater_stats(session, aggregation_type='org', aggregation_id=org_id, names_to_filter_out=not_human_names, filter_human_id=None, aggregation_window='Weekly')
323
+ aggregate_skater_stats(session, aggregation_type='org', aggregation_id=org_id, names_to_filter_out=not_human_names, filter_human_id=None, aggregation_window='Daily')
@@ -11,6 +11,15 @@ DB_PARAMS = {
11
11
  "host": "localhost",
12
12
  "port": 5432
13
13
  },
14
+
15
+ "boss": {
16
+ "dbname": "hockey_blast",
17
+ "user": "boss",
18
+ "password": "WrongPassword",
19
+ "host": "localhost",
20
+ "port": 5432
21
+ },
22
+
14
23
  }
15
24
 
16
25
  def get_db_params(config_name):
@@ -0,0 +1,22 @@
1
+ import argparse
2
+
3
+ MAX_HUMAN_SEARCH_RESULTS = 25
4
+ MAX_TEAM_SEARCH_RESULTS = 25
5
+ MIN_GAMES_FOR_ORG_STATS = 1
6
+ MIN_GAMES_FOR_DIVISION_STATS = 1
7
+
8
+ orgs = {'caha', 'sharksice', 'tvice'}
9
+
10
+ not_human_names = [
11
+ ("Away", None, None),
12
+ (None, "Unknown", None),
13
+ ("Not", None , None),
14
+ (None , None, "Goalie")
15
+ ]
16
+
17
+ def parse_args():
18
+ parser = argparse.ArgumentParser(description="Process data for a specific organization.")
19
+ parser.add_argument("org", choices=orgs, help="The organization to process (e.g., 'caha', 'sharksice', 'tvice').")
20
+ parser.add_argument("--reprocess", action="store_true", help="Reprocess existing data.")
21
+ parser.add_argument("--pre_process", action="store_true", help="Pre-Process existing data.")
22
+ return parser.parse_args()