11"""Ranking calculators implementing the Elo, Glicko and TrueSkill algorithms."""
2- from __future__ import absolute_import
2+ from collections . abc import Sequence
33
4- from collections import Sequence
54from skills .numerics import Gaussian
65
76
@@ -40,6 +39,7 @@ class Match(list):
4039 """Match is a list of Team objects"""
4140
4241 def __init__ (self , teams = None , rank = None ):
42+ super ().__init__ ()
4343 if teams is not None :
4444 for team in teams :
4545 self .append (Team .ensure_team (team ))
@@ -87,14 +87,14 @@ def player_rating(self):
8787 for player_rating in team .player_rating ():
8888 yield player_rating
8989
90- def sort (self ):
90+ def sort (self , ** kwargs ):
9191 """
9292 Performs an in-place sort of the items in accordance to the ranks in non-decreasing order
9393 """
9494 if not self .rank :
9595 raise AttributeError ("Match does not have a ranking" )
9696
97- rank_sorted , teams_sorted = map (list , zip (* sorted (zip (self .rank , self ))))
97+ rank_sorted , teams_sorted = map (list , zip (* sorted (zip (self .rank , self ), key = lambda x : x [ 0 ] )))
9898
9999 if rank_sorted != self .rank :
100100 # in-place update part
@@ -126,6 +126,7 @@ class Matches(list):
126126 """Matches is a list of Match objects"""
127127
128128 def __init__ (self , matches ):
129+ super ().__init__ ()
129130 for match in matches :
130131 self .append (Match .ensure_match (match ))
131132
@@ -194,9 +195,7 @@ def __init__(self, players=None):
194195 # or 1 list of player, rating tuples
195196 team = Team([(player1, rating1), (player2, rating2)])
196197 """
197- self .players = self .keys
198- self .ratings = self .values
199- self .player_rating = self .items
198+ super ().__init__ ()
200199 if players is not None :
201200 try :
202201 player_rating_tuples = players .items ()
@@ -209,6 +208,15 @@ def __init__(self, players=None):
209208 except (TypeError , ValueError ):
210209 raise TypeError ("Improper player dict or list" )
211210
211+ def players (self ):
212+ return list (self .keys ())
213+
214+ def ratings (self ):
215+ return list (self .values ())
216+
217+ def player_rating (self ):
218+ return list (self .items ())
219+
212220 def add_player (self , player , rating ):
213221 self [Player .ensure_player (player )] = RatingFactory .ensure_rating (rating )
214222 return self
@@ -237,6 +245,13 @@ def ensure_team(team):
237245 else :
238246 return team
239247
248+ def __lt__ (self , other ):
249+ """
250+ In python3, you can't order dicts anymore. Since we do that in Match.sort
251+ we'll define a custom team sort based on the current contents for consistency
252+ """
253+ return frozenset (self .items ()) < frozenset (other .items ())
254+
240255
241256class Rating (object ):
242257 """
@@ -250,14 +265,14 @@ def __init__(self, mean):
250265 raise ValueError ("Rating mean value must be numeric" )
251266
252267 def __repr__ (self ):
253- return "Rating(%s)" % ( self .mean )
268+ return "Rating(%s)" % self .mean
254269
255270 def __str__ (self ):
256- return "mean=%.5f" % ( self .mean )
271+ return "mean=%.5f" % self .mean
257272
258273 @staticmethod
259274 def ensure_rating (rating ):
260- if ( not hasattr (rating , 'mean' ) ):
275+ if not hasattr (rating , 'mean' ):
261276 try :
262277 return Rating (rating )
263278 except TypeError :
@@ -275,8 +290,9 @@ class RatingFactory(object):
275290
276291 rating_class = Rating
277292
278- def __new__ (cls ):
279- return RatingFactory .rating_class ()
293+ # def __new__(cls):
294+ # TODO: Rating ctor requires a param
295+ # return RatingFactory.rating_class()
280296
281297 @staticmethod
282298 def ensure_rating (rating ):
0 commit comments