import solo_turnier import logging import os import pprint import tabulate class BatchWorker: def __init__( self, config: solo_turnier.cli.Cli ): self.l = logging.getLogger('solo_turnier.batch') self.config = config self.__groupMap = { 'Kin.': 0, 'Kin./Jun.': 1, 'Jun.': 10, 'Jun./Jug.': 11, 'Jug.': 20 } self.__danceMap = { 'Samba': 1, 'Cha Cha': 2, 'Rumba': 3, 'Paso Doble': 4, 'Jive': 5, 'Langs. Walzer': 11, 'Tango': 12, 'Wiener Walzer': 13, 'Slowfox': 14, 'Quickstep': 15 } self.__groupFinalMap = { 'Kinder': 'Kin.', 'Junioren': 'Jun.', 'Jugend': 'Jug.' } def __extractDataFromFiles(self): allResultName = os.path.join(self.config.importPath(), 'allresults.csv') readerAllResults = solo_turnier.reader.AllResultReader(allResultName) allResults = readerAllResults.readFile() finals = [] # Do this in a loop finalName = os.path.join(self.config.importPath(), 'wert_er.txt') readerFinal = solo_turnier.reader.ERReader(finalName) result = readerFinal.readFile() finals.append(result) return (allResults, finals) def __convertFinalToTuple(self, result): return { 'group': result['gruppe'], 'class': result['klasse'], 'dance': result['tanz'], 'finalists': result['finalisten'] } def __extractAllData(self, r): return { 'date': r[1], 'group': r[2], 'class': r[3], 'dance': r[4], 'id': int(r[5]), 'firstName': r[6], 'lastName': r[7], 'club': r[10], 'ltv': r[11], 'place': r[12], 'placeTo': r[13], 'points': r[14], 'personGroup': r[15], 'personClass': r[16], 'remarks': r[17] } def __extractPersonData(self, r): data = self.__extractAllData(r) person = solo_turnier.participant.Person( firstName=data['firstName'], lastName=data['lastName'], club=data['club'], group=data['personGroup'] ) return person def __extractPersons(self, allResults): def decorate(person,i): return (person.firstName, person.lastName, person.club, i, person) personRows = [self.__extractPersonData(r) for r in allResults['data']] persons = list(set(personRows)) persons = [decorate(p,i) for i,p in enumerate(persons)] persons.sort() persons = [p[4] for p in persons] return persons def __extractAllResults(self, allResults, persons: list[solo_turnier.participant.Person]): def __extractDanceResult(r): data = self.__extractAllData(r) try: return { 'dance': data['dance'], 'class': data['personClass'], 'place': int(data['place']), 'placeTo': int(data['placeTo']), 'id': data['id'] } except ValueError: self.l.debug('Issue found with data %s.', data) return None ret = {} for row in allResults['data']: danceResult = __extractDanceResult(row) if danceResult is not None: person = self.__extractPersonData(row) if person not in ret: ret[person] = [] ret[person].append(danceResult) return ret def __extractCompetitionEntries(self, r): data = self.__extractAllData(r) return (data['personGroup'], data['dance']) def __extractCompetitions(self, allResults): def __decorate(r): return (self.__groupMap[r[0]], self.__danceMap[r[1]],r) competitionsRows = [self.__extractCompetitionEntries(r) for r in allResults['data']] # competitions = list(set([self.__extractDanceResult(r) for r in allResults['data']])) competitions = [__decorate(r) for r in list(set(competitionsRows))] competitions.sort() competitions = [r[2] for r in competitions] return competitions def __extractGroups(self, allResults): def __extractGroupEntries(r): data = self.__extractAllData(r) return data['personGroup'] def __decorate(r): return (self.__groupMap[r], r) rows = [__extractGroupEntries(r) for r in allResults['data']] groups = [__decorate(r) for r in list(set(rows))] groups.sort() groups = [r[1] for r in groups] return groups def __extarctBasicData(self, allResults): def __extractRow(r): ret = { 'firstName': r[6], 'lastName': r[7], 'number': int(r[5]), 'club': r[10], 'place': int(r[12]), 'placeTo': int(r[13]), 'group': r[15], 'class': r[16] } return ret return [__extractRow(r) for r in allResults['data'][0:2]] def run(self): allResults, finals = self.__extractDataFromFiles() persons = self.__extractPersons(allResults) self.l.debug('Found persons: %s', persons) totalResults = self.__extractAllResults(allResults, persons) self.l.debug('Total results: %s', totalResults) groups = self.__extractGroups(allResults) self.l.debug('Found groups: %s', groups) groupRes = {} for group in groups: self.l.info('Processing group %s', group) groupRes[group] = {} personsInGroup = [p for p in persons if p.group == group] self.l.debug('Remaining persons: %s', personsInGroup) groupRes[group]['participants'] = personsInGroup groupRes[group]['results'] = {} for person in personsInGroup: groupRes[group]['results'][person] = totalResults[person] # resultsInGroup = totalResults[personsInGroup] # self.l.debug('Results in group: %s', resultsInGroup) # Do this in a loop finalists = [self.__convertFinalToTuple(r) for r in finals] self.l.debug('Mapped to tuples: %s', finalists) self.l.info('Augmenting the list of participants') for finalistList in finalists: self.l.debug('Augmenting competition %s', finalistList) longGroup = finalistList['group'] grep = self.__groupFinalMap[longGroup] for person in groupRes[group]['results'].keys(): self.l.debug('Checking %s for finalist state in competition', person) for competition in groupRes[group]['results'][person]: if competition['dance'] != finalistList['dance']: continue if competition['class'] != finalistList['class']: continue competition['finalist'] = (competition['id'] in finalistList['finalists']) self.l.debug('Organized results: %s', groupRes) dancesRaw = [competition['dance'] for group in groups for person in groupRes[group]['participants'] for competition in groupRes[group]['results'][person]] dances = list(set(dancesRaw)) dances = [(self.__danceMap[d], d) for d in dances] dances.sort() dances = [r[1] for r in dances] self.l.debug('Found dances in competition: %s', dances) ret = {} for group in groups: ret[group] = {} for person in groupRes[group]['participants']: ret[group][person] = {} # Seed the data structure for dance in dances: ret[group][person][dance] = { 'participated': False, 'class': '', 'finalist': False, 'place': '', 'id': 0 } for competition in groupRes[group]['results'][person]: def __getPlace(): if competition['place'] == competition['placeTo']: return str(competition['place']) else: return f"{competition['place']}-{competition['placeTo']}" dance = competition['dance'] ret[group][person][dance]['participated'] = True ret[group][person][dance]['class'] = competition['class'] ret[group][person][dance]['finalist'] = competition.get('finalist', False) ret[group][person][dance]['place'] = __getPlace() ret[group][person][dance]['id'] = competition['id'] self.l.debug('Returned data: %s', pprint.pformat(ret)) for group in groups: self.l.debug('Outputting table for group %s', group) print(f'Ergebnisse der Gruppe {group}') print() row = ['Teilnehmer(in)'] + dances table = [row] for person in ret[group]: row = [str(person)] for dance in dances: if not ret[group][person][dance]['participated']: row.append('') continue if not ret[group][person][dance]['finalist']: row.append('x') continue row.append(f"{ret[group][person][dance]['place']} ({ret[group][person][dance]['class']}, {ret[group][person][dance]['id']})") table.append(row) self.l.debug(table) # print(tabulate.tabulate(table)) print(tabulate.tabulate(table, headers='firstrow', tablefmt='fancy_grid')) print() # self.l.debug('Organized results: %s', pprint.pformat( groupRes['Jun.'])) # competitions = self.__extractCompetitions(allResults) # self.l.debug('Competitions: %s', competitions) # basicData = self.__extarctBasicData(allResults) # self.l.debug('Basic extracted data: %s', basicData)