summaryrefslogtreecommitdiff
path: root/elo.py
blob: 7169b33049a2279b3867427c54061362f3d2970c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python
import argparse
import datetime

import dateutil.parser
import dateutil.relativedelta
from f1elo.db import Session
from f1elo.elo import Elo
from f1elo.model import *

session = Session()
elo = Elo(session)

parser = argparse.ArgumentParser(description='Ranks Formula One drivers using Elo rating')
parser.add_argument('command', metavar='COMMAND', nargs='?',
                    help='Action to execute against the database: print, reset or rate, print - prints the rankings for all drivers ranked in 12 months, reset - resets the rankings, rate - calculates the rankings',
                    default='print')
parser.add_argument('--date', help='Date for which the action should be executed. Print ratings for DATE, reset ratings all the way down to DATE or rank the races all the way up to DATE.')

arguments = parser.parse_args()
command = arguments.command.lower()
date = arguments.date
if date:
    date = dateutil.parser.parse(date).date()

one_day = datetime.timedelta(1)

if command == 'reset':
    query = session.query(Race)
    if date is not None:
        query = query.filter(Race.date > date)
    for race in query.all():
        race.ranked = False
    query = session.query(Ranking)
    if date is not None:
        query = query.filter(Ranking.rank_date > date)
    query.delete()
    if date is not None:
        date += one_day
elif command == 'rate':
    race_query = session.query(Race).filter(Race.ranked == False)
    if date is not None:
        race_query = race_query.filter(Race.date <= date)
    races = race_query.order_by(Race.date).all()

    for race in races:
        print race
        print

        ranks = elo.rank_race(race)
        driver_ranks = {}
        for entry, rank in ranks.iteritems():
            correction = rank / len(entry.drivers)
            for driver in entry.drivers:
                if not driver_ranks.has_key(driver):
                    driver_ranks[driver] = 0;
                driver_ranks[driver] += correction
        for driver, rank in driver_ranks.iteritems():
            ranking = Ranking()
            ranking.rank_date = race.date
            ranking.ranking = elo.get_ranking(driver, race.date) + rank
            session.add(ranking)
            driver.rankings.append(ranking)

        for entry in race.entries:
            print entry, elo.get_entry_ranking(entry, race.date), elo.get_entry_ranking(entry)
        print

        race.ranked = True
        date = race.date + one_day

if date is None:
    date = datetime.date.today()
    date += one_day

print 'Rankings for %s' % date

one_year = dateutil.relativedelta.relativedelta(years=1)

rankings = session.query(Ranking).filter(Ranking.rank_date > (date - one_year)).filter(Ranking.rank_date <= date).all()

drivers = {}
for ranking in rankings:
    if not drivers.has_key(ranking.driver):
        drivers[ranking.driver] = ranking.driver.get_ranking(date)

for rank in sorted(drivers.values(), key=lambda rank: rank.ranking, reverse=True):
    print rank

session.commit()