You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.2 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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