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.
@@ -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
- alternative_names = s.level_alternative_name.split(',')
60
- if div_level in alternative_names:
61
- level = s
62
- break
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
- # Add new Skill with values previously used for division
74
- new_level = Level(
75
- org_id=division.org_id,
76
- skill_value=-1,
77
- level_name=division.level,
78
- level_alternative_name='',
79
- is_seed=False,
80
- skill_propagation_sequence=-1
81
- )
82
- session.add(new_level)
83
- session.commit()
84
- division.skill_id = new_level.id
85
- print(f"Created new Level for Division {division.level}")
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 = session.query(Level).filter_by(id=from_level_id).first()
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 = session.query(Level).filter_by(id=to_level_id).first()
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
- print(f"\rProcessed {processed_levels}/{total_levels} levels ({(processed_levels/total_levels)*100:.2f}%)", end="")
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
- session.query(Level).filter_by(id=target_level_id).update({
356
- 'skill_value': avg_skill_value,
357
- 'skill_propagation_sequence': propagation_sequence + 1
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
 
@@ -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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hockey-blast-common-lib
3
- Version: 0.1.50
3
+ Version: 0.1.53
4
4
  Summary: Common library for shared functionality and DB models
5
5
  Author: Pavel Kletskov
6
6
  Author-email: kletskov@gmail.com
@@ -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,,