"""Решение задачи про классы и наследование""" from csv import reader from functools import reduce from os.path import splitext from typing import TYPE_CHECKING if TYPE_CHECKING: from typing import List class CarBase: """Базовый класс для автомобилей и спецтехники""" def __init__( self, brand: "str", photo_file_name: "str", carrying: "float", car_type: "str" = "car", ): """Конструктор базового класса""" self.brand: "str" = brand self.photo_file_name: "str" = photo_file_name self.carrying: "float" = carrying self.__car_type: "str" = car_type def __repr__(self) -> "str": """Строковое представления объекта""" return f"{self.car_type}: {self.brand} {self.carrying}" @property def car_type(self) -> "str": """Тип автомобиля или спецтехники""" return self.__car_type def get_photo_file_ext(self) -> "str": """Предоставляет расширение файла с фото""" return splitext(self.photo_file_name)[1] class Car(CarBase): """Класс легковых автомобилей""" def __init__( self, brand: "str", photo_file_name: "str", carrying: "float", passenger_seats_count: "int", ): """Конструктор класса легковых автомобилей""" super().__init__(brand, photo_file_name, carrying) self.passenger_seats_count: "int" = passenger_seats_count class Truck(CarBase): """Класс грузовых автомобилей""" def __init__( self, brand: "str", photo_file_name: "str", carrying: "float", body_whl: "str", ): """Конструктор класса грузовых автомобилей""" super().__init__(brand, photo_file_name, carrying, "truck") self.body_width: "float" = 0.0 self.body_height: "float" = 0.0 self.body_length: "float" = 0.0 if body_whl: try: self.body_width, self.body_height, self.body_length = tuple( map(float, body_whl.split("x", maxsplit=2)) ) except ValueError as error: raise ValueError( "Invalid format argument body_whl." ) from error def get_body_volume(self) -> "float": """Возвращает объем кузова в метрах кубических""" return reduce( lambda x, y: x * y, (self.body_width, self.body_height, self.body_length), ) class SpecMachine(CarBase): """Класс спецтехники""" def __init__( self, brand: "str", photo_file_name: "str", carrying: "float", extra: "str", ): """Конструктор класса спецтехники""" super().__init__(brand, photo_file_name, carrying, "spec_machine") self.extra: "str" = extra def get_car_list(csv_filename: "str") -> "List[CarBase]": """Чтение данных из csv файла и представление их в виде списка объектов""" car_list: "List[CarBase]" = [] with open(csv_filename, encoding="UTF-8") as csv_fd: for i, row in enumerate(reader(csv_fd, delimiter=";")): if i and len(row) == 7: try: if row[0] == "car": car_list.append( Car(row[1], row[3], float(row[5]), int(row[2])) ) elif row[0] == "truck": car_list.append( Truck(row[1], row[3], float(row[5]), row[4]) ) elif row[0] == "spec_machine": car_list.append( SpecMachine(row[1], row[3], float(row[5]), row[6]) ) except ValueError: continue return car_list