Skip to content

Commit

Permalink
Merge pull request #394 from SeanAmmirati/operator_bugfix
Browse files Browse the repository at this point in the history
NBA: adding TypeError checks around operations
  • Loading branch information
roclark authored Apr 19, 2020
2 parents 15e70fb + ef89497 commit 9fcd076
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 15 deletions.
53 changes: 41 additions & 12 deletions sportsreference/nba/boxscore.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class BoxscorePlayer(AbstractPlayer):
page. If the player appears in multiple tables, all of their
information will appear in one single string concatenated together.
"""

def __init__(self, player_id, player_name, player_data):
self._index = 0
self._player_id = player_id
Expand Down Expand Up @@ -195,6 +196,7 @@ class Boxscore:
The relative link to the boxscore HTML page, such as
'201710310LAL'.
"""

def __init__(self, uri):
self._uri = uri
self._date = None
Expand Down Expand Up @@ -958,16 +960,24 @@ def away_two_point_field_goals(self):
Returns an ``int`` of the total number of two point field goals made
by the away team.
"""
return self.away_field_goals - self.away_three_point_field_goals
try:
result = self.away_field_goals - self.away_three_point_field_goals
except TypeError:
result = None
return result

@int_property_decorator
def away_two_point_field_goal_attempts(self):
"""
Returns an ``int`` of the total number of two point field goal attempts
by the away team.
"""
return self.away_field_goal_attempts - \
self.away_three_point_field_goal_attempts
try:
result = self.away_field_goal_attempts - \
self.away_three_point_field_goal_attempts
except TypeError:
result = None
return result

@float_property_decorator
def away_two_point_field_goal_percentage(self):
Expand All @@ -976,9 +986,14 @@ def away_two_point_field_goal_percentage(self):
by the number of two point field goal attempts by the away team.
Percentage ranges from 0-1.
"""
result = float(self.away_two_point_field_goals) / \
float(self.away_two_point_field_goal_attempts)
return round(float(result), 3)
try:
result = float(self.away_two_point_field_goals) / \
float(self.away_two_point_field_goal_attempts)
except TypeError:
result = None
else:
result = round(float(result), 3)
return result

@int_property_decorator
def away_free_throws(self):
Expand Down Expand Up @@ -1263,16 +1278,24 @@ def home_two_point_field_goals(self):
Returns an ``int`` of the total number of two point field goals made
by the home team.
"""
return self.home_field_goals - self.home_three_point_field_goals
try:
result = self.home_field_goals - self.home_three_point_field_goals
except TypeError:
result = None
return result

@int_property_decorator
def home_two_point_field_goal_attempts(self):
"""
Returns an ``int`` of the total number of two point field goal attempts
by the home team.
"""
return self.home_field_goal_attempts - \
self.home_three_point_field_goal_attempts
try:
result = self.home_field_goal_attempts - \
self.home_three_point_field_goal_attempts
except TypeError:
result = None
return result

@float_property_decorator
def home_two_point_field_goal_percentage(self):
Expand All @@ -1281,9 +1304,14 @@ def home_two_point_field_goal_percentage(self):
by the number of two point field goal attempts by the home team.
Percentage ranges from 0-1.
"""
result = float(self.home_two_point_field_goals) / \
float(self.home_two_point_field_goal_attempts)
return round(float(result), 3)
try:
result = float(self.home_two_point_field_goals) / \
float(self.home_two_point_field_goal_attempts)
except TypeError:
result = None
else:
result = round(float(result), 3)
return result

@int_property_decorator
def home_free_throws(self):
Expand Down Expand Up @@ -1502,6 +1530,7 @@ class Boxscores:
empty, or if 'end_date' is prior to 'date', only the games from the day
specified in the 'date' parameter will be saved.
"""

def __init__(self, date, end_date=None):
self._boxscores = {}

Expand Down
10 changes: 7 additions & 3 deletions sportsreference/nba/roster.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class Player(AbstractPlayer):
'NN' is a number starting at '01' for the first time that player ID has
been used and increments by 1 for every successive player.
"""

def __init__(self, player_id):
self._most_recent_season = ''
self._index = None
Expand Down Expand Up @@ -720,9 +721,11 @@ def weight(self):
"""
Returns an ``int`` of the player's weight in pounds.
"""
if not self._weight:
return None
return int(self._weight.replace('lb', ''))
try:
result = int(self._weight.replace('lb', ''))
except AttributeError:
result = None
return result

@property
def birth_date(self):
Expand Down Expand Up @@ -1194,6 +1197,7 @@ class Roster:
respective stats which greatly reduces the time to return a response if
just the names and IDs are desired. Defaults to False.
"""

def __init__(self, team, year=None, slim=False):
self._team = team
self._slim = slim
Expand Down
136 changes: 136 additions & 0 deletions tests/unit/test_nba_boxscore.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,142 @@ def test_invalid_home_record_returns_default_losses(self):

assert self.boxscore.home_losses == 0

def test_away_two_point_field_goals_calc(self):
fake_none = PropertyMock(return_value=None)
fake_int = PropertyMock(return_value=5)

type(self.boxscore)._away_field_goals = fake_none
type(self.boxscore)._away_three_point_field_goals = fake_none

assert self.boxscore.away_two_point_field_goals is None

type(self.boxscore)._away_three_point_field_goals = fake_int
assert self.boxscore.away_two_point_field_goals is None

type(self.boxscore)._away_field_goals = fake_int
type(self.boxscore)._away_three_point_field_goals = fake_none

assert self.boxscore.away_two_point_field_goals is None

type(self.boxscore)._away_field_goals = fake_int
type(self.boxscore)._away_three_point_field_goals = fake_int

assert isinstance(self.boxscore.away_two_point_field_goals, int)

def test_away_two_point_field_goal_attempts_calc(self):
fake_none = PropertyMock(return_value=None)
fake_int = PropertyMock(return_value=5)

type(self.boxscore)._away_field_goal_attempts = fake_none
type(self.boxscore)._away_three_point_field_goal_attempts = fake_none

assert self.boxscore.away_two_point_field_goal_attempts is None

type(self.boxscore)._away_three_point_field_goal_attempts = fake_int
assert self.boxscore.away_two_point_field_goal_attempts is None

type(self.boxscore)._away_field_goal_attempts = fake_int
type(self.boxscore)._away_three_point_field_goal_attempts = fake_none

assert self.boxscore.away_two_point_field_goal_attempts is None

type(self.boxscore)._away_field_goal_attempts = fake_int
type(self.boxscore)._away_three_point_field_goal_attempts = fake_int

assert isinstance(
self.boxscore.away_two_point_field_goal_attempts, int)

def test_away_two_point_field_goal_percentage_calc(self):
fake_none = PropertyMock(return_value=None)
fake_int = PropertyMock(return_value=5)

type(self.boxscore).away_two_point_field_goals = fake_none
type(self.boxscore).away_two_point_field_goal_attempts = fake_none

assert self.boxscore.away_two_point_field_goal_percentage is None

type(self.boxscore).away_two_point_field_goal_attempts = fake_int
assert self.boxscore.away_two_point_field_goal_percentage is None

type(self.boxscore).away_two_point_field_goals = fake_int
type(self.boxscore).away_two_point_field_goal_attempts = fake_none

assert self.boxscore.away_two_point_field_goal_percentage is None

type(self.boxscore).away_two_point_field_goals = fake_int
type(self.boxscore).away_two_point_field_goal_attempts = fake_int

assert isinstance(
self.boxscore.away_two_point_field_goal_percentage, float)

def test_home_to_point_field_goals_calc(self):
fake_none = PropertyMock(return_value=None)
fake_int = PropertyMock(return_vzalue=5)

type(self.boxscore)._home_field_goals = fake_none
type(self.boxscore)._home_three_point_field_goals = fake_none

assert self.boxscore.home_two_point_field_goals is None

type(self.boxscore)._home_three_point_field_goals = fake_int
assert self.boxscore.home_two_point_field_goals is None

type(self.boxscore)._home_field_goals = fake_int
type(self.boxscore)._home_three_point_field_goals = fake_none

assert self.boxscore.home_two_point_field_goals is None

type(self.boxscore)._home_field_goals = fake_int
type(self.boxscore)._home_three_point_field_goals = fake_int

assert isinstance(self.boxscore.home_two_point_field_goals, int)

def test_home_two_point_field_goal_attempts_calc(self):
fake_none = PropertyMock(return_value=None)
fake_int = PropertyMock(return_value=5)

type(self.boxscore)._home_field_goal_attempts = fake_none
type(self.boxscore)._home_three_point_field_goal_attempts = fake_none

assert self.boxscore.home_two_point_field_goal_attempts is None

type(self.boxscore)._home_three_point_field_goal_attempts = fake_int
assert self.boxscore.home_two_point_field_goal_attempts is None

type(self.boxscore)._home_field_goal_attempts = fake_int
type(self.boxscore)._home_three_point_field_goal_attempts = fake_none

assert self.boxscore.home_two_point_field_goal_attempts is None

type(self.boxscore)._home_field_goal_attempts = fake_int
type(self.boxscore)._home_three_point_field_goal_attempts = fake_int

assert isinstance(
self.boxscore.home_two_point_field_goal_attempts, int)

def test_home_two_point_field_goal_percentage_calc(self):
fake_none = PropertyMock(return_value=None)
fake_int = PropertyMock(return_value=5)

type(self.boxscore).home_two_point_field_goals = fake_none
type(self.boxscore).home_two_point_field_goal_attempts = fake_none

assert self.boxscore.home_two_point_field_goal_percentage is None

type(self.boxscore).home_two_point_field_goal_attempts = fake_int
assert self.boxscore.home_two_point_field_goal_percentage is None

type(self.boxscore).home_two_point_field_goals = fake_int
type(self.boxscore).home_two_point_field_goal_attempts = fake_none

assert self.boxscore.home_two_point_field_goal_percentage is None

type(self.boxscore).home_two_point_field_goals = fake_int
type(self.boxscore).home_two_point_field_goal_attempts = fake_int

assert isinstance(
self.boxscore.home_two_point_field_goal_percentage, float)

def test_game_summary_with_no_scores_returns_none(self):
result = Boxscore(None)._parse_summary(pq(
"""<table id="line_score">
Expand Down

0 comments on commit 9fcd076

Please sign in to comment.