def test_get_kicking_offense(self): self.__set_kicking_consts() # Successful self.assertEqual( get_kicking_offense("DEN 35", "", "DEN", "SEA", (), ()), "away") self.assertEqual( get_kicking_offense("SEA 35", "", "DEN", "SEA", (), ()), "home") self.assertEqual( get_kicking_offense("DEN 50", "", "DEN", "SEA", (), ()), "away") self.assertEqual(get_kicking_offense("DEN", "", "DEN", "SEA", (), ()), "away") self.assertEqual( get_kicking_offense("", self.kicks[0], "DEN", "SEA", ("B. Simpson", "L. Simpson"), ("M. Simpson", )), "away") self.assertEqual( get_kicking_offense("", self.kicks[1], "DEN", "SEA", ("Shemp Howard", ), ("Moe Howard", "Larry Fine", "Curly Howard")), "home") # Failure self.assertRaises(KeyError, get_kicking_offense, "PTC 35", "", "", "", (), ()) # We squelch the warning from this test, we want the warning when # running on data, but not when testing with open(os.devnull, 'w') as f: oldstdout = sys.stdout f = open(os.devnull, 'w') sys.stdout = f # The squelched tests # Unknown kicker self.assertEqual( get_kicking_offense("", self.kicks[2], "", "", (), ()), None) # Degenerate kicker self.assertEqual( get_kicking_offense("", self.kicks[2], "", "", ("Player8", ), ("Player8", )), None) # Unknown team self.assertEqual( get_kicking_offense("DEN 35", self.kicks[2], "SEA", "SFO", (), ()), None) # Return stdout sys.stdout = oldstdout f.close()
def test_get_kicking_offense(self): self.__set_kicking_consts() # Successful self.assertEqual( get_kicking_offense( "DEN 35", "", "DEN", "SEA", (), () ), "away" ) self.assertEqual( get_kicking_offense( "SEA 35", "", "DEN", "SEA", (), () ), "home" ) self.assertEqual( get_kicking_offense( "DEN 50", "", "DEN", "SEA", (), () ), "away" ) self.assertEqual( get_kicking_offense("DEN", "", "DEN", "SEA", (), ()), "away" ) self.assertEqual( get_kicking_offense( "", self.kicks[0], "DEN", "SEA", ("B. Simpson", "L. Simpson"), ("M. Simpson",) ), "away" ) self.assertEqual( get_kicking_offense( "", self.kicks[1], "DEN", "SEA", ("Shemp Howard",), ("Moe Howard", "Larry Fine", "Curly Howard") ), "home" ) # Failure self.assertRaises( KeyError, get_kicking_offense, "PTC 35", "", "", "", (), () ) # We squelch the warning from this test, we want the warning when # running on data, but not when testing with open(os.devnull, 'w') as f: oldstdout = sys.stdout sys.stdout = f # The squelched tests # Unknown kicker self.assertEqual( get_kicking_offense("", self.kicks[2], "", "", (), ()), None ) # Degenerate kicker self.assertEqual( get_kicking_offense( "", self.kicks[2], "", "", ("Player8",), ("Player8",) ), None ) # Unknown team self.assertEqual( get_kicking_offense( "DEN 35", self.kicks[2], "SEA", "SFO", (), () ), None ) # Return stdout sys.stdout = oldstdout
def __parse_play(self): """ Set up the team stats dictionaries and add it to self.json """ soup = self.soup # Find each row of the table rows = soup.find_all("tr") for row in rows: # Deal with the different row types r_type = row_type(row.get_text(' ', strip=True)) # When setting the quarter, we need a special case to handle # overtimes after the first if r_type == 5 and self.last_play_info["quarter"] >= 5: self.current_play_info["quarter"] = self.last_play_info["quarter"] + 1 # Skip all other special rows if r_type != 0: # 0 indicates a normal row self.last_play_info = deepcopy(self.current_play_info) continue # Set the play class, which is used to indicate scores, turnovers, # and penalties self.__set_class(row) # Find each column of the table cols = row.find_all("td") if cols: # This if removes the header pbp_dict = {} # Set the number of the play first, so that if a play fails to # parse, we have a gap in the numbering to help us detect it self.current_play_info["number"] = self.last_play_info["number"] + 1 pbp_dict["number"] = self.current_play_info["number"] # Extract the plain text description and store it, because it # is used so often description = cols[5].get_text(' ', strip=True).replace('\n', ' ') # Sanitize replay challenges that they only the final result is used sanitized_description = remove_challenge(description) self.current_play_info["description"] = sanitized_description # Assign offense # We correct the 1999, 2013 kick offs when setting is_pchange if self.is_pchange: # For change of possession, we change the team with the # ball if self.last_play_info["offense"] == "home": self.current_play_info["offense"] = "away" else: self.current_play_info["offense"] = "home" else: self.current_play_info["offense"] = self.last_play_info["offense"] # Set current score pbp_dict["score"] = self.__set_score(cols) # Check the type of play pbp_dict["play"] = self.__set_play(cols) # Sometimes there are blank plays if pbp_dict["play"]["type"] is None: self.last_play_info = deepcopy(self.current_play_info) continue # On a kickoff, we make sure we have the team right if pbp_dict["play"]["type"] in {"kick off", "onside kick"}: kick_text = cols[4].get_text(' ', strip=True).replace('\n', ' ') kick_team = get_kicking_offense( kick_text, self.current_play_info["description"], self.home, self.away, self.home_players, self.away_players ) if kick_team in ["home", "away"]: self.current_play_info["offense"] = kick_team else: # Assume the last team with the ball is kicking flipped_team = self.__flip(self.last_play_info["offense"]) self.current_play_info["offense"] = flipped_team # Set penalty if self.is_penalty: pbp_dict["penalty"] = self.__set_penalty() # Parse state pbp_dict["state"] = self.__set_state(cols) turnovers = self.__set_turnover() if turnovers: pbp_dict["turnovers"] = turnovers self.json.append(pbp_dict) # Set last play info to current play info self.last_play_info = deepcopy(self.current_play_info)