From e83f04b960fe8bbe2d7df2f9c626a9ff64b3fc24 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Sat, 3 Dec 2022 20:40:41 +0100 Subject: [PATCH] Created complete data structures for algorithm in classes --- src/solo_turnier/__init__.py | 1 + src/solo_turnier/competition_class.py | 4 +- src/solo_turnier/group.py | 4 +- src/solo_turnier/html_parser.py | 15 +- src/solo_turnier/types.py | 230 +++++++++++++++++++++++++- 5 files changed, 238 insertions(+), 16 deletions(-) diff --git a/src/solo_turnier/__init__.py b/src/solo_turnier/__init__.py index 2f06776..a6913e4 100644 --- a/src/solo_turnier/__init__.py +++ b/src/solo_turnier/__init__.py @@ -1,6 +1,7 @@ from . import competition_class from . import group +from . import types from . import cli from . import reader diff --git a/src/solo_turnier/competition_class.py b/src/solo_turnier/competition_class.py index 57089d4..c222bba 100644 --- a/src/solo_turnier/competition_class.py +++ b/src/solo_turnier/competition_class.py @@ -15,6 +15,8 @@ class CombinedCompetitionClass: def __repr__(self): return f'{self.clsA}/{self.clsB}' +Class_t = CompetitionClass | CombinedCompetitionClass + class CompetitionClassParser: def __init__(self): self.NEWC = CompetitionClass('Newc.') @@ -33,7 +35,7 @@ class CompetitionClassParser: 'Advanced': self.ADV, } - def parseClass(self, cls: str) -> CompetitionClass|CombinedCompetitionClass: + def parseClass(self, cls: str) -> Class_t: match = re.compile('^(\\w+\\.?)/(\\w+\\.?)$').match(cls) if match is not None: clsA = self.mapNames[match.group(1)] diff --git a/src/solo_turnier/group.py b/src/solo_turnier/group.py index a9fb538..79aabfc 100644 --- a/src/solo_turnier/group.py +++ b/src/solo_turnier/group.py @@ -15,6 +15,8 @@ class CombinedGroup: def __repr__(self): return f'{self.clsA}/{self.clsB}' +Group_t = Group | CombinedGroup + class GroupParser: def __init__(self): self.KIN = Group('Kin.') @@ -33,7 +35,7 @@ class GroupParser: 'Jugend': self.JUG, } - def parseClass(self, cls: str) -> Group|CombinedGroup: + def parseClass(self, cls: str) -> Group_t: match = re.compile('^(\\w+\\.?)/(\\w+\\.?)$').match(cls) if match is not None: grpA = self.mapNames[match.group(1)] diff --git a/src/solo_turnier/html_parser.py b/src/solo_turnier/html_parser.py index 4d7f434..39d8b1b 100644 --- a/src/solo_turnier/html_parser.py +++ b/src/solo_turnier/html_parser.py @@ -3,19 +3,8 @@ from bs4 import BeautifulSoup import logging import re -class HtmlParticipant: - def __init__(self, name, place, finalist): - self.name = name - self.place = place - self.finalist = finalist - - def __str__(self): - return f'{self.name} (with place {self.place})' - -class HtmlImport: - def __init__(self, title: str, participants: dict[int, HtmlParticipant]): - self.title = title - self.participants = participants +from .types import HtmlPreviewParticipant as HtmlParticipant +from .types import HtmlPreviewImport as HtmlImport class HtmlParser: diff --git a/src/solo_turnier/types.py b/src/solo_turnier/types.py index 8f2baaf..a57eeb6 100644 --- a/src/solo_turnier/types.py +++ b/src/solo_turnier/types.py @@ -1,4 +1,7 @@ +from . import group +from . import competition_class + class CSVResultRow: def __init__(self, firstName, lastName, club, id, group, class_, dance, place, placeTo, competitionGroup, competitionClass): self.firstName = firstName @@ -17,9 +20,234 @@ class CSVResultRow: def __repr__(self): return f'{self.name} ({self.id}, {self.club}) is in {self.group} {self.class_} and danced the {self.dance} in {self.competitionGroup} {self.competitionClass} getting place {self.place}-{self.placeTo}' +class HtmlPreviewParticipant: + def __init__(self, name, place, finalist): + self.name = name + self.place = place + self.finalist = finalist + + def __repr__(self): + return f'{self.name} (with place {self.place})' + +class HtmlPreviewImport: + def __init__(self, title: str, participants: dict[int, HtmlPreviewParticipant]): + self.title = title + self.participants = participants + +class HtmlCompetitionResultRow: + def __init__(self, name, id, dance, group, class_, place, placeTo, finalist): + self.dance = dance + self.group = group + self.class_ = class_ + self.place = place + self.placeTo = placeTo + self.id = int(id) + self.name = name + self.finalist = finalist + + # @staticmethod + # def extractFromResultRow(row: ResultRow): + # return CompetitionResult( + # dance=row.dance, + # group=row.group, + # class_=row.class_, + # place=row.place, placeTo=row.placeTo, + # id=row.id, + # competitionGroup=row.competitionGroup, + # competitionClass=row.competitionClass + # ) + + def __repr__(self): + if self.place == self.placeTo: + result = f'{self.place}.' + else: + result = f'{self.place}.-{self.placeTo}.' + + if self.finalist == True: + finalist = '[F]' + else: + finalist = '' + return f'Result[{self.id}]({self.group} {self.class_} {self.dance} as {result}{finalist})' + + def __eq__(self, o): + if not isinstance(o, CompetitionResult): + return False + + return ( + self.dance == o.dance and + self.competitionClass == o.competitionClass and + self.competitionGroup == o.competitionGroup and + self.place == o.place and self.placeTo == o.placeTo and + self.id == o.id + ) + +class HtmlSingleCompetitionResult: + def __init__(self, name, place, placeTo, finalist): + self.name = name + self.place = place + self.placeTo = placeTo + self.finalist = finalist + +class HtmlCompetitionResultForDance: + def __init__(self, dance: str, results: dict[int, HtmlSingleCompetitionResult]): + self.dance = dance + self.results = results + + def get(self, id: int) ->HtmlSingleCompetitionResult: + return self.results[id] + +class HtmlCompetitionResultForClass: + def __init__( + self, + class_: competition_class.Class_t, + results: dict[str, HtmlCompetitionResultForDance] + ): + self.class_ = class_ + self.results = results + + def get(self, dance: str) -> HtmlCompetitionResultForDance: + return self.results[dance] + +class HtmlCompetitionResultForGroup: + def __init__( + self, + group: group.Group_t, + results: dict[competition_class.Class_t, HtmlCompetitionResultForClass] + ): + self.group = group + self.results = results + + def get(self, class_: str) -> HtmlCompetitionResultForClass: + return self.results[class_] + +class HtmlCompetitionTotalResults: + def __init__(self): + self.results = {} + + def __getTuple(self, group: group.Group_t, class_: competition_class.Class_t, dance: str, id: int): + return (group, class_, dance, id) + + def get(self, group: group.Group_t, class_: competition_class.Class_t, dance: str, id: int) -> list[HtmlSingleCompetitionResult]: + return self.results[self.__getTuple(group, class_, dance, id)] + + def add(self, group, class_, dance, id, result: HtmlSingleCompetitionResult): + tup = self.__getTuple(group, class_, dance, id) + l = self.results.get(tup, []) + l.append(result) + self.results[tup] = l + class State4: def __init__( self, - csvRows: list[CSVResultRow] + csvRows: list[CSVResultRow], + previewImport: HtmlPreviewImport, + htmlResults: HtmlCompetitionTotalResults ): self.csvRows = csvRows + self.previewImport = previewImport + self.htmlResults = htmlResults + +class Participant: + def __init__(self, firstName: str, lastName: str, club: str, group: group.Group, class_: competition_class.CompetitionClass): + self.firstName = firstName + self.lastName = lastName + self.club = club + self.group = group + self.class_ = class_ + +class ParticipantResult: + def __init__( + self, id: int, finalist: bool, cancelled: bool, + group: group.Group_t, + class_: competition_class.Class_t, + dance: str, + place, placeTo + ): + self.id = id + self.finalist = finalist + self.cancelled = cancelled + self.group = group + self.class_ = class_ + self.dance = dance + self.place = place + self.placeTo = placeTo + +class Stage2: + def __init__(self, results: dict[Participant, list[ParticipantResult]]): + self.results = results + +class TableCompetitionEntry: + def __init__( + self, + cancelled: bool, + finalist: bool, + class_: competition_class.Class_t, + place: int = -1, + placeTo: int = -1, + group: group.Group_t = None, + id: int = None + ): + self.finalist = finalist + self.cancelled = cancelled + self.group = group + self.class_ = class_ + self.place = place + self.placeTo = placeTo + + def __repr__(self): + def paramMerging(l): + return ', '.join(filter(lambda x: x is not None, l)) + + if self.cancelled: + params = paramMerging([self.group, self.class_, self.id]) + if len(params) > 0: + return f'- ({params})' + else: + return '-' + elif not self.finalist: + params = paramMerging([self.group, self.class_, self.id]) + if len(params) > 0: + return f'x ({params})' + else: + return 'x' + else: + if self.place == self.placeTo: + place = f'{self.place}.' + else: + place = f'{self.place}.-{self.placeTo}.' + params = paramMerging([self.group, self.class_, self.id]) + return f'{place} ({params})' + +class TableEntry: + def __init__(self, competitions: list[TableCompetitionEntry]): + self.competitions = competitions + + def __repr__(self): + return ', '.join(self.competitions) + +class TableRow: + def __init__( + self, + participant: Participant, + id: int, + entries: list[TableEntry] + ): + self.participant = participant + self.id = id + self.entries = entries + + def getRowList(self): + if self.id is not None: + first = f'{self.id}. {self.participant.firstName} {self.participant.lastName} ({self.participant.club})' + else: + first = f'{self.participant.firstName} {self.participant.lastName} ({self.participant.club})' + return [first] + map(str, self.entries) + +class OutputTable: + def __init__(self, dances: list[str], rows: list[TableRow]): + self.dances = dances + self.rows = rows + +class Stage1: + def __init__(self, tables: dict[group.Group, OutputTable]): + self.tables = tables