001:
002:
003:
004:
005:
006:
007:
008:
009: reloadables=[]
010:
011:
012:
013: from relational import base
014: from tabulate import enumcond,racesheet,scoresheet
015: from utility.verbose import vv,vvv,vvvv,debug
016:
017:
018:
019: def startcompleted(start):
020:
021:
022:
023:
024:
025:
026:
027:
028:
029:
030: try: start.abandoned
031: except AttributeError:
032: try: start.race.abandoned
033: except AttributeError: pass
034: else: raise AttributeError
035: else: raise AttributeError
036: return start
037:
038: def tabulate_all_series(
039: racesheetvalues,startsheetvalues,handicapsheet,rcsheet,
040: seriestab,seriesdivisionnew,seriesdivisiontab,
041: seriesscorenew,seriesscoretab,
042: ):
043:
044:
045:
046:
047:
048:
049: print>>vv,"TABULATING SERIES RESULTS"
050:
051: for (
052: seriesname,[races,starts,handicaps,rcs]
053: ) in base.polyhierarchy_filter(
054: ["seriesname"],
055: base.adjoin_sort(
056: racesheetvalues.converse_filter(["abandoned"]),
057: [("racename",lambda r,n: n.seriesname)]
058: ),
059: base.adjoin_sort(
060: startsheetvalues,
061: [("race",lambda s,r:
062: startcompleted(s) and r.racename.seriesname
063: )]
064: ),
065: base.adjoin_sort(
066: handicapsheet.obverse_filter([
067: "starter",
068: ("fleet",lambda entry,fleet: fleet.inseries)
069: ]),
070: [("start",lambda e,s:
071: startcompleted(s) and s.race.racename.seriesname
072: )]
073: ),
074: base.adjoin_sort(
075: rcsheet,
076: [("race",lambda s,r: r.racename.seriesname)]
077: ),
078: ):
079: print>>vv," SERIES:",seriesname
080:
081: racelist=racesheet.SheetList(races)
082: startlist=racesheet.SheetList(starts)
083: handicaplist=racesheet.SheetList(handicaps)
084: rclist=racesheet.SheetList(rcs)
085:
086: scoreseries=scoresheet.ScoreList()
087: infer_registration(
088: handicaplist,
089: seriesscorenew(seriesname),scoreseries
090: )
091: attribute_rc_redress(
092: handicaplist,rclist,scoreseries
093: )
094: collect_by_start(
095: startlist,handicaplist,rclist,
096: seriesdivisionnew(seriesname),scoreseries
097: )
098:
099: series=seriestab[seriesname]
100: series.races=racelist
101:
102: def infer_registration(handicapsheet,scorenew,scoreseries):
103:
104:
105:
106:
107:
108:
109:
110: print>>vvv," INFER REGISTRATION"
111:
112: for (boat,divisions) in base.adjoin_hierarchy(
113: handicapsheet,
114: ["boat",("start",lambda entry,start: start.divisionname)]
115: ):
116: maxstarts=[0]
117: registered=[]
118: for (divisionname,entries) in divisions:
119: startentries=[e.start.race for e in entries]
120: startentries.reverse()
121: starts=[len(startentries)]+startentries
122: if starts>maxstarts:
123: maxstarts=starts
124: registered=[divisionname]
125: elif starts==maxstarts:
126: registered+=[divisionname]
127: assert len(registered)>0
128:
129: for r in registered:
130: seriesscore=scorenew(boat,r)
131: if len(registered)>1:
132: seriesscore.duplicates=registered
133:
134:
135: scoreseries.append(seriesscore)
136:
137: def attribute_rc_redress(handicapsheet,rcsheet,scoreseries):
138:
139:
140:
141:
142:
143: print>>vvv," ATTRIBUTE RC REDRESS"
144:
145: for (race,boats) in base.polyhierarchy_filter(
146: ["race","boat"],
147: handicapsheet.adjoin_sort(
148: [("start",lambda e,s: s.race,lambda e: e.race),"boat"]
149: ),
150: rcsheet.adjoin_sort(["race","start"]),
151: ):
152: for (boat,jointentries) in boats:
153: for (entry,rc) in base.outer_product(jointentries):
154: print>>vvv," RC ENTRY COLLISION: %8s:%-18s",(
155: entry.boat.sailnumber,
156: entry.boat.boatname,
157: )
158:
159: for (boat,jointentries) in base.adjoin_polyhierarchy(
160: scoreseries,rcsheet,["boat"]
161: ):
162: for (registered,rc) in base.outer_product(jointentries):
163: rc.seriesdivision=registered.seriesdivision
164:
165: def collect_by_start(startsheet,handicapsheet,rcsheet,divisionnew,scoreseries):
166:
167:
168:
169:
170:
171:
172:
173: print>>vvv," COLLECT BY START"
174:
175: for (
176: divisionname,
177: [startentries,scoreentries,handicapentries,rcentries],
178: ) in base.polyhierarchy_filter(
179: ["divisionname"],
180: startsheet.adjoin_sort(["divisionname"]),
181: base.adjoin_sort(
182: scoreseries.adjoin_filter(["boat"]),
183: [("seriesdivision",lambda e,s:s.divisionname)]
184: ),
185: base.adjoin_sort(
186: handicapsheet.adjoin_filter(["boat"]),
187: [("start",lambda e,s: s.divisionname)]
188: ),
189: base.adjoin_sort(
190: rcsheet.adjoin_filter(["boat"]),
191: [("seriesdivision",lambda e,s:s.divisionname)]
192: ),
193: ):
194: print>>vvvv," DIVISION",divisionname
195:
196: starts=[s for s in startentries]
197: seriesindex=dict([(s.race,i) for (i,s) in enumerate(starts)])
198:
199: seriesdivision=divisionnew(divisionname)
200: seriesdivision.starts=starts
201:
202:
203:
204:
205:
206: completed=len(starts)
207: excluded=seriesdivision.series.seriesname.exclusions[completed]
208: included=completed-excluded
209: seriesdivision.completed=completed
210: seriesdivision.excluded=excluded
211: seriesdivision.included=included
212:
213: if not starts:
214: continue
215:
216: scorelist=scoresheet.ScoreList(scoreentries)
217:
218: seriesdivision.numberofentrants=len(scorelist)
219: seriesdivision.dnc=seriesdivision.numberofentrants+1
220:
221: registeredentries=[
222: jointentry
223: for (boat,jointentries) in base.polyhierarchy_filter(
224: ["boat"],scorelist,handicapentries
225: )
226: for jointentry in base.outer_product(jointentries)
227: ]
228:
229: for (
230: start,entries
231: ) in base.adjoin_hierarchy(registeredentries,["start"]):
232: entrylist=racesheet.SheetList(entries)
233:
234: calculate_series_points(start,entrylist)
235:
236: for (
237: boatscore,entries
238: ) in base.hierarchy_filter(["score"],registeredentries):
239: entrylist=scoresheet.ScoreList(entries)
240:
241: infer_fleet(boatscore,entrylist)
242:
243: boatscore.handicaps=[None]*completed
244: boatscore.displays=[None]*completed
245: boatscore.points=[None]*completed
246:
247: for (start,entry) in base.adjoin_filter(
248: entrylist,["start"]
249: ):
250: i=seriesindex[start.race]
251: boatscore.handicaps[i]=entry
252:
253: points=entry.seriespoints
254: if isinstance(points,str):
255: pts=points.upper()
256: else:
257: pts="%3.1f"%points
258:
259: boatscore.displays[i]=pts
260: boatscore.points[i]=points
261:
262: for (i,d) in enumerate(boatscore.displays):
263: if d==None:
264: boatscore.displays[i]="DNC"
265:
266: registeredrcs=[
267: jointentry
268: for (boat,jointentries) in base.polyhierarchy_filter(
269: ["boat"],scorelist,rcentries
270: )
271: for jointentry in base.outer_product(jointentries)
272: ]
273:
274: for (
275: boatscore,entries
276: ) in base.hierarchy_filter(["score"],registeredrcs):
277: entrylist=scoresheet.ScoreList(entries)
278:
279: for (race,entry) in base.adjoin_filter(
280: entrylist,["race"]
281: ):
282: i=seriesindex[race]
283: boatscore.handicaps[i]=entry
284:
285: boatscore.displays[i]="AVG"
286: boatscore.points[i]="AVG"
287:
288: determine_other_series_points(seriesdivision,scorelist)
289: total_scores(seriesdivision,scorelist)
290:
291: def calculate_series_points(start,handicapsheet):
292:
293:
294:
295:
296:
297:
298:
299: rank=1
300: for (finishcondition,timed) in base.adjoin_hierarchy(
301: handicapsheet.obverse_filter([("starter",True)]),
302: [("finishcondition",enumcond.FinishCondEnum.FIN_COND),"zipcorrected"]
303: ):
304:
305: assert finishcondition.fin_cond
306: for (zipcorrected,entries) in timed:
307: sharedrank=rank
308: sharedentries=[e for e in entries]
309: n=len(sharedentries)
310: sharedpoints=rank+round((n-1)/2.0,1)
311: for entry in sharedentries:
312: entry.seriespoints=sharedpoints
313: rank+=n
314:
315: sharedrank=rank
316: sharedentries=base.converse_sort(
317: handicapsheet.obverse_filter([("starter",True)]),
318: [("finishcondition",enumcond.FinishCondEnum.FIN_COND),"zipcorrected"]
319: )
320: n=len(sharedentries)
321: sharedpoints=rank+n
322: for entry in sharedentries:
323: entry.seriespoints=sharedpoints
324: rank=sharedpoints
325: start.seriesnumberofstarters=rank-1
326:
327: def infer_fleet(boatscore,handicapsheet):
328:
329:
330:
331:
332:
333: maxstarts=[0]
334: registered=[]
335: for (fleet,entries) in handicapsheet.adjoin_hierarchy(["fleet"]):
336: startentries=[e.start.race for e in entries]
337: startentries.reverse()
338: starts=[len(startentries)]+startentries
339: if starts>maxstarts:
340: maxstarts=starts
341: registered=[fleet]
342: elif starts==maxstarts:
343: registered+=[fleet]
344: assert len(registered)>0
345: registered.sort()
346: boatscore.fleet=registered[0]
347: if len(registered)>1:
348: boatscore.fleetduplicates=registered
349:
350:
351:
352:
353: def determine_other_series_points(seriesdivision,scoretab):
354:
355:
356:
357:
358: for score in scoretab:
359:
360: for (i,points) in enumerate(score.points):
361: if points==None:
362: score.points[i]=seriesdivision.dnc
363:
364: averaging=[p for p in score.points if not isinstance(p,str)]
365: if len(averaging):
366: average=round(sum(averaging)/len(averaging),1)
367: for (i,points) in enumerate(score.points):
368: if isinstance(points,str):
369: score.points[i]=average
370:
371: def total_scores(seriesdivision,scoretab):
372:
373:
374:
375:
376:
377: for score in scoretab:
378: sorted=[(p,-i) for (i,p) in enumerate(score.points)]
379: sorted.sort()
380:
381: score.excluded=[False]*seriesdivision.completed
382: for (p,i) in sorted[seriesdivision.included:]:
383: score.excluded[-i]=True
384:
385: del sorted[seriesdivision.included:]
386: sorted=[p for (p,i) in sorted]
387: score.totalpoints=sum(sorted)
388:
389: reversed=score.points[:]
390: reversed.reverse()
391:
392: score.total=(score.totalpoints,sorted,reversed)
393:
394: rank=1
395: for (total,scoreentries) in scoretab.adjoin_hierarchy(["total"]):
396: sharedrank=rank
397: sharedtotals=[e for e in scoreentries]
398: for seriesscore in sharedtotals:
399: seriesscore.ranking=sharedrank
400: rank+=1
401:
402: for (fleet,totals) in scoretab.adjoin_hierarchy(["fleet","total"]):
403: rank=1
404: for (total,scoreentries) in totals:
405: sharedrank=rank
406: sharedtotals=[e for e in scoreentries]
407: for seriesscore in sharedtotals:
408: seriesscore.fleetranking=sharedrank
409: rank+=1
410:
411: