From b47b34bd660084de13c5cdc23e2fd2f88cf6b0f4 Mon Sep 17 00:00:00 2001 From: Mateusz Zawadzki Date: Wed, 6 May 2020 08:37:57 +0200 Subject: [PATCH] Add coach to Roster The coach or manager's full name is now a property that can be retrieved from a team's Roster class. --- sportsreference/mlb/constants.py | 1 + sportsreference/mlb/roster.py | 36 +++++++++++++++++- sportsreference/nba/constants.py | 1 + sportsreference/nba/nba_utils.py | 1 + sportsreference/nba/roster.py | 37 +++++++++++++++++-- sportsreference/ncaab/constants.py | 1 + sportsreference/ncaab/roster.py | 36 +++++++++++++++++- sportsreference/ncaaf/constants.py | 1 + sportsreference/ncaaf/roster.py | 36 +++++++++++++++++- sportsreference/nfl/constants.py | 1 + sportsreference/nfl/roster.py | 36 +++++++++++++++++- sportsreference/nhl/constants.py | 1 + sportsreference/nhl/roster.py | 36 +++++++++++++++++- tests/integration/roster/test_mlb_roster.py | 3 ++ tests/integration/roster/test_nba_roster.py | 3 ++ tests/integration/roster/test_ncaab_roster.py | 3 ++ tests/integration/roster/test_ncaaf_roster.py | 3 ++ tests/integration/roster/test_nfl_roster.py | 3 ++ tests/integration/roster/test_nhl_roster.py | 3 ++ 19 files changed, 229 insertions(+), 13 deletions(-) diff --git a/sportsreference/mlb/constants.py b/sportsreference/mlb/constants.py index 72ddb865..d552a88f 100644 --- a/sportsreference/mlb/constants.py +++ b/sportsreference/mlb/constants.py @@ -306,6 +306,7 @@ } PLAYER_SCHEME = { + 'summary': '[data-template="Partials/Teams/Summary"]', 'season': 'th[data-stat="year_ID"]', 'name': 'h1[itemprop="name"]', 'team_abbreviation': 'td[data-stat="team_ID"]', diff --git a/sportsreference/mlb/roster.py b/sportsreference/mlb/roster.py index a9ec533f..dd4aadd2 100644 --- a/sportsreference/mlb/roster.py +++ b/sportsreference/mlb/roster.py @@ -1450,12 +1450,13 @@ class Roster: def __init__(self, team, year=None, slim=False): self._team = team self._slim = slim + self._coach = None if slim: self._players = {} else: self._players = [] - self._find_players(year) + self._find_players_with_coach(year) def __str__(self): """ @@ -1555,7 +1556,29 @@ def _get_name(self, player): name_tag = player('td[data-stat="player"] a') return name_tag.text() - def _find_players(self, year): + def _parse_coach(self, page): + """ + Parse the team's coach. + + Given a copy of the team's roster page, find and parse the team's + coach from the team summary. + + Parameters + ---------- + page : PyQuery object + A PyQuery object representing the team's roster page. + + Returns + ------- + string + Returns a string of the coach's name. + """ + for line in page(PLAYER_SCHEME['summary']).find('p').items(): + strong = line.find('strong') + if hasattr(strong, 'text') and strong.text().strip() == 'Manager:': + return line.find('a').text() + + def _find_players_with_coach(self, year): """ Find all player IDs for the requested team. @@ -1614,6 +1637,8 @@ def _find_players(self, year): player_instance = Player(player_id) self._players.append(player_instance) + self._coach = self._parse_coach(page) + @property def players(self): """ @@ -1624,3 +1649,10 @@ def players(self): first and last name as listed on the roster page. """ return self._players + + @property + def coach(self): + """ + Returns a ``string`` of the coach's name, such as 'AJ Hinch'. + """ + return self._coach diff --git a/sportsreference/nba/constants.py b/sportsreference/nba/constants.py index 91c7ac68..07709ff2 100644 --- a/sportsreference/nba/constants.py +++ b/sportsreference/nba/constants.py @@ -191,6 +191,7 @@ } PLAYER_SCHEME = { + 'summary': '[data-template="Partials/Teams/Summary"]', 'season': 'th[data-stat="season"]:first', 'name': 'h1', 'team_abbreviation': 'td[data-stat="team_id"]', diff --git a/sportsreference/nba/nba_utils.py b/sportsreference/nba/nba_utils.py index ef1973fb..7b7e5723 100644 --- a/sportsreference/nba/nba_utils.py +++ b/sportsreference/nba/nba_utils.py @@ -84,6 +84,7 @@ def _retrieve_all_teams(year, season_file=None): doc = utils._pull_page(SEASON_PAGE_URL % year, season_file) teams_list = utils._get_stats_table(doc, 'div#all_team-stats-base') opp_teams_list = utils._get_stats_table(doc, 'div#all_opponent-stats-base') + if not teams_list and not opp_teams_list: utils._no_data_found() return None, None diff --git a/sportsreference/nba/roster.py b/sportsreference/nba/roster.py index 2bf1ba2e..eb5eb803 100644 --- a/sportsreference/nba/roster.py +++ b/sportsreference/nba/roster.py @@ -1384,12 +1384,12 @@ class Roster: def __init__(self, team, year=None, slim=False): self._team = team self._slim = slim + self._coach = None if slim: self._players = {} else: self._players = [] - - self._find_players(year) + self._find_players_with_coach(year) def __str__(self): """ @@ -1489,7 +1489,29 @@ def _get_name(self, player): name_tag = player('td[data-stat="player"] a') return name_tag.text() - def _find_players(self, year): + def _parse_coach(self, page): + """ + Parse the team's coach. + + Given a copy of the team's roster page, find and parse the team's + coach from the team summary. + + Parameters + ---------- + page : PyQuery object + A PyQuery object representing the team's roster page. + + Returns + ------- + string + Returns a string of the coach's name. + """ + for line in page(PLAYER_SCHEME['summary']).find('p').items(): + strong = line.find('strong') + if hasattr(strong, 'text') and strong.text().strip() == 'Coach:': + return line.find('a').text() + + def _find_players_with_coach(self, year): """ Find all player IDs for the requested team. @@ -1541,6 +1563,8 @@ def _find_players(self, year): player_instance = Player(player_id) self._players.append(player_instance) + self._coach = self._parse_coach(page) + @property def players(self): """ @@ -1551,3 +1575,10 @@ def players(self): first and last name as listed on the roster page. """ return self._players + + @property + def coach(self): + """ + Returns a ``string`` of the coach's name, such as "Mike D'Antoni". + """ + return self._coach diff --git a/sportsreference/ncaab/constants.py b/sportsreference/ncaab/constants.py index f5c887a2..bd24c9ec 100644 --- a/sportsreference/ncaab/constants.py +++ b/sportsreference/ncaab/constants.py @@ -247,6 +247,7 @@ } PLAYER_SCHEME = { + 'summary': '[data-template="Partials/Teams/Summary"]', 'conference': 'td[data-stat="conf_abbr"]', 'season': 'th[data-stat="season"]:first', 'name': 'h1', diff --git a/sportsreference/ncaab/roster.py b/sportsreference/ncaab/roster.py index aa8b55a4..ea4231fd 100644 --- a/sportsreference/ncaab/roster.py +++ b/sportsreference/ncaab/roster.py @@ -656,12 +656,13 @@ class Roster: def __init__(self, team, year=None, slim=False): self._team = team self._slim = slim + self._coach = None if slim: self._players = {} else: self._players = [] - self._find_players(year) + self._find_players_with_coach(year) def __str__(self): """ @@ -761,7 +762,29 @@ def _get_name(self, player): name_tag = player('th[data-stat="player"] a') return name_tag.text() - def _find_players(self, year): + def _parse_coach(self, page): + """ + Parse the team's coach. + + Given a copy of the team's roster page, find and parse the team's + coach from the team summary. + + Parameters + ---------- + page : PyQuery object + A PyQuery object representing the team's roster page. + + Returns + ------- + string + Returns a string of the coach's name. + """ + for line in page(PLAYER_SCHEME['summary']).find('p').items(): + strong = line.find('strong') + if hasattr(strong, 'text') and strong.text().strip() == 'Coach:': + return line.find('a').text() + + def _find_players_with_coach(self, year): """ Find all player IDs for the requested team. @@ -802,6 +825,8 @@ def _find_players(self, year): player_instance = Player(player_id) self._players.append(player_instance) + self._coach = self._parse_coach(page) + @property def players(self): """ @@ -812,3 +837,10 @@ def players(self): first and last name as listed on the roster page. """ return self._players + + @property + def coach(self): + """ + Returns a ``string`` of the coach's name, such as 'Matt Painter'. + """ + return self._coach diff --git a/sportsreference/ncaaf/constants.py b/sportsreference/ncaaf/constants.py index 6c50b61b..5b131500 100644 --- a/sportsreference/ncaaf/constants.py +++ b/sportsreference/ncaaf/constants.py @@ -247,6 +247,7 @@ } PLAYER_SCHEME = { + 'summary': '[data-template="Partials/Teams/Summary"]', 'season': 'th[data-stat="year_id"]', 'name': 'h1[itemprop="name"]', 'team_abbreviation': 'td[data-stat="school_name"]', diff --git a/sportsreference/ncaaf/roster.py b/sportsreference/ncaaf/roster.py index c6a6d40d..02d85633 100644 --- a/sportsreference/ncaaf/roster.py +++ b/sportsreference/ncaaf/roster.py @@ -883,12 +883,13 @@ class Roster: def __init__(self, team, year=None, slim=False): self._team = team self._slim = slim + self._coach = None if slim: self._players = {} else: self._players = [] - self._find_players(year) + self._find_players_with_coach(year) def __str__(self): """ @@ -988,7 +989,29 @@ def _get_name(self, player): name_tag = player('th[data-stat="player"] a') return name_tag.text() - def _find_players(self, year): + def _parse_coach(self, page): + """ + Parse the team's coach. + + Given a copy of the team's roster page, find and parse the team's + coach from the team summary. + + Parameters + ---------- + page : PyQuery object + A PyQuery object representing the team's roster page. + + Returns + ------- + string + Returns a string of the coach's name. + """ + for line in page(PLAYER_SCHEME['summary']).find('p').items(): + strong = line.find('strong') + if hasattr(strong, 'text') and strong.text().strip() == 'Coach:': + return line.find('a').text() + + def _find_players_with_coach(self, year): """ Find all player IDs for the requested team. @@ -1028,6 +1051,8 @@ def _find_players(self, year): player_instance = Player(player_id) self._players.append(player_instance) + self._coach = self._parse_coach(page) + @property def players(self): """ @@ -1038,3 +1063,10 @@ def players(self): first and last name as listed on the roster page. """ return self._players + + @property + def coach(self): + """ + Returns a ``string`` of the coach's name, such as 'Jeff Brohm'. + """ + return self._coach diff --git a/sportsreference/nfl/constants.py b/sportsreference/nfl/constants.py index fe2afaef..f764862a 100644 --- a/sportsreference/nfl/constants.py +++ b/sportsreference/nfl/constants.py @@ -229,6 +229,7 @@ } PLAYER_SCHEME = { + 'summary': '[data-template="Partials/Teams/Summary"]', 'season': 'th[data-stat="year_id"]', 'name': 'h1[itemprop="name"]', 'team_abbreviation': 'td[data-stat="team"]', diff --git a/sportsreference/nfl/roster.py b/sportsreference/nfl/roster.py index 3253c337..73d501a7 100644 --- a/sportsreference/nfl/roster.py +++ b/sportsreference/nfl/roster.py @@ -1708,12 +1708,13 @@ class Roster: def __init__(self, team, year=None, slim=False): self._team = team self._slim = slim + self._coach = None if slim: self._players = {} else: self._players = [] - self._find_players(year) + self._find_players_with_coach(year) def __str__(self): """ @@ -1813,7 +1814,29 @@ def _get_name(self, player): name_tag = player('td[data-stat="player"] a') return name_tag.text() - def _find_players(self, year): + def _parse_coach(self, page): + """ + Parse the team's coach. + + Given a copy of the team's roster page, find and parse the team's + coach from the team summary. + + Parameters + ---------- + page : PyQuery object + A PyQuery object representing the team's roster page. + + Returns + ------- + string + Returns a string of the coach's name. + """ + for line in page(PLAYER_SCHEME['summary']).find('p').items(): + strong = line.find('strong') + if hasattr(strong, 'text') and strong.text().strip() == 'Coach:': + return line.find('a').text() + + def _find_players_with_coach(self, year): """ Find all player IDs for the requested team. @@ -1853,6 +1876,8 @@ def _find_players(self, year): player_instance = Player(player_id) self._players.append(player_instance) + self._coach = self._parse_coach(page) + @property def players(self): """ @@ -1863,3 +1888,10 @@ def players(self): first and last name as listed on the roster page. """ return self._players + + @property + def coach(self): + """ + Returns a ``string`` of the coach's name, such as 'Sean Payton'. + """ + return self._coach diff --git a/sportsreference/nhl/constants.py b/sportsreference/nhl/constants.py index 724e1d3d..9650b917 100644 --- a/sportsreference/nhl/constants.py +++ b/sportsreference/nhl/constants.py @@ -122,6 +122,7 @@ } PLAYER_SCHEME = { + 'summary': '[data-template="Partials/Teams/Summary"]', 'season': 'th[data-stat="season"]', 'name': 'h1[itemprop="name"]', 'team_abbreviation': 'td[data-stat="team_id"]', diff --git a/sportsreference/nhl/roster.py b/sportsreference/nhl/roster.py index 36d98446..87f25978 100644 --- a/sportsreference/nhl/roster.py +++ b/sportsreference/nhl/roster.py @@ -1105,12 +1105,13 @@ class Roster: def __init__(self, team, year=None, slim=False): self._team = team self._slim = slim + self._coach = None if slim: self._players = {} else: self._players = [] - self._find_players(year) + self._find_players_with_coach(year) def __str__(self): """ @@ -1208,7 +1209,29 @@ def _get_name(self, player): name_tag = player('td[data-stat="player"] a') return name_tag.text() - def _find_players(self, year): + def _parse_coach(self, page): + """ + Parse the team's coach. + + Given a copy of the team's roster page, find and parse the team's + coach from the team summary. + + Parameters + ---------- + page : PyQuery object + A PyQuery object representing the team's roster page. + + Returns + ------- + string + Returns a string of the coach's name. + """ + for line in page(PLAYER_SCHEME['summary']).find('p').items(): + strong = line.find('strong') + if hasattr(strong, 'text') and strong.text().strip() == 'Coach:': + return line.find('a').text() + + def _find_players_with_coach(self, year): """ Find all player IDs for the requested team. @@ -1248,6 +1271,8 @@ def _find_players(self, year): player_instance = Player(player_id) self._players.append(player_instance) + self._coach = self._parse_coach(page) + @property def players(self): """ @@ -1258,3 +1283,10 @@ def players(self): first and last name as listed on the roster page. """ return self._players + + @property + def coach(self): + """ + Returns a ``string`` of the coach's name, such as 'Jeff Blashill'. + """ + return self._coach diff --git a/tests/integration/roster/test_mlb_roster.py b/tests/integration/roster/test_mlb_roster.py index b5515a89..907c5257 100644 --- a/tests/integration/roster/test_mlb_roster.py +++ b/tests/integration/roster/test_mlb_roster.py @@ -1251,3 +1251,6 @@ def test_roster_class_string_representation(self, *args, **kwargs): roster = Roster('HOU') assert roster.__repr__() == expected + + def test_coach(self): + assert "AJ Hinch" == Roster('HOU', year=YEAR).coach diff --git a/tests/integration/roster/test_nba_roster.py b/tests/integration/roster/test_nba_roster.py index de2a227c..7f711d12 100644 --- a/tests/integration/roster/test_nba_roster.py +++ b/tests/integration/roster/test_nba_roster.py @@ -1326,3 +1326,6 @@ def test_roster_class_string_representation(self, *args, **kwargs): roster = Roster('HOU') assert roster.__repr__() == expected + + def test_coach(self): + assert "Mike D'Antoni" == Roster('HOU').coach diff --git a/tests/integration/roster/test_ncaab_roster.py b/tests/integration/roster/test_ncaab_roster.py index 7e849838..de9a0704 100644 --- a/tests/integration/roster/test_ncaab_roster.py +++ b/tests/integration/roster/test_ncaab_roster.py @@ -445,3 +445,6 @@ def test_roster_class_string_representation(self, *args, **kwargs): roster = Roster('PURDUE') assert roster.__repr__() == expected + + def test_coach(self): + assert "Matt Painter" == Roster('PURDUE', year=YEAR).coach diff --git a/tests/integration/roster/test_ncaaf_roster.py b/tests/integration/roster/test_ncaaf_roster.py index ac0fad00..33efabfa 100644 --- a/tests/integration/roster/test_ncaaf_roster.py +++ b/tests/integration/roster/test_ncaaf_roster.py @@ -574,3 +574,6 @@ def test_roster_class_string_representation(self, *args, **kwargs): roster = Roster('PURDUE') assert roster.__repr__() == expected + + def test_coach(self): + assert "Troy Calhoun" == Roster('air-force', year=YEAR).coach diff --git a/tests/integration/roster/test_nfl_roster.py b/tests/integration/roster/test_nfl_roster.py index ce931b45..2f465d53 100644 --- a/tests/integration/roster/test_nfl_roster.py +++ b/tests/integration/roster/test_nfl_roster.py @@ -1496,3 +1496,6 @@ def test_roster_class_string_representation(self, *args, **kwargs): roster = Roster('NOR') assert roster.__repr__() == expected + + def test_coach(self): + assert "Sean Payton" == Roster('NOR', year=YEAR).coach diff --git a/tests/integration/roster/test_nhl_roster.py b/tests/integration/roster/test_nhl_roster.py index 5d02cdff..5db38bb2 100644 --- a/tests/integration/roster/test_nhl_roster.py +++ b/tests/integration/roster/test_nhl_roster.py @@ -756,3 +756,6 @@ def test_roster_class_string_representation(self, *args, **kwargs): roster = Roster('DET') assert roster.__repr__() == expected + + def test_coach(self): + assert "Jeff Blashill" == Roster('DET', year=YEAR).coach