|
|
"""Решение задачи про классы и наследование"""
|
|
|
|
|
|
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
|