def time_to_otime(t): if isinstance(t, datetime.datetime): return OTime(0, t.hour, t.minute, t.second, round(t.microsecond / 1000)) if isinstance(t, QTime): return OTime(0, t.hour(), t.minute(), t.second(), t.msec()) if isinstance(t, datetime.timedelta): return time_to_otime(datetime.datetime(2000, 1, 1, 0, 0, 0) + t) if isinstance(t, OTime): return t return OTime()
def set_values(self): obj = race() if obj.get_setting('handicap_mode', True): self.handicap_mode.toggle() else: self.reverse_mode.toggle() self.zero_time.setTime(OTime(msec=obj.get_setting('handicap_start', OTime(0, 11).to_msec())).to_time()) self.max_gap.setTime(OTime(msec=obj.get_setting('handicap_max_gap', OTime(0, 0, 30).to_msec())).to_time()) self.second_time.setTime( OTime(msec=obj.get_setting('handicap_second_start', OTime(0, 11, 30).to_msec())).to_time()) self.interval_time.setTime(OTime(msec=obj.get_setting('handicap_interval', OTime(0, 0, 1).to_msec())).to_time()) self.dsq_offset.setTime(OTime(msec=obj.get_setting('handicap_dsq_offset', OTime(0, 0, 10).to_msec())).to_time())
def hhmmss_to_time(value): arr = str(value).split(':') if len(arr) == 3: msec = 0 secs = arr[2].split('.') sec = int(secs[0]) if len(secs) == 2: msec = int(secs[1]) if len(secs[1]) == 1: msec *= 100 elif len(secs[1]) == 2: msec *= 10 return OTime(0, int(arr[0]), int(arr[1]), sec, msec) return OTime()
def get_group_leader_time(self, group): if self.race.get_type(group) == RaceType.RELAY: team_result = find(self.race.relay_teams, group=group, place=1) if isinstance(team_result, RelayTeam): leader_time = team_result.get_time() else: return OTime() else: results = self.get_group_finishes(group) if len(results) > 0: leader_result = results[0] leader_time = leader_result.get_result_otime() else: return OTime() return leader_time
def calculate_scores_result(self, result): if isinstance(result, Result) and result.person and result.person.group: place = int(result.place) if self.race.get_type( result.person.group) == RaceType.RELAY and get_team_result( result.person) == OTime(0): place = 0 if place > 0: scores_type = self.race.get_setting('scores_mode', 'off') if scores_type == 'array': scores_array = str( self.race.get_setting('scores_array', '0')).split(',') if len(scores_array): if place > len(scores_array): result.scores = int(scores_array[-1]) else: result.scores = int(scores_array[place - 1]) else: result.scores = 0 elif scores_type == 'formula': if self.race.get_type( result.person.group) == RaceType.RELAY: time_value = get_team_result(result.person).to_msec() else: time_value = result.get_result_otime().to_msec() leader_time = self.get_leader_time(result) if leader_time: leader_time_value = leader_time.to_msec() else: leader_time_value = 1000 result.scores = self.get_scores_by_formula( leader_time_value, time_value) else: result.scores = 0
def set_numbers_by_minute(self, persons, first_number=1): max_assigned_num = first_number if persons and len(persons) > 0: # first find minimal start time first_start = min(persons, key=lambda x: x.start_time).start_time if not first_start: first_start = OTime() # find number >= initial first number and have %100 = first start minute minute = first_start.minute min_num = int(first_number / 100) * 100 + minute if min_num < first_number: min_num += 100 for current_person in persons: if current_person.start_time: start_time = current_person.start_time delta = (start_time - first_start).to_minute() current_person.bib = int(min_num + delta) max_assigned_num = max(max_assigned_num, current_person.bib) else: current_person.bib = 0 if max_assigned_num > first_number: return max_assigned_num + 1 return first_number
def recover_state(self): obj = race() self.reserve_check_box.setChecked( obj.get_setting('is_start_preparation_reserve', False)) self.reserve_prefix.setText( obj.get_setting('reserve_prefix', _('Reserve'))) self.reserve_group_count_spin_box.setValue( obj.get_setting('reserve_count', 1)) self.reserve_group_percent_spin_box.setValue( obj.get_setting('reserve_percent', 0)) self.draw_check_box.setChecked( obj.get_setting('is_start_preparation_draw', False)) self.draw_groups_check_box.setChecked( obj.get_setting('is_split_start_groups', False)) self.draw_teams_check_box.setChecked( obj.get_setting('is_split_teams', False)) self.draw_regions_check_box.setChecked( obj.get_setting('is_split_regions', False)) self.draw_mix_groups_check_box.setChecked( obj.get_setting('is_mix_groups', False)) self.start_check_box.setChecked( obj.get_setting('is_start_preparation_time', False)) if obj.get_setting('is_fixed_start_interval', True): self.start_interval_radio_button.setChecked(True) else: self.start_group_settings_radion_button.setChecked(True) t = OTime(msec=obj.get_setting('start_interval', 60000)) self.start_interval_time_edit.setTime(QTime(t.hour, t.minute, t.sec)) t = OTime(msec=obj.get_setting('start_first_time', 60000)) self.start_first_time_edit.setTime(QTime(t.hour, t.minute, t.sec)) self.numbers_check_box.setChecked( obj.get_setting('is_start_preparation_numbers', False)) if obj.get_setting('is_fixed_number_interval', True): self.numbers_interval_radio_button.setChecked(True) elif obj.get_setting('is_corridor_minute_number', False): self.numbers_minute_radio_button.setChecked(True) elif obj.get_setting('is_corridor_order_number', False): self.numbers_order_radio_button.setChecked(True) self.numbers_interval_spin_box.setValue( obj.get_setting('numbers_interval', 1)) self.numbers_first_spin_box.setValue( obj.get_setting('numbers_first', 1))
def execute(self): logging.debug('Penalty removing start') for result in race().results: result.penalty_time = OTime(msec=0) result.penalty_laps = 0 logging.debug('Penalty removing finish') ResultCalculation(race()).process_results() self.app.refresh()
def get_time_for_rank(self, leader_time, qual, rank): percent = self.get_percent_for_rank(qual, rank) if leader_time: assert isinstance(leader_time, OTime) msec_new = round(leader_time.to_msec() * percent / 100) ret = OTime(msec=msec_new) return ret return None
def change_start_time(if_add, time_offset): obj = race() for person in obj.persons: if person.start_time is None: person.start_time = OTime() if if_add: person.start_time = person.start_time + time_offset else: person.start_time = person.start_time - time_offset
def send(self, finish): if finish and isinstance(finish, WDBFinish): man = self.current_wdb.find_man_by_number(finish.number) assert isinstance(man, WDBMan) ret = self.url ret += ONLINE_NUMBER + "=" + str(finish.number) ret += "&" + ONLINE_RESULT + "=" + time_to_hhmmss( int_to_otime(man.result)) ret += "&" + ONLINE_FLAG + "=" + str(man.status) ret += "&" + ONLINE_TIME + "=" + str( OTime.now().to_sec() * 100) # WO-compatible time in sec * 100 if self.send_splits: splits = self.get_splits(self.current_wdb, man) ret += "&" + ONLINE_SPLIT + "=" + splits logging.info(ret) res = requests.get(ret)
def handicap_start_time(): obj = race() handicap_start = OTime(msec=obj.get_setting('handicap_start', OTime(hour=11).to_msec())) handicap_max_gap = OTime(msec=obj.get_setting('handicap_max_gap', OTime(minute=30).to_msec())) handicap_second_start = OTime( msec=obj.get_setting('handicap_second_start', OTime(hour=11, minute=30).to_msec())) handicap_interval = OTime(msec=obj.get_setting('handicap_interval', OTime(minute=30).to_msec())) rc = ResultCalculation(obj) for group in obj.groups: results = rc.get_group_finishes(group) # get sorted results leader_time = rc.get_group_leader_time(group) changed_persons = [] current_second_group_time = handicap_second_start for result in results: assert isinstance(result, Result) cur_time = result.get_result_otime() gap = cur_time - leader_time if gap < handicap_max_gap and result.is_status_ok(): start_time = handicap_start + gap else: start_time = current_second_group_time current_second_group_time += handicap_interval if result.person: result.person.start_time = start_time changed_persons.append(result.person) # also process people without finish (DNS) persons = rc.get_group_persons(group) for person in persons: if person not in changed_persons: person.start_time = current_second_group_time current_second_group_time += handicap_interval
def get_leader_time(self, result): # find leader time in group if result and isinstance(result, Result): if result.person and result.person.group: group = result.person.group results = ResultCalculation( self.race).get_group_finishes(group) best_time = None for cur_result in results: assert isinstance(cur_result, Result) if not cur_result.is_status_ok(): continue if self.race.get_type(group) == RaceType.RELAY: cur_time = get_team_result(cur_result.person) else: cur_time = cur_result.get_result_otime() if not best_time or cur_time < best_time: if cur_time > OTime(0): best_time = cur_time return best_time return None
def reverse_start_time(): obj = race() handicap_start = OTime(msec=obj.get_setting('handicap_start', OTime(hour=11).to_msec())) handicap_interval = OTime(msec=obj.get_setting('handicap_interval', OTime(minute=30).to_msec())) handicap_dsg_offset = OTime( msec=obj.get_setting('handicap_dsg_offset', OTime(minute=10).to_msec())) rc = ResultCalculation(obj) for group in obj.groups: results = rc.get_group_finishes(group) # get sorted results first_group = [] second_group = [] for result in results: assert isinstance(result, Result) if result.is_status_ok() and result.person: second_group.append(result.person) # reverse main group, leader should be last second_group.reverse() persons = rc.get_group_persons(group) for person in persons: if person not in second_group: first_group.append(person) # first process DSQ and DNS - toss them first_group = DrawManager(obj).process_array(first_group, False, True, False) cur_time = handicap_start for person in first_group: assert isinstance(person, Person) person.start_time = cur_time cur_time += handicap_interval # add offset after DSQ and DNS cur_time += handicap_dsg_offset - handicap_interval # set time for main group for person in second_group: assert isinstance(person, Person) person.start_time = cur_time cur_time += handicap_interval
def calculate_scores_rogain(result): user_array = [] ret = 0 for cur_split in result.splits: code = str(cur_split.code) if code not in user_array: user_array.append(code) ret += ResultChecker.get_control_score(code) if result.person and result.person.group: user_time = result.get_result_otime() max_time = result.person.group.max_time if OTime() < max_time < user_time: time_diff = user_time - max_time seconds_diff = time_diff.to_sec() minutes_diff = (seconds_diff + 59) // 60 # note, 1:01 = 2 minutes penalty_step = race().get_setting( 'result_processing_scores_minute_penalty', 1.0) ret -= minutes_diff * penalty_step if ret < 0: ret = 0 return ret
def set_values_from_model(self): cur_race = race() zero_time = cur_race.get_setting('system_zero_time', (8, 0, 0)) start_source = cur_race.get_setting('system_start_source', 'protocol') start_cp_number = cur_race.get_setting('system_start_cp_number', 31) finish_source = cur_race.get_setting('system_finish_source', 'station') finish_cp_number = cur_race.get_setting('system_finish_cp_number', 90) assign_chip_reading = cur_race.get_setting('system_assign_chip_reading', 'off') duplicate_chip_processing = cur_race.get_setting('system_duplicate_chip_processing', 'several_results') assignment_mode = cur_race.get_setting('system_assignment_mode', False) si_port = cur_race.get_setting('system_port', '') self.item_zero_time.setTime(QTime(zero_time[0], zero_time[1])) self.item_si_port.setCurrentText(si_port) if start_source == 'protocol': self.item_start_protocol.setChecked(True) elif start_source == 'station': self.item_start_station.setChecked(True) elif start_source == 'cp': self.item_start_cp.setChecked(True) elif start_source == 'gate': self.item_start_gate.setChecked(True) self.item_start_cp_value.setValue(start_cp_number) if finish_source == 'station': self.item_finish_station.setChecked(True) elif finish_source == 'cp': self.item_finish_cp.setChecked(True) elif finish_source == 'beam': self.item_finish_beam.setChecked(True) self.item_finish_cp_value.setValue(finish_cp_number) if assign_chip_reading == 'off': self.chip_reading_off.setChecked(True) elif assign_chip_reading == 'only_unknown_members': self.chip_reading_unknown.setChecked(True) elif assign_chip_reading == 'always': self.chip_reading_always.setChecked(True) elif assign_chip_reading == 'autocreate': self.chip_reading_autocreate.setChecked(True) if duplicate_chip_processing == 'several_results': self.chip_duplicate_serveral_results.setChecked(True) elif duplicate_chip_processing == 'bib_request': self.chip_duplicate_bib_request.setChecked(True) elif duplicate_chip_processing == 'relay_find_leg': self.chip_duplicate_relay_find_leg.setChecked(True) elif duplicate_chip_processing == 'merge': self.chip_duplicate_merge.setChecked(True) self.assignment_mode.setChecked(assignment_mode) # result processing obj = cur_race rp_mode = obj.get_setting('result_processing_mode', 'time') rp_score_mode = obj.get_setting('result_processing_score_mode', 'rogain') rp_fixed_scores_value = obj.get_setting('result_processing_fixed_score_value', 1) rp_scores_minute_penalty = obj.get_setting('result_processing_scores_minute_penalty', 1) if rp_mode == 'time': self.rp_time_radio.setChecked(True) else: self.rp_scores_radio.setChecked(True) if rp_score_mode == 'rogain': self.rp_rogain_scores_radio.setChecked(True) else: self.rp_fixed_scores_radio.setChecked(True) self.rp_fixed_scores_edit.setValue(rp_fixed_scores_value) self.rp_scores_minute_penalty_edit.setValue(rp_scores_minute_penalty) # penalty calculation mr_mode = obj.get_setting('marked_route_mode', 'off') mr_penalty_time = OTime(msec=obj.get_setting('marked_route_penalty_time', 60000)) mr_if_counting_lap = obj.get_setting('marked_route_if_counting_lap', True) mr_if_station_check = obj.get_setting('marked_route_if_station_check', False) mr_station_code = obj.get_setting('marked_route_station_code', 80) mr_if_dont_dsq_check = obj.get_setting('marked_route_dont_dsq', False) mr_if_max_penalty_by_cp = obj.get_setting('marked_route_max_penalty_by_cp', False) if mr_mode == 'off': self.mr_off_radio.setChecked(True) elif mr_mode == 'time': self.mr_time_radio.setChecked(True) else: self.mr_laps_radio.setChecked(True) self.mr_time_edit.setTime(mr_penalty_time.to_time()) self.mr_counting_lap_check.setChecked(mr_if_counting_lap) self.mr_lap_station_check.setChecked(mr_if_station_check) self.mr_lap_station_edit.setValue(mr_station_code) self.mr_dont_dqs_check.setChecked(mr_if_dont_dsq_check) self.mr_max_penalty_by_cp.setChecked(mr_if_max_penalty_by_cp) # score settings scores_mode = obj.get_setting('scores_mode', 'off') scores_array = obj.get_setting('scores_array', '40,37,35,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,' '16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1') scores_formula = obj.get_setting('scores_formula', '200 - 100 * time / leader') if scores_mode == 'off': self.scores_off.setChecked(True) elif scores_mode == 'array': self.scores_array.setChecked(True) elif scores_mode == 'formula': self.scores_formula.setChecked(True) self.scores_array_edit.setText(scores_array) self.scores_formula_edit.setText(scores_formula) # time settings time_accuracy = obj.get_setting('time_accuracy', 0) time_format_24 = obj.get_setting('time_format_24', 'less24') self.time_settings_accuracy_edit.setValue(time_accuracy) if time_format_24 == 'less24': self.time_settings_format_less.setChecked(True) elif time_format_24 == 'more24': self.time_settings_format_more.setChecked(True)
def int_to_otime(value): """ convert value from 1/100 s to otime """ ret = OTime(0, value // 360000 % 24, (value % 360000) // 6000, (value % 6000) // 100, (value % 100) * 10) return ret
def create_objects(self): """Create objects in memory, according to model""" my_race = race() assert (isinstance(my_race, Race)) my_race.data.title = '\n'.join(self.wdb_object.info.title) my_race.data.location = self.wdb_object.info.place my_race.data.chief_referee = self.wdb_object.info.referee my_race.data.secretary = self.wdb_object.info.secretary for team in self.wdb_object.team: assert (isinstance(team, WDBTeam)) new_team = Organization() new_team.name = team.name my_race.organizations.append(new_team) for course in self.wdb_object.dist: assert (isinstance(course, WDBDistance)) new_course = Course() new_course.controls = [] new_course.name = course.name new_course.climb = course.elevation new_course.length = course.length # new_course.type = self.wdb_object.info.type # TODO parse type # controls for i in range(course.point_quantity): control = CourseControl() control.code = str(course.point[i]) if control.code == '0': break if i < len(course.leg): control.length = course.leg[i] new_course.controls.append(control) my_race.courses.append(new_course) for group in self.wdb_object.group: assert (isinstance(group, WDBGroup)) new_group = Group() new_group.name = group.name new_group.price = group.owner_cost course = group.get_course() if course is not None: new_group.course = find(race().courses, name=course.name) my_race.groups.append(new_group) for man in self.wdb_object.man: assert (isinstance(man, WDBMan)) new_person = Person() new_person.surname = man.name.strip().split(" ")[0] new_person.name = man.name.strip().split(" ")[-1] new_person.bib = man.number if man.qualification: if man.qualification == 10: man.qualification = Qualification.MSMK.value # Convert ZMS to MSMK new_person.qual = Qualification.get_qual_by_code( man.qualification) new_person.set_year(man.year) race().person_card_number(new_person, man.si_card) new_person.is_out_of_competition = man.is_not_qualified new_person.comment = man.comment new_person.start_group = man.start_group new_person.is_rented_card = not (man.is_own_card >> 1) new_person.is_personal = man.is_without_team found_group = man.get_group() if found_group: group_name = found_group.name new_person.group = find(race().groups, name=group_name) found_team = man.get_team() if found_team: team_name = found_team.name new_person.organization = find(race().organizations, name=team_name) my_race.persons.append(new_person) new_person.start_time = int_to_otime(man.start) # result for fin in self.wdb_object.fin: assert (isinstance(fin, WDBFinish)) result = ResultSportident() result.finish_time = int_to_otime(fin.time) result.bib = fin.number person = find(my_race.persons, bib=result.bib) if person: result.person = person wdb_person = find(self.wdb_object.man, number=result.bib) if wdb_person.status in self.status: result.status = self.status[wdb_person.status] result.penalty_time = OTime(sec=wdb_person.penalty_second) my_race.add_result(result) # punches for chip in self.wdb_object.chip: assert (isinstance(chip, WDBChip)) person = find(my_race.persons, card_number=chip.id) if person: result = find(my_race.results, person=person) if not result: result = ResultSportident() result.person = person my_race.add_result(result) else: result = ResultSportident() my_race.add_result(result) result.card_number = chip.id result.splits = [] for i in range(chip.quantity): p = chip.punch[i] assert isinstance(p, WDBPunch) code = p.code time = int_to_otime(p.time) split = Split() split.code = str(code) split.time = time if code > 0: result.splits.append(split) ResultCalculation(race()).process_results()