{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0aeaec09",
   "metadata": {},
   "source": [
    "# Задания про классы и наследование #"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a98c34eb",
   "metadata": {},
   "source": [
    "Как правило задачи про классы носят не вычислительный характер. Обычно нужно написать классы, которые отвечают определенным интерфейсам. Насколько удобны эти интерфейсы и как сильно связаны классы между собой, определит легкость их использования в будущих программах.\n",
    "\n",
    "Предположим есть данные о разных автомобилях и спецтехнике. Данные представлены в виде таблицы с характеристиками. Обратите внимание на то, что некоторые колонки присущи только легковым автомобилям, например, кол-во пассажирских мест. В свою очередь только у грузовых автомобилей есть длина, ширина и высота кузова.\n",
    "\n",
    "| Тип (`car_type`) | Марка (`brand`) | Кол-во пассажирских мест (`passenger_seats_count`) | Фото (`photo_file_name`) | Кузов ДxШxВ, м (`body_whl`) | Грузоподъемность,Тонн (`carrying`) |     Дополнительно (`extra`)     |\n",
    "|:----------------:|:---------------:|:--------------------------------------------------:|:------------------------:|:---------------------------:|:----------------------------------:|:-------------------------------:|\n",
    "|        car       |  Nissan xTtrail |                          4                         |          f1.jpeg         |              -              |                 2.5                |                -                |\n",
    "|       truck      |       Man       |                          -                         |          f2.jpeg         |           8x3x2.5           |                 20                 |                -                |\n",
    "|        car       |     Mazda 6     |                          4                         |          f3.jpeg         |              -              |                 2.5                |                -                |\n",
    "|   spec_machine   |     Hitachi     |                          -                         |          f4.jpeg         |              -              |                 1.2                | Легкая техника для уборки снега |\n",
    "\n",
    "Вам необходимо создать свою иерархию классов для данных, которые описаны в таблице.\n",
    "\n",
    " - `CarBase`\n",
    " - `Car(CarBase)`\n",
    " - `Truck(CarBase)`\n",
    " - `SpecMachine(CarBase)`\n",
    "\n",
    "У любого объекта есть обязательный атрибут `car_type`. Он означает тип объекта и может принимать одно из значений: `car`, `truck`, `spec_machine`.\n",
    "\n",
    "Также у любого объекта из иерархии есть фото в виде имени файла — обязательный атрибут `photo_file_name`.\n",
    "\n",
    "В базовом классе нужно реализовать метод `get_photo_file_ext` для получения расширения файла (\".png\", \".jpeg\" и т.д.) с фото. Расширение файла можно получить при помощи `os.path.splitext`.\n",
    "\n",
    "Для грузового автомобиля необходимо разделить характеристики кузова на отдельные составляющие `body_length`, `body_width`, `body_height`. Разделитель — латинская буква `x`. Характеристики кузова могут быть заданы в виде пустой строки, в таком случае все составляющие равны `0`. Обратите внимание на то, что характеристики кузова должны быть вещественными числами.\n",
    "\n",
    "Также для класса грузового автомобиля необходимо реализовать метод `get_body_volume`, возвращающий объем кузова в метрах кубических.\n",
    "\n",
    "Все обязательные атрибуты для объектов `Car`, `Truck` и `SpecMachine` перечислены в таблице ниже, где `1` - означает, что атрибут обязателен для объекта, `0` - атрибут должен отсутствовать.\n",
    "\n",
    "| -                       | Car | Truck | SpecMachine |\n",
    "|-------------------------|:---:|:-----:|:-----------:|\n",
    "| `car_type`              |  1  |   1   |      1      |\n",
    "| `photo_file_name`       |  1  |   1   |      1      |\n",
    "| `brand`                 |  1  |   1   |      1      |\n",
    "| `carrying`              |  1  |   1   |      1      |\n",
    "| `passenger_seats_count` |  1  |   0   |      0      |\n",
    "| `body_width`            |  0  |   1   |      0      |\n",
    "| `body_height`           |  0  |   1   |      0      |\n",
    "| `body_length`           |  0  |   1   |      0      |\n",
    "| `extra`                 |  0  |   0   |      1      |\n",
    "\n",
    "Далее необходимо реализовать функцию, на вход которой подается имя файла в формате **csv**. Файл содержит данные аналогичны строкам из таблицы. Вам необходимо прочитать этот файл построчно при помощи модуля стандартной библиотеки **csv**. Затем проанализировать строки и создать список нужных объектов с автомобилями и специальной техникой. Функция должна возвращать список объектов.\n",
    "\n",
    "Не важно как вы назовете свои классы, главное чтобы их атрибуты имели имена:\n",
    "\n",
    "```python\n",
    "car_type\n",
    "brand\n",
    "passenger_seats_count\n",
    "photo_file_name\n",
    "body_width\n",
    "body_height\n",
    "body_length\n",
    "carrying\n",
    "extra\n",
    "```\n",
    "\n",
    "И методы:\n",
    "\n",
    "`get_photo_file_ext` и `get_body_volume`\n",
    "\n",
    "У каждого объекта из иерархии должен быть свой набор атрибутов и методов. У класса легковой автомобиль не должно быть метода `get_body_volume` в отличие от класса грузового автомобиля.\n",
    "\n",
    "Функция, которая парсит строки входного массива, должна называться `get_car_list`. Для проверки работы своей реализации функции `get_car_list` и всех созданных классов вам необходимо использовать следующий csv-файл: `cars.csv`.\n",
    "\n",
    "Первая строка в исходном файле — это заголовок **csv**, который содержит имена колонок. Нужно пропустить первую строку из исходного файла. Обратите внимание на то, что исходный файл с данными содержит некорректные строки, которые нужно пропустить. Если возникают исключения в процессе создания объектов из строк **csv**-файла, то требуется их корректно обработать стандартным способом. Проверьте работу вашего кода с входным файлом.\n",
    "\n",
    "Пример чтения **csv** файла:\n",
    "\n",
    "```python\n",
    "import csv\n",
    "\n",
    "with open(csv_filename) as csv_fd:\n",
    "    reader = csv.reader(csv_fd, delimiter=';')\n",
    "    next(reader)  # пропускаем заголовок\n",
    "    for row in reader:\n",
    "        print(row)\n",
    "```\n",
    "\n",
    "Также обратите внимание, что все значения в **csv** файле при чтении будут python-строками. Нужно преобразовать строку в `int` для `passenger_seats_count`, во `float` для carrying, а также во `float` для `body_width` `body_height`, `body_length`.\n",
    "\n",
    "Также ваша программа должна быть готова к тому, что в некоторых строках данные могут быть заполнены некорректно. Например, число колонок меньше . В таком случае нужно проигнорировать подобные строки и не создавать объекты. Строки с пустым значением для `body_whl` игнорироваться не должны. Вы можете использовать механизм исключений для обработки ошибок.\n",
    "\n",
    "Ниже приведен пример с заготовкой кода для выполнения задания.\n",
    "\n",
    "```python\n",
    "class CarBase:\n",
    "    def __init__(self, brand, photo_file_name, carrying):\n",
    "        pass\n",
    "\n",
    "\n",
    "class Car(CarBase):\n",
    "    def __init__(self, brand, photo_file_name, carrying, passenger_seats_count):\n",
    "        pass\n",
    "\n",
    "\n",
    "class Truck(CarBase):\n",
    "    def __init__(self, brand, photo_file_name, carrying, body_whl):\n",
    "        pass\n",
    "\n",
    "\n",
    "class SpecMachine(CarBase):\n",
    "    def __init__(self, brand, photo_file_name, carrying, extra):\n",
    "        pass\n",
    "\n",
    "\n",
    "def get_car_list(csv_filename):\n",
    "    car_list = []\n",
    "    return car_list\n",
    "```\n",
    "\n",
    "Вам необходимо расширить функционал исходных классов, дополнить методы нужным кодом и реализовать функцию `get_car_list`.\n",
    "\n",
    "Успехов!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
