112 lines
2.8 KiB
Python
112 lines
2.8 KiB
Python
import trueskill
|
|
from trueskill import Rating, rate
|
|
|
|
class Athlete:
|
|
def __init__(self, first_name, last_name, club, birth_year, mu=25, sigma=25./3.):
|
|
self.first_name = first_name
|
|
self.last_name = last_name
|
|
self.club = club
|
|
self.birth_year = birth_year
|
|
self.rating = Rating(mu, sigma)
|
|
|
|
def expose(self):
|
|
return trueskill.expose(self.rating)
|
|
|
|
def setrating(self, rating):
|
|
self.rating = rating
|
|
|
|
def __str__(self):
|
|
return u'{f} {l} {c} - {s:.2f}'.format(
|
|
f=self.first_name,
|
|
l=self.last_name,
|
|
c=self.club,
|
|
s=self.expose()
|
|
)
|
|
|
|
class Crew:
|
|
def __init__(self, athletes, name):
|
|
self.athletes = athletes
|
|
self.name = name
|
|
|
|
def size(self):
|
|
return len(self.athletes)
|
|
|
|
def __str__(self):
|
|
return u'{n}'.format(n=self.name)
|
|
|
|
class Result:
|
|
def __init__(self, crews, name, validated=False, processed=False):
|
|
self.crews = crews
|
|
self.name = name
|
|
self.verified = validated
|
|
self.processed = processed
|
|
|
|
def validate(self):
|
|
# crews need to be more than 2
|
|
if len(self.crews) < 2:
|
|
self.verified = False
|
|
return False
|
|
|
|
# crews need to be all same length
|
|
l = self.crews[0].size()
|
|
for crew in self.crews:
|
|
if crew.size() != l:
|
|
self.verified = False
|
|
return False
|
|
|
|
# crew length need to be 1, 2, 4 or 8
|
|
if l not in [1,2,4,8]:
|
|
self.verified = False
|
|
return False
|
|
|
|
# cannot have same crew multiple times in same race
|
|
if len(self.crews) != len(set(self.crews)):
|
|
self.verified = False
|
|
return False
|
|
|
|
# cannot have same athletes in different crews in same race
|
|
allathletes = []
|
|
for crew in self.crews:
|
|
for athlete in crew.athletes:
|
|
allathletes.append(athlete)
|
|
|
|
if len(allathletes) != len(set(allathletes)):
|
|
self.verified = False
|
|
return False
|
|
|
|
self.verified = True
|
|
return self.verified
|
|
|
|
def process(self):
|
|
if not self.verified:
|
|
if not self.validate():
|
|
return False
|
|
|
|
if self.processed:
|
|
return True
|
|
|
|
# validate the race
|
|
ratings = list([athlete.rating for athlete in crew.athletes] for crew in self.crews)
|
|
result = rate(ratings, ranks = list(range(len(self.crews))))
|
|
|
|
i = 0
|
|
j = 0
|
|
|
|
for c in result:
|
|
for rating in c:
|
|
self.crews[i].athletes[j].setrating(rating)
|
|
j += 1
|
|
i += 1
|
|
j = 0
|
|
|
|
self.processed = True
|
|
|
|
return True
|
|
|
|
def __str__(self):
|
|
s = self.name + ': '
|
|
for crew in self.crews:
|
|
s = s + str(crew) + ', '
|
|
|
|
return s[:-2]
|