001:
002:
003:
004:
005:
006:
007:
008:
009: reloadables=[]
010:
011:
012:
013: from relational import base
014: from standing import enumstat,eventstat
015: from tabulate import enumcond,racesheet
016:
017:
018:
019: def tabulate_all_races(handicapsheet):
020: for (race,entries) in handicapsheet.adjoin_hierarchy(
021: [("start",lambda e,s: s.race,lambda e: e.race)]
022: ):
023: handicaplist=racesheet.SheetList(entries)
024:
025: mark_duplicate_boats(handicaplist)
026: mark_peculiar_finishes(handicaplist)
027: for dname in [eventstat.DivisionName.SHARK]:
028: infer_level_racing_finish_times(handicaplist,dname)
029:
030: tabulate_race_by_start(handicaplist)
031:
032: def mark_duplicate_boats(handicapsheet):
033:
034:
035:
036:
037:
038:
039:
040:
041:
042:
043: for (boat,entries) in handicapsheet.adjoin_hierarchy(["boat"]):
044: duplicates=[e for e in entries]
045: if len(duplicates)>1:
046: for entry in duplicates:
047: entry.duplicates=duplicates
048:
049: def mark_peculiar_finishes(handicapsheet):
050:
051:
052:
053:
054: for entry in handicapsheet.obverse_filter(
055: [("finishcondition",enumcond.FinishCondEnum.TIMELESS),"finishhms"]
056: ):
057: entry.peculiar=True
058:
059: def infer_level_racing_finish_times(handicapsheet,divisionname):
060:
061:
062:
063:
064:
065:
066:
067:
068:
069:
070:
071:
072:
073:
074: assert divisionname.levelracing
075: boundhms=(0,0,0)
076: for entry in handicapsheet.obverse_sort(["entrynumber"]):
077: try:
078: entrydivname=entry.start.divisionname
079: except AttributeError:
080: entrydivname=None
081: if entrydivname==divisionname:
082: try:
083: boundhms=hms=entry.finishhms
084: except AttributeError:
085: hms=boundhms
086: entry.inferredhms=hms
087: else:
088: try:
089: if boundhms<entry.finishhms:
090: boundhms=entry.finishhms
091: except AttributeError:
092: pass
093:
094: def tabulate_race_by_start(handicapsheet):
095:
096:
097:
098:
099: for (start,entries) in handicapsheet.adjoin_hierarchy(["start"]):
100: entrylist=racesheet.SheetList(entries)
101:
102: scratch_classes(start,entrylist)
103: apply_handicaps(start,entrylist)
104: reckon_starters(start,entrylist)
105: rank_by_corrected_time(start,entrylist)
106:
107: def scratch_classes(start,handicapsheet,distance=None):
108:
109:
110:
111:
112:
113:
114:
115: try:
116: distance=start.distance
117: except AttributeError:
118: distance=start.race.distance
119:
120: try:
121: scratchco=round(start.levelrating*distance)
122: except AttributeError:
123: for (
124: rating,entries
125: ) in handicapsheet.adjoin_hierarchy(["rating"]):
126: scratchco=round(rating*distance)
127: break
128: else:
129: scratchco=0
130:
131: for entry in handicapsheet.obverse_filter(["rating"]):
132: correction=round(entry.rating*distance)
133: entry.relativeco=correction-scratchco
134:
135: def apply_handicaps(start,handicapsheet):
136:
137:
138:
139:
140:
141:
142: try:
143: start.levelracing
144: except AttributeError:
145: for (
146: relativeco,(hh,mm,ss),entry
147: ) in handicapsheet.adjoin_filter(["relativeco","finishhms"]):
148: corrected=(hh*60+mm)*60+ss-relativeco
149: (hm,ss)=divmod(corrected,60)
150: (hh,mm)=divmod(hm,60)
151: entry.correctedhms=(hh,mm,ss)
152: entry.zipcorrected=(
153: entry.finishcondition,
154: entry.correctedhms,
155: )
156: else:
157: for (
158: relativeco,(hh,mm,ss),entry
159: ) in handicapsheet.adjoin_filter(["relativeco","inferredhms"]):
160: corrected=(hh*60+mm)*60+ss-relativeco
161: (hm,ss)=divmod(corrected,60)
162: (hh,mm)=divmod(hm,60)
163: entry.correctedhms=(hh,mm,ss)
164: entry.zipcorrected=(
165: entry.finishcondition,
166: entry.correctedhms,
167: entry.entrynumber,
168: )
169:
170: for entry in base.converse_filter(
171: handicapsheet.converse_filter(["correctedhms"]),
172: [("finishcondition",enumcond.FinishCondEnum.FIN_COND)]
173: ):
174: entry.zipcorrected=(entry.finishcondition,)
175:
176:
177:
178:
179:
180:
181: def reckon_starters(start,handicapsheet):
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194: for (boat,finishes) in base.adjoin_hierarchy(
195: base.converse_filter(
196: base.converse_filter(
197: handicapsheet.obverse_filter(["rating"]),
198: [("fleet",enumstat.FleetEnum.UNREGISTERED)]
199: ),
200: [("finishcondition",enumcond.FinishCondEnum.DNC_COND)]
201: ),
202: ["boat","zipcorrected"]
203: ):
204: lastduplicate=[
205: entry
206: for (finish,entries) in finishes
207: for entry in entries
208: ][-1]
209: lastduplicate.starter=True
210: try:
211: lastduplicate.fin_cond
212: except AttributeError:
213: lastduplicate.finisher=False
214: else:
215: lastduplicate.finisher=True
216:
217: def rank_by_corrected_time(start,handicapsheet):
218:
219:
220:
221:
222:
223:
224:
225:
226: withfinish=handicapsheet.obverse_list(["starter"])
227: numberofstarters=len(withfinish)
228:
229: casualweight=numberofstarters-1
230:
231: rank=1
232: casualrank=-casualweight
233: for (finishcondition,timed) in withfinish.adjoin_hierarchy(
234: [("finishcondition",enumcond.FinishCondEnum.FIN_COND),"zipcorrected"]
235: ):
236:
237: assert finishcondition.fin_cond
238: for (zipcorrected,entries) in timed:
239: sharedrank=rank
240: sharedcasualrank=casualrank
241: sharedentries=[e for e in entries]
242: n=len(sharedentries)
243: sharedpoints=rank+round((n-1)/2.0,1)
244: sharedcasualpoints=casualrank+(n-1)
245: for entry in sharedentries:
246: entry.ranking=sharedrank
247: entry.points=sharedpoints
248: entry.casualpoints=sharedcasualpoints
249: rank+=n
250: casualrank+=2*n
251:
252: sharedrank=rank
253: sharedcasualrank=casualrank
254: sharedentries=withfinish.converse_sort(
255: [("finishcondition",enumcond.FinishCondEnum.FIN_COND),"zipcorrected"]
256: )
257: n=len(sharedentries)
258: sharedpoints=rank+n
259: sharedcasualpoints=casualrank+2*n
260: for entry in sharedentries:
261: entry.ranking=sharedrank
262: entry.points=sharedpoints
263: entry.casualpoints=sharedcasualpoints
264: rank=sharedpoints
265: casualrank=sharedcasualpoints
266:
267: assert numberofstarters==rank-1==casualrank-1
268:
269: start.numberofstarters=numberofstarters
270: start.casualweight=casualweight
271:
272: