hockey-blast-common-lib 0.1.50__py3-none-any.whl → 0.1.53__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.
- hockey_blast_common_lib/aggregate_goalie_stats.py +44 -25
- hockey_blast_common_lib/aggregate_h2h_stats.py +231 -0
- hockey_blast_common_lib/aggregate_human_stats.py +45 -26
- hockey_blast_common_lib/aggregate_referee_stats.py +44 -25
- hockey_blast_common_lib/aggregate_s2s_stats.py +143 -0
- hockey_blast_common_lib/aggregate_skater_stats.py +149 -36
- hockey_blast_common_lib/assign_skater_skill.py +27 -17
- hockey_blast_common_lib/h2h_models.py +107 -0
- hockey_blast_common_lib/hockey_blast_sample_backup.sql.gz +0 -0
- hockey_blast_common_lib/models.py +1 -0
- hockey_blast_common_lib/progress_utils.py +91 -0
- hockey_blast_common_lib/skills_propagation.py +56 -30
- hockey_blast_common_lib/stats_models.py +6 -0
- hockey_blast_common_lib/wsgi.py +1 -0
- {hockey_blast_common_lib-0.1.50.dist-info → hockey_blast_common_lib-0.1.53.dist-info}/METADATA +1 -1
- hockey_blast_common_lib-0.1.53.dist-info/RECORD +27 -0
- hockey_blast_common_lib-0.1.50.dist-info/RECORD +0 -23
- {hockey_blast_common_lib-0.1.50.dist-info → hockey_blast_common_lib-0.1.53.dist-info}/WHEEL +0 -0
- {hockey_blast_common_lib-0.1.50.dist-info → hockey_blast_common_lib-0.1.53.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
9
9
|
from hockey_blast_common_lib.models import Level, Division
|
10
10
|
from hockey_blast_common_lib.stats_models import LevelsGraphEdge, LevelStatsSkater, SkillValuePPGRatio
|
11
11
|
from hockey_blast_common_lib.db_connection import create_session
|
12
|
+
from hockey_blast_common_lib.progress_utils import create_progress_tracker
|
12
13
|
from sqlalchemy import func
|
13
14
|
|
14
15
|
import numpy as np
|
@@ -56,10 +57,11 @@ def reset_skill_values_in_divisions():
|
|
56
57
|
# If no match found, check each alternative name individually
|
57
58
|
skills = session.query(Level).filter(Level.org_id == division.org_id).all()
|
58
59
|
for s in skills:
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
if s.level_alternative_name: # Check if not None
|
61
|
+
alternative_names = s.level_alternative_name.split(',')
|
62
|
+
if div_level in alternative_names:
|
63
|
+
level = s
|
64
|
+
break
|
63
65
|
|
64
66
|
if level:
|
65
67
|
# Assign the skill_value and set skill_propagation_sequence to 0
|
@@ -70,19 +72,30 @@ def reset_skill_values_in_divisions():
|
|
70
72
|
level.skill_propagation_sequence = -1
|
71
73
|
level.skill_value = -1
|
72
74
|
else:
|
73
|
-
#
|
74
|
-
|
75
|
-
org_id
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
75
|
+
# Check if level already exists with this org_id/level_name combination
|
76
|
+
existing_level = session.query(Level).filter(
|
77
|
+
Level.org_id == division.org_id,
|
78
|
+
Level.level_name == division.level
|
79
|
+
).first()
|
80
|
+
|
81
|
+
if existing_level:
|
82
|
+
# Use existing level
|
83
|
+
division.level_id = existing_level.id
|
84
|
+
print(f"Using existing Level for Division {division.level}")
|
85
|
+
else:
|
86
|
+
# Add new Skill with values previously used for division
|
87
|
+
new_level = Level(
|
88
|
+
org_id=division.org_id,
|
89
|
+
skill_value=-1,
|
90
|
+
level_name=division.level,
|
91
|
+
level_alternative_name='',
|
92
|
+
is_seed=False,
|
93
|
+
skill_propagation_sequence=-1
|
94
|
+
)
|
95
|
+
session.add(new_level)
|
96
|
+
session.commit()
|
97
|
+
division.level_id = new_level.id
|
98
|
+
print(f"Created new Level for Division {division.level}")
|
86
99
|
|
87
100
|
# Commit the changes to the Division
|
88
101
|
session.commit()
|
@@ -113,14 +126,20 @@ def build_levels_graph_edges():
|
|
113
126
|
# Dictionary to store edges
|
114
127
|
edges = {}
|
115
128
|
|
116
|
-
# Build edges
|
129
|
+
# Build edges - batch load all levels first for performance
|
130
|
+
all_level_ids = list(level_human_stats.keys())
|
131
|
+
levels_dict = {level.id: level for level in session.query(Level).filter(Level.id.in_(all_level_ids)).all()}
|
132
|
+
|
117
133
|
total_levels = len(level_human_stats)
|
134
|
+
progress = create_progress_tracker(total_levels, "Building level graph edges")
|
118
135
|
processed_levels = 0
|
119
136
|
for from_level_id, from_humans in level_human_stats.items():
|
120
|
-
from_level =
|
137
|
+
from_level = levels_dict.get(from_level_id)
|
138
|
+
if not from_level:
|
139
|
+
continue
|
121
140
|
for to_level_id, to_humans in level_human_stats.items():
|
122
|
-
to_level =
|
123
|
-
if from_level.id >= to_level.id:
|
141
|
+
to_level = levels_dict.get(to_level_id)
|
142
|
+
if not to_level or from_level.id >= to_level.id:
|
124
143
|
continue
|
125
144
|
|
126
145
|
common_humans = set(from_humans.keys()) & set(to_humans.keys())
|
@@ -171,7 +190,7 @@ def build_levels_graph_edges():
|
|
171
190
|
edges[(from_level_id, to_level_id)] = edge
|
172
191
|
|
173
192
|
processed_levels += 1
|
174
|
-
|
193
|
+
progress.update(processed_levels)
|
175
194
|
|
176
195
|
# Insert edges into the database
|
177
196
|
for edge in edges.values():
|
@@ -313,12 +332,12 @@ def propagate_skill_levels(propagation_sequence):
|
|
313
332
|
# First confirm which way are we going here
|
314
333
|
if (ppg_ratio_edge < 1 and correlation.ppg_ratio > 1) or (ppg_ratio_edge > 1 and correlation.ppg_ratio < 1):
|
315
334
|
# Reverse the correlation
|
316
|
-
from_skill_value=correlation.to_skill_value
|
317
|
-
to_skill_value=correlation.from_skill_value
|
335
|
+
from_skill_value = correlation.to_skill_value
|
336
|
+
to_skill_value = correlation.from_skill_value
|
318
337
|
ppg_ratio_range = 1 / correlation.ppg_ratio
|
319
338
|
else:
|
320
|
-
from_skill_value=correlation.from_skill_value
|
321
|
-
to_skill_value=correlation.to_skill_value
|
339
|
+
from_skill_value = correlation.from_skill_value
|
340
|
+
to_skill_value = correlation.to_skill_value
|
322
341
|
ppg_ratio_range = correlation.ppg_ratio
|
323
342
|
|
324
343
|
# Now both ratios are either < 1 or > 1
|
@@ -345,6 +364,7 @@ def propagate_skill_levels(propagation_sequence):
|
|
345
364
|
suggested_skill_values[target_level_id].append(weighted_avg_skill_value)
|
346
365
|
|
347
366
|
# Update skill values for target levels
|
367
|
+
session.flush() # Ensure all previous changes are flushed before updates
|
348
368
|
for target_level_id, skill_values in suggested_skill_values.items():
|
349
369
|
skill_values = Config.discard_outliers(np.array(skill_values))
|
350
370
|
if len(skill_values) > 0:
|
@@ -352,10 +372,16 @@ def propagate_skill_levels(propagation_sequence):
|
|
352
372
|
avg_skill_value = max(avg_skill_value, 9.6)
|
353
373
|
if avg_skill_value < min_skill_value:
|
354
374
|
avg_skill_value = min_skill_value - 0.01
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
375
|
+
try:
|
376
|
+
session.query(Level).filter_by(id=target_level_id).update({
|
377
|
+
'skill_value': avg_skill_value,
|
378
|
+
'skill_propagation_sequence': propagation_sequence + 1
|
379
|
+
})
|
380
|
+
session.flush() # Flush each update individually
|
381
|
+
except Exception as e:
|
382
|
+
print(f"Error updating level {target_level_id}: {e}")
|
383
|
+
session.rollback()
|
384
|
+
continue
|
359
385
|
session.commit()
|
360
386
|
|
361
387
|
print(f"Skill levels have been propagated for sequence {propagation_sequence}.")
|
@@ -75,6 +75,10 @@ class BaseStatsSkater(db.Model):
|
|
75
75
|
gm_penalties_per_game = db.Column(db.Float, default=0.0)
|
76
76
|
gm_penalties_per_game_rank = db.Column(db.Integer, default=0)
|
77
77
|
total_in_rank = db.Column(db.Integer, default=0)
|
78
|
+
current_point_streak = db.Column(db.Integer, default=0)
|
79
|
+
current_point_streak_rank = db.Column(db.Integer, default=0)
|
80
|
+
current_point_streak_avg_points = db.Column(db.Float, default=0.0)
|
81
|
+
current_point_streak_avg_points_rank = db.Column(db.Integer, default=0)
|
78
82
|
first_game_id = db.Column(db.Integer, db.ForeignKey('games.id'))
|
79
83
|
last_game_id = db.Column(db.Integer, db.ForeignKey('games.id'))
|
80
84
|
|
@@ -87,6 +91,8 @@ class BaseStatsSkater(db.Model):
|
|
87
91
|
db.Index(f'idx_{cls.aggregation_type}_assists_per_game3', cls.get_aggregation_column(), 'assists_per_game'),
|
88
92
|
db.Index(f'idx_{cls.aggregation_type}_penalties_per_game3', cls.get_aggregation_column(), 'penalties_per_game'),
|
89
93
|
db.Index(f'idx_{cls.aggregation_type}_gm_penalties_per_game3', cls.get_aggregation_column(), 'gm_penalties_per_game'),
|
94
|
+
db.Index(f'idx_{cls.aggregation_type}_current_point_streak3', cls.get_aggregation_column(), 'current_point_streak'),
|
95
|
+
db.Index(f'idx_{cls.aggregation_type}_current_point_streak_avg_points3', cls.get_aggregation_column(), 'current_point_streak_avg_points'),
|
90
96
|
db.Index(f'idx_{cls.aggregation_type}_games_played3', cls.get_aggregation_column(), 'games_played')
|
91
97
|
)
|
92
98
|
|
hockey_blast_common_lib/wsgi.py
CHANGED
@@ -6,6 +6,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
6
6
|
from flask_migrate import Migrate
|
7
7
|
from flask import Flask
|
8
8
|
from hockey_blast_common_lib.models import *
|
9
|
+
from hockey_blast_common_lib.h2h_models import *
|
9
10
|
from hockey_blast_common_lib.stats_models import *
|
10
11
|
from hockey_blast_common_lib.stats_models import db
|
11
12
|
from hockey_blast_common_lib.db_connection import get_db_params
|
@@ -0,0 +1,27 @@
|
|
1
|
+
hockey_blast_common_lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
hockey_blast_common_lib/aggregate_all_stats.py,sha256=2bOj2BW0k3ZPQR1NH04upnkIfO9SastzTz7XwO3ujYo,1104
|
3
|
+
hockey_blast_common_lib/aggregate_goalie_stats.py,sha256=0pJOT6nKgFYmSTWA3HY-BKARgc7l6czqvzWfwNQMad0,14346
|
4
|
+
hockey_blast_common_lib/aggregate_h2h_stats.py,sha256=dC5TcJZGkpIQTiq3z40kOX6EjEhFbGv5EL0P1EClBQ0,11117
|
5
|
+
hockey_blast_common_lib/aggregate_human_stats.py,sha256=ku42TAjUIj49822noM8fEeB8GS4vFeCCNrLupTWmqzg,26043
|
6
|
+
hockey_blast_common_lib/aggregate_referee_stats.py,sha256=mUcTVQH9K4kwmIfgfGsnh_3AqX6Ia3RjfukkYuQas3I,13938
|
7
|
+
hockey_blast_common_lib/aggregate_s2s_stats.py,sha256=urYN0Q06twwLO-XWGlSMVAVOTVR_D2AWdmoGsxIYHXE,6737
|
8
|
+
hockey_blast_common_lib/aggregate_skater_stats.py,sha256=pA_2pDOGcJyEywISg2ySG8gFCuoLWwqw6a3Gm2wHLyo,23302
|
9
|
+
hockey_blast_common_lib/assign_skater_skill.py,sha256=8gAiqQm14QMFJNmdKb2jjaGyQlhzvVhXrqVvaZ84KDM,2499
|
10
|
+
hockey_blast_common_lib/db_connection.py,sha256=HvPxDvOj7j5H85RfslGvHVNevfg7mKCd0syJ6NX21mU,1890
|
11
|
+
hockey_blast_common_lib/dump_sample_db.sh,sha256=MY3lnzTXBoWd76-ZlZr9nWsKMEVgyRsUn-LZ2d1JWZs,810
|
12
|
+
hockey_blast_common_lib/h2h_models.py,sha256=0st4xoJO0U6ONfx3BV03BQvHjZE31e_PqZfphAJMoSU,7968
|
13
|
+
hockey_blast_common_lib/hockey_blast_sample_backup.sql.gz,sha256=AIB10IouLiSrxfaUZUN0zFjF_TzZ2D-Rjde9_yGTUTQ,4648897
|
14
|
+
hockey_blast_common_lib/models.py,sha256=PTIWyl7ygVQ_hbooqFWmnpOIKcJyyyTew_433IAMIFM,16559
|
15
|
+
hockey_blast_common_lib/options.py,sha256=2L4J9rKCKr58om34259D3_s7kbPdknMSwoo6IwTNnx0,849
|
16
|
+
hockey_blast_common_lib/progress_utils.py,sha256=H_zRFOsb2qQQpGw56wJghZ1nUe_m6zqGeR9hZ33Y1Uo,3229
|
17
|
+
hockey_blast_common_lib/restore_sample_db.sh,sha256=7W3lzRZeu9zXIu1Bvtnaw8EHc1ulHmFM4mMh86oUQJo,2205
|
18
|
+
hockey_blast_common_lib/skills_in_divisions.py,sha256=m-UEwMwn1KM7wOYvDstgsOEeH57M9V6yrkBoghzGYKE,7005
|
19
|
+
hockey_blast_common_lib/skills_propagation.py,sha256=CYpnjcJit01-QxkvVstNx1DhUo5ljZB_-o31vGzPT-A,17668
|
20
|
+
hockey_blast_common_lib/stats_models.py,sha256=uBNQSqCMXurzS-tD13OoV5WqurYYGHMZMHk1CeA5jgI,26104
|
21
|
+
hockey_blast_common_lib/stats_utils.py,sha256=DXsPO4jw8XsdRUN46TGF_IiBAfz3GCIVBswCGp5ELDk,284
|
22
|
+
hockey_blast_common_lib/utils.py,sha256=PduHp6HoI4sfr5HvJfQAaz7170dy5kTFVdIfWvBR-Jg,5874
|
23
|
+
hockey_blast_common_lib/wsgi.py,sha256=y3NxoJfWjdzX3iP7RGvDEer6zcnPyCanpqSgW1BlXgg,779
|
24
|
+
hockey_blast_common_lib-0.1.53.dist-info/METADATA,sha256=gQutIQ7tPRkjSSi-AcdJwikZt900Vhja3qU-owRdurI,318
|
25
|
+
hockey_blast_common_lib-0.1.53.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
26
|
+
hockey_blast_common_lib-0.1.53.dist-info/top_level.txt,sha256=wIR4LIkE40npoA2QlOdfCYlgFeGbsHR8Z6r0h46Vtgc,24
|
27
|
+
hockey_blast_common_lib-0.1.53.dist-info/RECORD,,
|
@@ -1,23 +0,0 @@
|
|
1
|
-
hockey_blast_common_lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
hockey_blast_common_lib/aggregate_all_stats.py,sha256=2bOj2BW0k3ZPQR1NH04upnkIfO9SastzTz7XwO3ujYo,1104
|
3
|
-
hockey_blast_common_lib/aggregate_goalie_stats.py,sha256=_9lP5xNX_QcIge-sHbqIlt7mKcFJBGVBbr33Rtf3LAY,12365
|
4
|
-
hockey_blast_common_lib/aggregate_human_stats.py,sha256=uBNzXbFsK5PhPg-5wjH2iuJ7VPpA7MWKFHx90rMbhjQ,24084
|
5
|
-
hockey_blast_common_lib/aggregate_referee_stats.py,sha256=dSl0LEpCzyzpD_tv8yw07NLBImo2RP_xuUQZK_p5kFs,12189
|
6
|
-
hockey_blast_common_lib/aggregate_skater_stats.py,sha256=MU4ICUUtDDKhdeb4sc0UPzjREwSB0rFZuJqRtIDedDU,17393
|
7
|
-
hockey_blast_common_lib/assign_skater_skill.py,sha256=p-0fbodGpM8BCjKHDpxNb7BH2FcIlBsJwON844KNrUY,1817
|
8
|
-
hockey_blast_common_lib/db_connection.py,sha256=HvPxDvOj7j5H85RfslGvHVNevfg7mKCd0syJ6NX21mU,1890
|
9
|
-
hockey_blast_common_lib/dump_sample_db.sh,sha256=MY3lnzTXBoWd76-ZlZr9nWsKMEVgyRsUn-LZ2d1JWZs,810
|
10
|
-
hockey_blast_common_lib/hockey_blast_sample_backup.sql.gz,sha256=Mg0lpOPFHwm8DnyiVEiLq3UbWa0eDan1ltV9ieFlyAc,4648905
|
11
|
-
hockey_blast_common_lib/models.py,sha256=nbJjypa2OBO5_fwjAbWVgBp4WDCuE-RtaELzJ9cvqB4,16468
|
12
|
-
hockey_blast_common_lib/options.py,sha256=2L4J9rKCKr58om34259D3_s7kbPdknMSwoo6IwTNnx0,849
|
13
|
-
hockey_blast_common_lib/restore_sample_db.sh,sha256=7W3lzRZeu9zXIu1Bvtnaw8EHc1ulHmFM4mMh86oUQJo,2205
|
14
|
-
hockey_blast_common_lib/skills_in_divisions.py,sha256=m-UEwMwn1KM7wOYvDstgsOEeH57M9V6yrkBoghzGYKE,7005
|
15
|
-
hockey_blast_common_lib/skills_propagation.py,sha256=x6yy7fJ6IX3YiHqiP_v7-p_S2Expb8JJ-mWuajEFBdY,16388
|
16
|
-
hockey_blast_common_lib/stats_models.py,sha256=NWigeIowIJU6o1Sk1cP08kEy4t594LZpecKUnl-O6as,25552
|
17
|
-
hockey_blast_common_lib/stats_utils.py,sha256=DXsPO4jw8XsdRUN46TGF_IiBAfz3GCIVBswCGp5ELDk,284
|
18
|
-
hockey_blast_common_lib/utils.py,sha256=PduHp6HoI4sfr5HvJfQAaz7170dy5kTFVdIfWvBR-Jg,5874
|
19
|
-
hockey_blast_common_lib/wsgi.py,sha256=7LGUzioigviJp-EUhSEaQcd4jBae0mxbkyBscQfZhlc,730
|
20
|
-
hockey_blast_common_lib-0.1.50.dist-info/METADATA,sha256=fd7SwCTv4w-PgDhuALLALEsq_w3nJXgy_RhD_APV9pE,318
|
21
|
-
hockey_blast_common_lib-0.1.50.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
22
|
-
hockey_blast_common_lib-0.1.50.dist-info/top_level.txt,sha256=wIR4LIkE40npoA2QlOdfCYlgFeGbsHR8Z6r0h46Vtgc,24
|
23
|
-
hockey_blast_common_lib-0.1.50.dist-info/RECORD,,
|
File without changes
|
{hockey_blast_common_lib-0.1.50.dist-info → hockey_blast_common_lib-0.1.53.dist-info}/top_level.txt
RENAMED
File without changes
|