wsba-hockey 1.1.3__py3-none-any.whl → 1.1.6__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.
wsba_hockey/wsba_main.py CHANGED
@@ -4,16 +4,16 @@ import requests as rs
4
4
  import pandas as pd
5
5
  import time
6
6
  from datetime import datetime, timedelta, date
7
- from .tools.scraping import *
8
- from .tools.xg_model import *
9
- from .tools.agg import *
10
- from .tools.plotting import *
7
+ from wsba_hockey.tools.scraping import *
8
+ from wsba_hockey.tools.xg_model import *
9
+ from wsba_hockey.tools.agg import *
10
+ from wsba_hockey.tools.plotting import *
11
11
 
12
12
  ### WSBA HOCKEY ###
13
13
  ## Provided below are all integral functions in the WSBA Hockey Python package. ##
14
14
 
15
15
  ## GLOBAL VARIABLES ##
16
- seasons = [
16
+ SEASONS = [
17
17
  '20072008',
18
18
  '20082009',
19
19
  '20092010',
@@ -34,7 +34,7 @@ seasons = [
34
34
  '20242025'
35
35
  ]
36
36
 
37
- convert_seasons = {'2007': '20072008',
37
+ CONVERT_SEASONS = {'2007': '20072008',
38
38
  '2008': '20082009',
39
39
  '2009': '20092010',
40
40
  '2010': '20102011',
@@ -53,17 +53,17 @@ convert_seasons = {'2007': '20072008',
53
53
  '2023': '20232024',
54
54
  '2024': '20242025'}
55
55
 
56
- convert_team_abbr = {'L.A':'LAK',
56
+ CONVERT_TEAM_ABBR = {'L.A':'LAK',
57
57
  'N.J':'NJD',
58
58
  'S.J':'SJS',
59
59
  'T.B':'TBL',
60
60
  'PHX':'ARI'}
61
61
 
62
- per_sixty = ['Fi','xGi','Gi','A1','A2','P1','P','OZF','NZF','DZF','FF','FA','xGF','xGA','GF','GA','CF','CA','HF','HA','Give','Take','Penl','Penl2','Penl5','Draw','Block']
62
+ PER_SIXTY = ['Fi','xGi','Gi','A1','A2','P1','P','Si','OZF','NZF','DZF','FF','FA','xGF','xGA','GF','GA','SF','SA','CF','CA','HF','HA','Give','Take','Penl','Penl2','Penl5','Draw','Block','GSAx']
63
63
 
64
64
  #Some games in the API are specifically known to cause errors in scraping.
65
65
  #This list is updated as frequently as necessary
66
- known_probs = {
66
+ KNOWN_PROBS = {
67
67
  '2007020011':'Missing shifts data for game between Chicago and Minnesota.',
68
68
  '2007021178':'Game between the Bruins and Sabres is missing data after the second period, for some reason.',
69
69
  '2008020259':'HTML data is completely missing for this game.',
@@ -79,11 +79,11 @@ known_probs = {
79
79
  '2019020876':'Due to the frightening collapse of Blues defensemen Jay Bouwmeester, a game on February 2nd, 2020 between the Ducks and Blues was postponed. \nWhen the game resumed, Ducks defensemen Hampus Lindholm, who assisted on a goal in the inital game, did not play in the resumed match.'
80
80
  }
81
81
 
82
- shot_types = ['wrist','deflected','tip-in','slap','backhand','snap','wrap-around','poke','bat','cradle','between-legs']
82
+ SHOT_TYPES = ['wrist','deflected','tip-in','slap','backhand','snap','wrap-around','poke','bat','cradle','between-legs']
83
83
 
84
- new = 2024
84
+ NEW = 2024
85
85
 
86
- standings_end = {
86
+ STANDINGS_END = {
87
87
  '20072008':'04-06',
88
88
  '20082009':'04-12',
89
89
  '20092010':'04-11',
@@ -104,12 +104,12 @@ standings_end = {
104
104
  '20242025':'04-17'
105
105
  }
106
106
 
107
- events = ['faceoff','hit','giveaway','takeaway','blocked-shot','missed-shot','shot-on-goal','goal','penalty']
107
+ EVENTS = ['faceoff','hit','giveaway','takeaway','blocked-shot','missed-shot','shot-on-goal','goal','penalty']
108
108
 
109
- dir = os.path.dirname(os.path.realpath(__file__))
110
- schedule_path = os.path.join(dir,'tools\\schedule\\schedule.csv')
111
- info_path = os.path.join(dir,'tools\\teaminfo\\nhl_teaminfo.csv')
112
- default_roster = os.path.join(dir,'tools\\rosters\\nhl_rosters.csv')
109
+ DIR = os.path.dirname(os.path.realpath(__file__))
110
+ SCHEDULE_PATH = os.path.join(DIR,'tools\\schedule\\schedule.csv')
111
+ INFO_PATH = os.path.join(DIR,'tools\\teaminfo\\nhl_teaminfo.csv')
112
+ DEFAULT_ROSTER = os.path.join(DIR,'tools\\rosters\\nhl_rosters.csv')
113
113
 
114
114
  ## SCRAPE FUNCTIONS ##
115
115
  def nhl_scrape_game(game_ids,split_shifts = False, remove = ['period-start','period-end','challenge','stoppage','shootout-complete','game-end'],verbose = False, sources = False, errors = False):
@@ -189,8 +189,8 @@ def nhl_scrape_game(game_ids,split_shifts = False, remove = ['period-start','per
189
189
  except:
190
190
  #Games such as the all-star game and pre-season games will incur this error
191
191
  #Other games have known problems
192
- if game_id in known_probs.keys():
193
- print(f"\nGame {game_id} has a known problem: {known_probs[game_id]}")
192
+ if game_id in KNOWN_PROBS.keys():
193
+ print(f"\nGame {game_id} has a known problem: {KNOWN_PROBS[game_id]}")
194
194
  else:
195
195
  print(f"\nUnable to scrape game {game_id}. Ensure the ID is properly inputted and formatted.")
196
196
 
@@ -302,7 +302,7 @@ def nhl_scrape_schedule(season,start = "09-01", end = "08-01"):
302
302
  #Return: specificed schedule data
303
303
  return df
304
304
 
305
- def nhl_scrape_season(season,split_shifts = False, season_types = [2,3], remove = ['period-start','period-end','game-end','challenge','stoppage'], start = "09-01", end = "08-01", local=False, local_path = schedule_path, verbose = False, sources = False, errors = False):
305
+ def nhl_scrape_season(season,split_shifts = False, season_types = [2,3], remove = ['period-start','period-end','game-end','challenge','stoppage'], start = "09-01", end = "08-01", local=False, local_path = SCHEDULE_PATH, verbose = False, sources = False, errors = False):
306
306
  #Given season, scrape all play-by-play occuring within the season
307
307
  # param 'season' - NHL season to scrape
308
308
  # param 'split_shifts' - boolean which splits pbp and shift events if true
@@ -382,7 +382,7 @@ def nhl_scrape_standings(arg = "now", season_type = 2):
382
382
  #arg param is ignored when set to "now" if season_type param is 3
383
383
  if season_type == 3:
384
384
  if arg == "now":
385
- arg = new
385
+ arg = NEW
386
386
 
387
387
  print(f"Scraping playoff bracket for date: {arg}")
388
388
  api = f"https://api-web.nhle.com/v1/playoff-bracket/{arg}"
@@ -394,12 +394,12 @@ def nhl_scrape_standings(arg = "now", season_type = 2):
394
394
  else:
395
395
  if arg == "now":
396
396
  print("Scraping standings as of now...")
397
- elif arg in seasons:
397
+ elif arg in SEASONS:
398
398
  print(f'Scraping standings for season: {arg}')
399
399
  else:
400
400
  print(f"Scraping standings for date: {arg}")
401
401
 
402
- api = f"https://api-web.nhle.com/v1/standings/{arg[4:8]}-{standings_end[arg]}"
402
+ api = f"https://api-web.nhle.com/v1/standings/{arg[4:8]}-{STANDINGS_END[arg]}"
403
403
  data = rs.get(api).json()['standings']
404
404
 
405
405
  return pd.json_normalize(data)
@@ -687,7 +687,7 @@ def nhl_shooting_impacts(agg,type):
687
687
  pos[f'{group[0]}-FNI-T'] = (pos[f'{group[0]}-FNI']/60)*pos['TOI']
688
688
 
689
689
  #Rank per 60 stats
690
- for stat in per_sixty[10:len(per_sixty)]:
690
+ for stat in PER_SIXTY[11:len(PER_SIXTY)]:
691
691
  pos[f'{stat}/60-P'] = pos[f'{stat}/60'].rank(pct=True)
692
692
 
693
693
  #Flip percentiles for against stats
@@ -788,7 +788,7 @@ def nhl_shooting_impacts(agg,type):
788
788
  pos['RushesFi'] = pos['RushFi/60'].rank(pct=True)
789
789
 
790
790
  #Rank per 60 stats
791
- for stat in per_sixty:
791
+ for stat in PER_SIXTY:
792
792
  pos[f'{stat}/60-P'] = pos[f'{stat}/60'].rank(pct=True)
793
793
 
794
794
  #Flip percentiles for against stats
@@ -868,7 +868,7 @@ def nhl_shooting_impacts(agg,type):
868
868
  #Return: skater stats with shooting impacts
869
869
  return df
870
870
 
871
- def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,roster_path=default_roster,shot_impact=False):
871
+ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,roster_path=DEFAULT_ROSTER,shot_impact=False):
872
872
  #Given play-by-play, seasonal information, game_strength, rosters, and xG model, return aggregated stats
873
873
  # param 'pbp' - play-by-play dataframe
874
874
  # param 'type' - type of stats to calculate ('skater', 'goalie', or 'team')
@@ -911,10 +911,11 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
911
911
  complete['TOI'] = complete['TOI']/60
912
912
 
913
913
  #Add per 60 stats
914
- for stat in ['FF','FA','xGF','xGA','GF','GA','CF','CA','GSAx']:
914
+ for stat in ['FF','FA','xGF','xGA','GF','GA','SF','SA','CF','CA','GSAx']:
915
915
  complete[f'{stat}/60'] = (complete[stat]/complete['TOI'])*60
916
916
 
917
917
  complete['GF%'] = complete['GF']/(complete['GF']+complete['GA'])
918
+ complete['SF%'] = complete['SF']/(complete['SF']+complete['SA'])
918
919
  complete['xGF%'] = complete['xGF']/(complete['xGF']+complete['xGA'])
919
920
  complete['FF%'] = complete['FF']/(complete['FF']+complete['FA'])
920
921
  complete['CF%'] = complete['CF']/(complete['CF']+complete['CA'])
@@ -953,10 +954,6 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
953
954
  #Find player headshot
954
955
  complete['Headshot'] = 'https://assets.nhle.com/mugs/nhl/'+complete['Season'].astype(str)+'/'+complete['Team']+'/'+complete['ID'].astype(int).astype(str)+'.png'
955
956
 
956
- end = time.perf_counter()
957
- length = end-start
958
- print(f'...finished in {(length if length <60 else length/60):.2f} {'seconds' if length <60 else 'minutes'}.')
959
-
960
957
  head = ['Goalie','ID','Game'] if 'Game' in complete.columns else ['Goalie','ID']
961
958
  complete = complete[head+[
962
959
  "Season","Team",'WSBA',
@@ -964,12 +961,12 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
964
961
  'Height (in)','Weight (lbs)',
965
962
  'Birthday','Age','Nationality',
966
963
  'GP','TOI',
967
- "GF","FF","xGF","xGF/FF","GF/xGF","FshF%",
968
- "GA","FA","xGA","xGA/FA","GA/xGA","FshA%",
964
+ "GF","SF","FF","xGF","xGF/FF","GF/xGF","ShF%","FshF%",
965
+ "GA","SA","FA","xGA","xGA/FA","GA/xGA","ShA%","FshA%",
969
966
  'CF','CA',
970
967
  'GSAx',
971
968
  'RushF','RushA','RushFxG','RushAxG','RushFG','RushAG'
972
- ]+[f'{stat}/60' for stat in ['FF','FA','xGF','xGA','GF','GA','CF','CA','GSAx']]]
969
+ ]+[f'{stat}/60' for stat in ['FF','FA','xGF','xGA','GF','GA','SF','SA','CF','CA','GSAx']]]
973
970
 
974
971
  #Apply shot impacts if necessary
975
972
  if shot_impact:
@@ -991,10 +988,11 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
991
988
  complete['TOI'] = complete['TOI']/60
992
989
 
993
990
  #Add per 60 stats
994
- for stat in per_sixty[10:len(per_sixty)]:
991
+ for stat in PER_SIXTY[11:len(PER_SIXTY)]:
995
992
  complete[f'{stat}/60'] = (complete[stat]/complete['TOI'])*60
996
993
 
997
994
  complete['GF%'] = complete['GF']/(complete['GF']+complete['GA'])
995
+ complete['SF%'] = complete['SF']/(complete['SF']+complete['SA'])
998
996
  complete['xGF%'] = complete['xGF']/(complete['xGF']+complete['xGA'])
999
997
  complete['FF%'] = complete['FF']/(complete['FF']+complete['FA'])
1000
998
  complete['CF%'] = complete['CF']/(complete['CF']+complete['CA'])
@@ -1003,16 +1001,17 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
1003
1001
  complete = complete[head+[
1004
1002
  'Season','WSBA',
1005
1003
  'GP','TOI',
1006
- "GF","FF","xGF","xGF/FF","GF/xGF","FshF%",
1007
- "GA","FA","xGA","xGA/FA","GA/xGA","FshA%",
1004
+ "GF","SF","FF","xGF","xGF/FF","GF/xGF","ShF%","FshF%",
1005
+ "GA","SA","FA","xGA","xGA/FA","GA/xGA","ShA%","FshA%",
1008
1006
  'CF','CA',
1009
- 'GF%','FF%','xGF%','CF%',
1007
+ 'GF%','SF%','FF%','xGF%','CF%',
1010
1008
  'HF','HA','HF%',
1011
1009
  'Penl','Penl2','Penl5','PIM','Draw','PENL%',
1012
1010
  'Give','Take','PM%',
1013
1011
  'Block',
1014
- 'RushF','RushA','RushFxG','RushAxG','RushFG','RushAG'
1015
- ]+[f'{stat}/60' for stat in per_sixty[10:len(per_sixty)]]]
1012
+ 'RushF','RushA','RushFxG','RushAxG','RushFG','RushAG',
1013
+ 'GSAx'
1014
+ ]+[f'{stat}/60' for stat in PER_SIXTY[11:len(PER_SIXTY)]]]
1016
1015
  #Apply shot impacts if necessary
1017
1016
  if shot_impact:
1018
1017
  complete = nhl_shooting_impacts(complete,'team')
@@ -1038,6 +1037,7 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
1038
1037
  complete['FC%'] = complete['Fi']/complete['FF']
1039
1038
  complete['xGC%'] = complete['xGi']/complete['xGF']
1040
1039
  complete['GF%'] = complete['GF']/(complete['GF']+complete['GA'])
1040
+ complete['SF%'] = complete['SF']/(complete['SF']+complete['SA'])
1041
1041
  complete['xGF%'] = complete['xGF']/(complete['xGF']+complete['xGA'])
1042
1042
  complete['FF%'] = complete['FF']/(complete['FF']+complete['FA'])
1043
1043
  complete['CF%'] = complete['CF']/(complete['CF']+complete['CA'])
@@ -1082,13 +1082,13 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
1082
1082
  complete['WSBA'] = complete['Player']+complete['Season'].astype(str)+complete['Team']
1083
1083
 
1084
1084
  #Add per 60 stats
1085
- for stat in per_sixty:
1085
+ for stat in PER_SIXTY:
1086
1086
  complete[f'{stat}/60'] = (complete[stat]/complete['TOI'])*60
1087
1087
 
1088
1088
  #Shot Type Metrics
1089
1089
  type_metrics = []
1090
1090
  for type in shot_types:
1091
- for stat in per_sixty[:3]:
1091
+ for stat in PER_SIXTY[:3]:
1092
1092
  type_metrics.append(f'{type.capitalize()}{stat}')
1093
1093
 
1094
1094
  head = ['Player','ID','Game'] if 'Game' in complete.columns else ['Player','ID']
@@ -1098,11 +1098,11 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
1098
1098
  'Height (in)','Weight (lbs)',
1099
1099
  'Birthday','Age','Nationality',
1100
1100
  'GP','TOI',
1101
- "Gi","A1","A2",'P1','P',
1101
+ "Gi","A1","A2",'P1','P','Si','Shi%',
1102
1102
  'Give','Take','PM%','HF','HA','HF%',
1103
1103
  "Fi","xGi",'xGi/Fi',"Gi/xGi","Fshi%",
1104
- "GF","FF","xGF","xGF/FF","GF/xGF","FshF%",
1105
- "GA","FA","xGA","xGA/FA","GA/xGA","FshA%",
1104
+ "GF","SF","FF","xGF","xGF/FF","GF/xGF","ShF%","FshF%",
1105
+ "GA","SA","FA","xGA","xGA/FA","GA/xGA","ShA%","FshA%",
1106
1106
  'Ci','CF','CA','CF%',
1107
1107
  'FF%','xGF%','GF%',
1108
1108
  'Rush',"Rush xG",'Rush G',"GC%","AC%","GI%","FC%","xGC%",
@@ -1112,7 +1112,8 @@ def nhl_calculate_stats(pbp,type,season_types,game_strength,split_game=False,ros
1112
1112
  'Block',
1113
1113
  'OZF','NZF','DZF',
1114
1114
  'OZF%','NZF%','DZF%',
1115
- ]+[f'{stat}/60' for stat in per_sixty]+type_metrics].fillna(0).sort_values(['Player','Season','Team','ID'])
1115
+ 'GSAx'
1116
+ ]+[f'{stat}/60' for stat in PER_SIXTY]+type_metrics].fillna(0).sort_values(['Player','Season','Team','ID'])
1116
1117
 
1117
1118
  #Apply shot impacts if necessary (Note: this will remove skaters with fewer than 150 minutes of TOI due to the shot impact TOI rule)
1118
1119
  if shot_impact:
@@ -1176,7 +1177,7 @@ def repo_load_rosters(seasons = []):
1176
1177
  #Returns roster data from repository
1177
1178
  # param 'seasons' - list of seasons to include
1178
1179
 
1179
- data = pd.read_csv(default_roster)
1180
+ data = pd.read_csv(DEFAULT_ROSTER)
1180
1181
  if len(seasons)>0:
1181
1182
  data = data.loc[data['season'].isin(seasons)]
1182
1183
 
@@ -1186,7 +1187,7 @@ def repo_load_schedule(seasons = []):
1186
1187
  #Returns schedule data from repository
1187
1188
  # param 'seasons' - list of seasons to include
1188
1189
 
1189
- data = pd.read_csv(schedule_path)
1190
+ data = pd.read_csv(SCHEDULE_PATH)
1190
1191
  if len(seasons)>0:
1191
1192
  data = data.loc[data['season'].isin(seasons)]
1192
1193
 
@@ -1195,7 +1196,7 @@ def repo_load_schedule(seasons = []):
1195
1196
  def repo_load_teaminfo():
1196
1197
  #Returns team data from repository
1197
1198
 
1198
- return pd.read_csv(info_path)
1199
+ return pd.read_csv(INFO_PATH)
1199
1200
 
1200
1201
  def repo_load_pbp(seasons = []):
1201
1202
  #Returns play-by-play data from repository
@@ -1203,11 +1204,11 @@ def repo_load_pbp(seasons = []):
1203
1204
 
1204
1205
  #Add parquet to total
1205
1206
  print(f'Loading play-by-play from the following seasons: {seasons}...')
1206
- dfs = [pd.read_parquet(f"https://weakside-breakout.s3.us-east-2.amazonaws.com/pbp/{season}.parquet") for season in seasons]
1207
+ dfs = [pd.read_parquet(f"https://weakside-breakout.s3.us-east-2.amazonaws.com/pbp/parquet/nhl_pbp_{season}.parquet") for season in seasons]
1207
1208
 
1208
1209
  return pd.concat(dfs)
1209
1210
 
1210
1211
  def repo_load_seasons():
1211
1212
  #List of available seasons to scrape
1212
1213
 
1213
- return seasons
1214
+ return SEASONS
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wsba_hockey
3
- Version: 1.1.3
3
+ Version: 1.1.6
4
4
  Summary: WeakSide Breakout's complete Python package of access to hockey data, primairly including the scraping of National Hockey League schedule, play-by-play, and shifts information.
5
5
  Author-email: Owen Singh <owenbksingh@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/owensingh38/wsba_hockey/
@@ -64,12 +64,18 @@ wsba.nhl_scrape_prospects('BOS')
64
64
 
65
65
 
66
66
  ## DATA ANALYTICS
67
- ### Expected Goals (WeakSide Breakout and MoneyPuck models)
67
+ ### Expected Goals
68
+ ```python
69
+ pbp = wsba.nhl_scrape_game(['2024020918'],split_shifts=False,remove=['game-end'])
70
+ pbp = wsba.nhl_apply_xG(pbp)
71
+ ```
72
+
68
73
  ### Goal Impacts and Shot Analysis
74
+
69
75
  ### Stat Aggregation
70
76
  ```python
71
77
  pbp = wsba.nhl_scrape_season('20232024',remove=[], local = True)
72
- wsba.nhl_calculate_stats(pbp,'skater',[2],['5v5','4v4','3v3'],xg='wsba',shot_impact = True)
78
+ wsba.nhl_calculate_stats(pbp,'skater',[2],['5v5','4v4','3v3'],shot_impact = True)
73
79
  ```
74
80
  ### Shot Plotting (Plots, Heatmaps, etc.)
75
81
  ```python
@@ -105,6 +111,4 @@ Dan Morse - Creator of the hockeyR package; another important inspiration and mo
105
111
 
106
112
  Patrick Bacon - Creator of TopDownHockey package
107
113
 
108
- MoneyPuck - Source of available xG data in the package
109
-
110
114
  Anyone in the NHL Public Analytics community who has stuck around and supported WeakSide Breakout Analysis hockey.
@@ -1,8 +1,8 @@
1
1
  wsba_hockey/__init__.py,sha256=yfr8z5PA503iaIQv30ngancwT_WnsuK-tZETKlHcI0M,377
2
- wsba_hockey/data_pipelines.py,sha256=wjyxw1ikv4N3kmfTuHxdHj7_W5bz0wAM-DIgxvJVg2s,10852
3
- wsba_hockey/workspace.py,sha256=ECScWNqkmx8SDoxTtZYZtM1K1_oX-wQSXXsb_1Bjca4,2014
4
- wsba_hockey/wsba_main.py,sha256=c8KEXBpjHHEadMMStMRXsNYqbvtoYdZbmOl8_FBmHQg,53761
5
- wsba_hockey/api/api/index.py,sha256=b2QEOJ72TxOCZT9KsHvIPPow0RwLRCOUyeyrIrSqb6o,5926
2
+ wsba_hockey/data_pipelines.py,sha256=SITapG3nbea6-_EsXujMW2JBQxtRaQ33XMcE6ohn2Ko,10853
3
+ wsba_hockey/workspace.py,sha256=MwuyqyLW0dHNa06WEm60RkvbFoCn8LBXhnki66V-ttY,954
4
+ wsba_hockey/wsba_main.py,sha256=Ucies8d27gWtzf8xprnu7hEcqGGHvOza8HCE0O80X-s,54031
5
+ wsba_hockey/api/api/index.py,sha256=tABWg5cYCY-fPaNJ6W_bMJKEYrjn93YGy84VlkHzIXA,6853
6
6
  wsba_hockey/evidence/weakside-breakout/node_modules/duckdb/vendor.py,sha256=lmu0TB0rIYkAuV9-csFJgW-1hJojso_-EZpEoorUUKM,4949
7
7
  wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/flatted.py,sha256=ke8FuEflns-WlphCcQ9CC0qJqWqX3zEEuak74o6rgE8,3879
8
8
  wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/test.py,sha256=uTOn6HJd7KeY_PTRvvufv60dmvON3KWp3nnqACj8IlA,2129
@@ -105,6 +105,8 @@ wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gy
105
105
  wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_sln.py,sha256=b_Fxm-SXUCPL3Tix4EyNwZNmQ-zkeRIFFmuL0R5wFhw,5482
106
106
  wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_vcproj.py,sha256=AwQrxK1F-jhjsbbT35XQjrvWNbc3IBFaKXoJogqMh_o,10633
107
107
  wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/test/fixtures/test-charmap.py,sha256=5raXzaQnO2eJnrlFtlDtWftryhZX7Fj0amFW3hdSnhE,547
108
+ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/app.py,sha256=PBdVi5qnR3Ye_dNjgqxmh5LIe6Tu_yu9-gebaaQnTfA,7947
109
+ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/calc.py,sha256=5T_TselP85ofTwf0inl3P7dtyRcosWg5ngUUL95jzLw,8789
108
110
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/app.py,sha256=P3vDaWyuij-DXlwk6XJ0aiAjrfs-NHi5hmngk-c9r8U,12704
109
111
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/name_fix.py,sha256=v7IN4JWrudeFuIsBdjLLlHsr9wU65jYi9-34pI_ZpoM,1488
110
112
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/app.py,sha256=f5uwSvNKbtud91e7B17zC0HbPnYIvUgnShhdJZCOtkE,3820
@@ -113,10 +115,13 @@ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/rink_p
113
115
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/app.py,sha256=XDoZ6-uTgT1vCAOjJ8KjW3r7T0eNDfShGScDxY95HyU,4255
114
116
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/plot.py,sha256=QERvb9I_OJPhrz84Omsf9Mq6JjaECark_ql1KfWha-I,4648
115
117
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/rink_plot.py,sha256=RB_csrnTxlFR4OyFEhZXbHDSR3dP-KgME0xGBR2JE-4,11994
116
- wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/app.py,sha256=JFWhfsyMhCnvLVyIfYzgZE2xT8_mnsOVWVXNi2EF9rM,6136
118
+ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/app.py,sha256=V9tcLkASOpvlnYNYwjYhxi5CgL1S8NUBmbnYcWjBSQ0,9457
119
+ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/plot.py,sha256=r-kPrlup8WrfKs5-Q0RGnLmF0hCOy7zWA_uKDvGy18o,14552
120
+ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/rink_plot.py,sha256=RB_csrnTxlFR4OyFEhZXbHDSR3dP-KgME0xGBR2JE-4,11994
121
+ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/app.py,sha256=dRpnCLE9G2H7VOCBgHUOfEmoruEkUcnS2qhyiV54dQ8,6136
117
122
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/plot.py,sha256=t3XRT88L0lh5jE-PSSboLZZ-Yg_u8L4gzJh-egWiRcY,3935
118
123
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/rink_plot.py,sha256=RB_csrnTxlFR4OyFEhZXbHDSR3dP-KgME0xGBR2JE-4,11994
119
- wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/app.py,sha256=oH_Su2Z9iCfwsgW2aINzzxlo1fCq6dnEkTMbngjw9vg,13811
124
+ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/app.py,sha256=hbMBjctovACO6KXswvb6gsN8AwQCOtT0BHHKR_EGBQM,13841
120
125
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/plot.py,sha256=zfUTSic2M1AfXufvLFDTxxvpqQXw0RzwwQTGxALjjSw,2779
121
126
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/rink_plot.py,sha256=RB_csrnTxlFR4OyFEhZXbHDSR3dP-KgME0xGBR2JE-4,11994
122
127
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/app.py,sha256=fNGWRHgqZr2G_QgACzh1l93ob-ugik1F9Wnq-sowWKU,4308
@@ -127,17 +132,17 @@ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps
127
132
  wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/rink_plot.py,sha256=RB_csrnTxlFR4OyFEhZXbHDSR3dP-KgME0xGBR2JE-4,11994
128
133
  wsba_hockey/flask/app.py,sha256=J51iA65h9xyJfLgdH0h2sVSbfIR7xgGd2Oy8bJsmpAk,1873
129
134
  wsba_hockey/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
- wsba_hockey/tools/agg.py,sha256=SYZDykUQFygDfRaazlBMKcfs_1eYP7GTJNpUnNKHH-8,21409
135
+ wsba_hockey/tools/agg.py,sha256=OkIYd-ApvGVYe2JJLOI21jnDIN5LH8nkeH7eo0reWFI,23364
131
136
  wsba_hockey/tools/plotting.py,sha256=81hBaM7tcwUNB4-tovPn7QreOUz6B2NuI_SR4-djVSk,6029
132
- wsba_hockey/tools/scraping.py,sha256=y6vvotniMaGS6-bNg0Vct1gUN3gAsKEy5FLXGkgi1w0,45657
137
+ wsba_hockey/tools/scraping.py,sha256=h6C016U0qmNQpHWMh7Xvn3ud57zKzRbRQ06Odl-rC_I,52573
133
138
  wsba_hockey/tools/xg_model.py,sha256=nOr_2RBijLgPmJ0TTs4wbSsORYmRqWCKRjLKDm7sAhI,18342
134
139
  wsba_hockey/tools/archive/old_scraping.py,sha256=hEjMI1RtfeZnf0RBiJFI38oXkLZ3WofeH5xqcF4pzgM,49585
135
140
  wsba_hockey/tools/utils/__init__.py,sha256=vccXhOtzARoR99fmEWU1OEI3qCIdQ9Z42AlRA_BUhrs,114
136
141
  wsba_hockey/tools/utils/config.py,sha256=D3Uk05-YTyrhfReMTTLfNI3HN_rON2uo_CDE9oER3Lg,351
137
142
  wsba_hockey/tools/utils/save_pages.py,sha256=CsyL_0n-b-4pJoUauwU3HpnCO6n69-RlBMJQBd_qGDc,4979
138
143
  wsba_hockey/tools/utils/shared.py,sha256=dH_JwZfia5fib8rksy5sW-mBp0pluBPvw37Vdr8Kap0,14211
139
- wsba_hockey-1.1.3.dist-info/licenses/LICENSE,sha256=Nr_Um1Pd5FQJTWWgm7maZArdtYMbDhzXYSwyJIZDGik,1114
140
- wsba_hockey-1.1.3.dist-info/METADATA,sha256=pGBQxsZfILi46XgUEfLDk3Q5TEadxe3pJNxCDGFZVpk,3542
141
- wsba_hockey-1.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
142
- wsba_hockey-1.1.3.dist-info/top_level.txt,sha256=acU7s3x-RZC1zGiqCOmO0g267iqCg34lzIfdmYxxGmQ,12
143
- wsba_hockey-1.1.3.dist-info/RECORD,,
144
+ wsba_hockey-1.1.6.dist-info/licenses/LICENSE,sha256=Nr_Um1Pd5FQJTWWgm7maZArdtYMbDhzXYSwyJIZDGik,1114
145
+ wsba_hockey-1.1.6.dist-info/METADATA,sha256=2CLs8qTA1iS8P7ToF4My86KkMRrt5zYoX9ynbQTS4zk,3566
146
+ wsba_hockey-1.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
147
+ wsba_hockey-1.1.6.dist-info/top_level.txt,sha256=acU7s3x-RZC1zGiqCOmO0g267iqCg34lzIfdmYxxGmQ,12
148
+ wsba_hockey-1.1.6.dist-info/RECORD,,