diff --git a/boatmovers/results.py b/boatmovers/results.py new file mode 100644 index 00000000..ebfdc0df --- /dev/null +++ b/boatmovers/results.py @@ -0,0 +1,111 @@ +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.validated = validated + self.processed = processed + + def validate(self): + # crews need to be more than 2 + if len(self.crews) < 2: + self.validated = 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.validated = False + return False + + # crew length need to be 1, 2, 4 or 8 + if l not in [1,2,4,8]: + self.validated = False + return False + + # cannot have same crew multiple times in same race + if len(self.crews) != len(set(self.crews)): + self.validated = 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.validated = False + return False + + self.validated = True + return self.validated + + def process(self): + if not self.validated: + 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]