Repository navigation
Expand file tree
/
Copy pathformation_success.py
More file actions
201 lines (180 loc) · 7.67 KB
/
Copy pathformation_success.py
File metadata and controls
201 lines (180 loc) · 7.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# Before we move on, you should install 1 new: keyring. Just do as when you installed requests and BeautifulSoup4
# This script doesn't display the team names anymore. Neither displays the information for both teams. I believe it makes the whole thing more focused.
# You'll be prompted for your username and password, they'll be stored in your machine (that's what the keyring module does). I need to create a GLB2 session so we can download the JSON with the entire offensive playbook, which we use to find out the kinds of plays and the nº of receivers. Let me know if you run into troubles with this module since I never used it previously.
# Instead of editing the code, now you'll be prompted to insert the Game ID and the Team ID of the team you want to scout afterwards.
# If you're feeling adventurous, you can look for a dictionary called yards. There you can customize what the script will consider as Very Short, Short, Medium and Long, just as in the Tactics section of GLB2
# Let's talk about improvements: This script is at least 8 times faster than the previous version. It displays only the valid information, so no more 0 (0%). It sorts all results in an order I consider pleasant to the eye. It shows percentages for the receivers considering the down, which may be great for you to decide your blitzes.
# Hope you enjoy, now let me sleep.
import getpass
import keyring # pip3 install keyring
import re
# Customize this!
define_success = {
'QB Rush': 5,
'Outside Run': 3,
'Inside Run': 3,
'Pass': 0
}
#Checking/Prompting for username/password
user_name = keyring.get_password('glb2', 'user_name')
password = keyring.get_password('glb2', 'password')
if user_name is None:
user_name = input('Your GLB2 Username: ')
keyring.set_password('glb2', 'user_name', user_name)
if password is None:
password = getpass.getpass('Your GLB2 Password: ')
keyring.set_password('glb2', 'password', password)
login = {'action': 'login','user_name': user_name,'password': password}
# Grabs the whole defensive playbook:
import requests # pip3 install requests
import json
with requests.Session() as c:
c.post('http://glb2.warriorgeneral.com/game/login', data=login)
r = c.get('http://glb2.warriorgeneral.com/game/playbook/O/ajax').content
w = c.get('http://glb2.warriorgeneral.com/game/playbook/D/ajax').content
offensive_playbook = json.loads(r.decode('utf-8'))
defensive_playbook = json.loads(w.decode('utf-8'))
play_formatting = {
'run_outside_qb': 'Outside QB',
'run_outside_fb': 'Outside Run',
'run_outside_hb': 'Outside Run',
'run_inside_fb': 'Inside Run',
'run_inside_qb': 'Inside QB',
'run_inside_hb': 'Inside Run',
'run_goalline': 'GL Run',
'pass_long': 'Pass',
'pass_medium': 'Pass',
'pass_screen': 'Pass',
'pass_short': 'Pass',
'pass_goalline': 'Pass'
}
formation_formatting = {
'zone_Dime': 'Dime [Z]',
'zone_Dime 3-2-6': 'Dime 3-2-6 [Z]',
'man_5-2': '5-2 [M]',
'man_Goal Line D': 'Goal Line D [M]',
'zone_4-4': '4-4 [Z]',
'man_Nickel 3-3-5': 'Nickel 3-3-5 [M]',
'zone_Nickel': 'Nickel [Z]',
'zone_4-4 Big': '4-4 Big [Z]',
'man_3-4': '3-4 [M]',
'man_Quarter': 'Quarter [M]',
'man_Dime 3-2-6': 'Dime 3-2-6 [M]',
'man_Nickel': 'Nickel [M]',
'zone_3-4': '3-4 [Z]',
'man_4-3': '4-3 [M]',
'zone_4-3': '4-3 [Z]',
'zone_Quarter': 'Quarter [Z]',
'man_Dime': 'Dime [M]',
'man_4-4': '4-4 [M]',
'man_4-4 Big': '4-4 Big [M]',
'zone_Nickel 3-3-5': 'Nickel 3-3-5 [Z]',
'zone_5-2': '5-2 [Z]'
}
def perc(kind, total):
if total == 0 or kind == 0:
return '0'
else:
return '{0}%'.format(int((kind * 100) / total))
def play_time(game_id):
stats = {}
team_of_interest = input('''Insert your Team ID: ''')
for game in game_id:
try:
p_b_p = requests.get('http://glb2.warriorgeneral.com/game/game/{0}/json?type=pbp'.format(game)).content
play_by_play = json.loads(p_b_p.decode('utf-8'))
pbp = [play for play in play_by_play.values() if play["offense"] != team_of_interest and play["down"] in ['1', '2', '3']]
except:
continue
for play_range in range(len(pbp) - 1):
play = pbp[play_range]
try:
offense_play = offensive_playbook[play['offense_play']]
offense_name = offense_play['name']
offense_formation = offense_play['formation']
offense_cat = play_formatting[offense_play['cat']]
defense_play = defensive_playbook[play['defense_play']]
defense_name = defense_play['name']
defense_cat = formation_formatting[defense_play['cat']]
except:
continue
play_description = play['description']
if offense_cat == 'Pass':
if 'sacked QB' in play_description:
success = 1
else:
pass_compile = re.match('(?!.*intercepted).*pass.*for a (\d+) yard (gain|loss)', play_description)
if pass_compile:
yardage = int(pass_compile.group(1))
if pass_compile.group(2) == 'loss':
success = 1
else:
success = 0
elif 'scrambled' in play_description:
scramble_compile = re.match('QB {\d+} scrambled for a (\d+) yard (gain|loss).*', play_description)
yardage = int(scramble_compile.group(1))
if scramble_compile.group(2) == 'loss':
yardage = yardage * -1
if yardage > define_success['Outside Run']:
success = 0
else:
success = 1
else:
success = 1
elif offense_cat in ['Inside Run', 'Outside Run']:
run_compile = re.match('.*for a (\d+) yard (gain|loss)', play_description)
if run_compile:
yardage = int(run_compile.group(1))
if run_compile.group(2) == 'loss':
yardage = yardage * -1
if yardage > define_success[offense_cat]:
success = 0
else:
success = 1
else:
gl_compile = re.match('.*(pitched|rushed|handed off).*for a (\d+) yard (gain|loss).*', play_description)
if gl_compile:
yardage = int(gl_compile.group(2))
if gl_compile.group(3) == 'loss':
yardage = yardage * -1
if gl_compile.group(1) == 'pitched':
gl_offense = 'Outside Run'
elif gl_compile.group(1) == 'handed off':
gl_offense = 'Inside Run'
else:
gl_offense = 'QB Rush'
if yardage > define_success[gl_offense]:
success = 0
else:
success = 1
formation = '{0} % {1}'.format(defense_name, defense_cat)
if offense_cat in stats:
if offense_name in stats[offense_cat]:
if formation in stats[offense_cat][offense_name]:
stats[offense_cat][offense_name][formation][0]+=success
stats[offense_cat][offense_name][formation][1]+=1
else:
stats[offense_cat][offense_name][formation] = [success, 1]
else:
stats[offense_cat][offense_name] = {formation: [success, 1]}
else:
stats[offense_cat] = {offense_name: {formation: [success, 1]}}
return stats
# Prompts for the Game ID, throws an error if it is not numerical.
def the_printer(play_dict):
for offense_play in play_dict.keys():
print(offense_play)
for offense_formation in play_dict[offense_play].keys():
print('\t%s' % offense_formation)
for defense_play in play_dict[offense_play][offense_formation].keys():
success = play_dict[offense_play][offense_formation][defense_play][0]
total = play_dict[offense_play][offense_formation][defense_play][1]
print('\t\t{0}: {1}/{2} ({3})'.format(defense_play, success, total, perc(success, total)))
print()
game_id = input('Insert the Game ID here: ')
game_id = game_id.split(',')#if not game_id.isdigit():
# raise Exception('A Game ID is only numbers. For example, the Game ID for http://glb2.warriorgeneral.com/game/game/54548 is only 54548')
# Collects the play-by-play information
# The Team of Interest section: where you pick the team you want to scout (after all, who tracks two teams before a match?)
#the_play_list = [play for play in play_by_play.values() if play["offense"] != team_of_interest and play["down"] in ['1', '2', '3']]
the_printer(play_time(game_id))