From b738126bf34086530450694848510ec0a5323905 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 13 Sep 2023 17:41:57 +0200 Subject: [PATCH] First working solution but with unclear about shared places --- src/solo_turnier/competition_class.py | 9 ++++ src/solo_turnier/output.py | 19 ++++--- src/solo_turnier/types.py | 9 +++- src/solo_turnier/worker.py | 75 ++++++++++++++++++++++++++- 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/src/solo_turnier/competition_class.py b/src/solo_turnier/competition_class.py index 1821d6a..9fe88c8 100644 --- a/src/solo_turnier/competition_class.py +++ b/src/solo_turnier/competition_class.py @@ -60,3 +60,12 @@ class CompetitionClassParser: def isPureClass(self, cls: str, allowPreview: bool = False) -> bool: parsedClass = self.parseClass(cls, allowPreview) return isinstance(parsedClass, CompetitionClass) + + def getAllClasses(self) -> list[CompetitionClass]: + return [self.NEWC, self.BEG, self.ADV] + + def isABetterThanB(self, a: CompetitionClass, b: CompetitionClass) -> bool: + classes = self.getAllClasses() + idxA = classes.index(a) + idxB = classes.index(b) + return idxA > idxB diff --git a/src/solo_turnier/output.py b/src/solo_turnier/output.py index 7066466..093ab7b 100644 --- a/src/solo_turnier/output.py +++ b/src/solo_turnier/output.py @@ -72,20 +72,25 @@ class ConsoleOutputter(AbstractOutputter): for participant in participants: results = groupResults.results[participant] def mapResultColumn(result: types.SingleParticipantResult): - def getPlace(): - if result.placeTo is None: - return f'{result.place}.' + def getPlace(place, placeTo): + if placeTo is None: + return f'{place}.' else: - return f'{result.place}.-{result.placeTo}.' + return f'{place}.-{placeTo}.' if result is None: return '' - place = getPlace() + placeNative = getPlace(result.placeNative, result.placeNativeTo) + place = getPlace(result.place, result.placeTo) + lineOne = f'{placeNative} ({result.nativeClass})' + lineTwo = f'[{place} in {result.competitionClass}]' + + lines = [lineOne, lineTwo] if not result.finalist: - return f'kein/e Finalist/in\n({place} in {result.nativeClass})' + lines = ['kein/e Finalist/in'] + lines - return f'{place} ({result.nativeClass})' + return '\n'.join(lines) mappedResults = map(mapResultColumn, results) tableRow = [f'{participant.name} ({participant.id})'] + list(mappedResults) diff --git a/src/solo_turnier/types.py b/src/solo_turnier/types.py index bdecc42..80c2507 100644 --- a/src/solo_turnier/types.py +++ b/src/solo_turnier/types.py @@ -182,19 +182,24 @@ class SingleParticipantResult: if placeTo == place: self.placeTo = None + + self.placeNative = None + self.placeNativeTo = None def __repr__(self): asFinalist = ' as finalist' if self.finalist else '' if self.placeTo is None: - return f'SR[{self.place} in {self.dance} {self.competitionClass} ({self.nativeClass}){asFinalist}]' + return f'SR[{self.place} in {self.dance} {self.competitionClass} ({self.placeNative}-{self.placeNativeTo}, {self.nativeClass}){asFinalist}]' - return f'SR[{self.place}-{self.placeTo} in {self.dance} {self.competitionClass} ({self.nativeClass}){asFinalist}]' + return f'SR[{self.place}-{self.placeTo} in {self.dance} {self.competitionClass} ({self.placeNative}-{self.placeNativeTo}, {self.nativeClass}){asFinalist}]' class TotalGroupResult: def __init__(self, dances: list[str], results: dict[HtmlPreviewParticipant, list[SingleParticipantResult]]): self.dances = dances self.results = results + def __repr__(self): + return f'TotalGroupResult({self.dances}, {self.results})' class State4: def __init__( diff --git a/src/solo_turnier/worker.py b/src/solo_turnier/worker.py index ad618b9..75d984b 100644 --- a/src/solo_turnier/worker.py +++ b/src/solo_turnier/worker.py @@ -107,6 +107,7 @@ class PreviewWorker: headerData = parser.guessDataFromHtmlTitle() dance = headerData['dance'] + classParser = solo_turnier.competition_class.CompetitionClassParser() def getRowIndexOfClass(): return data['titles'].index('Platz von\nPlatz bis') @@ -139,7 +140,7 @@ class PreviewWorker: group = data['table'][-1][index]['text'] # dance = - class_ = data['table'][classRowIndex][index]['text'] + class_ = classParser.parseClass(data['table'][classRowIndex][index]['text']) participant = types.HtmlPreviewParticipant(name, id, group) @@ -447,6 +448,11 @@ class Worker: self.l.log(5, 'Obtained result %s', resultsOfParticipant) results[participant] = resultsOfParticipant + self.l.log(5, 'Result before native fixing: %s', pformat(results)) + self._fixNativePlaces(dances, results) + self.l.log(5, 'Result after native fixing: %s', pformat(results)) + + totalResult[group] = types.TotalGroupResult(dances, results) self.l.log(5, 'Total result of all groups: %s', pformat(totalResult)) @@ -533,3 +539,70 @@ class Worker: results[danceIdx] = getResult() return results + + def _fixNativePlaces( + self, + dances: list[str], + data: dict[types.HtmlPreviewParticipant, list[types.SingleParticipantResult]] + ): + classParser = solo_turnier.competition_class.CompetitionClassParser() + allClasses = classParser.getAllClasses() + allClasses.reverse() + + for class_ in allClasses: + for danceIdx, dance in enumerate(dances): + self.l.log(5, 'Fixing native places for class %s in dance %s', class_, dance) + + remainingParticipants = [] + + for participant in data.keys(): + results = data[participant] + danceResult = results[danceIdx] + + if danceResult is None: + continue + + self.l.log(5, 'Result of dance: %s', danceResult) + + if classParser.isABetterThanB(danceResult.nativeClass, class_): + # self.l.log(5, 'Skipping %s as the native class is higher', participant) + continue + + remainingParticipants.append((danceResult.place, participant.id, participant)) + + remainingParticipants.sort() + self.l.log(5, 'Remaining participants %s', remainingParticipants) + + def getAllParticipantsWithSamePlace(): + first = remainingParticipants.pop(0) + ret = [first] + while len(remainingParticipants) > 0 and remainingParticipants[0][0] == first[0]: + ret.append(remainingParticipants.pop(0)) + return ret + + def updateNativePlaces(samePlaced, placeStart): + nextPlace = placeStart + len(samePlaced) + if len(samePlaced) == 1: + placeTo = None + else: + placeTo = nextPlace - 1 + + for p in samePlaced: + data[p[2]][danceIdx].placeNative = placeStart + data[p[2]][danceIdx].placeNativeTo = placeTo + + return nextPlace + + places = list(map(lambda x: x[0], remainingParticipants)) + place = 1 + while len(remainingParticipants) > 0: + samePlaced = getAllParticipantsWithSamePlace() + place = updateNativePlaces(samePlaced, place) + + self.l.log(5, '(Partially) fixed places: %s', pformat(data)) + + # firstEntry = remainingParticipants[0] + # numEntries = places.count(firstEntry[0]) + # placeTo = place + numEntries - 1 + +