Files
flask-formula10/formula10/database/model/race_result.py
Christoph Urlacher 3704192730
All checks were successful
Build Formula10 Docker Image / build-docker (push) Successful in 14s
Finish restructuring files
2024-02-24 17:41:12 +01:00

171 lines
6.7 KiB
Python

import json
from typing import Any, Dict, List
from sqlalchemy import ForeignKey, String
from sqlalchemy.orm import Mapped, mapped_column, relationship
from formula10.database.model.driver import Driver
from formula10.database.model.race import Race
from formula10 import db
class RaceResult(db.Model):
"""
The result of a past race.
It stores the corresponding race and dictionaries of place-/dnf-order and a list of drivers that are excluded from the standings for this race.
"""
__tablename__ = "raceresult"
__allow_unmapped__ = True # TODO: Used for json conversion, move this to some other class instead
__csv_header__ = ["race_name", "pxx_driver_names_json", "first_dnf_driver_names_json", "dnf_driver_names_json", "excluded_driver_names_json"]
def __init__(self, race_name: str):
self.race_name = race_name # Primary key
@staticmethod
def from_csv(row: List[str]):
race_result: RaceResult = RaceResult(str(row[0]))
race_result.pxx_driver_names_json = str(row[1])
race_result.first_dnf_driver_names_json = str(row[2])
race_result.dnf_driver_names_json = str(row[3])
race_result.excluded_driver_names_json = str(row[4])
return race_result
def to_csv(self) -> List[Any]:
return [
self.race_name,
self.pxx_driver_names_json,
self.first_dnf_driver_names_json,
self.dnf_driver_names_json,
self.excluded_driver_names_json
]
race_name: Mapped[str] = mapped_column(ForeignKey("race.name"), primary_key=True)
pxx_driver_names_json: Mapped[str] = mapped_column(String(1024), nullable=True)
first_dnf_driver_names_json: Mapped[str] = mapped_column(String(1024), nullable=True)
dnf_driver_names_json: Mapped[str] = mapped_column(String(1024), nullable=True)
excluded_driver_names_json: Mapped[str] = mapped_column(String(1024), nullable=True)
@property
def pxx_driver_names(self) -> Dict[str, str]:
return json.loads(self.pxx_driver_names_json)
@pxx_driver_names.setter
def pxx_driver_names(self, new_pxx_driver_names: Dict[str, str]):
self.pxx_driver_names_json = json.dumps(new_pxx_driver_names)
@property
def first_dnf_driver_names(self) -> List[str]:
return json.loads(self.first_dnf_driver_names_json)
@first_dnf_driver_names.setter
def first_dnf_driver_names(self, new_first_dnf_driver_names: List[str]):
self.first_dnf_driver_names_json = json.dumps(new_first_dnf_driver_names)
@property
def dnf_driver_names(self) -> List[str]:
return json.loads(self.dnf_driver_names_json)
@dnf_driver_names.setter
def dnf_driver_names(self, new_dnf_driver_names: List[str]):
self.dnf_driver_names_json = json.dumps(new_dnf_driver_names)
@property
def excluded_driver_names(self) -> List[str]:
return json.loads(self.excluded_driver_names_json)
@excluded_driver_names.setter
def excluded_driver_names(self, new_excluded_driver_names: List[str]):
self.excluded_driver_names_json = json.dumps(new_excluded_driver_names)
# Relationships
race: Mapped["Race"] = relationship("Race", foreign_keys=[race_name])
_pxx_drivers: Dict[str, Driver] | None = None
_first_dnf_drivers: List[Driver] | None = None
_dnf_drivers: List[Driver] | None = None
_excluded_drivers: List[Driver] | None = None
@property
def pxx_drivers(self) -> Dict[str, Driver]:
if self._pxx_drivers is None:
self._pxx_drivers = dict()
for position, driver_name in self.pxx_driver_names.items():
driver: Driver | None = db.session.query(Driver).filter_by(name=driver_name).first()
if driver is None:
raise Exception(f"Error: Couldn't find driver with id {driver_name}")
self._pxx_drivers[position] = driver
return self._pxx_drivers
def pxx_driver(self, offset: int = 0) -> Driver | None:
pxx_num: str = str(self.race.pxx + offset)
if pxx_num not in self.pxx_drivers:
raise Exception(f"Position {pxx_num} not found in RaceResult.pxx_drivers")
if self.pxx_drivers[pxx_num].name in self.excluded_driver_names:
none_driver: Driver | None = db.session.query(Driver).filter_by(name="None").first()
if none_driver is None:
raise Exception(f"NONE-driver not found in database")
return none_driver
return self.pxx_drivers[pxx_num]
def pxx_driver_position_string(self, driver_name: str) -> str:
for position, driver in self.pxx_driver_names.items():
if driver == driver_name and driver not in self.excluded_driver_names:
return f"P{position}"
return "NC"
@property
def all_positions(self) -> List[Driver]:
return [
self.pxx_drivers[str(position)] for position in range(1, 21)
]
@property
def first_dnf_drivers(self) -> List[Driver]:
if self._first_dnf_drivers is None:
self._first_dnf_drivers = list()
for driver_name in self.first_dnf_driver_names:
driver: Driver | None = db.session.query(Driver).filter_by(name=driver_name).first()
if driver is None:
raise Exception(f"Error: Couldn't find driver with id {driver_name}")
self._first_dnf_drivers.append(driver)
if len(self._first_dnf_drivers) == 0:
none_driver: Driver | None = db.session.query(Driver).filter_by(name="None").first()
if none_driver is None:
raise Exception("NONE-driver not found in database")
self._first_dnf_drivers.append(none_driver)
return self._first_dnf_drivers
@property
def dnf_drivers(self) -> List[Driver]:
if self._dnf_drivers is None:
self._dnf_drivers = list()
for driver_name in self.dnf_driver_names:
driver: Driver | None = db.session.query(Driver).filter_by(name=driver_name).first()
if driver is None:
raise Exception(f"Error: Couldn't find driver with id {driver_name}")
self._dnf_drivers.append(driver)
return self._dnf_drivers
@property
def excluded_drivers(self) -> List[Driver]:
if self._excluded_drivers is None:
self._excluded_drivers = list()
for driver_name in self.excluded_driver_names:
driver: Driver | None = db.session.query(Driver).filter_by(name=driver_name).first()
if driver is None:
raise Exception(f"Error: Couldn't find driver with id {driver_name}")
self._excluded_drivers.append(driver)
return self._excluded_drivers