"""Utilities to support splitting fuel and car maintainance costs""" import typing as T PassengerResult = dict[str, int] Results = dict[str, PassengerResult] TankenFailure = T.Tuple[None, str] TankenSuccess = T.Tuple[Results, None] TankenResult = T.Union[TankenSuccess, TankenFailure] # cost should be given in cents def tanken(_drives: list[str], cost: int, service_charge=0) -> TankenResult: """calculate costs per passange for one tank load""" passengers = {} distance = 0. drives = [d.split(' ') for d in _drives] for drive in drives: try: drive_distance = int(drive[0]) except (IndexError, ValueError): return None, "Lines have to start with the driven distance!" # calculate overall distance distance += drive_distance # collect distances per passenger for passenger in drive[1:]: if passenger not in passengers: passengers[passenger] = { "distance": drive_distance, "cost": 0, "service_charge": 0 } else: passengers[passenger]["distance"] += drive_distance # calculate cost per kilometer if distance <= 0: return None, "Driven distance must be greater than 0!" c_km = cost / distance for drive in drives: drive_distance = int(drive[0]) # calculate cost per drive split among passengers c_d = int(c_km * drive_distance / (len(drive) - 1)) for passenger in drive[1:]: passengers[passenger]["cost"] += c_d # calculate service charge per drive split among passengers sc_d = int(service_charge * drive_distance / (len(drive) - 1)) for passenger in drive[1:]: passengers[passenger]["service_charge"] += sc_d return passengers, None