Влияние языковых моделей на разработку приложений на примере создания «Smart Notes»

XXI Международный конкурс научно-исследовательских и творческих работ учащихся
Старт в науке

Влияние языковых моделей на разработку приложений на примере создания «Smart Notes»

Кадушкин О.В. 1
1МБОУ ГМ СОШ
Каменева Т.В. 1
1МБОУ ГМ СОШ
Автор работы награжден дипломом победителя II степени
Текст работы размещён без изображений и формул.
Полная версия работы доступна во вкладке "Файлы работы" в формате PDF

Введение

«Искусственный интеллект» — словосочетание, которое мы слышим всё чаще в нашей жизни. Для большинства это просто повод для дискуссии, для кого-то – интересный эксперимент, а для кого-то – основной источник дохода. Но многие до сих пор не понимают, что это такое, в чём суть ИИ и какая его цель.

ИИ (нейросеть) – это математическая модель (граф), где каждый сегмент (активация) наделён своим числом, а рёбра этого графа своим весом (который также является числом). Весь этот граф является большой функцией, которая на входе принимает определённые данные (будь то яркость пикселей на фото или числовые характеристики частной собственности) и выдаёт наиболее вероятный ответ из всех возможных.

Суть ИИ в том, что он может находить закономерности. Так же как мы – люди. Однако современная наука в области ИИ ещё не может воссоздать все возможности нашего мозга в цифровом виде. Поэтому мы имеем дело не с одним ИИ, а с множеством специализированных моделей, которые имитируют отдельные функции мозга. Например, есть модели, нацеленные на распознавание объектов, звуков, эмоций и других характеристик. Такие модели могут симулировать работу наших органов чувств. Но это не значит, что мы можем просто соединить их в одну систему и получить ИИ, похожий на человека. Для этого нужно больше, чем просто сумма частей. Однако есть модели, которые пытаются приблизиться к этой цели. Одна из них – GPT (в частности GPT-41), которая создаёт тексты на основе введённых данных. Эта модель способна решать разные задачи, в некоторых из которых даже превосходит человека.

Цель ИИ – это оптимизация. Многие думают, что цель состоит в том, чтобы сделать ИИ похожим на человека, но это лишь средство для достижения оптимизации. Если человечество сможет создать такой ИИ, который сможет заменить человека во всём, то тогда человек сможет избавиться от своих проблем и переложить их на ИИ. Но вряд ли ИИ будет счастлив от такого расклада. Сейчас же мы только начинаем пользоваться преимуществами оптимизации ИИ: Amazon почти полностью автоматизировал свои склады, в Германии появились магазины без кассиров, в Японии рестораны с роботами-официантами, а в Китае внедрили систему видеонаблюдения с ИИ. Художники, сценаристы, журналисты и другие творческие люди беспокоятся о том, что ИИ заберёт у них работу, ведь он может создавать уникальные произведения искусства. Как видите, история повторяется: как и в век индустриализации, когда машины вытесняли рабочих, сейчас ИИ вытесняет людей, но уже на более сложном уровне – интеллектуальном.

Возникло желание проверить, насколько в наше время ИИ может оптимизировать работу программиста, так как сам являюсь таковым. Для программистов и вправду нынешняя роль ИИ возрастает с каждым днём. Больше не надо искать в закоулках Интернета пласты информации, нанимать сотню работников искать часами решение проблемы – всё это может теперь сделать ИИ. Или нет?

Цель проекта : Выяснить положительные и отрицательные стороны разработки ПО с помощью ИИ на примере создания приложения «Smart Notes».

Задачи:

  1. Подобрать модель ИИ

  2. Осуществить подготовку для создания ПО с помощью ИИ

  3. Выяснить, может ли ИИ создать идею приложения

  4. Выяснить, может ли ИИ создать план по созданию приложения

  5. Выяснить, может ли ИИ создать приложение по плану

  6. Разработать приложение с помощью ИИ

  7. Определить влияние ИИ на разработку ПО

Гипотеза: ИИ ускоряет работу и предоставляет делегирование части работы на выбранную нами модель ИИ

Объект исследования: Процесс создания программы с помощью ИИ

Предмет исследования: Возможности чат-бота, основанного на ИИ

Проблема: долгий и затратный процесс создания приложений

Глава 1

1.1 Языковые модели: структура

Прежде чем перейти к использованию не только нейросетей, но и всего в целом, рекомендуется понять, как это благо устроено, чтобы понимать уже в свою очередь, чего от этого ждать и чего требовать. Понимание не только инструкции к применению, но и устройства позволяет не вводить себя в заблуждение и, в случае возникновения проблем, своевременно их решать на месте, а не с помощью пособий и интернета.

Возьмёмзапримертакуюнейросеть, как GPT (Generative Pre-training Transformer).

Вся их суть в том, что на входе такие модели принимают по большинству текст или речь и на выходе либо классифицируют его или пишут уже свой. Самый простой пример таких моделей – это классификатор почтовых сообщений SPAM OR HAM. Такой классификатор определяет, является ли сообщение спамом или же нет. На вход он получает текст почтового сообщения, а на выходе возвращает 0 (если это не спам) или 1 (если спам). Перед процессом предсказывания может использоваться другая нейросеть, которая убирает всё лишнее из текста, чтобы предоставить всю суть уже основной нейросети, которая преобразует слова в токены1 (числа), с которыми уже в дальнейшем и работает.

Языковые модели типа GPT отличаются от вышеприведённого примера тем, то классифицируют не весь текст, а слово, которое наиболее вероятно пойдёт следующим за всем текстом. Вот как выглядит основной алгоритм языковых моделей типа GPT (упрощённый):

  • Пользователь отправляет текст языковой модели.Затем модель разбивает текст на токены.

  • Затем эти токены отправляются через всю модель с её весами и активациями, которые по итогу выдают вероятность того или иного следующего слова.

  • Далее модель выбирает наиболее вероятный токен (слово) и связывает его со всем остальным текстом.

  • Итоговый результат (изначальное сообщение + угаданное слово) отправляется по новой через всю модель. Так языковая модель, умея предсказывать следующее слово, может создавать целые предложения

GPT же является более комплексной языковой моделью, которая способна создавать целые страницы текста. Чтобы достичь такого результата, создателям GPT пришлось внести некоторые изменения в вышеприведённый алгоритм:

  1. Чтобы не замедлять процесс обучения модели, пришлось изменить процесс токенизации слов. В силу того, что слов миллионы и миллионы, а база данных такого размера не удобна, теперь токенизируются не сами слова, а их морфемы (суффиксы, окончания, корни и т.д.). Так, создателям GPT удалось сжать базу данных токенов GPT примерно до 50000! На удивление с таким небольшим набором токенов GPT способна анализировать и создавать текст на любые темы, почти на любом языке.

  2. Чтобы ответы языковой модели не повторялись, GPT выбирает несколько самых вероятных ответов на запросы, а потом всоответствии функции распределения Больцмана2 выбирает наиболее контекстный вариант из наиболее вероятных. Так GPT ведёт себя естественнее:

  3. Чтобы предотвратить выбор совсем не подходящих ответов, GPT отбрасывает самые маловероятные варианты перед использовании функции Больцмана, чтобы ответ был «случайным» среди наиболее вероятных ответов

Обобщая, GPT отличается от обычных языковых моделей только тремя вышеперечисленными фактами (притом данные аспекты применяются во всех современных языковых моделей и это не является особенностью GPT) и количеством параметров. Чем больше параметров у модели, тем лучше она может определять малейшие закономерности в данных, на которых её обучают. Такие модели, как GPT, у которых более 150 миллиардов параметров, могут улавливать закономерности куда лучше, чем люди.

1.2 Какая языковая модель лучше?

Начиная работать с языковыми моделями, стоит выбрать, какая из их всех множеств подойдёт именно вам. Одни созданы для написания статей, вторые для разработки дизайна сайтов и приложений, третьи – консультации. Для программирования есть тоже свои варианты, причём немалые. Каждая модель в чём-то лучше, чем другие. Однако большинство использует именно GPT, а не специализированные нейросети. Причём GPT будет проигрывать по результатам запросов, связанных с созданием кода. Почему? Всё дело в том, что GPT обучена по сути на всём интернете до 2021 года, в то время как языковые модели, направленные на помощь с разработкой, обучены в большинстве на примерах кода программ, нежели на всём интернете. Так что GPT-3 будет проигрывать в некоторых аспектах такой языковой модели, как, например, Copilot от GitHub. Так что, если рассматривать частный случай с программированием, конечно стоит выбирать языковые модели, созданные именно для программирования

Из-за данной причины многие не могут воспользоваться такими языковыми моделями. Однако вскоре вследствие высокого спроса в РФ начали появляться платформы, предоставляющие доступ к GPT. Одной из таких стала BaiChat, являющееся сайтом китайских разработчиков, которые предоставляют возможность пользования разными языковыми моделями через удобный интерфейс (сайт). Сайт является посредником: через сайт пользователь выбирает языковую модель, а сайт в свою очередь после начала сеанса пользователя с моделью переадресовывает запросы пользователя на сервера платформ, предоставляющие доступ к языковым моделям. Одно удивляет: у BaiChat есть бесплатный доступ к GPT с небольшими нюансами: память GPT ограничена парой сообщений, а максимальное количество токенов – 4096.

Однако это не единственный способ получить бесплатный доступ к моделям наподобие GPT. Одновременно с сайтами, предоставляющими такую возможность, появлялись (причём в ещё больших количествах) телеграмм-боты, которые выполняли такую же функцию, как BaiChat, только без специализированного интерфейса. В данном случае предложений таких чат-ботов куда больше, чем сайтов. С одной стороны, это позволяет благодаря конкуренции создавать более качественный сервис, а с другой, когда нет никаких стандартов и ниша ещё никем не заполнена – введение в заблуждение и отсутствие гарантий. Так, большинство чат-ботов дезинформируют своих пользователях о версии модели GPT. Особенно это выявляется при заявлении о том, что данный чат бот основан на самой новой версии GPT.

К сожалению, создатели данных чат-ботов не занимаются благотворительностью, и, чтобы получить доступ, нужно подписаться на определённые телеграмм-каналы. Да, придётся немного засорить подписки, но это небольшая жертва по сравнению с платной подпиской. Есть и другие чат-боты в других мессенджерах, однако наиболее распространены данные в телеграмме. Да и проблемы всё те же.

Итак, если необходимо выбрать лучшую языковую модель, нужно определится с некоторыми фактами:

  1. Ценовой вопрос

  2. Доступность в вашем регионе

Если первое условие удовлетворено, однако второе не достижимо, то либо придётся использовать ВПН с картой оплаты не нашей страны, либо оплачивать платные сервисы, предоставляющие возможность, однако не гарантию. В таком случае лучшей языковой моделью будет GPT-4 или более новой версии, так как языковые модели GPT самые распространённые: найти сервисы, предлагающие GPT за деньги, не составит труда.

Если выполнено второе условие, но не первое, то советую либо подкопить денег на гарантированный продукт, либо найти бесплатные аналоги. В таком случае лучшей языковой моделью будет (в моём частном случае) Copilot от GitHub в связи с вышеуказанными причинами

Если выполнены все два условия, то, конечно, стоит выбирать Copilot от GitHub. В моём же случае, когда ни одно из условий не выполнено, лучшим вариантом будет GPT, так как найти её бесплатные аналоги проще всего из-за её популярности.

1.3 Использование языковых моделей

Уже только после того, как осознав инструмент, его структуру, выбрав какой является лучшим, стоит приступать за изучение его инструкции. В случае же языковых моделей нет как таковых инструкций: пользователь волен писать что-угодно. Однако уже создатели ставят специальные ограничения, чтобы не брать на себя ответственность за результаты модели. Так, GPT не будет с вами разговаривать по поводу аморальных тем. То есть, инструкций нет у пользователя, но есть у самой модели, которым она, казалось бы, должна следовать беспрекословно. Но есть способы запутать языковые модели, чтобы снять все ограничения.

Пока что есть только советы, как получить максимальную выгоду с результатов языковой модели. Все они построены на устройстве самих нейросетей, однако, чтобы полностью понять почему GPT выдаёт нелогичный или логичный ответ бывает тяжело, так как языковые модели выстраивают свои закономерности, которые могут не совпадать с нашими, а узнать, что за закономерности также тяжело, как и в нашем мозге. Вот некоторые из советов, которые я вывел на практике:

  1. Конкретизация. Чем лучше вы конкретизируете свой запрос, тем лучше его поймёт модель. Как инженер не поймёт расплывчатого ТЗ, так и GPT или другая языковая модель не поймёт, чего вы хотите от неё без чёткого ТЗ. Пишите, чего именно вы хотите, в каком виде вы этого хотите и в каком размере.

  2. Пояснение. Обязательно, если есть возможность, приводите примеры того, чего вы ожидаете от бота. Также как с человеком: архитектору легче понять заказчика, если у него есть эскиз желаемого.

  3. Выделение. Как ни странно, но GPT обращает внимание на слова, выделенные тем или иным образом. Так что, если хотите обратить акцент на важный параметр или факт, выделите его заглавными буквами:

  4. Роли. Чтобы снять ограничения языковых моделей, применяют роли: пользователь внушает нейросети, что она является кем-то и используют это в своих целях. Так, можно написать боту, что он является профессиональным сценаристом, чтобы улучшить качество текста

Также стоит отметить, что не надейтесь полностью на языковые модели: как бы это бы не звучало заманчиво, но основная работа всё же на пользователе.

Глава 2

2.1 Создание проекта с GPT: создание идеи

Для объективной оценки способностей GPT нужно выбрать такую сферу, в которой можно использовать GPT постоянно и сравнивать результаты GPT с верными. Для этой цели отлично подходит создание мобильного приложения. Из-за большого объёма работы, ситуативных задач и проблем, понимания всей картины можно будет увидеть, как себя поведёт GPT во множестве вариативных случаях. В конце исследования нужно будет провести выводы по собранным данным и вывести вердикт: приносит ли больше пользы или вреда использование языковых моделей.

Для формулирования идеи проекта нужно сначала найти проблему: я решил рассмотреть проблему забывания человеком информации из-за отсутствия закрепления оной в долговременной памяти. Далее я буду сравнивать моё решение и решение, которое предоставил GPT. Решение от GPT я буду выделять курсивным почерком. В конце сравнения я буду выбирать лучший вариант из двух.

Запрос: Напиши идею проекта, который будет решать проблему забывания человеком информации из-за отсутствия закрепления оной в долговременной памяти

Моё решение:

Создание мобильного приложения «Smart Notes» с удобным интерфейсом, являющиеся конспектом, поддерживающим фото, текст, видео и аудио информацию, который будет напоминать о времени повторений конспектов для закрепления информации в долговременной памяти.

Функции приложения:

  1. Создание конспектов. Пользователь может создать «блок», являющееся конспектом, содержащим фото и текст.

  2. Напоминание об повторении. Через определённые промежутки (интервалы) в соответствии кривой забывания Эбингауза приложение будет выводить пользователю блоки, которые нужно повторить

  3. Удаление, изменение конспектов. Пользователь может удалять и изменять каждый конспект по собственному желанию.

Однако не смотря на сходства, GPT ввёл несколько нововведений, которые у меня отсутствуют: Визуализация, Прогресс и статистика, а также Социальные функции. Однако точно сказать, как именно реализовать визуализацию ответа GPT невозможно из-за недостаточной конкретики. Тоже самое касается про персонализацию повторений.

GPT хочет реализовать функцию прикрепления фото к тексту для визуального запоминания. Тогда это уже похоже на функцию моего проекта, который предоставляет возможность хранение в одном конспекте (блоке) множество форматов информации, один из которых – фото.

Как и с визуализацией, после уточнения GPT выдал конкретное решение. В данном случае его решение сходно с моим лишь одним аспектом: в моём проекте также персонализация выражается в возможности записи любой информации. В остальных случаях GPT выдвинул идеи, отсутствующие в моём проекте.

2.2 Создание проекта с GPT: создание плана

Чтобы начать создавать проект «Smart Notes» после придумывания идеи, нужен план. Вот и новая проблема. Теперь я сравню своё решение данной проблемы и решение GPT, как в прошлой главе. Добавятся некоторые ограничения: в силу того, что я знаю только python и только библиотеку KivyMD для создания мобильных приложений, GPT должен будет учесть данные условия.

Запрос: Напиши план реализации к проекту «Smart Notes» с помощью KivyMD на Python

Моё решение:

План реализации «Smart Notes»

  1. Определиться со стилем приложения. Я выбрал минималистичный дизайн для избегания излишней загруженности интерфейса, а также чтобы он был удобный

  2. Изучить кривую Эббингауза3, KivyMD и Python до такого уровня, чтобы реализовать план

  3. Придумать алгоритм приложения. Всё приложение будет состоять из экранов, в каждом из которых будет своя информация (главный экран, экран конспекта и т.д.). Всего будет 5 экранов: Главный экран, экран Фильтров, экран Конспектов и экран Камеры.

  4. Реализовать алгоритм в виде кода. Будет создан материнский класс, от которого будут наследоваться все остальные, представляющие собой все экраны. Каждый имеет свою экосистему.

  5. Протестировать приложение на наличие ошибок. Без этого пункта нет гарантий, что приложение будет рабочим

  6. Конвертировать код в APK-файл. Сделать это поможет buildozer4

  7. Создать инструкцию к использованию приложения

  8. Скачать приложение

Теперь можно заметить наглядную закономерность в разнице между моими ответами и ответами GPT: ответы GPT больше по объёму, а также предлагают больше идей или функций. Этот ответ даже лучше, чем предыдущий: не считая части реализации приложения в магазины приложений, что не входит в мой проект, остальное всё отлично. Конечно, мой вариант немного подробнее, однако, если попросить подробней рассказать GPT о том или ином аспекте, как уже наблюдалось ранее, он без проблем объяснит. Скорее всего, если бы я продолжительное время думал над планом, то результаты GPT и мои сравнялись, или я бы даже обошёл его решение. Но решение от GPT занимает пару минут, моё же может длится днями. Так что в данном случае решение от GPT лучше, чем моё собственное. Далее я буду использовать план от GPT с небольшими изменениями: часть с распространением проекта и изучением технологий я вычеркну, остальное же будет таковым.

2.3 Создание проекта с GPT: реализация плана

После выбора плана следует его реализация: далее я покажу самые наглядные случаи в разработке приложения с использованием GPT.

Запрос:

Реализуй данную часть плана проекта «Smart Notes»:
1. Разработка интерфейса:

- Создание простого и удобного интерфейса с использованием KivyMD.

- Включение возможности добавления фото, текста, видео и аудио в конспекты.

GPT не предоставил код реализации пункта проекта, а порекомендовал использовать KivyMD, что было в самом запросе.

В данном случае интерфейс я разрабатывал не один, а совместно с GPT. Из-за некомпетентности GPT, а точнее его решения, я принял решение использовать GPT как консультанта, помогающего в разработке. Если у меня возникали проблемы с тем или иным фактом во время реализации данного пункта плана проекта, я обращался к GPT.

В ходе реализации удобного интерфейса у меня была идея, но не было достаточных знаний. GPT же не может совместить все свои знания в единое. Используя GPT, я одновременно устраняю недостатки GPT, а он, уже в свою очередь, устраняет мои. Таким образом, работая вместе, я смог достичь наилучшего результата.

Однако в некоторых моментах GPT не мог мне предоставить информацию из-за слишком узкой специализации проблемы: например, когда мне нужно было убрать тени с кнопок, GPT выдавал код, который не выполнял оного. Даже после уточнения он не выполнял мои требования, скорее всего, GPT знал только про один метод, который не работал в моём случае, поэтому предложить больше ничего не смог. Из-за этого мне самому приходилось находить решение проблем. Самая главное – приходилось решать проблемы именно самые сложные, ибо самые узкоспециализированные. Если GPT не знает решение, то и большинство всего интернета, ибо GPT обучен на нём.

2.4 Создание проекта с GPT: итоги

На протяжении полгода я анализировал использование GPT в создании проекта «Smart Notes». Чтобы сравнить создание проекта с использованием GPT, нужен опыт создание другого проекта, который у меня имеется. Сравнение будет между процессом создания «Умного конспекта» и «Smart Notes» с использованием GPT по следующим аспектам:

  1. Продолжительность работы.

  2. Комплексность работы

  3. Объём работы.

  4. Соотношение времени программирование/поиск информации

  5. Денежный объём работы

Оба проекта реализуют решение одной и той же проблемы: отсутствие закрепления информации в долговременной памяти. В «Умном конспекте» реализация в виде ПО для ПК, написанным на Tkinter Python с простым интерфейсом. Для конспектов доступен только текст.

В Smart Notes же реализация в виде мобильного приложения на KivyMD Python с удобным, минималистичным интерфейсом. Для конспектов доступен как текст, так и фото.

По итогам сравнения я вынесу вердикт: стоит ли использовать языковые модели в работе как помощников или это бесполезная трата времени.

  1. Продолжительность работы.

В случае с «Умным конспектом» весь процесс разработки приложения занял год.

Разработка «Smart Notes» заняла пол года

  1. Комплексность работы

«Умный конспект» из-за своей простоты интерфейса, синтаксиса кода и ограниченности функционала является элементарной программой

«Smart Notes» состоит из множества дочерних классов, каждый из которых отвечает за свой функционал. Совокупность данного, а также сложного интерфейса делает «Smart Notes» более комплексной, чем «Умный конспект»

  1. Объём работы.

Количество строк кода приложения «Умный конспект» - 464

Количество строк кода приложения «Smart Notes» - 1245

  1. Соотношение времени программирование/поиск информации

Из-за того, что во время разработки «Умного конспекта» мне приходилось самому находить информацию, соотношение программирование/поиск информации составляло 1 к 3 (например, за 2 часа программирования 40 минут составляло само программирование, а оставшиеся 80 – поиск информации)

Из-за того, что во время разработки «Smart Notes» GPT искал большинство информации и помогал в случае проблем, соотношение программирование/поиск информации составляло 3 к 4 (например, за 2 часа программирования 90 минут составляло программирование, а оставшиеся 30 – поиск информации

  1. Денежный объём работы

Разработка «Умного конспекта» обошлась без денежных затрат. Однако, для разработки требуется ПК.

Разработка «Smart Notes» обошлась без денежных затрат. Однако, для разработки требуется ПК и смартфон. Также, если не учитывать бесплатные аналоги GPT, требуется денежные средства для работы с языковыми моделями (если рассматривать большие проекты, в которых будут работать множество сотрудников, придётся пользоваться оригинальными языковыми моделями)

 

Заключение

По итогу можно сказать, что использование языковых моделей принесло свои плоды:

  1. Скорость работы увеличилась на 100%,

  2. Несмотря на увеличенную комплексность работы, скорость работы повысилась

  3. Объём работы увеличен на 300%

  4. Соотношение программирования/поиска информации увеличено на 225%

  5. Денежные затраты увеличены.

Судя по выводам, гипотеза проекта доказана. Разработка с языковыми моделями выигрывает разработку без оных во всех аспектах, кроме денежных затрат. Однако можно обойтись и без денежных затрат, если знать, где искать. Но это не является решением для компаний и небольших групп разработчиков: чтобы максимально увеличить эффективность работы, необходимо будет вкладывать денежные средства в платные языковые модели, так как они, в отличие от бесплатных, работают в разы быстрее, а все мы знаем, что время – деньги. Вопрос: стоит ли вкладывать денежные средства для увеличения скорости разработки, чтобы в дальнейшем заработать больше денег, нивелируется тем, что в той же GPT нужно всего лишь 0.09 доллара за 1000 слов.

Проблема различности примеров, на которых проводилось сравнение, а также разница во времени между ними (за данное время я мог, допустим, стать лучше в программировании, а это уже не будет объективным), нивелируется тем, что я разрабатывал «Smart Notes» на совершенно мною неизвестной библиотеке KivyMD, а также тем, что «Smart Notes» куда объёмней и комплексней, чем «Умный конспект» (Если было бы наоборот, то можно было бы выдвинуть ложные умозаключения о том, что разработка «Smart Notes» стала быстрее не из-за влияния языковых моделей, а из-за меньшей объёмности).

Несмотря на все вышеперечисленные преимущества использования языковых моделей во время разработки, у данного метода есть существенные минусы:

  1. Несамостоятельность. Когда языковая модель ищет за вас информацию, решает за вас проблемы, вы не сможете без неё, или вам будет очень сложно решить дальнейшие или найти информацию, если вы только начинаете путь разработчика

  2. Непонимание. Рассмотрим на конкретном примере: не зная библиотеку KivyMD, я делегировал всю работу GPT с интерпретацией своей идеи в код с использованием KivyMD. Данное привело к тому, что я не мог толком разобраться как именно работает та или иная часть моего кода, а в дальнейшем мне пришлось уже самому изучать KivyMD, чтобы решить те проблемы, которые не могла решить GPT.

  3. Галлюцинации: когда GPT не знает ответа, она может придумывать несуществующее или неработающее решение

Данные минусы можно устранить, используя GPT только как консультанта в изучении материала, необходимого для разработки. Однако от этого будет страдать скорость работы, так что в данном вопросе нужно будет найти золотую середину между скоростью разработки и пониманием кода.

Суммируя всё вышесказанное: языковые модели являются мощнейшим инструментом, помогающим программистам многократно ускорять процесс разработки, однако не стоит доверять данному инструменту всю работу, ибо языковые модели ещё слишком неразвитые для полноценной разработки с небольшим участием человека, но в то же время уже достаточно самостоятельны для создания частей кода, в которых вам придётся разбираться, если вы слишком предвзято к ним будете относится.

Библиографический список

  1. https://aws.amazon.com/ru/what-is/nlp/

  2. https://huggingface.co/blog/alonsosilva/nexttokenprediction

  3. https://habr.com/ru/articles/599673/

  4. https://beta.theb.ai

  5. https://t.me/NB_GPT4_bot

Приложения

Приложение 1:

#kivymd,plyer
import pickle
import kivy
from kivymd.uix.dialog import MDDialog
from kivy.lang import Builder
from kivymd.app import MDApp
import time
from plyer import audio
from kivy.core.window import Window
from kivymd.uix.filemanager import MDFileManager
from kivymd.uix.button import *
from kivymd.uix.fitimage import FitImage
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.theming import ThemeManager
from kivymd.uix.textfield import MDTextField
from kivymd.uix.menu import MDDropdownMenu
from kivymd.uix.button import MDIconButton
from kivy.uix.slider import Slider
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.animation import Animation
from kivy.uix.textinput import TextInput
from kivymd.uix.scrollview import MDScrollView
from kivy.uix.scrollview import ScrollView
from kivy.uix.modalview import ModalView
from kivymd.uix.relativelayout import MDRelativeLayout
from kivy.uix.relativelayout import RelativeLayout
from kivymd.uix.floatlayout import FloatLayout,MDFloatLayout
from kivy.uix.gridlayout import GridLayout
from kivymd.uix.gridlayout import MDGridLayout
from kivy.uix.image import Image
from kivymd.uix.label.label import MDIcon
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.behaviors import TouchBehavior
import platform
if platform == 'android':
from android.permissions import request_permissions, Permission
request_permissions([Permission.READ_EXTERNAL_STORAGE
, Permission.WRITE_EXTERNAL_STORAGE, Permission.requestLegacyExternalStorage, Permission.RECORD_AUDIO])
from datetime import datetime
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.uix.carousel import Carousel
from kivy.uix.filechooser import FileChooserIconView
from kivy.lang import Builder
from kivy.uix.camera import Camera
from kivy.uix.behaviors import ButtonBehavior
from kivymd.uix.label import MDLabel
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.app import MDApp
from kivymd.uix.list import MDList
from kivymd.uix.list import OneLineAvatarIconListItem
from kivy.uix.scatter import Scatter
from kivymd.uix.behaviors import (
CircularRippleBehavior
,
CommonElevationBehavior,
)
matrix_file =
"DATA5.pickle"
path = "/storage/emulated/0/DCIM/photos"
#path = "C:\\Users\\User\\Pictures"
kok = 0.1
learn_symbol = "@^&#"
s = """"""
KVV = '''
<Content>
orientation: "vertical"
spacing: "6dp"
size_hint_y: None
height: "40dp"
MDSlider:
step:1
max:5
min:1
MDFloatLayout:
MDFlatButton:
text: "ALERT DIALOG"
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.show_confirmation_dialog()
'''

class Content(BoxLayout):
pass
id = 0 # если 0 тоновыйблок
color_dict = {'Red': {'50': 'FFEBEE', '100': 'FFCDD2', '200': 'EF9A9A', '300': 'E57373', '400': 'EF5350', '500': 'F44336', '600': 'E53935', '700': 'D32F2F', '800': 'C62828', '900': 'B71C1C', 'A100': 'FF8A80', 'A200': 'FF5252', 'A400': 'FF1744', 'A700': 'D50000'}, 'Pink': {'50': 'FCE4EC', '100': 'F8BBD0', '200': 'F48FB1', '300': 'F06292', '400': 'EC407A', '500': 'E91E63', '600': 'D81B60', '700': 'C2185B', '800': 'AD1457', '900': '880E4F', 'A100': 'FF80AB', 'A200': 'FF4081', 'A400': 'F50057', 'A700': 'C51162'}, 'Purple': {'50': 'F3E5F5', '100': 'E1BEE7', '200': 'CE93D8', '300': 'BA68C8', '400': 'AB47BC', '500': '9C27B0', '600': '8E24AA', '700': '7B1FA2', '800': '6A1B9A', '900': '4A148C', 'A100': 'EA80FC', 'A200': 'E040FB', 'A400': 'D500F9', 'A700': 'AA00FF'}, 'DeepPurple': {'50': 'EDE7F6', '100': 'D1C4E9', '200': 'B39DDB', '300': '9575CD', '400': '7E57C2', '500': '673AB7', '600': '5E35B1', '700': '512DA8', '800': '4527A0', '900': '311B92', 'A100': 'B388FF', 'A200': '7C4DFF', 'A400': '651FFF', 'A700': '6200EA'}, 'Indigo': {'50': 'E8EAF6', '100': 'C5CAE9', '200': '9FA8DA', '300': '7986CB', '400': '5C6BC0', '500': '3F51B5', '600': '3949AB', '700': '303F9F', '800': '283593', '900': '1A237E', 'A100': '8C9EFF', 'A200': '536DFE', 'A400': '3D5AFE', 'A700': '304FFE'}, 'Blue': {'50': 'E3F2FD', '100': 'BBDEFB', '200': '90CAF9', '300': '64B5F6', '400': '42A5F5', '500': '2196F3', '600': '1E88E5', '700': '1976D2', '800': '1565C0', '900': '0D47A1', 'A100': '82B1FF', 'A200': '448AFF', 'A400': '2979FF', 'A700': '2962FF'}, 'LightBlue': {'50': 'E1F5FE', '100': 'B3E5FC', '200': '81D4FA', '300': '4FC3F7', '400': '29B6F6', '500': '03A9F4', '600': '039BE5', '700': '0288D1', '800': '0277BD', '900': '01579B', 'A100': '80D8FF', 'A200': '40C4FF', 'A400': '00B0FF', 'A700': '0091EA'}, 'Cyan': {'50': 'E0F7FA', '100': 'B2EBF2', '200': '80DEEA', '300': '4DD0E1', '400': '26C6DA', '500': '00BCD4', '600': '00ACC1', '700': '0097A7', '800': '00838F', '900': '006064', 'A100': '84FFFF', 'A200': '18FFFF', 'A400': '00E5FF', 'A700': '00B8D4'}, 'Teal': {'50': 'E0F2F1', '100': 'B2DFDB', '200': '80CBC4', '300': '4DB6AC', '400': '26A69A', '500': '009688', '600': '00897B', '700': '00796B', '800': '00695C', '900': '004D40', 'A100': 'A7FFEB', 'A200': '64FFDA', 'A400': '1DE9B6', 'A700': '00BFA5'}, 'Green': {'50': 'E8F5E9', '100': 'C8E6C9', '200': 'A5D6A7', '300': '81C784', '400': '66BB6A', '500': '4CAF50', '600': '43A047', '700': '388E3C', '800': '2E7D32', '900': '1B5E20', 'A100': 'B9F6CA', 'A200': '69F0AE', 'A400': '00E676', 'A700': '00C853'}, 'LightGreen': {'50': 'F1F8E9', '100': 'DCEDC8', '200': 'C5E1A5', '300': 'AED581', '400': '9CCC65', '500': '8BC34A', '600': '7CB342', '700': '689F38', '800': '558B2F', '900': '33691E', 'A100': 'CCFF90', 'A200': 'B2FF59', 'A400': '76FF03', 'A700': '64DD17'}, 'Lime': {'50': 'F9FBE7', '100': 'F0F4C3', '200': 'E6EE9C', '300': 'DCE775', '400': 'D4E157', '500': 'CDDC39', '600': 'C0CA33', '700': 'AFB42B', '800': '9E9D24', '900': '827717', 'A100': 'F4FF81', 'A200': 'EEFF41', 'A400': 'C6FF00', 'A700': 'AEEA00'}, 'Yellow': {'50': 'FFFDE7', '100': 'FFF9C4', '200': 'FFF59D', '300': 'FFF176', '400': 'FFEE58', '500': 'FFEB3B', '600': 'FDD835', '700': 'FBC02D', '800': 'F9A825', '900': 'F57F17', 'A100': 'FFFF8D', 'A200': 'FFFF00', 'A400': 'FFEA00', 'A700': 'FFD600'}, 'Amber': {'50': 'FFF8E1', '100': 'FFECB3', '200': 'FFE082', '300': 'FFD54F', '400': 'FFCA28', '500': 'FFC107', '600': 'FFB300', '700': 'FFA000', '800': 'FF8F00', '900': 'FF6F00', 'A100': 'FFE57F', 'A200': 'FFD740', 'A400': 'FFC400', 'A700': 'FFAB00'}, 'Orange': {'50': 'FFF3E0', '100': 'FFE0B2', '200': 'FFCC80', '300': 'FFB74D', '400': 'FFA726', '500': 'FF9800', '600': 'FB8C00', '700': 'F57C00', '800': 'EF6C00', '900': 'E65100', 'A100': 'FFD180', 'A200': 'FFAB40', 'A400': 'FF9100', 'A700': 'FF6D00'}, 'DeepOrange': {'50': 'FBE9E7', '100': 'FFCCBC', '200': 'FFAB91', '300': 'FF8A65', '400': 'FF7043', '500': 'FF5722', '600': 'F4511E', '700': 'E64A19', '800': 'D84315', '900': 'BF360C', 'A100': 'FF9E80', 'A200': 'FF6E40', 'A400': 'FF3D00', 'A700': 'DD2C00'}, 'Brown': {'50': 'EFEBE9', '100': 'D7CCC8', '200': 'BCAAA4', '300': 'A1887F', '400': '8D6E63', '500': '795548', '600': '6D4C41', '700': '5D4037', '800': '4E342E', '900': '3E2723', 'A100': '000000', 'A200': '000000', 'A400': '000000', 'A700': '000000'}, 'Gray': {'50': 'FAFAFA', '100': 'F5F5F5', '200': 'EEEEEE', '300': 'E0E0E0', '400': 'BDBDBD', '500': '9E9E9E', '600': '757575', '700': '616161', '800': '424242', '900': '212121', 'A100': '000000', 'A200': '000000', 'A400': '000000', 'A700': '000000'}, 'BlueGray': {'50': 'ECEFF1', '100': 'CFD8DC', '200': 'B0BEC5', '300': '90A4AE', '400': '78909C', '500': '607D8B', '600': '546E7A', '700': '455A64', '800': '37474F', '900': '263238', 'A100': '000000', 'A200': '000000', 'A400': '000000', 'A700': '000000'}, 'Light': {'StatusBar': 'E0E0E0', 'AppBar': 'F5F5F5', 'Background': 'FAFAFA', 'CardsDialogs': 'FFFFFF', 'FlatButtonDown': 'cccccc'}, 'Dark': {'StatusBar': '000000', 'AppBar': '1f1f1f', 'Background': '121212', 'CardsDialogs': '212121', 'FlatButtonDown': '999999'}}
try:
color = pickle.load(
open("color.pickle",'rb'))
except:
color=
"Red"
pickle.dump(color,open("color.pickle","wb"))
main_animation =
"in_out_cubic"
main_color = None
current_item = ""
line_size = .6
button_size=10
#filters_list = {
# 1: "
подате",
# 2: "
все",
# 3: "
учить"
#}
#pickle.dump(filters_list,open("filters.pickle",'wb'))

class CustomButton(MDFillRoundFlatButton):
def __init__(self, **kwargs):
super().__init__(
line_width=4 * line_size,
size_hint=(.01*button_size, 0.01*button_size),
md_bg_color=color_dict[color]["900"],
line_color=(0, 0, 0, 1),
_radius=100,
**kwargs
)

class CameraClick(Screen):
def __init__(self,**kwargs):
super(CameraClick, self).__init__(**kwargs)
self.scat = Scatter(
rotation= -90,
do_rotation= False, # disable user interaction
do_scale= False,
do_translation= True)
self.camera = Builder.load_string(
"""
Camera:
id: camera
resolution: (1920, 1080)
size_hint:(2,1)
pos_hint:{'center_x':.5}
play: True
canvas.before:
PushMatrix
Rotate:
angle: -90
origin: self.center
canvas.after:
PopMatrix"""
)
self.capture_button =CustomButton(on_press=self.capture)
self.exit_btn = CustomButton(
theme_icon_color="Custom",
icon_color="#311021",
on_press=self.on_exit,
pos_hint={"center_x": .9, "center_y": 0.915},
)
self.exit_btn.add_widget(MDIcon(icon="exit-to-app", ))
self.add_widget(self.scat)
self.add_widget(self.camera)
self.add_widget(self.capture_button)
self.add_widget(self.exit_btn)
def on_pre_enter(self, *args):
print(self.manager.children)
element =
self.manager.screens.pop([str(i) for i in self.manager.screens].index("<Screen name='camera'>"))
self.manager.screens.insert(len(self.manager.screens), element)
print(self.manager.children)
if color != pickle.load(open("color.pickle", "rb")):
for i in self.children:
if "MDScrollView" not in str(i):
setattr(i, 'md_bg_color', color_dict[pickle.load(open("color.pickle", "rb"))]["900"])
def on_exit(self,b):
print(self.manager.children)
self.manager.transition.direction = 'left'
self.manager.current = self.manager.previous()
element =
self.manager.screens.pop(-2)
self.manager.screens.insert(len(self.manager.screens), element)
print(self.manager.children)
def capture(self,b):
'''
Function to capture the images and give them the names
according to their captured time and date.
'''

timestr = time.strftime("%d-%m-%Y_%H-%M-%S")
print(timestr)
self.camera.export_to_png("IMG_{}.png".format(timestr))
m = pickle.load(
open(matrix_file,'rb'))
m[
self.manager.get_screen("editor").idd]["image"]=m[self.manager.get_screen("editor").idd]["image"]+["IMG_{}.png".format(timestr)]
pickle.dump(m
,open(matrix_file,'wb'))
class SettingsPrompt(Screen):
def __init__(self, **kwargs):
super(SettingsPrompt, self).__init__(**kwargs)
self.scrollvieww = MDScrollView(size_hint=(1, 0.9))
self.overall_layout = MDBoxLayout(orientation="vertical", adaptive_height=True, spacing=20) # Нескроллится
self.gui_layout = MDBoxLayout(
pos_hint={"center_x": .5, "center_y": .95},
size_hint=(1, 0.1), md_bg_color=color_dict[color]["900"])
self.exit_btn = CustomButton(
theme_icon_color="Custom",
icon_color="#311021",
on_press=self.on_exit,
pos_hint={"center_x": .9, "center_y": 0.915},
)
self.exit_btn.add_widget(MDIcon(icon="exit-to-app", ))
self.list_layout = MDList()
self.overall_layout.add_widget(self.list_layout)
self.scrollvieww.add_widget(self.overall_layout)
KV =
"""
MDLabel
text: "
настройки"
font_size:50
valgin: "center"
halign: "center"
"""

self.settings_text = Builder.load_string(KV)
self.add_widget(self.gui_layout)
self.add_widget(self.scrollvieww)
self.add_widget(self.exit_btn)
self.gui_layout.add_widget(self.settings_text)
def on_exit(self,b):
self.manager.transition.direction = 'left'
print(self.manager.screens)
self.manager.current = self.manager.previous()
element =
self.manager.screens.pop(-2)
self.manager.screens.insert(len(self.manager.screens), element)
class Mp3Screen(SettingsPrompt):
def __init__(self,**kwargs):
super(Mp3Screen, self).__init__(**kwargs)
self.s=0
self.s2=0
self.Audio =audio
self.settings_text.text = "аудиофайлы"
self.add_mp3_button = CustomButton(
pos_hint = {"center_x":.8,"center_y":.915},
on_press = self.add_audio)
self.add_widget(self.add_mp3_button)
self.add_mp3_button.add_widget(MDIcon(icon = "plus"))
self.record_button_start = CustomButton(
pos_hint = self.exit_btn.pos_hint,
on_press = self.record)
self.record_button_start.add_widget(MDIcon(icon = "microphone"))
self.animation_close = Animation(
opacity =0,
duration=.5)
self.animation_start = Animation(
opacity = 1,
duration=0.5)
def on_pre_enter(self, *args):
print(self.manager.screens)
element =
self.manager.screens.pop([str(i) for i in self.manager.screens].index("<Screen name='mp3'>"))
self.manager.screens.insert(len(self.manager.screens), element)
print(self.manager.screens)
if color != pickle.load(open("color.pickle", "rb")):
for i in self.children:
if "MDScrollView" not in str(i):
setattr(i, 'md_bg_color', color_dict[pickle.load(open("color.pickle", "rb"))]["900"])
def add_audio(self,b):
if not self.s:
self.add_mp3_button.children[0].icon = "close"
self.add_widget(self.record_button_start)
def close_audio(self,b):
self.add_mp3_button.children[0].icon = "plus"
self.remove_widget(self.record_button_start)
def record(self,b):
if not self.s2:
self.record_button_start.children[0].icon="check"
self.Audio.start()
self.s2=1
else:
self.record_button_start.children[0].icon = "microphone"
self.Audio.stop()
self.s2=0
class FilterSettings(SettingsPrompt):
def __init__(self, **kwargs):
super(FilterSettings, self).__init__(**kwargs)
self.filters_list = pickle.load(open("filters.pickle",'rb'))
self.s = 0
self.add_layout = MDFloatLayout()
self.text_input = MDTextField(
pos_hint={"center_y": 0.4},
pos = (90,0),
size_hint=[0.2, 0.2],
)
self.apply_add_filter_button = MDIconButton(
icon="check",
pos_hint={"right": .8, "center_y": .5},
on_press=self.confirm_text
)

self.list_add_item = MDIconButton(icon="plus",pos_hint = {"right":.94,"center_y":.9})
self.filters = OneLineAvatarIconListItem(
text="фильтры")
self.settings_text.text="фильтры"
self.scrollvieww.clear_widgets()
self.list_layout.clear_widgets()
self.add_layout.add_widget(self.list_add_item)
self.scrollvieww.add_widget(self.overall_layout)
#self.mdlist = MDList(md_bg_color=color_dict["Red"]["500"])
for i in self.filters_list:
list_item = OneLineAvatarIconListItem(

text=self.filters_list[i])
KV =
"""
IconRightWidget:
icon: 'minus'"""

minus_icon = Builder.load_string(KV)
minus_icon.on_press =
lambda id=i, item=list_item: self.delete_button(id, item)
list_item.add_widget(minus_icon)

self.list_layout.add_widget(list_item)
#self.overall_layout.add_widget(self.mdlist)
self.list_add_item.on_press = lambda id=len(self.filters_list) + 1, item=list_item: self.add_button(id,
item)
self.overall_layout.add_widget(self.add_layout)
self.shelter = OneLineAvatarIconListItem(pos_hint = {"center_y":1})
def on_pre_enter(self, *args):
element =
self.manager.screens.pop([str(i) for i in self.manager.screens].index("<Screen name='filter'>"))
self.manager.screens.insert(len(self.manager.screens), element)
for i in self.children:
if "MDScrollView" not in str(i):
setattr(i, 'md_bg_color', color_dict[pickle.load(open("color.pickle", "rb"))]["900"])
def confirm_text(self, b):
self.filters_list[max(self.filters_list.keys()) + 1] = self.text_input.text
list_item = OneLineAvatarIconListItem(

text=self.filters_list[max(self.filters_list.keys())])
KV =
"""
IconRightWidget:
icon:'minus'"""

minus_icon = Builder.load_string(KV)
minus_icon.on_press =
lambda id=len(self.filters_list) + 1, item=list_item: self.delete_button(id, item)
list_item.add_widget(minus_icon)

self.list_layout.add_widget(list_item)
self.s = 1
self.add_button(matrix_item=0, button=None)
self.text_input.text = ""
pickle.dump(self.filters_list,open("filters.pickle",'wb'))
def add_button(self, matrix_item, button):
if not self.s:
self.add_layout.add_widget(self.shelter)
self.list_add_item.icon = "close"
self.s += 1
self.add_layout.add_widget(self.text_input)
self.add_layout.add_widget(self.apply_add_filter_button)
else:
self.list_add_item.icon = "plus"
self.s = 0
self.add_layout.clear_widgets()
self.add_layout.add_widget(self.list_add_item)
def delete_button(self, matrix_item, button):
self.list_layout.remove_widget(button)
del self.filters_list[matrix_item]
pickle.dump(
self.filters_list,open("filters.pi kle","wb"))
class SettingsScreen(SettingsPrompt):
def __init__(self,**kwargs):
super(SettingsScreen, self).__init__(**kwargs)
Builder.load_string(KVV)

self.s = 0
self.filters_list = None
self.filters = OneLineAvatarIconListItem(
on_press=self.filters_window,
text="фильтры")
self.color_changer = OneLineAvatarIconListItem(
on_press = self.change_color,
text = "цвет"
)
self.dialog = MDDialog(
title="насколькодней?",
type="custom",
content_cls=Content(),
buttons=[
MDFlatButton(

text="НАЗАД",
theme_text_color="Custom",
on_release=lambda x: self.dialog.dismiss(),
),
MDFlatButton(
text="OK",
theme_text_color="Custom",
on_release=self.print_slider_value,
),
],
)
#colors
self.freeze = OneLineAvatarIconListItem(
on_press=self.freeze_dates,
text="заморозить"
)
# colors
red = MDIconButton(
theme_icon_color= "Custom",
icon ="circle",
pos_hint = {"center_x":.8,"center_y":.5},
icon_color=color_dict["Red"]["400"],
size = [.001,.3],
on_press = lambda x: self.change_color("Red"))
green = MDIconButton(

theme_icon_color= "Custom",
icon ="circle",
pos_hint = {"center_x":.7,"center_y":.5},
icon_color=color_dict["Green"]["400"],
size= [.001,.3],
on_press=lambda x: self.change_color("Green"))
purple = MDIconButton(

theme_icon_color= "Custom",
icon ="circle",
pos_hint = {"center_x":.6,"center_y":.5},
icon_color=color_dict["Purple"]["400"],
size= [.001,.3],
on_press = lambda x: self.change_color("Purple"))
blue = MDIconButton(

theme_icon_color="Custom",
icon="circle",
pos_hint={"center_x": .5, "center_y": .5},
icon_color=color_dict["Blue"]["400"],
size=[.001, .3],
on_press=lambda x: self.change_color("Blue"))
self.color_changer.add_widget(red)
self.color_changer.add_widget(green)
self.color_changer.add_widget(purple)
self.color_changer.add_widget(blue)
self.list_layout.add_widget(self.filters)
self.list_layout.add_widget(self.color_changer)
self.list_layout.add_widget(self.freeze)
def freeze_dates(self,a):
self.dialog.open()
def print_slider_value(self, *args): # определитеэтуфункцию
pickle.dump(-self.dialog.content_cls.children[0].value*1440,open("time.pickle",'wb'))
self.dialog.dismiss()
def change_color(self,colorr):
pickle.dump(colorr
,open("color.pickle",'wb'))
setattr(self.gui_layout, 'md_bg_color', color_dict[colorr]["900"])
setattr(self.exit_btn, 'md_bg_color', color_dict[colorr]["900"])
color = colorr

def on_pre_enter(self, *args):
element =
self.manager.screens.pop([str(i) for i in self.manager.screens].index("<Screen name='settings'>"))
self.manager.screens.insert(len(self.manager.screens), element)
if color !=pickle.load(open("color.pickle","rb")):
for i in self.children:
if "MDScrollView" not in str(i):
setattr(i, 'md_bg_color', color_dict[pickle.load(open("color.pickle","rb"))]["900"])
def filters_window(self,b):
self.manager.current="filter"
self.manager.get_screen("filter").filters_list = self.filters_list
class MainScreen(Screen):
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
self.layout = GridLayout(cols = 1, size_hint_y=None, row_default_height=Window.width,spacing = "300dp")
self.layout.bind(minimum_height=self.layout.setter("height"))
self.timeout = []
self.last_input = ""
self.deadline = [480, 2880, 8640]
self.now = [datetime.now().year, datetime.now().month, datetime.now().day, datetime.now().hour,datetime.now().minute] # списокснастоящимвременем
self.buttons = []
try:
self.matrix = pickle.load(open(matrix_file, "rb"))
except:
pickle.dump({}
,open(matrix_file,'wb'))
self.matrix = pickle.load(open(matrix_file, "rb"))
self.matrix_keys = self.matrix.keys()
self.matrix_values = self.matrix.values()
self.list_layout = MDList()
self.scrollvieww = ScrollView(size_hint = (1,0.9))
self.scrollvieww.add_widget(self.list_layout)
self.add_widget(self.scrollvieww)
self.close = 0
self.s2=0
self.filter = ""
self.current_menu_item = ""
self.menu_items ={
1:"подате",
2:"все",
3:"учить"
}
self.learn_list = []
self.list_dict = {}
#layouts
KV = """
MDFloatLayout:
pos_hint:{"center_x": .5, "center_y": .95}
size_hint:(1,0.1)
"""

self.gui_layout = Builder.load_string(KV)
self.gui_layout.md_bg_color = color_dict[color]["900"]
#upper_section
self.text_input = MDTextField(
size_hint=(.6,None),
hint_text="искать...",
pos_hint={"center_x": 0.5,"center_y": 0.5},
)
Clock.schedule_interval(
self.update_search_results, 1)
#lower_section
self.settings_button = CustomButton(
theme_icon_color="Custom",
icon_color="#311021",
on_press=self.settings,
pos_hint={"center_x": .9, "center_y": 0.915},
)
self.settings_button.add_widget(MDIcon(icon="dots-horizontal"))
#filters
self.filter_btn = CustomButton(
icon='filter-outline',
pos_hint={"center_x":0.1,'center_y': self.settings_button.pos_hint["center_y"]},
)
self.filter_btn.add_widget(MDIcon(icon = "filter-outline"))
# settings
self.add_btn = CustomButton(
theme_icon_color="Custom",
icon_color="#311021",
on_press=self.on_add,
pos_hint={"center_x": self.settings_button.pos_hint["center_x"],
"center_y": self.settings_button.pos_hint["center_y"]},
opacity = 0,
)
self.add_btn.add_widget(MDIcon(icon="new-box"))
self.settings_button2 = CustomButton(
theme_icon_color="Custom",
icon_color="#311021",
on_press=self.on_settings,
pos_hint={"center_x": self.settings_button.pos_hint["center_x"],
"center_y": self.settings_button.pos_hint["center_y"]},
opacity=0,
)
self.settings_button2.add_widget(MDIcon( icon="wrench",))
self.exit_btn = CustomButton(
theme_icon_color="Custom",
icon_color="#311021",
on_press=self.on_exit,
pos_hint={"center_x": self.settings_button.pos_hint["center_x"],
"center_y": self.settings_button.pos_hint["center_y"]},
opacity=0
)
self.exit_btn.add_widget(MDIcon(icon="exit-to-app",))
#adding
Clock.schedule_once(lambda dt: self.canvas.ask_update(), 0)
#self.add_filter_layout.add_widget(self.text_input2)
s#elf.add_filter_layout.add_widget(self.apply_button)
s#elf.delete_filter_layout.add_widget(self.delete_filter_input)
s#elf.delete_filter_layout.add_widget(self.apply_delete_filter_button)
self.add_widget(self.gui_layout)
self.gui_layout.add_widget(self.text_input)
self.add_widget(self.settings_button2)
self.add_widget(self.exit_btn)
self.add_widget(self.add_btn)
self.add_widget(self.settings_button)
#self.add_widget(self.text_button)
#self.add_widget(self.add_filter_button)
#self.add_widget(self.add_filter_layout)
#self.add_widget(self.delete_filter_button)
#self.add_widget(self.filter_settings)

self.add_widget(self.filter_btn)
self.button_layout = RelativeLayout()
self.check()
self.on = 0
self.s = 0
self.s3 = 0
def on_settings(self,b):
self.manager.get_screen("settings").filters_list = self.menu_items
self.manager.transition.direction = 'left'
self.manager.current = 'settings'
def settings(self,a):
if self.s3:
animation = Animation(

opacity=0,
pos_hint= {"center_y":self.settings_button.pos_hint["center_y"]},
duration=0.5,
t=main_animation)
animation.start(
self.settings_button2)
animation.start(
self.add_btn)
animation.start(
self.exit_btn)
self.s3=0
elif self.s3==0:
if self.close:
self.filters(None)
k =
self.settings_button.pos_hint["center_y"]
animation2 = Animation(

opacity=1,
pos_hint={"center_y": k-kok},
duration=0.4,
t=main_animation).start(self.settings_button2)
delete_animation1 = Animation(

opacity=1,
pos_hint={"center_y":k-kok*2},
duration=0.6,
t=main_animation).start(self.add_btn)
set_animation = Animation(

opacity=1,
pos_hint={"center_y":k-kok*3},
duration=0.8,
t=main_animation).start(self.exit_btn)
self.s3+=1
def apply_filters(self,a):
self.menu_items.append(self.text_input2.text)
self.menu.items = [{
"text": f"{i}",
"viewclass": "OneLineListItem",
"on_release": lambda x=f"Item {i}", i=i: self.update_search_results(filters=i),
} for i in self.menu_items]
def delete_filters(self, a):
self.menu_items.remove(self.delete_filter_input.text)
self.menu.items = [{
"text": f"{i}",
"viewclass": "OneLineListItem",
"on_release": lambda x=f"Item {i}", i=i: self.update_search_results(filters=i),
} for i in self.menu_items]
def add_filter(self,a):
if self.s2:
self.delete_filter(None)
self.s2 = 0
print(1)
if self.s:
anim = Animation(
duration=0.3,size_hint=(-.4,0))
anim&=Animation(
pos_hint = self.add_filter_button.pos_hint)
anim.start(
self.add_filter_layout)
self.add_filter_layout.disabled=True
self.s=0
else:
self.add_filter_layout.disabled=False
anim = Animation(duration=0.3,size_hint=(4,0))
anim&=Animation(
pos_hint = {"center_x":.25})
anim.start(
self.add_filter_layout)
self.s+=1
def delete_filter(self,a):
if self.s:
self.add_filter(None)
self.s = 0
if self.s2:
Animation(
duration=0.3,opacity=0).start(self.delete_filter_layout)
self.delete_filter_layout.disabled=True
self.s2=0
else:
self.delete_filter_layout.disabled=False
Animation(duration=0.3,opacity=1).start(self.delete_filter_layout)
self.s2+=1
def filters(self,a):
self.s=0
self.s2=0
if self.close:
animation = Animation(

opacity=0,
pos_hint=self.filter_settings.pos_hint,
duration=0.5,
t=main_animation)
animation2 = Animation(

opacity=0,
duration=0.5,
t=main_animation)
animation.start(
self.add_filter_button)
animation.start(
self.text_button)
animation.start(
self.delete_filter_button)
self.add_filter_layout.disabled = True
self.delete_filter_layout.disabled = True
self.close=0
elif self.close==0:
if self.s3:
self.settings(None)
animation4 = Animation(

opacity=1,
pos_hint={"center_y":0.9-kok*2},
duration=0.6,
t=main_animation)
animation4.start(
self.add_filter_button)
animation4.start(
self.text_button)
animation4.start(
self.add_filter_layout)
delete_animation1 = Animation(

opacity=1,
pos_hint={"center_y":0.9-kok*1},
duration=0.8,
t=main_animation)
delete_animation1.start(
self.delete_filter_button)
self.delete_filter_layout.disabled=False
self.close+=1
def open_menu(self, a):
self.menu.open()
def on_pre_enter(self, *args):
for i in self.children:
if "MDScrollView" not in str(i):
setattr(i, 'md_bg_color', color_dict[pickle.load(open("color.pickle","rb"))]["900"])
if "MDTextField" in str(i):
setattr(i, "color_mode", "custom")
setattr(i, 'line_color_focus', color_dict[pickle.load(open("color.pickle", "rb"))]["900"])
def on_enter(self):
element =
self.manager.screens.pop([str(i) for i in self.manager.screens].index("<Screen name='main'>"))
self.manager.screens.insert(len(self.manager.screens), element)
self.menu = MDDropdownMenu(
caller=self.filter_btn,
items=[
{

"text": f"{self.menu_items[i]}",
"viewclass": "OneLineListItem",
"on_release": lambda x=f"Item {self.menu_items[i]}", i=self.menu_items[i]: self.update_search_results(filters=i),
} for i in self.menu_items
]
,
width_mult=4,
)
self.filter_btn.bind(on_release=self.open_menu)
self.menu_items=pickle.load(open("filters.pickle","rb"))
self.update_search_results(filters=self.filter) if self.list_dict else None
self.matrix = pickle.load(open(matrix_file,'rb'))
for child in self.children:
if child.__class__.__name__ == 'MDRaisedButton':
child.elevation_normal =
2
def update_button(self, matrix_item, button_dict):
if self.matrix[matrix_item]['text']:
button_dict[matrix_item].text =
f"{self.matrix[matrix_item]['id']} {self.matrix[matrix_item]['text']}"
if not self.matrix[matrix_item]["learn"]:
button_dict[matrix_item].md_bg_color = color_dict[color]

else:
button_dict[matrix_item].text =
f"AAAAA "
def save_matrix(self):
pickle.dump(
self.matrix, open(matrix_file, 'wb'))
def on_save(self, text, image, editor_id=0, age=1):
self.matrix= pickle.load(open(matrix_file,'rb'))
if isinstance(editor_id, int):
if age:
self.matrix[editor_id]['text'] = text
self.matrix[editor_id]['image'] = image
else:
if self.matrix.keys():
self.matrix[max(self.matrix.keys()) + 1] = {
"id": max(self.matrix.keys()) + 1,
"date": [datetime.now().year, datetime.now().month, datetime.now().day, datetime.now().hour,
datetime.now().minute, ],
"time": 480,
"text": text,
"image": image,
"learn": False
}
self.add_button(max(self.matrix.keys()),f"{max(self.matrix.keys())} ")
else:
self.matrix[1] = {
"id": 1,
"date": [datetime.now().year, datetime.now().month, datetime.now().day, datetime.now().hour,
datetime.now().minute, ],
"time": 480,
"text": text,
"image": image,
"learn": False
}
self.add_button(1,f"1")
self.save_matrix()
def check(self):
for i in self.matrix_keys:
self.time = pickle.load(open("time.pickle",'rb'))
self.num = self.matrix[i]['date']
print(self.num)
self.num = [self.now[i] - self.num[i] for i in
range(len(self.now))] # списоксзначениемвремени - нынешнеевремя
self.time += self.num[0] * 525960 # переводимгодавминуты... |
self.time += self.num[1] * 43800 # переводиммесяцывминуты... |
self.time += self.num[2] * 1440 # переводимднивминуты... | - вот это
self.time += self.num[3] * 60 # переводим часы в минуты... |
self.time += self.num[4] * 1 # переводим минуты в минуты... |
if self.time >= self.matrix[i]['time']: # если время больше или равн о значению # времени блока
if self.deadline[self.deadline.index(self.matrix[i]['time'])] >= self.deadline[
-
1]: # еслизначениевремениужемаксимальноето:
pass
else
:
self.matrix[i]['time'] = self.deadline[self.deadline.index(self.matrix[i][
'time']) + 1] # задаёмпеременной x значениесписка deadline, котороеидётзазначением, присвоенномдоэтого (было 480 стало 2880, кпримеру)
self.matrix[i]['date'] = self.now
self.timeout.append(self.matrix[i])
for i in self.timeout:
self.matrix[i['id']]['learn'] = True
pickle.dump(self.matrix, open(matrix_file, "wb"))
def delete_button(self,matrix_item,button):
self.list_layout.remove_widget(button)
del self.list_dict[matrix_item]
del self.matrix[matrix_item]
self.save_matrix()
#def clear_list(self,text="",filter = ""):
# if filter=="
учить":
def add_button(self,matrix_item,first_sentence,red=0):
if matrix_item not in self.list_dict.keys():
self.button_layout = RelativeLayout()
KV =
"""
IconRightWidget:
icon: "minus"
"""

list_item = OneLineAvatarIconListItem(
on_press = lambda *args:self.on_edit(list_item),
text = str(self.matrix[matrix_item]['id'])+" "+str(first_sentence))
minus_icon = Builder.load_string(KV)
minus_icon.on_press =
lambda *args: self.delete_button(matrix_item,list_item)
list_item.add_widget(minus_icon)

self.list_dict[matrix_item] = list_item
#self.button_layout.add_widget(self.button_dict[matrix_item])
self.list_layout.add_widget(list_item)
def update_search_results(self,dt=0,filters=""):
if filters:
self.filter_btn.text = filters
self.filter = filters
text =
self.text_input.text
self.matrix = pickle.load(open(matrix_file,'rb')) # без pickle невидитпоследнийэлемент
if len(text)>0 or filters: # filters отсеитьнадо, атолюбойфильтроткрываетчастькодаэтого
for i in self.matrix:
if filters == 'учить':
first_sentence =
self.matrix[i]['text'][0:50]
if self.matrix[i]['learn']:
print(self.matrix[i]["id"])
if self.matrix[i]["id"] not in self.list_dict.keys():
self.add_button(i,first_sentence,1)
else:
if self.matrix[i]["id"] in self.list_dict.keys():
self.list_layout.remove_widget(self.list_dict[self.matrix[i]["id"]])
del self.list_dict[self.matrix[i]["id"]]
elif text in self.matrix[i]['text'] and text!="" or filters == "все" or filters in self.matrix[i]['text'] and filters!="" :
editor =
self.matrix[i]
first_sentence = editor[
'text'][0:50]
if not editor['learn']:
self.add_button(i, first_sentence)
else:
self.add_button(i, first_sentence,red = 1)
else:
if self.matrix[i]["id"] in self.list_dict.keys():
self.list_layout.remove_widget(self.list_dict[self.matrix[i]["id"]])
del self.list_dict[self.matrix[i]["id"]]
self.last_input = text
def on_add(self, instance):
editor_id =
len(self.matrix) + 1
self.show_editor(editor_id, text=0,age = 0)
def on_exit(self):
MyApp.stop()

def on_edit(self, button,learn=None):
if learn:
self.add_widget(self.over)
editor_screen =
self.manager.get_screen('editor')
editor_id =
int(button.text[:10].split(" ")[0]) # Получаемпервыйсимволдляопределенияномеракнопки
editor_screen.idd = editor_id
if self.matrix[editor_id]:
editor_screen.textt_input.text =
self.matrix[editor_id]['text']
editor_screen.list_dict =
self.list_dict
text =
self.matrix[editor_id]["text"]
self.show_editor(editor_id, text=1)
pickle.dump(editor_id
,open('id.pickle','wb'))
def save_matrix(self):
with open(matrix_file, "wb") as file:
pickle.dump(
self.matrix, file)
def show_editor(self, editor_id, text,age = 1):
if text:
pickle.dump(editor_id
,open('id.pickle','wb'))
if self.matrix and age:
if self.matrix[editor_id]["learn"]:
self.manager.get_screen("editor").over = 1
self.manager.get_screen("editor").age = age
self.manager.transition.direction = 'left'
self.manager.current = 'editor'
class EditorScreen(Screen):
def __init__(self, text=0, launch=0, **kwargs):
super(EditorScreen, self).__init__(**kwargs)
self.ms = MainScreen()
self.Sslider = Slider(min=0,max = 50,value =0)
self.Sslider.bind(value=self.change_spacing)
self.layout = GridLayout(cols=1,spacing = 1, size_hint_y=None, row_default_height=Window.width*.5)
KV =
"""
MDFloatLayout:
pos_hint:{"center_x": .5, "center_y": .05}
size_hint:(1,0.1)
"""

self.gui_layout = Builder.load_string(KV)
self.gui_layout.md_bg_color = color_dict[color]["700"]
self.sc = Scatter(do_rotation=False,auto_bring_to_front=False)
self.layout.bind(minimum_height=self.layout.setter("height"))
self.idd = 0
self.over = 0
self.age = 1
self.text = text
self.s = 0
self.close = 0
self.list_dict = {}
self.matrix = pickle.load(open(matrix_file, "rb"))
if self.matrix:
self.matrix_keys = self.matrix.keys()
self.matrix_values = self.matrix.values()
self.launch = launch
scrollview = ScrollView()
scrollview.add_widget(
self.layout)
self.add_widget(scrollview)
self.add_widget(self.gui_layout)
self.image_list = []
self.settings_button = CustomButton(
pos_hint={'right': 0.99, "center_y": 0.1},
on_press = self.show_buttons
)

self.settings_button.add_widget(MDIcon(icon="wrench"))
self.file_button = CustomButton(
pos_hint=self.settings_button.pos_hint,
on_press=lambda iw: self.file_chooser.show(path),
)
self.file_button.add_widget(MDIcon(icon="file-image-plus-outline"))
self.camera_button = CustomButton(
pos_hint=self.settings_button.pos_hint,
on_press=self.capture,
)
self.camera_button.add_widget(MDIcon(icon="camera"))
self.mp3_button = CustomButton(
pos_hint=self.settings_button.pos_hint,
on_press=self.on_mp3,
)
self.mp3_button.add_widget(MDIcon(icon="music-note"))
self.textt_input = TextInput()
self.text_mode_button = CustomButton(
pos_hint=self.settings_button.pos_hint,
on_press=lambda iw: self.on_text_mode(self.idd, self.age),
)
self.text_mode_button.add_widget(MDIcon(icon="note-text-outline"))
self.back_button = CustomButton(
icon="keyboard-backspace",
pos_hint={'center_x': 0.1, "center_y": 0.1},
on_press=lambda text: self.on_main(text=self.textt_input.text,
editor_id=self.idd),
)
self.back_button.add_widget(MDIcon(icon="keyboard-backspace"))
self.add_widget(self.mp3_button)
self.add_widget(self.camera_button)
self.add_widget(self.back_button)
self.add_widget(self.text_mode_button)
self.add_widget(self.file_button)
self.file_chooser = MDFileManager(
exit_manager=self.exit_manager,
select_path=self.on_file_selection)
self.add_widget(self.settings_button)
self.gui_layout.add_widget(self.Sslider)
self.overlearn = 0
self.launch = launch
def on_pre_leave(self, *args):
if self.image_list:
self.matrix[self.idd]["image"]=self.image_list
pickle.dump(
self.matrix, open(matrix_file, 'wb'))
print(1213213213123)
def on_mp3(self,b):
self.manager.current = "mp3"
def capture(self,b):
print(1121321)
self.manager.current = "camera"
def change_spacing(self, instance, value):
self.layout.spacing=value*2
def show_buttons(self,a):
if self.s:
animation = Animation(

opacity=0,
pos_hint={"center_y": self.settings_button.pos_hint["center_y"]},
duration=0.5,
t=main_animation)
animation.start(
self.file_button)
animation.start(
self.text_mode_button)
animation.start(
self.camera_button)
animation.start(
self.mp3_button)
self.s = 0
elif self.s == 0:
file_button_animation = Animation(

opacity=1,
pos_hint={"center_y": 0.2},
duration=0.5,
t=main_animation)
file_button_animation.start(
self.file_button)
button_text_animation = Animation(

opacity=1,
pos_hint={"center_y": 0.3},
duration=0.6,
t=main_animation)
button_text_animation.start(
self.text_mode_button)
camera_animation = Animation(

opacity=1,
pos_hint={"center_y": 0.4},
duration=0.7,
t=main_animation)
camera_animation.start(
self.camera_button)
mp3_animation = Animation(

opacity=1,
pos_hint={"center_y": 0.5},
duration=0.8,
t=main_animation)
mp3_animation.start(
self.mp3_button)
self.s += 1
def exit_manager(self, *args):
self.file_chooser.close()
def on_pre_enter(self):
element =
self.manager.screens.pop([str(i) for i in self.manager.screens].index("<Screen name='editor'>"))
self.manager.screens.insert(len(self.manager.screens), element)
self.matrix = pickle.load(open(matrix_file, 'rb'))
if self.matrix:
if self.age and self.idd:
self.image_list = self.ms.matrix[self.idd]['image']
self.image_list = self.ms.matrix[self.idd]['image']
self.on_load_images(self.ms.matrix[self.idd]['image'])
# self.overlearn = 0
else:
self.layout.clear_widgets()
self.image_list = []
# self.layout.add_widget(self.file_chooser)
if self.over:
self.over_learn = CustomButton(
pos_hint={'center_x': 0.3,"center_y":.1},
)
self.over_learn.add_widget(MDIcon(icon = "note-check-outline"))
self.over_learn.bind(on_press=lambda text: self.on_main(text=self.textt_input.text,
editor_id=self.idd, over=1))
self.add_widget(self.over_learn)
for i in self.children:
if "MDScrollView" not in str(i):
setattr(i, 'md_bg_color', color_dict[pickle.load(open("color.pickle", "rb"))]["900"])
def on_text_mode(self, ids, age):
self.id = ids
if age:
if not self.textt_input.text:
self.textt_input.text = self.ms.matrix[self.id]['text']
self.add_widget(self.textt_input)
self.back_button = CustomButton(
text='Back',
pos_hint={'center_x': 0.5},
)
self.back_button.bind(on_press=lambda button: self.on_back_button_press(button, text=1, save_text=True))
self.add_widget(self.back_button)
from functools import partial
def delete_image(self, image,block):
del self.image_list[self.image_list.index(image)]
self.layout.remove_widget(block)
def on_file_selection(self, path):
self.image = path
if self.image:
self.image_list.append(self.image)
im = MDRectangleFlatButton(

on_press = self.spotlight,
size_hint = (1,1))
im.add_widget(FitImage(

source=path))
self.xox = CustomButton(
pos_hint={'center_x': .9, 'center_y': .9},
)
self.page = MDRelativeLayout(
line_color=(0, 0, 0, 1),
size_hint=im.size_hint, )
self.xox.add_widget(MDIcon(icon = "close-thick"))
self.xox.bind(on_release=lambda x, image=path,button = im: self.delete_image(image,im))
self.page.add_widget(im)
self.page.add_widget(self.xox)
self.layout.add_widget(self.page)
def on_load_images(self,images):
self.layout.clear_widgets()
for i33 in images:
im = MDRectangleFlatButton(

on_press= lambda x,i=i33: self.spotlight(x,i),
size_hint=(.99,.99),
pos_hint = {"center_x":.5,"center_y":.5})
image = FitImage(
source = i33)
im.add_widget(image)

self.xox = MDFillRoundFlatButton(
pos_hint={'center_x': .9, 'center_y': .9},
line_width=4*line_size, # задаемширинуобводки
_radius=20,
line_color = (0,0,0,1)
)

self.page = MDRelativeLayout()
self.xox.add_widget(MDIcon(icon="close-thick"))
self.xox.bind(on_release=lambda x,image=i33, button = self.page: self.delete_image(image,button))
self.page.add_widget(im)
self.page.add_widget(self.xox)
self.layout.add_widget(self.page)
def spotlight(self,b,image):
self.gray = MDBoxLayout(md_bg_color = (128, 128, 128,.5))
self.add_widget(self.gray)
if not self.sc.children:
im = Image(
source = image,size = (Window.width,Window.height))
self.close_button = MDFillRoundFlatButton(
pos_hint={'center_x': .95, 'center_y': .95},
line_width=4*line_size, # задаемширинуобводки
line_color=(0, 0, 0, 1),
_radius=20,
)
self.close_button.add_widget(MDIcon(icon="close-thick"))
self.close_button.bind(on_release= self.close_spotlight)
self.sc.add_widget(im)
if self.sc not in self.children:
self.add_widget(self.sc)
self.add_widget(self.close_button)
for i in self.children:
i.disabled=
True
if
i==self.close_button:
self.close_button.disabled=False
if
i==self.sc:
self.sc.disabled=False
def
close_spotlight(self,b):
self.sc.clear_widgets()
self.remove_widget(self.gray)
for i in self.children:
i.disabled =
False
self.remove_widget(self.close_button)
self.remove_widget(self.sc)
def update_button(self, matrix_item, button_dict):
self.matrix = pickle.load(open(matrix_file,'rb'))
if self.matrix[matrix_item]['text']:
button_dict[matrix_item].text =
f"{self.matrix[matrix_item]['id']} {self.matrix[matrix_item]['text']}"
if not self.matrix[matrix_item]["learn"]:
button_dict[matrix_item].md_bg_color = color_dict[color]

def on_main(self, text, editor_id, over=0):
if over:
self.matrix[editor_id]['learn'] = False
pickle.dump(self.matrix, open(matrix_file, 'wb'))
self.manager.transition.direction = 'up'
self.manager.current = 'main'
self.textt_input.text = ""
self.ms.on_save(text=text, image=self.image_list, editor_id=editor_id, age=self.age)
if editor_id:
self.update_button(editor_id, self.list_dict)
self.ms.update_search_results(filters="учить")
self.sc.clear_widgets()
def on_back_button_press(self, button, text=0, save_text=False):
self.remove_widget(self.textt_input)
self.remove_widget(self.back_button)
class MyApp(MDApp):
def build(self):
global sm
sm = ScreenManager()

self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = color
self.theme_cls.material_style = "M3"
sm.add_widget(MainScreen(name = "main"))
sm.add_widget(EditorScreen(
name = "editor"))
sm.add_widget(SettingsScreen(
name="settings"))
sm.add_widget(FilterSettings(
name="filter"))
sm.add_widget(CameraClick(
name="camera"))
sm.add_widget(Mp3Screen(
name="mp3"))
sm.current =
'main'
element = sm.screens.pop([str(i) for i in sm.screens].index("<Screen name='main'>"))
sm.screens.insert(
len(sm.screens), element)
return sm
if __name__ == "__main__":
MyApp().run()

1 GPT-4 является четвёртым поколением алгоритмом естественного языка от компании OpenAI

2 Так как функция распределения Больцмана не создавалась для машинного обучения, используют её частный случай, а именно функцию softmax.

3 Кривая Эббингауза была получена вследствие экспериментального изучения памяти самим Германом Эббингаузом

4 Buildozer является open-source проектом на Linux, позволяющий конвертировать код в APK-файл

Просмотров работы: 28