Skip to content

Commit

Permalink
docstring updates and type hints
Browse files Browse the repository at this point in the history
  • Loading branch information
Will McGinnis committed Mar 29, 2020
1 parent 7af92d7 commit f91a1f4
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 55 deletions.
18 changes: 9 additions & 9 deletions docs/source/competitors.rst
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
Competitors
===========

.. autoclass:: elote.competitors.dwz.DWZCompetitor
:members:

.. autoclass:: elote.competitors.ecf.ECFCompetitor
:members:

.. autoclass:: elote.competitors.elo.EloCompetitor
:members:
:members: export_state,expected_score,beat,tied

.. autoclass:: elote.competitors.glicko.GlickoCompetitor
:members:
:members: export_state,expected_score,beat,tied

.. autoclass:: elote.competitors.dwz.DWZCompetitor
:members: export_state,expected_score,beat,tied

.. autoclass:: elote.competitors.ecf.ECFCompetitor
:members: export_state,expected_score,beat,tied

.. autoclass:: elote.competitors.ensemble.BlendedCompetitor
:members:
:members: export_state,expected_score,beat,tied
24 changes: 15 additions & 9 deletions elote/competitors/dwz.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class DWZCompetitor(BaseCompetitor):
_J = 10

def __init__(self, initial_rating=400):
def __init__(self, initial_rating: float = 400):
"""
class vars:
Expand Down Expand Up @@ -36,11 +36,13 @@ def export_state(self):
}
}

def expected_score(self, competitor):
def expected_score(self, competitor: BaseCompetitor):
"""
The expected outcome of a match between this competitor and one passed in. Scaled between 0-1, where 1 is a strong
likelihood of this competitor winning and 0 is a strong likelihood of this competitor losing.
:param competitor:
:return:
:param competitor: another EloCompetitor to compare this competitor to.
:return: likelihood to beat the passed competitor, as a float 0-1.
"""
self.verify_competitor_types(competitor)

Expand All @@ -65,9 +67,12 @@ def _E(self):
def _new_rating(self, competitor, W_a):
return self.rating + (800 / (self._E + self._count)) * (W_a - self.expected_score(competitor))

def beat(self, competitor):
def beat(self, competitor: BaseCompetitor):
"""
takes in a competitor object that lost, updates both's scores.
Takes in a competitor object that lost a match to this competitor, updates the ratings for both.
:param competitor: the competitor that lost thr bout
:type competitor: DWZCompetitor
"""

self.verify_competitor_types(competitor)
Expand All @@ -81,11 +86,12 @@ def beat(self, competitor):
competitor.rating = competitor_rating
competitor._count += 1

def tied(self, competitor):
def tied(self, competitor: BaseCompetitor):
"""
Takes in a competitor object that tied in a match to this competitor, updates the ratings for both.
:param competitor:
:return:
:param competitor: the competitor that tied with this one
:type competitor: DWZCompetitor
"""
self.verify_competitor_types(competitor)

Expand Down
26 changes: 16 additions & 10 deletions elote/competitors/ecf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class ECFCompetitor(BaseCompetitor):
_delta = 50
_n_periods = 30

def __init__(self, initial_rating=40):
def __init__(self, initial_rating: float = 40):
"""
class vars:
Expand Down Expand Up @@ -45,7 +45,7 @@ def rating(self):

return statistics.mean([_ for _ in self.scores if _ is not None])

def _update(self, rating):
def _update(self, rating: float):
if self.scores is None:
self.__initialize_ratings()

Expand All @@ -70,19 +70,24 @@ def export_state(self):
def transformed_elo_rating(self):
return 10 ** (self.elo_conversion / 400)

def expected_score(self, competitor):
def expected_score(self, competitor: BaseCompetitor):
"""
The expected outcome of a match between this competitor and one passed in. Scaled between 0-1, where 1 is a strong
likelihood of this competitor winning and 0 is a strong likelihood of this competitor losing.
:param competitor:
:return:
:param competitor: another EloCompetitor to compare this competitor to.
:return: likelihood to beat the passed competitor, as a float 0-1.
"""
self.verify_competitor_types(competitor)

return self.transformed_elo_rating / (competitor.transformed_elo_rating + self.transformed_elo_rating)

def beat(self, competitor):
def beat(self, competitor: BaseCompetitor):
"""
takes in a competitor object that lost, updates both's scores.
Takes in a competitor object that lost a match to this competitor, updates the ratings for both.
:param competitor: the competitor that lost their bout
:type competitor: ECFCompetitor
"""

self.verify_competitor_types(competitor)
Expand All @@ -105,11 +110,12 @@ def beat(self, competitor):
self._update(competitors_rating + self._delta)
competitor._update(self_rating - self._delta)

def tied(self, competitor):
def tied(self, competitor: BaseCompetitor):
"""
Takes in a competitor object that tied in a match to this competitor, updates the ratings for both.
:param competitor:
:return:
:param competitor: the competitor that tied with this one
:type competitor: ECFCompetitor
"""

self.verify_competitor_types(competitor)
Expand Down
45 changes: 37 additions & 8 deletions elote/competitors/elo.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,43 @@ class EloCompetitor(BaseCompetitor):
_base_rating = 400
_k_factor = 32

def __init__(self, initial_rating=400):
def __init__(self, initial_rating: float = 400):
"""
Overview
========
Elo rating is a rating system based on pairwise comparisons. Ratings are given to competitors based on their
comparisons (bouts) with peers, in which they can win, lose or tie. The change in a players rating is scaled by
the rating difference between them and their competitor.
class vars:
[1] Elo, Arpad (1978). The Rating of Chessplayers, Past and Present. Arco. ISBN 0-668-04721-6.
Basic Usage
-----------
.. code-block:: python
from elote import EloCompetitor
good = EloCompetitor(initial_rating=400)
better = EloCompetitor(initial_rating=500)
better.beat(good)
print('probability of better beating good: %5.2f%%' % (better.expected_score(good) * 100, ))
Class Variables
---------------
Class variables are configured for all competitors in a population, not on a per-competitor basis. See the
documentation on ``Arenas`` to see how to set these safely.
* _base_rating: defaults to 400.
* _k_factor: tunes the speed of response to new information, higher is faster response. Default=32
Configuration Options
---------------------
:param initial_rating: the initial rating to use for a new competitor who has no history. Default 400
:type initial_rating: int
"""
self.rating = initial_rating

Expand Down Expand Up @@ -44,7 +69,7 @@ def export_state(self):
def transformed_rating(self):
return 10 ** (self.rating / self._base_rating)

def expected_score(self, competitor):
def expected_score(self, competitor: BaseCompetitor):
"""
In Elo rating, a player's expected score is their probability of winning plus half their probability of drawing.
This is because in Elo rating a draw is not explicitly accounted for, but rather counted as half of a win and
Expand All @@ -58,9 +83,12 @@ def expected_score(self, competitor):

return self.transformed_rating / (competitor.transformed_rating + self.transformed_rating)

def beat(self, competitor):
def beat(self, competitor: BaseCompetitor):
"""
takes in a competitor object that lost, updates both's scores.
Takes in a competitor object that lost a match to this competitor, updates the ratings for both.
:param competitor: the competitor that lost their bout
:type competitor: EloCompetitor
"""

self.verify_competitor_types(competitor)
Expand All @@ -74,11 +102,12 @@ def beat(self, competitor):
# update the loser's rating
competitor.rating = competitor.rating + self._k_factor * (0 - lose_es)

def tied(self, competitor):
def tied(self, competitor: BaseCompetitor):
"""
Takes in a competitor object that tied in a match to this competitor, updates the ratings for both.
:param competitor:
:return:
:param competitor: the competitor that tied with this one
:type competitor: EloCompetitor
"""

self.verify_competitor_types(competitor)
Expand Down
24 changes: 14 additions & 10 deletions elote/competitors/ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class BlendedCompetitor(BaseCompetitor):
def __init__(self, competitors, blend_mode="mean"):
def __init__(self, competitors: list, blend_mode: str = "mean"):
"""
:param competitors:
Expand Down Expand Up @@ -47,11 +47,13 @@ def export_state(self):
]
}

def expected_score(self, competitor):
def expected_score(self, competitor: BaseCompetitor):
"""
The expected outcome of a match between this competitor and one passed in. Scaled between 0-1, where 1 is a strong
likelihood of this competitor winning and 0 is a strong likelihood of this competitor losing.
:param competitor:
:return:
:param competitor: another EloCompetitor to compare this competitor to.
:return: likelihood to beat the passed competitor, as a float 0-1.
"""

self.verify_competitor_types(competitor)
Expand All @@ -61,23 +63,25 @@ def expected_score(self, competitor):
else:
raise NotImplementedError('Blend mode %s not supported' % (self.blend_mode, ))

def beat(self, competitor):
def beat(self, competitor: BaseCompetitor):
"""
takes in a competitor object that lost, updates both's scores.
Takes in a competitor object that lost a match to this competitor, updates the ratings for both.
:param competitor:
:param competitor: the competitor that lost their bout
:type competitor: BlendedCompetitor
"""

self.verify_competitor_types(competitor)

for c in self._sub_competitors:
c.beat(competitor)

def tied(self, competitor):
def tied(self, competitor: BaseCompetitor):
"""
Takes in a competitor object that tied in a match to this competitor, updates the ratings for both.
:param competitor:
:return:
:param competitor: the competitor that tied with this one
:type competitor: BlendedCompetitor
"""

self.verify_competitor_types(competitor)
Expand Down
24 changes: 15 additions & 9 deletions elote/competitors/glicko.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class GlickoCompetitor(BaseCompetitor):
_c = 1
_q = 0.0057565

def __init__(self, initial_rating=1500, initial_rd=350):
def __init__(self, initial_rating: float = 1500, initial_rd: float = 350):
"""from http://www.glicko.net/glicko/glicko.pdf
class vars:
Expand Down Expand Up @@ -49,11 +49,13 @@ def tranformed_rd(self):
def _g(cls, x):
return 1 / (math.sqrt(1 + 3 * cls._q ** 2 * (x ** 2) / math.pi ** 2))

def expected_score(self, competitor):
def expected_score(self, competitor: BaseCompetitor):
"""
The expected outcome of a match between this competitor and one passed in. Scaled between 0-1, where 1 is a strong
likelihood of this competitor winning and 0 is a strong likelihood of this competitor losing.
:param competitor:
:return:
:param competitor: another EloCompetitor to compare this competitor to.
:return: likelihood to beat the passed competitor, as a float 0-1.
"""

self.verify_competitor_types(competitor)
Expand All @@ -62,9 +64,12 @@ def expected_score(self, competitor):
E = 1 / (1 + 10 ** ((-1 * g_term * (self.rating - competitor.rating))/400))
return E

def beat(self, competitor):
def beat(self, competitor: BaseCompetitor):
"""
takes in a competitor object that lost, updates both's scores.
Takes in a competitor object that lost a match to this competitor, updates the ratings for both.
:param competitor: the competitor that lost thr bout
:type competitor: GlickoCompetitor
"""

self.verify_competitor_types(competitor)
Expand All @@ -90,11 +95,12 @@ def beat(self, competitor):
competitor.rating = c_new_r
competitor.rd = c_new_rd

def tied(self, competitor):
def tied(self, competitor: BaseCompetitor):
"""
Takes in a competitor object that tied in a match to this competitor, updates the ratings for both.
:param competitor:
:return:
:param competitor: the competitor that tied with this one
:type competitor: GlickoCompetitor
"""

self.verify_competitor_types(competitor)
Expand Down

0 comments on commit f91a1f4

Please sign in to comment.