**Задание на автомат**
***
**Python (Kivy/KivyMD)**
***
**main2.py**
***
```
from kivy.app import App
from kivymd.app import MDApp # Импорт главного окна приложения
from kivy.uix.boxlayout import BoxLayout # Импорт бокслояута для добавления в него виджетов
from kivy.uix.gridlayout import GridLayout # Импорт гридлояута для добавления элементов в виде сетки
from kivy.uix.spinner import Spinner # Импорт для выпадающего списка
from kivymd.uix.textfield import MDTextField # Импорт для таблицы
from kivymd.uix.button import MDIconButton # Импорт для иконок кнопок
from kivy.uix.image import Image # Импорт для изменения размера
from kivy.uix.label import Label # Импорт Label для отображения текста
from kivy.uix.scrollview import ScrollView # Импорт для прокрутки таблицы
from kivy.metrics import dp # Импорт для изменения размера
from kivy.utils import get_color_from_hex # Импорт для использования шестнадцатеричных цветовых кодов

import json

class CarItem(BoxLayout):
    def __init__(self, car_data, **kwargs):
        super().__init__(**kwargs)
        self.orientation = 'horizontal'
        self.size_hint_y = None
        self.height = dp(100)
        self.padding = [10, 10, 10, 10]

        self.image = Image(
            source=car_data.get('image'),
            size_hint_x=0.3,
            allow_stretch=True
        )
        self.add_widget(self.image)

        info_layout = BoxLayout(orientation='vertical')
        self.add_widget(info_layout)

        self.name_label = Label(text=car_data['Название'], font_size=18, color=get_color_from_hex('#000000'))
        info_layout.add_widget(self.name_label)

        self.price_label = Label(text=f"{car_data['Цена']} руб.", font_size=16, color=get_color_from_hex('#000000'))
        info_layout.add_widget(self.price_label)

class SearchBoxLayout(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation = 'vertical'
        self.padding = [50, 0, 50, 50]

        # Импорт фотографии
        self.image = Image(
            source='net.jpg',
            size_hint_y=0.3
        )
        self.add_widget(self.image)

        # Панель поиска и фильтрации
        search_filter_bar = BoxLayout(size_hint_y=None, height=dp(40), spacing=10)
        self.add_widget(search_filter_bar)

        # Строка поиска
        self.search_field = MDTextField(
            hint_text="Search...",
            size_hint_x=0.5
        )
        self.search_field.bind(text=self.filter_items)
        search_filter_bar.add_widget(self.search_field)

        # Кнопки фильтрации
        self.asc_button = MDIconButton(icon="arrow-up-drop-circle")
        self.asc_button.bind(on_release=self.sort_ascending)
        search_filter_bar.add_widget(self.asc_button)

        self.desc_button = MDIconButton(icon="arrow-down-drop-circle")
        self.desc_button.bind(on_release=self.sort_descending)
        search_filter_bar.add_widget(self.desc_button)

        # Выпадающий список для выбора машины
        self.spinner_car = Spinner(
            text='Выберите машину',
            values=[],
            size_hint=(None, None),
            size=(dp(200), dp(44))
        )
        self.spinner_car.bind(text=self.filter_items)
        search_filter_bar.add_widget(self.spinner_car)
        # Выпадающий список для выбора ценового диапазона
        self.spinner_price = Spinner(
            text='Выберите цену',
            values=('10000 - 20000', '21000 - 30000', '31000 - 70000'),
            size_hint=(None, None),
            size=(dp(200), dp(44))
        )
        self.spinner_price.bind(text=self.filter_items)
        search_filter_bar.add_widget(self.spinner_price)

        # Прокрутка для таблицы
        self.scrollview = ScrollView()
        self.add_widget(self.scrollview)

        # Сетчатая разметка для хранения элементов автомобиля
        self.car_grid = GridLayout(cols=1, spacing=10, size_hint_y=None)
        self.car_grid.bind(minimum_height=self.car_grid.setter('height'))
        self.scrollview.add_widget(self.car_grid)

        # Загрузка данных из JSON
        self.car_data = self.load_data_from_json('package.json')
        self.original_car_data = self.car_data.copy()
        self.populate_car_grid()

        self.spinner_car.values = list({car['Название'] for car in self.car_data})

    def load_data_from_json(self, filename):
        with open(filename, 'r', encoding='utf-8') as f:
            data = json.load(f)
        return data

    def populate_car_grid(self):
        # Заполнение сетки виджетов
        self.car_grid.clear_widgets()
        for car in self.car_data:
            car_item = CarItem(car)
            self.car_grid.add_widget(car_item)

    def filter_items(self, instance, *args):
        # Сортировка по названию и цене
        filtered_data = self.original_car_data.copy()

        search_text = self.search_field.text.lower()
        filtered_data = [car for car in filtered_data if search_text in car['Название'].lower()]

        selected_car = self.spinner_car.text
        if selected_car != 'Выберите машину':
            filtered_data = [car for car in filtered_data if car['Название'] == selected_car]

        price_range = self.spinner_price.text
        if price_range != 'Выберите цену':
            min_price, max_price = map(int, price_range.split(' - '))
            filtered_data = [car for car in filtered_data if min_price <= int(car['Цена']) <= max_price]

        self.car_data = filtered_data
        self.populate_car_grid()

    def sort_ascending(self, instance):
        # Сортировка таблицы по цене в порядке возрастания
        self.car_data = sorted(self.car_data, key=lambda x: int(x['Цена']))
        self.populate_car_grid()

    def sort_descending(self, instance):
        # Сортировка таблицы по цене в порядке убывания
        self.car_data = sorted(self.car_data, key=lambda x: int(x['Цена']), reverse=True)
        self.populate_car_grid()

class MyApp(MDApp):
    def build(self):
        return SearchBoxLayout()

if __name__ == '__main__':
    MyApp().run()
```
***
**json**
***
```
[
    {
        "Название": "Toyota Trueno AE86",
        "Год": 1995,
        "Цена": 15000,
        "Цвет": "white",
        "Повреждения": "True",
        "Дата СТО": "19/04/2024",
        "image": "tru.jpg"
    },
    {
        "Название": "Toyota Supra A80",
        "Год": 1996,
        "Цена": 30000,
        "Цвет": "black",
        "Повреждения": "False",
        "Дата СТО": "09/02/2024",
        "image": "su.jpg"
    },
    {
        "Название": "Nissan Skyline R34",
        "Год": 1996,
        "Цена": 25000,
        "Цвет": "orange",
        "Повреждения": "False",
        "Дата СТО": "10/07/2024",
        "image": "sk.jpg"
    },
    {
        "Название": "Nissan Silvia S15Nissan Silvia S15",
        "Год": 1999,
        "Цена": 20000,
        "Цвет": "gray",
        "Повреждения": "False",
        "Дата СТО": "20/03/20244",
        "image": "sil.jpg"
    },
    {
        "Название": "Toyota Camry 3.5",
        "Год": 2020,
        "Цена": 20000,
        "Цвет": "blue",
        "Повреждения": "False",
        "Дата СТО": "19/04/2024",
        "image": "ca.jpg"
    },
    {
        "Название": "Audi RS 6",
        "Год": 2016,
        "Цена": 30000,
        "Цвет": "lightblue",
        "Повреждения": "True",
        "Дата СТО": "10/07/2024",
        "image": "au.jpg"
    },
    {
        "Название": "Трактор LOVOL TE354 HT",
        "Год": 2024,
        "Цена": 66666,
        "Цвет": "brown",
        "Повреждения": "False",
        "Дата СТО": "19/04/2024",
        "image": "tr.jpg"
    },
    {
        "Название": "BMW M5 F90",
        "Год": 2019,
        "Цена": 30000,
        "Цвет": "black",
        "Повреждения": "True",
        "Дата СТО": "20/03/20244",
        "image": "b.jpg"
    },
    {
        "Название": "BMW E36",
        "Год": 2006,
        "Цена": 35000,
        "Цвет": "red",
        "Повреждения": "False",
        "Дата СТО": "19/04/2024",
        "image": "bm.jpg"
    },
    {
        "Название": "Daewoo Matiz",
        "Год": 2010,
        "Цена": 20000,
        "Цвет": "pink",
        "Повреждения": "True",
        "Дата СТО": "10/07/2024",
        "image": "ma.jpg"
    }
]
```
![](./img/7.png)