diff --git a/README.md b/README.md index e40acc85..0e4a60b2 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,13 @@ Team(Team 1) >>> matchups[0].away_team Team(Team 10) ``` +### Get power rankings +```python +>>> from ff_espn_api import League +>>> league = League(1234, 2018) +>>> league.power_rankings(week=13) +[('70.85', Team(Team 7)), ('65.20', Team(Team 1)), ('62.45', Team(Team 8)), ('57.70', Team(THE KING)), ('45.10', Team(Team Mizrachi)), ('42.80', Team(Team 10)), ('40.65', Team(Team Viking Queen)), ('37.30', Team(Team 2)), ('27.85', Team(Team 5)), ('20.40', Team(FANTASY GOD))] +``` ### Helper functions ```python diff --git a/ff_espn_api/league.py b/ff_espn_api/league.py index 13c62861..9506c270 100644 --- a/ff_espn_api/league.py +++ b/ff_espn_api/league.py @@ -9,6 +9,7 @@ from .settings import Settings from .matchup import Matchup from .pick import Pick +from .utils import power_points, two_step_dominance def checkRequestStatus(status: int) -> None: @@ -277,3 +278,24 @@ def scoreboard(self, week=None): matchup.away_team = team return matchups + + def power_rankings(self, week): + '''Return power rankings for any week''' + + if week <= 0 or week > self.current_week: + week = self.current_week + # calculate win for every week + win_matrix = [] + teams_sorted = sorted(self.teams, key=lambda x: x.team_id, + reverse=False) + + for team in teams_sorted: + wins = [0]*32 + for mov, opponent in zip(team.mov[:week], team.schedule[:week]): + opp = int(opponent.team_id)-1 + if mov > 0: + wins[opp] += 1 + win_matrix.append(wins) + dominance_matrix = two_step_dominance(win_matrix) + power_rank = power_points(dominance_matrix, teams_sorted, week) + return power_rank diff --git a/ff_espn_api/utils.py b/ff_espn_api/utils.py new file mode 100644 index 00000000..245b1ad5 --- /dev/null +++ b/ff_espn_api/utils.py @@ -0,0 +1,51 @@ +# Helper functions for power rankings + +def square_matrix(X): + '''Squares a matrix''' + result = [[0.0 for x in range(len(X))] for y in range(len(X))] + + # iterate through rows of X + for i in range(len(X)): + + # iterate through columns of X + for j in range(len(X)): + + # iterate through rows of X + for k in range(len(X)): + result[i][j] += X[i][k] * X[k][j] + + return result + + +def add_matrix(X, Y): + '''Adds two matrices''' + result = [[0.0 for x in range(len(X))] for y in range(len(X))] + + for i in range(len(X)): + + # iterate through columns + for j in range(len(X)): + result[i][j] = X[i][j] + Y[i][j] + + return result + + +def two_step_dominance(X): + '''Returns result of two step dominance formula''' + matrix = add_matrix(square_matrix(X), X) + result = [sum(x) for x in matrix] + return result + + +def power_points(dominance, teams, week): + '''Returns list of power points''' + power_points = [] + for i, team in zip(dominance, teams): + avg_score = sum(team.scores[:week]) / week + avg_mov = sum(team.mov[:week]) / week + + power = '{0:.2f}'.format((int(i)*0.8) + (int(avg_score)*0.15) + + (int(avg_mov)*0.05)) + power_points.append(power) + power_tup = [(i, j) for (i, j) in zip(power_points, teams)] + return sorted(power_tup, key=lambda tup: float(tup[0]), reverse=True) \ No newline at end of file diff --git a/tests/unit/test_league.py b/tests/unit/test_league.py index bf6c03c0..16532ad7 100644 --- a/tests/unit/test_league.py +++ b/tests/unit/test_league.py @@ -180,4 +180,20 @@ def test_draft(self, m): self.assertEqual(repr(first_pick), 'Pick(Le\'Veon Bell, Team(Rollin\' With Mahomies))') self.assertEqual(third_pick.round_num, 1) self.assertEqual(third_pick.round_pick, 3) + + @requests_mock.Mocker() + def test_power_rankings(self, m): + self.mock_setUp(m) + + league = League(self.league_id, self.season) + + invalid_week = league.power_rankings(0) + current_week = league.power_rankings(league.current_week) + self.assertEqual(invalid_week, current_week) + + valid_week = league.power_rankings(13) + self.assertEqual(valid_week[0][0], '71.70') + self.assertEqual(repr(valid_week[0][1]), 'Team(Misunderstood Mistfits )') + +