-
Notifications
You must be signed in to change notification settings - Fork 0
/
nba_stats.py
276 lines (202 loc) · 7.47 KB
/
nba_stats.py
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#
# NBA Stats
# Stephen Hoerner
# CSCD 110
#
import sys
def main():
# VARIABLES
## stats - dictionary; contains nifty data
## cmd - string; command inputed by user
try:
stats = loadStats('player_career.txt')
except IOError as e:
print(e)
sys.exit(0)
except:
print('An unknown error occured.')
sys.exit(0)
# menu selection
showMenu()
cmd = getInt('Enter Command: ')
while cmd != 0:
print()
if cmd == 1:
print(getTop(stats, 'top-players'))
elif cmd == 2:
print(getTop(stats, 'top-offensives'))
elif cmd == 3:
print(getTop(stats, 'top-defensives'))
elif cmd == 4:
print(getTop(stats, 'top-scorers'))
elif cmd == 5:
print(getTop(stats, 'top-assists'))
elif cmd == 6:
print(getTop(stats, 'top-steals'))
elif cmd == 7:
print(getTop(stats, 'top-rebounds'))
elif cmd == 8:
print(getTop(stats, 'top-blocks'))
elif cmd == 9:
print(getTop(stats, 'top-shooters'))
elif cmd == 10:
print(getTop(stats, 'top-3-shooters'))
else:
print('Invalid command!')
showMenu()
cmd = getInt('Enter Command: ')
# returns the top players (in a string) for a given category
def getTop(data,calcType):
# PARAMETERS
## data - dictionary; contains all the stat data
## calcType - string; the category of operation to perform
# VARIABLES
## calc - list; contains calculated values
## ids - list; contains corresponding player IDs
## index - number; accumulator which represents a player
calc = []
ids = []
for index in range(len(data['id'])):
ids.append(data['firstname'][index] + ' ' + data['lastname'][index])
calc.append(getCalculation(data, calcType, index))
return topFifty(data, combineAndSort(calc, ids))
# returns the calculated value for a given index
def getCalculation(dat, calcType, i):
# PARAMETERS
## dat - dictionary; contains all the stat data
## calcType - string; the calculation ID to perform
## i - int; index value for the current row to operate on
# VARIABLES
## amt - number; represents the calculated result
## fga, fta, tpa - numbers; represent their corresponding values, but prevent division by zero
amt = 0
if calcType == 'top-players':
# calculate the value ... a complicated value
amt = ((dat['pts'][i] + dat['reb'][i] + dat['asts'][i] \
+ dat['stl'][i] + dat['blk'][i]) - ((dat['fga'][i] - dat['fgm'][i]) \
- (dat['fta'][i] - dat['ftm'][i]) + dat['turnover'][i])) / dat['gp'][i]
elif calcType == 'top-offensives':
# prevent division by 0
fga = dat['fga'][i] if dat['tpm'][i] != 0 else 1
# calculate the value
amt = ((dat['pts'][i] + dat['asts'][i]) - (dat['turnover'][i] * 4)) \
* (dat['fgm'][i] / fga)
elif calcType == 'top-defensives':
# calculate the value
amt = (dat['dreb'][i] + (dat['stl'][i] * 1.5)) + (dat['blk'][i] * 2)
elif calcType == 'top-scorers':
# calculate the value
amt = dat['pts'][i]
elif calcType == 'top-assists':
# calculate the value
amt = dat['asts'][i]
elif calcType == 'top-rebounds':
# calculate the value
amt = dat['reb'][i]
elif calcType == 'top-steals':
# calculate the value
amt = dat['stl'][i]
elif calcType == 'top-blocks':
# calculate the value
amt = dat['blk'][i]
elif calcType == 'top-shooters':
# prevent division by 0
fga = dat['fga'][i] if dat['tpm'][i] != 0 else 1
fta = dat['fta'][i] if dat['fta'][i] != 0 else 1
tpa = dat['tpa'][i] if dat['tpa'][i] != 0 else 1
# calculate the value
amt = ((dat['fgm'][i] / fga) * 2) + (dat['ftm'][i] / fta) \
+ ((dat['tpm'][i] / tpa) * 3)
elif calcType == 'top-3-shooters':
# prevent division by 0
tpa = dat['tpa'][i] if dat['tpa'][i] != 0 else 1
# calculate the value
amt = dat['tpm'][i] / tpa
## end calculations
return amt
# takes two lists, sorts them by valueList, and returns
# one list containing sub-lists in the form [value, key]
def combineAndSort(valueList, keyList):
# PARAMETERS
## valueList - list; a list to sort by
## keyList - list; a list with identifiers
# VARIABLES
## result - list; contains final results
## i - number; simple accumulator index
result = list(zip(keyList, valueList)) # zip into a tupled list [('name', num), ...]
result.sort(key = lambda row: row[1], reverse = True) # sorts by the 'rating numbers' backwards
for i in range(len(result)):
result[i] = list(result[i]) # convert tuples to lists
return result
# returns the first fifty player names in a given ID-list
def topFifty(data, ranking):
# PARAMETERS
## data - dictionary; contains all the stat data
## ranking - list; contains player ID's in whatever order desired
# VARIABLES
## output - string; contains output...
## tempID - string; holds a temporary player ID
output = ''
for i in range(50):
output += str(i + 1) + '. ' + ranking[i][0] + '\n' # 'num. name \n'
return output
# gets an int from the user
def getInt(prompt):
# PARAMETERS
## prompt: string, countains user input prompt
try:
return int(input(prompt))
except:
return None
# displaysthe menu
def showMenu():
print()
print('- - - - - - - - - - - -')
print('1. List top 50 players')
print('2. List top 50 offensive players')
print('3. List top 50 defensive players')
print('4. List top 50 scorers')
print('5. List top 50 assisters')
print('6. List top 50 stealers')
print('7. List top 50 rebounders')
print('8. List top 50 blockers')
print('9. List top 50 shooters')
print('10. List top 50 three-point shooters')
print()
print('0. exit')
print('- - - - - - - - - - - -')
print()
# loads the player statistics from a given filename
def loadStats(filename):
# PARAMETERS
## filename - string; the file to open
# VARIABLES
## file - handle; represents the file
## columns - list; the columns to use
## data - dictionary; accumulates all the data
## line - string; contains the value of a line
## values - list; contains individual values of a list
try:
with open(filename, 'r') as file:
file.readline() # skip the first line
columns = ['id','firstname','lastname','leag','gp','minutes','pts','oreb','dreb',\
'reb','asts','stl','blk','turnover','pf','fga','fgm','fta','ftm','tpa','tpm'] # define our columns
data = {}
for id in columns: # initiate columns within dict
data[id] = []
while True:
line = file.readline().strip() # current line; whitespace stripped
if (line == ''): # EOF
break
values = line.split(',') # create list of values
for j in range(len(values)):
if j > 3: # first 4 columns cannot be cast to ints
data[columns[j]].append(int(values[j]))
else: # these are strings
data[columns[j]].append(values[j].strip())
print('Loaded stats.')
return data
except:
raise IOError('An error occured while loading the file.')
return None
main() # the all-important call.