-
Notifications
You must be signed in to change notification settings - Fork 20
/
GetTeamResults.py
144 lines (129 loc) · 4.61 KB
/
GetTeamResults.py
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import operator
from collections import defaultdict
import Model
import Utils
from GetResults import GetResults
class TeamResult:
def __init__( self, team, t=None, points=None, bestPos=0, note='', numParticipants=None ):
self.team = team
self.t = t
self.points = points
self.bestPos = bestPos
self.note = note
self.criteria = ''
self.numParticipants = numParticipants
self.gap = ''
def __repr__( self ):
values = ['{}={}'.format(a, getattr(self, a)) for a in ('team', 't', 'points', 'bestPos', 'note', 'criteria')]
return ', '.join( values )
@Model.memoize
def GetTeamResults( category ):
results = GetResults( category )
if not results:
return tuple()
race = Model.race
Finisher = Model.Rider.Finisher
formatTime = lambda t: Utils.formatTime( t, highPrecision=race.highPrecisionTimes )
formatTimeGap = lambda t: Utils.formatTimeGap( t, highPrecision=race.highPrecisionTimes )
# Group the results by teams.
teamInfo = defaultdict( list )
independent = _('Independent').lower()
fastestTime = None
def getPercentTime( rr ):
return 100.0 * ((rr.lastTime - race.getStartOffset(rr.num)) / fastestTime)
for pos, rr in enumerate(results, 1):
if rr.status != Finisher:
continue
if fastestTime is None:
fastestTime = rr.lastTime - race.getStartOffset(rr.num) if rr.lastTime else None
team = getattr( rr, 'Team', '' )
if team and not (team.lower().startswith(independent) or team.lower().startswith('independent')):
rr.pos = pos
teamInfo[team].append( rr )
# Create the team rank criteria based on the individual results.
teamResults = []
if race.teamRankOption == race.teamRankByRiderTime: # by nth rider (team time trial)
for team, rrs in teamInfo.items():
numParticipants = len(rrs)
try:
rr = rrs[race.nthTeamRider-1]
except IndexError:
continue
teamResults.append( TeamResult(
team,
t=rr.lastTime - race.getStartOffset(rr.num),
note='{}'.format(rr.num),
numParticipants=numParticipants,
)
)
if teamResults:
teamResults.sort( key=operator.attrgetter('t') )
top = teamResults[0]
for tr in teamResults:
tr.criteria = formatTime( tr.t )
tr.gap = formatTimeGap( tr.t - top.t ) if tr != top else ''
elif race.teamRankOption == race.teamRankBySumPoints: # sum of individual points
pointsForPos = {pos:points for pos, points in enumerate( (int(v.strip()) for v in race.finishPointsStructure.split(',')), 1) }
for team, rrs in teamInfo.items():
numParticipants = len(rrs)
if len(rrs) < race.topTeamResults:
continue
rrs = rrs[:race.topTeamResults]
teamResults.append(
TeamResult(
team,
points=sum(pointsForPos.get(rr.pos, 0) for rr in rrs),
bestPos=rrs[0].pos,
note=', '.join('{}:{} ({})'.format(pointsForPos.get(rr.pos, 0), rr.pos, rr.num)),
numParticipants=numParticipants,
)
)
if teamResults:
teamResults.sort( key=lambda x:(-x.points, x.bestPos) )
top = teamResults[0]
for tr in teamResults:
tr.criteria = '{}'.format( tr.points )
tr.gap = '{}'.format( tr.points - top.points ) if tr != top else ''
elif race.teamRankOption == race.teamRankBySumTime: # sum of individual times
for team, rrs in teamInfo.items():
numParticipants = len(rrs)
if len(rrs) < race.topTeamResults:
continue
rrs = rrs[:race.topTeamResults]
teamResults.append(
TeamResult(
team,
t=sum(rr.lastTime - race.getStartOffset(rr.num) for rr in rrs),
bestPos=rrs[0].pos,
note=', '.join('{}:{} ({})'.format(formatTime(rr.lastTime - race.getStartOffset(rr.num)), rr.pos, rr.num)),
numParticipants=numParticipants,
)
)
if teamResults:
teamResults.sort( key=lambda x:(x.t, x.bestPos) )
top = teamResults[0]
for tr in teamResults:
tr.criteria = formatTime( tr.t )
tr.gap = formatTimeGap( tr.t - top.t ) if tr != top else ''
elif race.teamRankOption == race.teamRankBySumPercentTime and fastestTime: # sum of percent times of winner. Must be the last in the if-else.
for team, rrs in teamInfo.items():
numParticipants = len(rrs)
if len(rrs) < race.topTeamResults:
continue
rrs = rrs[:race.topTeamResults]
teamResults.append(
TeamResult(
team,
points=sum(getPercentTime(rr) for rr in rrs),
bestPos=rrs[0].pos,
note=', '.join('{:.2f}:{} ({})'.format(getPercentTime(rr), rr.pos, rr.num)),
numParticipants=numParticipants,
)
)
if teamResults:
teamResults.sort( key=lambda x:(-x.points, x.bestPos) )
top = teamResults[0]
for tr in teamResults:
tr.criteria = '{:.2f}'.format( tr.points )
tr.gap = '{:.2f}'.format( tr.points - top.points ) if tr != top else ''
return tuple( teamResults )