diff --git a/sportsreference/nba/boxscore.py b/sportsreference/nba/boxscore.py index e85e5b75..38d2d647 100644 --- a/sportsreference/nba/boxscore.py +++ b/sportsreference/nba/boxscore.py @@ -654,15 +654,18 @@ def _parse_game_data(self, uri): continue index = 0 strip = False + secondary_index = None if short_field in BOXSCORE_ELEMENT_INDEX.keys(): index = BOXSCORE_ELEMENT_INDEX[short_field] + secondary_index = 1 if short_field == 'home_record': strip = True value = utils._parse_field(BOXSCORE_SCHEME, boxscore, short_field, index, - strip) + strip, + secondary_index) setattr(self, field, value) self._away_players, self._home_players = self._find_players(boxscore) diff --git a/sportsreference/nba/constants.py b/sportsreference/nba/constants.py index dd78c422..91c7ac68 100644 --- a/sportsreference/nba/constants.py +++ b/sportsreference/nba/constants.py @@ -153,41 +153,41 @@ 'date': 0, 'location': 1, 'home_record': -1, - 'home_minutes_played': 1, - 'home_field_goals': 1, - 'home_field_goal_attempts': 1, - 'home_field_goal_percentage': 1, - 'home_two_point_field_goals': 1, - 'home_two_point_field_goal_attempts': 1, - 'home_two_point_field_goal_percentage': 1, - 'home_three_point_field_goals': 1, - 'home_three_point_field_goal_attempts': 1, - 'home_three_point_field_goal_percentage': 1, - 'home_free_throws': 1, - 'home_free_throw_attempts': 1, - 'home_free_throw_percentage': 1, - 'home_offensive_rebounds': 1, - 'home_defensive_rebounds': 1, - 'home_total_rebounds': 1, - 'home_assists': 1, - 'home_steals': 1, - 'home_blocks': 1, - 'home_turnovers': 1, - 'home_personal_fouls': 1, + 'home_minutes_played': 7, + 'home_field_goals': 7, + 'home_field_goal_attempts': 7, + 'home_field_goal_percentage': 7, + 'home_two_point_field_goals': 7, + 'home_two_point_field_goal_attempts': 7, + 'home_two_point_field_goal_percentage': 7, + 'home_three_point_field_goals': 7, + 'home_three_point_field_goal_attempts': 7, + 'home_three_point_field_goal_percentage': 7, + 'home_free_throws': 7, + 'home_free_throw_attempts': 7, + 'home_free_throw_percentage': 7, + 'home_offensive_rebounds': 7, + 'home_defensive_rebounds': 7, + 'home_total_rebounds': 7, + 'home_assists': 7, + 'home_steals': 7, + 'home_blocks': 7, + 'home_turnovers': 7, + 'home_personal_fouls': 7, 'home_points': -1, - 'home_true_shooting_percentage': 1, - 'home_effective_field_goal_percentage': 1, - 'home_three_point_attempt_rate': 1, - 'home_free_throw_attempt_rate': 1, - 'home_offensive_rebound_percentage': 1, - 'home_defensive_rebound_percentage': 1, - 'home_total_rebound_percentage': 1, - 'home_assist_percentage': 1, - 'home_steal_percentage': 1, - 'home_block_percentage': 1, - 'home_turnover_percentage': 1, - 'home_offensive_rating': 1, - 'home_defensive_rating': 1 + 'home_true_shooting_percentage': 7, + 'home_effective_field_goal_percentage': 7, + 'home_three_point_attempt_rate': 7, + 'home_free_throw_attempt_rate': 7, + 'home_offensive_rebound_percentage': 7, + 'home_defensive_rebound_percentage': 7, + 'home_total_rebound_percentage': 7, + 'home_assist_percentage': 7, + 'home_steal_percentage': 7, + 'home_block_percentage': 7, + 'home_turnover_percentage': 7, + 'home_offensive_rating': 7, + 'home_defensive_rating': 7 } PLAYER_SCHEME = { diff --git a/sportsreference/utils.py b/sportsreference/utils.py index 5e8febb3..35e89790 100644 --- a/sportsreference/utils.py +++ b/sportsreference/utils.py @@ -148,7 +148,8 @@ def _parse_abbreviation(uri_link): return abbr.upper() -def _parse_field(parsing_scheme, html_data, field, index=0, strip=False): +def _parse_field(parsing_scheme, html_data, field, index=0, strip=False, + secondary_index=None): """ Parse an HTML table to find the requested field's value. @@ -182,6 +183,12 @@ def _parse_field(parsing_scheme, html_data, field, index=0, strip=False): elements which might show up during list comprehensions. Specify True if the invalid elements should be removed from lists, which can help with reverse indexing. + secondary_index : int (optional) + An optional index if multiple fields have the same attribute, but the + original index specified above doesn't work. This happens if a page + doesn't have all of the intended information, and the requested index + isn't valid, causing the value to be None. Instead, a secondary index + could be checked prior to returning None. Returns ------- @@ -205,6 +212,11 @@ def _parse_field(parsing_scheme, html_data, field, index=0, strip=False): try: return items[index] except IndexError: + if secondary_index: + try: + return items[secondary_index] + except IndexError: + return None return None diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index e25b1d5c..3983f7a3 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -297,7 +297,40 @@ def test_pulling_data_with_no_inputs(self, *args, **kwargs): with pytest.raises(ValueError): utils._pull_page() - def test_pulling_local_file(seld, *args, **kwargs): + def test_pulling_local_file(self, *args, **kwargs): output = utils._pull_page(local_file='VERSION') assert output + + def test_secondary_index_pulling_values(self): + parsing_scheme = {'batters_used': 'td[data-stat="batters_used"]'} + html_string = '''32 +29.1 +4.10 +31 +34''' + items = [32, 31, 34] + expected = 31 + + result = utils._parse_field(parsing_scheme, + MockHtml(html_string, items), + 'batters_used', + index=3, + secondary_index=1) + assert result == expected + + def test_secondary_index_pulling_values_bad_secondary(self): + parsing_scheme = {'batters_used': 'td[data-stat="batters_used"]'} + html_string = '''32 +29.1 +4.10 +31 +34''' + items = [32, 31, 34] + + result = utils._parse_field(parsing_scheme, + MockHtml(html_string, items), + 'batters_used', + index=3, + secondary_index=4) + assert not result