1 """
2 Introduction
3 ============
4 An API to retrieve and read NFL Game Center JSON data.
5 It can work with real-time data, which can be used for fantasy football.
6
7 nflgame works by parsing the same JSON data that powers NFL.com's live
8 GameCenter. Therefore, nflgame can be used to report game statistics while
9 a game is being played.
10
11 The package comes pre-loaded with game data from every pre- and regular
12 season game from 2009 up until August 28, 2012. Therefore, querying such data
13 does not actually ping NFL.com.
14
15 However, if you try to search for data in a game that is being currently
16 played, the JSON data will be downloaded from NFL.com at each request (so be
17 careful not to inspect for data too many times while a game is being played).
18 If you ask for data for a particular game that hasn't been cached to disk
19 but is no longer being played, it will be automatically cached to disk
20 so that no further downloads are required.
21
22 nflgame requires Python 2.6 or Python 2.7. It does not (yet) work with
23 Python 3.
24
25 Examples
26 ========
27
28 Finding games
29 -------------
30 Games can be selected in bulk, e.g., every game in week 1 of 2010::
31
32 games = nflgame.games(2010, week=1)
33
34 Or pin-pointed exactly, e.g., the Patriots week 17 whomping against the Bills::
35
36 game = nflgame.game(2011, 17, "NE", "BUF")
37
38 This season's (2012) pre-season games can also be accessed::
39
40 pregames = nflgame.games(2012, preseason=True)
41
42 Find passing leaders of a game
43 ------------------------------
44 Given some game, the player statistics can be easily searched. For example,
45 to find the passing leaders of a particular game::
46
47 for p in game.players.passing().sort("passing_yds"):
48 print p, p.passing_att, p.passing_cmp, p.passing_yds, p.passing_tds
49
50 Output::
51
52 T.Brady 35 23 338 3
53 R.Fitzpatrick 46 29 307 2
54 B.Hoyer 1 1 22 0
55
56 See every player that made an interception
57 ------------------------------------------
58 We can filter all players on whether they had more than zero defensive
59 interceptions, and then sort those players by the number of picks::
60
61 for p in game.players.filter(defense_int=lambda x:x>0).sort("defense_int"):
62 print p, p.defense_int
63
64 Output::
65
66 S.Moore 2
67 A.Molden 1
68 D.McCourty 1
69 N.Barnett 1
70
71 Finding weekly rushing leaders
72 ------------------------------
73 Sequences of players can be added together, and their sum can then be used
74 like any other sequence of players. For example, to get every player
75 that played in week 10 of 2009::
76
77 week10 = nflgame.games(2009, 10)
78 players = nflgame.combine(week10)
79
80 And then to list all rushers with at least 10 carries sorted by rushing yards::
81
82 rushers = players.rushing()
83 for p in rushers.filter(rushing_att=lambda x: x > 10).sort("rushing_yds"):
84 print p, p.rushing_att, p.rushing_yds, p.rushing_tds
85
86 And the final output::
87
88 A.Peterson 18 133 2
89 C.Johnson 26 132 2
90 S.Jackson 26 131 1
91 M.Jones-Drew 24 123 1
92 J.Forsett 17 123 1
93 M.Bush 14 119 0
94 L.Betts 26 114 1
95 F.Gore 25 104 1
96 J.Charles 18 103 1
97 R.Williams 20 102 0
98 K.Moreno 18 97 0
99 L.Tomlinson 24 96 2
100 D.Williams 19 92 0
101 R.Rice 20 89 1
102 C.Wells 16 85 2
103 J.Stewart 11 82 2
104 R.Brown 12 82 1
105 R.Grant 19 79 0
106 K.Faulk 12 79 0
107 T.Jones 21 77 1
108 J.Snelling 18 61 1
109 K.Smith 12 55 0
110 C.Williams 14 52 1
111 M.Forte 20 41 0
112 P.Thomas 11 37 0
113 R.Mendenhall 13 36 0
114 W.McGahee 13 35 0
115 B.Scott 13 33 0
116 L.Maroney 13 31 1
117
118 You could do the same for the entire 2009 season::
119
120 players = nflgame.combine(nflgame.games(2009))
121 for p in players.rushing().sort("rushing_yds").limit(35):
122 print p, p.rushing_att, p.rushing_yds, p.rushing_tds
123
124 And the output::
125
126 C.Johnson 322 1872 12
127 S.Jackson 305 1361 4
128 A.Peterson 306 1335 17
129 T.Jones 305 1324 12
130 M.Jones-Drew 296 1309 15
131 R.Rice 240 1269 7
132 R.Grant 271 1202 10
133 C.Benson 272 1118 6
134 D.Williams 210 1104 7
135 R.Williams 229 1090 11
136 R.Mendenhall 222 1014 7
137 F.Gore 206 1013 8
138 J.Stewart 205 1008 9
139 K.Moreno 233 897 5
140 M.Turner 177 864 10
141 J.Charles 165 861 5
142 F.Jackson 205 850 2
143 M.Barber 200 841 7
144 B.Jacobs 218 834 5
145 M.Forte 242 828 4
146 J.Addai 213 788 9
147 C.Williams 190 776 4
148 C.Wells 170 774 7
149 A.Bradshaw 156 765 7
150 L.Maroney 189 735 9
151 J.Harrison 161 735 4
152 P.Thomas 141 733 5
153 L.Tomlinson 221 729 12
154 Kv.Smith 196 678 4
155 L.McCoy 154 633 4
156 M.Bell 155 626 5
157 C.Buckhalter 114 624 1
158 J.Jones 163 602 2
159 F.Jones 101 594 2
160 T.Hightower 137 574 8
161
162 Load data into Excel
163 --------------------
164 Every sequence of Players can be easily dumped into a file formatted
165 as comma-separated values (CSV). CSV files can then be opened directly
166 with programs like Excel, Google Docs, Open Office and Libre Office.
167
168 You could dump every statistic from a game like so::
169
170 game.players.csv('player-stats.csv')
171
172 Or if you want to get crazy, you could dump the statistics of every player
173 from an entire season::
174
175 nflgame.combine(nflgame.games(2010)).csv('season2010.csv')
176 """
177
178 try:
179 from collections import OrderedDict
180 except:
181 from ordereddict import OrderedDict
182
183 import nflgame.game
184 import nflgame.player
185 import nflgame.schedule
186 import nflgame.seq
187
188 VERSION = "1.0.7"
189
190 NoPlayers = nflgame.seq.GenPlayerStats(None)
191 """
192 NoPlayers corresponds to the identity element of a Players sequences.
193
194 Namely, adding it to any other Players sequence has no effect.
195 """
196
197 players = nflgame.player._create_players()
198 """
199 A dict of all players and meta information about each player keyed
200 by GSIS ID. (The identifiers used by NFL.com GameCenter.)
201 """
202
203
205 """
206 Finds a player (or players) with a name matching (case insensitive)
207 name and returns them as a list.
208 """
209 hits = []
210 for player in players.itervalues():
211 if player.name.lower() == name.lower():
212 hits.append(player)
213 return hits
214
215
216 -def games(year, week=None, home=None, away=None, preseason=False):
217 """
218 games returns a list of all games matching the given criteria. Each
219 game can then be queried for player statistics and information about
220 the game itself (score, winner, scoring plays, etc.).
221
222 As a special case, if the home and away teams are set to the same team,
223 then all games where that team played are returned.
224
225 Note that if a game's JSON data is not cached to disk, it is retrieved
226 from the NFL web site. A game's JSON data is *only* cached to disk once
227 the game is over, so be careful with the number of times you call this
228 while a game is going on. (i.e., don't piss off NFL.com.)
229 """
230 eids = __search_schedule(year, week, home, away, preseason)
231 if not eids:
232 return None
233 return [nflgame.game.Game(eid) for eid in eids]
234
235
236 -def one(year, week, home, away, preseason=False):
237 """
238 one returns a single game matching the given criteria. The
239 game can then be queried for player statistics and information about
240 the game itself (score, winner, scoring plays, etc.).
241
242 one returns either a single game or no games. If there are multiple games
243 matching the given criteria, an assertion is raised.
244
245 Note that if a game's JSON data is not cached to disk, it is retrieved
246 from the NFL web site. A game's JSON data is *only* cached to disk once
247 the game is over, so be careful with the number of times you call this
248 while a game is going on. (i.e., don't piss off NFL.com.)
249 """
250 eids = __search_schedule(year, week, home, away, preseason)
251 if not eids:
252 return None
253 assert len(eids) == 1, 'More than one game matches the given criteria.'
254 return nflgame.game.Game(eids[0])
255
256
258 """
259 Combines a list of games into one big player sequence.
260
261 This can be used, for example, to get Player objects corresponding to
262 statistics across an entire week, some number of weeks or an entire season.
263 """
264 return reduce(lambda ps1, ps2: ps1 + ps2, map(lambda g: g.players, games))
265
266
268 """
269 Searches the schedule to find the game identifiers matching the criteria
270 given.
271 """
272 ids = []
273 for (y, t, w, h, a), info in nflgame.schedule.games:
274 if y != year:
275 continue
276 if week is not None:
277 if isinstance(week, list) and w not in week:
278 continue
279 if not isinstance(week, list) and w != week:
280 continue
281 if home is not None and away is not None and home == away:
282 if h != home and a != home:
283 continue
284 else:
285 if home is not None and h != home:
286 continue
287 if away is not None and a != away:
288 continue
289 if preseason and t != "PRE":
290 continue
291 if not preseason and t != "REG":
292 continue
293 ids.append(info['eid'])
294 return ids
295