Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix NFL players wrongly being listed as away #507

Merged
merged 1 commit into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions sportsreference/nfl/boxscore.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ def _find_home_or_away(self, row):
the home or away team.
"""
name = row('td[data-stat="team"]').text().upper()
if self._home_abbr and name == self._home_abbr.upper():
return HOME
if self._away_abbr and name == self._away_abbr.upper():
return AWAY
if name == self.home_abbreviation.upper():
return HOME
else:
Expand Down Expand Up @@ -698,6 +702,35 @@ def _find_players(self, boxscore):
away_players, home_players = self._instantiate_players(player_dict)
return away_players, home_players

def _alt_abbreviations(self, boxscore):
"""
Find the alternative abbreviations for both teams.

The listed team abbreviations are occasionally different from the
abbreviations used on sports-reference.com to identify a team. In order
properly match a player to a specific team, the abbreviations must be
parsed directly from the page instead of the URI links.

Parameters
----------
boxscore : PyQuery object
A PyQuery object containing all of the HTML data from the boxscore.

Returns
-------
tuple
Returns a ``tuple`` in the format (away_abbr, home_abbr)
where each element is a string of the away and home team's
abbreviations, respectively.
"""
abbreviations = []
game_info = boxscore(BOXSCORE_SCHEME['team_stats'])

for column in game_info('th').items():
if column.text():
abbreviations.append(column.text())
return abbreviations

def _parse_game_data(self, uri):
"""
Parses a value for every attribute.
Expand Down Expand Up @@ -763,6 +796,7 @@ def _parse_game_data(self, uri):
setattr(self, field, value)
self._parse_game_date_and_location(boxscore)
self._parse_game_details(boxscore)
self._away_abbr, self._home_abbr = self._alt_abbreviations(boxscore)
self._away_players, self._home_players = self._find_players(boxscore)

@property
Expand Down
1 change: 1 addition & 0 deletions sportsreference/nfl/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
'game_details': 'table#game_info tr',
'home_name': 'a[itemprop="name"]:first',
'summary': 'table[class="linescore nohover stats_table no_freeze"]:first',
'team_stats': 'table#team_stats thead',
'away_name': 'a[itemprop="name"]:last',
'away_points': 'div[class="scorebox"] div[class="score"]',
'away_first_downs': 'td[data-stat="vis_stat"]',
Expand Down
28 changes: 20 additions & 8 deletions tests/unit/test_nfl_boxscore.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ def test_winning_abbr_is_home(self):
.and_return(expected_name)

fake_winner = PropertyMock(return_value=HOME)
fake_home_abbr = PropertyMock(return_value=MockName(expected_name))
type(self.boxscore).winner = fake_winner
type(self.boxscore)._home_abbr = fake_home_abbr

assert self.boxscore.winning_abbr == expected_name

Expand All @@ -124,9 +122,7 @@ def test_winning_abbr_is_away(self):
.and_return(expected_name)

fake_winner = PropertyMock(return_value=AWAY)
fake_away_abbr = PropertyMock(return_value=MockName(expected_name))
type(self.boxscore).winner = fake_winner
type(self.boxscore)._away_abbr = fake_away_abbr

assert self.boxscore.winning_abbr == expected_name

Expand Down Expand Up @@ -158,9 +154,7 @@ def test_losing_abbr_is_home(self):
.and_return(expected_name)

fake_winner = PropertyMock(return_value=AWAY)
fake_home_abbr = PropertyMock(return_value=MockName(expected_name))
type(self.boxscore).winner = fake_winner
type(self.boxscore)._home_abbr = fake_home_abbr

assert self.boxscore.losing_abbr == expected_name

Expand All @@ -172,9 +166,7 @@ def test_losing_abbr_is_away(self):
.and_return(expected_name)

fake_winner = PropertyMock(return_value=HOME)
fake_away_abbr = PropertyMock(return_value=MockName(expected_name))
type(self.boxscore).winner = fake_winner
type(self.boxscore)._away_abbr = fake_away_abbr

assert self.boxscore.losing_abbr == expected_name

Expand Down Expand Up @@ -324,6 +316,26 @@ def test_nfl_game_details(self):
for field, value in fields.items():
assert getattr(self.boxscore, field) == value

def test_finding_home_team_with_no_abbrs(self):
mock_html = pq('<td data-stat="team">KAN</td>')
abbr = PropertyMock(return_value='KAN')
self.boxscore._home_abbr = None
self.boxscore._away_abbr = None
type(self.boxscore).home_abbreviation = abbr
team = self.boxscore._find_home_or_away(mock_html)

assert team == HOME

def test_finding_away_team_with_no_abbrs(self):
mock_html = pq('<td data-stat="team">HTX</td>')
abbr = PropertyMock(return_value='KAN')
self.boxscore._home_abbr = None
self.boxscore._away_abbr = None
type(self.boxscore).home_abbreviation = abbr
team = self.boxscore._find_home_or_away(mock_html)

assert team == AWAY


class TestNFLBoxscores:
@patch('requests.get', side_effect=mock_pyquery)
Expand Down