From d5b04a1a66c1ff6cb65c775697da8c027d04b290 Mon Sep 17 00:00:00 2001 From: Trygve Date: Fri, 25 Feb 2022 00:26:39 +0100 Subject: [PATCH] =?UTF-8?q?Begynte=20=C3=A5=20implementere=20event=20og=20?= =?UTF-8?q?card=5Fpunches=20klassene?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev.py | 27 ++++++ otime.py | 247 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 199 insertions(+), 75 deletions(-) create mode 100644 dev.py diff --git a/dev.py b/dev.py new file mode 100644 index 0000000..d64fca0 --- /dev/null +++ b/dev.py @@ -0,0 +1,27 @@ +import otime +from rich import print +from rich import inspect +from rich.console import Console +from rich.columns import Columns +from rich.table import Table + +if __name__ == "__main__": + #courses = otime.courses_from_ttime_conf('sc_2021_ttime/ttime.cnf.txt') + #o_classes = otime.classes_from_ttime_conf('sc_2021_ttime/ttime.cnf.txt', courses) + #runner_list = otime.ttime_db_to_class('sc_2021_ttime/db_eventor.csv', o_classes) + #runner_list = otime.xml_to_class('entries_KOK_Sommercup,_løp_2.xml', o_classes) + #otime.ttime_mtr_to_class('sc_2021_ttime/mtr.csv', runner_list) + #print_runners(runner_list) + #print_time(runner_list) + #print_o_classes(o_classes) + #print_class_splits(runner_list, o_classes[0]) + #print(otime.check_codes(runner_list[1])) + #otime.gen_xml_result(runner_list, o_classes) + + event = otime.event(0, 'supercup') + event.import_ttime_cnf('sc_2021_ttime/ttime.cnf.txt') + event.import_ttime_db('sc_2021_ttime/db_eventor.csv') + #event.import_mtr_file('sc_2021_ttime/mtr.csv') + card_punches = otime.card_punch.list_from_mtr_f('sc_2021_ttime/mtr.csv') + event.append_punch_list(card_punches) + event.get_xml_res().write('Resultater.xml') diff --git a/otime.py b/otime.py index d8aa792..b03a8ae 100644 --- a/otime.py +++ b/otime.py @@ -1,7 +1,130 @@ +import copy import datetime import csv import re import xml.etree.ElementTree as ET + +class event: + def __init__(self, eventid, name, **kwargs): + self.id = eventid + self.name = name + + self.courses = [] + self.o_classes = [] + self.runners = [] + self.card_punches= [] + def add_course(self, *args): + for n in args: + self.courses.append(n) + + def add_o_class(self, *args): + for n in args: + self.o_classes.append(n) + + def add_runners(self, *args): + for n in args: + self.runners.append(n) + def import_ttime_cnf(self, ttime_file): + self.add_course(*courses_from_ttime_conf(ttime_file)) + self.add_o_class(*classes_from_ttime_conf(ttime_file, self.courses)) + + def import_ttime_db(self, ttime_file): + self.add_runners(*ttime_db_to_class(ttime_file, self.o_classes)) + + def import_mtr_file(self, mtr_file): + ttime_mtr_to_class(mtr_file, self.runners) + + # MIDLERTIDIG + def append_punch_list(self, punches): + for n in self.runners: + for i in punches: + if n.card == i.card: + n.controls = list(i.punches.keys()) + n.splits = list(i.punches.values()) + + def get_xml_res(self): + root = ET.Element('ResultList') + root.set('xmlns', 'http://www.orienteering.org/datastandard/3.0') + root.set('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance') + root.set('iofVersion', '3.0') + root.set('createTime', datetime.datetime.now().isoformat(timespec='seconds')) + root.set('creator', 'oTime') + root.set('status', 'Complete') + tree = ET.ElementTree(root) + event = ET.SubElement(root, 'Event') + xml_child(event, 'Id', self.id) + xml_child(event, 'Name', self.name) + for i in self.o_classes: + # + class_result = ET.SubElement(root, 'ClassResult') + # + t = ET.SubElement(class_result, 'Class') + xml_child(t, 'Name', i.name) + # + runners_same_c = get_runners_in_class(self.runners, i) + runners_ranked = rank_runners(runners_same_c, i) + # Put the OK runners first and Active last + print(len(runners_same_c), len(runners_ranked)) + runners_sorted = [i for i in runners_same_c if i not in runners_ranked] + print(len(runners_same_c), len(runners_ranked)) + runners_ranked.extend(runners_sorted) + + print(len(runners_same_c), len(runners_ranked)) + for n in runners_ranked: + person_result = ET.SubElement(class_result, 'PersonResult') + # + person = ET.SubElement(person_result, 'Person') + xml_child(person, 'Id', n.id) + # + name = ET.SubElement(person, 'Name') + xml_child(name, 'Family', n.last) + xml_child(name, 'Given', n.first) + # + # + # + org = ET.SubElement(person_result, 'Organisation') + xml_child(org, 'Id', '0') + xml_child(org, 'Name', n.club) + country = ET.SubElement(org, 'Country') + # TODO: hent land fra løperobjektet + country.text = 'Norway' + country.set('code', 'NOR') + # + # + result = ET.SubElement(person_result, 'Result') + if len(n.splits) > 2: + xml_child(result, 'StartTime', n.s_time.isoformat()) + xml_child(result, 'FinishTime', n.f_time.isoformat()) + xml_child(result, 'Time', n.totaltime()) + if n.status() == 'OK': + # + xml_child(result, 'TimeBehind', n.totaltime() - runners_ranked[0].totaltime()) + # + xml_child(result, 'Position', n.rank(self.runners)) + xml_child(result, 'Status', n.status()) + # + for code,split in zip(n.o_class.course.codes, n.res_splits(), strict=True): + st = ET.SubElement(result, 'SplitTime') + xml_child(st, 'ControlCode', code) + xml_child(st, 'Time', split) + # + elif n.status() == 'Disqualified': + xml_child(result, 'Status', n.status()) + for code in n.o_class.course.codes: + st = ET.SubElement(result, 'SplitTime') + xml_child(st, 'ControlCode', code) + for control,split in zip(n.controls, n.splits): + if code == control: + xml_child(st, 'Time', split) + else: + xml_child(result, 'Status', n.status()) + else: + xml_child(result, 'Status', n.status()) + # + # + # + ET.indent(root, space=' ', level=0) + return tree class runner: def __init__(self, eventorid, first, last, club, country, card, o_class, controls, splits): self.id = eventorid @@ -40,6 +163,53 @@ class runner: for n in control_map: splits.append(self.splits[n]) return splits +class card_punch: + def __init__(self, card, punches, s_time, f_time): + self.card = card + self.punches = punches + self.s_time = s_time + self.f_time = f_time + def __repr__(self): + return f'card({self.card}) punches({self.punches})' + + def list_from_mtr_f(mtr_f): + csvreader = csv.reader(open(mtr_f)) + fields = next(csvreader) + + fields = [] + rows = [] + + cards = [] + # hver rad er brikkenummer med tilhørende info + for row in csvreader: + rows.append(row) + controls = [] + splits = [] + # postkodene kommer på oddetall fra og med den 11. De blir hevet inn i controls + for item in row[11::2]: + if item != '000' and item != '0000' and item != '00000': + controls.append(int(item)) + # strekktidene kommer på partall fra og med den 12. De blir hevet i splits. + for item in row[12::2]: + if item != '000' and item != '0000' and item != '00000': + splits.append(int(item)) + # looper gjonnom løperobjektene og legger til poster og strekktider + start og sluttid + # usikker på om dette er riktig klokeslett + tl = row[5].split(' ') + tl[0] = tl[0].split('.') + tl[0][2] = '20' + tl[0][2] + tl[0] = list(map(int, tl[0])) + tl[1] = tl[1].split(':') + tl[1][2] = float(tl[1][2]) + tl[1] = list(map(int, tl[1])) + f_time = datetime.datetime(tl[0][2], tl[0][1], tl[0][0], tl[1][0], tl[1][1], tl[1][2]) + if controls[-1] == 250: + s_time = f_time - datetime.timedelta(seconds = splits[-2]) + else: + pass + #s_time = f_time + cards.append(card_punch(int(row[6]), dict(zip(controls, splits)), s_time, f_time)) + return cards class course: def __init__(self, name, codes): self.name = name @@ -144,6 +314,7 @@ def ttime_db_to_class(ttime_file, o_class_list=[]): runnerarray.append(runner(eventorid, first, last, club, country, card, runner_o_class, [], [])) return runnerarray +# Denne fjernes når card_punch klasses er ferdig def ttime_mtr_to_class(csv_file, runnerarray): csvreader = csv.reader(open(csv_file)) fields = next(csvreader) @@ -216,83 +387,9 @@ def rank_runners(allrunners, o_class): for i in runners: if i.status() == 'OK': runners_ranked.append(i) + runners_ranked.sort(key=lambda x: x.totaltime()) return runners_ranked def xml_child(parent, tag, content): e = ET.SubElement(parent, tag) e.text = str(content) - -def gen_xml_result(runners, o_classes): - root = ET.Element('ResultList') - root.set('iofVersion', '3.0') - root.set('createTime', datetime.datetime.now().isoformat()) - root.set('creator', 'oTime') - root.set('status', 'Complete') - tree = ET.ElementTree(root) - event = ET.SubElement(root, 'Event') - xml_child(event, 'Name', 'PLACEHOLDER') - for i in o_classes: - # - class_result = ET.SubElement(root, 'ClassResult') - # - t = ET.SubElement(class_result, 'Class') - xml_child(t, 'Name', i.name) - # - runners_same_c = get_runners_in_class(runners, i) - runners_ranked = rank_runners(runners_same_c, i) - for n in runners_same_c: - person_result = ET.SubElement(class_result, 'PersonResult') - # - person = ET.SubElement(person_result, 'Person') - xml_child(person, 'Id', n.id) - # - name = ET.SubElement(person, 'Name') - xml_child(name, 'Family', n.last) - xml_child(name, 'Given', n.first) - # - # - # - org = ET.SubElement(person_result, 'Organisation') - xml_child(org, 'Id', '0') - xml_child(org, 'Name', n.club) - country = ET.SubElement(org, 'Country') - # TODO: hent land fra løperobjektet - country.text = 'Norway' - country.set('code', 'NOR') - # - # - result = ET.SubElement(person_result, 'Result') - if len(n.splits) > 2: - xml_child(result, 'StartTime', n.s_time.isoformat()) - xml_child(result, 'FinishTime', n.f_time.isoformat()) - xml_child(result, 'Time', n.totaltime()) - if n.status() == 'OK': - # - xml_child(result, 'TimeBehind', n.totaltime() - runners_ranked[0].totaltime()) - # - xml_child(result, 'Position', n.rank(runners)) - xml_child(result, 'Status', n.status()) - # - for code,split in zip(n.o_class.course.codes, n.res_splits(), strict=True): - st = ET.SubElement(result, 'SplitTime') - xml_child(st, 'ControlCode', code) - xml_child(st, 'Time', split) - # - elif n.status() == 'Disqualified': - xml_child(result, 'Status', n.status()) - for code in n.o_class.course.codes: - st = ET.SubElement(result, 'SplitTime') - xml_child(st, 'ControlCode', code) - for control,split in zip(n.controls, n.splits): - if code == control: - xml_child(st, 'Time', split) - else: - xml_child(result, 'Status', n.status()) - else: - xml_child(result, 'Status', n.status()) - # - # - # - ET.indent(root, space=' ', level=0) - tree.write('Resultater.xml') - return tree