-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Expand file tree
/
Copy pathswimmers.py
More file actions
52 lines (39 loc) · 1.6 KB
/
swimmers.py
File metadata and controls
52 lines (39 loc) · 1.6 KB
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
import csv
import datetime
import itertools as it
import statistics
from collections import namedtuple
class Event(namedtuple("Event", ["stroke", "name", "time"])):
__slots__ = ()
def __lt__(self, other):
return self.time < other.time
def sort_and_group(iterable, key=None):
return it.groupby(sorted(iterable, key=key), key=key)
def grouper(iterable, n, fillvalue=None):
iters = [iter(iterable)] * n
return it.zip_longest(*iters, fillvalue=fillvalue)
def read_events(csvfile, _strptime=datetime.datetime.strptime):
def _median(times):
return statistics.median(
(_strptime(time, "%M:%S:%f").time() for time in row["Times"])
)
fieldnames = ["Event", "Name", "Stroke"]
with open(csvfile) as infile:
reader = csv.DictReader(infile, fieldnames=fieldnames, restkey="Times")
next(reader) # Skip header.
for row in reader:
yield Event(row["Stroke"], row["Name"], _median(row["Times"]))
events = tuple(read_events("swimmers.csv"))
for stroke, evts in sort_and_group(events, key=lambda evt: evt.stroke):
events_by_name = sort_and_group(evts, key=lambda evt: evt.name)
best_times = (min(evt) for _, evt in events_by_name)
sorted_by_time = sorted(best_times, key=lambda evt: evt.time)
teams = zip(("A", "B"), it.islice(grouper(sorted_by_time, 4), 2))
for team, swimmers in teams:
print(
"{stroke} {team}: {names}".format(
stroke=stroke.capitalize(),
team=team,
names=", ".join(swimmer.name for swimmer in swimmers),
)
)