From 3b17831683e7d2d5c32a1012e39759efc74f08bc Mon Sep 17 00:00:00 2001 From: Sean Ammirati Date: Sat, 11 Apr 2020 21:33:37 -0400 Subject: [PATCH 1/2] adding TypeError checks around operations --- sportsreference/nba/boxscore.py | 53 +++++++++++++++++++++++++-------- sportsreference/nba/roster.py | 6 +++- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/sportsreference/nba/boxscore.py b/sportsreference/nba/boxscore.py index 8101474d..b6f54532 100644 --- a/sportsreference/nba/boxscore.py +++ b/sportsreference/nba/boxscore.py @@ -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 @@ -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 @@ -958,7 +960,11 @@ 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): @@ -966,8 +972,12 @@ 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): @@ -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): @@ -1263,7 +1278,11 @@ 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): @@ -1271,8 +1290,12 @@ 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): @@ -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): @@ -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 = {} diff --git a/sportsreference/nba/roster.py b/sportsreference/nba/roster.py index f23ec2ee..c983a69b 100644 --- a/sportsreference/nba/roster.py +++ b/sportsreference/nba/roster.py @@ -720,7 +720,11 @@ def weight(self): """ Returns an ``int`` of the player's weight in pounds. """ - return int(self._weight.replace('lb', '')) + try: + result = int(self._weight.replace('lb', '')) + except AttributeError: + result = None + return result @property def birth_date(self): From 686f20c7b3044cc3879055a6d17e662a66327b5d Mon Sep 17 00:00:00 2001 From: Sean Ammirati Date: Mon, 13 Apr 2020 21:07:06 -0400 Subject: [PATCH 2/2] adding unittesting for operation type checks --- tests/unit/test_nba_boxscore.py | 136 ++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/tests/unit/test_nba_boxscore.py b/tests/unit/test_nba_boxscore.py index bddb8c4b..25bb4a01 100644 --- a/tests/unit/test_nba_boxscore.py +++ b/tests/unit/test_nba_boxscore.py @@ -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( """