From 6e92003c6384148233fa1878594f4ba10aef6e5f Mon Sep 17 00:00:00 2001 From: Dayal Date: Mon, 8 Sep 2025 19:45:27 +0300 Subject: [PATCH 01/24] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=20log.ipynb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Прогнал на нем все линтеры, описал по датам что нового узнал --- log.ipynb | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ log.py | 10 ++++++++++ 2 files changed, 58 insertions(+) create mode 100644 log.ipynb create mode 100644 log.py diff --git a/log.ipynb b/log.ipynb new file mode 100644 index 00000000..cd9fec9d --- /dev/null +++ b/log.ipynb @@ -0,0 +1,48 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "c2a61223", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Документ для логирования знаний полученных на уроках.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "6bb24181", + "metadata": {}, + "source": [ + "06.09\n", + "\n", + "1) Узнал как устанавливать приложения из исходников с github\n", + "2) Установил cpython из исходников" + ] + }, + { + "cell_type": "markdown", + "id": "3627f778", + "metadata": {}, + "source": [ + "08.09\n", + "\n", + "1) Понял что не нужно ничего додумывать и строго соблюдать регламент" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/log.py b/log.py new file mode 100644 index 00000000..8471b727 --- /dev/null +++ b/log.py @@ -0,0 +1,10 @@ +"""Документ для логирования знаний полученных на уроках.""" + +# 06.09 +# +# 1) Узнал как устанавливать приложения из исходников с github +# 2) Установил cpython из исходников + +# 08.09 +# +# 1) Понял что не нужно ничего додумывать и строго соблюдать регламент From 2265a8c04c3b69cb074ab0cf8261a9f95f479cc6 Mon Sep 17 00:00:00 2001 From: Dayal Date: Fri, 12 Sep 2025 23:05:01 +0300 Subject: [PATCH 02/24] [TASK] Quiz (https://github.com/SENATOROVAI/intro-cs/issues/6) closes https://github.com/SENATOROVAI/intro-cs/issues/6 --- quiz.ipynb | 510 +++++++++++++++++++++++++++++++++++++++++++++++++++++ quiz.py | 474 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 984 insertions(+) create mode 100644 quiz.ipynb create mode 100644 quiz.py diff --git a/quiz.ipynb b/quiz.ipynb new file mode 100644 index 00000000..dff79f69 --- /dev/null +++ b/quiz.ipynb @@ -0,0 +1,510 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "1264f403", + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "\"\"\"quiz.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "c4d3ca6b", + "metadata": {}, + "source": [ + "quiz1\n", + "\n", + "1) Как понять, что домашка пришла?\n", + "меня тегнут в чате HomeWork, формат \"@мой_ник прими пул\"\n", + "0:10-0:17\n", + "\n", + "2) Как принять домашку?\n", + "github desktop -> pull origin -> fetch origin\n", + "\n", + "3) Зачем нужна кнопка history и какие функции появляются \n", + "при нажатии правой кнопки мыши на коммит?\n", + "В ней находится история коммитов, сверху вниз по новизне\n", + "0:30-0:43\n", + "По нажатию ПКМ даются функции: amend, reset to, checkout, reorder revert changes... commit. \n", + "А так же посмотреть коммит на гитхабе чтобы взять на него ссылку\n", + "3:47-3:50\n", + "\n", + "3.1) Где брать ссылку на коммит? куда её отправлять? \n", + "Коммит - локальная фиксация изменений\n", + "Ссылка на коммит по нажатию ПКМ -> View on github. \n", + "Отправляем в чат тг Homework с подписью \"Коммит отдал\"\n", + "3:50-4:30\n", + "\n", + "4) Что такое файл лога? \n", + "Файл формата ipynb(markdown) который нужно заполнять \n", + "в конце урока(дата и что узнал в течение урока по пунктам), \n", + "как сказано в видео, по факту он создается единожды, для прогона линтеров\n", + "1:10-2:16\n", + "\n", + "4.1) Когда нужно его пушить?\n", + "Как я понял, после выполнения домашней работы вместе с файлом домашки, \n", + "либо же после окончания урока в случае если параллельно заполнялся лог\n", + "3:10-3:14\n", + "\n", + "5) Что такое интерпритатор? \n", + "Программа которая читает и запускает записанный пользователем код\n", + "2:44-2:51\n", + "\n", + "6) Где можно выбрать интерпритатор?\n", + "При запуске ячейки в ноутбуке предоставляется возможность \n", + "выбора интерпретатора в поле для ввода \n", + "\n", + "в верхней части VSCODE далее select another kernel -> python environments -> ...\\anaconda\\...\n", + "\n", + "Либо по кнопке справа от ячейки в ноутбуке\n", + "2:51-3:06\n", + "\n", + "7) Что такое модуль? \n", + "Файл с расширением .py или .ipynb\n", + "8:47-8:51\n", + "\n", + "8) Как создать и отправить коммит?\n", + "После изменения файлов эти изменения отобразятся в github desktop, записываем summary и \n", + "description для этого коммита и жмем Commit to main -> push origin\n", + "3:25-3:40\n", + "\n", + "9) Как посмотреть что коммит точно отправлен и находится в github?\n", + "Коммит точно отправлен если есть возможность взять на него ссылку с github, \n", + "а также он отобразиться во вкладке history на github desktop\n", + "3:46-4:00\n", + "\n", + "10) Какая команда показывает что код не прошёл проверки на ошибки? \n", + "pre-commit run --all-files\n", + "6:03-6:15\n", + "\n", + "10.1) Напишите список линтеров которые используются \n", + "для проверки кода и дайте их краткую характеристику.\n", + "\n", + "pylint - линтер который проверяет код на синтаксические и другие ошибки\n", + "black - позволяет писать код согласно стандарту pep8, соблюдая все отступы, \n", + "пробелы и т.д. Сам переформатирует отступы, пробелы автоматически по стандарту PEP8\n", + "mypy - позволяет проверять аннотацию типов (псевдостатическая типизация)\n", + "из курса на степике\n", + "\n", + "11) Как узнать какой именно линтер не прошёл проверку?\n", + "После запуска команды \"pre-commit run --all-files\" в терминале будут отображаться линтеры и \n", + "описание результата их работы, в том случае если результат работы неуспех - \n", + "ниже показывается имя файла в котором произошла ошибка, \n", + "номер ячейки, а также краткое описание ошибки\n", + "6:15-6:50\n", + "\n", + "12) Линтер Pylint видит markdown?\n", + "Нет, из-за этого случаются расхождения в номерах ячеек в vscode и терминале\n", + "7:05-7:12\n", + "\n", + "13) Номер ячейки в терминале и номер ячейки в vs code может отличаться? в каком случае?\n", + "Линтер не видит markdown\n", + "Если ошибка в ячейке после markdown, то линтер укажет на ошибку в ячейке \n", + "(номер ячейки в vscode - количество ячеек markdown до нее)\n", + "7:00-7:30\n", + "\n", + "14) Где посмотреть номер ячейки в vscode?\n", + "Внизу справа в окне vscode, \"cell (сколько-то) of (сколько-то)\"\n", + "6:41-6:53\n", + "\n", + "15) В каком формате ipynb отправляется в гитхаб? причём здесь JSON?\n", + "Файлы ipynb отправляются на гитхаб в формате JSON\n", + "3:19-3:25 из видео\n", + "\n", + "JSON, это стандартный текстовый формат для представления структурированных данных, \n", + "основанный на синтаксисе объектов JavaScript. \n", + "Так веб-приложения и не только, обмениваются данными, в таком формате.\n", + "из курса на степике\n", + "\n", + "16) Где посмотреть в какой ячейке ошибка?\n", + "В информации после прогона линтеров, будет указано - файл:номер ячейки:код ошибки:краткое описание\n", + "6:31-6:50\n", + "\n", + "17) Как запустить терминал?\n", + "Кнопка \"terminal\" в верхней панели VSCODE, \n", + "нажимаем на нее и далее \"new terminal\", либо сочетание ctrl+shift+'\n", + "5:55-6:00\n", + "\n", + "18) Что такое линтер?\n", + "Программа которая проверяет файл на корректность, насколько код соответствует стандартам\n", + "6:06-6:20\n", + "\n", + "19) В какой сайт нужно вставлять код ошибки если ошибка связана с pylint?\n", + "https://pylint.pycqa.org/en/latest/index.html\n", + "8:15-8:50 \n", + "\n", + "20) Секция pydocstyle в большинстве случаев \n", + "автоматический закрывается после исправления ошибок в каком линтере?\n", + "\n", + "Секция pydocstyle автоматически закрывается когда закрыты ошибки по pylint\n", + "10:05-10:20\n", + "\n", + "21) Что такое описание модуля? Оно должно отражать информацию о том что находится в модуле?\n", + "Одно или несколько предложений, объясняющие суть этого модуля, должна быть \n", + "точка в конце предложений(я), а то будет ругаться pydocstyle. Писать в тройных кавычках \n", + "9:23-9:45\n", + "\n", + "21) С какой git команды начинается утро программиста?\n", + " git pull\n", + "\n", + "22) После внесения изменений в файлах, кнопка open in vs code пропадает в \n", + "кошке, как по другому открыть vs code из кошки?\n", + "Главный репозиторий -> ПКМ -> open in vscode\n", + "14:10-14:21\n", + "\n", + "23) Что такое stash? \n", + " Функция stash позволяет спрятать изменения пользователя в буфер обмена, \n", + " и принять изменения из репозитория на github\n", + "\n", + "23.1) Как сохранить стэш?\n", + " git командa: \n", + " git stash\n", + " Кнопка в \"кошке\":\n", + " \"Stash changes and continue\"\n", + "\n", + "23.2) Как восстановить стэш?:\n", + " В VScode:\n", + " Кнопка stashed changes либо же view stash -> restore\n", + " git команда?:\n", + " git stash save \"NUMBER_STASH\"\n", + " git stash apply \"NUMBER_STASH\"\n", + " Команда для терминала может сохранить стэш под определенным именем и \n", + " восстановить стэш в любой момент, а при нажатии discard в \"кошке\" данные удаляться безвозвратно\n", + "\n", + "23.3) Различие между стэшем и коммитом. \n", + " Когда лучше сохранить изменения в стэше, а когда коммитить.\n", + "\n", + "Как я понял, стэш позволяет отложить временные изменения в хранилище, \n", + "изменения которые еще не готовы быть закоммиченными\n", + "В то время как коммит это постоянное сохранение изменений в историю \n", + "репозитория, это создание точки к которой может понадобиться вернуться после\n", + "Формально можно сказать что для черновых изменений которые не \n", + "готовы для публикации подходит стэш, а для готовых и протестированных - коммит\n", + "\n", + "23.4) Как просмотреть список сохраненных стэшей? \n", + " git команда:\n", + " git stash list\n", + "\n", + "23.5) Как удалить стэш? \n", + " Команды для удаления отдельных стэшей или всех сразу.\n", + " git команда:\n", + " git stash pop [] - применяет стэш и удаляет его из списка \n", + " сохраненных стэшэй, думаю можно засчитать за команду для удаления\n", + "\n", + " git stash drop [] - позволяет удалить конкретный элемента из списка сохраненных стэшэй не трогая остальные\n", + "\n", + " git stash clear - очищает список сохраненных стэшэй, полное удаление\n", + "\n", + "23.6) Практические примеры использования стэша. \n", + " Краткие сценарии, где стэш помогает.\n", + "Необходимость сделать pull при неготовых для коммита изменениях в файле\n", + "Возможно какие-то эксперименты, в которых пользователь не уверен, но хочет из сохранить\n", + "Проверка кода на ошибки, как вариант, допустим спрятать часть кода в стэш и затем запустить линтеры \n", + "\n", + "24) Где посмотреть что есть конфликт в файлах? \n", + "В \"кошке\" вылезет ошибка\n", + "24.1) Когда он появляется?\n", + "Когда мы принимаем изменения из удаленного репозитория и эти изменения \n", + "содержатся в файлах измененных пользователем, изменение на изменение накладывается в общем\n", + "\n", + "25) Как решить конфликт в файлах?\n", + "Гит не понимает какие изменения нужно оставить, нужно выбрать какое \n", + "изменение оставить, с локального или удаленного репозитория, пути решения в п.28\n", + "\n", + "26) Напишите правильное утверждение\n", + "-Зелёное то что пришло с гитхаба и синее локальные изменения \n", + "16:30-16:39\n", + "\n", + "27) Если мы работаем в одном файле, можно ли принять pull после того как вы спрячете в стэш свои изменения? \n", + "Да, потому что в случае если мы \"спрячем\" наши изменения - файл вернется \n", + "к исходному состоянию и можно будет без проблем принять pull из удаленного репозитория\n", + "\n", + "27.1) Что может произойти когда stash восстановите после принятия pull?\n", + "В случае изменений в разных частях кода - гит применит изменения из стэша без проблем\n", + "\n", + "При изменении одинаковых строк будет предложено решить конфликт вручную\n", + "\n", + "(В этом случае стэш не удалится, даже если вызывался \n", + "через git stash pop и нужно будет удалить его вручную если нужно)\n", + "\n", + "Возможно так же частичное применение стэша если файл переименовали или удалили\n", + "\n", + "28) Сколько способов решения конфликтов было показано в видео? Напишите ЧИСЛО и укажите их способы.\n", + "4\n", + "Accept current change - принятие изменений который пришли с гитхаба(чаще всего)\n", + "Accept incoming change - принятие локальных изменений, вместо изменений с гитхаба(нежелательно)\n", + "Accept both change - принять оба изменения\n", + "Устранение конфликта вручную - resolve in merge editor -> complete merge\n", + "16:40-17:46\n", + "\n", + "29) Что делает кнопка complete merge?\n", + "Кнопка принимает изменения выполненные выбранным способом решения конфликта\n", + "17:36-17:50\n", + "\n", + "30) В какой чат нужно писать если остались вопросы?\n", + "Чат \"HELP ME\" в тг\n", + "18:30-18:39\n", + "\n", + "31) Что такое FORK? Зачем его делают? \n", + "FORK позволяет скопировать репозиторий и сделать его личным\n", + "18:58-19:15\n", + "Его также можно рассматривать как внешнюю ветку для текущего репозитория\n", + "из курса на степике\n", + "\n", + "32) Как скачать форкнутый репозиторий на локальный компьютер?\n", + "Из github desktop заходим в главный репозиторий, нажимаем ПКМ на \"add\" -> \n", + "clone repository -> \n", + "выбираем репозиторий из списка -> \n", + "clone\n", + "19:32-20:00\n", + "\n", + "33) С какой вероятностью ваши ошибки были уже решены? и кто их решил?\n", + "С вероятностью 90% эти ошибки решены преподавателем и другими студентами\n", + "12:48-13:00\n", + "\n", + "34) Как создать файл в vs code?\n", + "ПКМ в поле Explorer -> new file либо же по кнопке \"new file\" при наведении на корневую папку проекта\n", + "\n", + "35) Файл лога нужно заполнять в конце каждого урока?\n", + "Нет, файл лога заполняется единожды при начале обучения\n", + "\n", + "==================\n", + "\n", + "Дополнительные вопросы:\n", + "1) Какая команда конвертирует файл в py из ipynb? \n", + "\"jupytext --to py *.ipynb\", предварительно \"pip install jupytext\"\n", + "\n", + "2) Что такое пакетный менеджер? Вы пользуетесь пакетным менеджером conda или pip? \n", + "Какой лучше использовать для дата сайнс?\n", + "\n", + "Пакетный менеджер — это инструмент для установки, \n", + "обновления и управления библиотеками и зависимостями в проекте.\n", + "\n", + "Чаще в уроках я пользуюсь pip\n", + "\n", + "Для Data Science лучше использовать conda — он управляет Python-пакетами и системными зависимостями.\n", + "Поддерживает изолированные окружения и хорошо работает с научными библиотеками типа numpy, pandas.\n", + "\n", + "3) Почему расширение py лучше чем ipynb?\n", + ".py легче запускать, версионировать в Git, интегрировать в системы.\n", + "Меньше накладных расходов, чище код, лучше поддержка IDE и линтеров.\n", + ".ipynb удобен для исследований и визуализаций — .py для финального кода.\n", + "\n", + "4) Что такое pep8? \n", + "pep8 - официальное руководство по стилю написания кода Python\n", + "\n", + "4.1) линтеры проверяют на соблюдение pep8?\n", + "Да, например flake8 или pylint проверяют код на соответствие рекомендациям pep8\n", + "\n", + "4.2) Какая нотация используется для создания переменных? \n", + "нотация snake_case - слова через нижнее подчёркивание, всё в нижнем регистре(например melon_count)\n", + "\n", + "Вместе с тем\n", + "\n", + "1. Имена классов необходимо записывать в схеме Pascal.\n", + "2. Имена констант следует записывать в верхнем змеином регистре.\n", + "3. Имена функций, методов и переменных записывают в нижнем змеином регистре.\n", + "\n", + "4.3) Может ли переменная состоять из одной буквы например андерскор \"_\" ?\n", + "Да, согласно pep8 это допустимо\n", + "\n", + "4.4) Зачем и где мы используем андерскор _\n", + "Временная переменная, к которой не нужно будет возвращаться\n", + "Результат последнего исполнения операции\n", + "Приватные атрибуты классов всегда начинают с символа подчеркивания _var\n", + "\n", + "4.5) По PEP8 допустима переменная в одну букву?\n", + "\n", + "Допустима, но не рекомендована\n", + "Допустима в случаях:\n", + "- Имя i часто используется с переменными циклов for, перебирающих диапазоны чисел или индексов списка\n", + "- j и k (следующие за i в алфавитном порядке) используются с вложенными циклами\n", + "- использование x и y для декартовых координат" + ] + }, + { + "cell_type": "markdown", + "id": "4ae536c1", + "metadata": {}, + "source": [ + "quiz2\n", + "\n", + "1. Как включить автосохранение данных в VSCODE?\n", + "В окне VSCODE, File -> Auto Save\n", + "0:09-0-14\n", + "\n", + "2. Как настроить перенос строки? \n", + "В окне VSCODE, File -> Preferences -> Settings -> пишем \"wrap\" -> wordWrapColumn -> \n", + "79 -> сохраняемся -> нажимаем Enter или просто закрываем окно\n", + "0:14-0:40\n", + "\n", + "3. Сколько символов по pep8 разрешено на строке?\n", + "79 символов\n", + "0:31-0:34\n", + "Для строк с комментариями и документацией — 72 символа\n", + "\n", + "4. Какие способы переноса строк показаны в видео:\n", + "-Использование круглых скобок для продолжения строки(4.4)\n", + " Тем самым улучшается удобочитаемость кода\n", + " 2:25-2:45\n", + "-Сложение строк с помощью +(4.6)\n", + " Части строк записываются в отдельные переменные и \n", + " затем складываются в переменной для вывода\n", + " 2:52-4:28\n", + "\n", + "4.1 Строки с использованием обратного слэша (\\)\n", + "\n", + "string_continued = \"This is a long string that we want to \" \\\n", + " \"split across multiple lines.\"\n", + "print(string_continued)\n", + "\n", + "4.2 Тройные кавычки (''' или \"\"\") \n", + "\n", + "multi_line_string = \"\"\"This is a string that spans\n", + "multiple lines. You can write freely\n", + "and it will keep the line breaks.\"\"\"\n", + "print(multi_line_string)\n", + "\n", + "4.3 Создание списка строк и объединение с помощью join\n", + "\n", + "strings = [\n", + " \"This is the first line.\",\n", + " \"This is the second line.\",\n", + " \"This is the third line.\"\n", + "]\n", + "result = \"\\n\".join(strings) # Используем перенос строк '\\n'\n", + "print(result)\n", + "\n", + "4.4 Использование круглых скобок для продолжения строки\n", + "long_string = (\n", + " \"This is a very long string that I would like to \"\n", + " \"continue on the next line.\"\n", + ")\n", + "print(long_string)\n", + "\n", + "4.5 Форматированные строки (f-строки) с использованием скобок\n", + "letter_a = 5\n", + "letter_b = 6\n", + "product_ab = letter_a * letter_b\n", + "\n", + "message = (\n", + " f\"when {letter_a} is multiplied by {letter_b}, \"\n", + " f\"the result is {product_ab}\"\n", + ")\n", + "print(message)\n", + "\n", + "4.6 Сложение строк с помощью +\n", + "\n", + "string_part1 = \"This is the first part, \"\n", + "string_part2 = \"and this is the second part.\"\n", + "full_string = string_part1 + string_part2\n", + "print(full_string)\n", + "\n", + "5. Проверка на ошибки c помощью кнопки problems, где она находится?\n", + "В нижней панели VScode слева от вкладки terminal\n", + "4:40-6:14\n", + "\n", + "6. Где в vscode находится клиент гита? как в нём отправить коммит? как принять домашку?\n", + "Клиент гита находится в vscode в панели слева(три кружочка).\n", + "\n", + "Во вкладке source control отображается список изменений, мы можем дать \n", + "название коммиту и выбрав в боковой панели кнопки \"Commit\" commit and push, отправить коммит\n", + "\n", + "Домашка принимается нажатием в секции source control repositories трех точек и далее pull\n", + "6:23-6:48\n", + "\n", + "7. Что такое GIT? он локальный? \n", + "В нём можно посмотреть историю изменений файлов и вернуться к любому коммиту?\n", + "\n", + "GIT - система контроля версий\n", + "GIT позволяет работать как локально, так и с удаленными репозиториями\n", + "В нем можно как посмотреть историю изменений файлов так и вернуться к прошлым изменениям, коммитам\n", + "В нижней панели vscode есть панель gitlens в ней можно удобно смотреть историю коммитов\n", + "6:53-7:32\n", + "\n", + "8. Как вставить картинку в маркдаун? \n", + "Сохранить картинку в буфер обмена и нажать ctrl+v, нажав предварительно на ячейку\n", + "7:59-8:04\n", + "\n", + "9. Где посмотреть длину строки в vs code?\n", + "10. Как поменять тип ячейки с питона на маркдаун?\n", + "Кнопка в нижнем правом углу ячейки, кликнуть на python или markdown, \n", + "в зависимости от того какого типа ячейка сейчас\n", + "7:42-7:50\n", + "\n", + "11. Как запустить сразу все ячейки в юпитере?\n", + "Кнопка \"run all\" в верхней панели vscode под окном с названием файла\n", + "8:27-8:34\n", + "\n", + "12. Как изменить размер картинки в юпитере? Нужно для этого знать HTML?\n", + "Чтобы регулировать размер картинки нужно вставить ее в тэг \n", + "HTML для этого придется подучить \n", + "8:08-8:26\n", + "\n", + "13. Какой хоткей чтобы запустить ячейку с смещением на следующую?\n", + "shift + enter\n", + "8:39-8:51\n", + "\n", + "14. Как включить отображение номеров строк в юпитере(Cell line numbers)?\n", + "Нажимаем на три точки находясь в ячейке и выбираем Show cell lines ИЛИ хоткей \"L\"\n", + "9:00-9:11\n", + "\n", + "15. Что такое \"Go To\" чем это полезно? Как перейти сразу на ошибочную ячейку?\n", + "To Go позволяет нажатием на нее увидеть в какой ячейке произошла ошибка, она отвалилась\n", + "При нажатии на Go To автоматически перебросит на ячейку с ошибкой\n", + "9:25-10:00\n", + "\n", + "16. Как очистить вывод ячеек которые уже запущены?\n", + "Кнопка \"Clear all outputs\", в той же менюшке что и \"Run all\"\n", + "10:46-10:54\n", + "\n", + "17. Как работать одновременно в нескольких файлах в VSCODE? Что такое SPLIT?\n", + "Работать одновременно в нескольких файлах в VSCODE можно с помощью команды Split editor right (ctrl+\\\\)\n", + "Split позволяет разделить рабочую область на несколько частей, делить можно вертикально или горизонтально\n", + "10:55-11:10\n", + "\n", + "18. Каким сочетанием убирается левый сайдбар?\n", + "Ctrl + b либо нажатием на активное окно\n", + "11:20-11:27\n", + "\n", + "19. Кнопка два листочка это наши локальные файлы?\n", + "Да, нажав на эту вкладку нас перекинет в локальные файлы\n", + "11:33-11:36\n", + "\n", + "20. Какая ошибка появилась в трассировке при запуске всех ячеек DICT или LIST?\n", + "DICT - NameError: name \"Dict is not defined\n", + "10:17-10:22\n", + "\n", + "21. Вы ознакомились с https://t.me/c/1937296927/832/19307? и \n", + "https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?\n", + ">**Да**\n", + "\n", + "22. Что такое валидация?\n", + "Валидация — это проверка данных на корректность и соответствие заданным правилам\n", + "9:48-10:00\n", + "\n", + "23. Что такое трассировка ошибки?\n", + "Трассировка - визуализация ошибки(Traceback), показывает где и в каком порядке возникли ошибки в программе\n", + "10:00-10:12\n", + "\n", + "24. Что значит отвалился интерпритатор?\n", + "Значит интерпритатор аварийно завершил работу или перестал отвечать, обычно из-за ошибки в коде\n", + "9:55-10:00" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/quiz.py b/quiz.py new file mode 100644 index 00000000..de60427f --- /dev/null +++ b/quiz.py @@ -0,0 +1,474 @@ +"""quiz.""" + +# quiz1 +# +# 1) Как понять, что домашка пришла? +# меня тегнут в чате HomeWork, формат "@мой_ник прими пул" +# 0:10-0:17 +# +# 2) Как принять домашку? +# github desktop -> pull origin -> fetch origin +# +# 3) Зачем нужна кнопка history и какие функции появляются +# при нажатии правой кнопки мыши на коммит? +# В ней находится история коммитов, сверху вниз по новизне +# 0:30-0:43 +# По нажатию ПКМ даются функции: amend, reset to, checkout, reorder revert changes... commit. +# А так же посмотреть коммит на гитхабе чтобы взять на него ссылку +# 3:47-3:50 +# +# 3.1) Где брать ссылку на коммит? куда её отправлять? +# Коммит - локальная фиксация изменений +# Ссылка на коммит по нажатию ПКМ -> View on github. +# Отправляем в чат тг Homework с подписью "Коммит отдал" +# 3:50-4:30 +# +# 4) Что такое файл лога? +# Файл формата ipynb(markdown) который нужно заполнять +# в конце урока(дата и что узнал в течение урока по пунктам), +# как сказано в видео, по факту он создается единожды, для прогона линтеров +# 1:10-2:16 +# +# 4.1) Когда нужно его пушить? +# Как я понял, после выполнения домашней работы вместе с файлом домашки, +# либо же после окончания урока в случае если параллельно заполнялся лог +# 3:10-3:14 +# +# 5) Что такое интерпритатор? +# Программа которая читает и запускает записанный пользователем код +# 2:44-2:51 +# +# 6) Где можно выбрать интерпритатор? +# При запуске ячейки в ноутбуке предоставляется возможность +# выбора интерпретатора в поле для ввода +# +# в верхней части VSCODE далее select another kernel -> python environments -> ...\anaconda\... +# +# Либо по кнопке справа от ячейки в ноутбуке +# 2:51-3:06 +# +# 7) Что такое модуль? +# Файл с расширением .py или .ipynb +# 8:47-8:51 +# +# 8) Как создать и отправить коммит? +# После изменения файлов эти изменения отобразятся в github desktop, записываем summary и +# description для этого коммита и жмем Commit to main -> push origin +# 3:25-3:40 +# +# 9) Как посмотреть что коммит точно отправлен и находится в github? +# Коммит точно отправлен если есть возможность взять на него ссылку с github, +# а также он отобразиться во вкладке history на github desktop +# 3:46-4:00 +# +# 10) Какая команда показывает что код не прошёл проверки на ошибки? +# pre-commit run --all-files +# 6:03-6:15 +# +# 10.1) Напишите список линтеров которые используются +# для проверки кода и дайте их краткую характеристику. +# +# pylint - линтер который проверяет код на синтаксические и другие ошибки +# black - позволяет писать код согласно стандарту pep8, соблюдая все отступы, +# пробелы и т.д. Сам переформатирует отступы, пробелы автоматически по стандарту PEP8 +# mypy - позволяет проверять аннотацию типов (псевдостатическая типизация) +# из курса на степике +# +# 11) Как узнать какой именно линтер не прошёл проверку? +# После запуска команды "pre-commit run --all-files" в терминале будут отображаться линтеры и +# описание результата их работы, в том случае если результат работы неуспех - +# ниже показывается имя файла в котором произошла ошибка, +# номер ячейки, а также краткое описание ошибки +# 6:15-6:50 +# +# 12) Линтер Pylint видит markdown? +# Нет, из-за этого случаются расхождения в номерах ячеек в vscode и терминале +# 7:05-7:12 +# +# 13) Номер ячейки в терминале и номер ячейки в vs code может отличаться? в каком случае? +# Линтер не видит markdown +# Если ошибка в ячейке после markdown, то линтер укажет на ошибку в ячейке +# (номер ячейки в vscode - количество ячеек markdown до нее) +# 7:00-7:30 +# +# 14) Где посмотреть номер ячейки в vscode? +# Внизу справа в окне vscode, "cell (сколько-то) of (сколько-то)" +# 6:41-6:53 +# +# 15) В каком формате ipynb отправляется в гитхаб? причём здесь JSON? +# Файлы ipynb отправляются на гитхаб в формате JSON +# 3:19-3:25 из видео +# +# JSON, это стандартный текстовый формат для представления структурированных данных, +# основанный на синтаксисе объектов JavaScript. +# Так веб-приложения и не только, обмениваются данными, в таком формате. +# из курса на степике +# +# 16) Где посмотреть в какой ячейке ошибка? +# В информации после прогона линтеров, будет указано - файл:номер ячейки:код ошибки:краткое описание +# 6:31-6:50 +# +# 17) Как запустить терминал? +# Кнопка "terminal" в верхней панели VSCODE, +# нажимаем на нее и далее "new terminal", либо сочетание ctrl+shift+' +# 5:55-6:00 +# +# 18) Что такое линтер? +# Программа которая проверяет файл на корректность, насколько код соответствует стандартам +# 6:06-6:20 +# +# 19) В какой сайт нужно вставлять код ошибки если ошибка связана с pylint? +# https://pylint.pycqa.org/en/latest/index.html +# 8:15-8:50 +# +# 20) Секция pydocstyle в большинстве случаев +# автоматический закрывается после исправления ошибок в каком линтере? +# +# Секция pydocstyle автоматически закрывается когда закрыты ошибки по pylint +# 10:05-10:20 +# +# 21) Что такое описание модуля? Оно должно отражать информацию о том что находится в модуле? +# Одно или несколько предложений, объясняющие суть этого модуля, должна быть +# точка в конце предложений(я), а то будет ругаться pydocstyle. Писать в тройных кавычках +# 9:23-9:45 +# +# 21) С какой git команды начинается утро программиста? +# git pull +# +# 22) После внесения изменений в файлах, кнопка open in vs code пропадает в +# кошке, как по другому открыть vs code из кошки? +# Главный репозиторий -> ПКМ -> open in vscode +# 14:10-14:21 +# +# 23) Что такое stash? +# Функция stash позволяет спрятать изменения пользователя в буфер обмена, +# и принять изменения из репозитория на github +# +# 23.1) Как сохранить стэш? +# git командa: +# git stash +# Кнопка в "кошке": +# "Stash changes and continue" +# +# 23.2) Как восстановить стэш?: +# В VScode: +# Кнопка stashed changes либо же view stash -> restore +# git команда?: +# git stash save "NUMBER_STASH" +# git stash apply "NUMBER_STASH" +# Команда для терминала может сохранить стэш под определенным именем и +# восстановить стэш в любой момент, а при нажатии discard в "кошке" данные удаляться безвозвратно +# +# 23.3) Различие между стэшем и коммитом. +# Когда лучше сохранить изменения в стэше, а когда коммитить. +# +# Как я понял, стэш позволяет отложить временные изменения в хранилище, +# изменения которые еще не готовы быть закоммиченными +# В то время как коммит это постоянное сохранение изменений в историю +# репозитория, это создание точки к которой может понадобиться вернуться после +# Формально можно сказать что для черновых изменений которые не +# готовы для публикации подходит стэш, а для готовых и протестированных - коммит +# +# 23.4) Как просмотреть список сохраненных стэшей? +# git команда: +# git stash list +# +# 23.5) Как удалить стэш? +# Команды для удаления отдельных стэшей или всех сразу. +# git команда: +# git stash pop [] - применяет стэш и удаляет его из списка +# сохраненных стэшэй, думаю можно засчитать за команду для удаления +# +# git stash drop [] - позволяет удалить конкретный элемента из списка сохраненных стэшэй не трогая остальные +# +# git stash clear - очищает список сохраненных стэшэй, полное удаление +# +# 23.6) Практические примеры использования стэша. +# Краткие сценарии, где стэш помогает. +# Необходимость сделать pull при неготовых для коммита изменениях в файле +# Возможно какие-то эксперименты, в которых пользователь не уверен, но хочет из сохранить +# Проверка кода на ошибки, как вариант, допустим спрятать часть кода в стэш и затем запустить линтеры +# +# 24) Где посмотреть что есть конфликт в файлах? +# В "кошке" вылезет ошибка +# 24.1) Когда он появляется? +# Когда мы принимаем изменения из удаленного репозитория и эти изменения +# содержатся в файлах измененных пользователем, изменение на изменение накладывается в общем +# +# 25) Как решить конфликт в файлах? +# Гит не понимает какие изменения нужно оставить, нужно выбрать какое +# изменение оставить, с локального или удаленного репозитория, пути решения в п.28 +# +# 26) Напишите правильное утверждение +# -Зелёное то что пришло с гитхаба и синее локальные изменения +# 16:30-16:39 +# +# 27) Если мы работаем в одном файле, можно ли принять pull после того как вы спрячете в стэш свои изменения? +# Да, потому что в случае если мы "спрячем" наши изменения - файл вернется +# к исходному состоянию и можно будет без проблем принять pull из удаленного репозитория +# +# 27.1) Что может произойти когда stash восстановите после принятия pull? +# В случае изменений в разных частях кода - гит применит изменения из стэша без проблем +# +# При изменении одинаковых строк будет предложено решить конфликт вручную +# +# (В этом случае стэш не удалится, даже если вызывался +# через git stash pop и нужно будет удалить его вручную если нужно) +# +# Возможно так же частичное применение стэша если файл переименовали или удалили +# +# 28) Сколько способов решения конфликтов было показано в видео? Напишите ЧИСЛО и укажите их способы. +# 4 +# Accept current change - принятие изменений который пришли с гитхаба(чаще всего) +# Accept incoming change - принятие локальных изменений, вместо изменений с гитхаба(нежелательно) +# Accept both change - принять оба изменения +# Устранение конфликта вручную - resolve in merge editor -> complete merge +# 16:40-17:46 +# +# 29) Что делает кнопка complete merge? +# Кнопка принимает изменения выполненные выбранным способом решения конфликта +# 17:36-17:50 +# +# 30) В какой чат нужно писать если остались вопросы? +# Чат "HELP ME" в тг +# 18:30-18:39 +# +# 31) Что такое FORK? Зачем его делают? +# FORK позволяет скопировать репозиторий и сделать его личным +# 18:58-19:15 +# Его также можно рассматривать как внешнюю ветку для текущего репозитория +# из курса на степике +# +# 32) Как скачать форкнутый репозиторий на локальный компьютер? +# Из github desktop заходим в главный репозиторий, нажимаем ПКМ на "add" -> +# clone repository -> +# выбираем репозиторий из списка -> +# clone +# 19:32-20:00 +# +# 33) С какой вероятностью ваши ошибки были уже решены? и кто их решил? +# С вероятностью 90% эти ошибки решены преподавателем и другими студентами +# 12:48-13:00 +# +# 34) Как создать файл в vs code? +# ПКМ в поле Explorer -> new file либо же по кнопке "new file" при наведении на корневую папку проекта +# +# 35) Файл лога нужно заполнять в конце каждого урока? +# Нет, файл лога заполняется единожды при начале обучения +# +# ================== +# +# Дополнительные вопросы: +# 1) Какая команда конвертирует файл в py из ipynb? +# "jupytext --to py *.ipynb", предварительно "pip install jupytext" +# +# 2) Что такое пакетный менеджер? Вы пользуетесь пакетным менеджером conda или pip? +# Какой лучше использовать для дата сайнс? +# +# Пакетный менеджер — это инструмент для установки, +# обновления и управления библиотеками и зависимостями в проекте. +# +# Чаще в уроках я пользуюсь pip +# +# Для Data Science лучше использовать conda — он управляет Python-пакетами и системными зависимостями. +# Поддерживает изолированные окружения и хорошо работает с научными библиотеками типа numpy, pandas. +# +# 3) Почему расширение py лучше чем ipynb? +# .py легче запускать, версионировать в Git, интегрировать в системы. +# Меньше накладных расходов, чище код, лучше поддержка IDE и линтеров. +# .ipynb удобен для исследований и визуализаций — .py для финального кода. +# +# 4) Что такое pep8? +# pep8 - официальное руководство по стилю написания кода Python +# +# 4.1) линтеры проверяют на соблюдение pep8? +# Да, например flake8 или pylint проверяют код на соответствие рекомендациям pep8 +# +# 4.2) Какая нотация используется для создания переменных? +# нотация snake_case - слова через нижнее подчёркивание, всё в нижнем регистре(например melon_count) +# +# Вместе с тем +# +# 1. Имена классов необходимо записывать в схеме Pascal. +# 2. Имена констант следует записывать в верхнем змеином регистре. +# 3. Имена функций, методов и переменных записывают в нижнем змеином регистре. +# +# 4.3) Может ли переменная состоять из одной буквы например андерскор "_" ? +# Да, согласно pep8 это допустимо +# +# 4.4) Зачем и где мы используем андерскор _ +# Временная переменная, к которой не нужно будет возвращаться +# Результат последнего исполнения операции +# Приватные атрибуты классов всегда начинают с символа подчеркивания _var +# +# 4.5) По PEP8 допустима переменная в одну букву? +# +# Допустима, но не рекомендована +# Допустима в случаях: +# - Имя i часто используется с переменными циклов for, перебирающих диапазоны чисел или индексов списка +# - j и k (следующие за i в алфавитном порядке) используются с вложенными циклами +# - использование x и y для декартовых координат + +# quiz2 +# +# 1. Как включить автосохранение данных в VSCODE? +# В окне VSCODE, File -> Auto Save +# 0:09-0-14 +# +# 2. Как настроить перенос строки? +# В окне VSCODE, File -> Preferences -> Settings -> пишем "wrap" -> wordWrapColumn -> +# 79 -> сохраняемся -> нажимаем Enter или просто закрываем окно +# 0:14-0:40 +# +# 3. Сколько символов по pep8 разрешено на строке? +# 79 символов +# 0:31-0:34 +# Для строк с комментариями и документацией — 72 символа +# +# 4. Какие способы переноса строк показаны в видео: +# -Использование круглых скобок для продолжения строки(4.4) +# Тем самым улучшается удобочитаемость кода +# 2:25-2:45 +# -Сложение строк с помощью +(4.6) +# Части строк записываются в отдельные переменные и +# затем складываются в переменной для вывода +# 2:52-4:28 +# +# 4.1 Строки с использованием обратного слэша (\) +# +# string_continued = "This is a long string that we want to " \ +# "split across multiple lines." +# print(string_continued) +# +# 4.2 Тройные кавычки (''' или """) +# +# multi_line_string = """This is a string that spans +# multiple lines. You can write freely +# and it will keep the line breaks.""" +# print(multi_line_string) +# +# 4.3 Создание списка строк и объединение с помощью join +# +# strings = [ +# "This is the first line.", +# "This is the second line.", +# "This is the third line." +# ] +# result = "\n".join(strings) # Используем перенос строк '\n' +# print(result) +# +# 4.4 Использование круглых скобок для продолжения строки +# long_string = ( +# "This is a very long string that I would like to " +# "continue on the next line." +# ) +# print(long_string) +# +# 4.5 Форматированные строки (f-строки) с использованием скобок +# letter_a = 5 +# letter_b = 6 +# product_ab = letter_a * letter_b +# +# message = ( +# f"when {letter_a} is multiplied by {letter_b}, " +# f"the result is {product_ab}" +# ) +# print(message) +# +# 4.6 Сложение строк с помощью + +# +# string_part1 = "This is the first part, " +# string_part2 = "and this is the second part." +# full_string = string_part1 + string_part2 +# print(full_string) +# +# 5. Проверка на ошибки c помощью кнопки problems, где она находится? +# В нижней панели VScode слева от вкладки terminal +# 4:40-6:14 +# +# 6. Где в vscode находится клиент гита? как в нём отправить коммит? как принять домашку? +# Клиент гита находится в vscode в панели слева(три кружочка). +# +# Во вкладке source control отображается список изменений, мы можем дать +# название коммиту и выбрав в боковой панели кнопки "Commit" commit and push, отправить коммит +# +# Домашка принимается нажатием в секции source control repositories трех точек и далее pull +# 6:23-6:48 +# +# 7. Что такое GIT? он локальный? +# В нём можно посмотреть историю изменений файлов и вернуться к любому коммиту? +# +# GIT - система контроля версий +# GIT позволяет работать как локально, так и с удаленными репозиториями +# В нем можно как посмотреть историю изменений файлов так и вернуться к прошлым изменениям, коммитам +# В нижней панели vscode есть панель gitlens в ней можно удобно смотреть историю коммитов +# 6:53-7:32 +# +# 8. Как вставить картинку в маркдаун? +# Сохранить картинку в буфер обмена и нажать ctrl+v, нажав предварительно на ячейку +# 7:59-8:04 +# +# 9. Где посмотреть длину строки в vs code? +# 10. Как поменять тип ячейки с питона на маркдаун? +# Кнопка в нижнем правом углу ячейки, кликнуть на python или markdown, +# в зависимости от того какого типа ячейка сейчас +# 7:42-7:50 +# +# 11. Как запустить сразу все ячейки в юпитере? +# Кнопка "run all" в верхней панели vscode под окном с названием файла +# 8:27-8:34 +# +# 12. Как изменить размер картинки в юпитере? Нужно для этого знать HTML? +# Чтобы регулировать размер картинки нужно вставить ее в тэг +# HTML для этого придется подучить +# 8:08-8:26 +# +# 13. Какой хоткей чтобы запустить ячейку с смещением на следующую? +# shift + enter +# 8:39-8:51 +# +# 14. Как включить отображение номеров строк в юпитере(Cell line numbers)? +# Нажимаем на три точки находясь в ячейке и выбираем Show cell lines ИЛИ хоткей "L" +# 9:00-9:11 +# +# 15. Что такое "Go To" чем это полезно? Как перейти сразу на ошибочную ячейку? +# To Go позволяет нажатием на нее увидеть в какой ячейке произошла ошибка, она отвалилась +# При нажатии на Go To автоматически перебросит на ячейку с ошибкой +# 9:25-10:00 +# +# 16. Как очистить вывод ячеек которые уже запущены? +# Кнопка "Clear all outputs", в той же менюшке что и "Run all" +# 10:46-10:54 +# +# 17. Как работать одновременно в нескольких файлах в VSCODE? Что такое SPLIT? +# Работать одновременно в нескольких файлах в VSCODE можно с помощью команды Split editor right (ctrl+\\) +# Split позволяет разделить рабочую область на несколько частей, делить можно вертикально или горизонтально +# 10:55-11:10 +# +# 18. Каким сочетанием убирается левый сайдбар? +# Ctrl + b либо нажатием на активное окно +# 11:20-11:27 +# +# 19. Кнопка два листочка это наши локальные файлы? +# Да, нажав на эту вкладку нас перекинет в локальные файлы +# 11:33-11:36 +# +# 20. Какая ошибка появилась в трассировке при запуске всех ячеек DICT или LIST? +# DICT - NameError: name "Dict is not defined +# 10:17-10:22 +# +# 21. Вы ознакомились с https://t.me/c/1937296927/832/19307? и +# https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet? +# >**Да** +# +# 22. Что такое валидация? +# Валидация — это проверка данных на корректность и соответствие заданным правилам +# 9:48-10:00 +# +# 23. Что такое трассировка ошибки? +# Трассировка - визуализация ошибки(Traceback), показывает где и в каком порядке возникли ошибки в программе +# 10:00-10:12 +# +# 24. Что значит отвалился интерпритатор? +# Значит интерпритатор аварийно завершил работу или перестал отвечать, обычно из-за ошибки в коде +# 9:55-10:00 From b9676302d94ecf78d58b471b6fca45e7c6a8dfc5 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 17 Sep 2025 00:51:52 +0300 Subject: [PATCH 03/24] delete log.ipynb and log.py --- log.ipynb | 48 ------------------------------------------------ log.py | 10 ---------- 2 files changed, 58 deletions(-) delete mode 100644 log.ipynb delete mode 100644 log.py diff --git a/log.ipynb b/log.ipynb deleted file mode 100644 index cd9fec9d..00000000 --- a/log.ipynb +++ /dev/null @@ -1,48 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "c2a61223", - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"Документ для логирования знаний полученных на уроках.\"\"\"" - ] - }, - { - "cell_type": "markdown", - "id": "6bb24181", - "metadata": {}, - "source": [ - "06.09\n", - "\n", - "1) Узнал как устанавливать приложения из исходников с github\n", - "2) Установил cpython из исходников" - ] - }, - { - "cell_type": "markdown", - "id": "3627f778", - "metadata": {}, - "source": [ - "08.09\n", - "\n", - "1) Понял что не нужно ничего додумывать и строго соблюдать регламент" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "base", - "language": "python", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "3.13.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/log.py b/log.py deleted file mode 100644 index 8471b727..00000000 --- a/log.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Документ для логирования знаний полученных на уроках.""" - -# 06.09 -# -# 1) Узнал как устанавливать приложения из исходников с github -# 2) Установил cpython из исходников - -# 08.09 -# -# 1) Понял что не нужно ничего додумывать и строго соблюдать регламент From efe522e939c1d282b9d43f8c0574fc4322c2cb2b Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 17 Sep 2025 01:11:57 +0300 Subject: [PATCH 04/24] fix: correct floating-point rounding From 68f9387e729de7b668354b48e9c328abdd55bae5 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 17 Sep 2025 01:15:29 +0300 Subject: [PATCH 05/24] feat: add generateReport function From efd619825fefe792baabebb89abded8d15d0c272 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 17 Sep 2025 01:17:04 +0300 Subject: [PATCH 06/24] style: corrected indentation and formatting throughout the project From 169fc4fd6305838bc74614a38c248e8d9758659d Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 17 Sep 2025 01:18:55 +0300 Subject: [PATCH 07/24] docs: improved documentation for generateReport From d9f9dfd4afdaca2f4b8058bdc27eaca9c5a04482 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 17 Sep 2025 01:19:05 +0300 Subject: [PATCH 08/24] test: added tests for generateReport From e330460ad74e2d62e0487ad640ac77414a992de3 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 17 Sep 2025 01:26:45 +0300 Subject: [PATCH 09/24] [TASK] Commits (https://github.com/SENATOROVAI/intro-cs/issues/5) closes https://github.com/SENATOROVAI/intro-cs/issues/5 --- python/commits.ipynb | 108 +++++++++++++++++++++++++++++++++++++++++++ python/commits.py | 58 +++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 python/commits.ipynb create mode 100644 python/commits.py diff --git a/python/commits.ipynb b/python/commits.ipynb new file mode 100644 index 00000000..ba7e70ae --- /dev/null +++ b/python/commits.ipynb @@ -0,0 +1,108 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "1c48512d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'commit issue'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"commit issue.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "d614fe62", + "metadata": {}, + "source": [ + "1. Опишите своими словами назначение каждого из этих типов коммитов:\n", + "feat, fix, docs, style, refactor, test, build, ci, perf, chore.\n", + "\n", + "feat - добавление новой функции, поведения, расширение старого функционала новыми фичами\n", + "\n", + "fix - исправление ошибок, починка функционала и тп.\n", + "\n", + "docs - работа с документацией. README, LICENSE и тп.\n", + "\n", + "style - изменение стиля кода, без изменения его поведения, \n", + "пробелы, отступы, порядок импортов и тп.\n", + "\n", + "refactor - изменение кода, для улучшения его структуры, \n", + "читаемости, поддерживаемости(без исправления багов и фич).\n", + "\n", + "test - добавление, обновление, исправление тестов. Без изменения кода приложения\n", + "\n", + "build - изменения в сборке проекта, инструменты, зависимости и тп.\n", + "\n", + "ci - изменение в конфигурации ci/cd. Как github actions \n", + "\n", + "perf - оптимизация кода для улучшения производительности\n", + "(скорости, потребления памяти, времени отклика и тп.). Не меняя функционал\n", + "\n", + "chore - уборка, рутина, не связанная с функционалом, как, например, изменить .gitignore\n", + "\n", + "2. Представьте, что вы исправили баг в функции, которая некорректно округляет числа. \n", + "Сделайте фиктивный коммит и напишите для него сообщение в соответствии \n", + "с Conventional Commits (используя тип fix).\n", + "\n", + "`git commit --allow-empty -m 'fix: correct floating-point rounding'`\n", + "\n", + "3. Добавление новой функциональности:\n", + "Допустим, вы реализовали новую функцию generateReport в проекте. \n", + "Сделайте фиктивный коммит с типом feat, отражающий добавление этой функциональности\n", + "\n", + "`git commit --allow-empty -m 'feat: add generateReport function'`\n", + "\n", + "4. Модификация формата кода или стилей:\n", + "Представьте, что вы поправили отступы и форматирование во всём проекте, \n", + "не меняя логики кода. Сделайте фиктивный коммит с типом style\n", + "\n", + "`git commit --allow-empty -m 'style: corrected indentation and formatting throughout the project'`\n", + "\n", + "5. Документация и тестирование:\n", + "\n", + " - Сделайте фиктивный коммит с типом docs, добавляющий \n", + " или улучшающий документацию для вашей новой функции.\n", + "\n", + "`git commit --allow-empty -m 'docs: improved documentation for generateReport'`\n", + "\n", + " - Сделайте фиктивный коммит с типом test, добавляющий тесты для этой же функции.\n", + "\n", + "`git commit --allow-empty -m 'test: added tests for generateReport'`\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python/commits.py b/python/commits.py new file mode 100644 index 00000000..9f712bb9 --- /dev/null +++ b/python/commits.py @@ -0,0 +1,58 @@ +"""Commit issue.""" + +# 1. Опишите своими словами назначение каждого из этих типов коммитов: +# feat, fix, docs, style, refactor, test, build, ci, perf, chore. +# +# feat - добавление новой функции, поведения, расширение старого функционала новыми фичами +# +# fix - исправление ошибок, починка функционала и тп. +# +# docs - работа с документацией. README, LICENSE и тп. +# +# style - изменение стиля кода, без изменения его поведения, +# пробелы, отступы, порядок импортов и тп. +# +# refactor - изменение кода, для улучшения его структуры, +# читаемости, поддерживаемости(без исправления багов и фич). +# +# test - добавление, обновление, исправление тестов. Без изменения кода приложения +# +# build - изменения в сборке проекта, инструменты, зависимости и тп. +# +# ci - изменение в конфигурации ci/cd. Как github actions +# +# perf - оптимизация кода для улучшения производительности +# (скорости, потребления памяти, времени отклика и тп.). Не меняя функционал +# +# chore - уборка, рутина, не связанная с функционалом, как, например, изменить .gitignore +# +# 2. Представьте, что вы исправили баг в функции, которая некорректно округляет числа. +# Сделайте фиктивный коммит и напишите для него сообщение в соответствии +# с Conventional Commits (используя тип fix). +# +# `git commit --allow-empty -m 'fix: correct floating-point rounding'` +# +# 3. Добавление новой функциональности: +# Допустим, вы реализовали новую функцию generateReport в проекте. +# Сделайте фиктивный коммит с типом feat, отражающий добавление этой функциональности +# +# `git commit --allow-empty -m 'feat: add generateReport function'` +# +# 4. Модификация формата кода или стилей: +# Представьте, что вы поправили отступы и форматирование во всём проекте, +# не меняя логики кода. Сделайте фиктивный коммит с типом style +# +# `git commit --allow-empty -m 'style: corrected indentation and formatting throughout the project'` +# +# 5. Документация и тестирование: +# +# - Сделайте фиктивный коммит с типом docs, добавляющий +# или улучшающий документацию для вашей новой функции. +# +# `git commit --allow-empty -m 'docs: improved documentation for generateReport'` +# +# - Сделайте фиктивный коммит с типом test, добавляющий тесты для этой же функции. +# +# `git commit --allow-empty -m 'test: added tests for generateReport'` +# +# From e1956bb0c256de86ae450f650f88f2089ec0ee72 Mon Sep 17 00:00:00 2001 From: Dayal Date: Thu, 18 Sep 2025 21:57:30 +0300 Subject: [PATCH 10/24] [TASK] STASH (https://github.com/SENATOROVAI/intro-cs/issues/3) Closes https://github.com/SENATOROVAI/intro-cs/issues/3 --- git/stash.ipynb | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 git/stash.ipynb diff --git a/git/stash.ipynb b/git/stash.ipynb new file mode 100644 index 00000000..1dc18daf --- /dev/null +++ b/git/stash.ipynb @@ -0,0 +1,130 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "04b03bdf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Stash issue.'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"Stash issue.\"\"\"" + ] + }, + { + "attachments": { + "Снимок экрана 2025-09-18 214627.png": { + "image/png": "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4nB326Jio7efiIjywqCbpkTbUFq/+x5iFAIRnWfaEzhSC2xzBN1121PGM6kcIktUSAy6iYgKb8qHl9P5pW1IH763VrN/ZoaIyKUxLjzuY74EigE3ERERzXzs6SYiIiI6T7Gnm4io8Bh0ExERERERERUIh5cTERERERERFQiDbiIiIiIiIqICYdBNREREREREVCAMuomIiIiIiIgKhEE3ERERERERUYEw6CYiIiIiIiIqEAbdRERERERERAXCoJuIiIiIiIioQBh0ExERERERERUIg24iIiIiIiKiAmHQTURERERERFQgDLqJiIiIiIiICoRBNxEREREREVGBMOgmIiIiIiIiKhAG3UREREREREQFwqCbiIiIiIiIqEAYdBMREREREREVCINuIiIiIiIiogJh0E1ERERERERUIAy6iYiIiIiIiAqEQTcRERERERFRgTDoJiIiIiIiIioQBt1EREREREREBcKgm4iIiIiIiKhAGHQTERERERERFQiDbiIiIiIiIqICYdBNREREREREVCAMuomIiIiIiIgKhEE3ERERERERUYEw6CYiIiIiIiIqEAbdRERERERERAXCoJuIiIiIiIioQBh0ExERERERERUIg24iIiIiIiKiAmHQTURERERERFQgDLqJiIiIiIiICoRBNxEREREREVGBMOgmIiIiIiIiKhAG3UREREREREQFwqCbiIiIiIiIqEAYdBMREREREREVCINuIiIiIiIiogJh0E1ERERERERUIAy6iYiIiIiIiAqEQTcRERERERFRgTDoJiIiIiIiIioQBt1EREREREREBcKgm4iIiIiIiKhAGHQTERERERERFQiDbiIiIiIiIqICYdBNREREREREVCAMuomIiIiIiIgKhEE3ERERERERUYEw6CYiIiIiIiIqEAbdRERERERERAXCoJuIiIiIiIioQBh0ExERERERERUIg24iIiIiIiKiAmHQTURERERERFQgDLqJiIiIiIiICoRBNxEREREREVGBMOgmIiIiIiIiKhAG3UREREREREQFwqCbiIiIiIiIqEAYdBMREREREREVCINuIiIiIiIiogJh0E1ERERERERUIAy6iYiIiIiIiAqEQTcRERERERFRgTDoJiIiIiIiIioQBt1EREREREREBcKgm4iIiIiIiKhAGHQTERERERERFQiDbiIiIiIiIqICYdBNREREREREVCAMuomIiIiIiIgKhEE3ERERERERUYEw6CYiIiIiIiIqEAbdRERERERERAXy/wOeReS2Ez7YbAAAAABJRU5ErkJggg==" + }, + "Снимок экрана 2025-09-18 214957.png": { + "image/png": "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" + }, + "Снимок экрана 2025-09-18 215203.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "id": "cb56c7ce", + "metadata": {}, + "source": [ + "1. Что делает команда git stash?\n", + "Сохраняет изменения в отслеживаемых файлах локально, при этом убирая эти изменения из рабочего пространства \n", + "\n", + "2. Как просмотреть список всех сохранённых изменений (стэшей)?\n", + "\n", + "`git stash list` покажет изменения списком\n", + "\n", + "3. Какая команда применяется для использования верхнего стэша?\n", + "\n", + "`git stash apply` или `git stash pop` в случае если стэш нужно удалить после применения\n", + "\n", + "4. Как применить конкретный стэш по его номеру?\n", + "\n", + "`git stash apply stash@{stash_number}` либо `git stash apply pop@{stash_number}`\n", + "\n", + "5. Чем отличается команда git stash apply от git stash pop?\n", + "\n", + "`git stash pop` удаляет стэш после применения\n", + "\n", + "6. Что делает команда git stash drop?\n", + "\n", + "Безвозвратно удаляет стэш из стэш листа, без предварительного применения\n", + "\n", + "7. Как полностью очистить все сохранённые стэши?\n", + "\n", + "`git stash clear`\n", + "\n", + "8. В каких случаях удобно использовать git stash?\n", + "\n", + "Когда нужно принять пулл или объединить ветки, при этом спрятать изменения которые находятся в работе на локальном репозитории\n", + "\n", + "9. Что произойдёт, если выполнить git stash pop, но в проекте есть конфликтующие изменения?\n", + "\n", + "Вылезет сообщение о конфликте изменений, нужно будет решить его вручную\n", + "\n", + "10. Можно ли восстановить удалённый стэш после выполнения git stash drop?\n", + "\n", + "В теории можно, если сборщик мусора гита не удалил их, но лучше держать в голове что никак нельзя будет восстановить\n", + "\n", + "11. Что делает команда git stash save \"NAME_STASH\"\n", + "\n", + "Сохраняет измененные файлы в стэш под определенным именем\n", + "\n", + "12. Что делает команда git stash apply \"NUMBER_STASH\"\n", + "\n", + "Возвращает изменения под конкретным именем из стэша в рабочую область\n", + "\n", + "13. Что делает команда git stash pop \"NUMBER_STASH\"\n", + "\n", + "Возвращает изменения под конкретным именем из стэша в рабочую область и затем удаляет этот стэш\n", + "\n", + "14. Сохраните текущие изменения в стэш под названием \"SENATOROV ver1\", вставьте скриншот из терминала\n", + "\n", + "![alt text](<Снимок экрана 2025-09-18 214521.png>)\n", + "\n", + "15. Внесите любые изменения в ваш репозиторий и сохраните второй стэш под именем \"SENATOROV ver2\"\n", + "\n", + "![Снимок экрана 2025-09-18 214627.png]()\n", + "\n", + "16. Восстановите ваш стэш \"SENATOROV ver1\", вставьте скриншот из терминала\n", + "\n", + "![Снимок экрана 2025-09-18 214957.png]()\n", + "\n", + "17. Удалите все стеши из истории, вставьте скриншот из терминала\n", + "\n", + "![Снимок экрана 2025-09-18 215203.png]()\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 488eaa41a602558bd36aea75355ee08200ed64ae Mon Sep 17 00:00:00 2001 From: Dayal Date: Thu, 18 Sep 2025 22:00:25 +0300 Subject: [PATCH 11/24] [TASK] STASH (https://github.com/SENATOROVAI/intro-cs/issues/3) Closes https://github.com/SENATOROVAI/intro-cs/issues/3 --- git/stash.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 git/stash.py diff --git a/git/stash.py b/git/stash.py new file mode 100644 index 00000000..a3d1f6e7 --- /dev/null +++ b/git/stash.py @@ -0,0 +1,69 @@ +"""Stash issue.""" + +# 1. Что делает команда git stash? +# Сохраняет изменения в отслеживаемых файлах локально, при этом убирая эти изменения из рабочего пространства +# +# 2. Как просмотреть список всех сохранённых изменений (стэшей)? +# +# `git stash list` покажет изменения списком +# +# 3. Какая команда применяется для использования верхнего стэша? +# +# `git stash apply` или `git stash pop` в случае если стэш нужно удалить после применения +# +# 4. Как применить конкретный стэш по его номеру? +# +# `git stash apply stash@{stash_number}` либо `git stash apply pop@{stash_number}` +# +# 5. Чем отличается команда git stash apply от git stash pop? +# +# `git stash pop` удаляет стэш после применения +# +# 6. Что делает команда git stash drop? +# +# Безвозвратно удаляет стэш из стэш листа, без предварительного применения +# +# 7. Как полностью очистить все сохранённые стэши? +# +# `git stash clear` +# +# 8. В каких случаях удобно использовать git stash? +# +# Когда нужно принять пулл или объединить ветки, при этом спрятать изменения которые находятся в работе на локальном репозитории +# +# 9. Что произойдёт, если выполнить git stash pop, но в проекте есть конфликтующие изменения? +# +# Вылезет сообщение о конфликте изменений, нужно будет решить его вручную +# +# 10. Можно ли восстановить удалённый стэш после выполнения git stash drop? +# +# В теории можно, если сборщик мусора гита не удалил их, но лучше держать в голове что никак нельзя будет восстановить +# +# 11. Что делает команда git stash save "NAME_STASH" +# +# Сохраняет измененные файлы в стэш под определенным именем +# +# 12. Что делает команда git stash apply "NUMBER_STASH" +# +# Возвращает изменения под конкретным именем из стэша в рабочую область +# +# 13. Что делает команда git stash pop "NUMBER_STASH" +# +# Возвращает изменения под конкретным именем из стэша в рабочую область и затем удаляет этот стэш +# +# 14. Сохраните текущие изменения в стэш под названием "SENATOROV ver1", вставьте скриншот из терминала +# +# ![alt text](<Снимок экрана 2025-09-18 214521.png>) +# +# 15. Внесите любые изменения в ваш репозиторий и сохраните второй стэш под именем "SENATOROV ver2" +# +# ![Снимок экрана 2025-09-18 214627.png]() +# +# 16. Восстановите ваш стэш "SENATOROV ver1", вставьте скриншот из терминала +# +# ![Снимок экрана 2025-09-18 214957.png]() +# +# 17. Удалите все стеши из истории, вставьте скриншот из терминала +# +# ![Снимок экрана 2025-09-18 215203.png]() +# From 4bde0f12d2ddcca57dd213c1e195721fd5431b2d Mon Sep 17 00:00:00 2001 From: Dayal Date: Mon, 22 Sep 2025 22:15:48 +0300 Subject: [PATCH 12/24] [TASK] issues (https://github.com/SENATOROVAI/intro-cs/issues/2) closes https://github.com/SENATOROVAI/intro-cs/issues/2 --- python/issues.ipynb | 206 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 python/issues.ipynb diff --git a/python/issues.ipynb b/python/issues.ipynb new file mode 100644 index 00000000..1e0c4a5e --- /dev/null +++ b/python/issues.ipynb @@ -0,0 +1,206 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "3e32d085", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Issues issue.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "13f285d1", + "metadata": {}, + "source": [ + "Общие вопросы\n", + "\n", + "1. Что такое Issues на GitHub и для чего они используются?\n", + "Можно использовать чтобы разработчик рассказывал вам как работает код или для обучения программированию\n", + "Можно запрашивать объяснение выделяя интересующие строчки в коде и запрашивать объяснение\n", + "Так же для нахождения проблем в коде\n", + "\n", + "2. Чем Issues отличаются от других инструментов управления задачами?\n", + "Можно ссылаться на issue в коммитах, PR, ветках\n", + "Автоматическое закрытие issue при мерже PR\n", + "Можно автоматически назначать метки, ответственных, переносить в проекты\n", + "Возможность просматривать, какие коммиты/PR относятся к задаче\n", + "\n", + "3. Какие основные компоненты (поля) есть у каждого Issue?\n", + "Тайтл и дескрипшен\n", + "А также Labels, Assignees, Milestone, Статус, Обсуждение \n", + "\n", + "Создание Issues\n", + "\n", + "4. Как создать новое Issue в репозитории?\n", + "Выделяем нужные строчки кода через шифт, кликом на первую и последнюю строчку \n", + "Нажимаем \"copy permalink\" \n", + "В верхней панели гитхаба \"issues\" -> new issue\n", + "Выбираем тип issue(bug report, feature request и т.д.)\n", + "Далее заполняем тайтл и дескрипшен\n", + "Нажимаем \"Submit new issue\"\n", + "\n", + "5. Какие данные рекомендуется указывать в описании Issue для лучшего понимания задачи?\n", + "Действия которые нужно произвести, файл на который ссылаемся\n", + "В целом максимально информативно описать суть проблемы, ссылаясь на места куда нужно обратить внимание\n", + "Код ошибки, трассировка из терминала и т.д.\n", + "\n", + "6. Какие теги (labels) можно добавить к Issue? Какие из них стандартные?\n", + "Теги помогают классифицировать задачи\n", + "Стандартные: \n", + "- `bug` — Неожиданная ошибка или неправильное поведение.\n", + "- `documentation` — Нужно обновить или дополнить документацию.\n", + "- `duplicate` — Дубликат другой задачи или обсуждения.\n", + "- `enhancement` — Улучшение существующей функции.\n", + "- `good first issue` — Подходит для новичков (отображается на странице «Contribute»).\n", + "- `help wanted` — Нужна помощь от сообщества или команды.\n", + "- `invalid` — Задача неактуальна или основана на ошибке.\n", + "- `question` — Требуется уточнение или дополнительная информация.\n", + "- `wontfix` — Задачу не будут исправлять или реализовывать.\n", + "\n", + "7. Как прикрепить Assignees (ответственных) к Issue?\n", + "При переходе на ишью можно выбрать ответственных в поле assignees справа\n", + "\n", + "Выберите ишью, которые нужно назначить кому-то\n", + "В верхнем правом углу нажмите кнопку 'Назначить'\n", + "Можно назначить для ишью до 10 пользователей.\n", + "\n", + "Работа с Issues\n", + "\n", + "8. Как использовать Labels для классификации задач?\n", + "Метки позволяют классифицировать задачи, пулреквесты и обсуждения по категориям, таким как: \n", + "- приоритет (например, high-priority)\n", + "- тип задачи (например, bug, feature request)\n", + "- часть проекта (например, frontend, backend)\n", + "- команда, ответственная за выполнение\n", + "\n", + "Вы можете создавать собственные метки и применять их для фильтрации и организации работы.\n", + "Цвет метки помогает визуально отличать категории — например, красный для багов, зелёный для улучшений.\n", + "\n", + "9. Для чего нужен Milestone, и как связать его с Issue?\n", + "Дедлайн ошибки, в каком месяце нужно решить ишью,\n", + "по нему можно находить тикеты которые закрыли в определенный месяц\n", + "При переходе на ишью можно выбрать майлстоуны в поле справа\n", + "\n", + "10. Как привязать Issue к пул-реквесту (Pull Request)?\n", + "Можно указать ссылку на ишью в тайтле пулл реквеста или написать номер ишью\n", + "Ссылку или номер ишью обязательно в тайтле в скобках\n", + "В заголовке пул реквеста должен быть заголовок из ишью\n", + "\n", + "11. Как добавить комментарий к существующему Issue?\n", + "На странице задачи github внизу в поле \"Leave a comment\"\n", + "После этого нажать кнопку Comment, чтобы опубликовать\n", + "\n", + "\n", + "Закрытие и завершение Issues\n", + "\n", + "12. Как закрыть Issue вручную?\n", + "Нужно открыть его на GitHub и нажать на кнопку \"Close issue\" под полем комментария. \n", + "При желании добавьте поясняющий комментарий перед закрытием — это поможет команде понять причину. \n", + "Закрытые Issues можно в любой момент переоткрыть.\n", + "\n", + "13. Можно ли автоматически закрыть Issue с помощью сообщения в коммите или пул-реквесте? Как это сделать?\n", + "Да можно, в PR должно быть указанно ключевое слово, и PR должен находится в ветке по умолчанию\n", + "Ключевые слова:\n", + "- close\n", + "- closes\n", + "- closed\n", + "- fix\n", + "- fixes\n", + "- fixed\n", + "- resolve\n", + "- resolves\n", + "- resolved\n", + "\n", + "14. Как повторно открыть закрытое Issue, если работа ещё не завершена?\n", + "Зайти на его страницу на GitHub и нажать кнопку \"Reopen issue\" рядом с закрытым статусом. \n", + "Это вернёт задачу в активное состояние. \n", + "Все комментарии и история сохраняются.\n", + "\n", + "Фильтрация и поиск\n", + "\n", + "15. Как найти все открытые или закрытые Issues в репозитории?\n", + "Во вкладке \"issues\" на странице репозитория\n", + "Кнопки \"open\" и \"closed\"\n", + "\n", + "16. Как использовать фильтры для поиска Issues по меткам, исполнителям или другим критериям?\n", + "Во вкладке \"issues\" на странице репозитория справа от кнопок \"open\" и \"closed\"\n", + "Можно фильтровать по авторам, меткам, проектам, майлстоунам, ответственным\n", + "\n", + "17. Как сортировать Issues по приоритету, дате создания или другим параметрам?\n", + "Кнопка \"sort\" справа от фильтрации по меткам, исполнителям и т.п.\n", + "\n", + "Интеграции и автоматизация\n", + "\n", + "18. Как настроить автоматические уведомления о новых или изменённых Issues?\n", + "Настраиваются через вкладку Watch в репозитории, нужно выбрать “All Activity” или “Issues” для получения уведомлений\n", + "Также можно настроить правила в Settings -> Notifications -> Custom routing, чтобы перенаправлять уведомления по упоминаниям\n", + "Для сложной автоматизации - GitHub Actions \n", + "\n", + "19. Что такое Projects в контексте GitHub, и как связать их с Issues?\n", + "Projects в GitHub — это гибкие доски, таблицы или роадмапы, которые помогают планировать и отслеживать работу, интегрируясь напрямую с Issues и Pull Requests. \n", + "В них не установлена методология, а адаптируются: можно фильтровать, группировать, сортировать задачи, добавлять кастомные поля, диаграммы и автоматизации. \n", + "\n", + "Чтобы связать Project с Issue, нужно добавить Issue в Project — вручную, через метки, или автоматически по правилам. \n", + "Все изменения синхронизируются в обе стороны: если назначим исполнителя в Project — это отразится в самом Issue, и наоборот.\n", + "\n", + "20. Какие сторонние инструменты можно использовать для автоматизации работы с Issues (например, боты, Webhooks)?\n", + "GraphQL API, GitHub Actions\n", + "Вебхуки (отправка событий в Slack, Discord, Jira и т.п.) \n", + "Интеграции через GitHub Apps \n", + "Также сторонние боты — Probot, Dependabot, Mergify\n", + "\n", + "Коллаборация\n", + "\n", + "21. Как упомянуть другого пользователя в комментарии к Issue?\n", + "Введите символ @ и начните вводить имя пользователя — GitHub предложит совпадения\n", + "Выберите нужного участника, и он получит уведомление\n", + "\n", + "22. Как запросить дополнительные данные или уточнения у автора Issue?\n", + "Тэгнуть автора и задать вопрос, так как он получит уведомление, шанс что вопрос увидят очень велик\n", + "\n", + "\n", + "23. Что делать, если Issue неактуально или его нужно объединить с другим?\n", + "Можно закрыть его с комментарием \"закрытие из-за не актуальности\" или \"закрываю как дубликат #номер_ишью\"\n", + "Так же есть возможность удалить ишью, в правом сайд баре под кнопкой \"notifications\" есть кнопка \"delete issue\"\n", + "\n", + "Практические аспекты\n", + "\n", + "24. Как использовать шаблоны для создания Issues?\n", + "Нужно добавить в репозиторий папку .github/ISSUE_TEMPLATE/ с файлами в формате Markdown (например, bug_report.md, feature_request.md) \n", + "или YAML (для Issue Forms). \n", + "При создании Issue пользователь увидит выпадающий список с шаблонами — при выборе подставится структурированная форма. \n", + "YAML-формы позволяют задавать поля, валидацию и автоматические метки.\n", + "\n", + "25. Что такое Linked Issues, и как создать связь между задачами?\n", + "Связанные между собой issue, могут упоминать друг друга через #номер_ишью в описании, названии или комменту к ишью\n", + "Связь отображается в интерфейсе обеих задач\n", + "Все связи отображаются на странице Issue \n", + "\n", + "26. Какие метрики (например, время выполнения) можно отслеживать с помощью Issues?\n", + "Можно отслеживать метрики вроде времени от создания до закрытия, времени первого ответа, срока нахождения в статусе, \n", + "частоты открытия/закрытия задач, а также распределение по меткам, исполнителям или майлстоунам \n", + "\n", + "27. Какие best practices рекомендуются при работе с Issues в команде?\n", + "При работе с Issues в команде рекомендуется: \n", + "- использовать понятные заголовки и шаблоны \n", + "- классифицировать задачи метками (тип, приоритет, область) \n", + "- назначать ответственных \n", + "- связывать зависимости \n", + "- закрывать с пояснением \n", + "- вести обсуждения в комментариях\n", + "- регулярно актуализировать статус чтобы вся история и контекст оставались в GitHub\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 5b8d908970273e379700d6471c2477fbd2edd7a3 Mon Sep 17 00:00:00 2001 From: Dayal Date: Mon, 22 Sep 2025 22:18:00 +0300 Subject: [PATCH 13/24] [TASK] issues (https://github.com/SENATOROVAI/intro-cs/issues/2) closes https://github.com/SENATOROVAI/intro-cs/issues/2 --- python/issues.py | 181 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 python/issues.py diff --git a/python/issues.py b/python/issues.py new file mode 100644 index 00000000..a7eaa8e6 --- /dev/null +++ b/python/issues.py @@ -0,0 +1,181 @@ +"""Issues issue.""" + +# Общие вопросы +# +# 1. Что такое Issues на GitHub и для чего они используются? +# Можно использовать чтобы разработчик рассказывал вам как работает код или для обучения программированию +# Можно запрашивать объяснение выделяя интересующие строчки в коде и запрашивать объяснение +# Так же для нахождения проблем в коде +# +# 2. Чем Issues отличаются от других инструментов управления задачами? +# Можно ссылаться на issue в коммитах, PR, ветках +# Автоматическое закрытие issue при мерже PR +# Можно автоматически назначать метки, ответственных, переносить в проекты +# Возможность просматривать, какие коммиты/PR относятся к задаче +# +# 3. Какие основные компоненты (поля) есть у каждого Issue? +# Тайтл и дескрипшен +# А также Labels, Assignees, Milestone, Статус, Обсуждение +# +# Создание Issues +# +# 4. Как создать новое Issue в репозитории? +# Выделяем нужные строчки кода через шифт, кликом на первую и последнюю строчку +# Нажимаем "copy permalink" +# В верхней панели гитхаба "issues" -> new issue +# Выбираем тип issue(bug report, feature request и т.д.) +# Далее заполняем тайтл и дескрипшен +# Нажимаем "Submit new issue" +# +# 5. Какие данные рекомендуется указывать в описании Issue для лучшего понимания задачи? +# Действия которые нужно произвести, файл на который ссылаемся +# В целом максимально информативно описать суть проблемы, ссылаясь на места куда нужно обратить внимание +# Код ошибки, трассировка из терминала и т.д. +# +# 6. Какие теги (labels) можно добавить к Issue? Какие из них стандартные? +# Теги помогают классифицировать задачи +# Стандартные: +# - `bug` — Неожиданная ошибка или неправильное поведение. +# - `documentation` — Нужно обновить или дополнить документацию. +# - `duplicate` — Дубликат другой задачи или обсуждения. +# - `enhancement` — Улучшение существующей функции. +# - `good first issue` — Подходит для новичков (отображается на странице «Contribute»). +# - `help wanted` — Нужна помощь от сообщества или команды. +# - `invalid` — Задача неактуальна или основана на ошибке. +# - `question` — Требуется уточнение или дополнительная информация. +# - `wontfix` — Задачу не будут исправлять или реализовывать. +# +# 7. Как прикрепить Assignees (ответственных) к Issue? +# При переходе на ишью можно выбрать ответственных в поле assignees справа +# +# Выберите ишью, которые нужно назначить кому-то +# В верхнем правом углу нажмите кнопку 'Назначить' +# Можно назначить для ишью до 10 пользователей. +# +# Работа с Issues +# +# 8. Как использовать Labels для классификации задач? +# Метки позволяют классифицировать задачи, пулреквесты и обсуждения по категориям, таким как: +# - приоритет (например, high-priority) +# - тип задачи (например, bug, feature request) +# - часть проекта (например, frontend, backend) +# - команда, ответственная за выполнение +# +# Вы можете создавать собственные метки и применять их для фильтрации и организации работы. +# Цвет метки помогает визуально отличать категории — например, красный для багов, зелёный для улучшений. +# +# 9. Для чего нужен Milestone, и как связать его с Issue? +# Дедлайн ошибки, в каком месяце нужно решить ишью, +# по нему можно находить тикеты которые закрыли в определенный месяц +# При переходе на ишью можно выбрать майлстоуны в поле справа +# +# 10. Как привязать Issue к пул-реквесту (Pull Request)? +# Можно указать ссылку на ишью в тайтле пулл реквеста или написать номер ишью +# Ссылку или номер ишью обязательно в тайтле в скобках +# В заголовке пул реквеста должен быть заголовок из ишью +# +# 11. Как добавить комментарий к существующему Issue? +# На странице задачи github внизу в поле "Leave a comment" +# После этого нажать кнопку Comment, чтобы опубликовать +# +# +# Закрытие и завершение Issues +# +# 12. Как закрыть Issue вручную? +# Нужно открыть его на GitHub и нажать на кнопку "Close issue" под полем комментария. +# При желании добавьте поясняющий комментарий перед закрытием — это поможет команде понять причину. +# Закрытые Issues можно в любой момент переоткрыть. +# +# 13. Можно ли автоматически закрыть Issue с помощью сообщения в коммите или пул-реквесте? Как это сделать? +# Да можно, в PR должно быть указанно ключевое слово, и PR должен находится в ветке по умолчанию +# Ключевые слова: +# - close +# - closes +# - closed +# - fix +# - fixes +# - fixed +# - resolve +# - resolves +# - resolved +# +# 14. Как повторно открыть закрытое Issue, если работа ещё не завершена? +# Зайти на его страницу на GitHub и нажать кнопку "Reopen issue" рядом с закрытым статусом. +# Это вернёт задачу в активное состояние. +# Все комментарии и история сохраняются. +# +# Фильтрация и поиск +# +# 15. Как найти все открытые или закрытые Issues в репозитории? +# Во вкладке "issues" на странице репозитория +# Кнопки "open" и "closed" +# +# 16. Как использовать фильтры для поиска Issues по меткам, исполнителям или другим критериям? +# Во вкладке "issues" на странице репозитория справа от кнопок "open" и "closed" +# Можно фильтровать по авторам, меткам, проектам, майлстоунам, ответственным +# +# 17. Как сортировать Issues по приоритету, дате создания или другим параметрам? +# Кнопка "sort" справа от фильтрации по меткам, исполнителям и т.п. +# +# Интеграции и автоматизация +# +# 18. Как настроить автоматические уведомления о новых или изменённых Issues? +# Настраиваются через вкладку Watch в репозитории, нужно выбрать “All Activity” или “Issues” для получения уведомлений +# Также можно настроить правила в Settings -> Notifications -> Custom routing, чтобы перенаправлять уведомления по упоминаниям +# Для сложной автоматизации - GitHub Actions +# +# 19. Что такое Projects в контексте GitHub, и как связать их с Issues? +# Projects в GitHub — это гибкие доски, таблицы или роадмапы, которые помогают планировать и отслеживать работу, интегрируясь напрямую с Issues и Pull Requests. +# В них не установлена методология, а адаптируются: можно фильтровать, группировать, сортировать задачи, добавлять кастомные поля, диаграммы и автоматизации. +# +# Чтобы связать Project с Issue, нужно добавить Issue в Project — вручную, через метки, или автоматически по правилам. +# Все изменения синхронизируются в обе стороны: если назначим исполнителя в Project — это отразится в самом Issue, и наоборот. +# +# 20. Какие сторонние инструменты можно использовать для автоматизации работы с Issues (например, боты, Webhooks)? +# GraphQL API, GitHub Actions +# Вебхуки (отправка событий в Slack, Discord, Jira и т.п.) +# Интеграции через GitHub Apps +# Также сторонние боты — Probot, Dependabot, Mergify +# +# Коллаборация +# +# 21. Как упомянуть другого пользователя в комментарии к Issue? +# Введите символ @ и начните вводить имя пользователя — GitHub предложит совпадения +# Выберите нужного участника, и он получит уведомление +# +# 22. Как запросить дополнительные данные или уточнения у автора Issue? +# Тэгнуть автора и задать вопрос, так как он получит уведомление, шанс что вопрос увидят очень велик +# +# +# 23. Что делать, если Issue неактуально или его нужно объединить с другим? +# Можно закрыть его с комментарием "закрытие из-за не актуальности" или "закрываю как дубликат #номер_ишью" +# Так же есть возможность удалить ишью, в правом сайд баре под кнопкой "notifications" есть кнопка "delete issue" +# +# Практические аспекты +# +# 24. Как использовать шаблоны для создания Issues? +# Нужно добавить в репозиторий папку .github/ISSUE_TEMPLATE/ с файлами в формате Markdown (например, bug_report.md, feature_request.md) +# или YAML (для Issue Forms). +# При создании Issue пользователь увидит выпадающий список с шаблонами — при выборе подставится структурированная форма. +# YAML-формы позволяют задавать поля, валидацию и автоматические метки. +# +# 25. Что такое Linked Issues, и как создать связь между задачами? +# Связанные между собой issue, могут упоминать друг друга через #номер_ишью в описании, названии или комменту к ишью +# Связь отображается в интерфейсе обеих задач +# Все связи отображаются на странице Issue +# +# 26. Какие метрики (например, время выполнения) можно отслеживать с помощью Issues? +# Можно отслеживать метрики вроде времени от создания до закрытия, времени первого ответа, срока нахождения в статусе, +# частоты открытия/закрытия задач, а также распределение по меткам, исполнителям или майлстоунам +# +# 27. Какие best practices рекомендуются при работе с Issues в команде? +# При работе с Issues в команде рекомендуется: +# - использовать понятные заголовки и шаблоны +# - классифицировать задачи метками (тип, приоритет, область) +# - назначать ответственных +# - связывать зависимости +# - закрывать с пояснением +# - вести обсуждения в комментариях +# - регулярно актуализировать статус чтобы вся история и контекст оставались в GitHub +# +# From 2e62d61780e7da0b355fdc0e6fd6baae95822728 Mon Sep 17 00:00:00 2001 From: Dayal Date: Tue, 23 Sep 2025 00:38:43 +0300 Subject: [PATCH 14/24] =?UTF-8?q?[TASK]=20=D0=92=D0=B8=D1=80=D1=82=D1=83?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5=20=D0=BE=D0=BA=D1=80=D1=83?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20(https://github.com/SENATOROVA?= =?UTF-8?q?I/intro-cs/issues/7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes https://github.com/SENATOROVAI/intro-cs/issues/7 --- python/venv.ipynb | 111 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 python/venv.ipynb diff --git a/python/venv.ipynb b/python/venv.ipynb new file mode 100644 index 00000000..42767d35 --- /dev/null +++ b/python/venv.ipynb @@ -0,0 +1,111 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "e96170c4", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Venv issue.\"\"\"" + ] + }, + { + "attachments": { + "image-2.png": { + "image/png": "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fNCrK8zT/cN6LuY53OeJl/SSAp87487Jmv1Y5B6ZeiGwGcvmeL1XysvRjdsXa/qdi3VD3hvB6XZDBx99Q/NCm50s97bfBQAAxNoHb7+vV37xkt57813NWXO1rv5CunT2rI7+4q96743zO/IZV49a+sTKm5W5aKG9LEm6OT0w6mk24ePW85HX+/FKAAAAF7v+HrUUV+GzP2tXJOgnDwQefLRp63HNSR6vLw1x1HPoCJ8AAAB2/YXPuJt278vWZ/2a8HGvJnzcq01bj8cgeAIAAGCoLpjwOToMHWTUEwAAYNAInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGYInwAAAIgZwicAAABihvAJAACAmCF8AgAAIGb+fzZ2fuCAMXD4AAAAAElFTkSuQmCC" + }, + "image-3.png": { + "image/png": "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" + }, + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "id": "48bb6bab", + "metadata": {}, + "source": [ + "\n", + "1. Что делает команда python -m venv venv?\n", + "Создаёт виртуальное окружение Python в папке venv\n", + "\n", + "1.1 Что делает каждая команда в списке ниже?\n", + " pip list — показывает список установленных пакетов\n", + " pip freeze > requirements.txt — сохраняет список пакетов в файл requirements.txt\n", + " pip install -r requirements.txt — устанавливает пакеты из файла requirements.txt\n", + " \n", + "2. Что делает каждая команда в списке ниже?\n", + " conda env list — выводит список всех виртуальных окружений \n", + " conda create -n env_name python=3.5 — создаёт виртуальное окружение с Python 3.5 \n", + " conda env update -n env_name -f file.yml — обновляет окружение по файлу file.yml\n", + " source activate env_name — активирует виртуальное окружение \n", + " source deactivate — деактивирует виртуальное окружение \n", + " conda clean -a — удаляет все пакеты\n", + "\n", + "3. вставьте скрин вашего терминала, где вы активировали сначала venv, потом conda, назовите окружение \"SENATOROV\"\n", + "Окружение \"SENATOROV\" создал до этого, просто проблемы с кондой были\n", + "![image.png](attachment:image.png)\n", + "\n", + "4. Как установить необходимые пакеты внутрь виртуального окружения для conda/venv?\n", + "ДЛЯ CONDA:\n", + "Активировать виртуальное окружение `conda activate имя_окружения`\n", + "Установить пакет `conda install имя_пакета`\n", + "\n", + "ДЛЯ PIP:\n", + "venv\\Scripts\\activate\n", + "pip install имя_пакета\n", + "\n", + "5. Что делают эти команды?\n", + " pip freeze > requirements.txt - сохраняет список установленных пакетов в файл requirements.txt\n", + " conda env export > environment.yml - сохраняет полное описание окружения Conda в файл environment.yml\n", + "\n", + "\n", + "5.1 вставьте скрин, где будет видна папка VENV в вашем репозитории а также файлы зависимостей \n", + "requirements.txt и environment.yml, файлы должны содержать зависимости\n", + "![image-2.png](attachment:image-2.png)\n", + "\n", + "6. Что делают эти команды?\n", + " pip install -r requirements.txt - устанавливает пакеты из списка в файле requirements.txt\n", + " conda env create -f environment.yml - создаёт новое окружение Conda на основе файла environment.yml\n", + "\n", + "\n", + "7. Что делают эти команды?\n", + " pip list - показывает все установленные пакеты в текущем окружении\n", + " pip show - выводит детали по конкретному пакету (версия, описание, зависимости) \n", + " conda list - показывает все пакеты, установленные в текущем окружении Conda (включая системные)\n", + "\n", + "\n", + "8. Где по умолчанию больше пакетов venv/pip или conda? и почему дата сайнинисты используют conda?\n", + "Больше пакетов по умолчанию — в Conda, потому что оно устанавливает Python + базовые научные пакеты (numpy, pandas и др.)\n", + "Дата сайнинисты используют конду потому что она предоставляет лучшую совместимость сложных пакетов, а также\n", + "Поддержку виртуальных окружений + установка разных версий Python\n", + "\n", + "9. вставьте скрин где будет видно, Выбор интерпретатора Python (conda) в VS Code/cursor\n", + "![image-3.png](attachment:image-3.png)\n", + "\n", + "10. добавьте в .gitignore папку SENATOROV\n", + "Дописал \"SENATOROV/\" в .gitignore\n", + "Но как я понял это не обязательно, потому что папка SENATOROV не находится в папке проекта, \n", + "а хранится в системной директории Conda \n", + "\n", + "11. Зачем нужно виртуально окружение?\n", + "Виртуальное окружение нужно, чтобы изолировать зависимости и версии пакетов для каждого \n", + "проекта — это предотвращает конфликты, обеспечивает воспроизводимость и упрощает совместную разработку\n", + "\n", + "12. С этого момента надо работать в виртуальном окружении conda, ты научился(-ась) выгружать зависимости и работать с окружением?\n", + "да\n", + "\n", + "13. Удалите папку VENV, она больше не нужна, мы же не разрабы, нам нужна только conda\n", + "сделано\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From be7031db094b4309696a390bf011e727f9db05c2 Mon Sep 17 00:00:00 2001 From: Dayal Date: Tue, 23 Sep 2025 00:39:52 +0300 Subject: [PATCH 15/24] =?UTF-8?q?[TASK]=20=D0=92=D0=B8=D1=80=D1=82=D1=83?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5=20=D0=BE=D0=BA=D1=80=D1=83?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20(https://github.com/SENATOROVA?= =?UTF-8?q?I/intro-cs/issues/7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes https://github.com/SENATOROVAI/intro-cs/issues/7 --- python/venv.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 python/venv.py diff --git a/python/venv.py b/python/venv.py new file mode 100644 index 00000000..2c9f50d7 --- /dev/null +++ b/python/venv.py @@ -0,0 +1,75 @@ +"""Venv issue.""" + +# +# 1. Что делает команда python -m venv venv? +# Создаёт виртуальное окружение Python в папке venv +# +# 1.1 Что делает каждая команда в списке ниже? +# pip list — показывает список установленных пакетов +# pip freeze > requirements.txt — сохраняет список пакетов в файл requirements.txt +# pip install -r requirements.txt — устанавливает пакеты из файла requirements.txt +# +# 2. Что делает каждая команда в списке ниже? +# conda env list — выводит список всех виртуальных окружений +# conda create -n env_name python=3.5 — создаёт виртуальное окружение с Python 3.5 +# conda env update -n env_name -f file.yml — обновляет окружение по файлу file.yml +# source activate env_name — активирует виртуальное окружение +# source deactivate — деактивирует виртуальное окружение +# conda clean -a — удаляет все пакеты +# +# 3. вставьте скрин вашего терминала, где вы активировали сначала venv, потом conda, назовите окружение "SENATOROV" +# Окружение "SENATOROV" создал до этого, просто проблемы с кондой были +# ![image.png](attachment:image.png) +# +# 4. Как установить необходимые пакеты внутрь виртуального окружения для conda/venv? +# ДЛЯ CONDA: +# Активировать виртуальное окружение `conda activate имя_окружения` +# Установить пакет `conda install имя_пакета` +# +# ДЛЯ PIP: +# venv\Scripts\activate +# pip install имя_пакета +# +# 5. Что делают эти команды? +# pip freeze > requirements.txt - сохраняет список установленных пакетов в файл requirements.txt +# conda env export > environment.yml - сохраняет полное описание окружения Conda в файл environment.yml +# +# +# 5.1 вставьте скрин, где будет видна папка VENV в вашем репозитории а также файлы зависимостей +# requirements.txt и environment.yml, файлы должны содержать зависимости +# ![image-2.png](attachment:image-2.png) +# +# 6. Что делают эти команды? +# pip install -r requirements.txt - устанавливает пакеты из списка в файле requirements.txt +# conda env create -f environment.yml - создаёт новое окружение Conda на основе файла environment.yml +# +# +# 7. Что делают эти команды? +# pip list - показывает все установленные пакеты в текущем окружении +# pip show - выводит детали по конкретному пакету (версия, описание, зависимости) +# conda list - показывает все пакеты, установленные в текущем окружении Conda (включая системные) +# +# +# 8. Где по умолчанию больше пакетов venv/pip или conda? и почему дата сайнинисты используют conda? +# Больше пакетов по умолчанию — в Conda, потому что оно устанавливает Python + базовые научные пакеты (numpy, pandas и др.) +# Дата сайнинисты используют конду потому что она предоставляет лучшую совместимость сложных пакетов, а также +# Поддержку виртуальных окружений + установка разных версий Python +# +# 9. вставьте скрин где будет видно, Выбор интерпретатора Python (conda) в VS Code/cursor +# ![image-3.png](attachment:image-3.png) +# +# 10. добавьте в .gitignore папку SENATOROV +# Дописал "SENATOROV/" в .gitignore +# Но как я понял это не обязательно, потому что папка SENATOROV не находится в папке проекта, +# а хранится в системной директории Conda +# +# 11. Зачем нужно виртуально окружение? +# Виртуальное окружение нужно, чтобы изолировать зависимости и версии пакетов для каждого +# проекта — это предотвращает конфликты, обеспечивает воспроизводимость и упрощает совместную разработку +# +# 12. С этого момента надо работать в виртуальном окружении conda, ты научился(-ась) выгружать зависимости и работать с окружением? +# да +# +# 13. Удалите папку VENV, она больше не нужна, мы же не разрабы, нам нужна только conda +# сделано +# From ff82229d111795df50845a7efd3aac2636a73947 Mon Sep 17 00:00:00 2001 From: Dayal Date: Tue, 23 Sep 2025 00:41:07 +0300 Subject: [PATCH 16/24] chore: update .gitignore and add env files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлены файлы окружений: requirements.txt, environment.yml - Обновлён .gitignore для игнорирования локальных зависимостей - Подготовка к воспроизводимой настройке проекта --- .gitignore | 2 ++ environment.yml | Bin 0 -> 1550 bytes requirements.txt | 0 3 files changed, 2 insertions(+) create mode 100644 environment.yml create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 0fa2f447..894a8a73 100644 --- a/.gitignore +++ b/.gitignore @@ -333,3 +333,5 @@ coverage/ /Math/calculus/theory /Math/school_theory + +SENATOROV/ \ No newline at end of file diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000000000000000000000000000000000000..fb7bca53f548e5430af143364a9a0bea5e19a1d7 GIT binary patch literal 1550 zcmb7^-EP`I5QXPDQr{sj5M+aGpb{5V)!Rl&f37N7#x}w#7&kU)$iuh&&aP20q(9MW z&9XaZ&dizF{rRJ|%(hnAYrD1&_Rikh8~bRtcE|i|uk6ZlTVqo*O50eArFO3wH_U?F z73X`-I!<+_y@px4RgH&=f9J@hJ+a@|*cKMr$O7h!^_ra}W5o#hO)VKP=CIx1v$T5{ zE37L1Wvs=q039%6yv^N|$BZ#&FSZG1DHf+Wl=es*@*wocrp(YqG9!b67{=@=k|Ayb zvyZdFdIBnPQ;Y=&VM4G%h66^A+`=lYa?nCbfuQFVV~)>~xS!{JLUHkX^~CODR`wbD z3E$NPcGp*?MXOC8wRl7L6!!#;5~tFN-*e^$#s)jDuPWEr0aQ-qrtF3ee~CJv?b>#9 zgx5)S(%Dx#A?sydA1M_uQhYX8$?~*T;ye0EU7knnWhpKGgly5WqfZ;YJBE6BK@2mO zy;o1(J?FoArnPTQe|4SDDJJR>8u;p~-!iJI4mz)XXJ4@rZ{oOPhf%lB840NAh4LM@ zrNCpy{N3ZK{u8gYB~kh} z;L`7RxJ!oagA|IeeQ7^DQlEvxsisk%&y*cys&U>0FT1}DI_jmZc&qeQzvcVIKGDN^ h2V2&Ave0XFV7P3EVw$H!xzW`%B&?^7{ literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..e69de29b From 53eb7d44344ae490b8f8ab1e77b96581e86d53f2 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 24 Sep 2025 14:31:39 +0300 Subject: [PATCH 17/24] =?UTF-8?q?[TASK]=20=D0=9A=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=B8=D0=B1=D1=8C=D1=8E=D1=82=D0=B8=D0=BD=D0=B3=20=D0=B2=20Ope?= =?UTF-8?q?n=20Source=20(https://github.com/SENATOROVAI/intro-cs/issues/8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes https://github.com/SENATOROVAI/intro-cs/issues/8 --- github/opensource.ipynb | 90 ++++++++++++++ github/opensource.py | 65 ++++++++++ github/quiz.ipynb | 265 ++++++++++++++++++++++++++++++++++++++++ github/quiz.py | 262 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 682 insertions(+) create mode 100644 github/opensource.ipynb create mode 100644 github/opensource.py create mode 100644 github/quiz.ipynb create mode 100644 github/quiz.py diff --git a/github/opensource.ipynb b/github/opensource.ipynb new file mode 100644 index 00000000..81dc9c42 --- /dev/null +++ b/github/opensource.ipynb @@ -0,0 +1,90 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "3b33dc37", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"opensource issue.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "962ffd3c", + "metadata": {}, + "source": [ + "1. Есть ли у него лицензия? Обычно в корне репозитория находится \n", + "файл LICENSE.\n", + "Да, есть\n", + "\n", + "2. Напишите название понравившейся компании и ссылку на репозиторий\n", + "Google\n", + "\n", + "3. Проект активно принимает стороннюю помощь?\n", + "Да\n", + "\n", + "4. Напишите второе улучшение которое вы сделали\n", + "Исправил опечатку в названии переменной\n", + "https://github.com/googleapis/google-api-nodejs-client/pull/3789\n", + "\n", + "5. Посмотрите на коммиты в основной ветке, напишите общее количество\n", + "10244 \n", + "\n", + "6. Когда был последний коммит?\n", + "Sep 18, 2025\n", + "\n", + "7. Сколько контрибьюторов у проекта?\n", + "143\n", + "\n", + "8. Как часто люди коммитят в репозиторий? (На GitHub выяснить это можно, \n", + "кликнув по ссылке «Commits» в верхней панели.)\n", + "Примерно по 10-15 раз в месяц\n", + "\n", + "9. Сколько сейчас открытых ишью?\n", + "210 \n", + "\n", + "10. Быстро ли мейнтейнеры реагируют на ишью после того, когда они открываются?\n", + "Примерно 1-2 недели\n", + "\n", + "11. Ведётся ли активное обсуждение ишью?\n", + "В каждом ишью 2-20 комментариев\n", + "\n", + "12. Есть ли недавно созданные ишью?\n", + "Да, не считая меня 5 дней назад было создано еще одно\n", + "\n", + "13. Есть ли закрытые ишью? (На странице Issues GitHub-репозитория щелкните на \n", + "вкладку «Closed», чтобы увидеть закрытые ишью.)\n", + "Да, 1559\n", + "\n", + "14. Сколько сейчас открытых пул-реквестов?\n", + "5 \n", + "\n", + "15. Быстро ли мейнтейнеры реагируют на пул-реквесты после их открытия?\n", + "Да, вполне, 5-7 дней до закрытия или хотя бы начала обсуждения\n", + "\n", + "16. Ведётся ли активное обсуждение пул-реквестов?\n", + "Да\n", + "\n", + "17. Есть ли недавно отправленные пул-реквесты?\n", + "Да, на прошлой неделе\n", + "\n", + "18. Как давно были объединены пул-реквесты? (На странице Pull \n", + "Request GitHub-репозитория \n", + "щелкните на вкладку «Closed», чтобы увидеть закрытые пул-реквесты.)\n", + "На прошлой неделе\n", + "\n", + "https://github.com/googleapis/google-api-nodejs-client/issues/3787 - ишью\n", + "https://github.com/googleapis/google-api-nodejs-client/pull/3788 - пулл к гуглу\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/github/opensource.py b/github/opensource.py new file mode 100644 index 00000000..b7da0184 --- /dev/null +++ b/github/opensource.py @@ -0,0 +1,65 @@ +"""Opensource issue.""" + +# 1. Есть ли у него лицензия? Обычно в корне репозитория находится +# файл LICENSE. +# Да, есть +# +# 2. Напишите название понравившейся компании и ссылку на репозиторий +# Google +# +# 3. Проект активно принимает стороннюю помощь? +# Да +# +# 4. Напишите второе улучшение которое вы сделали +# Исправил опечатку в названии переменной +# https://github.com/googleapis/google-api-nodejs-client/pull/3789 +# +# 5. Посмотрите на коммиты в основной ветке, напишите общее количество +# 10244 +# +# 6. Когда был последний коммит? +# Sep 18, 2025 +# +# 7. Сколько контрибьюторов у проекта? +# 143 +# +# 8. Как часто люди коммитят в репозиторий? (На GitHub выяснить это можно, +# кликнув по ссылке «Commits» в верхней панели.) +# Примерно по 10-15 раз в месяц +# +# 9. Сколько сейчас открытых ишью? +# 210 +# +# 10. Быстро ли мейнтейнеры реагируют на ишью после того, когда они открываются? +# Примерно 1-2 недели +# +# 11. Ведётся ли активное обсуждение ишью? +# В каждом ишью 2-20 комментариев +# +# 12. Есть ли недавно созданные ишью? +# Да, не считая меня 5 дней назад было создано еще одно +# +# 13. Есть ли закрытые ишью? (На странице Issues GitHub-репозитория щелкните на +# вкладку «Closed», чтобы увидеть закрытые ишью.) +# Да, 1559 +# +# 14. Сколько сейчас открытых пул-реквестов? +# 5 +# +# 15. Быстро ли мейнтейнеры реагируют на пул-реквесты после их открытия? +# Да, вполне, 5-7 дней до закрытия или хотя бы начала обсуждения +# +# 16. Ведётся ли активное обсуждение пул-реквестов? +# Да +# +# 17. Есть ли недавно отправленные пул-реквесты? +# Да, на прошлой неделе +# +# 18. Как давно были объединены пул-реквесты? (На странице Pull +# Request GitHub-репозитория +# щелкните на вкладку «Closed», чтобы увидеть закрытые пул-реквесты.) +# На прошлой неделе +# +# https://github.com/googleapis/google-api-nodejs-client/issues/3787 - ишью +# https://github.com/googleapis/google-api-nodejs-client/pull/3788 - пулл к гуглу +# diff --git a/github/quiz.ipynb b/github/quiz.ipynb new file mode 100644 index 00000000..31911a52 --- /dev/null +++ b/github/quiz.ipynb @@ -0,0 +1,265 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "3982ec7d", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"contributing issue.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "5c74a6d5", + "metadata": {}, + "source": [ + "1.1. Что такое GitHub?\n", + "GitHub — это платформа для хостинга Git-репозиториев и совместной разработки\n", + "\n", + "1.2. Как GitHub связан с Git?\n", + "GitHub использует Git как систему контроля версий \n", + "Git работает локально \n", + "GitHub — удалённый хостинг для репозиториев\n", + "\n", + "1.3. Чем отличается fork репозитория от его клонирования (clone)?\n", + "Fork создаёт копию репозитория на GitHub (в вашем аккаунте) \n", + "clone — копирует репозиторий на компьютер.\n", + "\n", + "1.4. Зачем нужны и как работают pull requests?\n", + "Pull request — запрос на слияние изменений из одной ветки в другую\n", + "Используется для обсуждения и проверки кода перед слиянием\n", + "\n", + "1.5. GitHub использует ваш почтовый адрес для привязки ваших Git \n", + "коммитов к вашей учётной записи?\n", + "Да, GitHub связывает коммиты с учётной записью по \n", + "email, указанному в настройках Git и GitHub\n", + "\n", + "1.6 Какая команда генерирует SSH ключ для Доступа по \n", + "SSH к репозиторию (Рисунок 83)\n", + "`ssh-keygen -o`\n", + "\n", + "2. Создайте ишьюс и запомните его номер, в \n", + "https://github.com/SENATOROVAI/Data-Science-For-\n", + "Beginners-from-scratch-SENATOROV/issues, \n", + "назовите его \"UPDATE README\", в дескрипшене \n", + "добавьте список задач (Рисунок 102)\n", + "\n", + "https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV/issues/401\n", + "\n", + "2.1. Если вы хотите вносить свой вклад в уже \n", + "существующие проекты, в которых у нас нет прав на внесения \n", + "изменений путём отправки (push) изменений, вы можете \n", + "создать своё собственное ответвление, \n", + "что нужно сделать чтобы создать собственное ответвление? \n", + "(Рисунок 88), сделайте ответвление \n", + "https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV, \n", + "и вставьте сюда ссылку на ваше ответвление\n", + "\n", + "https://github.com/oh-ddy/Data-Science-For-Beginners-from-scratch-SENATOROV\n", + "\n", + "\n", + "2.2 создайте ветку dev в ФОРКЕ Data-Science-For-Beginners, \n", + "вставьте сюда ссылку на вашу ветку dev\n", + "\n", + "https://github.com/oh-ddy/Data-Science-For-Beginners-from-scratch-SENATOROV/tree/dev\n", + "\n", + "2.3 В README файле вашего ФОРКА, добавьте ссылку на мой телеграм канал https://t.me/RuslanSenatorov, \n", + "сохраните коммит, название коммита - в тайтле название ишьюса \n", + "(#номер_ишьюс), в дескрипшене - \n", + "Closes #NUMBER-ISSUES номер возьмите из пункта 2\n", + "\n", + "**сделано**\n", + "\n", + "2.4 Отправьте пул реквест из ФОРКА в основу В ВАШУ ВЕТКУ, \n", + "тайтл пул реквеста скопируйте \n", + "из ISSUES-TITLE, в дескрипшине пул реквеста напишите \n", + "Closes #NUMBER-ISSUES вставьте номер из пункта 2\n", + "\n", + "**сделано**\n", + "\n", + "2.5 Прокомментириуйте ваш пул реквест перед слиянием, \n", + "перейдите во вкладку(Рисунок 92) \n", + "и напишите \"ок\", потом нажимайте сабмит ревью \n", + "затем не выходя из этой вкладки, в файле README, \n", + "добавьте туда ссылку на https://t.me/SENATOROVAI\n", + "\n", + "**сделано**\n", + "\n", + "2.6 Выполните Merge pull request (Рисунок 116), \n", + "вставьте сюда ссылку на ваш пул реквест\n", + "\n", + "https://github.com/oh-ddy/Data-Science-For-Beginners-from-scratch-SENATOROV/pull/1\n", + "\n", + "2.7 Вставьте сюда ссылку на закрытые пул реквесты \n", + "в репозитории, найти можно тут\n", + "\n", + "https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV/pulls?q=is%3Apr+is%3Aclosed - SENATOROV\n", + "\n", + "2.8 Как посмотреть какие файлы были в \n", + "репозитории на момент определенного коммита? \n", + "вставьте сюда ссылку на любой коммит, где взять ссылку? \n", + "\n", + "https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV/tree/6e92003c6384148233fa1878594f4ba10aef6e5f\n", + "\n", + "2.9 как открыть запрос слияния, указывающий на \n", + "другой запрос слияния и зачем это нужно? (Рисунок 117)\n", + "\n", + "При открытии запроса на слияние вверху страницы есть меню для выбора целевой и\n", + "исходной веток. Если нажать кнопку Edit справа, \n", + "то станет доступным выбор не только\n", + "исходной ветки, а ещё и форка.\n", + "Здесь можно указать новую ветку для слияния с другим запросом слияния или другим\n", + "форком проекта.\n", + "Далее упомянуть другой PR в описании или комментарии с помощью #номер — \n", + "это создаёт ссылку и уведомление, но не техническую зависимость.\n", + "Это нужно для того чтобы предлагать улучшение \n", + "чужому пулл реквесту или организовать цепочку изменений\n", + "\n", + "\n", + "Рабочий процесс с использованием GitHub\n", + "\n", + "\n", + "3. Напишите 8 пунктов, которые нужно сделать, \n", + "чтобы внести вклад в чужой проект.\n", + "\n", + " 1. Ознакомиться с проектом: прочитать README, LICENSE, CONTRIBUTING.md, а также посмотреть открытые issues. \n", + " 2. Сделать fork репозитория, чтобы получить свою копию на GitHub. \n", + " 3. Клонировать свой fork локально и настроить \n", + " remote upstream на оригинальный репозиторий. \n", + " 4. Создать новую ветку на основе актуальной ветки main/master из upstream. \n", + " 5. Внести изменения, следуя стилю и соглашениям проекта, и закоммитить их. \n", + " 6. Запушить ветку в свой fork на GitHub. \n", + " 7. Открыть pull request в оригинальный репозиторий. \n", + " 8. После мержа (или для дальнейшей работы) синхронизировать \n", + " свой fork с upstream, чтобы он оставался актуальным.\n", + " \n", + "\n", + "3.1.\n", + "\n", + " Какие практики принято соблюдать при создании Pull \n", + " Request чтобы закрыть автоматический issues?\n", + "\n", + " Упомянуть ишью в описании PR с ключевым словом и номером ишью (closes #1)\n", + " PR должен быть смёржен в ветку по умолчанию (main/master), иначе закрытие не сработает\n", + " Номер issue должен быть корректным и существовать в том же репозитории\n", + "\n", + " Какие практики принято соблюдать при создании commit чтобы закрыть автоматический issues?\n", + "\n", + " В целом те же что и для пулл реквеста, ключевые слова, \n", + " упоминания ишью, нахождение в том же репозитории\n", + "\n", + "\n", + "\n", + "3.2 Как отклонить/закрыть пул реквест? (предоставьте скриншот где это в гитхабе)\n", + "Вкладка \"pull requests\" в репозитории, при выборе пулл реквеста внизу страницы будет \"close pull request\"\n", + "![image.png](attachment:image.png)\n", + "\n", + "3.3 Перед отправкой пул реквеста нужно ли создавать ишьюс?\n", + "Это хорошая практика и зачастую нужно создать сначала ишью, но в случаях мелких изменений это необязательно\n", + "\n", + "3.4 В какой вкладке можно посмотреть список изменений который был в пул реквесте? (Рисунок 92)\n", + "Files changed\n", + "\n", + "3.5 В какой вкладке находится страница обсуждений пул реквеста? (Рисунок 94)\n", + "Conversation\n", + "\n", + "Создание запроса на слияние\n", + "\n", + "\n", + "4. Можно ли открыть пул реквест, если вы ничего не вносили в FORK?\n", + "Нет, нельзя открыть pull request, если вы ничего не вносили в свой fork\n", + "Pull request на GitHub создаётся из ветки с изменениями в целевую ветку\n", + "Если в вашем fork’е нет новых коммитов по сравнению с целевой веткой — GitHub покажет: \n", + "“There isn’t anything to compare” и не даст создать PR\n", + "\n", + "4.1 Что нужно сделать чтобы открыть пул реквест? (Рисунок 90)\n", + "При наличии запушенных изменений нажать на \"Compare & pull request\"\n", + "\n", + "4.2 Что нужно сделать Если ваш Форк устарел?\n", + "Нажать Sync fork\n", + "\n", + "4.3 Что нужно сделать если в пул реквесте имеются конфликты слияния (Рисунок 96)\n", + "нужно синхронизировать его с оригинальным репозиторием: добавить remote upstream, \n", + "получить свежие изменения (git fetch upstream), обновить свою локальную ветку (main/master) \n", + "через merge или rebase, и отправить обновления в свой fork на GitHub (git push origin main).\n", + "\n", + "Отрывки кода\n", + "\n", + "\n", + "5. Что нужно сделать Для добавления отрывка кода в комментарии к ишьюсу? (Рисунок 104)\n", + "Для добавления отрывка кода следует обрамить его обратными кавычками\n", + "\n", + "5.1 На какую клавишу нажать клавишу чтобы выделенный текст был включён как цитата в ваш комментарий?(Рисунок 105)\n", + "r\n", + "\n", + "5.2 Как вставить картинку в ишьюс? (Рисунок 108)\n", + "Воспользоваться шаблоном Markdown \\!\\[описание\\]\\(ссылка\\)\n", + "Или просто вставить картинку из буфера или drag and drop\n", + "\n", + "Поддержание GitHub репозитория в актуальном состоянии\n", + "\n", + "\n", + "6. Как понять что ваш форк устарел?\n", + "GitHub покажет сообщение 'This branch is behind main by (some) commits'\n", + "\n", + "6.1 Как обновить форк?\n", + "Sync fork\n", + "\n", + "Добавление участников\n", + "\n", + "\n", + "7. Как добавить участников в ваш репозиторий, чтобы команда могла работать над одним репозиторием? (Рисунок 112)\n", + "На странице репозитория -> settings -> collaborators -> add collaborators\n", + "\n", + "Упоминания и уведомления\n", + "\n", + "\n", + "8. Какой символ нужен для упоминания кого-либо? (Рисунок 118)\n", + "@\n", + "\n", + "8.1 Где находится Центр уведомлений, напишите ссылку (Рисунок 121)\n", + "https://github.com/notifications\n", + "\n", + "Особенные файлы\n", + "\n", + "\n", + "9. Что такое и зачем нужен файл README\n", + "README — это текстовый файл в корне репозитория, который описывает проект: что он делает, его цели и особенности\n", + "Содержит инструкции, зависимости, примеры кода\n", + "Помогает быстро понять, как установить, запустить и использовать проект\n", + "\n", + "9.1 Что такое и зачем нужен файл CONTRIBUTING (Рисунок 122)\n", + "GitHub будет показывать ссылку на него при создании любого запроса на слияние\n", + "Файл CONTRIBUTING это руководство для участников проекта, нужен чтобы\n", + "Объяснить, как правильно вносить вклад \n", + "Указать требования к коду, стилю, тестам и коммитам\n", + "Описать процесс работы с pull request’ами и issue\n", + "\n", + "Управление проектом\n", + "\n", + "\n", + "10. Как изменить основную ветку (Рисунок 123)\n", + "В настройках репозитория на закладке «Options»\n", + "Просто выберите нужную ветку из выпадающего меню и она станет основной для\n", + "большинства операций, включая извлечение кода при клонировании репозитория\n", + "\n", + "10.1 Как передать проект? какая кнопка? (рисунок 124)\n", + "Кнопка «Transfer ownership» в настройках репозитория на закладке «Options»\n", + "\n", + "10.2 Что такое файл .gitignore?\n", + "Файл .gitignore указывает Git, какие файлы и директории \n", + "следует игнорировать и не отслеживать в репозитории, \n", + "например временные, локальные или секретные файлы\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/github/quiz.py b/github/quiz.py new file mode 100644 index 00000000..3722672d --- /dev/null +++ b/github/quiz.py @@ -0,0 +1,262 @@ +"""Contributing issue.""" + +# 1.1. Что такое GitHub? +# GitHub — это платформа для хостинга Git-репозиториев и совместной разработки +# +# 1.2. Как GitHub связан с Git? +# GitHub использует Git как систему контроля версий +# Git работает локально +# GitHub — удалённый хостинг для репозиториев +# +# 1.3. Чем отличается fork репозитория от его клонирования (clone)? +# Fork создаёт копию репозитория на GitHub (в вашем аккаунте) +# clone — копирует репозиторий на компьютер. +# +# 1.4. Зачем нужны и как работают pull requests? +# Pull request — запрос на слияние изменений из одной ветки в другую +# Используется для обсуждения и проверки кода перед слиянием +# +# 1.5. GitHub использует ваш почтовый адрес для привязки ваших Git +# коммитов к вашей учётной записи? +# Да, GitHub связывает коммиты с учётной записью по +# email, указанному в настройках Git и GitHub +# +# 1.6 Какая команда генерирует SSH ключ для Доступа по +# SSH к репозиторию (Рисунок 83) +# `ssh-keygen -o` +# +# 2. Создайте ишьюс и запомните его номер, в +# https://github.com/SENATOROVAI/Data-Science-For- +# Beginners-from-scratch-SENATOROV/issues, +# назовите его "UPDATE README", в дескрипшене +# добавьте список задач (Рисунок 102) +# +# https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV/issues/401 +# +# 2.1. Если вы хотите вносить свой вклад в уже +# существующие проекты, в которых у нас нет прав на внесения +# изменений путём отправки (push) изменений, вы можете +# создать своё собственное ответвление, +# что нужно сделать чтобы создать собственное ответвление? +# (Рисунок 88), сделайте ответвление +# https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV, +# и вставьте сюда ссылку на ваше ответвление +# +# https://github.com/oh-ddy/Data-Science-For-Beginners-from-scratch-SENATOROV +# +# +# 2.2 создайте ветку dev в ФОРКЕ Data-Science-For-Beginners, +# вставьте сюда ссылку на вашу ветку dev +# +# https://github.com/oh-ddy/Data-Science-For-Beginners-from-scratch-SENATOROV/tree/dev +# +# 2.3 В README файле вашего ФОРКА, добавьте ссылку на мой телеграм канал +# https://t.me/RuslanSenatorov, +# сохраните коммит, название коммита - в тайтле название ишьюса +# (#номер_ишьюс), в дескрипшене - +# Closes #NUMBER-ISSUES номер возьмите из пункта 2 +# +# **сделано** +# +# 2.4 Отправьте пул реквест из ФОРКА в основу В ВАШУ ВЕТКУ, +# тайтл пул реквеста скопируйте +# из ISSUES-TITLE, в дескрипшине пул реквеста напишите +# Closes #NUMBER-ISSUES вставьте номер из пункта 2 +# +# **сделано** +# +# 2.5 Прокомментириуйте ваш пул реквест перед слиянием, +# перейдите во вкладку(Рисунок 92) +# и напишите "ок", потом нажимайте сабмит ревью +# затем не выходя из этой вкладки, в файле README, +# добавьте туда ссылку на https://t.me/SENATOROVAI +# +# **сделано** +# +# 2.6 Выполните Merge pull request (Рисунок 116), +# вставьте сюда ссылку на ваш пул реквест +# +# https://github.com/oh-ddy/Data-Science-For-Beginners-from-scratch-SENATOROV/pull/1 +# +# 2.7 Вставьте сюда ссылку на закрытые пул реквесты +# в репозитории, найти можно тут +# +# https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV/pulls?q=is%3Apr+is%3Aclosed +# - SENATOROV +# +# 2.8 Как посмотреть какие файлы были в +# репозитории на момент определенного коммита? +# вставьте сюда ссылку на любой коммит, где взять ссылку? +# +# https://github.com/SENATOROVAI/Data-Science-For-Beginners-from-scratch-SENATOROV/tree/6e92003c6384148233fa1878594f4ba10aef6e5f +# +# 2.9 как открыть запрос слияния, указывающий на +# другой запрос слияния и зачем это нужно? (Рисунок 117) +# +# При открытии запроса на слияние вверху страницы есть меню для выбора +# целевой и +# исходной веток. Если нажать кнопку Edit справа, +# то станет доступным выбор не только +# исходной ветки, а ещё и форка. +# Здесь можно указать новую ветку для слияния с другим запросом слияния или +# другим +# форком проекта. +# Далее упомянуть другой PR в описании или комментарии с помощью #номер — +# это создаёт ссылку и уведомление, но не техническую зависимость. +# Это нужно для того чтобы предлагать улучшение +# чужому пулл реквесту или организовать цепочку изменений +# +# +# Рабочий процесс с использованием GitHub +# +# +# 3. Напишите 8 пунктов, которые нужно сделать, +# чтобы внести вклад в чужой проект. +# +# 1. Ознакомиться с проектом: прочитать README, LICENSE, CONTRIBUTING.md, +# а также посмотреть открытые issues. +# 2. Сделать fork репозитория, чтобы получить свою копию на GitHub. +# 3. Клонировать свой fork локально и настроить +# remote upstream на оригинальный репозиторий. +# 4. Создать новую ветку на основе актуальной ветки main/master из +# upstream. +# 5. Внести изменения, следуя стилю и соглашениям проекта, и закоммитить +# их. +# 6. Запушить ветку в свой fork на GitHub. +# 7. Открыть pull request в оригинальный репозиторий. +# 8. После мержа (или для дальнейшей работы) синхронизировать +# свой fork с upstream, чтобы он оставался актуальным. +# +# +# 3.1. +# +# Какие практики принято соблюдать при создании Pull +# Request чтобы закрыть автоматический issues? +# +# Упомянуть ишью в описании PR с ключевым словом и номером ишью (closes #1) +# PR должен быть смёржен в ветку по умолчанию (main/master), иначе +# закрытие не сработает +# Номер issue должен быть корректным и существовать в том же репозитории +# +# Какие практики принято соблюдать при создании commit чтобы закрыть +# автоматический issues? +# +# В целом те же что и для пулл реквеста, ключевые слова, +# упоминания ишью, нахождение в том же репозитории +# +# +# +# 3.2 Как отклонить/закрыть пул реквест? (предоставьте скриншот где это в +# гитхабе) +# Вкладка "pull requests" в репозитории, при выборе пулл реквеста внизу +# страницы будет "close pull request" +# ![image.png](attachment:image.png) +# +# 3.3 Перед отправкой пул реквеста нужно ли создавать ишьюс? +# Это хорошая практика и зачастую нужно создать сначала ишью, но в случаях +# мелких изменений это необязательно +# +# 3.4 В какой вкладке можно посмотреть список изменений который был в пул +# реквесте? (Рисунок 92) +# Files changed +# +# 3.5 В какой вкладке находится страница обсуждений пул реквеста? (Рисунок 94) +# Conversation +# +# Создание запроса на слияние +# +# +# 4. Можно ли открыть пул реквест, если вы ничего не вносили в FORK? +# Нет, нельзя открыть pull request, если вы ничего не вносили в свой fork +# Pull request на GitHub создаётся из ветки с изменениями в целевую ветку +# Если в вашем fork’е нет новых коммитов по сравнению с целевой веткой — +# GitHub покажет: +# “There isn’t anything to compare” и не даст создать PR +# +# 4.1 Что нужно сделать чтобы открыть пул реквест? (Рисунок 90) +# При наличии запушенных изменений нажать на "Compare & pull request" +# +# 4.2 Что нужно сделать Если ваш Форк устарел? +# Нажать Sync fork +# +# 4.3 Что нужно сделать если в пул реквесте имеются конфликты слияния +# (Рисунок 96) +# нужно синхронизировать его с оригинальным репозиторием: добавить remote +# upstream, +# получить свежие изменения (git fetch upstream), обновить свою локальную +# ветку (main/master) +# через merge или rebase, и отправить обновления в свой fork на GitHub (git +# push origin main). +# +# Отрывки кода +# +# +# 5. Что нужно сделать Для добавления отрывка кода в комментарии к ишьюсу? +# (Рисунок 104) +# Для добавления отрывка кода следует обрамить его обратными кавычками +# +# 5.1 На какую клавишу нажать клавишу чтобы выделенный текст был включён как +# цитата в ваш комментарий?(Рисунок 105) +# r +# +# 5.2 Как вставить картинку в ишьюс? (Рисунок 108) +# Воспользоваться шаблоном Markdown \!\[описание\]\(ссылка\) +# Или просто вставить картинку из буфера или drag and drop +# +# Поддержание GitHub репозитория в актуальном состоянии +# +# +# 6. Как понять что ваш форк устарел? +# GitHub покажет сообщение 'This branch is behind main by (some) commits' +# +# 6.1 Как обновить форк? +# Sync fork +# +# Добавление участников +# +# +# 7. Как добавить участников в ваш репозиторий, чтобы команда могла работать +# над одним репозиторием? (Рисунок 112) +# На странице репозитория -> settings -> collaborators -> add collaborators +# +# Упоминания и уведомления +# +# +# 8. Какой символ нужен для упоминания кого-либо? (Рисунок 118) +# @ +# +# 8.1 Где находится Центр уведомлений, напишите ссылку (Рисунок 121) +# https://github.com/notifications +# +# Особенные файлы +# +# +# 9. Что такое и зачем нужен файл README +# README — это текстовый файл в корне репозитория, который описывает проект: +# что он делает, его цели и особенности +# Содержит инструкции, зависимости, примеры кода +# Помогает быстро понять, как установить, запустить и использовать проект +# +# 9.1 Что такое и зачем нужен файл CONTRIBUTING (Рисунок 122) +# GitHub будет показывать ссылку на него при создании любого запроса на слияние +# Файл CONTRIBUTING это руководство для участников проекта, нужен чтобы +# Объяснить, как правильно вносить вклад +# Указать требования к коду, стилю, тестам и коммитам +# Описать процесс работы с pull request’ами и issue +# +# Управление проектом +# +# +# 10. Как изменить основную ветку (Рисунок 123) +# В настройках репозитория на закладке «Options» +# Просто выберите нужную ветку из выпадающего меню и она станет основной для +# большинства операций, включая извлечение кода при клонировании репозитория +# +# 10.1 Как передать проект? какая кнопка? (рисунок 124) +# Кнопка «Transfer ownership» в настройках репозитория на закладке «Options» +# +# 10.2 Что такое файл .gitignore? +# Файл .gitignore указывает Git, какие файлы и директории +# следует игнорировать и не отслеживать в репозитории, +# например временные, локальные или секретные файлы +# From 415312fdd7a3f872dc2331ad7ed8942dd5b695f6 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 24 Sep 2025 15:39:54 +0300 Subject: [PATCH 18/24] [TASK] Cpython (https://github.com/SENATOROVAI/intro-cs/issues/4) closes https://github.com/SENATOROVAI/intro-cs/issues/4 --- python/cpython.ipynb | 108 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 python/cpython.ipynb diff --git a/python/cpython.ipynb b/python/cpython.ipynb new file mode 100644 index 00000000..10039de3 --- /dev/null +++ b/python/cpython.ipynb @@ -0,0 +1,108 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "9ebd9f3a", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"cpython issue.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "500c6264", + "metadata": {}, + "source": [ + "1. Что такое CPython и чем он отличается от Python?\n", + "Официальная реализация питона написанная на языке С\n", + "CPython - именно интерпретатор, который выполняет Python-код\n", + "Python - язык программирования\n", + "\n", + "3. Сколько существует реализаций Python, и какая из них самая популярная?\n", + "Реализаций 6, самая популярная CPython\n", + "\n", + "4. На каком языке написан CPython?\n", + "На языке С\n", + "\n", + "5. (опционально) Кто создал CPython?\n", + "Гвидо ван Россум\n", + "\n", + "6. Почему Python считается быстрым, несмотря на то, что это интерпретируемый язык?\n", + "Питон вызывает инструкции из языка С и в целом так как он написан на С\n", + "1:07 в видео\n", + "\n", + "7. Напишите путь к Интерпретатору CPython на вашем компьютере\n", + "C:\\Users\\uhddy\\AppData\\Local\\Programs\\Python\\Python313\\python.exe\n", + "\n", + "8. Что содержится в папке include в CPython?\n", + "Файлы для разработки и сборки С-расширений для PYTHON\n", + "\n", + "9. Где можно найти исходный код CPython дайте ссылку на репозиторий гитхаб\n", + "https://github.com/python/cpython\n", + "\n", + "10. (опционально) Как работает интерпретатор CPython при выполнении кода?\n", + "Выполняет программу построчно\n", + "\n", + "11. Какая команда используется для запуска файла с помощью CPython?\n", + "python filename\n", + "можно указать в формате \"путь до интерпретатора\" \"путь до файла с текстом(не обязательно .py)\"\n", + "\n", + "12. Можно ли запускать текстовые файлы через интерпретатор Python? Почему?\n", + "Можно, интерпретатору все равно какое расширение, лишь бы был текст\n", + "\n", + "13. Как указать путь к интерпретатору и файлу для выполнения кода?\n", + "Взять пути до интерпретатора и файла через свойства файлов, в терминале ввести\n", + "\"путь до интерпретатора\" \"путь до файла с текстом(не обязательно .py)\"\n", + "\n", + "14. Чем PyPy отличается от CPython?\n", + "Скоростью работы, однако он достаточно новый и не совместим с некоторыми проектами\n", + "\n", + "15. Почему PyPy не может использоваться для всех проектов на Python?\n", + "Он достаточно новый и не совместим с некоторыми проектами\n", + "\n", + "16. Где можно скачать PyPy\n", + "htttps://pypy.org\n", + "\n", + "17. Как установить PyPy после скачивания?\n", + "Распаковать архив с интерпретатором, запустить интерпретатор\n", + "\n", + "18. Как запустить файл с помощью PyPy?\n", + "\"путь до интерпретатора pypy\" \"путь до файла с текстом(не обязательно .py)\"\n", + "\n", + "19. Почему PyPy выполняет код быстрее, чем CPython?\n", + "благодаря JIT-компиляции (Just-In-Time compilation)\n", + "\n", + "Задание 1: Поиск и установка CPython\n", + "C:\\Users\\uhddy>python --version\n", + "Python 3.13.5\n", + "\n", + "Задание 2: Исследование структуры CPython\n", + "77 файлов .h в папке include\n", + "\n", + "Задание 3: Запуск файла с помощью CPython\n", + "Сделано, файлы запускаются вне зависимости от расширения \n", + "\n", + "Задание 4: Установка и использование PyPy\n", + "\"Hello from pypy!\" выводится не зависимо от расширения\n", + "\n", + "Задание 5: Сравнение производительности CPython и PyPy\n", + "Запустите этот файл сначала через CPython, а затем через PyPy. Запишите результаты времени выполнения для обоих интерпретаторов.\n", + "Сделайте вывод о разнице в производительности.\n", + "\n", + "pypy - 0.009631872177124023 seconds\n", + "cpython - 0.5141646862030029 seconds\n", + "\n", + "Огромная разница в производительности, в 50+ раз" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a61b3c94d5f76a71ab7ca4107b064576f5c3ba7a Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 24 Sep 2025 15:40:31 +0300 Subject: [PATCH 19/24] [TASK] Cpython (https://github.com/SENATOROVAI/intro-cs/issues/4) closes https://github.com/SENATOROVAI/intro-cs/issues/4 --- python/cpython.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 python/cpython.py diff --git a/python/cpython.py b/python/cpython.py new file mode 100644 index 00000000..4bc3565c --- /dev/null +++ b/python/cpython.py @@ -0,0 +1,82 @@ +"""Cpython issue.""" + +# 1. Что такое CPython и чем он отличается от Python? +# Официальная реализация питона написанная на языке С +# CPython - именно интерпретатор, который выполняет Python-код +# Python - язык программирования +# +# 3. Сколько существует реализаций Python, и какая из них самая популярная? +# Реализаций 6, самая популярная CPython +# +# 4. На каком языке написан CPython? +# На языке С +# +# 5. (опционально) Кто создал CPython? +# Гвидо ван Россум +# +# 6. Почему Python считается быстрым, несмотря на то, что это интерпретируемый язык? +# Питон вызывает инструкции из языка С и в целом так как он написан на С +# 1:07 в видео +# +# 7. Напишите путь к Интерпретатору CPython на вашем компьютере +# C:\Users\uhddy\AppData\Local\Programs\Python\Python313\python.exe +# +# 8. Что содержится в папке include в CPython? +# Файлы для разработки и сборки С-расширений для PYTHON +# +# 9. Где можно найти исходный код CPython дайте ссылку на репозиторий гитхаб +# https://github.com/python/cpython +# +# 10. (опционально) Как работает интерпретатор CPython при выполнении кода? +# Выполняет программу построчно +# +# 11. Какая команда используется для запуска файла с помощью CPython? +# python filename +# можно указать в формате "путь до интерпретатора" "путь до файла с текстом(не обязательно .py)" +# +# 12. Можно ли запускать текстовые файлы через интерпретатор Python? Почему? +# Можно, интерпретатору все равно какое расширение, лишь бы был текст +# +# 13. Как указать путь к интерпретатору и файлу для выполнения кода? +# Взять пути до интерпретатора и файла через свойства файлов, в терминале ввести +# "путь до интерпретатора" "путь до файла с текстом(не обязательно .py)" +# +# 14. Чем PyPy отличается от CPython? +# Скоростью работы, однако он достаточно новый и не совместим с некоторыми проектами +# +# 15. Почему PyPy не может использоваться для всех проектов на Python? +# Он достаточно новый и не совместим с некоторыми проектами +# +# 16. Где можно скачать PyPy +# htttps://pypy.org +# +# 17. Как установить PyPy после скачивания? +# Распаковать архив с интерпретатором, запустить интерпретатор +# +# 18. Как запустить файл с помощью PyPy? +# "путь до интерпретатора pypy" "путь до файла с текстом(не обязательно .py)" +# +# 19. Почему PyPy выполняет код быстрее, чем CPython? +# благодаря JIT-компиляции (Just-In-Time compilation) +# +# Задание 1: Поиск и установка CPython +# C:\Users\uhddy>python --version +# Python 3.13.5 +# +# Задание 2: Исследование структуры CPython +# 77 файлов .h в папке include +# +# Задание 3: Запуск файла с помощью CPython +# Сделано, файлы запускаются вне зависимости от расширения +# +# Задание 4: Установка и использование PyPy +# "Hello from pypy!" выводится не зависимо от расширения +# +# Задание 5: Сравнение производительности CPython и PyPy +# Запустите этот файл сначала через CPython, а затем через PyPy. Запишите результаты времени выполнения для обоих интерпретаторов. +# Сделайте вывод о разнице в производительности. +# +# pypy - 0.009631872177124023 seconds +# cpython - 0.5141646862030029 seconds +# +# Огромная разница в производительности, в 50+ раз From f2dc0aeefc938fca71b3a79c8d31d5b80628cf64 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 10 Dec 2025 12:48:27 +0300 Subject: [PATCH 20/24] [TASK] Python (https://github.com/SENATOROVAI/python/issues/1) closes https://github.com/SENATOROVAI/python/issues/1 --- ...pter_4_choosing_understandable_names.ipynb | 270 +++ ...science_and_programming_fundamentals.ipynb | 290 +++ .../chapter_2_introduction_to_python.ipynb | 242 ++ .../makarov/chapter_10_numpy_array.ipynb | 2047 +++++++++++++++++ .../makarov/chapter_15_iterators.ipynb | 723 ++++++ .../makarov/chapter_16_decorators.ipynb | 1285 +++++++++++ python_issue/makarov/chapter_1_pandas.ipynb | 1180 ++++++++++ .../chapter_1_variables_in_python.ipynb | 298 +++ .../chapter_2_data_types_in_python.ipynb | 605 +++++ .../chapter_3_conditions_and_cycles.ipynb | 573 +++++ python_issue/makarov/chapter_4_files.ipynb | 254 ++ .../chapter_5_date_and_time_in_python.ipynb | 574 +++++ .../makarov/chapter_6_functions.ipynb | 1013 ++++++++ .../chapter_7_lists_tuples_and_sets.ipynb | 1127 +++++++++ .../chapter_8_dictionary_in_python.ipynb | 1255 ++++++++++ ...pter_9_classes_and_objects_in_python.ipynb | 974 ++++++++ python_issue/oop_molchanov.ipynb | 1375 +++++++++++ 17 files changed, 14085 insertions(+) create mode 100644 python_issue/clean_code/chapter_4_choosing_understandable_names.ipynb create mode 100644 python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.ipynb create mode 100644 python_issue/made-easy/chapter_2_introduction_to_python.ipynb create mode 100644 python_issue/makarov/chapter_10_numpy_array.ipynb create mode 100644 python_issue/makarov/chapter_15_iterators.ipynb create mode 100644 python_issue/makarov/chapter_16_decorators.ipynb create mode 100644 python_issue/makarov/chapter_1_pandas.ipynb create mode 100644 python_issue/makarov/chapter_1_variables_in_python.ipynb create mode 100644 python_issue/makarov/chapter_2_data_types_in_python.ipynb create mode 100644 python_issue/makarov/chapter_3_conditions_and_cycles.ipynb create mode 100644 python_issue/makarov/chapter_4_files.ipynb create mode 100644 python_issue/makarov/chapter_5_date_and_time_in_python.ipynb create mode 100644 python_issue/makarov/chapter_6_functions.ipynb create mode 100644 python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb create mode 100644 python_issue/makarov/chapter_8_dictionary_in_python.ipynb create mode 100644 python_issue/makarov/chapter_9_classes_and_objects_in_python.ipynb create mode 100644 python_issue/oop_molchanov.ipynb diff --git a/python_issue/clean_code/chapter_4_choosing_understandable_names.ipynb b/python_issue/clean_code/chapter_4_choosing_understandable_names.ipynb new file mode 100644 index 00000000..125d48b4 --- /dev/null +++ b/python_issue/clean_code/chapter_4_choosing_understandable_names.ipynb @@ -0,0 +1,270 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "a949f413", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Choosing understandable names.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "574f9c8c", + "metadata": {}, + "source": [ + "*Имена формально называются идентификаторами*\n", + "\n", + "\n", + "### Схемы регистра имен\n", + "\n", + "\n", + "Так как в идентификаторах Python различается регистр символов и они не могут содержать пробельные\n", + "символы, программисты используют несколько схем в идентификаторах, состоящих из нескольких слов.\n", + "\n", + "\n", + "1. Змеиный регистр (snake_case) разделяет слова символом подчеркивания, который напоминает ползущую\n", + "между словами змею. В этом случае все буквы записываются в нижнем регистре, а константы часто \n", + "записываются в верхнем змеином регистре (UPPER_SNAKE_CASE).\n", + "\n", + "2. Верблюжий регистр (camelCase) — слова записываются в нижнем регистре, но второе и следующие \n", + "слова начинаются с заглавной. Эта схема в большин-\n", + "стве случаев подразумевает, что первое слово начинается с буквы нижнего регистра. \n", + "Буквы верхнего регистра напоминают верблюжьи горбы.\n", + "\n", + "3. Схема Pascal (PascalCase) — названа так, потому что применяется в языке программирования Pascal\n", + "Аналогична схеме верблюжьего регистра, но первое слово в ней тоже начинается с заглавной.\n", + "\n", + "\n", + "### Соглашения об именах PEP 8\n", + "\n", + "\n", + "- **Символы в идентификаторах**:\n", + " - Должны быть **ASCII-символами** (латинские буквы без диакритических знаков)\n", + "\n", + "\n", + "- **Стили именования**:\n", + " - **Модули**: короткие, только строчные буквы (`lowercase`)\n", + " - **Классы**: записываются в **PascalCase** (CapWords).\n", + " - **Константы**: записываются в **UPPER_SNAKE_CASE** (все заглавные с подчёркиваниями).\n", + " - **Функции, методы и переменные**: записываются в **snake_case** (строчные с подчёркиваниями).\n", + "\n", + "\n", + "- **Специальные аргументы**:\n", + " - Первый аргумент **метода экземпляра** — всегда `self` (в нижнем регистре)\n", + " - Первый аргумент **метода класса** — всегда `cls` (в нижнем регистре)\n", + "\n", + "\n", + "- **Атрибуты классов**:\n", + " - **Приватные** атрибуты начинаются с символа подчёркивания (`_`)\n", + " - **Публичные** атрибуты **не начинаются** с подчёркивания\n", + "\n", + "\n", + "- **Гибкость применения правил**:\n", + " - PEP 8 **не обязателен к неукоснительному соблюдению**\n", + " - Допустимо использовать идентификаторы на других языках\n", + " - Можно использовать другие стили (например, camelCase), если это улучшает читаемость\n", + "\n", + "- **Главный принцип читаемости**:\n", + " - Важнее не выбор конкретной схемы именования, а **последовательность её применения** в рамках проекта или модуля\n", + "\n", + "\n", + "### Длина имен\n", + "\n", + "\n", + "**Рекомендации по выбору имён переменных и функций**\n", + "\n", + "**Общий принцип**\n", + "- Код читают чаще, чем пишут → **предпочтение более длинным, понятным именам**, \n", + "даже если их дольше вводить\n", + "\n", + "\n", + "**Слишком короткие имена — проблема читаемости**\n", + "\n", + "\n", + "- **Одно- или двухбуквенные имена** (например, `g`) неясны: неизвестно, какое слово они обозначают\n", + "\n", + "\n", + "- **Сокращения** (`mon` → monitor/month/monster?) вводят в заблуждение\n", + "\n", + "\n", + "- **Однословные имена** (`start`) не указывают контекст: начало чего?\n", + "\n", + "\n", + "- Такие имена могут быть понятны автору в момент написания, \n", + "но **непонятны другим или самому через время**\n", + "\n", + "\n", + "**Допустимые исключения для коротких имён**\n", + "\n", + "\n", + "- `i`, `j`, `k` — для индексов в циклах `for`\n", + "\n", + "\n", + "- `x`, `y` — для декартовых координат\n", + "\n", + "\n", + "- Иногда допустимы `w`/`h` (width/height) или `n` (number), \n", + "но это **не всегда очевидно** другим\n", + "\n", + "\n", + "**Слишком длинные имена — когда это оправдано**\n", + "\n", + "\n", + "- Чем **шире область видимости** (например, глобальная переменная в большом проекте), \n", + "тем **более содержательным должно быть имя**\n", + "\n", + "\n", + "- Пример: `payment` — нормально для локальной переменной; \n", + " `salesClientMonthlyPayment` — лучше для глобального контекста\n", + "\n", + "\n", + "- **Уточняющие слова устраняют неоднозначность** → лучше перестраховаться, чем недоговорить\n", + "\n", + "\n", + "**Не пропускайте буквы**\n", + "\n", + "\n", + "- Имена вроде `memcpy` или `strcmp` (из C) **устарели** и плохо читаются\n", + "\n", + "\n", + "- Имя должно быть **произносимым и понятным**\n", + "\n", + "\n", + "- Предпочтение **естественным фразам**: `number_of_trials` лучше, чем `number_trials`\n", + "\n", + "\n", + "**Префиксы: когда полезны, а когда избыточны**\n", + "\n", + "\n", + "- **Избыточные префиксы**:\n", + " - `catWeight` в классе `Cat` — излишне, так как `weight` и так относится к кошке\n", + " - **Венгерская нотация** (`strName`, `iVacationDays`) — устарела: \n", + " современные IDE и типизация делают её ненужной\n", + "\n", + "\n", + "- **Полезные префиксы**:\n", + " - `is_`, `has_` для **логических значений**: \n", + " `is_vehicle`, `has_key()` → код читается как естественный язык\n", + " - **Единицы измерения** в имени (`weight_kg`, `speed_mph`) — **не венгерская нотация**\n", + " Пример: ошибка Mars Climate Orbiter (1999) из-за путаницы между \n", + " фунтами и ньютонами обошлась в $125 млн\n", + "\n", + "\n", + "**Последовательные числовые суффиксы — признак плохого дизайна**\n", + "\n", + "\n", + "- Имена вроде `payment1`, `payment2`, `payment3` **не объясняют различий**\n", + "\n", + "\n", + "- Лучшие альтернативы:\n", + " - Объединить в коллекцию: `payments = [p1, p2, p3]`\n", + " - Передавать параметр: `makePayment(priority=1, amount)`\n", + " - Использовать осмысленные имена: `makeHighPriorityPayment()`, `make1stQuarterPayment()`\n", + "\n", + "\n", + "- Числовые суффиксы допустимы **только при веской причине**, а не из лени\n", + "\n", + "\n", + "**Выбирайте имена, пригодные для поиска**\n", + "\n", + "\n", + "- Короткие и обобщённые имена (`num`, `a`, `email`) вызывают **ложные совпадения** \n", + "при поиске (Ctrl+F)\n", + "\n", + "\n", + "- **Уникальные, конкретные имена** проще найти и понять:\n", + " - Вместо `email` → `emailAddress`, `replyToAddress`, `downloadEmailAttachment`\n", + "\n", + "\n", + "- Даже при наличии инструментов рефакторинга в IDE, **пишите так, будто их нет** — \n", + "это стимулирует выбор более осмысленных имён\n", + "\n", + "\n", + "## Не заменяйте встроенные имена\n", + "\n", + "\n", + "- **Никогда не используйте встроенные имена Python** (например, `list`, `set`, `str`, `open`) \n", + "**в качестве имён своих переменных**.\n", + " - Это **перезаписывает встроенные функции**, что может привести к ошибкам.\n", + " - Пример: после `list = ['cat', 'dog']` вызов `list(range(5))` вызовет \n", + " `TypeError: 'list' object is not callable`.\n", + "\n", + "\n", + "- **Как проверить, является ли имя встроенным**:\n", + " - Введите имя в интерактивной оболочке Python.\n", + " - Если возвращается объект (например, ``), имя занято.\n", + " - Попробуйте импортировать как модуль.\n", + " - `NameError` или `ModuleNotFoundError` означают, что имя свободно.\n", + "\n", + "\n", + "- **Часто переопределяемые встроенные имена** (избегайте их!):\n", + " - `all`, `any`, `date`, `email`, `file`, `format`, `hash`, `id`, `input`, `list`, `min`, \n", + " `max`, `object`, `open`, `random`, `set`, `str`, `sum`, `test`, `type`.\n", + "\n", + "\n", + "- **Не называйте свои `.py`-файлы так же, как сторонние модули**.\n", + " - Пример: файл `pyperclip.py` в рабочей директории **перекрывает** установленный \n", + " модуль `pyperclip`.\n", + " - При `import pyperclip` импортируется ваш файл, а не настоящий модуль → \n", + " вызов `pyperclip.copy()` завершится ошибкой `AttributeError`.\n", + "\n", + "\n", + "- **Общее правило**: избегайте конфликтов имён с встроенными функциями, модулями и сторонними \n", + "библиотеками — это частая причина неочевидных ошибок, особенно `AttributeError` при отсутствии \n", + "ожидаемых функций.\n", + "\n", + "\n", + "## Итоги\n", + "\n", + "### Плохие примеры имён\n", + "- **`data`** — бессодержательно, так как *все* переменные содержат данные.\n", + "- **`var`** — тавтология (аналог клички «Собака» для собаки).\n", + "- **`temp`** — неинформативно; все переменные временные по своей природе.\n", + "- Такие имена распространены, но их **следует избегать**.\n", + "\n", + "### Хорошая альтернатива\n", + "- Вместо обобщённых имён используйте **конкретные и описательные**:\n", + " - Например: `temperatureVariance` вместо `tempVarData`.\n", + "\n", + "### Основные принципы выбора имён\n", + "- Выбор имён не связан с алгоритмами, но **критически важен для читаемости кода**.\n", + "- Следуйте рекомендациям PEP 8:\n", + " - Модули — `lowercase`.\n", + " - Классы — `PascalCase`.\n", + " - Функции/переменные — `snake_case`.\n", + " - Константы — `UPPER_SNAKE_CASE`.\n", + "- Имена **не должны быть слишком короткими или слишком длинными**.\n", + " - Лучше слегка избыточное, чем недостаточно содержательное имя.\n", + "\n", + "### Требования к хорошему имени\n", + "- **Лаконичное**, но **информативное**.\n", + "- **Уникальное** — легко находится через поиск (Ctrl+F).\n", + "- **Понятное** даже тем, для кого английский не родной.\n", + "- **Без шуток, каламбуров и культурных отсылок** — они не универсальны и часто непонятны.\n", + "- **Прямолинейное, традиционное, без юмора**.\n", + "\n", + "### Избегайте конфликтов с встроенными именами\n", + "- Не используйте имена, зарезервированные стандартной библиотекой Python:\n", + " - `all`, `any`, `date`, `email`, `file`, `format`, `hash`, `id`, `input`, `list`, `min`, \n", + " `max`, `object`, `open`, `random`, `set`, `str`, `sum`, `test`, `type`.\n", + "- Их переопределение вызывает **скрытые и трудноуловимые ошибки**.\n", + "\n", + "### Главный вывод\n", + "- Компьютеру безразличны имена — они нужны **людям**.\n", + "- Хорошо читаемый код → понятный код → легко изменяемый код → проще исправлять ошибки и \n", + "добавлять функции.\n", + "- **Понятные имена — основа качественного программного обеспечения.**\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.ipynb b/python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.ipynb new file mode 100644 index 00000000..0ce05372 --- /dev/null +++ b/python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.ipynb @@ -0,0 +1,290 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "21f70375", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Introduction to Data Science and Programming Fundamentals.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "67204e08", + "metadata": {}, + "source": [ + "# Введение в Data Science\n", + "\n", + "\n", + "**Data Science** - это научная дисциплина, которая включает в себя извлечение информации\n", + "из огромных объемов данных с использованием различных научных\n", + "методов, алгоритмов и процессов. Эта наука помогает обнаруживать в необработанных\n", + "данных скрытые закономерности.\n", + "\n", + "\n", + "Эта наука помогает нам:\n", + "- задавать правильные вопросы;\n", + "- находить основную причину проблемы;\n", + "- находить закономерности среди, на первый взгляд, хаотичных необработанных\n", + "данных;\n", + "- создавать модели для предиктивного анализа;\n", + "- визуализировать и отображать результаты с помощью графиков, информацион-\n", + "ных панелей и т. д.;\n", + "- наделять машины интеллектом;\n", + "- определять лояльность клиентов с помощью анализа настроений;\n", + "- принимать более качественные и быстрые решения;\n", + "- рекомендовать правильный продукт нужному клиенту для развития нашего бизнеса.\n", + "\n", + "\n", + "**Машинное обучение** - это инструмент для извлечения знаний из данных.\n", + "В машинном обучении модели могут обучаться на данных самостоятельно или\n", + "поэтапно: обучение с учителем, т. е. на данных, подготовленных человеком, или\n", + "обучение без учителя, в котором работа ведется над хаотичными и неорганизованными\n", + "данными.\n", + "\n", + "**Глубокое обучение** - это создание многослойных нейронных сетей в областях,\n", + "где требуется более продвинутый или быстрый анализ, а традиционное машинное\n", + "обучение не справляется. Под глубиной понимается наличие более одного\n", + "скрытого слоя нейронов в сети, которые проводят математические вычисления.\n", + "\n", + "**Большие данные** - это работа с огромными объемами часто неструктурированных\n", + "данных. Специфика этой сферы - инструменты и системы, способ1;1ые\n", + "выдерживать высокие нагрузки.\n", + "\n", + "\n", + "**Статистика**\n", + "Статистика лежит в основе Data Science. Правильная обработка статистики\n", + "может помочь вам извлечь больше информации и получить более значимые\n", + "результаты.\n", + "\n", + "**Базы данных**\n", + "Будучи специалистом по данным, вам необходимо понимать, как работают базы\n", + "данных, как ими управлять и как извлекать из них данные.\n", + "\n", + "**Моделирование**\n", + "Математические модели позволяют выполнять вычисления и прогнозы на основе\n", + "того, что вы уже знаете о данных. Моделирование также относится к машинному\n", + "обучению и включает определение того, какой алгоритм больше подходит\n", + "для решения данной проблемы и как обучать эти модели.\n", + "\n", + "\n", + "**Программирование** - это идеи, преобразованные в пошаговые\n", + "инструкции, понятные компьютеру. Такая пошаговая инструкция называется **алгоритмом**.\n", + "\n", + "**Алгоритм** - это конечная последовательность четко определенных,\n", + "реализуемых компьютером инструкций для решения какой-то проблемы или\n", + "для выполнения вычислений. Алгоритмы всегда однозначны и используются для\n", + "вычислений, обработки данных, автоматизированных решений и других задач.\n", + "\n", + "\n", + "### Реальный пример алгоритма\n", + "\n", + "\n", + "Шаг 1: Начало.\n", + "Шаг 2: Возьмите ковшик и налейте в него один стакан воды.\n", + "Шаг 3: Зажгите конфорку и поставьте на нее ковшик.\n", + "Шаг 4: Доведите воду до кипения.\n", + "Шаг 5: Добавьте в кипящую воду две столовые ложки сахара и две столовые ложки чайных листьев.\n", + "Шаг 6: Добавьте в кипящую смесь одну чашку молока.\n", + "Шаг 7: Варите содержимое в течение одной минуты.\n", + "Шаг 8: Выключите конфорку.\n", + "Шаг 9: Процедите чай через сито.\n", + "Шаг 10: Разлейте чай по чашкам и подавайте.\n", + "Шаг 11: Конец.\n", + "\n", + "\n", + "Алгоритмы можно изображать в графической форме с использованием определенных\n", + "обозначений. Полученное изображение называется блок-схемой.\n", + "В блок-схемах для представления различных функций программ используются\n", + "некоторые стандартные символы.\n", + "\n", + "\n", + "Компилятор - это программа, преобразующая исходный код в машинный.\n", + "\n", + "Интерпретатор - это компьютерная программа,\n", + "которая непосредственно выполняет инструкции, написанные на языке\n", + "программирования, без предварительной компиляции в программу на машинном\n", + "языке." + ] + }, + { + "attachments": { + "image-3.png": { + "image/png": "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Jy97jDMdREREpAqGDiIiIlKFcPXqVa8PryjpzJkzWL16NZo2bcrDK0SkuqysLCxduhR79uyR7oNCRPdHsNlsXocOp9MJp9MJjUbj83M6Tp48ie+//x7169dn6CAi1RWGjkOHDmH58uXystfy8vJgt9uh0WgUO+avZH+73Q6TyQSdTofg4GB52WtK7z/7u+dwOGA0GqHT6RASEiIve4wnkhIRucETSd3jiaTuqdGfJ5ISERERyTB0EBERkSoYOoiIiEgVDB1ERESkCoYOIiIiUgVDBxEREamCoYOIiIhUwdBBREREqmDoICIiIlX4zR1JbTYb2rdvLy8TESkuPj4eN2/e5B1J74J3JHVPjf7+dEfSBz50nDlzBsuWLcPp06cRFBSEgADfT87k5+dDFEUEBARAEAR52Wvs715eXp707B4lXt/U1FQkJyejdu3aqFixorzsNVEUkZ+fr9j3x9/7F76+QUFBPn9/gAr7X9i/ffv2+PDDD+VlrykdCpTuz9Dhnhr9GTp8zGQywWKxwGAwKPJAIYfDAYfDodgPBfu7ZzabYTabodfrffJAIblNmzZh5cqVGDNmDDp06CAve03pN3V/72+1WmE0GqHX6xX5UFJ6/9nfPYYO99To70+hw/d/VhIRERHdBUMHERERqYKhg4iIiFTB0EFERESqYOggIiIiVTB0EBERkSoYOoiIiEgVDB1ERESkCoYOIiIiUoWQlZXl9R1JiR5kW7duxYYNG/D222+jdevW8jIREalEcDqdXocOp9MpPTtDidugWywW2Gw26HQ6aLVaedlrSu8/+7tntVphtVoVe303b96MVatWYfTo0Yo8NFDp74/S/fPy8uBwOBTrb7PZYDabodPpFHmMgdL7r0Z/u90OjUaj2G2ylexvt9thMpkUfX2V3H/2d8/hcMBoNEKn0/nkMRV89ooKzxZhf/f47BX3/L0/n73inr/357NX3FOjP5+9QkRERCTD0EFERESqYOggIiIiVTB0EBERkSoYOoiIiEgVDB1ERESkCoYOIiIiUgVDBxEREamCoYOIiIhUwdBBREREqmDoICIiIlUwdBAREZEqGDqIiIhIFQwdVGqlpKTgq6++wuTJk7Fv3z6MGDECY8eORWJionwoERGpgKGDSi2NRoPbt28jPj4emZmZSExMRH5+PqpUqSIfSkREKmDooFIrNDQU7dq1Q506dQAAYWFhaNSoEcqWLSsfSkREKmDooFItNDRUCh2hoaGIjo6WDyEiIpUwdFCpVhg0AgMDERUVhbp168qHEBGRShg6qFSrUaMGWrdujeDgYERERCAqKko+hIiIVMLQQaVaQEAAtFotwsPDUbVqVXmZiIhUJIiiKMpXesrhcMDpdEKr1SIwMFBe9prJZILFYoHBYEBwcLC87JWcnBxs3LgR69evR0BAAARBkA/xWn5+PkRRZP9i5OXlwel0QqPRICDA9zk4JSUFly9fRu3atREZGSkve00UReTn5yv2/fH3/oWvb1BQkCLvD6IoIjg4GE899RTeeOMNedlrTqcTdrsdWq0WQUFB8rLXlOxvNpuxa9cuLFiwQLHXNz8/Hw6HQ9HXV8mfz9LQPy8vDwEBAYq8fxa+vlFRURg0aBAef/xx+RCPCFlZWV6HDn924MABfPfddxAEAS1btpSXiegB53A4cPr0aVgsFsybNw9hYWHyIQ+ts2fP4j//+Q9u377t9YcFPZwsFguOHTuG27dvY9WqVV7fckBwOp1ehw6n0yn9papE0rVYLLDZbNDpdNBqtfLyfcvJycGsWbNw5MgRfPrpp2jevLl8CBH5gcOHD2POnDl4/PHHMWTIEHnZK3l5eXA4HIq9v+Xl5cFut0Oj0fh0psNsNmPVqlVYuHAhvvnmG3Ts2FE+hOieEhISMHXqVDRv3hxjxoyRlz0WEBgYCG+Xwmkd+XpfLYIgSNP78po3S1xcHK5fv45+/foxcBD5saioKISHh2PTpk3IzMws8rvuzVI4Le7r95/CRan3z6tXr+Lo0aPo168fAwfdl4yMDKxfvx4XLlxA3759i/yM3c/i+wNAfiInJwd79uxBSkoKAweRn6tatSr69euHypUrY8uWLfLyQ8dsNuPw4cM4ceIEAwfdt8zMTCQkJOD555/3+rBKoYc2dJw8eRLXrl3jLAdRKVE42/HTTz8hLS1NXn6oJCYm4vDhw5zloPtWOMtx7tw5PPvss/LyfXsoQwdnOYhKH852/D+c5SBfyMzMxPnz5/Gvf/3LZ7MceFhDB2c5iEonzna4znJ06NBBXia6p8JZjosXL6J///7yslceutDBWQ6i0uthn+3gLAf5QuEsx4svvujzexs9dKGDsxxEpdvDPNvBWQ7ylpKzHHjYQkdJZjmWLl2K+vXrY+bMmfKS4ubPnw9BEKSlU6dO2Ldvn3zY3+bnn39Gjx49sGDBAnkJf/31F3r27Cnte4cOHRAbG+syJjk5GWPHjpXG1K5dG/Pnz3cZQ+Sth3W2g7Mc5AtKznLgYQsdJZnleP3113H+/Hm899578pJicnJyMG3aNMycORPff/89RFFEUlISmjdvjlGjRmHjxo3yTVS3e/duTJ06FVeuXJGX8Ndff2Hy5MkwGAxIT0/H9evX0bZtW3z44YdS8EhOTsZXX32FQ4cOYc+ePRBFERMnTsQXX3zB4EE+9zDOdnCWg7yl9CwHHqbQUZJZjr/L2bNnsW/fPjzxxBMYOnQoUPDX2jPPPIPAwEDs3LlTvomqFi1ahO7du+Po0aPyEgDg9OnTSE5ORr9+/RAaGoqoqCj861//Qnh4uPSX5vHjx3HgwAE8/fTT6NKlCwDgqaeewvPPP4/ff/8d6enpsq5E9+9hm+3gLAf5gtKzHHiYQkdJZjngweGVZcuWoUKFCtKhgueeew4JCQnYuXMnWrVq5XKY5M7lrbfekrdCu3btsHPnTsybN89lvcFgQMWKFV3W3c2KFStc9qVw6dWrF86ePSuNW7lypcu4p59+2qV+N6tWrcLkyZMxduxYfP/99/IykpOTcebMGURFRaFhw4bS+sjISNSsWRNnz57FmTNnkJ6eDrPZjHr16kljoqKi0KhRI5w/fx579+6V1t9p7dq1qFu3LqZNmyatO3/+PF577TU89dRTiI+PBwAYjUZ88cUXLv//gwYNuqNTUXv37kXbtm2LfN+eeOIJqe+GDRtQt25dfPLJJwCA7du3Izo6Gj169EBcXBz279+Pdu3aFekhCEKRMa+88or0tS9evIjBgwdLYxs1aoTVq1cDAH788UfUrFkTs2fPdhk/ZMgQdOvWDXFxcThw4AAee+wxvPTSS0XG1KhRA59++ilmzZpVZJ8Kl4YNG+LHH39Ebm4uvvnmG5fav/71L6nn3eqFS+XKlTFx4kTk5ubi22+/xaOPPooff/xR2vZOiYmJeOONN9C5c2ecOnVKWr9161ZER0djwoQJ0rpDhw6hQ4cO0tepX78+VqxYIdVL6mGa7eAsB3lLjVkOPCyhw9ezHN999x0++OADfPjhhxBFEfHx8ShbtiyGDx+OMmXK4OjRoxBFETt37kTLli0xfPhwiKIIURTx3XffydsVKzU1FSkpKShfvry85MJsNqNJkybYu3cvRFHE2bNnXT6MAGDhwoUYO3Ysxo8fL42pWLEi3nzzzWI/8AHgxRdfREpKSrEhzGg0IjMzEwaDweVBW4X/zsnJweXLl5GRkQGDwYDQ0FCX7XU6HQIDA3Hz5k2X9Z5ISUnBlClTMG/ePMydOxeiKCI2NhZnz55F37593c6ilClTBiNHjpRen6NHj0Kr1WLy5MlFtrtw4QK2bNmCp59+Grt27ULjxo2lHiNGjJB6pKSk4P3333fZ9k7Hjx/Hu+++i1u3biEtLQ05OTkYMmQIpk2bJgWP+xEfHy8ditPr9Rg9ejREUYTRaMTXX38thYLC17979+749NNP8dVXX2HWrFkQRREHDhzA1atX8eyzz7p8ULds2RI7d+6U/h9/++03REdH3/HVfWP37t149dVXERkZKe37yJEjMWHCBHz11Vfy4W49LLMdnOUgX8jIyFB8lgMPS+go6SxHSRw8eBCbN29Gjx498PrrrwMAGjVqhEGDBsFoNGLNmjXyTe7L2bNnsWHDBmg0GrRt21ZeLsJgMKBy5cry1UDBw7B++ukndOvWTXoY1qOPPopBgwbBarUW+9dpSRiNRmRkZMhXu8jJySnyAe5LJ06cwI4dO9C7d29pJqlz584YO3YsLl++jA0bNsg3KVZERAQaNWoEo9FYZJ8TExORnJyM9u3bu6z31JUrV3D79m0MHDgQYWFhMBgM6NKlC2rVqoVt27ahTJkyqFChgnwzt06cOOFxYImLi8PWrVvx9NNPY9SoUQCA9u3bY/z48bh27ZrPfpZLKi0tDXv27IHBYJAeUa/X69GzZ0/07NkTmzdvdpklKYmHYbaDsxzkLbVmOfAwhA5fz3KkpKQgJSUF1apVc/mrPSoqCvXq1UNSUhISEhJctvHU9evXsWDBAuzatQsDBw7ECy+8IB8iycnJueeHfmpqKpKTk4vsc2RkJOrXr4/r16/f8zDLg6zw/18eBsLDw1G+fHmcP3/eZb07ly5dwt69exEZGYmYmBhpfWpqKvbs2YPAwEB069bNZRtPGI1G/O9//0NISAgaNWokrY+IiEBMTAxSU1MRFxfnss295ObmYu/evcjMzMTw4cPl5WLdvHkTDoejyF/HoaGhqFSpEs6dO+eyXmlpaWk4ffo0wsPD0aRJE2l9WFgYmjZtKtU9UdpnOzjLQb6QkZGBCxcuKD7LgYchdPhylgMFb/B2u71E51rcj7Nnz+KDDz7AmjVrMGbMGHzwwQfyIS5ycnKQmZmJatWquZxTcScl9/luh0zkypUr53LoxVOZmZmYNGmSdIy/QYMGWL58OVDwIZ6eno74+HgMGDDA5ZyDLl26YO/evcjOzpa3lFgsFnz77bfSNp07d4YgCHjttdekMZmZmViwYAEuXbqE+fPn3/f/y8qVK1GuXDmMHTtWXnJRq1YtVK1aFZs3by5RADl16hR27dqFjh07Sod87iU3NxdpaWk4d+4cXn75ZZfvW4cOHbBnzx5kZWXJN3NL3qtSpUr48MMPXcbs27cPzZo1k8Y8++yzuH37NlDwAZqRkQG9Xu/T2y6X5tkOznKQtwpnOS5duqT4LAdKe+jw9SwHCqZ7tVotbt26JS8BBR+wxR3muJdDhw5h9OjROHz4MKZPn37PwIGC/0eTyeT2vI+S7PO9gkNxCg/ryA9HFP67XLlyqF27NkJDQ+96KMZsNiMvLw+VKlVyWX+nypUrY+rUqdL5BOfOncOrr77qMiYmJgZr166Vxty5LF261GXsneTndCQnJ6NTp06YMGECdu/eDRR8/TfffBPR0dF47rnnpPWeevnll6XzPXJzc4scvinUvHlzjB8/HiaTCU2aNIEgCKhXrx5++OEH+VCkpqZi69atCAgIwNtvvy0v31ODBg2wcuXKIt8zURQ9Plwj7zVv3jzMnz/fJXh06tQJJ0+elMZs2bIFjzzyCFBwfk9oaChyc3Nx48aNOzr/P2XLlkV4eLh89T3dOdvx888/y8t+i7Mc5AuFsxz/+te/FJ/lQGkPHb6e5UDBIYnIyEgkJSW5fIAmJyfjwoULKF++/H19gB86dAiTJ0/G5cuXMX78eOnS2Xu5cOECrly54vakvoiICERFRRXZ55SUFJw/f96r0FF4BUpycrLLIZqUlBQkJCRI9bCwMOh0Oly4cEEaU3jlS2RkZLGzNPdiMBhQs2ZNWK3WIodRtm3bhsaNG0vnK5RE4WGVtLQ0l8NkEREReOaZZyCKImbPnl1sYLiXiIgING7cGLm5uS6vRWpqKuLj46V6x44dcejQIenD+cKFCxg8eLBLLxT83OzduxcDBw706ANZr9ejZs2acDgcRQ6j/Pbbb2jSpIlHh2ruplq1amjatCkyMzPlpbsqPKwiP4ySnp6OU6dOQa/Xe/T/eKfSONvh6SyH2WzGokWLXGa17lyeeeYZ+SZ+78KFC+jfvz+eeuopoODy/i5duuDJJ5+UD30oqT3LgdIcOrKzs30+y4GC8wb69OmDTZs2SWfTnzlzBkuWLIHBYMDAgQPlm9zT9evXsXr1ao8DR05ODuLj4xEcHOz2Tadt27bo27cvfv75Z3z55ZcAgISEBCxZsgQhISFFrnTxVJMmTRAVFYUffvgBZ86cQXJyMlavXo2cnBy8/PLLAIAWLVqgQ4cOWLt2LdavXw8A+PXXX7Fp0yb06dPH5fwGT3Xs2BF9+vTBDz/8IF0ddPToUcydOxcRERHSSYklkZKSgvj4eISHh+PRRx91qXXq1Alvv/02Tpw4gXXr1knry5Yt63amRq5hw4aoVasW1qxZg/T0dKSmpmLt2rW4cuUKevXqJR/ulsViQa1atfDiiy/KS/fUtm1b9O/fH8uXL8c333wDFByqmT17NipVquQSOu7nAz8pKQmnTp0q8cxfeHg4unbtKl1tc+PGDeTm5mL79u3Yvn07+vTpg6ZNm8o3K5HC2Y7Q0NBSMdvhzSxHnTp18MMPP7jMav3xxx+4dOkSunbtitTUVPkmpUaTJk0QGxv7t9/76EGh9iwHSnPoUGKWo9Bbb72F7777DvPmzYMgCIiJiYHJZMK8efPw+OOPy4ff019//YUtW7ZI9zKQ/wUiv98GCoLK5MmTMWnSJPzyyy9o1KiRNL7wHgy//PILpk6dioyMDPz73//GggULsHDhQmnMrVu3sGDBAnTu3Nmlt6dat26NKVOmAAWHOapWrSodIiq8EVhUVBTGjBmDJ554Av3794cgCJg2bRref/99DBs2TNbRM5GRkZg8eTKGDx+Ot99+G4IgoHXr1ihTpgxWrlzpckKonPycjqioKKxfvx6vvPLKXU8YbdeuHbp27YpPP/0UTZo0QadOnZCZmenR696iRQtMmTIFTqcT4eHhiIyMxNatWzFx4kSXe2SUROvWre86A1ISVapUwYQJEzBmzBiMHj0agiCgWbNmEEURa9aswZUrV1CtWjX83//9Hxo0aOBycufdyM/peO211/DPf/4T06dPlw8tVrdu3bB8+XLk5OQgIiICBoMB3377LT799FOMGTNGPtwjUVFRqFKlSqmY7fB0luNemjdvjnHjxiEzMxMnTpyQl6kU+jtmOQAAog/Y7XbRbDaLTqdTXvKJ3NxcMSMjQ7RarfLSXWVlZYkfffSR+I9//EM8fvy4vFwqJCUliaNGjRLffPNNeUkURVHMzs4Wp02bJg4cOFBMT0+Xl4keSocPHxZffvllceHChfJSsRwOh2gymUSHwyEv+YSn/U0mk/j999+LLVu2FP/44w95uViF29WpU0f84YcfitQWLVoktmnTRjx+/Lj079q1a4uLFy92GVvowIEDYpMmTcSXXnpJGg/AZalQoYI4evRol+1+//13sWLFitKYVq1aiceOHZPqJpNJ/OGHH4r0AiA+9dRTLr3kDh06JDZo0EAEIAYHB4stWrQQ+/XrJz755JOiKIriqVOnxM6dO4tPPPGEtM3evXtd9qdmzZpiv379xB49etzR+d7i4uLEzp07S32Cg4PFfv36iaIoimazWVy+fLlYo0YNccGCBdI2Fy9eFAcMGCB269ZNFEVR/Ouvv8S2bduKnTt3Frt06SL1ateunXjkyBHx3XffldY1adJEPHLkiNTLU2fOnBFffPFF8euvv5aXXNhsNjEtLU00mUzy0n3xy5mOy5cvY+XKldiyZUuRExNRMMuRlJSkyCwHEfkvf5jtuHHjBlavXo1169bd9VCHr2c5UHCfl5UrV+L555/36j0zJiYG27Ztkw7brFq1CmvWrMFnn30GFNzRt2/fvnj11VchiiKuXbuGxx57DK+88gq2bdsGFBw6Sk1NRadOnZCSkgJRFHHixAl06tRJ9tVc7d27F88//7w0W3fp0iV07NhROpx7N/v27cPAgQPxxBNPSOdOtW7d2u02dxMfH4+xY8ciLCxM+n/ftWsXjh49infeeUc+3K2cnBxcuXIFAwcOhFhww76LFy+iR48esNlsEEURZ86cQcWKFd3ehNCdv22W4+86vGIymaT7XZRkuXHjBm7cuCH9u/B8hOeeew7R0dF4/PHH8dFHH2H37t04c+YMfv75Z5+fy0FE/i8qKgr9+vXDI488ghUrVhR5ryluSU1Nle4Q7OtF3vvixYtYt24dBgwYgOjoaLRu3Rrvv/8+tm/fjnPnzmHHjh33dS5HocTERJdb8AuCgI4dO+LkyZN3/SPOGxUqVECNGjWQnp6O8+fP44cffkDTpk2lD8tq1aph8ODBqFy5MubMmeOyrU6nQ0REhMu64iQlJWHjxo2oU6eOdK5d1apVMWTIkGLDyvXr1/HTTz+hdu3a0jZ169bFe++9hwYNGsiHu2W1WmGz2VwuWe/YsSMuX75c5P+rJOrUqYM333wTKDjXqUePHmjYsKF0JViVKlXQq1cv3Lp1C3/99Zds63v7O87lKBSQnZ0Nbxez2Qy73Y7c3NwitbstK1euRNOmTREVFVWiJTo6Go0bN0bt2rURFRWFZ555RrpsMScnB3/88QemTJmC7t27IyYmBvPnz0eLFi1KdeioWrUqZs2aVewTWsuVK4cPP/wQq1evvu8rU4hKo8jISERERGDcuHFF3mvuttSoUQPR0dGoXr16kZovlurVqyM6Oho1atRAVFQUOnXqhM2bNwMFf/UfPXoUX375JZ5++mk8+uijmDVrllezHHc7kTQhIQHdu3fH5s2b73pp9v0wm81ISEhAeno6YmJicOvWLVy4cAFVq1Z1CROVKlWSrnI6fvw4LBbLXS+ZdufWrVtISEgo0rtixYpo1qyZy9hCt27dwrlz51C1alWXD95HHnmkxPe7KVShQgWEh4dj8uTJ6NChA1JSUuRDSqxcuXJFTmJHweX9vggIhbMc58+fR8+ePYt8PssXi8WC4OBgOByOIrX7WQL0ej28XUJCQhAUFIQyZcoUqd1tCQ4ORteuXbFt2zZcu3btnsuFCxcQHx+PxMREXLt2DT///DO6du0qfRMrVqyIrl274r333sOiRYswcOBAHD9+nCdEEVERhbMLM2bMKPJec7flypUruHjxIq5cuVKk5otF3j82Nha9e/eW9tdgMKBDhw4YNmwYBg4ciMjIyPue5ShOgwYNMHz4cFgsFuzZs0daf/nyZQwZMkSaEQkJCZGuSLub+Ph49OrVC4IgoGzZsnjrrbfQvn17DBkyBBaLBbm5uff8I8hsNsNisaB+/fry0gMrOjoa8+bNw4wZM3Dw4EFERUVBEAQ0b9682Kdz/10KZzleeuklREdHF/l8li/BwcGw2+0ICgoqUrufJSAwMBDeLgEBAQgICCiyvrglICAAISEhCA8PR7Vq1e65REZGIjw8HFFRUahWrRrCw8NRpUoV9OjRA7NmzcL+/fvx66+/4ssvv8SQIUOkB0YxdND9SCm4gded088vvPDCfd+bgx4cycnJWL9+PW7fvo3XXnutyHvN3ZbCv4SrVq1apOaLRd6/SpUqCA0NRYcOHfDZZ58hNjYWu3fvxltvvQW9Xu/VLIenateujcWLF0szIrt378bRo0eLvbRbfk7Hnj17EBcXh5dffln6o7S4QziFh1MsFgtycnI8vvOvzWYr9gaIxbmfbYpTeI7Fned0nDx5EqNGjcLt27d9MkvhrTvP5RgwYECRz+a7LQEBARBFEYIgFKndz/K3nNPhrZYtW2LZsmX47bffMGrUKDRs2BAajUaqN2vWDNWqVcP69esZPMgjFy5cwIcffoh9+/bh999/h1jw5FmbzYaXXnpJeuQ9+afk5GTcuHEDffv29fi+I2qpW7cu5s6diz/++APjx49HixYt4HQ6cejQIZw8eVKxwGG1WoGCB1gWp2rVqujRo4d0sue9VKxYEfXq1cP169dhs9mk/75z25s3b+LUqVNS6Lhx4wbi4+M9uidL4WGUmzdv4tixY9L6W7du4eTJky5jC1WsWBFNmzaF2Wx2ORxy+/btEj1+4F6aN2+OGTNmFOl/J6vVquoJzX/nuRyF/DJ0BAYGuoQMufLly6Nr166c7SCPJSYmIiEhAT179pTu09GyZUsMGjQIV69exU8//STfhPzE9evXsX79emRkZOC5556Tlx8YAQEB0Gq1LusSExNx5MgRxWY5jh8/jhkzZqBatWrS3Tvv5vr169i1a1eJT/K88zyOLl26YPDgwTh06BDGjRsHFJwA+sMPPyAzMxPvvPMOkpKS8Msvv6B69erFzqbcTbVq1fDiiy/CZDJhwoQJQMG+Ll68GPv27ZMPBwoCVN++fXH58mXpHjAXL17EzJkzi9yl917++OMP1K5d2+VKlcuXL2Pp0qWoVKkSWrVqhfLly0On02Ht2rVAQQBevHgxYmNj7+iknL/zipU7+WXoKIlmzZqhevXqnO3wI2vWrEHdunVdbia1detWtGvXDtOmTXNZ17hxY7z77rvSuqVLl7ocDqlVq5Z0d1Kj0Ygvv/zSpS4IAl5//XVp+0I9e/bEoUOH8NFHH7ms9/Suo/Tg8YdZjrsxm80+neW429UrLVu2RGBgIDZv3uxyAr78nI4OHTqgTp060uWtcnee0yEIAtq3b49HHnlEuhNyz5498csvv2D79u0QBAHVq1fHn3/+iRUrViA6OhpjxozB7NmzsWPHDpf9a968Ofbt24fY2Nhi777btm1brF27FlarFYIgoFq1avjtt98wcuRI+VBJp06dsGbNGvz2228QBAGNGzdGYmIi+vXrJx/qVseOHbF8+XKsXr1a2ufWrVsjMjISu3btAgC0atUKCxcuxKlTpyAU3KAxISEBAwYMkLdTxIMwywHg77k52LJly8RXXnlFPHr0qLx0V57eHKzQ3r17xcGDBxd7cxt6sKxevVqMjo4Wp02bJq3bsmWL2LZtW3Hq1Kku62JiYsTRo0eLOTk54owZM8SYmBhx7dq1oiiK0rqaNWuKc+fOFXNycsQvvvhCbNeunbh7926pjyeWLVsm1qxZU5wzZ468RH4gKSlJHDt2rPjUU0+JN27ckJfd8vTmXZ66V//Tp0+LQ4cOFWfMmCEvlSrnzp0Thw4dKo4aNUpeEkVRFK9duya+99574r/+9S95yadOnTolPvnkk2L//v3lJb+Vnp4ufvzxx2KbNm3E5ORkedkt3hzMA5ztKP3Onz+P2NhYtGrVSpoyNBgMaNSoEcLDw3Hz5k35Jh7bt28f5s6di+joaK9vGU9/j+TkZKSlpT30sxz0/7t48SL69++Pjh07SudcWCwW6eaSr7zyinwTv/XAzHKU5sMrKLjemed2lG6tWrXCL7/8giVLlsBoNOKLL76AUPDEzNOnT3sdOo4dO4YZM2bAZDJh6NChbp/jQg+mwnM5MjMzH+hzOe5G6XM5HmaFh3IjIyOlS1x1Oh2++eYbrFixAs888wx27drlcpjnbktISMjfeo7EvTwo53IUKtWhA5zteCgUns9Rrlw5zJw5E1OmTMHWrVtRp04d+VCP7Nu3D2+99Rb+97//YdKkSaodeyXf4iyHf6hfvz6+//57zJo1S14CCk4W/fLLL7Fq1Sp56b7VrVsX69atc7lR2rFjx9CyZUsAQI8ePVxqd1usVqvLU6cfNA/SLAcehtDB2Y7SLTY2FvPmzcPrr78OURSRnp6OSZMmyYd5bPv27dLJdt9++y0Dh5+6c5bj2WeflZcfaJzlIG89aLMceBhCBzjbUarl5ubCbDajfPnyLuszMjKQmJjosq6ktm/fjhEjRqBy5cr49NNP7/qIe/IPnOWgh1l6evoDNcuBhyV0cLaj9NLr9dDpdDh79qx0465t27Zh6tSp8qElcuzYMcyZM4eBoxTgLAc9zB7EWQ48LKEDnO3wGxkZGZg4caJ0ktazzz6Lw4cPY9KkSS7rCmcxunTpgsmTJyMxMRGNGzeGIAgYP348+vbtiy5duiApKcmj25efOXMGv/zyCw4fPozu3bsXOWnstddek29CDyjOctDDLD09HRcvXnygZjkAQBBFUZSv9JTD4YDT6YRWq0VgYKC8XMTy5cuxa9cujBo1Sjphxx2TyQSLxQKDwYDg4GB5ucT27duHZcuWoUOHDhg8eLC8TESlxPXr1zFr1iycOXMGS5cu9Sp0OJ1O2O12aLVaBAUFyctek/ePi4vDt99+i7p160qPgCfyREZGBubOnYsdO3Zg48aNXoUOu92OrKwsaVbZWw/NTAc420H00OAsBz3MHtRZDjxsoYPndhCVfjyXgx5mhedy3M/t3NXwUIUOcLaDqNTz11kOk8nEWQ7y2oM8y4GHMXRwtoOo9PLnWY7Lly9zloO88qDPcuBhDB3gbAdRqeWvsxw8l4N84UGf5cDDGjo420FU+vjzLEdiYiKOHj3KWQ66b/4wy4GHNXSAsx1EpY4/z3IcOXIEp0+fZuCg++YPsxx4mEMHZzuISg9/nuW4cuUKTpw4wVkOum/+MsuBhzl0gLMdRKWGv85ymEwmHD58GHFxcQwcdN/8ZZYDAISsrCyv70jqqTVr1iA2NhbDhg1Ds2bN5GVVHThwAAsXLkRAQACaNGkiLxPRAy4/Px/x8fHIycnBvHnzEBYWJh/ywDpz5gymTp2K5ORkvPDCC/Iy0T3l5+cjMTERFy5cwMqVK1GlShX5kAeK4HQ6vQ4dTqcTTqcTGo2mRLdBX7FiBX7//XeMHDkSLVq0kJeLsFgssNls0Ol00Gq18rJXcnJysGnTJvz000/S8zV8TRRFiKLI/sXIz89HXl4eAgMDERDg+8m3GzduIDk5GbVq1ULFihXlZa8p/f3x9/5Kv76iKCIkJARPPvkkhgwZIi97LS8vDw6Ho8Tvb544cuQIpk+fruj3vzS8vp7s/61bt3Dx4kXUqVMHlStXlpeL8LS/p9Tor9Vq8fjjj2PkyJHystccDgeMRiN0Oh1CQkLkZY89VM9eKY7D4YDD4VDs2Qrs757ZbIbZbIZer/fJD7Xcpk2bsHLlSowZM0aRKWz5szN8zd/7W61WGI1G6PV6lClTRl72mtL7z/7u2Ww2ZGdnw2AwKPL65uXlwWazlXj/Dxw4gOnTp2PcuHHo2rWrvFyEp/09pUZ/q9UKrVYLjUYjL3uNz14hIiIiv8TQQURERKpg6CAiIiJVMHQQERGRKhg6iIiISBUMHURERKQKhg4iIiJSBUMHERERqYKhg4iIiFTB0EFERESqYOggIiIiVTB0EBERkSoYOoiIiEgVDB1ERESkCoYOIiIiUgVDBxEREamCoYOIiIhUwdBBREREqmDoICIiIlUwdBAREZEqGDqIiIhIFcLVq1dF+Uql/fTTTzhw4AAGDRqExo0by8tEPvXrr7/i559/xpAhQ9CiRQt5mYhKkaNHj2LOnDl488038dhjj8nL9DcTbDab16HD6XTC6XRCo9EgMDBQXi5i5cqV2L17N955550SfQhYLBbYbDbodDpotVp52Wue7r+n2N89q9UKq9Wq2Ov73//+F6tXr8aoUaMUeRNS+vujdP+8vDw4HA7F+ttsNpjNZuh0OgQHB8vLXlN6/9Xob7fbodFoEBQUJC97Ten+drsdJpNJ0dfXk/0/ePAgPv/8c4wZMwZdunSRl4vwtL+n/L2/w+GA0WiETqdDSEiIvOwxQRRFr0OHw+GA0+mEVqst0S/l8uXLsWvXLowaNQotW7aUl4swmUywWCwwGAyK/FA7HA44HA5otVrFXjT2L57ZbIbZbIZer/fJD7Xcpk2bsHLlSowZMwYdOnSQl73mdDpht9sV+/74e3+r1Qqj0Qi9Xo8yZcrIy15Tev/Z3z2bzYbs7GwYDAZFXt+8vDzYbLYS7/+BAwcwffp0jBs3Dl27dpWXi/C0v6fU6G+1WqHVaqHRaORlr9ntdmRlZUGv10On08nLHuM5HURERKQKhg4qtVJSUvDVV19h8uTJ2LdvH0aMGIGxY8ciMTFRPpSIiFTA0EGllkajwe3btxEfH4/MzEwkJiYiPz8fVapUkQ8lIiIVMHRQqRUaGop27dqhTp06AICwsDA0atQIZcuWlQ8lIiIVMHRQqRYaGiqFjtDQUERHR8uHEBGRShg6qFQrDBqBgYGIiopC3bp15UOIiEglDB1UqtWoUQOtW7dGcHAwIiIiEBUVJR9CREQqYeigUi0gIABarRbh4eGoWrWqvExERCrizcE8vPnV2bNn8eOPPyIuLk5eKlZ+fj5EUURAQAAEQZCXvebv/fPy8qQ7bgYE+D4Hp6Sk4PLly6hduzYiIyPlZa+Jooj8/HzFvj/+3r/w9Q0KCirR+0Oh9u3bY/z48fLVRSh98yv2d483B3NPjf7+dHMwhg4PQ8fJkycxf/58/O9//0P16tXlZSLygaSkJFSqVAkrVqyQl4pQ+kOV/d1j6HBPjf4MHfdQGkJHzZo1S/RXGBF55vbt21iyZAlOnDjB0OEDSvdn6HBPjf7+FDp8P5dNREREdBcMHURERKQKhg4iIiJSBUMHERERqYKhg4iIiFTB0EFERESqYOggIiIiVTB0EBERkSoYOoiIiEgVDB1ERESkCiErK8vr26B7as2aNYiNjcWwYcPQrFkzefmBFhcXhyVLlqBu3bq8DTqRAgpvg37kyBEsWLBAXiZy69ChQ5g5cyZGjhyJTp06ycv0NxOcTqfXocPpdMJZ8JTQkjx7ZcWKFfj9998xcuRItGjRQl4uwmKxwGazQafTQavVyste82T/T548iYULF6JWrVoMHUQKKAwdx48fx7Jly+TlIvLy8uBwOEr0+3s/1Ohvt9uh0WgUezaHkv3tdjtMJhN0Op0iz8bydP8PHDiAzz77DGPHji3xs1c86e8pf+/vcDhgNBqh0+kQEhIiL3ssIDAwEN4uAQEBCAgIKLK+uKXwEdol3UYQBOnR6vKaL5b72R8iUpYgCEV+9+62ePr76+miRn+legeq1D8/P7/Er9f9LJ7uv6f74ml/Txel+yv98ymKosff0+IWntNBREREqmDoICIiIlUwdBAREZEqGDr8zObNm9GuXTt8/vnnyMnJwbRp09CsWTNs3LhRPpTcSElJwbhx4/Dkk08iPj4e+/btQ9u2bfHaa6/Jh1KBP//8E+3bt8fAgQPlJSKiEmHo8GPlypXDxIkTcfLkSbzwwgvyMnmgU6dOOHz4cImulnhYPfbYYzh48CDWrFkjLxERlQhDB9FD7LfffkO7du0wadIkeYmIyOcYOh5w8+fPhyAIEAQB0dHR+P7776Xa3Q6v5OTkYPr06dI24eHhaNeunXRIxhOrVq1ChQoVpF516tSRbtaUkJCAV155BT179sSZM2ekbbZs2YJ27dph+vTpAIDFixejSZMmeOGFF6ReZcuWxZgxY7Bnzx60adNG6j9kyBCpj68dO3YMvXr1kr5W3759kZGRIdXvdnilcF3hNjExMejVqxd69OiBuLg4ady97N+/H+3atZP66HQ6jBgxQqr/9NNPqFu3Lj766CNpXWpqKsaPH4/u3bsjLi4Ov/76K9q1a4fu3bvjsccek3o999xzOHDgAIYMGSKt69q1K06fPi318hUeXiEibzF0PKAKA8XMmTOxcOFCiKKI+fPnIy0tDVeuXJEPBwq2mT17Nn744QcsWLAAoihiwYIFSE9PL3ab4vz444+YOXMmZsyYAVEUkZ2djaFDh+K7777Dhg0b5MPdiouLg8ViwYEDB5CTk4PJkyfj66+/xqhRozBu3DiIoojVq1dj3759UliRi42NdQko8qVx48ZYt26dfDMAwN69e/HWW28hJCQEaWlpyMnJwQsvvOD2UMq+ffswbtw4REVFIS0tDcnJyXj66afxyy+/yIe6tX//fkyePBmtW7eGKIoQRRErVqzAjh078PHHH8uHu3Xz5k2kpqZixIgREEURGzduxP79+9G7d29ERUVBFEX88ccfsFqtHgdMIiI1MHQ8oA4fPoydO3eib9++eOONNwAAPXr0wKhRo1C+fHn5cADAkSNHpG3+/e9/AwD69OlzX3dONZvN0Ol0aNCgAVBw/sj//d//4dSpU/jnP/8pH+5WaGgoOnbsiEaNGsFgMKBhw4aIiYlBjx490K9fPwBAnTp1EB0djcuXL8s3BwB06dIFR44ckT645UtcXBz69+8v3wxGoxFHjhxBQEAA3nnnHYSFhcFgMOC5554r9qTRwm0EQZC2iYyMxIABA/D000/Lh7tlMpkQEBCA+vXrS+v69u2Lixcvehw6AKB58+Z48cUXAQA1a9ZEx44d0b59e7z99ttAwfexa9euSE1NvetsR25uLmbNmiWFtSeffBKHDx/GtGnTpHXPPvss0tLS5JsSEXmNoeMBdePGDZhMJtStW9dlfURERJF1hVJTU2E0GhEdHe2yPiwsDLVq1XJZdy9hYWFISUnB008/jffee09e9kiVKlVQr149l3Vly5ZFpUqVXNYpISUlBWfOnEFkZCQaNWokrZf/+06pqanSNjExMdL6iIiIYrcpTlhYGMqUKYMRI0agT58+SE9Plw8psUqVKqFOnTry1TAYDAgPD5evviu9Xo/Ro0dLYW3nzp1o27YtJk6cKK3bsmVLifsREXmCoYPuqnfv3lizZg0ef/xx/Oc//5H+Ci6cdaGSadGiBb7//nu8//77+O9//4vw8HAIgiCdq0FE9DBh6HiAGY1G3Lx5U77ardzcXNy6dUu++r60adMGO3bsgCiKuH79Ot59912sWrUK7733HsqVK4fQ0FD5Jorx5pwOFHwvPZ1luJ9t7iYiIkI6N6bwnI7du3dj0qRJSE9PV23Wh4jo78bQ8YCqUqUKypUrh6tXr7qsT01NxcWLF13WFYqIiEBERESR0HE/J5LKRUVFYeDAgXj88ceRnZ0tL0t8GXrudL/ndBQeRik8zFJI/u87FR5GkYeOwsMu3urevTvef/99GI3GYs+dyM3N9UnguZcnnngChw4dwtSpU+UlIiKfY+h4QD3xxBMYOnQoNm7cKF2JsGvXLnzzzTfFfui3adMGTz75JH766ScsXLgQKLiDqadXMuTk5ODTTz9F06ZNXa5UOX36NI4fP45atWohKioKDRs2xLFjx7B582YAwJ49e/D1118jKyvrjm5/L4PBgG7duqFGjRpYvHgx4uPjYTQa8fPPPxd79YrBYECbNm0giiLmzJmD9PR0pKSkYO3atR5fvVJ4OeydJ42eOnUKP/30EyIjI9G4cWOEhYWhcuXK+OOPPxAXF4fc3Fxs3boVS5YscelFROTvGDoeYMOGDcPMmTPx+eefQxAEvPTSS6hQoQJatWolHwoUXGEyYsQIDB48GG+++SYEQcDYsWPx6KOPenQiably5fDOO+9g4MCB6Nevn3QIY8KECRg9ejQmTJgAAOjfvz/GjBmDiRMnQhAEjBo1Cg0aNEDt2rXlLf9WLVu2xFdffSV9yJcrVw4bN24s9uoVFNyh9Msvv0RycjLCw8MRFRWFffv24fXXX5cPdatv3774/PPP8c0330jfx549e+Kxxx7DihUrgILzPj744AOYTCY0adIEBoMBW7duxQcffCBvR0Tk1wRRFEX5Sk85HA44nU5otVoEBgbKy0UsX74cu3btwqhRo9CyZUt5uQiTyQSLxQKDwYDg4GB52WsOhwMOhwNarRZBQUHysouTJ09i/vz5qFmz5n1divp3WLlyJb766isMGzZMupSWPHfhwgV89tlnyMrKwoIFCxAWFiYfQj5w+/ZtLFmyBCdOnJCCmTtOpxN2u71Ev7/3g/3ds9lsyM7OhsFgQJkyZeRlr+Xl5cFms5V4/w8cOIDp06dj3Lhx6Nq1q7xchKf9PaVGf6vVCq1WC41GIy97zW63IysrC3q9HjqdTl72GGc6SpHNmzcjJiYG77//vrQuISEBO3bsQP369fH888+7jKe7S0lJwfvvv4927dph9+7d0vrTp0/jxIkT6N69OwMHEdF9YOgoRfr06YNp06Zhw4YN0lR+w4YNUbZsWaxevRo2mw2jR48ucuWHfKlTp450TsjDKDIyEqNHj0anTp3QvXt36fvy8ccf4//+7//wzjvvYMWKFUW+b/JFfrtzIqKHHUNHKdOnTx9cvnzZ5cqOwuelVK1aFbNmzSpy5Yd8SUxMfOgPw0RGRuKLL75w+b7Ex8djwIABAIBXXnmlyPdNvpjNZsyePVvemojoocXQQURERKpg6CAiIiJVCFlZWV5fveKpNWvWIDY2FsOGDUOzZs3k5QdaXFwclixZgrp16/rN1StE/qTw6pUjR45IhwaJSurQoUOYOXMmRo4ciU6dOsnL9DcTnE6n16HD6XTC6XRCo9GU6JLZFStW4Pfff8fIkSPRokULebkIi8UCm80GnU4HrVYrL3vNk/0/efIkFi5ciFq1ajF0ECmgMHQcP3682Bu43SkvLw8Oh6NEv7/3Q43+drsdGo1GsUsqlexvt9thMpmg0+kUuaWBp/t/4MABfPbZZxg7dmyJL5n1pL+n/L2/w+GA0WiETqdDSEiIvOyxgMDAQHi7BAQEICAgoMj64paAgAAIglDibQRBgCiKJR7v6XI/+0NEyhIEocjv3t0WT39/PV3U6K9U70CV+ufn55f49bqfxdP993RfPO3v6aJ0f6V/PkVR9Ph7WtzCczqIiIhIFQwdREREpAqGDiIiIlIFQwcRERGpgqGDiIiIVMHQQURERKpg6CAiIiJVMHQQERGRKhg6iIiISBWCKIpe3wbd4XDA6XRCq9UisAS3CV6+fDl27dqFUaNGoWXLlvJyESaTCRaLBQaDQZHb7DocDjgcDmi12nveRvbkyZOYP38+zGYzOnbsKC8TkQ+cPn0a2dnZWLFihbxUhNPphN1uL9Hv7/1gf/dsNhuys7NhMBhQpkwZedlreXl5sNlsJd7/AwcOYPr06Rg3blyJb4PuSX9PqdHfarVCq9VCo9HIy16z2+3IysqCXq+HTqeTlz3G0OFh6Dh79ix+/PFHxMXFyUvFys/Pl27jrsQt1P29f15envTsm4AA30++paamIjk5GbVr10bFihXlZa+Jooj8/HzFvj/+3r/w9Q0KCirR+0Oh9u3bl+j5Rkp/qLK/ewwd7qnRn6HjHvw5dNwP9nfPbDbDbDZDr9f75IFCcps2bcLKlSsxZswYdOjQQV72mtJv6v7e32q1wmg0Qq/XK/KhpPT+s797DB3uqdHfn0KH7/+sJCIiIroLhg4iIiJSBUMHERERqYKhg4iIiFTB0EFERESqYOggIiIiVTB0EBERkSoYOoiIiEgVDB1ERESkCiErK8vrO5J6as2aNYiNjcWwYcPQrFkzeZnIp7Zu3YoNGzbg7bffRuvWreVlIipFDh06hJkzZ2LkyJHo1KmTvEx/M8HpdHodOpxOp/TsjJLcBn3FihX4/fffMXLkSLRo0UJeLsJiscBms0Gn00Gr1crLXvN0/z3F/u5ZrVZYrVbFXt/Nmzdj1apVGD16NNq3by8ve03p74/S/fPy8uBwOBTrb7PZYDabodPpFHmMgdL7r0Z/u90OjUaj2G2ylexvt9thMpkUfX092f8DBw7gs88+w9ixY0t8G3RP+nvK3/s7HA4YjUbodDqfPKYiIDAwEN4uAQEBCAgIKLK+uKXwwVIl3UYQBOmBY/KaLxZP98fThf3dL4WvryAIRWq+WAIKHiKn1P4HFvw/+Gt/pV/fgIAAxV9fpfdf6f5K9Q5UqX9+fr5ir29gwdeQr3O3eLovnvb3dFG6v9I/n778/eU5HURERKQKhg4iIiJSBUMHERERqYKhg4iIiFTB0EFERESqYOggIiIiVTB0EBERkSoYOoiIiEgVgiiKXt+R1OFwwOl0QqvVIrAEd+xbvnw5tm3bhkGDBqFJkybychEWiwUWiwVly5ZV5I53nu6/p5Tu73Q64XA4/La/1WqF2WxW7PXdvn07tm7divfeew8dOnSQl73mdDpht9uh1WoVuSOgv/e3Wq0wGo3Q6/UoU6aMvOw1pfef/d2z2WzIzs6GwWBQ5PXNy8uDzWYr8f4fOHAA06dPx7hx40p8R1JP+ntKjf5WqxVarRYajUZe9prdbkdWVhb0ej10Op287LG/LXS89957yMjIkJeIFNGxY0d8/vnnDB13oXR/hg73/L0/Q4d7avRn6LgHk8mE7Oxs+epicabDPafCMxFK91d6psPpdCIoKAhhYWGK/NIr/abu7/0ZOtzz9/4MHe6p0Z+hw8dMJhMsFgsMBoMiH0oOh0P6UFXih4L93TObzTCbzdDr9T55oJCc0m+67O8eQ4d7/t6focM9Nfr7U+jgiaRERESkCoYOIiIiUgVDBxEREamCoYOIiIhUwdBBREREqmDoICIiIlUwdBAREZEqGDqIiIhIFQwdREREpAohKyvL6zuSEhERPQgOHTqEmTNnYuTIkejUqZO8TH8zwel0eh06nE4nnE4nNBqNIrdBt1gssNls0Ol00Gq18rLXlN5/9nfParXCarXy9S2G0v3z8vLgcDgU62+z2WA2m6HT6RR5jIHS+69Gf7vdDo1Go9htspXsb7fbYTKZFH19Pdn/AwcO4LPPPsPYsWNLfBt0T/p7yt/7OxwOGI1G6HQ6nzymgs9eUeHZIuzvHp+94p6/9+ezV9zz9/589op7avTns1eIiIiIZBg6iIiISBUMHURERKQKhg4iIiJSBUMHERERqYKhg4iIiFTB0EFERESqYOggIiIiVfDmYCrc/Ir93VP65mA5OTnIyMhQ7OfT6XRK3x/2L8pmsyE3Nxdly5ZV5PVVev+V7q/0HSWV7m+326U7Vip1czBP9v+vv/7Cd999h/Hjx/PmYD7g65uDMXSo8KHK/u4pHTo2bdqE4cOHIy0tTV4iolKocePG+Oabbxg6fIChg6GjCH/vr0bo+OGHHzB06FC0bt1aXvaa0n8J+3t/znS45+lf8p5Suv+DNtMBAMHBwahUqZJ89V2pEQqU7s/Q4WMMHe75e381QsfKlSsxZswYdOjQQV72mtLPtvD3/nz2inv+3v9Be/aKp0pDf38KHTyRlIiIiFTB0EFERESqYOggIiIiVTB0EBERkSoYOoiIiEgVDB1ERESkCoYOIiIiUgVDB5VaKSkp+OqrrzB58mTs27cPI0aMwNixY5GYmCgfSkREKmDooFJLo9Hg9u3biI+PR2ZmJhITE5Gfn48qVarIhxIRkQqEq1even1HUqIH1e7du/HJJ5/gf//7H2rUqIHhw4dj4MCB8mFERKQCwWazeR06nE4nnE4nNBqNIrdBt1gssNls0Ol00Gq18rLXlN5/9nfParXCarUq8vr+9ddf+OSTT/Dbb7+hXbt2mDp1Kjp16iQf5hWlvz9K98/Ly4PD4VCsv81mg9lshk6nU+QxBkrvvxr9PX22iCeU7m+322EymRR9fZXcf/Z3z+FwSM/W8cVjKvjsFRWeLcL+7in57JUrV65g5syZWLBgAZ5//nnMmjULUVFR8mFeUfrZFv7en89ecc/f+/PZK+6p0Z/PXiF6QNSoUQOtW7dGcHAwIiIifB44iIio5Bg6qFQLCAiAVqtFeHg4qlatKi8TEZGKSvXhlfT0dJw8eRKXLl1CSkoKEhISkJaWhooVK7qMy8/PhyiKCAgIgCAILjVfYH/38vLypHMWAgJ8n4NTUlJw+fJl1K5dG5GRkfKy10RRRH5+vmLfH3/vX/j6BgUFKfL+4G7/tVotQkNDERkZiYiICDRo0AAtWrTwaJpY6cMT/t6fh1fcU6O/Px1eKXWhIykpCTt27MDWrVtx8OBBWK1WREZGokqVKoiMjERkZCQMBoN8MyIqZfLz82E0GpGSkoJr164hNTUVaWlpKF++PHr27InevXujS5cuqFChgnxTF0p/aPt7f4YO99Toz9DhYyUJHdevX8eqVauwdu1aBAYG4vHHH0enTp3Qpk0bREREyIcT0UPG4XAgKSkJ+/fvx/79+3Hw4EEEBQVhwoQJ6NevX7HvXUp/aPt7f4YO99Toz9DhY+5CR25uLrZt24bZs2dDEAQMHDgQvXr1Qs2aNV3GEREVcjqduHTpElavXo3t27dDr9dj3Lhx6Nmzp3yo4h/a/t6focM9Nfr7U+jw/QF0FaWkpGDGjBn46KOP0KZNGyxbtgxvv/02AwcRuRUUFIQGDRrg448/xooVKxAdHY33338fS5YskQ8lIh/y29CRkJCACRMmYPfu3Zg+fTqmTZuG2rVry4cRERVLEATUr18fU6ZMwdChQ7F69WpMmTIFZrNZPpSIfMAvQ8fFixfxxRdf4NKlS5gyZQr69u3rk2kfIno4ValSBcOHD8fIkSOxe/dufPnll/IhROQDfhc60tLSsHjxYly9ehXTpk1D9+7d5UOIiDym1WrRqVMnDB8+HHFxcZg/f758CBF5ya9Ch8ViwebNm3Hq1CmMHj0aXbp0kQ8hIrpv5cqVQ9euXdGhQwds27YNmzdvlg8hIi/4Vej466+/sGPHDrRq1Qr/+Mc/5GUiIq+FhYXhxRdfRPPmzTF//nxkZmbKhxDRffKb0JGVlYVdu3bBbrfjhRdeKHLpLBGRr4SFheHpp59G5cqVsWHDBnmZiO6T34SO48ePIykpCQMGDEDz5s3lZSIinxEEAdWrV0f16tWxefNmXLlyRT6EiO6DX4QOs9mMo0ePIicnB82aNZOXiYh8LjIyEr1790blypURGxsrLxPRffCL0HHt2jVkZ2ejc+fOaNSokbxMpcS5c+fw6quv4h//+Afi4+Ol9Vu3bkWdOnUgCAL++c9/Ij093WU7IqWEhYUhMjISJ06ckJeI6D74RehISkqC0WhEvXr1FLnNOj24YmNjMWXKFDRv3hxpaWnYsGEDwsLC5MOIFFG5cmXUr18fqampuHDhgrxMRB564EOH0+lEYmIijEYjatWqJS9TKWY0GnHkyBFkZmaie/fuDBukOoPBgCZNmqBChQo4fvy4vExEHnrgQ0dubi6ysrIQFhaGGjVqyMtUip0/fx6xsbFo0aIF+vbtW6T22muvQRAECIKAsLAwTJ06Varv3bsXbdu2xaBBg6R1RqMRX375JWJiYrB27Vpp/fr16/HII49IvZ544gnp8I7RaMTMmTOLbHP8+HH06tULr776qrSOSie9Xo/y5cvzsB6RDzzwocNkMsHhcCA8PBzlypWTl6mUMhqN2L17N86dO1dkluPo0aN49913cePGDcTFxUEURcyZMwfz5s3D6NGjXfrcy7Jly/Daa6/hlVdegSiKOH/+PKpWrYqhQ4di9+7d8uH0EAoJCUFISAhu3bolLxGRh/wmdJQvXx6CIMjLVAr9+uuvaN++PTZv3ozFixdj+PDhLvW4uDicO3cOffr0QUxMDACgZ8+eGD16NH7//XesW7fOZXxxjh07hnXr1qFnz56YOHEiAKBevXoYNGgQypQpw7tREgAgODgYZcqUQVZWlrxERB4SsrKyRPnKB8np06exYMEC1K9fH5MmTZKXqRQ5d+4cPv30U6Snp+ONN97Azz//jO3bt2PkyJFSKEhOTsbXX3+NgwcPYvr06ejatau0/bp16/Dhhx/i1VdfRadOnfD++++jYcOG0uPKjUYj5s+fj2XLlmHSpEkwGAyYMmUKnn76aUyePFnqc+HCBXz22WfIzs7Gl19+iU2bNmHp0qWYNGkSBgwYABQcXpk0aRIqVaqE5cuXS9tS6ZOZmYnvv/8ex48fx6JFi+RlIvKA4HQ6vQ4dTqcTTqcTGo3G51eXXLhwAd9//z3Cw8PxwQcfyMtUitwZOmbOnAmr1YrJkycjKSkJkyZNQv/+/XH+/Hl8+umnuHHjBv7zn/9IMx0oJnQcOXLE5WsAQKNGjTBp0iQEBATg3//+d7F/wfbo0QNTpkzBgQMHGDoeYteuXcOCBQuQlZWFb7/9Vl72Wl5eHux2OzQaDYKCguRlrynd3263w2QyQafTKXKnaKX3n/3dczgcMBqN0Ol0CAkJkZc9FhAYGAhvl4CAAAQEBBRZ74ulXLly0Gq1yM7Ohih6nY/Ij7Rq1QqvvfYarl+/jnXr1iE9PR16vR6hoaEwGo3IyMiQbwK9Xo9KlSpJ/3799dchiiJEUUROTg6++OILl/GVK1fGJ598Io25c/ntt99cQg09nGw2GywWCx555JEi70++WJR8/wxUqX9+fj4EQShS89Wi5P4HloL+giAo9jUCAgIgiqLPXt8H/pyOsmXLQqPRIC0tDTk5OfIylXLNmjXDc889h+PHj+Onn35CVFQUGjVqhBs3buDcuXPSOKPRiKtXr8LpdKJy5couPYoTFhaGihUr4vLlyy7rjx07hl69euGFF17gFQsEq9UKq9WKihUryktE5KEHPnTo9XpUqFABt2/fxo0bN+RlKuXq16+Pfv36QRAEbN68GfHx8WjcuDEaNGiAFStWYM+ePQCA7du3Y9asWejevTv69+8vb3NXnTt3xltvvYV169Zh5MiRAICUlBSsXbsW//vf/zBgwADeG4RgtVphs9n4s0DkAw986AgKCkKdOnUQEhLi8pctPTw6d+6MN998Ezt37sRXX32FVq1a4euvv0bdunXRrVs3CIKAd955B8OHD8esWbPkm7v12muvYdmyZVixYgUEQUBUVBT27duHb7/9Vjp/AwDOnDmDgQMHSvfyaNmyJX755ResWLGC9+ooxYxGI44fP44bN26gRYsW8jIReUgQfXCihMPhgNPphFarRaCPTyRFwXT3woULER0djTFjxijyNYg8VXiVS15eHk8mLaWuXLmC2bNnIycnB/Pnz1fkRD2n0wm73Q6tVuuX/W02G7Kzs2EwGFCmTBl52Wt5eXmw2WyK7X9p6G+1WqHVaqHRaORlr9ntdmRlZUGv10On08nLHnvgZzoAoHr16ihfvjwOHjyIS5cuyctERIq4efMmbt26hebNm8tLRHQf/CJ06HQ6tGrVCmXKlMHhw4flZSIin0tJScHGjRtx/fp1dOnSRV4movvgF6EDAFq0aIFq1aph7dq1fMw0PRDq1auHJUuW8NBKKSSKIq5du4Zr166hT58+fNgkkY/4TeioUKECevTogbJly2LHjh3Iz8+XDyEi8omsrCz88ccfyMzMxD//+U95mYjuk9+EDgBo3bo1unfvjn379mHLli3yMhGR19LT07F06VLs3bsXw4YNK/F9X4jo3vwqdJQpUwZ9+vRB06ZNMWvWLMTGxsqHEBHdt5ycHOzZswcHDhxAr1690KdPH/kQIvKCX4UOAAgPD8eQIUNQu3ZtzJw5EydPnpQPISLyWF5eHk6fPo3Vq1ejcePGGDZsmHwIEXnJ70IHANStWxfvvfceKleujLfffhs//fQTzGazfBgRUYncuHEDs2fPxpQpU9CiRQuMGzdOPoSIfMAvQwcAPProo/j000/RrVs3fPrpp5gzZ85dHwBGROROSkoK5s+fjx9//BEDBw7E5MmTfXITJCIqyi/uSGoymWCxWGAwGIo8Ojk3Nxfbtm3D7NmzIQgCBg4ciF69eqFmzZou44iICjmdTly6dAmrV6/G9u3bodfrMW7cOPTs2VM+VPE7evp7f96R1D01+vvTHUn9PnQUun79OlatWoVly5YhICAAzz33HHr16oWWLVsWuw0RPVxyc3Nx7NgxbNy4ETt37oRGo8GECRPQr1+/Yt+7lP7Q9vf+DB3uqdGfocPHShI6CiUlJWHHjh3YunUrDh8+jODgYDRo0ABVqlRBWFgYypYtK9+EiEoxs9mMpKQkpKSkIDExEU6nEz179kTv3r3RpUsXVKhQQb6JC6U/tP29P0OHe2r0Z+jwMU9Cx53S09Nx8uRJXLp0CSkpKUhNTcWtW7eQl5fnMi4/Px+iKCIgIACCILjUfIH93cvLy4PT6YRGo0FAgO9PMxJFEfn5+YrtP/u7V/j6BgUFKfL+4G7/tVotQkNDERkZiYiICDRo0AAtWrTw6M1T6Q9tf+/P0OGeGv0ZOnzsfkNHSTkcDjgcDsV+KNjfPbPZDLPZDL1ej5CQEHnZa0q/6bK/e1arFUajEXq9XpEPJaX3n/3dY+hwT43+/hQ6fP9nJREREdFdMHQQERGRKhg6iIiISBVCVlaW1+d0EBEREd2L4HQ6vQ4dTqdTuvpAiRNJLRYLbDYbdDodtFqtvOw1pfef/d2zWq2wWq18fYuhdP+8vDw4HA7F+ttsNpjNZuh0OkVOBFd6/9Xob7fbodFoFDvRUMn+drsdJpNJ0ddXyf1nf/ccDgeMRiN0Op1PTvTn1SsqXJ3B/u7x6hX3/L0/r15xz9/78+oV99Toz6tXiIiIiGQYOoiIiEgVDB1ERESkCoYOIiIiUgVDBxEREamCoYOIiIhUwdBBREREqmDoICIiIlUwdBAREZEqGDqIiIhIFQwdREREpAqGDiIiIlIFQwcRERGpgqGDiIiIVMHQQURERKpg6CAiIiJVMHQQERGRKhg6iIiISBUMHURERKQKhg4iIiJSBUMHERERqULIysoS5SuJiIiIfE1wOp1ehw6n0wmn0wmNRoPAwEB52WsWiwU2mw06nQ5arVZe9prS+8/+7lmtVlitVr6+xVC6f15eHhwOh2L9bTYbzGYzdDodgoOD5WWvKb3/avS32+3QaDQICgqSl72mdH+73Q6TyaTo66vk/rO/ew6HA0ajETqdDiEhIfKyxwRRFL0OHQ6HA06nE1qtVpFfSpPJBIvFAoPBoMgPtcPhgMPhgFarVexFY//imc1mmM1m6PV6n/xQyzmdTtjtdsX2n/3ds1qtMBqN0Ov1KFOmjLzsNaX3n/3ds9lsyM7OhsFgUOT1zcvLg81mU2z/S0N/q9UKrVYLjUYjL3vNbrcjKysLer0eOp1OXvYYz+kgIiIiVTB0EBERkSoYOoiIiEgVDB1ERESkCoYOIiIiUgVDBxEREani/wNQYFuaYdIfBQAAAABJRU5ErkJggg==" + }, + "image-4.png": { + "image/png": "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MjK0IV2ZleNgck4wqx8zco/b7YbNZjP8MzIrx5k1voo291hkWW5wQezxeGC1Wg1P2D6fDwAMP3vi9/uhKIrhharT6YTH40FOTo42pKtAIAC/3294IpUkCV6vF5mZmdqQrmRZhsfjQUZGhqEJTlVVuFwupKWlGfpFFUKgpKQEzZo1M/w75HQ6kZSUZHgidblcsNvthvdj1h8Gr9cLi8VieO6pqKiAqqpo0qSJNqSrQCAASZKQlpamDekqEAggEAgYflbDrBxnVu6RJAmlpaU46aSTIv7jHQkhROhgnJH9AIDD4UBKSorhBYpZOc6s3FNWVga73Y6srCxtSFexNr4yM8eZkXu8Xi/Ky8tx8skna0O6MivHmTm+MivHmZV7Dh48iLS0NMP3ObNynFnjq2hPOFiEEA0uiN1uN6xWq+Er4/V6ASDilYmUz+eDoiiGJ1KHwwGXy4WWLVtqQ7oKBALw+XyGF6qSJMHj8Rj+h1uWZbjdbmRmZhqesJ1OJ9LT0w1P2MXFxcjJyTH8O+RwOJCcnGx4gnM6nbDb7YYX+C6XCzabzfB+PB4PLBaL4bmnvLwcqqqiWbNm2pCu/H4/JEkyvFD1+/0IBAKG/+E2K8eZlXskScL+/fvRqlUrQwdxQgg4HA6kpaUZ2g8AVFVVITU11fCC2KwcZ1buKS0thd1uR3Z2tjakq1gbX5mV48zKPR6PB2VlZcjNzdWGdGVWjjNzfGVWjjMr95SUlCAjI8Pwfc6sHGfW+Mrr9UIIEfHBOGPPjxMREREREREdp1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcsni9XqFtrI8kSUhISIDVatWGdCXLMgAgMTFRG9KVoihQVRU2m00b0lUgEEAgEEB6ero2pCtFUaAoCux2uzakK1VVIUkSkpKStCFdCSEQCARM68dut8NisWjDunI4HEhLSzP8OxQIBGC1WtlPhMzKPV6vFwCQkpKiDenKrJwQa/2YlXtUVYXL5UJGRobhucfv95uS4/x+P2w2GxISjD3eblZOMKsfj8eDhIQEJCcna0O6MivHmTW+MisnmNWPLMvweDzIzMzUhnRlVo4zc3xlVo4zKye4XC7Y7XbD9zmz1ses3BNtP9axY8dO0DbWR1VVADB8Zwv2Y/QfVDP7MeMPgxACQgjD10cIAVVVDf/yBLeb0f0E18fo7Ybqg0qJiYmmfIcSEhJM6cdiscRUPzAhJyiKAkSRsCOlqqopOcGsfszKcWbmHlmWTckJiqKY8h1SFMW03GNWP2ZsN1mWYbFYDN/nzMpxZvZjRk4wM/eYUXibmeOC31WjmZXjzMo9kiTBarUavu3MynFm5gRE0Y9FUZQGnyH2er1ISEgw/IiSz+cDAMOPlPr9fqiqavhZGpfLBY/Hg+bNm2tDupIkCX6/3/Az0bIsw+v1IiMjQxvSVbCf9PR0Q7+oqqrC7XYjNTXV0D8OQgjs378fTZs2Nfw75HK5kJSUZPhBGLfbDZvNZvgfb4/Hg8TERMP78Xq9sFgshueeyspKqKqKxo0ba0O6CgQCkGUZqamp2pCuAoEAJElCWlqaNqQrs3Oc0blHlmWUlpYiJyfH0IMjQgi4XC6kpKQY2g8AOJ1OU/oxK8eZlXsOHz4Mm82GrKwsbUhXsTa+MivHmZV7vF4vjhw5glatWmlDujIrx5k5vjIrx5mVe0pLS5GWlmb4PmdWjjNrfOXz+SCEiDj3WIQQDS6I3W43rFar4Stj1uWEPp8PiqIYPohzOBxwuVxo2bKlNqSrQCAAn89n+KU2kiTB4/EY/odblmW43W5kZmYanrCdTifS09MNT9jFxcXIyckx/DvkcDiQnJxseIJzOp2w2+2mFPg2m83wfjweDywWi+G5p7y8HKqqolmzZtqQrvx+PyRJMvwPqt/vRyAQMPwgmVk5zqzcI0kS9u/fj1atWhk6iBNChG7XMLIfAKiqqkJqaqrhg0WzcpxZuae0tBR2ux3Z2dnakK5ibXxlVo4zK/d4PB6UlZUhNzdXG9KVWTnOzPGVWTnOrNxTUlKCjIwMw/c5s3KcWeMrr9cLIUTEB8kiO59MREREREREFCNYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXLL4fD6hbaxPIBBAQkICEhMTtSFdSZIEALDZbNqQrmRZhqqqsNvt2pCu/H4//H4/MjMztSFdKYoCWZaRlJSkDelKURRIkoTk5GRtSFeqqiIQCBjejxACfr8fSUlJsFgs2rCuKisrkZ6ebvh3yO/3IzExEVarVRvSld/vh9VqNWV9zOjHrNzj8XgghEBaWpo2pCtZlqEoiuE5wax+zMpxZuUeRVHgdDqRmZmJhARjj0/7fD7Y7XZT+rHZbKbknljKcS6XC1arFSkpKdqQrszKcWaNr2It90iSBLfbjUaNGmlDujIrx5k5vjIrx5mVe6qqqpCcnGz4PmdWjjMr90Tbj8Xtdje4IFYUBRaLxfCdTVEUADB8Z1NVFUIIw/uRZRmyLBueeFRVhaqqhu/UqqpCUZSId7ZICSEgy7Jp/SQmJhqesD0eD5KTkw3/DsmyjISEBPYTIbNyTyAQAADDB4tm5oRY6ses3KOqKnw+H1JSUgzPPZIkmZLjJEmC1Wo1/LtqVk4wqx+/34+EhATD9zmzcpxZ4yuzcoJZ/SiKAr/fj9TUVG1IV2blODPHV2blOLNygtfrhc1mM3yfM2t9zMo90fZjURSlwQWxx+OB1Wo1/GiFz+cDAMMLSL/fD0VRDE88LpcLHo8HzZs314Z0FQgEEAgEkJ6erg3pSpIk+Hw+ZGRkaEO6kmUZXq8X6enphiY4VVXhdruRmpoa8RcoEkIIHDhwAE2aNDH8O+RyuWC32w0vuNxuN2w2W8z04/V6YbFYDM89lZWVUFUVjRs31oZ0FQgEIEmS4WeizezHjBxnVu6RJAllZWVo3ry5oYMeIQRcLhdSUlIM7QcAnE4nkpOTDR9ox1qOO3z4MGw2G7KysrQhXcXa+CrWco/X60VFRQVatmypDenKrBxn5vjKrBxnVu4pLS1FWlqa4fucWTnOrPGVz+eDECLiq20sQogGF8RutxtWq9XwlfF6vQAQ8cpEyufzQVEUwxOpw+GAy+UyPMEFAgH4fD7DL82WJAkej8fwP9yyLMPtdiMzM9PwhO10OpGenm54wi4uLkZOTo7h3yGHw4Hk5GTDE5zT6YTdbjelwLfZbIb34/F4YLFYDM895eXlUFUVzZo104Z05ff7IUmS4X9Q/X4/AoGA4QfJzMpxZuUeSZKwf/9+tGrVytBBnBACDocDaWlphvaD6sv8UlNTDS+IzcpxZuWe0tJS2O12ZGdna0O6irXxlVk5zqzc4/F4UFZWhtzcXG1IV2blODPHV2blOLNyT0lJCTIyMgzf58zKcWaNr7xeL4QQER+MM/b8OBEREREREdFxigUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlSyAQENrG+vj9fiQkJMBms2lDugoEAgAAu92uDelKkiSoqoqkpCRtSFderxd+vx+NGjXShnQlyzIkSUJKSoo2pCtFURAIBGKmHyEEfD4fkpKSkJBg7DGi8vJyZGZmGv4d8nq9sNlsSExM1IZ05fP5kJiYGDP9+P1+WCwWw3OPy+WCEAIZGRnakK5kWYYsy0hOTtaGdGVmP7GW4yorK9GoUSNYrVZtWFderxd2uz2m+omlHOdwOGC1WpGWlqYN6SrWxlexlnv8fj9cLheaNGmiDenKrBxn5vgq1nJPRUUFkpOTDf+MzMpxZo2vAoEAhBAR5x6Ly+VqcEGsKAosFovhO7WqqgBgSj9CCMO/PLIsQ1GUiD+cSAkhoCiK4Tt1rPWD6s/IarXCYrFoQ7ryer2m/GEwa31kWUZCQoIp62NGP2blOEmSIIQw/A+DqqpQVdXw75BZ/ZiVE8zsx+fzITk52ZTvqlk5Idb6MSP3BAIBWCwWww+Wxtr4KtZyj5mFqhnrA5O/q7HUj1mFqlk5zqzxVbS5xyLLcoMLYq/Xi4SEBMMLO7/fDwCm9KOqquGJx+12w+PxoFmzZtqQriRJQiAQMPwIsyzL8Pl8SE9P14Z0pSgKvF4v0tLSDE08qqrC4/EgJSUl4i9QJIQQOHjwIBo3bmz4vu12u2G32w0fXLndbthsNsMLO4/Hg8TERMP78fl8sFgshn8+VVVVUFUV2dnZ2pCuAoEAZFlGamqqNqSrQCAASZIMzz1m5Tizco8syygrK0Pz5s0Nzz1ut9vwHIfqqx+Sk5MNH8SZlePMyj1HjhxBYmIiMjMztSFdxdr4yqwcZ1bu8fl8qKioQIsWLbQhXZmV48wcX5mV48zKPYcOHUJaWprh+5xZOc6s8ZXf74cQIuKrRixCiAYXxG63G1arNeJOIuX1egHA8ETq8/mgKIrhO5vD4YDL5ULLli21IV0FAgH4fD7D/6BKkgSPx4OsrCxtSFeyLMPtdiMzM9PwhO10OpGenm5oIhVCoLi4GDk5OYZ/hxwOB5KTkw1PcE6nE3a73fAE53K5YLPZDO/H4/HAYrEYnnvKy8uhqqrhB8n8fj8kSTL84JXf70cgEDD8EnCzcpxZuUeSJOzfvx+tWrUytIAUQsDhcCAtLc3QflB9sCc1NdXwwaJZOc6s3FNaWgq73W74QbJYG1+ZlePMyj0ejwdlZWXIzc3VhnRlVo4zc3xlVo4zK/eUlJQgIyPD8H3OrBxn1vjK6/VCCBHxQTJjz1sTERERERERHadYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXLIEAgGhbayP3++HxWKB3W7XhnQVCAQAwJR+hBBISkrShnTl8Xjg8/nQuHFjbUhXsiwjEAggNTVVG9KVWf0oigK/34+UlBRYLBZtWDdCCHi9XiQnJyMhwbhjREIIlJWVoVGjRobv2x6PB3a7HYmJidqQrrxeLxITE2Gz2bQhXfl8PlitVsP7MSvHOZ1OqKqKrKwsbUhXkiRBURQkJydrQ7qSJAmyLCMlJUUb0lWs5R5ZlnHkyBE0adIEVqtVG9ZNMMclJSUZ2g9MzD1m9WNW7qmsrERiYiLS09O1IV3F2vjKrBxnVu7x+/2oqqpC8+bNtSFdmZXjzBxfxVqOO3LkCJKTkw3f58zKcWaNr6LNPRaXy9XgglhRFFgsFkN3agBQVRUATOlHCGH4l0eWZSiKEvGHEylVVaGqquFfUrP7sVqthidsRVFM6cfv98Nutxu+b8uyjISEBPYTIbNynCRJEEIY/ofB7O9qrPVjdE5QVRWBQMDwnBDMcWZ8h8z6rsZaP4FAABaLxfBBqRpj4yuzc4LR/SiKAkmSDC/wzcpxZo6vYi3H+f1+WK1Ww/c5s9bHrPFVtLnHIklSgwtin8+HhIQEwwdxZh7BVFXV8MTj8Xjg9XrRpEkTbUhXZh3BlGUZfr8faWlp2pCuFEWBz+czvB8hBDweD1JSUgz/opaWliI7O9vwfdusI5gejwc2m83wQZxZZ6LNOoLpcDigqioaNWqkDenKrDO3kiRBkiRTco8ZOc6s3CPLMsrLy9G0adOI/3hHyu12Izk52ZR+kpKSTMk9ZuQ4s3JPRUUFbDZbTJ0hNmN8ZVaOMyv3+P1+VFZWIicnRxvSlVk5zszxlVk5zqzcc/jwYaSmphq+z5mV48waX0V9hlgI0eCC2O12w2q1Gp7gvF4vABie4Hw+HxRFMTwhOBwOuFwutGzZUhvSVSAQgM/nQ2ZmpjakK0mS4PF4DL/cU5ZluN1uZGZmGnpkUVVVOJ1OpKenG5pIhRAoLi5GTk6O4d8hh8OB5ORkwxOP0+mE3W6POPFEyuVywWazGd6Px+OBxWIxPPeUl5dDVVU0a9ZMG9KV3++HJEmGD7L9fj8CgQAyMjK0IV2ZlePMyj2SJGH//v1o1aqVoYMrIQQcDgfS0tIM7QcAqqqqkJqaavjgyqwcZ1buKS0thd1uR3Z2tjakq1gbX5mV48zKPR6PB2VlZcjNzdWGdGVWjjNzfGVWjjMr95SUlCAjI8Pwfc6sHGfW+Mrr9UIIEfGBBGMP1xAREREREREdp1gQExERERERUVziJdMmXNLDS6ajE4uX9MTyJdNHjhxBeXk5KioqUF5ejm+++QYdOnTQviQqsfYURKfTCSGEKd9VxYQnsJp5H58kSYb3o5j0BFZZllFRUYHGjRsbnntO1Cew2mw2NG7cODQ1adIEaWlppuU4sy4n5CXT0eEl09GJxfEVL5mOjlk57ni/ZJoFsQkJmwVxdGIxYcdaQfzNN99g586d+OGHH/Dbb7/B5/PB7/cjKysLXq8XLVq00L4kKqqqwmKxGLofoPozAmB4P4qiAICh+xuq10cIYfjDTNhPdIQQkGUZiYmJhu9zZn2H9O6nqqoKgUAAfr8fSUlJSE5Oxvnnn4+zzjoLF1xwAdq0aaN9ia7MGiyyII4OC+LoxOL4igVxdMzKcSyIoxBrCZsFcXRiMWHHSkG8dOlSfPTRR9izZw8yMzNx+umno1OnTsjMzER2dnbooTpG/2EiotgWfGCb1+tFeXk59u/fj19++QVFRUWwWq3o2bMnBgwYgC5dumhfqguzBossiKPDgjg6sTi+YkEcHbNyHAviKMRawmZBHJ1YTNgnekG8Zs0aLFq0CNu3b0fHjh1x0UUXoX379mjRogVycnJCl08TEelJCAGfzwe3240DBw7g0KFD+OGHH/C///0PZWVl6Nu3L2677Tacdtpp2pf+JWYNFlkQR4cFcXRicXzFgjg6ZuW4470gNvZ6MCKKCW63G88++yxeeeUVJCYmYujQoRg7dizuuOMOXHTRRfjHP/6BjIwMwxMqEcWn4ECqadOm6NSpEy6//HI88MADePbZZ3Hdddfh559/xoMPPoiPPvpI+1IiIqKjYkFMREe1d+9eDB8+HMuXL8eAAQMwYsQI9OvXD+3atTP86D8RUX0aN26Mrl27YtCgQRg5ciS6d++OiRMn4t///rd2ViIionqxICaiem3cuBEPP/wwnE4nRo0ahb59++If//hHxJeiEBEZpXnz5ujcuTMee+wx3HDDDVi2bBnGjRsHn8+nnZWIiKgWFsREVKe9e/di5MiREEJg9OjRuP766w2/T4uIKFotW7bEv/71LwwaNAgrV67E9OnTtbMQERHVwoKYiGpxu9145pln0Lx5c0ydOhVnn302zwoT0XGvRYsWuPrqq3HXXXfhiy++wH//+1/tLERERGFYEBNRLdOnT0dFRQWGDx+Obt26GfoUSiIiPaWmpuKuu+7C1Vdfjddffx2ff/65dhYiIqIQFsREFGbt2rWYM2cOBg0ahJ49exr6UwlEREZo1qwZHnjgAVxwwQWYPHky7ycmIqJ6sSAmojCzZs3C5Zdfjssvv5yXSRPRCevkk0/GXXfdBbfbjQ8//FAbJiIiAlgQE1FNn3zyCQ4cOIAHHniAD9AiohPeWWedheuuuw5Tp07FoUOHtGEiIiIWxET0/82cORPdunVD165dtSEiohNOcnIyHnroIaiqikWLFmnDRERELIiJ6P/8+OOP2Lt3L/r168dLpeNM3759kZeXp20OycvLQ9++fbXNRCeEtm3bok+fPiyIiYioTiyIiQgA8MUXX6Bjx47o3r27NkQxbtmyZdi4caO2OWTjxo1YtmyZtpnohHHFFVdg+/bt2LdvnzZERERxjgUxEQEAVqxYgYsvvhgZGRnaEBHRCe3iiy9GmzZtsGbNGm2IiIjiHAtiIsKRI0fwww8/4NJLL9WGiOr066+/Yvz48bjtttvQt29f9O3bF+PHj8evv/4KANi+fTv69u2LuXPnhr2uvva5c+diyJAhofe69957a82D6su765u2b98eNu/27dvD3nP8+PG15qH40LRpU1x44YVYv369NkRERHGOBTERYf/+/fD7/ejQoYM2RFTLwYMH8eijj2L58uU49dRT0bVrV2RlZWHu3Ll49NFHAQBlZWVYtmwZfv7557DX1tX+2muvYcqUKXC73ejatSvat2+PgoICTJkyBUuWLAl7/bJly3DkyBF07do1NGVlZWHZsmUoKysLzffFF19gyJAh2L17N9q3b4/27dtj3bp1GDJkyFEvD6fY1aZNm9ABGyIioiAWxESEAwcOIDs7G02aNNGGKE7s2bMHN910U53Tnj17wubdvHkz1q1bhyeeeAKPPvooBg0ahKeffhrdu3fHunXrsGPHjoh+tuudd95BTk4ORo0ahUGDBmHYsGGYNWsW9u7di/fff187O8455xwMGjQoNF1//fXaWTBhwgQcOXIE06dPx7BhwzBs2DBMmTIFBQUFmDRpknZ2igPNmjXD/v37tc1ERBTnLF6vV2gb6+Pz+ZCQkAC73a4N6crv9wMAkpKStCFdBQIBqKqK5ORkbUhXHo8HXq/X8GJDlmUEAgHDnxCsKAp8Ph/S0tK0IV0F+0lNTYXFYtGGdSOEgMfjQUpKChISjDtGJITAoUOHkJ2dbfh3yOPxwG63IzExURuq0/vvv4+XX34Zu3bt0oYoDlgsFmRnZ6N3797aEADgq6++QkVFBYT4vz8XhYWF2LlzJ6644oqwPPDBBx9g4MCBWLVqFbp164bs7Gzce++9mDNnTmie1atXo0+fPsjLy8OMGTMAAKtWrUKTJk1w3nnnheYDgPbt2yM7OxvffPNNqM1isYS9FjXec9WqVbjqqquwY8cOnH/++cjLy8PUqVND8wHAQw89hPfffx9btmxB586dw2IU2z755BPcdtttKC8vb3Bu9Hq9SExMhM1m04Z0VVFRAZvNFtGBpGjE2vhKkiTIsoyUlBRtSFdmja98Ph+qqqqQk5OjDekqFsdXHo8HycnJsFqt2rCuIh1fRevw4cNITU01fJ8zK8f5fD5YLBbDc4/f74cQIuLcYzlw4ECDC2JVVQHA0J0aMdiPLMtQVdXwIkgIAUVRDP+Sxlo/qP6MrFaroX8YUP1FtdlspuxzkazP66+/jgULFqCgoEAbojhgsVhw9tlnY/78+doQAODOO+/Erl27QgVx0I4dO7B371643W789NNP2LZtG9avXx8qTC+88EIUFhZiypQpOOecc3Dw4EEsW7YMr7/+eq2i9uDBg9i7dy9+++03HDp0CIWFhfjwww/Rrl27iAvi119/HUOGDMHSpUtx0003heYDgEWLFuG2224LzUvx48cff8TZZ5+N3bt3N/gAtaIosFgshufsQCCAhIQEw//emTXuMbMfIYThRZBZ4xFVVSFJkuFFg1nrgyjGI9GKtX7Myglm5TgzcwKi6Mfi8XgaXBDzDHF0Yu0MsSzL8Pv9MXOGWFVVeL1eU45glpWVoVGjRoZ/hyI9gvn222/j9ddfxy+//KINURywWCzo3r17WOFZU48ePbB169ZQQexyufDkk09i+/bt8Pv9OOmkk5CRkQFVVbF48eJQsbl+/Xo899xz2L9/PzIyMpCUlISqqips3749rKj94osv8MILL6CyshLp6elIS0tDmzZtsHz5crRq1SrignjatGkYM2ZMnUWvdl6KH+vWrcPll1+OI0eONPjvvllnT3iGODqxdobY7/ejqqoKzZs314Z0FYvjq1g7Q1xeXo6UlBTD9zmzcpxZuSfafixCe8j/KNxuN6xWq+EJzuv1AoDhCc7n80FRFMMLO4fDAZfLhZYtW2pDugoEAvD5fMjMzNSGdCVJEjweD7KysrQhXcmyDLfbjczMTMMTttPpRHp6uqGJVAiB4uJi5OTkGP4dcjgcSE5ObnDh/emnn+LRRx9FcXGxoduajk+RFsRjx47Fyy+/jJEjR+K8885DRkYGsrKy8Omnn2L8+PGhYjMQCOCXX37Bn3/+CVmWkZycjN27d2PkyJGhovbXX39F//79YbFYMHLkSLRo0QIpKSlo2rQpevXqhVNPPTXigjh4FnjevHm4++67Q/Oh+mqIIUOGsCCOQ3PnzsWIESNw5MgRbaheLpcLNpst4sFVpEpLS2G325Gdna0N6SrWxld+vx+SJBl+IMGs8ZXH40FZWRlyc3O1IV3F4vjK4XAgLS3N8EI10vFVtEpKSpCRkWH4PmdWjvN4PLBYLIbnHq/XCyFExAcSjDtcQ0QnjJYtW6KsrAyVlZXaEFEtGzZsQFZWFgYPHozrrrsOF198Mc4555xaP2lkt9txzjnn4LrrrkPfvn3Rp08fdOrUKWyeP//8Ezt37sQdd9yB/v3747LLLkPPnj3hdrtRUVERNm9D9e7dG8nJyVixYoU2hA8++ADJycm8fzgOlZaWokWLFtpmIiKKcyyIiQgtW7aE3+9HYWGhNkRUS6NGjVBVVYXPP/8cO3bswKZNmzBq1Chs3bpVO+sxBW8l2bJlC7799lvs2LED8+bNwxNPPBF2pH/v3r344osvAOCYZ4OaN2+OBx98EGvWrMGoUaOwadOm0DJ+//33GDZsmOGXJNLxp6yszPArtYiI6MTDgpiI0KxZM3To0IG/z0oNMmLECJxzzjl44YUX8K9//QuTJk1CeXk5Jk6cCFQXtw112mmn4YknnkB+fj4ef/xx/Otf/8LKlStx6aWX4rLLLsOePXvgcrkwY8YMPPXUU2jXrl2dP7OkNWLECNx///344osv8Pjjj+Pxxx/Htm3b8OSTT2Lo0KHa2SnGVVRUYOvWrejVq5c2REREcY73EJtwjwvvIY5OLN7jcrzeQwwAw4YNQ1FREZYuXWro9qbjzyeffILs7Gxccskl2hAA4H//+x8qKipCT2wOBALYuXMnSktLQ/cGt27dGm3btsWXX36Jtm3b1ntJ8qFDh/D111/j9NNPx5lnnglU3yuVn58Pp9MJVJ/h/cc//oH9+/ejsLAQ1157LbZs2YKKigpkZ2ejZ8+eYft28D0vuOCCsDO/9b0vzw7Hn7Vr1+Kmm27CunXrcP7552vD9TLr/jreQxwd3kMcnVgcX/Ee4uiYleOO93uIWRCbkLBZEEcnFhP28VwQf/nll7jjjjuwfv36Wvd5EhGdyMaPH4+FCxdi+/btEY0tzBossiCODgvi6MTi+IoFcXTMynHHe0HMS6aJCADQvXt3ZGZmYuXKldoQEdEJa+/evVizZg2uuuoqwwdjRER04mFBTEQAgMzMTNx///1YtGgRdu3apQ0TEZ2QVqxYgf379+Nf//qXNkRERMSCmIj+v/vuuw9WqxVLly7VhoiITjg///wzFixYgJtvvhnt27fXhomIiFgQE9H/16pVK9x///2YO3cutm3bpg0TEZ1QlixZAqfTySeLExFRvVgQE1GYfv36oXPnzpg5cya+//57bZiI6ITw/vvvY86cOXjkkUdwyimnaMNEREQAC2Ii0mrWrBkmTZqEiooKvPHGG/j111+1sxARHdeWLVuGyZMn49prr8Udd9yhDRMREYWwICaiWs466yyMGzcOO3bswOTJk1FeXq6dhYjouLRt2zZMnjwZZ511FvLy8tCsWTPtLERERCEsiImoTr169cLw4cPx888/Y+LEifjmm2+0sxARHTdcLhc++OADPP7442jTpg2effZZtG3bVjsbERFRGBbERFQnq9WKvn37YsaMGSgqKsJTTz2F9evXa2cjIvrbud1uzJ07F5MmTUKnTp0wYcIEnHnmmdrZiIiIamFBTET1Sk9PR+/evTFmzBi0aNECo0aNwqRJk7Bu3TpIkqSdnYjIVIWFhfjggw8wbNgwfPjhh7jtttuQl5eHs846SzsrERFRnVgQE9FRWSwWdOvWDU8//TTuuusu7N69G6NGjcL48eOxZs0aOBwO7UuIiAx18OBBLFmyBHl5eZg1axZsNhueeeYZ/Otf/+ITpYmIKCIWIYTQNtbH7XbDarUiOTlZG9KV1+sFAKSkpGhDuvL5fFAUBWlpadqQrhwOB1wuF1q2bKkN6SoQCMDn8yEzM1Mb0pUkSfB4PMjKytKGdCXLMtxuNzIzM2GxWLRh3aiqCqfTifT0dFitVm1YN0IIFBcXIycnx/DvkMPhQHJyMux2uzb0lzidTuTn52P16tX45ptvcPjwYeTk5ODcc8/F+eefj4yMDGRnZ/MhNkSkG5/Ph8rKSpSXl+PgwYPYvHkz9u7dC0mSkJOTg5tuugmdO3dGu3bttC/9y1wuF2w2G5KSkrQhXZWWlsJutyM7O1sb0lWsja/8fj8kSUJ6ero2pCuzxlcejwdlZWXIzc3VhnQVi+Mrh8OBtLQ0JCYmasO6Mmp8pVVSUoKMjAzD9zmzcpzH44HFYjE893i9XgghkJqaqg0dFQtiExI2C+LoxGLCPtEL4qDy8nLs3bsXe/fuxc6dO1FSUoKKigq43W4AiDgRERHVR5Zl+P1+2Gw2pKamIicnB23btkWXLl2Qm5uLDh06GDYINmuwyII4OiyIoxOL4ysWxNExK8exII5CrCVsFsTRicWEHSsFcZDD4cCRI0dw5MgRHD58GF6vF06nExUVFaisrNTOHrVAIACr1Wro54PqfdtisRj+BzXahB0pRVGgKIrh+0E0/Wzbtg3r169HXl6eNlQvRVEgy7Lhf7hVVYUkSab043Q6kZGRgYQEY+9gChaUJ1o/NpsN2dnZaNy4MVJSUpCWloaTTjoJ6enpyMnJiWifi4ZZg0UWxNFhQRydWBxfsSCOjlk5jgVxFGItYbMgjk4sJuxYK4idTifsdntYIpUkCT6fD36/P2zev8LtdiMxMTFmEvaRI0egqiqaNm2qDenK7/dDlmXDc1w0g9J58+Zh5syZ2L17tzZUr0AgAL/fj4yMDG1IV7Isw+PxICMjw9DcI0kSDh48iBYtWhg6iBNCwOl0IjU11dB+UJ17UlJSYLPZtKGoJCQkIDk5GSkpKWGfhVk5zqzBIgvi6ESTe6Jh1viKBXF0WBBHz6wcZ9b4igVxFMxK2CyIoxOLCTseCmIjxFrCLi8vh6qqht9rbdZg0e/3IxAIRFSovvnmm3j22Wexf/9+baheZuU4s3KPJEnYv38/WrVqZeggzszBYlVVFVJTU3UriOtjVo4zK/ewII6OWTnOrNzDgjg6ZuY4s3IPC+LoRFsQ63NNExEREREREdEJxiLLcoPPEHu9XlitVsOPigQvtTT6aEUgEICiKIYfrXC73fB4PIafDQo+eMToI7KyLMPn8xl+RFZRFHi9XqSlpRl6BFMIAbfbjdTUVN3ue6uLEAIHDx5EkyZNDP8Oud1uJCUlGX6k1O12w263G342yOPxwGazGd6Pz+eDxWIxPPdUVVVBVVXDzwZJkgRJkiI+UhopSZIQCAQiyj1vv/02Jk6ciD/++EMbqpdZOc6s3CPLMsrKytC8eXPDz5643W6kpKQY2g+qzzYkJyebknvMyHFm5Z7y8nLYbDbDzwbF2vjKrBxnVu7x+XyoqKhAixYttCFdmZXjzBxfmZXjzMo9hw4dQlpamuH7nFk5zqzxld/vhxAi4isxLS6Xq8EFsaIosFgshu7UqO4HgOE7taqqEEIY3o8sy1AUxfCdQFVVqKpq+JfUrH6EEFAUBVar1fCEbVY/fr8fdrvd8O+QLMtISEiImX5iLfdIkgRUPzDISGbluGhywn/+8x9MmzYNe/fu1YbqFU0/0TArJ6iqikAggKSkJEP7MWt9YGJOMKsfs3JPIBCAxWIxPCeYlePMzD1m9WNG7lEUBZIkRTyYj5RZOSHW+oGJucfv98NqtZqyz5mR48zKPdH2Y/H7/Q0uiP1+PxISEgxP2IFAAAAMP4smSRJUVTW8UPX5fPD5fGjUqJE2pCtZliHLsuGJVFEUBAIBw4/8qqoKv99veD9CCPh8PiQlJRmeEA4fPoysrCzDv0M+nw+JiYmGJ1Kz+jHrD4NZucflckEIEdE9t9Ew62BcNLnn7bffxpQpU1BYWKgN1SuafqJhVu5RFAUVFRVo3Lix4bnH6/WakuO8Xi/sdnvEg5FIxVrucTgcSExMNPxMp1k5zqzx1fGc46IRCATgcDgMf+CiWTnOzPGVWTnOrNxTUVGBlJQUw/c5s3KcWbkn2n74UC0THvrAh2pFR47Bhz7woVrRibWHPvChWnyoFvhQrb/ErBxnVu7hQ7WiY1aOMyv38KFa0TEzx5mVe/hQrejwoVpEREREREREEWBBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTEREZnG6XRi0qRJWLlyJVwuFyZNmoQXXnhBOxsRERGRKVgQExGRaSwWC1auXImvvvoKbrcb//73v5Gfn6+djYiIiMgULIiJiMg0qampaNu2LZxOJ1RVxaFDh3DOOedoZyMiIiIyBQtiIiIyTUJCAnr27Bn6f1ZWFnr06BE2DxEREZFZWBATEZGpevbsiZSUFABAp06d0KFDB+0sRERERKZgQUxERKbq2LEjWrVqBQDo3r070tPTtbMQERERmYIFMRERmSo9PR3t27cHAHTr1k0bJiIiIjINC2IiIjLdmWeeCYvFEnY/MREREZHZLIqiCG1jfTweD6xWK5KSkrQhXfl8PgBAcnKyNqQr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4qyzzgKq/06sWLECX3/9dejz7dmzJ/r37x9ahuCy1nxdfe333nsvrrnmGtx2222h+bTto0ePhsfjqbWMhw4dwqhRo3DPPffg0ksvxcSJEwEgbN+oa1+sa3vVZeHChVi3bh38fj/OOussDB48GOnp6cjLy8OMGTOA6m0ITZ9bt27F/PnzUVVVhaysLFxwwQUoKCioNV9DuN1uLF68GNu3b693HerarvW133vvvRg8eDB++eUXbNmyBX6/H6eeeiruuusuAMBbb72FAwcOICkpCZdddlmtz0VP+/btw5lnnokhQ4aEfVcKCgrQoUMHjB07FpMnTw57zdF888036NmzJ4qKitCmTRttuE4ulws2mw1JSUnakK5KS0tht9uRnZ2tDekq1sZXfr8fkiQhPT1dG9KVWeMrj8eDsrIy5ObmakO6isXxlcPhQFpaGhITE7VhXUU6vopWSUkJMjIyDN/nzMpxHo8HFovF8Nzj9XohhEBqaqo2dFQ8Q0xEUTl06BC+/PJLdO3aFZdffrk2DAC4/PLL8Z///Ac33nhjqO21117D+PHj8euvv6JZs2ZQFAVvv/02hg8fjkOHDgHVg/yRI0fio48+Cg2oXn755bCiGtUF9y+//IJmzZqFpnnz5uGzzz4LzXPo0CGMHDkSCxYsQHJyMpo1awa3243XXnsNI0eODHu/hQsXYsyYMaH3TEtLw4IFC8KWDQDmzZuHhQsX4u233w57PQC8/vrrmDdvHubNm6cNhdm/fz/mzZsHt9sdtvy//PJL2GvdbjeGDx+O999/H4qioFmzZigpKcH48ePDiubg+40ZMwbr169Hs2bN4HQ68fLLL+Ppp58OzYcI1vOzzz4LrWfNdgBYsmRJaD33798fap82bRpmzpyJysrK0Oc7a9assGUILmvN19XXPm/evLBLkOtqLysrw9tvv419+/aFzbN27VrMmzcvdPDus88+C9s3VqxYgfHjx2PLli2hZa1re9Xltddew6RJk3Dw4EE0a9YMBQUFtfZP1NHn+vXrMWrUqFCfgUAAM2fOxCuvvBI2X0O9//77mDVrFgKBQL3rUNd2ra993rx5eOaZZ7B8+XI0adIEAPD2229j6tSpePrpp+HxeNCsWTN8++23mDRp0jHP0t57771HnWreb621bds2eL1e9OzZM6y9ffv2OO2007Bly5awdiIioqiICLhc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d69zXWqq6/5NUWM5ggCISy65JGyeutT3fkIIkZWVJa699lohIlzPmve/du7cWTz22GNi69atIj09Xfz++++h9wr22b17d5GVlVXv/hAUXFbt/dPz58+vtQ6ovk+95nwl1feK17xX1+fziW7duolu3bqF7uWePn16KC6ql69Lly6ipKRErFmzRqCee2BTUlJC26suwfu8tftxaWlpreWquQ3nzJkjAIj333+/xqv+z9lnnx3VPcRBv//+u/j666/FwoULxeDBg0ViYqJ45513hDjKvjFr1qxa7drlF3Xsk0F1zat1zTXXHHWaM2eO9iUhn3/+eb3bq1mzZkf9jOoSvId43759tXJgfZPT6RRer7dWu95T8B5ibbveU6yNr7xeryn9mDW+crlcoqioqFa73lMsjq8qKytFIBCoFdN7inR8Fe1UUlJiyj5nVo5zuVym5B632y1cLlet9mNNEZ0htlgsphxFiLV+8H8jiVrtek9mHcGMtX4STDxCdrwewQxu60hkZGRgyJAh2Lt3b51nFQHg+eefR1lZGa6++moAQJ8+fQAAy5cvD5vv0KFD2LBhQ+inX+bOnYvhw4cDAFq2bIlTTjkFnTt3hizLoTPSy5YtwznnnHPMs1ZffPEFUlNT8fjjj+Of//wnrrvuOvTs2RM//fRT2Hy9e/cGgFr30Aaf8jxp0qSwdgBo2rQpunbtiuXLl2Px4sX13q/6V3Tr1g07duyo9TTfFStW4L777qvVrr3Md/369aiqqgrd7xvNegLANddcg9WrV2PJkiU4++yza/1cFQBceOGFqKqqCrvfGNX389Z1NlB7/3RdZ2tRfZ96zflqXmYdlJSUhFtvvRU//vgj3nvvPaiqiv79+2tng91uR8uWLdGtWzc0atQo9BNZQevXr4fX68X5558f1l5T8JJ07X6s/b/WVVddVeu+c1Rvn6KiorC2hgh+ZnPnzsUpp5yCnj17YsCAAbjnnnsgy3Lop5yCysrKwv6vXXcjaO8Z1k7aS6FrOu+889CoUaNa22v9+vUoKyur86feGkKb/442IcJcGu0UzbJFM5k17jGzH7O2m1n9xNJ4McHk71As9WPmVSNmrI+ZOSGqfkBEFKX7778fV155JV566SVMmjQJ69evx+7du7F+/XqMGTMGc+fOxd133x36rdJLL70U3bp1w+zZs/Haa6+F5h09ejTK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uHHjBk1GnxUjIiKKB7xk2oRLenjJdHRi8ZIeXjJNRqnr/tt4cfjwYSxfvhw2mw3nn3/+UR+I9XfT3tNe1z30JSUl2pfVKTMzM+y+ezo6XjIde+MrXjIdnVgcX/GS6eiYleN4yTQRERmuVatWuO++++KuGEb108vvu+8+DBw48LguhlH9ZOjevXtj4MCBoWXu3bt3WGHbqlWrBk0shomIiP46FsREREREREQUl1gQExERERERUVxiQUxERERERERxiQUxERERERERxSUWxERERERERBSXWBATERERERFRXGJBTERERERERHGJBTERERERERHFJRbEREREREREFJdYEBMREREREVFcYkFMREREREREcYkFMREREREREcUlFsREREREREQUl1gQExERERERUVyyeDweoW2sjyzLsFgssFqt2pCuZFkGACQmJmpDulIUBUIIw/sJBAKQZRmpqanakK5UVYUsy7Db7dqQrszux2azwWKxaMO6EUJAkiRT+nG73UhJSTH8OxQIBJCYmIiEhIYd85o6dSq2bNmCqVOnakNERDHh0KFDuOGGG1BQUIDWrVtrw3WSJAkJCQmG52yv14uEhAQkJSVpQ7qKtfGVoihQVRU2m00b0pVZ4x5ZluHz+ZCenq4N6SoWx1eSJEU07olWpOOraLndbthsNsP3ObNynFm5J9p+IiqIJUmCxWKJuJNIRbsykZJlGUIIwxNpIBCAJElIS0vThnRlVsI2ux+zEqkZ/bhcLqSkpBi+b0easKdOnYq5c+eiffv22hCRIYQQEEI0eB8l0sO6deuQn59/3BXEHo8HVqs1Zgpis8ZXsVgQe71eZGRkaEO6isXxFQvi6JiV48zMPYiiH4uiKA0uiM1K2D6fDwCQnJysDenK7/dDURTDz9y6XC643W7k5ORoQ7qSJAl+v9/wI4tmJexgP+np6YYmUlVV4Xa7kZqaamhCEEJg//79aNq0qeHfIZfLhaSkpAYPErZv347t27drm4/J5/MhMTEx4sQTKb/fD6vVang/gUAAFoulwdstWm63G6qqmvIdUhTF8P1NlmXIshxRzt64cSOWLl2KWbNmaUP1UhQFkiRF1E80VFWF3+9HSkqKNqQrRVFQWVmJ7OxswwdXXq8XSUlJpvRjt9sNzaWozj02my2qfm677bYGH6D2eDxITEw0fFB6+PBh2Gw2ZGVl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HuKomXV/XUPvIQ4EArj66qvRrl07zJw50/CDKUR0YlmzZg2GDBmC559/HjfeeKM2XItZOY73EEcnkvHVc889hxUrVuCDDz6I+HYaIopNS5cuxaBBg/DSSy/h9ttv14brFe09xJFdyE1EFIXVq1dj//796N+/P4thIqqle/fuuPTSSzFr1iz4/X5tmGJUUVER3nvvPfTv35/FMBEB1WeHFy9ejNNPPx19+vTRhg3BgpiIDCVJEmbNmoXevXujW7du2jARETIyMtCvXz+UlJRg1apV2jDFqA8//BDZ2dkNvj+QiGLfhg0bsHbtWjz66KOGXzUTxIKYiAy1evVqlJSU8OwwER1VzbPEwXtdKXbx7DARaR05cgRLlizBP/7xD9PODoMFMREZKXh2+NJLL+XZYSI6qszMTPTv359nieNE8Oxw3759tSEiilPBs8NDhw417ewwWBATkZGCZ4cHDBjAs8NEdEw8Sxwfap4dbtu2rTZMRHHoyJEjWLx4MU477TRTzw6DBTERGUWSJLz44ou49NJLcf7552vDRES11DxL/MUXX2jDFCN4dpiItP6us8NgQUxERvnyyy9NuXf4k08+wdChQ7XNfxuPx4OxY8fik08+0YaOG8daxsmTJ2Po0KG1pueff147K5HueJY4tvHsMBFp/Z1nh8GCmIiMUPPJ0kafHf7666/x73//W9v8t/B4PJg2bRpeeuklfP3119rwcaEhyzhr1iysWLECv/zyS9j0xx9/aGcl0l3wLPH+/ft5ljgGLViwgGeHiSjM3/Fk6ZpYEBOR7tasWWPK2WEA6Nu3L15++WVts+k2bdqEJ598Eq+++ircbrc2fFxoyDIWFxejoqICN954I5599tmw6aGHHtLOTmSI4FniF198EV6vVxumE1RRURHeffdd9OvXj2eHiQjQnB2++uqrtWFTWIQQQttYH7fbDavViuTkZG1IV8E/fikpKdqQrnw+HxRFQVpamjakK4fDAZfLhZYtW2pDugoEAvD5fMjMzNSGdCVJEjweD7KysrQhXcmyDLfbjczMTFgsFm1YN6qqwul0Ij09HVarVRvWjRACxcXFyMnJMfw75HA4kJycDLvdrg3pyul0wm63IykpKdQmyzKuueYanH766ZgxYwbS09PDXqO3Tz/9FGvXrj1mUezxeLBs2TJs27YNgUAAmZmZOP/883HllVci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GIgZiJPGQGxMawrEAHD77bdj27ZteOWVV9C9e3exTESUUPQ7O5csWdLk7tJW9TgG4sbmzJmDt956C4sWLULPnj3FMhG1Qh988AH++te/Yvbs2bEzZzfU0gMxd5kmIlOMHz8excXFPJaYiJLyyy+/8NjhFqqoqAjz58/HZZddxjBMRED97PDbb799WB47HMVATESmOO6443DOOefwWGIiSsoHH3yA/fv383CLFui///0vjx0mojjR7x2+5ZZbGu0qfbhgICYi03CWmIiSsXv3brz99tucHW6BODtMRKLomaW7dOmC888/XywfNhiIicg0/fr14ywxETVbdHaYZ5Zuef773/8iIyMDo0aNEktE1EpFZ4cPxzNLN8RATESmGj9+PPbv389ZYiI6qOjs8DnnnIP+/fuLZfoNcXaYiERHyuwwGIiJyGzRWeK3336bs8RElNBHH33EY4dbKM4OE5Fow4YNR8TsMBiIicgKN910E/bt24ePP/5YLBERYffu3Xjrrbdw9tln89jhFmbfvn2cHSaiOEfS7DAYiInICv369cPZZ5/NY4mJqEnR2WEeO9zy/Oc//+HsMBHF2bBhA5YtW3ZEzA4DgC0cDuviwkTC4TDS0tLgdDrFUkrJsgwAlqxH0zSkp6eLpYTGjBkDAHjttdfEUkKhUAjhcBht27YVSymlKApkWTb9S69VVUUkEjF9PZqmIRwOm74eXdchSRLS09ORlmbeZ0Q7duzAgAED8NVXX+G4444TyykVCoXgdDrhcDjEUkpJkgSHw9Gs9Wzfvh2XX3457r77btx0001imYhaqT179uC6665Dr1698PTTT4vlJlnV48LhMOx2u+nr8Xq9cDgc8Hg8Yimlkh1f7d+/HxdccAHGjBmDe++9VywTUStUV1eHO++8E9u3b8fSpUubFYgjkQhsNluze49RsixD13W4XC6xdFC2YDDY7EAsyzLS0tJgt9vFUkopigIApr8BqaoKTdOS+uOMHTsWADB//nyxlFAkEoGiKKa/0amqClVVk94IkqVpGhRFOWLWo+s6ZFmG0+mEzWYTyymzY8cOHH/88di6dSv69u0rllMqEonAbreb/lpNtifceeed2Lx5M8444wyxREStVHFxMb744gu88cYb6Nevn1huUkvtcUaFQiHY7XbT3++SHV/NmzcPDz30EC688EL06tVLLBNRK+Tz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zOPmzZvx5z//GR07dsTy5cvjZhk3b96MNWvWwOfzAQD69euHP/zhD8jLyzvobsCdO3fGDTfcAABYsWIFfvrpp9iustnZ2Rg4cCDOOussAGj2/ezatQsfffRR7H569OiBk08+OS6IvfTSSwAQu83mzZuxfPlytG/fPrasKdXV1fjggw+wa9cuoH533mHDhsVmLl966SXs379fuNX/SfQYVqxYgfXr1yesN3TRRRcBAJYsWSKWAABffvklTjrpJMybNw933HFHbHl1dTUGDhyIfv36YdmyZXG3SZXo7PVVV12F559/PrZ88+bNGDJkCGbMmIH77rsv7jZR1dXV6N+/PwYOHIiPP/44rnbuuedi1apVCIfDccsPZ+KscsOLOKvcMCzb7fYmj1WO/j+Z9y6rBosMxMYwEBtj1fiKgdg4BmJjGIgNMNKwGYgZiI1qCYE4OtvbMPBG/19RUQFZlhuF3qZme8WLmc9bS7F27VqceeaZGDduXFyQEd1555144oknsGTJElx44YVA/e65L7zwAiorK9GrVy/U1NSgpKQE5513Hh588EH89a9/jd3+9ddfR0FBAc4991wAQM+ePTF58uTYLr4FBQXIycmBJEn4+eef4fF4MHPmTJxyyim45pprDnk/mzdvxpNPPomdO3eiS5cuAIADBw6ga9euuPfee2PHoTacfQyFQrjqqqtQU1OD008/PeEsbXFxMZ544gmsXbs29iHJvn37kJWVhfHjx+OCCy7A1KlT8fPPPwMAPv74Y1RWVuLqq6+O3cfChQsb3OP/ae4u06FQCF27dsWcOXMwduxYsQzUfyCwcOFCXHPNNXEfAoRCIfTq1Qs9evTAmjVr4m7T0KFC+YgRI2IfUoiWLFmCP//5z3jzzTdx+eWXx9U6d+580DBeXV2NV199Ne5DkKjLL78c77333hEViA8mKByr3NSsMhocq2y322G325GZmRkLyg1DcqJZZasGiwzExjAQG2PV+IqB2DgGYmMYiA0w0rAZiBmIjbIyEO/evRtVVVWIRCJNHtsrht7osb2tZbbXiBkzZuD+++9vMsg0tHbtWpx66qn4+9//jieffDK2e64kSZg8eTIGDx6MmpoazJs3Dx9//DHWrFkT1+t69uyJ448/Hm+//TYAwO12o1OnThg5ciQqKiowb948HHPMMQiFQvjqq68wZswYjBkzBgsW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dO3aFYMHD8bIkSMxYMAAHHXUUaYHKCIiIqKmMBATERERERFRq8RATERERERERK0SAzERERERERG1SgzERERERERE1CoxEBMREREREVGrxEBMRERERERErRIDMREREREREbVKDMRERERERETUKjEQExERERERUavEQExEREREREStEgMxERERERERtUoMxERERERERNQqMRATERERERFRq8RATERERERERK0SAzERERERERG1SgzERERERERE1CoxEBMREREREVGrxEBMRERERERErRIDMREREREREbVKDMRERERERETUKjEQExERERERUatkUxRFFxcmEgqFYLfb4XK5xFJKhcNhAEB6erpYSqlIJAJVVZGRkSGWErr66qsBAK+//rpYSsjv9yMUCqFdu3ZiKaVkWUY4HEZWVpZYSilFUSBJkunrUVUVoVAImZmZsNlsYjlldF1HIBCAx+NBWpp5nxHpuo6ysjLk5+eb/hry+/1IT0+H0+kUSykVCATgcrlMX08wGITT6Wz2ejZu3IjPP/9cXHxIsiwDQLPXY1QwGISu68jMzBRLKaWqKlRVNX17U1UViqKY3rOtWo+maYhEInC73WIppTRNg9frRU5Ojqm9BwAkSYLL5Up6Pe3bt8dVV10lLk7I7/fD7XbD4XCIpZSyqscl23uMOvbYYzF69Gg89NBDYimlWvL4yghZliHLMjwej1hKKavGV5IkoaamBkcddZRYSimrxldlZWXo3Lkz1q1bh2HDhonllImO4zIyMmC328VySlnVew4cOACPx2P6NmdVj5MkCTabzfTeEw6Hoet60u/ftkAg0OxArCgKbDab6RubqqoAYMl6dF1P6o173LhxAIBXX31VLCUkyzIURTH9jUHTNKiqavpGres6FEU5YtaD+r+Rw+Ew9Y0B9QHS7Xabvm3Lsgy73Z704DdZVq1HURSkpaU1ez0zZszAvHnz8Kc//UksEVEz1dXVoaysDOvXrxdLCVnVS1tq7zFq0KBBuPLKKzFx4kSxlFIteXxlhKZp0DTNkvVYMb5SVRWSJJn+YalV46sDBw7g6KOPxurVqzFkyBCxnFJHWu8JhUJwOBym/42s6nFW9h4YWI8tFAo1OxDLsgybzWZ641EUBQAsWY+u60ltbNdeey0AYMGCBWIpoXA4jEgkguzsbLGUUlbOnsiybPp6dF1HJBKx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i4sPqra2Vo9EIuLilLOqxyXbe4zq1auXPnnyZHFxyrXk8ZURkiTpPp9PXJxyVo2vAoGAvmfPHnFxylk1viopKdEB6Bs2bBBLKaVpml5bW6vLsiyWUs6q3rN//35LtjmrelwgELCk9wSDQT0QCIiLD4m7TBMR1du6dSsA4LzzzhNLMZdddhnuvffe2Ozxxo0bMXXqVHTq1An3338/pk+fjjvuuAMOhwNTp07Ft99+CwBYsWIF3nnnHdxyyy2YPn067r33Xqxbtw7PP/987L4lSQIAjBs3DtOnT8f06dMxbty4WD1q1qxZKC4uxk033YTp06fjkUcewS233IJVq1bhX//6V+x677//Ph5//HGcdtppeOCBB2K/24EDBzBp0qRGJwjr27cvVqxYEbfs888/h6IoccsOpkuXLrHfPXoRPfXUU1iyZAlGjRqFRx55BNOnT8f111+PJUuW4IknnhCvji1btuCOO+7A9OnTcfvtt6O4uDju9zfzcSb7u6aCx+PBJZdcgm+//RY//fRTbLkkSfjf//6H008/Hfn5+XG3Qf22OGvWLAwYMADTpk2L/a4ffPCBab8rERHR4Y6BmIioXk1NDQA0GTYSef311xEIBDB58mT84Q9/QJ8+fXDBBRfggQceQE1NDV566SUAQIcOHXDPPfdg/Pjx6NOnDwYOHIi0tDRUVlbG7mv37t0AgBNOOAF9+vRBnz590Llz51g9asSIEXjggQdwwQUXoE+fPjj++OMxfvx4dOzYEdu3b49db86cOcjKysJf/vIXdOrUCW63GwMHDsS5554bO1lYQ2effTa+/fZb7N27N7Zs0aJFOO200+KudzButzv2u0cvDZWXl+Oll17CgAEDcO655yI3NxdutxvnnnsuBgwYgEWLFjXa1X3ixImxx3rZZZfh6quvjvv9zXqcRn7XVLn66quhaRrefvvt2LKNGzfip59+ih26I3r99dcRCoUwefJknHzyyejTpw/Gjx+PYcOGmfq7EhERHc4YiImIfoU1a9agU6dOjYLfySefjMLCQnzxxRcAgAsuuABTpkzB3r17MW/ePMyYMQPhcBh/+tOfYrfZt28fAKBXr16xZU2ZMmUKLrzwQuzYsQNr167FBx98gAULFjQ6Bujbb7+Fpml48sknMWPGjNjlq6++AuoDVkMnnHACMjMz8b///Q+oPx51+fLluOqq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5syZg+effx7fffcdbrvtNgwePBion6E86qij0Ldv37jbGv1e065du2LOnDno2bMntm3bFjtGuKljjwHEAm9D33zzDXRdx1NPPYWZM2fGLtEwvXHjxrjrN9S3b19cdNFFB738Gpqm4ZRTTsGECRNiyzweD+6++24MGTIEmqbFXT+Rbdu2Yfr06VixYgVuvfVW/OlPfxKvQkRERC0YAzERUQt32WWX4Z577kHnzp2xatUqTJ06FQ888ABmzZoVd4Kro446Ku52AJCfny8uaraPP/4Yjz32GB599FE899xzeOWVV/D++++LVwMSfK9pOBxGQUEBHA5H3OXoo4/GbbfdhkGDBok3iVm/fj2efvrpg15+DY/HgyeffBKXX3553PKxY8dizpw5jcJ9U9avX49HH30UH330EW655Rbcd999zbodERERtRwMxERELVx05nLOnDmYNGkSbrnlFgwYMAAvvvgiXnnlFQCAy+VCdXW1eFOEw2FxUZPErxvavHkz7r//fnz66ado3749Bg0ahIsvvhhjxoyJu96hHH300Y1OhhW9HGyWd+vWrZg/f/5BL7+ljz/+GJMnT8bWrVsxYcIE/OMf/2AYJiIiOgwxEBMRtXBLlizB66+/jq5du+Kiiy7Cgw8+iMcffxxZWVlYtWoVAKBfv34oKipq9JVIib7iyOfzxf28YsWKuJ//97//4auvvsLEiRPx1FNP4e6778a4ceOaHbABoFevXvjyyy+bDNtPP/10o+UNmX0M8a+xfv163H///SgqKsI//vEP3H333QzDREREhykGYiKiFu6///0v7rnnHixZsgRFRUUoKirC+vXroaoqjj/+eADAVVddBY/Hg8ceewzbt29HUVERlixZgnfffVe8O3Tt2hWbNm3C+vXrY/f19ttvx13H4XAA9cfaRtf58ccf47XXXou73sHcfPPNqK6uxty5c2O/0/r16zFt2jRMnjwZwWBQvEmM2ccQG1VXV4fJkydj+/btOPXUU9G7d2+sX78+7kJERESHDwZiIqIW7rLLLkNhYSFmzZqF2bNnY/bs2Zg1axaGDx+Ov/71rwCA3//+97j55puxefPm2PX++c9/orCwULw7/P3vf4fP58OUKVMwe/ZsvPzyyygoKIi7zumnn45Bgwbh8ccfx+zZszFv3jy8+uqr6Ny5M3Jzc7F79+646zfl6quvxrXXXouVK1fG/e6//PILbr755kYnADscbNy4EZ988gnS0tKwd+9eTJkypdGFiIiIDh8MxERELdyf//xnTJo0Ceeffz5sNhtsNhvOP/98TJ8+PXaWaQC4//77MWHCBLRv3x42mw0XXnhhk8f8/u1vf8M//vEP9O3bFzabDSeccAIeeeQR3HrrrTj55JOB+oA9adIknHPOObDZbEhLS8M555yDGTNm4K677sLvfve72P1deumluPTSSxus4f8rKCiIXT/6O/Xv3x8PPvgg7r//fvHqKXXyySfj1ltvFRf/ajabDbfeeituvPFG9O3bt8kLERERHT5suq7r4sJEAoEA7HY73G63WEqpUCgEJDhraSpJkgRVVZGZmSmWEho9ejQAYNGiRWIpIa/XC7/f3+RMTSpFIhFIkoScnByxlFKyLCMYDKJNmzZiKaUURUEgEEBOTg5sNptYThlN0+Dz+ZCVlQW73S6WU0bXdRQVFaFDhw6mv4a8Xi/cbjdcLpdYSimfzweXyxX7Llyz+P1+OJ3OZq9n2rRpePbZZ1FeXi6WWp3ly5fjnHPOwbJlywx/BRO1Ti+99BKee+45bNmyRSwlVFdXB4/HA6fTKZZSyqoel2zvMaq8vBwulwu5ubliKaVa8vjKiHA4DFmWkZWVJZZSyqrxVTAYREVFBbp16yaWUsqq8VVpaSkKCwuxYcMGDB8+XCynjK7r8Hq9yMzMjB3uYxarek9xcTGys7NN3+as6nHBYBA2m8303hMKhaDretLn9eAMMREREREREbVKDMRERERERETUKjEQExEdwbp06YJbbrkFXbp0EUtERERErR4DMRHREezYY4/FM888g2OPPVYsEREREbV6DMRERERERETUKjEQExERERERUavEQExEREREREStEgMxERERERERtUppmqahuRdd16HreqPlqb605PVEicsPdgEAm83WaHmqL7quJ/27GbkcaevR6v9GyW4LRi42m82S9Vj1eFrqeqLbDhH9euLr62AXJPlaNXo5EteT7HNt5GJk3GPkYuV6rHrerFrPkThetGJbONLWY7PZLPkbWfV4rOwJRtZjCwaDzR45yrKMtLQ02O12sZRSiqIAABwOh1hKKVVVoWkanE6nWEpo7NixAID58+eLpYQikQhkWUZmZqZYSilVVaGqKlwul1hKKU3TIMsy0tPTxVJK6bqOSCRi2XpcLlesAZnF6/UiMzPT9NdQJBKB3W43fT1W9YRk1zNjxgy88MILWLx4sVgiombasGED3njjDWzYsEEsJRQOh+F0OpGWZu4OaEdajwsGg7Db7aa/37Xk8ZURVq7HivGVoigIBoPIyckRSyll1fiqvLwcRx99NFavXo2TTjpJLKdUOBy2ZBxnVe/x+/1wuVymb3NW9Tireo/R9SQViBVFgc1mO2KeNFVVoet6UusxGogVRYHH4xFLKaVpGhRFMf3FY/V6nE6nqQ1O13XIsmzJegKBADIyMkx/DUUiETgcDtMHpVY10mTXM3v2bLz55ps48cQTxdJB6fWfzptNq/9U1uy/Dyx8TMmuJxgMoq6uDkcddZRYOqhk12OUVetRVbXZ2/WvYfTx7N27F8uWLRMXJ2RV77FqPcn2HqNCoRDS0tJMDygteXxlhFWB2Kpxj6IokCQJWVlZYimlrBpfWRWIo+M4K3qCVb0nEAjA6XSavs1Z1eOs6j1G12PTNK3ZgdiqTzAlSQIAuN1usZRS4XAYqqomFVSvuuoqAMC///1vsZSQz+dDIBBAx44dxVJKybIMSZKQnZ0tllJKlmWEQiHTP8GMflKanZ1tasPWNA1+v9/0mVtd17F//360b9/e9NeQz+eD2+02fZBg1SeYyb4xrFixAt9//724+JBkWYbNZku6kSYrGAxC13XT9xpRFAWapjX7eTNKURSoqprUdr1x40Z8+OGHmDZtmlhKSFVVyLJs+nuDpmmIRCKmr0dVVXi9XrRp08b0wZUkSXC5XEmvx+Px4MYbbxQXJ+T1epGRkWF677GqxyXbe4yqqKiA0+lE27ZtxVJKteTxlRFW7YFn1fgqFAqhsrISXbp0EUspZdX4qrS0FJ06dcL69esxfPhwsZwyuq7D5/PB4/GY/v5tVe8pLS1FVlaW6ducVT0uFArBZrOZ3nskSYKu68jIyBBLB2XT9eYfbBcIBGC3201/MKFQCACSfjDJkiQJqqom1UhHjx4NAFi0aJFYSsjr9cLv96OwsFAspVQkEoEkSaYHVVmWEQwG0aZNG7GUUoqiIBAIICcnx9SGrWkafD4fsrKyTA/ERUVF6NChg+mvIa/XC7fbbXqD8/l8cLlcSQUhI/x+P5xOp+nrCQaDsNlspveeqqoqaJqGdu3aiaWUCofDkGXZ9NmGcDiMSCSS1Bv3Sy+9hAceeADl5eViKSGrepxVvUeWZZSUlKBTp06mDuJ0XY8drmHmegCgrq4OHo/H9MGiVT3Oqt5TXl4Ol8uF3NxcsZRSLXl8ZYRVPc6q3hMMBlFRUYFu3bqJpZSyqseVlpaisLAQGzZsMD0QW9XjrOo9xcXFyM7ONn2bs6rHWTW+CoVC0HU96Q/jkvuomIiIiIiIiOgIwUBMRERERERErRIDMREREREREbVKDMRERERERETUKjEQExERERERUavEQExEREREREStEgMxERERERERtUoMxERERERERNQqMRATERERERFRq8RATERERERERK0SAzERERERERG1SgzERERERERE1CoxEBMREREREVGrxEBMRESWkSQJW7Zswd69e6EoCrZs2YKvv/5avBoRERGRJRiIiYjIMn6/H/PmzcP777+PQCCAqVOn4s033xSvRkRERGQJBmIiIrJMeno69uzZg2+++QbhcBjvv/8+dF0Xr0ZERERkCQZiIiKyTHZ2NoYPHx772eFwYNiwYXHXISIiIrIKAzEREVlq+PDhSEv7/28/nTp1wpAhQ8SrEBEREVmCgZiIiCw1ZMgQ5ObmAgCGDRuGzp07i1chIiIisgQDMRERWapLly7o1asXAODEE08Uy0RERESWYSAmIiLLHXvssUD9DDERERHRb8WmaVqzT+8ZDAZht9uRnp4ullJKkiQAgNvtFkspFQ6HoaoqPB6PWEroqquuAgD8+9//FksJ+Xw++P1+HHXUUWIppWRZhiRJyM7OFksppSgKgsEgcnJyxFJKqaqKQCCA7Oxs2Gw2sZwymqbB7/cjMzMTdrtdLKeMruvYv38/2rdvb/pryOfzwe12w+l0iqWU8vv9cLlccLlcYqlJ3377Lfbv3y8uPiRJkmC3201/POFwGDabrdmPxyifzwdd101/DcmyDFVVTe+lsixDURRkZGSIpYQWLVqEN954A//5z3+a3YMVRUEkEmn29Y3SNA2SJCEjI8PU3qOqKqqrq5Gfnx87ptoMuq4jFArB7Xabuh7UjxPS09MN9dLzzz9fXJSQVT0uEAjA6XSa3hMOHDgAl8uFtm3biqWUasnjKyMikQhkWUZmZqZYSimrxlehUAiVlZXo0qWLWEopq8ZXpaWl6NSpE9avXx93MsVU03UdPp/P9HEcLOw9JSUlyM7ONn2bs6rHhUIh2Gw203uPJEnQ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gbjvvvuwbNkynH322Vi+fDnOOeec2M+oD+ezZs3CgQMHkJeXBwDo2bMnnnvuOUyYMAGzZ88W1nZwL7zwAhYuXIjMzEzouo5gMIicnBw89NBDGD58OABg4sSJmDNnDsS2Ky6fOHEili5diosvvhg7duyAz+fDrl270KdPH9xyyy1YtGgRfD4fKisrUV1djVtvvRW33npr3H02tHnz5kPuxjx27FhxUYzR51m8XVZWFmw2G3JycvD222/H/T2aqznP87BhwwAAGzdujLutuDzVz7PIZrMltS2tWLECs2fPhsPhgKqqkGUZkUgEf/vb33D11VcDTfwtos9pnz598PTTT8c9p4nWLy632Wy4/vrrUVRUBADo3LkzXnnlFZSUlGDevHn49ttvY4PN6upqjBw5EjfffDOOPvrouPs1Kvo3UFVVLCVkVY/z+/1wOp3N7nFGlZeXw+VyITc3VyylVEseXxkRDochyzKysrLEUkpZNb4KBoOoqKhAt27dxFJKWTW+Ki0tRWFhITZs2BDrz2bQdR1erxeZmZmmBzurek9xcTGys7NN3+as6nHBYBA2m8303hMKhaDrelIfXoO7TBPR4eyrr77CxIkTkZeXh0cffRTTp0/HoEGD8O6774pXjVNZWYmJEyeiqKgIEyZMwNy5c3H99dfjs88+E6/aLJWVlZg6dSrat2+PadOmYe7cubjtttvwzTffYN68eeLVm2Xv3r3YuHEjbr31VsydOxdXX301PvroI9x3330YNGgQpk+fjkcffRQulwtPPPGEePM4a9euxWOPPXbQy8EYfZ7F282dOxdnnXUWVq9eLV61WVr68/xrzZkzB/v27cPEiRMxd+5cTJo0CbquY/LkyfD5fMBBntND/S0O5f3338f111+PuXPnYvz48UD9hw/z58/HWWedhVmzZmHu3Lm44oorMH/+fDz77LPiXRARER2WGIiJ6LD12muvoba2FjNmzMDIkW39zOYAADkCSURBVCPRv39/3HPPPejZs6d41TirVq3CF198gTvuuAOXX345+vfvj8svvxwTJ04Ur9oslZWVKC0tRZcuXdC2bVv06tULl19+Oe688070799fvHqzSJKEe++9N/a4brnlFgCAx+PBPffcg/79+2PkyJE47bTTsGvXLvHmcc466yw89NBDB70cjNHnOdHtLrjgAvGqzdLSn+ctW7Zg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NsRE9Lm++93v4vnnn0dRURGqq6uxatUqvPbaazh69Cja29th27b7LUREQmiahpaWFhw6dAjr16/HsmXL8Nvf/hYzZszACy+8gFtvvdX9FiIioiviPcQS7nHhPcTeZOI9LtfbPcSXs2PHDmzduhXvv/8+Ro8ejYqKCowdOxbDhg1DMBhEKBQS/vmIKHtYlgVd16FpGlRVxcmTJ3H48GE0NjbizJkzuOeee/DAAw+goqLC/darJuv+Ot5D7A3vIfYmE+sr3kPsjawcd63fQ8yGWELCZkPsTSYm7ExoiNH9f/anP/0J9fX1aGhogKqquOWWWxAOh5GXl4eioiLea0xEV83v98PuXss0Ho8jGo2itbUVw4cPx7hx4zB+/Hh87Wtfc78tbWQVi2yIvWFD7E0m1ldsiL2RlePYEHuQaQmbDbE3mZiwM6UhvqSrqwuapuHQoUNobGxENBrtecViMfdwzyxJa6BfuvRb9DyGYQCA8CVJbIlrgcqYx3Ec2LYtZR7LsoQXVo7jQNM05ObmCs1x6M6ngUDgupsnGAyiuLgYxcXFGDx4MAYPHoxx48bhpptukpLjZBWLbIi9YUPsTSbWV2yIvZGV49gQe5BpCZsNsTeZmLAzsSEOhULCE2mmJexoNArbtjFkyBB3KK1kFYuapkHXdRQUFLhDaSUrx8nKPYZhoKWlBeXl5UKLOJnFYmdnJ/Ly8oT/2CMrx8nKPWyIvZGV42TlHjbE3sjMcbJyDxtib7w2xGJPgxARERERERFdo9gQExERERERUVZiQ0xERERERERZiQ0xERERERERZSU2xERERERERJSV2BATERERERFRVmJDTERERERERFmJDTERERERERFlJTbERERERERElJXYEBMREREREVFWYkNMREREREREWYkNMREREREREWUlNsRERERERESUldgQExERERERUVZiQ0xERERERERZyWdZluPeeCWqqsLv9yM3N9cdSqtUKgUACIfD7lBaaZoG27YxYMAAdyitEokEFEVBSUmJO5RWhmFA0zTk5+e7Q2llmiZUVUVBQYE7lFaWZUFRFOHzOI6DRCKBSCQCv1/sb0TNzc0YPHiw8GMokUggNzcXwWDQHUqrZDKJYDCIUCjkDqWVoijIyckRPo+qqvD5fMJzz8WLF2HbNgYNGuQOpZWu6zBNE3l5ee5QWum6DsMwEIlE3KG0kpXjZOUe0zTR1taG0tJSBAIBdziturq6kJeXJ2WeAQMGICcnxx1KK1k5Tlbu6ejoQDAYxMCBA92htMq0+kpWjpOVe1RVxYULF1BeXu4OpZWsHCezvpKV42Tlnra2NkQiEeH7nKwcJ6u+SqVScByn37nHp6pqnxtiwzDg8/mEf9GZpgkAUuZxHEf4Ti2rWLQsC5ZlCd+pbduGaZoZM4/jODAMA8FgED6fzx1OK1nFoq7rCAQCwr8YMm0eWTnOa8LuL1k5IdPmkZV7bNtGMpmUUizquo6cnJyMmkdGTpA1j6IoCAQCwn8szbT6SlZOkDWPYRhIpVLCG1VZOU5mfZVpuSeRSCAUCgn/G8n6PLLqK6+5J7B06dIn3RuvxLZtABC+s2XaPJcSaX//OP3lOA5s2xa+U2fiPJZlwefzCU/YmqZJSdiWZcHv9wv/PLL+32zbljYPJOSESwlb9BeDbdtwHEf457FtW9qxmmnz6LoupViUmRMyaR5Zucc0Tfh8PuH7nKwcJ3MeGTlOVk6wbRuGYQhvgmR9Hpn1laycIGsewzDg9/uF/41k5TiZOQEe5vE5jtPnM8TJZBKBQED46W5VVQFA+NmTVCoFy7KEn7mNx+NIJBIoKytzh9JK13WkUikUFha6Q2llGAYURRF+aZdpmkgmkygsLBR6oNq2ja6uLuTn5wtNPI7j4MyZMxg6dKjwYygejyMcDgv/Uu3q6kIoFBJ+ViORSCAYDAqfR1EU+Hw+4bknGo3Ctm0MGTLEHUorTdNgGIbwS640TYOu68LPasjKcbJyj2EYaGlpQXl5udAfRxzHQTweRyQSEToPAHR2diIvL0/4D8Cycpys3NPW1oZQKISioiJ3KK0yrb6SleNk5R5FUdDe3o4RI0a4Q2klK8fJrK9k5ThZuae5uRkFBQXC9zlZOU5WfaWqKhzH6fdtFP1rn4mIiIiIiIgyBBtiIiIiIiIiykpsiImIiIiIiCgrsSEmIiIiIiKirMSGmIiIiIiIiLISG2IiIiIiIiLKSmyIiYiIiIiIKCuxISYiIiIiIqKsxIaYiIiIiIiIshIbYiIiIiIiIspKbIiJiIiIiIgoK7EhJiIiIiIioqzEhpiIiIiIiIiyEhtiIiIiIiIiykpsiImIiIiIiCgrsSEmIiIiIiKirMSGmIiIiIiIiLISG2IiIiIiIiLKSmyIiYiIiIiIKCuxISYiIiIiIqKsxIaYiIiIiIiIshIbYiIiIiIiIspK/we6Nmi/0mJKyAAAAABJRU5ErkJggg==" + }, + "image-5.png": { + "image/png": "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X331FV577TV+XcTXuInl5eXZvd6Xexbf+PHjsX//fmRlZWHjxo0YOHBguef0TZ06lQ/utm7disGDB9sts169enjkkUfw7bffIisrC2fPnsXQoUMF8xw5cgQjR45EcnIyBg4ciPHjx6NJkybQ6XSC+cSCgoLESQgKCuK30/jx41G/fn3s2rVLMM+oUaNw4sQJnDlzRpBeGWeW88KFCwgPDy+3vewJDAwUJxHyt/PUBxfb8sylroL9+/fTXbKk2rDtbF2dKvL444/zwWanTp349KysLKxatQqdOnUSPKvPthN+/vnnsXz5cv57bIMqZz7PCQ8PFyeVY7ucgwcPxjfffOMw39X1UKlUKCoqws6dO/mA46GHHuLz7alfv3650SZbw4cPB8pG7VJTUzFlyhTxLGjatClUKhV2796NrVu38jc12DNkyBBs3LgR3377LR555JFyPww++OADoOzGheeffx4jRoyAv7+/YB577K1DYGCg4EdI9+7dsXHjRsE8jz/+OAYOHIilS5eWe95cZGSk4H9bziznvn37nD5jIr7pgpAH4fTp0x754GJbNSK4u3jxIp2SJdWKbWfr6lQVoaGhuHfvHpo3b87fofjmm29Cr9fz86hUKsH32AZVznye4+roS1pamuDdzxVxZjmysrKwdOlSPPnkk3zA0bJlS5tSyps0aRL27dsneE7hm2++yY8oRkREYODAgVi1apXdU7KcxMREJCcno0mTJmjatKk4m/f444/jr7/+wqpVq+wGivn5+ahduzZGjBgBlUqFjRs3VvoMxU6dOiEjI0OcXE5WVpbd0YhJkyZBoVBgzZo1gvSKRtycWc4dO3YgKSlJkGZPVlYW9Hq9oN4R8iB4+ilZ1JTgbteuXXRKltRoKpUK06dPx4oVKzBq1CiMGjUKubm56NmzJ65cuSKevRxnPj958mSsWbPGqVf7zZw5ky9n//79+Pjjj8Wz2OXMcsyaNQu5ublYsmRJhYGJraeffhqTJ0/Gyy+/zJf722+/YfDgwfw8gwcPxvXr1+2ekuVMnToVKSkplY6wRkREoG/fvlAoFHYDxblz52Lfvn38snz99dcYO3YsCgoKyo2scR5//HEEBQWVu26yoKCAL4c7/Wpve0dERGDmzJn4/PPPsXLlSowaNQoFBQUYOHCgeFZeZcs5atQopKamYuPGjYJlAIA1a9YIlvW7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nrBTTjkFzz77LAYNGgQAuPXWW3HNNdfA6/WKq0Z06NAB+/fvF4sT8tBDD9V5j1089u3bhw4dOojFREQxY3JHRLXs27cP7733Hm699VYxBAC488474fF48Pbbb4uhE+Kqq66qlTTeeuutuOqqq6LKarrhhhuwe/duqWfKpk6dih49eojFcdm6dWuDl5OJiI6HyR0R1RIKhXDPPfdE3axf06BBg/DQQw9JvUe2b9++eOihh8Riy1xxxRVQVRXbt28XQwCATp064aGHHqrz/sBEDR06FPfee69YjH379mHPnj31fu411bV9dZURUfPD5I6IaunRo8dxz0JNnTq13jN7jTFo0KB6H26wQuvWrXHzzTdjwYIFYgio8RmIZwRluOqqq/D444+LxZg/fz6uuOKKBj/3sLq2r64yImp+mNwRUbN1zz334D//+Q9WrVolhn5xH3/8MdauXVvrjRlERPFickdEzVaPHj3w5z//GRUVFWLoF1dZWYlbbrkl8lAIEVFjMbkjombt1ltvlXp5ubGuvvpq3H///WIxEVHcmNwRERERpRAmd0REREQphMkdERERUQphckdERESUQpjcEREREaUQJndEREREKYTJHREREVEKYXJHRERElEKY3BERERGlECZ3RERERCmEyR0RERFRCrF5vV5TLDyeQCCA9PR02O3yckPDMFBaWoqTTjpJDCVE13WoqoqMjAwxlBBN02AYBtLS0sRQQkKhEOx2O5xOpxhKSDAYhMvlgsPhEEO19OnTB3PmzInpBebHjh1DXl6e9LagKAoyMzPFUEI0TYOu60hPTxdDCVFVFQDgcrnEUEIURYHD4ZDaFubNm4dt27bh6aefFkPUDL355pv48ssvMX/+fDHUaOy/VTweD9LS0qSPPVaMv6ZpIhAIwO12i6GEJNv46/V64XA4pLfdeMbfePj9fmRmZsJms4kh2EpKSuJO7kKhEFwuV50VNpZpmvB6vcjJyRFDCTEMA7quS++4uq7DNE2pAy+qG63NZpPeCFRVhcPhiOmA0L9/f8ycORMDBw4UQ7VUVlYiOztbeltQVVV6x7WyLQA4ofssVq+99hree+899O/fXwwlzDRNqe0gzIp6NU2DpmnSBx0rthXV9QKQXndhYSFUVcXcuXPFUKOx/1YJBAJwOp3St9eK8RfVXyZlJ85W7jMrxt9gMAi73S697VpxLMdx9pktFArFndx5vV643W6pG2oYBoqKinDKKaeIoYRomoZQKCT9G0koFIJhGNIHB6sal9/vR1paWkydoWfPnnjllVcwePBgMVRLYWEhTj75ZOltwe/3Izs7WwwlRFVVaJom/VuZoigAUG8naywrBocvvvgCb7/9NrKysqQPZg0daBrLMAxomia9P+zatQu7du3C7373OzGUEFVVYbfbpX+2Xq8X6enpUtsCqvdZz549MXr0aDHUaOy/VUpKSpCZmSl97LFi/LXq5Eqyjb/l5eVwOp3S22484288Gjq5YjPDXwnj4PF4pA8Ouq6joKAAp59+uhhKiKZpCAaD0neWoigwDEP6gSYQCMBut0s/0Hi9XmRkZMTUuLp374758+fjwgsvFEO17N+/Hx06dJDeFnw+H3Jzc8VQQkKhEFRVRVZWlhhKSDAYBADpBxqfzweXyyU9sSkoKEDbtm2l1muaJjweD1q0aCGGEmJV/33ttdewcOFCbNiwQQwlxKr+e/jwYbRs2VL68aaiogK5ubl1Dg6Nxf5b5ciRI3C73dLbrhXjb7L1X6vG35KSErhcLultN57xNx4N9V95qT8RERERnXBM7oiIiIhSCJM7IiIiohTC5I6IiIgohTC5IyIiIkohTO6IiIiIUgiTOyIiIqIUwuSOiIiIKIUwuSMiIiJKIUzuiIiIiFIIkzsiIiKiFMLkjoiIiCiFMLkjIiIiSiFM7oiIiIhSCJM7IiIiohTC5I6IiIgohTC5IyIiIkohTO6IiIiIUohNURRTLDyeYDCItLQ02O3yckPDMFBeXo68vDwxlBBd16FpGtLT08VQQjRNg2EYSEtLE0MJCYVCsNvtcDqdYighiqLA6XTC4XCIoVp69eqF/Px8DB48WAzVUlpaipYtW0pvC6FQCBkZGWIoIZqmQdd16W1BVVUAgMvlEkMJURQFDodDelsoLy9Hdna21HpN00QwGERmZqYYSohV/XfhwoVYvHgx/vWvf4mhhFjVfysqKpCZmSn9eBMIBJCRkQGbzSaGGo39t0plZSXS0tKkb68V42+y9V+rxl+fzweHwyG97cYz/sajof5r8/v9cSd3oVAILperzgobyzRN+Hw+ZGdni6GEGIYBXdeld1xd1wFA+s6yql5VVeFwOGI6IJx99tmYM2cOLrjgAjFUi9frRVZWlvS2oKqq9I5rGAYMw5A+8Fq1zzRNg91uj2mfxcPn8yEzM1NqvVbuMyv675IlS7B48WK8//77YighVrUFv9+P9PR06fVadSy3qi0kU/8NBAJwOp3S226y7TMr+q9V+0xRFNhsNumfQzzjbzwaags2wzDiTu4qKyvhdrulfrC6rqOwsBCnnXaaGEqIpmlQFAVZWVliKCGhUAiGYUjP8IPBIOx2u/TG5fP5kJ6eHtOBsUePHnj11Vdx4YUXiqFaDh48iFNOOUV6W/D7/cjJyRFDCVFVFaqqwu12i6GEKIoCANK/nfr9frhcLukHxsLCQrRp00ZqvaZporKyErm5uWIoIVb13wULFmDhwoVYv369GEqIVf23uLgYLVq0kH688Xg8yMnJqXNwaCz23yrHjh1DZmam9LZrxfibbP3XqvG3rKwMTqdTetuNZ/yNR0P9126z2RDvAqBWmYzFNM1aZTIWK7Y3TCxPdLGyXrGsviWedbnPkq9e06z6PieWJ7pYUafNgnqLiopQVlYGRVFQWFiIQCBQa53GLtxnVYsV9Vr12VpVL/dZ1WJFvdxnVUtD9co9R0hE1MQtX74cH3zwAfbv34+pU6fi4MGD4ipEREmNyR0RNSs7d+7Ehx9+iIKCAixfvlzq5S0ioqaAyR0RNSuDBg2K/HvAgAHo0qVLVJyIKNkxuSOiZmXQoEGRG7wHDRok/Qk2IqITjUc1ImpWevTogU6dOgFATHM5EhElGyZ3RNSsZGRkoFevXnC5XOjbt68YJiJKejYz/OxvHDweD7KysqTeiKzrOgoKCnD66aeLoYRomoZgMCh9cmRFUWAYhvQZvQOBAOx2u/Q5l7xeLzIyMmKaZ6d79+6YP39+TPPc7d+/Hx06dJDeFnw+n/Q5l0KhEFRVlT7nUjAYBKqThuNZv3595HH747FqEtSjR4+iZcuWUus1TRN+v1/6Z6vrOkKhkPR+Nm/ePKxZswZvv/22GEqIoiiw2+1SP1sAKCkpQXZ2tvTjgs/ng9vtjkyrIIOu6wgGg9Lbgqqq0DQtrraQm5uLAQMGiMVR4um/8Thy5Ajcbrf0sceK8dc0TXg8HrRo0UIMJSTZxt+SkhK4XC7pY0884288KioqkJubW2f/ZXLXSFY1LiZ3qZvcHTx4EH/4wx/Qo0cPMVQnwzCi5jOSpaFZzROh67rUdoDqQcc0Ten3xR09ehRFRUU4++yzxVBCrNpnVs1wb9U+MwzDknpjbQu6ruPrr7/GjTfeiPHjx4vhKLH233gxuUu+8ZfJnQWNi8ldFSZ3qZvcTZ06Fdu2bcPvf/97MUREEn3++ed4+eWXsXr16uO+RjHW/hsvJnfJN/4yubOgcTG5q8LkLjWTu4MHD2LMmDH429/+hosuukgME5EkpaWlGDduHHRdx5IlS8RwLbH038Zgcpd8428qJXfHP79NRAlbunQpunfvftz7f4goMVu2bMHXX3+N++67TwwRNRtM7ogsdvDgQXz00Ue48cYbpb9Qnoj+p7S0FG+++Sb69et33MuxRKmMyR2RxXjWjuiXwbN2RFWY3BFZiGftiH4ZNc/a1XzFHFFzxOSOyELLli1D9+7dcf7554shIpJoy5Yt2LFjB8/aETG5I7LOwYMHsXHjRtx4443Sn34mov/hWTuiaEzuiCzCs3ZEv4zwWbs//elPYoioWbKHZ/2OZ0GN2cJlLjabrVaZjMWq7bWiXivqNOOsN551uc/qXg4cOMCzdkS/gJpn7QYOHFirL56oJUwsT3Sxok6T9cJMsX1mCwaD//sfxUhRFLhcrpheAxMrwzBQUVGBVq1aiaGEGIYBVVWlD7CapsE0TenvkFRVFTabTfpkh/Hss7POOgtz587F4MGDxVAtZWVlaNGiRUz1xsrKfWYYhvQHG1RVBYCotvDCCy+gsLAQ06ZNk/7/IKL/WblyJR555BH885//bNQl2br6rwxerxcul0t6/4/nWB4r0zShKIr0iZytPJZbMf76/X44HA7p22vFPkP1BNzp6el1T2IsZnsnckm2s0DJtMTzGcSzrlX7zIolTCxPdBHrDZ+1++1vfyv9IEFE/1NWVoY333wT55xzTqPP2oWJ5Yku4QFXLG+qi1XbalW9VixWbeuJqJevH2skq15/wtePJf/rx6ZNm4aDBw/yrB2RxVauXIlHH30U+fn5GDhwoBiOidh/ZeHrx5Jv/OXrx4ioTgUFBTxrR/QLCJ+1C99rR0T/w+SOSCK+jYLol/HJJ59g586dfEKWqA5M7ogkaQpn7RYuXIg5c+bUWnbv3i2uSils/fr1kX2+detWbN26VVylTh6PJ9JmmrKysjK89dZbkXvtiCgakzsiSZYtW4Zu3bqd0LN2Dz/8MGbNmoUdO3ZElpUrV2LSpEkoKCgQV6cUtXfvXkyaNAlz5szBlClTUFhYKK5Sp82bN2PixIkYO3Zsk/5CEJ7X7o9//KMYIiImd0RyHDp0CBs2bGgS89oNGzYMs2fPjizTpk3D+vXr8eGHH4qrUoq6++67kZOTgx07dqBHjx4YOXKkuEqd5s2bhwsuuABdu3ZFfn6+GG4SxCdkiag2Pi3bSFY9rcOnZZPzadnwvHbTp0+Xvu/iccopp+DWW2/F1KlTo8oHDhyIIUOGRMpXrFiB7Oxs/PrXv45aDwB2796NTz75BPfcc09k3eLi4qh1unbtGvW7W7duxa5duyI/X3TRRejVq1fk53CdNbndbtx2221RZWEFBQV4//33xeJavyNu28033xxpN1u3bkVRURGys7Px008/AQDatWuH66+/PrI+Yqhj165d6Nu3b1QiEd4+sb7j1fXjjz9Gbf/69evh9XojdcyZMyfqs/N4PFi6dCmuuuoqdOjQAajjsxH3RX11iPtEVFBQgN69e+OFF17Avn37sHDhQuzcuVN6P0zUqlWr8Le//S2hJ2Rr4tOyfFo2jE/LElHEoUOHsGnTpiZx1q4uBQUF8Hq9UQPh5MmT6z0zs3nzZowdOzby8+TJkzFt2rTIZd5NmzZhwoQJkcu8W7duxRNPPFHrMnDNy3rhy33hdWbNmoWHH344Ehft3r0bY8eOxaZNm+r9nRUrVmDy5MlRf3fGjBmR7XrnnXfw17/+FS+88EJkncceewwrVqyIu44pU6ZEfidcPnbsWEyePDlSFktd4v85Pz8/qo6xY8di8+bNkZ+PHj0adYm0oKAA06dPx8qVKyN/Z8KECVi/fn29dSxfvrxWWV3eeecdpKen4+qrr8aoUaNQXFxcZ4J9IoXP2p177rlSEjuilGU2QkVFhalpmlicEE3TzH379onFCVNV1aysrBSLExYMBk2/3y8WJ8zv95vBYFAsTlhlZaWpqqpYXKdu3bqZn3zyiVhcp3379lnSFioqKsTihCmKYnq9XrE4Yc8++6x53333WbLf4tW+fXtz2LBh5pw5cyLLuHHjzBYtWkStN2DAAPOmm26KKgubNWuWWfPQIK67Z88eE4C5du1a0zRNc9iwYeaFF14YiX/33Xdm3759zbvvvjtSNmXKFPOyyy6L/PzQQw+Z7du3j/wsWrt2rQnA3LNnT6Ss5u8cPHjQ7Ny5s/nss89G4t99953ZpUsXc8aMGZH1AUStc/PNN5udO3c2KyoqYq6jffv2Zvfu3c2DBw9G1hsyZIjZtm1bc8CAAaYZx/aI/+ebbropUodZdRXFnDVrVuRn8bOeNGmS2aVLF/O7776LrDNixAizf//+kT5Ts47du3ebl112Wa1669K/f3/ztttui/w8ZMgQs3///lHrnGgrV640zz77bPPzzz8XQ40WCATMQCAgFiesuLjYkrHHivHXMAyzvLxcLE5Yso2/x44ds2TsiWf8jUd5eblpGIZYbJqmafLMHVECCgoK8NFHHzWps3bFxcXYvn17ZAkEAlBVNeqMFQD8/PPPmDt3bmT54osvouI11Vx32bJl6NKlCzp06ACPx4N169bh3nvvjazbq1cv/OY3v8Ebb7wRKTt27JjUWy62bt2KvXv3Ii8vL7JdW7ZsQV5eHv71r39F1nO73ZgwYULk58ceewx79+7FTz/9FHMdqL6s/e677wLV+/zw4cM4++yzI/FY6/L7/VGf+c8//xyJhW3ZsiXqs65pyZIluPjii6Murz7++OPYtm1b5NJzTZMmTcJNN90kFtfy/fffY9u2bbjzzjsjZbfffju2bduG77//PmrdE4X32hHFjskdUQKWLVuGHj16nNAnZEXDhg2rNRXKJZdcgr/+9a9R65WWlkYlgRMnTqw3wau57oEDB5CXlwebzYajR48CAE466aSo9du0aYOKiorIz4cPH0anTp2i1knEsWPH4Ha7o7Z/+/btOPfcc3HRRRdF1hPvIQonRUePHo25DgC488478frrrwMA3n33XQwcOBCtW7eOxGOtS1XVqHhpaWkkFrZ///5I/Ntvv42KlZaWRv1dVH/WqP4/1bRhwwbs378fY8aMiSqvS/gS/X//+99IYhl+wra+y/e/ND4hSxQ7JndEjVRQUNBknpA9nquvvrrWQxH9+/ePSgD37NmDBQsWRK0TJq574MABLF26NHLjscfjiVrf4/HA7XZHfv7000/Rr1+/qHUSkZubC5fLhWnTptVKZGueqfP7/VG/F77/LTc3N+Y6AGDo0KE4cOAAvv/+e7z++utRZ7gQx/a0aNEiKta/f/+oegDglltuicT/8Y9/RMWys7Ph9XqjysKffc2bwAsLC/H888/X+v26eDwerFixAiNGjIhKPA8cOIC+fftixYoVtfbvLy181q5Pnz5N6osUUVPF5I6okZYvX37C57WL1ddff43zzjtPLI6S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YwIw165da5rVdfz973+PxOsi1lFfGSWHXbt2mR07dhSLE1ZcXGzJ2GPF+GsYhlleXi4WJyzZxt9jx441euxpiFXjb3l5uWkYhlhsmqZpyvuaQtQEjBgxAn/+858xdOhQtGzZMip22mmn4eDBg1FllJwmTJiAM888Ew8++GDkZvhLLrkEX3/9ddRTq8uXL0fHjh3RtWvXGr9dv0suuQQffPBBVB27du3CsmXLOFFyitq7dy9fRUgph8kdNRvnnHMOduzYgfLycjFESaZdu3Z47LHHsGvXLsyYMQNerxf3338/MjIyMHnyZCxbtgzLli3D4sWL8de//jXmefDqquPxxx/He++9FzVR8rZt2yLxZcuWRcqYACafzz77DOeee65YTJTUmNxRs3HxxRfjp59+ijxwQcmja9euGDVqVFTZLbfcgt/97nf4+eef4fP50KdPH7z44ovwer1YsWIFVqxYgb/85S8YN25c5HdGjRoVdRYvOzsbo0aNijyYUVcdbrcbS5cujSSIo0aNioqvWLECV111FebNm4fi4uJI3dT0lZeXY/PmzRgxYoQYIkpqfKCikay6obMpPFARj/3796NDhw7S24LP55N+U2soFMLll1+OwYMH4+9//ztcLpe4ClGjhB/c2LNnT8yXgOnEW716NcaNG4evvvoKeXl5YjghfKAi+cbfVHqggmfuqFkZNWoU1q1bh927d4shImpGSkpK8MYbb+Caa66B2+0Ww0RJjckdNSsjR46EaZqYM2dO5M0VRIkKX96VfYaCrLN582b897//xR133CGGiJIekztqVnJycvDoo49i9erV+OKLL6DrurgKUdzatWuHZcuWxfzgBp1YP/74I5YtW4YbbrgBPXr0EMNESc8WCoXivucuEAggPT1d6oSPhmGgpKQEbdq0EUMJMQwDoVAIGRkZYighqqrCNM1GvUWhIaFQCDabTfr9YMFgEGlpaVL3GQAcPXoUrVu3llqvYRhQFEX6/RSapkHXdaSnp+P222/HsWPHMHnyZJxzzjniqkSUogoKCjB58mT8+9//xuuvvx4Zc2QfcysqKpCeni597LFi/AUAv98v/fJ0so2/lZWVcDqd0sceq8bfhvaZzefzxZ3cqaoKp9NZ5018jWWaJvx+f6PeStAQ0zSh67r0GxnDZ3xk3tQKC+vVNA0Oh0PqPgMAn88Ht9sttV7T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" + }, + "image.png": { + "image/png": "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" + }, + "Снимок экрана 2025-10-05 185114.png": { + "image/png": "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yJEjy3wscc0112DNmjXw+XyR4JKamlom3JyrdNz27dsxYMCAMr3uu+8+fPnllygsLIyMT0lJQcuWLbF//37s3LkTu3fvjgSoUnl5ecjLy4sEiXN7PvXUUzhx4gTy8/Mj4994440y4yZPnlzmPs835sknnywz5tzjW5544glMmjQJ2dnZ6N27d2TMgAEDsH37diQlJUX6pKenY9myZZExVan0I6GK2L9/P06fPo3evXujbdu25Z5n8f44nU7Y7XZl/75U97fZbDBNM+H/fkt/VM+f/aP/2O32GrF/lQQXVb+UqwqDy8UeuMr+sH/0HwAwTTPh+/err75K2LEtpVq0aIHXX3+93EcTQgi8/vrraN26tXyTiNJ3DqX69OmDDRs2lOsjhMALL7xQ5radO3dGOBzG5s2bsXfvXjRv3hzdunUrMwYAhg8fjkOHDpXrd/z4cYwePToybtiwYWXGzZw5E16vt0wvecysWbMiY3JycvD3v/8dN9xwAw4ePAghRJmDhM/13nvv4Z133sH999+PgwcPVusxLikpKUhNTUVeXh7OnDkT2V76EZIcbM49tqVv377lnmOJ+FH9xsDpdCrtX/rCluh/v6U/qudfFf1VvrFU3b+qgsvF5s9jXKjWi3bdlspq1aoVAODkyZNltq9duxbXXnstnnzyyciKy5EjR8ocPHvo0CEcOXIErVu3RteuXdGiRQucPn0ax44dO6cTsHDhQrRv3x5z584tsz09PR0ulwvLli3D119/jZYtW5b7uKp169Y4cuRIuY+ESq9Zsnr16jLb43H27Fnk5eVFgkCp3NzcMr9T6cqSaZq44447znvcSWVU9hiXK664Am3atMHRo0fLnDFVerZR69atceWVV0a2l6629OrVi8e2EFUjBheq9c69Sm6iVlvuu+8+3HXXXeXODlq+fDmSkpJw6623RsLEv//9byxbtixyptGyZcuwdetW/OY3v0HXrl1x9913o2vXrpgzZw7ee+89AMC6deuwdOlSXHPNNbjjjjvOueefj5HJzMzE0aNH4XQ6yx0bk5qaittuuw1CCMybNy9yIO5rr72GRYsW4Z577sE999xT5jbxaNy4MVJSUrBz587IfW3YsAFLliyJHIuDkou9bdiwAf369cPAgQPP6VB9evbsiaSkJCxbtgwHDx7E999/jzfeeAP16tXDnXfeGRlXutridrtx7bXXlulBRFWLwYVqNRWrLaX+9Kc/4fe//z2ef/552Gw2XHnllfD7/Zg7d26Zs2v69OmDn376Cd26dYPNZsPf//53zJs3DyNHjgRKgshf//pXXH/99RgyZAhsNhtuvvlm9OzZE3PmzDnvR06ZmZno3LkzevTocd6PiW666SbMmzcPQgj06NEjclzKE088galTp8rD49K9e/fIqdeDBg2CzWbDgw8+iD59+mDEiBE4cuQI3nnnHSxbtgwNGzbE7bffXuFjS1Tp378/pk2bhpMnT6Jt27Zo3bo1fvjhB0yfPh3XXHNNZFzpmUS9evWKrLYRUfWwCSGEvDEemqZBCPHz51D2xOei/Px8GIYBr9eLpKQkuRw3TdNgmiZcJZ83Jxr7R1dQUABd1+H1euEqOeYlHp999hlWrFiBnj17YujQoQkNLrF44YUX8Nlnn2HatGmR06HJWnJzczF79mwEg0E88cQTaNmypbLnfygUgmEYyvrruo5wOKysv9/vRzAYhNfrhdvtlstxUz3/quiv6zpcJcdzJJrq/oFAAIFAAMnJyfB4PHI5brHOP/HJgqiGULnaQnUHr9tCVLMwuFCttW3btoQf20J1S+mxLfXq1UOfPn3kMhFVAwYXqpVKV1sS9Z1ElfXHP/4R27Zt48dEFsXVFqKah8GFaqXS1ZZ+/fpxtYUqhastRDUTgwvVOjVltYWsjastRDUTgwvVOlxtoXhxtYWo5mJwoVqFqy2UCFxtIaq5GFyoVuFqC8Xr2LFjXG0hqsEYXKjW4GoLJQJXW4hqNgYXqjW42kLx4moLUc3H4EK1AldbKBH279+PvLw8rrYQ1WAMLlQrcLWF4sXVFiJrYHAhy+NqCyUCV1uIrIHBhSyPqy0UL662EFkHgwtZGldbKBG42kJkHQwuZGlcbaF4cbWFyFoYXMiyuNpCicDVFiJrsZ06dUrIG+MhxM/tbDabXEoIwzAghIDD4VByH6rnz/7RVWT/fv7555g3bx7atWuHe++9F06nUx5CFFU4HMbbb7+NwsJCTJo0CS1btpSHlCGEgBACNpvtos/PyrB6f9M0YZom7HY77PbEvy9WPX/2j66m7F9bQUFBQoNLOByGKHnhUfGLBYNBmKYJj8cDh8Mhl+Omev7sH11xcTEMw4Db7Y4aRAzDwJw5c/Dqq6+iuLhYLlMl6boO0zSRlJSkZP/WRC1btsTjjz+O++67Ty6VYxgGDMOA0+lU8vhYvb+madB1HR6PJ+q/38pSPX/2jy4UCiEUCsHtdiMpKUkux610/g6HI+rru02IkrfQCaJpGoQQcLlcSh64/Px8GIYBr9er5IHTNA2macLlckV94CqL/aMrKCiAruvwer1wuVxyOW6hUAiGYSibv9X7z58/H3v27MGECROQmZkpl+NWVFQETdOQnJwMt9stl+Om+vGxen9d1xEOh5X19/v9CAaD8Hq9Svav6vlXRX9d1+FyuZQEO9X9A4EAAoEAkpOT4fF45HLcYp1/4pMFERERkSIMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGbbCwkIhb4yHED+3s9lscikhDMOAEAIOh0PJfaief23oL4SAzWZTch9VsX9Vzt/q/RcsWIB9+/Zh7Nix6Nixo1yOW+n+tdvtsNsT/75J9ePD/tGZpgnTNLl/L8Dq/WvK/rVpmpbQ4BIOhyFKXnhU/GLBYBCmacLj8cDhcMjluKmeP/tHV1xcDMMw4Ha74XQ65XLcVM+/Kvqbpgmn06mk/yuvvIK9e/fi0UcfRUZGhlyOm6Zp0HUdHo9Hyf41DAOGYSh7fNg/utL963a7kZSUJJfjpnr+7B9dKBRCKBSq9v1rE6LkLXqCaJoGIQRcLlfUO66s/Px8GIYBr9er5IHTNA2macLlcikJRuwfXUFBAXRdh9frhcvlkstxC4VCMAxD2fyt3n/+/PnYs2cPJkyYgMzMTLkct6KiImiahuTkZLjdbrkcN9WPj9X767qOcDisrL/f70cwGITX61Wyf1XPvyr667oOl8ulJLir7h8IBBAIBJCcnAyPxyOX4xbr/BOfLIiIiIgUYXAhIpw6dQpvvvkm1q5di927d2PBggV49913cfr0aXkoEVG1YnAhIgQCAaxZswZr1qzB7t278cYbb+Cbb75RslxORBQPBhciQlpaGrp06YJLLrkEANCiRQtkZGQgJSVFHkpEVK0YXIgIHo8H6enpSEtLA0qCS4sWLeRhRETVjsGFiICSVZfS4JKWlsbgQkQ1EoMLEQHnrLI0adIEmZmZDC5EVCMxuBARAKBp06Zo3rw5GjZsiAYNGshlIqIagRegk6i+wBr7R1eTLkB3/Phx/POf/8Tx48fl0gWVXjnX6XRGvWR1Zanuv3nzZnz77bfo168fOnToIJfjpmkawuGwsisjG4YB0zThqOCVi6+55hr06dNH3lxORZ4/laG6v+oLrPECdNHFeoG1ylLdv6ZcgI7BRaL6hZn9o6tJwWX79u1YuHAhvv32W7lEtYjP58MDDzyAqVOnyqVyKvL8qQzV/VW/MDO4RBfrC3Nlqe7P4FJJDC7RWb1/TQwu/fr1w8iRI+Uy1QI//vgjsrKy0KhRIwaXBGBwiS7WF+bKUt2/pgSXxCcLIiIiIkUYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDJshYWFCb3kf+k3CKj4AjiUfImaEAIOh0PJfaief23oL4SAzWZTch9VsX9jnf/nn3+OZcuWYcCAAbzkfy31448/4uWXX0b9+vXx3HPPyeVyKvL8qQyr9zdNE6Zpwm63K/nKF9XzZ//oasr+tWmaltDgUvrttY4KfjtrrILBIEzThMfjUfJdEqrnz/7RFRcXwzAMZd8eXJH579ixA0uWLEH//v0ZXGqp0u8qSk5OxvPPPy+XyzEMA4ZhwOl0XvT5UxlW769pGnRdh9vtVvJdcqrnz/7RhUIhhEKhat+//JJFieovEWT/6Pgli1SV+CWLicUvWYwu1i8RrCzV/fkli0REREQVxOBCRERElsHgQkRERJbB4EJUy/h8PkyYMAF9+vTBhg0b5HJCbdiwATfffDNmzpwpl4iIlGBwIaplUlNTMX/+fGzfvh0DBgyQywmTk5ODefPmYceOHXKJiEgZBheiOm7RokXo2bMnFi1aJJcuaPHixRg8eDA++eQTuUREpBSDC1Eto/qjonfffRdz5szB4MGDkZWVhbS0NHkIEZEyDC5EVCFDhgzBv//9b8yfPx+pqalyudYwTRNHjx7FgQMHEAqF5DIRVRMGF6I6xufzYeLEiZHLao8ZMwZffvklxowZE9k2ceJE+Hw++aa1XmFhIbZu3Yrf//736NGjB371q19h3rx58Pv98lAiqia8cq5E9ZVh2T86Xjk3fj6fD9OmTcOuXbswbdq0ix6gu2jRIixatAijR4/G6NGj5XJUixcvxsyZM/HQQw9h8uTJcrnG+/HHH/GnP/0JS5YsgdPpRDAYRDgcLjOmcePGaNKkCRwOR8zfpVJZVu9vmiaEELDb7TH379mzJyZMmIBu3brJpXKq4sq2qvvHcmXYylLdv6ZcOZfBRaL6hZn9o2NwiR+DS+x+/PFH/OUvf8H27dvRokULHDx4ELm5uSgqKoqMGTBgAO699140aNAA4XAYpmle9LtUKsvq/Sv6XUXbtm2Dz+fD008/zeCSAKr715TgApFgxcXFIhgMCsMw5FJCnD17Vpw5c0aEQiG5lBDFxcUiEAiIcDgslxKC/aPLz88Xp0+fFpqmyaWE0DQt5vlv27ZNDB8+XCxZskQu1WhnzpwRjz32mOjdu7fIzs6Wy+W89tpr4pprrhGvvfaaXLqoRYsWiXbt2okZM2bIJUv44YcfxKRJk8S0adOEKHl+/Pvf/xZz5swRAwYMEI0aNRKPPPKI8Pl8kXqsz5/KUN0/FAop7V9UVCR++uknUVxcLJfOa+nSpWLEiBEiJydHLp2X6vlXRX+/3y90XZdLCaG6v9/vFz/99JMIBoNyKSFinX/iIzcRWcro0aPxxRdfVHi1pTZyuVzo2LEjHn/8cWRnZ+PgwYN47rnn0KBBA3koEVUTBhciogu45JJL0KJFCyUfWxJR5TC4EBERkWUwuBDVMlV1yX8AeOihh/Ddd99Z8sBcIrImBhciIiKyDAYXIiIisgwGFyIiIrIMBhciIiKyDAYXIiIisgxbYWFhQi/5X/oNArF+T0VFGYYBIQQcDoeS+1A9/9rQX+V3nVTF/o11/p9//jmWLVuGAQMGWOqS/xS7H3/8ES+//DLq16+P5557Ti6XU5HnT2VYvb9pmjBNE3a7PaavFFi5ciW2bNmCcePG4aqrrpLL5aieP/tHV9H9W1Gxzt+maVpCg0s4HIYoeeFR8YsFg0GYpgmPx6PkuyRUz5/9oysuLoZhGHC73dG/q6KSKjL/HTt2YMmSJejfvz+DSy31448/IisrC8nJyXj++eflcjmGYcAwDGXf9WP1/hX9rqIVK1Zg8+bNGD9+PLp27SqXy1E9f/aPLhQKIRQKxbx/KyrW+fNLFiWqv0SQ/aPjlyxSVSoNLo0aNcLUqVPlcjkVef5Uhur+qr9E0O/3IxgMwuv1wu12y+Vyli1bhk2bNvHboRNEdf+a8iWLiU8WRERERIowuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFlMLgQERGRZfDKuRLVV4Zl/+hq4pVz27Zti1tuuUUuUy2xcuVKXjk3QXjl3OhivTJsZanuX1OunMvgIlH9wsz+0dW04PKXv/wF27Ztk0sXVPoFYaqU/nNVdR+hUAimaSIpKemij09lnPvnRtXvUNF9YLfbMXny5Ji+q6giz5/KUN1f9Qszg0t0sb4wV5bq/gwulcTgEp3V+9ek4FIZVu8/f/587NmzBxMmTEBmZqZcjltRURE0TUNycnJML2wVpfrxsXp/1S/MDC7RxfrCXFmq+9eU4JL4ZEFERESkCIMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVmGrbCwMKFXzlV9SXLDMCCEgMPhUHIfqudfG/qXXlJdxX1Uxf5VOX+r91+wYAH27duHsWPHomPHjnI5bqX71263K7myturHh/2jM00TpmnGvH9XrlyJLVu2YNy4cbjqqqvkcjmq58/+0VV0/1ZUrPO3aZqW0OASDochSl54VPxiwWAQpmnC4/EouSSz6vmzf3TFxcUwDANutzvqJZ8rS/X8q6K/aZpwOp1K+r/yyivYu3cvHn30UWRkZMjluGmaBl3X4fF4lOxfwzBgGIayx4f9oyvdv263O6avZFmxYgU2b96M8ePHo2vXrnK5HNXzZ//oQqEQQqFQzPu3omKdP7+rSKL6u3jYPzp+V1F0qvvzu4qis3p/1d/Fw+8qii7W7+KpLNX9+V1FRERERBXE4EJERESWweBCRERElsHgQkRERJbB4EJERESWweBCRERElsHgQkRERJbB4EJERESWweBCRERElsHgQkRERJbB4EJERESWweBCRERElsHgQkRERJbB4EJEOHXqFN58802sXbsWu3fvxoIFC/Duu+/i9OnT8lAiomrF4EJECAQCWLNmDdasWYPdu3fjjTfewDfffAOHwyEPJSKqVgwuRIS0tDR06dIFl1xyCQCgRYsWyMjIQEpKijyUiKhaMbgQETweD9LT05GWlgaUBJcWLVrIw4iIqh2DCxEBJasupcElLS2NwYWIaiQGFyICzllladKkCTIzMxlciKhGYnAhIgBA06ZN0bx5czRs2BANGjSQy0RENQKDCxEBJWcWBYNB1K9fH/Xq1ZPLREQ1gu3UqVNC3hgPIX5uZ7PZ5FJCGIYBIQQcDoeS+1A9f/aPrir2rxACNpuN/Uvk5uZizZo1WL16NY4cOQK73Q6v14vrrrsO9957L7p165awIFO6f+12O+z2xL9vUvH4nIv9ozNNE6Zpxrx/33nnHWzfvh2jR49G586d5XI5qufP/tFVdP9WVKzztxUUFCQ0uITDYYiSFx4Vv1gwGIRpmvB4PEquMaF6/uwfXXFxMQzDgNvthtPplMtxUz1/q/QPBoP46quv8Oabb2Ljxo1o2LAh7rnnHtx///1IS0vD1q1bsWjRImzZsgUtW7bE/fffj9tuuw2tWrWSW1WIpmnQdR0ej0fJ/jUMA4ZhwOl0xvX4XAj7R1fR/fvmm29iy5YteOSRR3DVVVfJ5XJUz5/9owuFQgiFQnC73UhKSpLLcSudv8PhiPr6bhOi5C10gmiaBiEEXC6XkgcuPz8fhmHA6/UqeeA0TYNpmnC5XFEfuMpi/+gKCgqg6zq8Xi9cLpdcjlsoFIJhGMrmX9P7f//99/jggw+wfPly5OfnY8CAAbjlllvQu3dvNGvWrMxYXdfx3XffYe3atVizZg1OnjyJa6+9FiNGjMC1116L+vXrlxkfi6KiImiahuTkZLjdbrkct3gfn4uxen9d1xEOh5X19/v9CAaD8Hq9Me3fZcuWYdOmTZgwYQK6desml8tRPf+q6K/rOlwuV0zBrqJU9w8EAggEAkhOTobH45HLcYt1/olPFkRUowQCAWzcuBEPPPAABg0ahI8//hi//e1v8eGHH+LVV1/FXXfdVS60AEBSUhI6d+6Mp59+GqtWrcJLL70Et9uN0aNHo1evXpg9eza+//57+WZEREoxuBCV8Pl8GDduHPr27YtNmzZFtq9atQodOnTAn//858i2r776Cr/+9a8jn8W2bNkSS5cuRV5eHiZOnAin0xmpnftz3XXXYePGjZE+Kn3//feYPXs2evXqhdGjR8PtduOll17CqlWr8Mwzz6Bz584xr1o2a9YMd911F1599VV89NFHuP/++/Hxxx9j0KBBeOCBB7Bx40YEAgH5ZtVm3rx5aNiwYbnH/7e//S0OHjwYGffnP/+5TL1Dhw5YtWpVmV5EVLMwuBBV0Nq1azFx4kQkJSVh586dEEJg3Lhx+P3vf4/ly5dj3rx5CIfDOHPmDB599FH06dMHGzZsgBAC27Ztw4033ii3TJjzra7cf//9+Oijj6KursTK6XQiIyMj6irMkSNH5JtVuaKiIvTp0wdffvklhBDYuXMn7rzzzkg9Ly8PkydPxscff4w1a9ZACAGfz4df//rXePHFF/HWW2+V6UdENQeDC1EFbd++HX6/Hw8++CC6du0KAHj44YcxePBgbNmyBXv27JFvotyRI0cuuLry9NNPIyMjI+pnxpVxoVWYm2++GSNGjKj2VZjGjRsjNTVV3gwA2L17N7766iv0798fN998MwAgJSUFGRkZaNiwIfLy8uSbEFENweBCVAGHDh3CkSNH0K1bN2RmZka2p6amokWLFjh9+jRyc3PL3EaV0tWVESNG4Oabb0746kqs5FWYl19+GR6PB6NHj8a1115b5aswZ8+evWjw6N+/P7Zu3Yr/9//+X2T1xWaz4cEHH8S+ffuQn58v34SIaggGFyJJ6cc55x4X8d133wElx8GcPXsWS5cuRXp6epnjI5577jmcOHFC+Yve0aNHMWfOHFx77bUYPXo0PB4PXn75ZaWrK7Fq1qwZBg8eHFmFGTp0aLlVmGAwKN8sofLy8uDz+dC6dWu0adNGLkeUHt+SmpqKt956C6+++iqWLl3KrzogquEYXIgkpQfQll4M6a233kL79u3LjHnwwQdx+PDhyJjSnyNHjmDYsGFlxiZC6erKQw89hDvuuAOffvophg4dGlldGTx4cJWsrsTqQqswjz/+OG6++WbMnz9f2SrM2bNnEQqFkJycLJciPvjgA6xatQq///3vIYTAyZMn8cgjj8jDiKgGYnAhqoA2bdrgiiuuwOHDh3H06NEyteeffx5du3bFxx9/XGZ7PI4cOYJZs2ZFVlfq1auHrKysGrG6Eit5FWbEiBH4xz/+EVmF2bBhQ0KPhdm7dy/OnDkT9WJ5BQUFCIfD8Hq9ZbafPHkSx48fL7ONiGoWBheiCkhNTcXtt98OXdcxb9487Nq1CwCwYMECvP7667j77rtx++23yzerkEAggA0bNkSOXfnkk09q9OpKrM5dhXn77bcjqzAPP/wwrr32WsyaNSvuVZizZ89i3759+MUvfoHu3bvL5YiGDRvC6XRiz549kdOjly1bhgULFshDiaiGYXAhqqCbb74Z8+bNg67r6NatG2w2G55++mk8/fTT+MMf/iAPj9m5qysPP/xw5NiVt99+2zKrK7Fq2rRpZBXmww8/xNChQ/HJJ5/EtQpz5MgRPPPMM/jrX/+Kt956C1deeWXk+KNu3brhww8/xKpVqzBnzhxcf/31ePLJJ7Fjxw60bdsWNpsNCxYswH333YcuXbogNzcXPp9PvgsiqgF4yX+J6kvas390de2S/4FAAJ9//jmWL1+OL774Ar/85S9xyy234JZbbkH79u1rTVCJxX//+1/s2LEDa9euRXZ2NrxeL0aMGIHBgwejdevW8vByjhw5gj/+8Y+49NJL8ac//anc45+Xl4f/9//+HwKBAP70pz9d8FTpaCq6fytKdX/Vl7TnJf+ji/WS9pWluj8v+U9Uh9Wl1ZVYla7CvPLKK/joo48wbNgwfPrpp3GtwhBR7cPgQlRF5GNXPv30UwwbNqzMsStNmzaVb1bnOJ1OdOrUCU899VTkjKR69eol9FgYIrIuflQkUf1RCPtHVxs/Kjpy5EjkG5kLCwsxcOBA3HzzzejduzeDSozC4TD279+PNWvWYM2aNThx4gR69uyJESNGoFevXpFvqj7f459IVu+v+qMQflQUXawfhVSW6v78qIioFou2uvLKK69wdaWCoq3C9OzZk6swRHUIgwtRAn3//feYO3cuevXqhYcffhj16tWLXNX2qaeeQqdOnaK+k6iMGTNmoH379li8eLFcSrjp06fjtttuQ05OjlzC9OnTI2fxeL1ezJgxQx6SEPKxMMOHD48cC/Pggw9i06ZNPBaGqBZjcCGKU+nqyvDhw3H77bcjOzsbI0aMqLLVlaeeegrfffcdHnroIbl0UdnZ2Xj66aeRnZ0tl8qZPXs2Zs2aJW8GSkLL6tWr8fbbb0MIgXnz5mHJkiXKwgsusArj9Xrx2GOPoXfv3lyFIaqlGFyIKqn0zKCePXvi4YcfRv369ZWvriRKdnY2evfujZtuugk7duyQy2UcPnwYI0aMwJNPPonCwkK5jA0bNiA7OxtDhgzBvffeCwAYNWoUfvvb3+Kzzz7D119/Ld8k4aKtwgwfPpxnJBHVIgwuRBVw7upK6bErw4cPr7LVlfOpyEdF69evjwSWzz//HMOGDcPy5csxcOBAeShQ8qWSf/3rX7Fr1y785S9/wfDhw+UhOHbsGMLhMH75y1+W2Z6WloYzZ85g9+7dZbardL5VmPr160eOhZk5cyYOHz4s34yILITBhSgGhw8fxsyZMy25uoJzAsugQYOQn5+Pd955B0IIrFixAunp6fLwiNTUVMydOxf//ve/cc8998hloORMPwBo3Lhxme2NGjWCzWZT/m3ZF3K+VZjS70gaPnw4srOzuQpDZEEMLkQXEAgEkJ2djXvvvRc33ngj/vGPf1T76kplrF69Gk888QR69OgBn88XNYRURmFhIYqKiuTNNYa8CjNjxgzUr18fv/vd77gKQ2RBtsLCwoRex6X0sjA2m00uJYRhGBBCwOFwKLkP1fOvDf2FEJGzRy5mwYIFWLp0KTRNk0vnpXr+sSoqKoLP54NpmujTpw/Gjx+PAQMGoFGjRvLQajdjxgwsWbIEkydPvuABuuvXr8f06dPx+eefo2PHjpg6dWqFw8vhw4cxffp0+Hw+TJs2LfIlhqUH5so933vvPcycORN33XUXnnrqqXM6VT/TNHHo0CEsW7YMK1euxIkTJ9CoUSM0atQo4dfv6NmzJx555BF07txZLpVT0X9fFaW6v2maME0Tdrs9put4rVy5Elu2bMG4ceNw1VVXyeVyVM+f/aOr6P6tqFjnb9M0LaHBJRwOQ5QECxW/WDAYhGma8Hg8Cf8DgyqYf13rP2vWLGzbtg19+/ZF8+bN5XI5uq7DNE0kJSXF1L+iTNOEEAJ2uz3qP4yCggL8+9//xvbt21FYWIirr74aN998MwYMGIDLL79cHl6tYgkupc4NMAAwbNgwTJs2LerHRaUuFFxmz56Nd955B08++aQlgkthYSF2794duZjdTz/9hMzMTPTq1QstW7aUh5cR6/On1GeffYZgMIgnnngCmZmZcrkcwzBgGAacTqeS57/q/pqmQdd1uN3umC4QumLFCmzevBnjx49H165d5XI5qufP/tGFQiGEQqGY929FxTx/kWDFxcUiGAwKwzDkUkKcPXtWnDlzRoRCIbmUEMXFxSIQCIhwOCyXEqKu9X/55ZfFo48+Kvbt2yeXzis/P1+cPn1aaJomlxJC07QKzV8IIb755hvx5JNPirZt24rMzEzx7LPPii1btoiCggJ5aLXIysoS7dq1E4sWLZJLF7R+/XrRq1cvAUD06tVLrF+/Xh5SzqFDh8Tw4cPFrbfeKr7++uvI9kWLFolrrrlGLFy4sMz4xYsXi2uuuUb87W9/K7O9uhw9elQsWrRIDBkyRKSnp4sBAwaIFStWiB9//FEeekEVff4sXLhQjBw5UuzevVsunVdF+1dUKBRS2r+oqEj89NNPori4WC6d19KlS8WIESNETk6OXDov1fOviv5+v1/oui6XEkJ1f7/fL3766ScRDAblUkLEOv8okYaIACAzMxMzZ87E1q1bMXnyZOzcuROjRo3CyJEjsXjxYhw7dky+SY03cOBA7NixI3LQbjwuv/xyOJ1OnDx5ssz2EydOwOFwoFWrVmW2V6XCwkJs3boVzz33HO68805kZWXh8ssvx3vvvYfs7GwMGzYMzZo1k29GRDUYgwtRjJo1a4Zhw4Zh/fr1eO+993DFFVcgKysLd955J5577jls3br1vNc5qckGDhyIrKysC54OHYsBAwZg4MCBWLRoERYuXAgAWLJkCd566y385je/wU033STfRLljx45h8eLFGDlyJEaNGoWdO3di8uTJ2Lp1K2bOnBnTxzZEVDMxuBBVQmZmJmbMmIFt27bVmlWYeEydOhVjxozB7373O9hsNkycOBGjRo2q0mNbzre6csUVV+C9997D+vXrubpCVEswuBDFoWnTpmVWYS6//HK8/PLLVboKE88l/ysiPT0dy5cvxyeffBI5MPdcU6dOjZwVUFhYWGWh5dzVlZEjR+Lrr7/Gk08+iW3btmHGjBlcXSGqZRhciBIkMzMTf/nLX5CdnY0nnniizq/CqHSh1ZVVq1bh448/xv3332+Ja+wQUcUxuBAlWNOmTTF06FCsX78e77//Pq644grMmDGjSldhaqsLHbvC1RWiuoPBhUihzp07Y8aMGbXqjKSqJq+uzJgxA1dccQXef//9yLErXF0hqjsYXIiqwLnHwpxvFWbLli1chZFcaHVl69atmDFjRkxXoiWi2ofBhaiKnW8V5qGHHsLIkSOxaNGiOr0Kw9UVIroYBheianK+VZiZM2fijjvuwLPPPlunVmGOHTuGRYsWcXWFiC6KwYWoBjh3Febpp5/Grl27av0qTGFhIbZs2YJnn30Wd9xxB2bOnMnVFSK6KAYXohrkfGck1bZVmHNXVx566CHs2rULTz/9NFdXiCgmDC5ENZS8CrN79+4yqzBHjx6Vb1JjXWx1ZejQoVxdIaKYMLgQ1XClqzDr1q3DO++8gxYtWkTOSKrpqzBHjx4ts7ry5ZdfYty4cdiwYQNXV4ioUhhciCykU6dO+POf/4zPPvusxq7CnLu6cuedd2LmzJlo3bo13n//fXz88ccYMmQILrnkEvlmREQxYXAhsqBzV2Hef/99tG7dGjNnzqzWVRh5dWX37t2RY1eysrK4ukJECcHgQmRxnTt3RlZWFrZu3Ypnnnkmsgrz4IMPKl+Fiba6sm7dOh67QkQJx+BCVEs0bdoU999/P9atW4cPPvgA6enpylZhSldXHnzwwcjqyjPPPMPVFSJSjsGFqBbKyMhI+CrM+VZX0tPT8cEHH2DdunX8RmYiqhIMLkS12IVWYe644w4888wz+Oyzz1BQUCDfrIyLra5kZGTINyEiUobBhaiOOHcV5tlnn8U333yD+++/H8OGDcNHH31ULsAcOnQIf/7zn3H77bcjKyuLqytEVCPYCgsLhbwxHkL83M5ms8mlhDAMA0IIOBwOJfehev61ob8QAjabLab7mDt3Lo4fP44xY8agXbt2crmcqti/FZl/RVmt/759+7Bq1Sp8/PHHSEpKwt13342WLVti/fr1+OKLL9CuXTvcf//96NevX0JOYS7dv3a7HXZ74t83JfrxkVW0/9KlS/Hll1/ikUceiem4n4r2ryjV/U3ThGmaMe/flStXYsuWLRg3bhyuuuoquVyO6vmzf3QV3b8VFev8bZqmJTS4hMNhiJIXHhW/WDAYhGma8Hg8cDgccjluqudf1/rPmjULubm5GDt2LNq3by+XyykuLoZhGHC73XA6nXI5bhWdf0VVRX/TNOF0OhPa/6effsLGjRuxYsUK/Pjjj7jpppswdOhQdOrUSR4aF03ToOs6PB6Pkv1rGAYMw0j441Oqov0XL16ML7/8Eo8++igyMzPlcjkV7V9RqvuX7l+3242kpCS5XM6KFSuwefNmjB8/Hl27dpXL5aieP/tHFwqFEAqFYt6/FRXr/G1ClLxFTxBN0yCEgMvlinrHlZWfnw/DMOD1epU8cJqmwTRNuFwuJcGorvXPyspCbm4uxo0bhw4dOsjlcgoKCqDrOrxeL1wul1yOWygUgmEYMc+/otg/uqKiImiahuTkZLjdbrkcN9Xzr2j/1157Df/85z8xYcKEmFYUKtq/onRdRzgcVtbf7/cjGAzC6/XGtH+XLVuGTZs2YcKECejWrZtcLkf1/Kuiv67rcLlcSoK76v6BQACBQADJycnweDxyOW6xzj/xyYKIiIhIEQYXIiIisgwGFyIiIrIMBhciIiKyDAYXIiIisgwGFyIiIrIMBhciIiKyDAYXIiIisgwGFyIiIrIMBhciIiKyDAYXIiIisgwGFyIiIrIMBhciIiKyDAYXIiIisgwGFyIiIrIMBhciIiKyDAYXIiIisgwGFyIiIrIMBhciIiKyDAYXIiIisgwGFyIiIrIMW2FhoZA3xkOIn9vZbDa5lBCGYUAIAYfDoeQ+VM+/NvQXQsBms8V0H3PnzsXx48cxZswYtGvXTi6XUxX7tyLzryj2j650/9rtdtjtiX/fpHr+Fe2/dOlSfPnll3jkkUfQuXNnuVxORftXlOr+pmnCNM2Y9+/KlSuxZcsWjBs3DldddZVcLkf1/Nk/uoru34qKdf42TdMSGlzC4TBEyQuPil8sGAzCNE14PB44HA65HDfV869r/WfNmoXc3FyMHTsW7du3l8vlFBcXwzAMuN1uOJ1OuRy3is6/oqqiv2macDqdluyvaRp0XYfH41Gyfw3DgGEYyuZf0f6LFy/Gl19+iUcffRSZmZlyuZyK9q8o1f1L96/b7UZSUpJcLmfFihXYvHkzxo8fj65du8rlclTPn/2jC4VCCIVCMe/fiop1/jYhSt6iJ4imaRBCwOVyRb3jysrPz4dhGPB6vUoeOE3TYJomXC6XkmBU1/pnZWUhNzcX48aNQ4cOHeRyOQUFBdB1HV6vFy6XSy7HLRQKwTCMmOdfUewfXVFRETRNQ3JyMtxut1yOm+r5V7T/a6+9hn/+85+YMGFCTCsKFe1fUbquIxwOK+vv9/sRDAbh9Xpj2r/Lli3Dpk2bMGHCBHTr1k0ul6N6/lXRX9d1uFwuJcFddf9AIIBAIIDk5GR4PB65HLdY55/4ZEFERESkCIMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVmGrbCwUMgb4yHEz+1sNptcSgjDMCCEgMPhUHIfqudfG/oLIWCz2WK6j7lz5+L48eMYM2YM2rVrJ5fLqYr9W5H5V5TV+y9duhQLFiyApmlyKSFUPz9rmoKCAlx99dV47rnn0LlzZ7lcjur9q7q/aZowTRN2ux12+8XfF69cuRJbtmzBuHHjcNVVV8nlclTPn/2jq+j+rahY52/TNC2hwSUcDkOUvPCo+MWCwSBM04TH44HD4ZDLcVM9/7rWf9asWcjNzcXYsWPRvn17uVxOcXExDMOA2+2G0+mUy3Gr6Pwrqir6m6YJp9OppP8rr7yCNWvW4Prrr0eLFi3kctx0XYdhGEhKSlLy79c0TQghYLfbo/7hq6zK9L/88svRuXNnNGjQQC6VYxgGDMNQtn9V99c0Dbquw+12IykpSS6Xs2LFCmzevBnjx49H165d5XI5qufP/tGFQiGEQqGY929FxTp/mxAlb4ESRNM0CCHgcrmi3nFl5efnwzAMeL1eJQ+cpmkwTRMul0vJH9a61j8rKwu5ubkYN24cOnToIJfLKSgogK7r8Hq9cLlccjluoVAIhmHEPP+Ksnr/+fPnY8+ePZgwYQIyMzPlctyKioqgaRqSk5PhdrvlctxUPz5W76/rOsLhsLL+fr8fwWAQXq83pv27bNkybNq0CRMmTEC3bt3kcjmq518V/XVdh8vlUvLGTHX/QCCAQCCA5ORkeDweuRy3WOef+GRBREREpAiDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxEREVkGgwsRERFZBoMLERERWQaDCxHh1KlTePPNN7F27Vrs3r0bCxYswLvvvovTp0/LQ4mIqhWDCxEhEAhgzZo1WLNmDXbv3o033ngD33zzDRwOhzyUiKhaMbgQEdLS0tClSxdccsklAIAWLVogIyMDKSkp8lAiomrF4EJE8Hg8SE9PR1paGlASXFq0aCEPIyKqdgwuRASUrLqUBpe0tDQGFyKqkRhciAg4Z5WlSZMmyMzMZHAhohqJwYWIAABNmzZF8+bN0bBhQzRo0EAuExHVCDYhhJA3xkPTNAgh4HK5YLcnPhfl5+fDMAx4vV4kJSXJ5bhpmgbTNOFyuZScUVHX+mdlZSE3Nxfjxo1Dhw4d5HI5BQUF0HUdXq8XLpdLLsctFArBMIyY5m8YBrZv346cnBy5dEHhcBhCCDidTthsNrkcN9X9N2/ejG+//Rb9+vWLaX9VlKZpCIfDcLvdcDqdcjluhmHANE04HA4lf38q279Vq1bo1asXLrvsMrlURkWen5Wh6zrC4bCy/n6/H8FgEF6vF263Wy6Xs2zZMmzatAkTJkxAt27d5HI5qudfFf11XYfL5VLy/FfdPxAIIBAIIDk5GR6PRy7HLdb5206dOpXQ4FKag1T8UUXJHw4hBBwOh5L7UD3/utb/1VdfxYkTJzBy5EhceeWVcrmcqti/QgjYbLaL9v/nP/+JV155BT/88AOaNWsml4kuStM0HDt2DFdffTWeeeYZXH755fKQMiry/KwM1f1N04RpmrDb7TEFu3feeQfbt2/H6NGj0blzZ7lcjur5s390Fd2/FRXr/G0FBQUJDS6l7wgr+o4kVsFgEKZpwuPxKEnEqudf1/rPnTsXJ06cwJgxY/CrX/1KLpdTXFwMwzCUvSOPdf6GYWDmzJk4dOgQnnrqqZjeDRLJsrOzsWzZMlx33XW4//775XI5hmHAMAw4nc6oz8/KUt1f0zToug6PxxPTv98333wTW7ZswSOPPIKrrrpKLpejev7sH10oFEIoFILb7VbyiUfp/B0OR9TXd35UJKnoRyEVVdf6W/Wjoi1btmD58uW45pprMGzYMNSvX18eQhRVbm4u5syZg6KiIjz33HNo3bq1PKScWJ+flaX6oxB+VBRdrB+FVJbq/jXlo6LEJwsiizMMA1u3bkUgEEC3bt0YWqhSDhw4gDNnzqBPnz4xhRYiig2DC5Fk+/btOHr0KPr164f27dvLZaKLys3NxT/+8Q+43W5cd911cpmI4sDgQnQOrrZQIuzfv5+rLUSKMLgQnYOrLRQvrrYQqcXgQlSCqy2UCPv374fP5+NqC5EiDC5EJbjaQvEqXW3xeDxcbSFShMGFiKstlCBcbSFSj8GFiKstlABcbSGqGgwuVOdxtYUS4dzVliuuuEIuE1GCMLhQncfVFooXV1uIqg6DC9VpXG2hROBqC1HVYXChOo2rLRQvrrYQVS0GF6qzDMPAli1buNpCceFqC1HVYnChOmv79u04duwYV1uo0rjaQlT1GFyoTuJqCyUCV1uIqh6DC9VJpast/fv3r9LVlpdffhlerxc2m63cz4MPPogjR47IN7GUDRs2oE+fPpHfqXfv3li/fr08rJy8vDw88cQTmDJlilwq4/3330dGRgZeeOEFuVTluNpCVD0YXKjOqe7VlrS0NCxZsgRCiMjP2rVr8Z///AePP/44du7cKd/EEjZs2IBp06ahS5cuOHPmDHw+H66++mpMmjQJ77zzjjwcAHDkyBE8+OCDuPXWW/Hdd99h/fr1yMjIwPjx4+Hz+eThuOuuu7B371788Y9/lEtVjqstRNWDwYXqnB07diA3Nxf9+/dHu3bt5HK1GDRoEH7zm9/gp59+wtGjR+WyJezYsQNCCNx+++1ITU1FSkoKbr31VqSkpGDfvn3ycABASkoKZs+ejT/+8Y8oKipCkyZNsHjx4hoRTKLhagtR9WFwoTolHA5j27ZtKC4urpbVlotp3LgxGjduDADIyspC+/btsWTJEnkYAGD9+vXo3bs3Jk2ahLy8PMycOfO8H0NNnz69zO1Wr16NTp06lfk4Jzs7O1L3+XyYOHFiuT42mw3Tpk0r0+tcU6dOxY4dO3DTTTfJpQtKSUmBzWbDp59+Cp/Ph9zcXHz88cdISUlBamqqPLzGfFTE1Rai6sPgQnXKF198gRMnTtSo1RYAWLduHTZu3IhBgwbhxhtvlMsx69SpE1avXh35CGrhwoVYtWoVZs+eDQB47bXXMGnSJAwZMgRCCJw5cwbdu3fHpEmTsHr1aqDkeBOfz4cJEybgzJkzEEJg9erV6Nixo3Rv0R05cgQrVqyAEAK9e/eWyxGbNm3CyZMnMWXKFEyaNAkHDhzAunXr5GE1BldbiKoXgwvVGYZhYNu2bdA0rVpXW06cOIFRo0aVWcm4+eabsX79ehQWFsrD43L55ZcjNTUVhYWFOHz4MLZu3YouXbrgtttuAwCkpqZi+PDhaNWqFT766CMcPnw4ctsLrXpczJEjR/DAAw8gPT0d77//Pn7zm99EXYW5++678fbbb+N//ud/MGrUKLzzzjsYNGiQPKzG4GoLUfWyFRYWCnljPIT4uZ3NZpNLCWEYBoQQcDgcSu5D9fxrQ38hROQF92Lmzp2L48ePY8yYMTGtcKjcv9u3b8eqVavQu3dvDB06tFqCy8svv4ylS5fi6aefxsiRIyPbDx06hKlTp2Lr1q2YPn06Ro0ahaysLLz++ut46qmnMGrUqDJ9UPJR0fTp03H11VdjypQpWLx4Md577z08+eSTGDJkCABg5syZWLx4MSZPnowWLVpg+vTp6NGjB6ZMmRIJJT6fD9OnT0dOTg6mTZuGlJQUTJs2Dd27d498NPTuu+9i2rRpGDJkSNSPi2Tvvfcepk2bhhtuuAHTp0+vVBA61/vvv4+pU6fiN7/5TbUcB5Obm4vZs2fj7bffhtvtRlJSkjykziv9+xCLgoICdOnSBc8//zyuuuoquVxORf/+VBT7R2eaJkzThN1uh92e+HWPWOdv0zQtocElHA5HXnhU/GLBYBCmacLj8cDhcMjluKmef13rP2vWLOTm5mLs2LExnXZcXFwMwzDgdrvhdDrlcqUZhoGXXnoJ//nPf/DUU0+ha9eu8pAqcaHgAgBvv/02XnzxRQwaNAgvvPACXnvttchBq+d6/PHHMWXKFHz99dflgsv06dPLjZ84cSKmTp2KDRs2YPr06bjnnnswderUSF0OLgCwaNEiDBw4EKNHjwbiCC4A8OKLL+Ltt9/G1KlTce+998rlCqnu4LJ+/Xq8+uqraNasWdSPvyrLNE0IIWC326P+4a4s1f3D4TDC4TCSkpJi/vvcokULZGZmIjk5WS6VYxgGDMOA0+mM6e9PRbF/dKFQCKFQSFloj3n+IsGKi4tFMBgUhmHIpYQ4e/asOHPmjAiFQnIpIYqLi0UgEBDhcFguJURd6//yyy+LRx99VOzbt08unVd+fr44ffq00DRNLsXls88+E6NGjRILFy4Ufr9fLleZl156SbRr104sWbJELolVq1aJDh06iEmTJgmfzydefvll0a5dO7F48eLImHXr1olevXqJESNGiFdffVX06tVLPP7448Ln84kZM2aInj17itWrV5cbP3HiRLFq1arIf585cyYy5syZM2LChAni1ltvFV9//bV45513xL333iveeeedyJjVq1eLjh07iqlTp0a2xWr69OmiQ4cO4u2335ZLFfbee++JTp06ieeff14uKXfs2DExceJE8dBDD4mDBw/K5YTQNK1C/74qKhQKKe1fVFQkfvrpJ1FcXCyXEkL1/Kuiv9/vF7quy6WEUN3f7/eLn376SQSDQbmUELHOP0qkIaodqvu6LbHKz8+HaZpo2bIlUlJS5DIAoHv37ujatSvy8vJw9uxZuVxOeno6WrduHTl2pfS/z73Q3ZEjR3D48GGkpKRETl32+/0VOn4jLy8Pjz/+OG699VZ8/fXXZbbn5eWVOVvKqvbv34/Tp0+jV69eFXpsiCixGFyo1jv3KrmxHGdTHb7++mt8+OGH+MUvfoGMjAy5HJGTk4Ndu3YhJSUlpiBQGlLS09Nx0003oW/fvti9ezdWrFgBn88Hn8+HFStW4OjRo7jjjjuQl5eHnJwcdO/eHd27d5fbXVBKSgr69OmD3NxcLF++PHLxuL/+9a9YtGjRRQ/QrelKzyRyu9249tpr5TIRVSEGF6rVauJqy/nOKrr66qvhcDgwd+7cMqdDnzhxAg899FBk3KBBg9CmTRtMnToV6enpZfoCwL///W/cc889ZcanpqZi2LBhSElJwZgxYzBnzhxs3LgRTZo0QZMmTZCTk4M5c+agcePGmDhxIj799FNMnz69zPzuuece7Nu3D7NmzcLMmTPluwUADBkyBHPmzMHu3bvRpEkT2Gw2LFy4ELNmzcJTTz0lD7eU0jOJevXqhVatWsllIqpCNiFKTkNJEE3TIISAy+WKfnBNJeXn58MwDHi9XiUHB2maBtM04XK5Yj64rCLqWv+srCzk5uZi3Lhx6NChg1wup6CgALquw+v1wuVyyeUK++yzz7BixQr07Nmz2s4ksors7OxyB+WeKycnB7NmzUK3bt0wefJkuVxrlZ5JFAwG8cQTT6Bly5YxP/8rKhQKwTAMZf11XUc4HFbW3+/3IxgMwuv1wu12y+W4qZ5/VfTXdR0ulyuhJx+UUt0/EAggEAggOTkZHo9HLsct1vknPlkQ1RA1cbWFrIfXbSGqWRhcqNbatm1bjT+2hWq20mNb6tWrhz59+shlIqoGDC5UK5WuttTU7ySqiQYOHIi33377vB8ToeSMprfeeqtOfUzE1RaimofBhWql0tWWfv36cbWFKoWrLUQ1E4ML1TpcbaFE4GoLUc3E4EK1DldbKF5cbSGquRhcqFbhagslAldbiGouBheqVbjaQvE6duwYV1uIajAGF6o1uNpCicDVFqKajcGFag2utlC8uNpCVPMxuFCtwNUWSoT9+/cjLy+Pqy1ENRiDC9UKXG2heHG1hcgaGFzI8rjaQonA1RYia2BwIcvjagvFi6stRNbB4EKWxtUWSgSuthBZB4MLWRpXWyheXG0hshYGF7IsrrZQInC1hchabIWFhULeGA8hfm5ns9nkUkIYhgEhBBwOh5L7UD3/2tBfCAGbzRbTfcydOxfHjx/HmDFjYloRqcj+3bZtG2bMmIE2bdrg3nvvhdPplIcQRRUOh/H2228jGAziueeew+WXXy4PKaOiz/+Ksnp/0zRhmibsdjvs9sS/L1Y9f/aPrqbsX5umaQkNLuFwGKLkhUfFLxYMBmGaJjweDxwOh1yOm+r517X+s2bNQm5uLsaOHYv27dvL5XKKi4thGAbcbnfUIGIYBmbMmIH//d//RXFxsVy+IFEFwQ5V0B+K7sPq/VGJfdCyZUs8+eSTGDp0qFwqxzAMGIYBp9MZ0/O/oqzeX9M06LoOt9uNpKQkuRw31fNn/+hCoRBCoVC171+bOPcvSQJomgYhBFwuV9Q7rqz8/HwYhgGv16vkgdM0DaZpwuVyKQlGda1/VlYWcnNzMW7cOHTo0EEul1NQUABd1+H1euFyueRy3EKhEAzDiHn+FcX+0RUVFUHTNCQnJ8PtdsvluKmev9X767qOcDisrL/f70cwGITX61Wyf1XPvyr667oOl8sV9Y1ZZanuHwgEEAgEkJycDI/HI5fjFuv8E58siIiIiBRhcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy7AVFhYKeWM8hPi5nc1mk0sJYRgGhBBwOBxK7kP1/GtDfyEEbDZbTPcxd+5cHD9+HGPGjEG7du3kcjlVsX8rMv+KYv/oSvev3W6H3Z74902q58/+0ZmmCdM0uX8vwOr9a8r+tWmaltDgEg6HIUpeeFT8YsFgEKZpwuPxwOFwyOW4qZ5/Xes/a9Ys5ObmYuzYsWjfvr1cLqe4uBiGYcDtdsPpdMrluFV0/hVVFf1N04TT6bRkf03ToOs6PB6Pkv1rGAYMw1A2f/aPrnT/ut1uJCUlyeW4qZ4/+0cXCoUQCoWqff/ahCh5i54gmqZBCAGXyxX1jisrPz8fhmHA6/UqeeA0TYNpmnC5XEqCUV3rn5WVhdzcXIwbNw4dOnSQy+UUFBRA13V4vV64XC65HLdQKATDMGKef0Wxf3RFRUXQNA3Jyclwu91yOW6q52/1/rquIxwOK+vv9/sRDAbh9XqV7F/V86+K/rquw+VyKQnuqvsHAgEEAgEkJyfD4/HI5bjFOv/EJwsiIiIiRRhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgybIWFhULeGA8hfm5ns9nkUkIYhgEhBBwOh5L7UD3/2tBfCAGbzRbTfcydOxcLFy6EzWaDy+WSy+Wonj9dXJ8+fTB27Fh07NhRLsWt9N+v3W6H3Z74900VfX5WFPtHZ5omTNPk/r0Aq/evKfvXpmlaQoNLOByGKAkWKn6xYDAI0zTh8XjgcDjkctxUz7+u9f/mm2+wf/9+efMF6boO0zSRlJQUU/+KMk0TouSFM9o/jMqyev/s7GwIITBp0iRkZGTI5bhpmgZd1+HxeOB0OuVy3AzDgGEYcDqdSp4/7B9d6f51u91ISkqSy3FTPX/2jy4UCiEUClX7/rUJUfIWN0E0TYMQAi6XK+odV1Z+fj4Mw4DX61XywGmaBtM04XK5lAQj9o+uoKAAuq7D6/XGtEJTUaFQCIZhKJu/1fvPnz8fe/bswYQJE5CZmSmX41ZUVARN05CcnAy32y2X46b68bF6f13XEQ6HlfX3+/0IBoPwer1K9q/q+VdFf13X4XK5lAR31f0DgQACgQCSk5Ph8XjkctxinX/ikwURERGRIgwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuRIRTp07hzTffxNq1a7F7924sWLAA7777Lk6fPi0PJSKqVgwuRIRAIIA1a9ZgzZo12L17N9544w188803Si7CRUQUDwYXIkJaWhq6dOmCSy65BADQokULZGRkICUlRR5KRFStGFyICB6PB+np6UhLSwNKgkuLFi3kYURE1Y7BhYiAklWX0uCSlpbG4EJENRKDCxEB56yyNGnSBJmZmQwuRFQjMbgQEQCgadOmaN68ORo2bIgGDRrIZSKiGsEmhBDyxnhomgYhBFwuF+z2xOei/Px8GIYBr9eLpKQkuRw3TdNgmqayrzWvyf3z8vJw4sQJnDp1Ct999x0KCwtRv379MmPC4TCEEHA6nbDZbGVqiVBcXAzTNOF2uys8/1ionr/V+2/evBnffvst+vXrhw4dOsjluGmahnA4DLfbHfVr6yvLMAyYpgmHw6Hk709t7l+vXr1IeG3evDmaNm1a7t//xfj9fgSDQXi9XrjdbrkcN13XEQ6HK/X3LRZV0V/XdbhcLiXPf9X9A4EAAoEAkpOT4fF45HLcYp0/g4sknhf+WNSk/uFwGP/617/wySef4NNPP8XevXsRDAbhdrvxi1/8As2bN+c7b6I6IBwOIz8/HydPnoTP5wMANG/eHP3798ett96Kvn37onnz5vLNymFwiS7WF+bKUt2fwaWSGFyii6W/rutYu3Yt/vKXv2Dnzp1IT0/Hrbfeil//+tfo0KEDUlNTlTy2RFTz+f1+nDx5Ejk5Ofjwww/x2WefweVy4b777sPo0aPxq1/9Sr5JBINLdLG+MFeW6v4MLpXE4BLdxfpv3boVWVlZyMnJwY033ojx48eje/fuSh5LIrI+n8+HTz/9FK+88grOnj2LkSNHYujQoZEz0M7F4BJdrC/MlaW6f00JLolPFlQjaZqGv/3tb3j00UeRlJSEd999F8uWLcO1117L0EJEF5Samorhw4dj7dq1ePrpp/HGG29gzJgxyMnJkYcSVQkGlzrg1KlTmDJlCt577z2MHz8eCxYsQJ8+faImWiKiczVu3BijRo3C8uXL0bRpU0yZMgVr166VhxEpx+BSy506dQovvPACdu3ahcceewxDhw5Fs2bN5GFERDHp0qULnn/+eVx11VX429/+hg8++EAeQqSU7dSpUwk9xqX0kBkVp2qi5HQ+IQQcDoeS+1A9/6rsX/rx0IEDBzBx4kRcf/318nAioko5duwYFi5ciP3792PYsGHo2bMnTNOEaZqw2+1KjnEUQkAIAZvNpuRvKPtHV1P2r62goCChwaX0OhOO81wnIBGCwSBM04TH41Fy8JTq+Vdl/zfffBMbN27E3Xffjdtvvx3JycnycCKiStu3bx9mzpwJv9+PyZMno3Xr1tB1HR6PR8lH0YZhwDAMOJ1OJX8/2T+6UCiEUCgEt9ut5NjI0vk7HI6or+88q0hysbNy4lVV/b/44gvMmDEDPXv2xIQJE9C4cWN5KBFR3HJycjB37ly0a9cOkyZN4llFUcR61kxlqe7Ps4pIGb3kOi2pqam44447GFqISJn27dujX79+OHToEDZs2CCXiRKOwaUW2rRpE06dOoVBgwahXbt2cpmIKGEaNGiAHj16IBQK4ZNPPkEwGJSHECUUg0stEw6HkZ2dDb/fj44dOypZziMiOlfnzp3x61//Gv/3f/+HL774Qi4TJRSDSy2zf/9++P1+3HjjjWjfvr1cplri66+/xq233ooHHngAR44ciWx/7bXXkJaWBpvNhscffxx5eXllbkekyq9+9Ss0adIEBw4ckEtECcXgUsvs378fNpsNbdu2Rb169eQy1WKrV6/GvHnzMGTIEPh8PsydOxcpKSnyMCIl0tLS0LhxYxw8eBCnT5+Wy0QJw+BSy+zfvx92u/283yNCtZfP58O2bdsAAH369GFgoSp32WWXoXfv3rDb7di/f79cJkoYBpdaJC8vDz/++COaNWuGyy67TC5TLZaTk4OdO3diwIABuPHGG8vVbrvttshFnVq0aIFFixZF6qtXr0anTp0wbdq0yDafz4eJEyeid+/eWL9+fWT77Nmz0bBhw0iv4cOH4/Dhw0DJ82/SpEnlbrNhwwb06dMHU6dOjWyj2unSSy9FgwYN8MMPP8glooRhcKlFSq9x06xZM15srg7x+Xz4+OOPkZ+fX261Zf369Zg4cSJSU1Nx6NAhCCEwceJETJkyBbNmzSrT52KmT5+OqVOnYsqUKRBC4Ouvv8bZs2cxceJEfuEeAQCSkpIQDodRWFgol4gShsGlFikoKIDdbkejRo2iXryHao/ly5ejR48eOHbsGJYuXYohQ4aUqX/++efIz8/HHXfcgfT0dADAqFGjcM899+D9999HdnZ2mfEXsmHDBmRnZ2PkyJEYNWoUAKB79+544IEHcObMGXz22WfyTagOatCgARwOB4MLKcXgUosUFBSgoKAApmnKJaqlRowYgVWrVsEwDAwePBiLFy+O1A4fPozDhw/jiiuuQKtWrSLbU1NT0bJlS/h8Phw7diyyPZpjx44hHA4jIyMDqampke2tWrXCL37xC+Tm5sLn85W5DdU9jRs3Rr169VBQUCCXiBKGwaUWcbvdaNSoEa/dUsf06NEDEydORMuWLfH6669Hrl6al5eHvLw8pKSkxHSw7vTp0yPHrjRp0gTz58+P1PLz8/Htt9/i4Ycfjoyx2Wzo0aMHPvnkE+Tl5TG4EPx+P4qLi+FyueQSUcIwuNQiDRs2hGma8Pv9colquZtuugmDBw/Gnj17IkGiNLCUBhhZo0aN0KhRo8j/T506NfLtrGfOnMGECRPKjP/lL3+JhQsXRsac+7NixQq0adOmzHiqewKBAEzTRMOGDeUSUcIwuNQijRo1gmma+O9//8vLbtdBN9xwA66//nps2LABGzduRHp6OtLT0/H999/j6NGjkXE+nw+5ublwOBwxf49Vy5Yt4XA4cPLkyTLbS88YmjBhAldcCH6/H4ZhMLiQUgwutUjDhg1Rv359nDlzhp8x10Hdu3fHnXfeibNnz+Kjjz7C4cOH0atXLzRq1AjLli2LnPmzZMkSrF69GnfddRcGDhwotzmvIUOG4J577sGsWbMwc+ZMoOQYmuXLl0MIgdtuu63MsS9UN2maBrvdDq/XK5eIEobBpRapX78+2rZti7Nnz5Z5h011x91334277roLK1aswBtvvIGbbroJ8+bNgxACPXr0gM1mw7x58/Diiy/iySeflG8e1dSpUzF9+nS8+OKLsNlsaNOmDXw+H+bNm4ebbropMu7zzz/HoEGDIsfBDBw4EDt27MCLL77Ia7nUYkVFRdi7dy+CwSDatm0rl4kSxiaEEPLGeGiaBiEEXC4X7PbE56LSa5V4vV4kJSXJ5bhpmgbTNOFyueBwOORy3FT3X7duHVatWoXbb78dd911l1wmqhY7d+7E9OnT0aVLF0yfPl0uUy1w4MABZGVloWHDhnjppZfgdrvlIXHTdR3hcFjZ38+q6K/rOlwul5JLVqjuHwgEEAgEkJycrOQkkFjnn/hkQdWqXbt20DQNX331FY85IKIq89NPP8HhcHC1hZRjcKllLr30UvTo0QPHjx/H3r175TIRUcKdOnUKa9asQX5+PjIyMuQyUUIxuNRC/fv3h9PpxD/+8Q+cOHFCLhNVuW7duuGjjz7ix0S11IEDB5Cbm4uePXuiXbt2cpkooRhcaqG2bduib9++OHjwIHbt2iWXiYgSxu/34/PPP4cQAgMGDJDLRAnH4FJLDRgwAF6vF8uXL8fu3bvlMhFR3PLy8rBy5Urs2bMHt912G1q3bi0PIUo4W2FhYULPKio9Sclms8mlhDAMA0IIOBwOJfehev5V2X/Xrl343//9X1x66aV47LHHcOWVV8rDiYgqJRQKYf369Xj99dfRu3dvPPzwwzBNE6Zpwm63KzmrtPRKzaWn2ica+0dXU/avTdO0hAaXcDgcCRYqfrFgMAjTNOHxeJScrqZ6/lXdf/369Zg3bx5uuOEGPProozFfKZWIKJpdu3Zh9uzZuOSSS/Dcc8+hcePG0DQNuq7D7XYruVyFYRgwDANOp1PJ30/2jy4UCiEUClX7/uV1XCSqr7NSHf0/+OADvPbaa0hPT8fYsWPRsWNH+WZERDHJy8vDmjVr8Prrr6NVq1Z45plnIt9T5ff7EQwG4fV6eR2X84j1OiWVpbo/r+NCVWbw4MF49tln8e233+IPf/gDvvrqK5imKQ8jIorK7/fj73//OxYtWoQbb7wRWVlZ/HJNqnIMLnVE3759MX/+fKSkpGDs2LF48skn8dVXXyEUCslDiYjKOHXqFJYsWYLBgwdjwYIFePjhh/Hss88iJSVFHkqkHINLHdKxY0e8/vrryMrKwr/+9S/ce++9eOKJJ7B9+3YUFhbKw4mojvvhhx+wcuVKjBkzBjNnzsS1116Lt956C/fdd588lKjK8BgXyfmOEUmkmtLf7/cjOzsbb7zxBrZt24YGDRqgb9++6NChA5o1a4amTZuiXr168s2IqBYrKCjA8ePHcfLkSezcuRO7du3CZZddhsGDB+Oee+5Bp06d5JuUwWNcoov1GI7KUt2/phzjwuAiifWFv7JqYv/Tp09jx44d2LFjBw4fPowffvgBp06dijzW5yo9VU2V0qejqvuoivmr7g/Fjw+qoD8U34eq3qjF/T0eD5o1a4bmzZvjsssuQ+fOnXHLLbegffv28tALYnCJLtYX5spS3Z/BpZIYXKKzev+CggLoug6v1wuXyyWX4xYKhWAYhrL5s390RUVF0DQNycnJSl7YVM/f6v1VvzAzuEQX6wtzZanuX1OCS+KTBREREZEiDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBkMLkRERGQZDC5ERERkGQwuREREZBm2wsJCIW+MhxA/t7PZbHIpIQzDgBACDodDyX2onn9t6C+EgM1mU3IfVbF/Vc6f/aMr3b92ux12e+LfN6meP/tHZ5omTNPk/r0Aq/evKfvXpmlaQoNLOByGKHnhUfGLBYNBmKYJj8cDh8Mhl+Omev7sH11xcTEMw4Db7YbT6ZTLcVM9/6rob5omnE6nJftrmgZd1+HxeJTsX8MwYBiGsvmzf3Sl+9ftdiMpKUkux031/Nk/ulAohFAoVO371yZEyVv0BNE0DUIIuFyuqHdcWfn5+TAMA16vV8kDp2kaTNOEy+VSEozYP7qCggLoug6v1wuXyyWX4xYKhWAYhrL5s390RUVF0DQNycnJcLvdcjluqudv9f66riMcDivr7/f7EQwG4fV6lexf1fOviv66rsPlcikJ7qr7BwIBBAIBJCcnw+PxyOW4xTr/xCcLIiIiIkUYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMhhciIiIyDIYXIiIiMgyGFyIiIjIMmyFhYVC3hgPIX5uZ7PZ5FJCGIYBIQQcDoeS+1A9/9rQXwgBm82m5D6qYv+qnD/7R1e6f+12O+z2xL9vUj1/9o/ONE2Ypsn9ewFW719T9q9N07SEBpdwOAxR8sKj4hcLBoMwTRMejwcOh0Mux031/Nk/uuLiYhiGAbfbDafTKZfjpnr+VdHfNE04nU5L9tc0Dbquw+PxKNm/hmHAMAxl82f/6Er3r9vtRlJSklyOm+r5s390oVAIoVCo2vevTYiSt+gJomkahBBwuVxR77iy8vPzYRgGvF6vkgdO0zSYpgmXy6UkGLF/dAUFBdB1HV6vFy6XSy7HLRQKwTAMZfNn/+iKioqgaRqSk5PhdrvlctxUz9/q/XVdRzgcVtbf7/cjGAzC6/Uq2b+q518V/XVdh8vlUhLcVfcPBAIIBAJITk6Gx+ORy3GLdf6JTxZEREREijC4EBERkWUwuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFlMLgQERGRZTC4EBERkWUwuBAREZFl2AoLC4W8MR5C/NzOZrPJpYQwDANCCDgcDiX3oXr+taG/EAI2m03JfVTF/lU5f/aPrnT/2u122O2Jf9+kev7sH51pmjBNk/v3Aqzev6bsX5umaQkNLuFwGKLkhUfFLxYMBmGaJjweDxwOh1yOm+r5s390xcXFMAwDbrcbTqdTLsdN9fyror9pmnA6nZbsr2kadF2Hx+NRsn8Nw4BhGMrmz/7Rle5ft9uNpKQkuRw31fNn/+hCoRBCoVC171+bECVv0RNE0zQIIeByuaLecWXl5+fDMAx4vV4lD5ymaTBNEy6XS0kwYv/oCgoKoOs6vF4vXC6XXI5bKBSCYRjK5s/+0RUVFUHTNCQnJ8PtdsvluKmev9X767qOcDisrL/f70cwGITX61Wyf1XPvyr667oOl8ulJLir7h8IBBAIBJCcnAyPxyOX4xbr/BOfLIiIiIgUYXAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIstgcCEiIiLLYHAhIiIiy2BwISIiIsv4//3Cn/y0EDxVAAAAAElFTkSuQmCC" + } + }, + "cell_type": "markdown", + "id": "be048f2c", + "metadata": {}, + "source": [ + "1.5.1. Ответьте на вопросы\n", + "\n", + "1. Какие предметные области входят в Data Science? Что между ними общего и\n", + "в чем различие?\n", + "\n", + "Программирование\n", + "Статистика\n", + "Базы данных\n", + "Моделирование\n", + "\n", + "Общее - работа с данными как с основным объектом\n", + "Различия - фокус на разных моментах, разные выходные данные и задачи которые они решают\n", + "\n", + "2. Как вы понимаете термин «алгоритм»? Как алгоритмы связаны с блок-схемами?\n", + "\n", + "Алгоритм - конечная последовательность четко определенных,\n", + "реализуемых компьютером инструкций для решения какой-то проблемы\n", + "\n", + "Иногда алгоритмы изображаются в графической форме, используя определенные обозначения,\n", + "графический вид алгоритма и есть блок-схема\n", + "\n", + "3. Какую программу можно назвать хорошей? Запишите все характеристики, какие\n", + "удастся придумать.\n", + "\n", + "Хорошая программа обладает следующими характеристиками: корректностью, надёжностью, читаемостью, \n", + "поддерживаемостью, тестируемостью, эффективностью, безопасностью, удобством использования, \n", + "расширяемостью, переносимостью и соблюдением принятых стандартов кодирования.\n", + "\n", + "4. Какой язык понимает компьютер?\n", + "\n", + "Машинный код\n", + "\n", + "5. Чем языки программирования отличаются от языков, на которых мы говорим?\n", + "\n", + "Языки программирования строго формализованы, однозначны и предназначены для общения с машиной, \n", + "тогда как естественные языки гибкие, многозначные и служат для общения между людьми.\n", + "\n", + "\n", + "1.5.2. Правда или ложь\n", + "\n", + "1. Машинное обучение - это инструмент для извлечения знаний из данных.\n", + "Правда\n", + "\n", + "2. Глубокое обучение - это то же самое, что машинное обучение.\n", + "Ложь, глубокое обучение — подмножество машинного обучения\n", + "\n", + "3. Все инженеры-программисты также могут считаться специалистами по данным.\n", + "Ложь \n", + "\n", + "4. Статистика - важный инструмент для специалистов по данным.\n", + "Правда\n", + "\n", + "5. Компьютер может принимать решения, выходящие за рамки данных ему инструкций,\n", + "подстраиваясь под изменения среды.\n", + "Ложь, строго по заданной инструкции\n", + "\n", + "6. Компьютеры понимают языки программирования «как есть».\n", + "Ложь, компьютер «понимает» только машинный код; языки программирования преобразуются \n", + "в него с помощью компиляторов/интерпретаторов\n", + "\n", + "7. Некоторые языки программирования компилируются, некоторые интерпретируются,\n", + "а некоторые используют и то и другое.\n", + "Правда\n", + "\n", + "8. Все программы выполняются последовательно.\n", + "Правда\n", + "\n", + "9. В IDЕ есть встроенный текстовый редактор.\n", + "Правда\n", + "\n", + "10. Компиляторы и интерпретаторы - это такие механизмы, наподобие привода\n", + "для компакт-дисков.\n", + "Ложь\n", + "\n", + "\n", + "1.5.3. Практические задания\n", + "\n", + "1. Напишите алгоритм для расчета простых процентов от некоторой суммы.\n", + "Шаг 1. Начало\n", + "Шаг 2. Введите число, сумму, от которой будет браться процент и сохраните ее в start_sum\n", + "Шаг 3. Введите число, процент, который будет браться от суммы и сохраните ее в percent\n", + "Шаг 4. Проведите вычисление, start_sum / 100 * percent и сохраним ее в final_percent\n", + "Шаг 5. Выведите final_percent\n", + "Шаг 6. Конец\n", + "\n", + "2. Напишите алгоритм для вычисления площади прямоугольника.\n", + "Шаг 1. Начало\n", + "Шаг 2. Введите число, ширину, сохраните в rectangular_width\n", + "Шаг 3. Введите число, длину, сохраните в rectangular_height\n", + "Шаг 4. Проведите вычисление height * width и сохраните в rectangular_area\n", + "Шаг 5. Выведите rectangular_area\n", + "Шаг 6. Конец\n", + "\n", + "3. Напишите алгоритм вычисления периметра круга.\n", + "Шаг 1. Начало\n", + "Шаг 2. Введите число, радиус, сохраните в circle_radius\n", + "Шаг 3. Проведите вычисление 2 * \\Pi * circle_radius, сохраните в circle_area\n", + "Шаг 4. Выведите circle_area\n", + "Шаг 5. Конец\n", + "\n", + "4. Напишите алгоритм, который находит все простые числа меньше 100.\n", + "Шаг 1. Начало \n", + "Шаг 2. Создайте список всех простых чисел от 2 до 100 не включительно\n", + "Шаг 3. Берем первое число в созданном списке записываем в simple_digit\n", + "Шаг 4. Выводим simple_digit\n", + "Шаг 5. Удаляем simple_digit из списка\n", + "Шаг 6. Удаляем все числа кратные simple_digit\n", + "Шаг 7. Возвращаемся к шагу 3\n", + "Шаг 8. Конец\n", + "\n", + "5. Напишите алгоритм превращения предложения, написанного в верхнем регистре,\n", + "в обычный для предложений регистр.\n", + "Шаг 1. Начало\n", + "Шаг 2. Создайте переменную index и присваиваем значение 1\n", + "Шаг 3. Проведите вычисление index + 1\n", + "Шаг 4. Поменяйте регистр буквы номер index с верхнего на нижний\n", + "Шаг 5. Проверьте что значение index не больше длинны предложения если больше то перейдите к шагу 6\n", + "если меньше то перейдите к шагу 3\n", + "Шаг 6. Конец\n", + "\n", + "6. Составьте блок-схему приготовления льда из кипяченой воды с помощью холодильника.\n", + "\n", + "![image.png](attachment:image.png)\n", + "\n", + "7. Составьте блок-схему для нахождения суммы всех четных чисел меньше ста.\n", + "\n", + "![image-3.png](attachment:image-3.png)\n", + "\n", + "8. Составьте блок-схему для вычисления квадрата всех нечетных чисел от 1 до 15\n", + "включительно.\n", + "\n", + "![image-4.png](attachment:image-4.png)\n", + "\n", + "9. Составьте блок-схему вывода таблицы умножения на 3.\n", + "\n", + "![Снимок экрана 2025-10-05 185114.png]()\n", + "\n", + "10. Составьте блок-схему для расчета сложных процентов (с капитализацией).\n", + "\n", + "![image-5.png](attachment:image-5.png)" + ] + }, + { + "cell_type": "markdown", + "id": "c82b1ab7", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/made-easy/chapter_2_introduction_to_python.ipynb b/python_issue/made-easy/chapter_2_introduction_to_python.ipynb new file mode 100644 index 00000000..3d034b6e --- /dev/null +++ b/python_issue/made-easy/chapter_2_introduction_to_python.ipynb @@ -0,0 +1,242 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "40e03519", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Introduction to Python.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "4d7c871a", + "metadata": {}, + "source": [ + "# Введение в Python\n", + "\n", + "\n", + "**Python** - это бесплатный интерпретируемый высокоуровневый язык программирования\n", + "общего назначения с открытым исходным кодом.\n", + "\n", + "Что касается популярности, то самыми популярными языками программирования\n", + "для специалистов по данным являются:\n", + "- Python \n", + "- С++\n", + "- R \n", + "- Java\n", + "- SQL \n", + "- Matlab\n", + "\n", + "\n", + "Программы, написанные на Python, обычно намного короче таких же программ на С, С++ или Java\n", + "по нескольким причинам.\n", + "- Типы данных высокого уровня позволяют записывать сложные операции в одну\n", + "строку.\n", + "\n", + "- Группировка операторов выполняется с помощью отступов, а не с помощью\n", + "скобок в начале и конце блока.\n", + "\n", + "- Объявление переменных или аргументов не требуется.\n", + "\n", + "\n", + "## Философия Python\n", + "\n", + "\n", + "- Красивое лучше, чем уродливое.\n", + "- Явное лучше, чем неявное.\n", + "- Простое лучше, чем сложное.\n", + "- Сложное лучше, чем запутанное.\n", + "- Читаемость имеет значение.\n", + "\n", + "\n", + "## Преимущества Python\n", + "\n", + "\n", + "- Простота\n", + "- Легкость в изучении\n", + "- Свободны й и открытый исходный код\n", + "- Высокоуровневость \n", + "- Портативность\n", + "- Интерпретируемость\n", + "- Объектная ориентированность\n", + "- Расширяемость \n", + "- Встраиваемость\n", + "- Внушительные библиотеки\n", + "\n", + "\n", + "## Дистрибутив Anaconda\n", + "\n", + "\n", + "Anaconda - это самый простой и наиболее часто используемый способ\n", + "установки Python и других необходимых пакетов. Он находится в свободном\n", + "доступе и прост в установке.\n", + "\n", + "Он является отраслевым стандартом в области разработки, тестирования\n", + "и машинного обучения и позволяет специалистам по данным:\n", + "- быстро загрузить более 1 500 пакетов Python/R, предназначенных для задач анализа\n", + "данных;\n", + "\n", + "- управлять библиотеками, зависимостями и средами с помощью Conda;\n", + "\n", + "- разрабатывать и обучать модели машинного обучения и глубокого обучения\n", + "с помощью пакетов Scikit-leam, TensorFlow и Theano;\n", + "\n", + "- выполнять эффективный и масштабируемый анализ данных с помощью Dask,\n", + "NumPy, Pandas и Numba;\n", + "\n", + "- визуализировать результаты с помощью Matplotlib, Bokeh, Datashader и Holoviews.\n", + "\n", + "\n", + "## Запуск Python через командную строку\n", + "\n", + "\n", + "Командная строка - это приложение, которое позволяет запускать команды для\n", + "просмотра папок и файлов, выполнения скриптов и, конечно, для работы с Python.\n", + "\n", + "Консоль (она же терминШL или командная строка) - это текстовый способ взаимодействия\n", + "с вашей ОС, точно такой же, по существу, как рабочий стол и мышь,\n", + "которые тоже являются способом взаимодействия с системой.\n", + "\n", + "\n", + "## Jupyter Notebook\n", + "\n", + "\n", + "**Jupyter Notebook** - это интерактивная вычислительная веб-платформа. В ее документах\n", + "сочетаются выполняемый код, математические уравнения, обычный\n", + "текст, средства визуализации, интерактивные информационные панели и другие\n", + "мультимедийные средства. Этот инструмент становится очень полезным, когда необходимо\n", + "опубликовать результаты анализа данных (а это нужно в большинстве\n", + "случаев). Здесь вы можете писать код и документацию, создавать диаграммы и\n", + "давать пояснения - и все в одном месте.\n", + "\n", + "Этот редактор расширяет консольный подход к интерактивным вычислениям в качественно\n", + "новом направлении и сконструирован как веб-приложение, подходящее\n", + "для записи всего вычислительного процесса: разработки, документирования и выполнения\n", + "кода, а также передачи результатов. Jupyter Notebook объединяет в себе\n", + "два компонента:\n", + "\n", + "- веб-приложение - инструмент на основе браузера, предназначенный для интерактивного\n", + "создания документов, сочетающий в себе пояснительный текст,\n", + "математические вычисления и мультимедийный вывод результатов;\n", + "\n", + "- документы Notebook, содержащие все видимое в веб-браузере, включая входные\n", + "и выходные данные вычислений, пояснительный текст, математические данные,\n", + "изображения и мультимедийные представления объектов." + ] + }, + { + "cell_type": "markdown", + "id": "1abdb5b2", + "metadata": {}, + "source": [ + "2.12.1. Ответьте на вопросы\n", + "\n", + "1. Python - это программное обеспечение с открытым исходным кодом. Это то\n", + "же самое, что и бесплатное ПО?\n", + "Открытый исходный код позволяет гибко настраивать его под себя, пользователи могут изучать,\n", + "изменять и распространять его. Если говорить о бесплатном ПО, то это верно для питона, но\n", + "тут слово free скорее используется в значении свободный\n", + "\n", + "2. У всех ли бесплатных программ открытый исходный код? А если нет, то в чем\n", + "разница?\n", + "Нет не у всех бесплатных программ открытый исходный код, опять же тут идет разница между\n", + "freeware и free software, бесплатное не означает открытое\n", + "\n", + "3. Python поддерживает динамическую типизацию. Что это такое?\n", + "В Python значение, на которое указывает переменная, имеет определенный тип\n", + "данных, но сама переменная не имеет строгого типа.\n", + "\n", + "4. Назовите 5 самых популярных языков программирования для специалистов по\n", + "анализу данных.\n", + "Python, R, SQL, C++, Java, Matlab\n", + "\n", + "5. В чем заключается преимущество Python по сравнению с языком С?\n", + "Преимущество Python перед языком C заключается в его простоте, читаемости и высокой \n", + "производительности разработки: Python позволяет писать меньше кода для решения той же \n", + "задачи благодаря высокоуровневым конструкциям и богатой стандартной библиотеке. \n", + "В то время как C требует ручного управления памятью и более детального описания процессов, \n", + "Python автоматизирует многие низкоуровневые операции, что ускоряет написание и отладку программ, \n", + "особенно в областях вроде анализа данных, веб-разработки и машинного обучения.\n", + "\n", + "6. Python портативен. Что в этом контексте означает «портативность»?\n", + "Python можно использовать на разных типах машин,\n", + "независимо от аппаратных средств или ограничений операционной системы\n", + "\n", + "7. В чем разница между «расширяемым» и «встраиваемым» языком?\n", + "Расширяемый язык можно дополнить кодом на другом языке программирования\n", + "Встраиваемый язык можно добавить в программу на другом языке программирования\n", + "\n", + "8. В чем смысл IDE? Чем она отличается от командной строки?\n", + "IDE — это полный рабочий стол программиста со всеми удобствами, \n", + "а командная строка — инструмент для выполнения команд, без встроенной поддержки разработки\n", + "\n", + "9. Как открыть существующий документ Jupyter Notebook? Чем эта процедура отличается\n", + "от открытия РDF-файла или текстового файла?\n", + "- Запустить Jupyter Notebook или JupyterLab из командной строки \n", + "(например, командой `jupyter notebook` или `jupyter lab`).\n", + "- В открывшемся веб-интерфейсе (в браузере) перейти в папку, где находится нужный .ipynb-файл.\n", + "- Кликнуть по имени файла — он откроется в интерактивной среде, \n", + "где можно запускать ячейки кода, редактировать их и видеть результаты выполнения.\n", + "\n", + "\n", + "10. В чем разница между «ячейками разметки Markdown» и «ячейками кода»\n", + "в Jupyter Notebook? Для чего они нужны?\n", + "Ячейка кода позволяет редактировать и писать новый код с выделением синтаксиса\n", + "цветом и заполнением табуляцией. Используемый вами язык программирования\n", + "зависит от ядра, а ядро по умолчанию (IPython) запускает код Python.\n", + "\n", + "Язык Markdown - это простой способ выполнить разметку\n", + "текста и указать, какой текст нужно выделить курсивом, какой жирным шрифтом,\n", + "где вставить список и т. д.\n", + "При выполнении ячейки Markdown разметка Markdown преобразуется в соответствующий\n", + "форматированный текст. Markdown также допускает форматирование\n", + "с помощью НТМL-кода.\n", + "\n", + "\n", + "2.12.2. Правда или ложь\n", + "\n", + "1. Язык программирования Python был назван в честь змеи питон.\n", + "Ложь, назван в честь шоу «Летающий цирк Монти Пайтона»\n", + "\n", + "2. Python - это высокоуровневый язык общего назначения.\n", + "Правда\n", + "\n", + "3. Python компилируется и не интерпретируется.\n", + "Ложь, Python — интерпретируемый язык\n", + "\n", + "4. В Python команда два + два вернет Четыре.\n", + "Правда, 2 + 2 выведет 4, если написать словами то получится \"двадва\"\n", + "\n", + "5. Консоль IPython аналогична окну командной строки.\n", + "Правда\n", + "\n", + "6. Графики, выводимые в документе Jupyter Notebook, отображаются внутри\n", + "самого документа.\n", + "Правда\n", + "\n", + "7. В комплекте с пакетом Aлaconda идут браузеры Chrome и Firefox.\n", + "Ложь\n", + "\n", + "8. «Простое лучше, чем сложное» - это одна из философий Python.\n", + "Правда\n", + "\n", + "9. Аббревиатура FLOSS означает «Free/Libre and Open Source Software».\n", + "Правда\n", + "\n", + "10. Python поддерживает ТОЛЬКО объектно-ориентированное программирование.\n", + "Ложь, Python — мультипарадигменный язык\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_10_numpy_array.ipynb b/python_issue/makarov/chapter_10_numpy_array.ipynb new file mode 100644 index 00000000..da780954 --- /dev/null +++ b/python_issue/makarov/chapter_10_numpy_array.ipynb @@ -0,0 +1,2047 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "9adc4b1f", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Numpy array.\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b082256", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from scipy.sparse import csr_matrix" + ] + }, + { + "cell_type": "markdown", + "id": "4f18c278", + "metadata": {}, + "source": [ + "## Массив Numpy" + ] + }, + { + "cell_type": "markdown", + "id": "f2dd31db", + "metadata": {}, + "source": [ + "### Как создать массив Numpy" + ] + }, + { + "cell_type": "markdown", + "id": "635ae0e3", + "metadata": {}, + "source": [ + "#### Функция np.array()\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f146833", + "metadata": {}, + "outputs": [], + "source": [ + "arr_list: np.ndarray = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0])\n", + "print(arr_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "84a03c7a", + "metadata": {}, + "outputs": [], + "source": [ + "arr_tuple: np.ndarray = np.array((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0))\n", + "print(arr_tuple)" + ] + }, + { + "cell_type": "markdown", + "id": "857e00aa", + "metadata": {}, + "source": [ + "#### Функция np.arange()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "84b7a77c", + "metadata": {}, + "outputs": [], + "source": [ + "arr_range_full: np.ndarray = np.arange(10)\n", + "print(arr_range_full)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4877d3e", + "metadata": {}, + "outputs": [], + "source": [ + "arr_main: np.ndarray = np.arange(2, 10, 2)\n", + "print(arr_main)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ee6dc79", + "metadata": {}, + "outputs": [], + "source": [ + "# в arange() тип float допускается\n", + "print(np.arange(2, 5.5, 0.5))" + ] + }, + { + "cell_type": "markdown", + "id": "c87e9529", + "metadata": {}, + "source": [ + "#### Тип данных элементов массива\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95ee1358", + "metadata": {}, + "outputs": [], + "source": [ + "# Можно указать явно тип данных массива\n", + "arr_f: np.ndarray = np.array((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0), float)\n", + "print(arr_f)\n", + "print(arr_f.dtype)" + ] + }, + { + "cell_type": "markdown", + "id": "97e45dfe", + "metadata": {}, + "source": [ + "### Свойства (атрибуты) массива\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49623ec1", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_main)" + ] + }, + { + "cell_type": "markdown", + "id": "6991cd42", + "metadata": {}, + "source": [ + "#### Количество измерений\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6cce899", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_main.ndim)" + ] + }, + { + "cell_type": "markdown", + "id": "480a8d66", + "metadata": {}, + "source": [ + "#### Количество элементов в каждом измерении\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c772f54", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_main.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "ab5a56d4", + "metadata": {}, + "source": [ + "#### Общее количество элементов во всех измерениях\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b262ea03", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_main.size)" + ] + }, + { + "cell_type": "markdown", + "id": "cf847aac", + "metadata": {}, + "source": [ + "#### Tип данных массива\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "111810ac", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_main.dtype)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42a0cbfa", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_main.nbytes)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "200931d9", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_main.size * arr_main.itemsize)" + ] + }, + { + "cell_type": "markdown", + "id": "4f2742fd", + "metadata": {}, + "source": [ + "### Измерения массива\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "3c3512b6", + "metadata": {}, + "source": [ + "#### Массив с нулевым измерением" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec394d18", + "metadata": {}, + "outputs": [], + "source": [ + "arr_0d_scalar: np.ndarray = np.array(42)\n", + "print(arr_0d_scalar.ndim)\n", + "print(arr_0d_scalar.shape)\n", + "print(arr_0d_scalar.size)" + ] + }, + { + "cell_type": "markdown", + "id": "0ca94abb", + "metadata": {}, + "source": [ + "#### Одномерный массив (вектор)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ebae8616", + "metadata": {}, + "outputs": [], + "source": [ + "arr_1d_vector: np.ndarray = np.array([42, 15, 52, 63, 94])\n", + "print(arr_1d_vector.ndim)\n", + "print(arr_1d_vector.shape)\n", + "print(arr_1d_vector.size)" + ] + }, + { + "cell_type": "markdown", + "id": "c7e717a2", + "metadata": {}, + "source": [ + "#### Двумерный массив (матрица)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39c78abf", + "metadata": {}, + "outputs": [], + "source": [ + "arr_2d_matrix: np.ndarray = np.array([[42, 15, 52, 63], [94, 22, 53, 15]])\n", + "print(arr_2d_matrix.ndim)\n", + "print(arr_2d_matrix.shape)\n", + "print(arr_2d_matrix.size)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fa8e0f08", + "metadata": {}, + "outputs": [], + "source": [ + "# такая матрица имеет три строки с один элементом в каждой\n", + "column: np.ndarray = np.array([[1], [2], [3]])\n", + "print(column)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d301cc84", + "metadata": {}, + "outputs": [], + "source": [ + "print(column.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1485e2dd", + "metadata": {}, + "outputs": [], + "source": [ + "# такая матрица имеет три строки с один элементом в каждой\n", + "row: np.ndarray = np.array([[1, 2, 3]])\n", + "print(row)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4881f79a", + "metadata": {}, + "outputs": [], + "source": [ + "print(row.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "cce5b092", + "metadata": {}, + "source": [ + "#### Трехмерный массив\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81dc8b75", + "metadata": {}, + "outputs": [], + "source": [ + "arr_3d_info: np.ndarray = np.arange(12).reshape(2, 2, 3)\n", + "print(arr_3d_info)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "caf9a0d7", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_3d_info.ndim)\n", + "print(arr_3d_info.shape)\n", + "print(arr_3d_info.size)" + ] + }, + { + "cell_type": "markdown", + "id": "b867b14b", + "metadata": {}, + "source": [ + "### Другие способы создания массивов\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "2eb476d7", + "metadata": {}, + "source": [ + "#### Функция np.zeros()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d380d7f1", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.zeros(5))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ba6ab17", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.zeros((2, 3)))" + ] + }, + { + "cell_type": "markdown", + "id": "8f03ede7", + "metadata": {}, + "source": [ + "#### Функция np.ones()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e075de77", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.ones((2, 3)))" + ] + }, + { + "cell_type": "markdown", + "id": "41a7b2f6", + "metadata": {}, + "source": [ + "#### Функция np.full()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8677a3d4", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.full((2, 3), 4))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "deea9c21", + "metadata": {}, + "outputs": [], + "source": [ + "# Функция np.empty()\n", + "print(np.empty((3, 2)))" + ] + }, + { + "cell_type": "markdown", + "id": "ff61f842", + "metadata": {}, + "source": [ + "#### Функции np.zeros_like(), np.ones_like(), np.full_like(), np.empty_like()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3d81a836", + "metadata": {}, + "outputs": [], + "source": [ + "base_matrix: np.ndarray = np.arange(1, 7).reshape(2, 3)\n", + "print(base_matrix)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e2cfeb7", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.zeros_like(base_matrix))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6a6300b", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.ones_like(base_matrix))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43a1428e", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.full_like(base_matrix, 10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2f63ec79", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.empty_like(base_matrix))" + ] + }, + { + "cell_type": "markdown", + "id": "21236b83", + "metadata": {}, + "source": [ + "#### Функция np.linspspace()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "930f0d96", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.linspace(0, 0.9, 10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a274c17e", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.arange(0, 1, 0.1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bda737a5", + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure(figsize=(8, 6))\n", + "\n", + "x_line: np.ndarray = np.linspace(-5, 5, 5000)\n", + "y_parabola: np.ndarray = x_line**2\n", + "\n", + "plt.grid()\n", + "\n", + "plt.plot(x_line, y_parabola)\n", + "\n", + "plt.xlabel(\"x\", fontsize=14)\n", + "plt.ylabel(\"y\", fontsize=14)\n", + "\n", + "plt.show()\n", + "\n", + "print(x_line[:10])" + ] + }, + { + "cell_type": "markdown", + "id": "8770383f", + "metadata": {}, + "source": [ + "#### Функции np.random.rand() и np.random.randint()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34298de1", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.random.rand(4, 3))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b928c2df", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.random.randint(-3, 3, size=(2, 3, 2)))" + ] + }, + { + "cell_type": "markdown", + "id": "d6b4890e", + "metadata": {}, + "source": [ + "#### np.fromfunction()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "93da96a9", + "metadata": {}, + "outputs": [], + "source": [ + "def power(base_val: float, exp_val: float) -> float:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " return float(base_val**exp_val)\n", + "\n", + "\n", + "print(np.fromfunction(power, (3, 3)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fea98818", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.fromfunction(lambda row_idx, col_idx: row_idx == col_idx, (3, 3)))" + ] + }, + { + "cell_type": "markdown", + "id": "e3ed3ff4", + "metadata": {}, + "source": [ + "### Матрица в формате csr и метод .toarray()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "d28a3f91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[2 0 0 1 0 0 0]\n", + " [0 0 3 0 0 2 0]\n", + " [0 0 0 1 0 0 0]]\n" + ] + } + ], + "source": [ + "matrix_sparse_data: np.ndarray = np.array(\n", + " [[2, 0, 0, 1, 0, 0, 0], [0, 0, 3, 0, 0, 2, 0], [0, 0, 0, 1, 0, 0, 0]]\n", + ")\n", + "print(matrix_sparse_data)" + ] + }, + { + "cell_type": "markdown", + "id": "d064a487", + "metadata": {}, + "source": [ + "#### Доля нулевых значений\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55d4dbe4", + "metadata": {}, + "outputs": [], + "source": [ + "print(1.0 - np.count_nonzero(matrix_sparse_data) / matrix_sparse_data.size)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "e8ad46f3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Coords\tValues\n", + " (0, 0)\t2\n", + " (0, 3)\t1\n", + " (1, 2)\t3\n", + " (1, 5)\t2\n", + " (2, 3)\t1\n" + ] + } + ], + "source": [ + "csr_matrix_data: csr_matrix = csr_matrix(matrix_sparse_data)\n", + "\n", + "print(csr_matrix_data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1814b72d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "numpy.ndarray" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dense_data: np.ndarray = csr_matrix_data.toarray()\n", + "print(dense_data)" + ] + }, + { + "cell_type": "markdown", + "id": "31674114", + "metadata": {}, + "source": [ + "### Индексы и срезы\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "c1821b55", + "metadata": {}, + "source": [ + "#### Индекс элемента массива" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4a7a2a1e", + "metadata": {}, + "outputs": [], + "source": [ + "matrix_2x3: np.ndarray = np.array([[1, 2, 3], [4, 5, 6]])\n", + "print(matrix_2x3)\n", + "print(matrix_2x3.shape)\n", + "print(matrix_2x3[0])\n", + "print(matrix_2x3[0][0])\n", + "print(matrix_2x3[0][1])" + ] + }, + { + "cell_type": "markdown", + "id": "ffbba8e8", + "metadata": {}, + "source": [ + "### Срез массива\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "01ada51e", + "metadata": {}, + "source": [ + "#### Массив 1D" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ff9dcc21", + "metadata": {}, + "outputs": [], + "source": [ + "vector_1_to_8: np.ndarray = np.arange(1, 9)\n", + "print(vector_1_to_8)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92fdb43f", + "metadata": {}, + "outputs": [], + "source": [ + "print(vector_1_to_8[1:6:2])" + ] + }, + { + "cell_type": "markdown", + "id": "e726ea83", + "metadata": {}, + "source": [ + "#### Массив 2D\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a29c0756", + "metadata": {}, + "outputs": [], + "source": [ + "matrix_2x4: np.ndarray = np.arange(1, 9).reshape(2, 4)\n", + "print(matrix_2x4)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3eb112fc", + "metadata": {}, + "outputs": [], + "source": [ + "print(matrix_2x4[0, :2])\n", + "print(matrix_2x4[:, 1])\n", + "print(matrix_2x4[0, 0])\n", + "print(matrix_2x4[-1, -1])\n", + "print(matrix_2x4[1, ::2])" + ] + }, + { + "cell_type": "markdown", + "id": "668a6d75", + "metadata": {}, + "source": [ + "#### Массив 3D\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9531560", + "metadata": {}, + "outputs": [], + "source": [ + "tensor_4x2x2: np.ndarray = np.arange(16).reshape(4, 2, -1)\n", + "print(tensor_4x2x2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d24d255a", + "metadata": {}, + "outputs": [], + "source": [ + "print(tensor_4x2x2[2][1][0])\n", + "print()\n", + "print(tensor_4x2x2[2:, 1, :])\n", + "print()\n", + "print(tensor_4x2x2[:2])\n", + "print()\n", + "print(tensor_4x2x2[:, 0, :])" + ] + }, + { + "cell_type": "markdown", + "id": "417d7416", + "metadata": {}, + "source": [ + "### Оси массива\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "1a233624", + "metadata": {}, + "source": [ + "#### Массив 2D" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f48c1a6", + "metadata": {}, + "outputs": [], + "source": [ + "arr_2d_sum: np.ndarray = np.array([[1, 2], [3, 4]])\n", + "print(arr_2d_sum)\n", + "print(arr_2d_sum.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20a6b66b", + "metadata": {}, + "outputs": [], + "source": [ + "# Сложение вдоль первой оси (axis = 0)\n", + "print(np.sum(arr_2d_sum, axis=0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39787ce6", + "metadata": {}, + "outputs": [], + "source": [ + "# Сложение вдоль второй оси (axis = 1)\n", + "print(np.sum(arr_2d_sum, axis=1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dfbf2c20", + "metadata": {}, + "outputs": [], + "source": [ + "# Сложение вдоль обеих осей (axis = (0, 1))\n", + "print(np.sum(arr_2d_sum, axis=(0, 1)))\n", + "print(np.sum(arr_2d_sum))\n", + "print(np.sum(arr_2d_sum, axis=None))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5d817bce", + "metadata": {}, + "outputs": [], + "source": [ + "# Отрицательные значения в параметре axis\n", + "print(np.sum(arr_2d_sum, axis=-1))\n", + "print(np.sum(arr_2d_sum, axis=-2))" + ] + }, + { + "cell_type": "markdown", + "id": "ec051340", + "metadata": {}, + "source": [ + "### Массив 3D\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33e03788", + "metadata": {}, + "outputs": [], + "source": [ + "arr_3d_sum: np.ndarray = np.arange(12).reshape(2, 2, 3)\n", + "print(arr_3d_sum)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8d4aad3", + "metadata": {}, + "outputs": [], + "source": [ + "# применим np.sum() с параметром axis = 0\n", + "print(np.sum(arr_3d_sum, axis=0)) # ==\n", + "print()\n", + "print(arr_3d_sum[0])\n", + "print()\n", + "print(arr_3d_sum[1])\n", + "print()\n", + "print(arr_3d_sum[0] + arr_3d_sum[1]) # ==" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "06b9181d", + "metadata": {}, + "outputs": [], + "source": [ + "sum_axis0: np.ndarray = np.zeros((2, 3))\n", + "\n", + "for row_idx in range(2):\n", + " sum_axis0 += arr_3d_sum[row_idx]\n", + "\n", + "print(sum_axis0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a0cc8f3", + "metadata": {}, + "outputs": [], + "source": [ + "# Сложение вдоль второй оси (axis = 1)\n", + "print(np.sum(arr_3d_sum, axis=1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e76522b", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_3d_sum[0][0] + arr_3d_sum[0][1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bccb425b", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_3d_sum[1][0] + arr_3d_sum[1][1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2977ee73", + "metadata": {}, + "outputs": [], + "source": [ + "sum_axis1: np.ndarray = np.zeros((2, 3))\n", + "\n", + "for row_idx in range(2):\n", + " for col_idx in range(2):\n", + " sum_axis1[row_idx] += arr_3d_sum[row_idx][col_idx]\n", + "\n", + "print(sum_axis1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b255202a", + "metadata": {}, + "outputs": [], + "source": [ + "# Сложение вдоль третьей оси (axis = 2)\n", + "print(np.sum(arr_3d_sum, axis=2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "099532a6", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_3d_sum[0][0][0] + arr_3d_sum[0][0][1] + arr_3d_sum[0][0][2])\n", + "print(arr_3d_sum[0][1][0] + arr_3d_sum[0][1][1] + arr_3d_sum[0][1][2])\n", + "print(arr_3d_sum[1][0][0] + arr_3d_sum[1][0][1] + arr_3d_sum[1][0][2])\n", + "print(arr_3d_sum[1][1][0] + arr_3d_sum[1][1][1] + arr_3d_sum[1][1][2])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b2a6dac", + "metadata": {}, + "outputs": [], + "source": [ + "sum_axis2: np.ndarray = np.zeros((2, 2))\n", + "\n", + "for plane_idx in range(2):\n", + " for row_idx in range(2):\n", + " for value in arr_3d_sum[plane_idx][row_idx]:\n", + " sum_axis2[plane_idx][row_idx] += value\n", + "\n", + "print(sum_axis2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91faf631", + "metadata": {}, + "outputs": [], + "source": [ + "print(arr_3d_sum)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "68b25859", + "metadata": {}, + "outputs": [], + "source": [ + "# Сложение вдоль первой и второй осей (axis = (0, 1))\n", + "print(np.sum(arr_3d_sum, axis=(0, 1))) # ==" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3d285ca3", + "metadata": {}, + "outputs": [], + "source": [ + "sum_axes0_1: np.ndarray = np.zeros((2, 3))\n", + "\n", + "for plane_idx in range(2):\n", + " sum_axes0_1 += arr_3d_sum[plane_idx]\n", + "\n", + "print(sum_axes0_1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b0edd558", + "metadata": {}, + "outputs": [], + "source": [ + "sum_axis0_after: np.ndarray = np.zeros(3)\n", + "\n", + "for row_idx in range(2):\n", + " sum_axis0_after += sum_axes0_1[row_idx]\n", + "\n", + "print(sum_axis0_after)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e639ceb7", + "metadata": {}, + "outputs": [], + "source": [ + "sum_axis_all: np.ndarray = np.zeros(3)\n", + "\n", + "for plane_idx in range(2):\n", + " for row_idx in range(2):\n", + " sum_axis_all += arr_3d_sum[plane_idx][row_idx]\n", + "\n", + "print(sum_axis_all)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ffdecaab", + "metadata": {}, + "outputs": [], + "source": [ + "# Сложение вдоль всех трех осей (axis = (0, 1, 2))\n", + "print(np.sum(arr_3d_sum, axis=(0, 1, 2))) # ==\n", + "print(np.sum(arr_3d_sum)) # ==" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "06b844ff", + "metadata": {}, + "outputs": [], + "source": [ + "sum_axis_all_int: int = 0\n", + "\n", + "for plane_idx in range(2):\n", + " for row_idx in range(2):\n", + " for depth_idx in range(3):\n", + " sum_axis_all_int += arr_3d_sum[plane_idx][row_idx][depth_idx]\n", + "\n", + "print(sum_axis_all_int)" + ] + }, + { + "cell_type": "markdown", + "id": "80b183af", + "metadata": {}, + "source": [ + "### Операции с массивами\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "6b75f63e", + "metadata": {}, + "source": [ + "#### Функция len()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a5af8b4", + "metadata": {}, + "outputs": [], + "source": [ + "arr_3d_reshape: np.ndarray = np.arange(12).reshape(2, 2, -1)\n", + "print(arr_3d_reshape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "302b8b2c", + "metadata": {}, + "outputs": [], + "source": [ + "print(len(arr_3d_reshape))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e4dd52a7", + "metadata": {}, + "outputs": [], + "source": [ + "print(len(arr_3d_reshape[0][0]))" + ] + }, + { + "cell_type": "markdown", + "id": "bccc2fb9", + "metadata": {}, + "source": [ + "#### Вхождение в массив\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c9bb5ab", + "metadata": {}, + "outputs": [], + "source": [ + "print(3 in arr_3d_reshape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d983f6ee", + "metadata": {}, + "outputs": [], + "source": [ + "print(11 not in arr_3d_reshape)" + ] + }, + { + "cell_type": "markdown", + "id": "a151ae82", + "metadata": {}, + "source": [ + "#### Распаковка массива\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3e3e48e", + "metadata": {}, + "outputs": [], + "source": [ + "matrix_3x9: np.ndarray = np.arange(1, 28).reshape(3, 9)\n", + "print(matrix_3x9)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "002c7139", + "metadata": {}, + "outputs": [], + "source": [ + "first_row, second_row, third_row = matrix_3x9\n", + "\n", + "print(first_row)\n", + "print(second_row)\n", + "print(third_row)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3bf8f310", + "metadata": {}, + "outputs": [], + "source": [ + "first_value, *middle_values, last_value = matrix_3x9[0]\n", + "\n", + "print(first_value)\n", + "print(middle_values)\n", + "print(last_value)" + ] + }, + { + "cell_type": "markdown", + "id": "ee6c4795", + "metadata": {}, + "source": [ + "### Изменение элементов массива\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14a5686a", + "metadata": {}, + "outputs": [], + "source": [ + "arr_2d_mutable: np.ndarray = np.array([[1, 2, 3], [4, 5, 6]])\n", + "print(arr_2d_mutable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8114cee3", + "metadata": {}, + "outputs": [], + "source": [ + "# заменим первый элемент первой строки по его индексу\n", + "arr_2d_mutable[0][0] = 2\n", + "print(arr_2d_mutable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc283042", + "metadata": {}, + "outputs": [], + "source": [ + "# запишем значение 1 в первую строку\n", + "arr_2d_mutable[0] = 1\n", + "print(arr_2d_mutable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eeef681a", + "metadata": {}, + "outputs": [], + "source": [ + "# запишем 0 в третий столбец массива\n", + "arr_2d_mutable[:, 2] = 0\n", + "print(arr_2d_mutable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f384b02", + "metadata": {}, + "outputs": [], + "source": [ + "arr_3d_filled = np.arange(12).reshape(2, 2, 3)\n", + "print(arr_3d_filled)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c950927a", + "metadata": {}, + "outputs": [], + "source": [ + "# при такой операции размер среза должен совпадать\n", + "# с количеством передаваемых значений\n", + "arr_3d_filled[1, :, 1] = [0, 1]\n", + "print(arr_3d_filled)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45a51900", + "metadata": {}, + "outputs": [], + "source": [ + "# заменим все элементы массива на число семь\n", + "arr_3d_filled.fill(7)\n", + "print(arr_3d_filled)" + ] + }, + { + "cell_type": "markdown", + "id": "e4b4cfc3", + "metadata": {}, + "source": [ + "### Сортировка массива и обратный порядок его элементов\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "08ee37a8", + "metadata": {}, + "source": [ + "#### Функция np.sort()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "97ec9f21", + "metadata": {}, + "outputs": [], + "source": [ + "matrix_sort: np.ndarray = np.array([[4, 8, 2], [2, 3, 1]])\n", + "print(matrix_sort)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e55561a3", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.sort(matrix_sort))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5154a83", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.sort(matrix_sort, axis=1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "68a1b921", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.sort(matrix_sort, axis=0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4276d2a", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.sort(matrix_sort, axis=None))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec6525b6", + "metadata": {}, + "outputs": [], + "source": [ + "# Обратный порядок элементов массива через оператор среза\n", + "print(np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[::-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92e421b6", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[-3:3:-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "887829a7", + "metadata": {}, + "outputs": [], + "source": [ + "matrix_slice: np.ndarray = np.array([[4, 8, 2], [2, 3, 1], [1, 7, 2]])\n", + "print(matrix_slice)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90b29413", + "metadata": {}, + "outputs": [], + "source": [ + "print(matrix_slice[::-1, ::-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3bb3eea2", + "metadata": {}, + "outputs": [], + "source": [ + "print(matrix_slice[::-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6a80837", + "metadata": {}, + "outputs": [], + "source": [ + "print(matrix_slice[:, ::-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b8eb120", + "metadata": {}, + "outputs": [], + "source": [ + "# Обратный порядок через функцию np.flip()\n", + "print(np.flip(matrix_slice))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e7f96b64", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.flip(matrix_slice, axis=0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82f6d39e", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.flip(matrix_slice, axis=1))" + ] + }, + { + "cell_type": "markdown", + "id": "8fcd15d0", + "metadata": {}, + "source": [ + "#### Сортировка в убывающем порядке\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64efa7c5", + "metadata": {}, + "outputs": [], + "source": [ + "vector_sort: np.ndarray = np.array([4, 2, 6, 1, 7, 3, 5])\n", + "# мы можем последовательно применить np.sort() и оператор среза\n", + "print(np.sort(vector_sort)[::-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "701fe8af", + "metadata": {}, + "outputs": [], + "source": [ + "# изменение стало постоянным\n", + "print(vector_sort[::-1].sort())" + ] + }, + { + "cell_type": "markdown", + "id": "f17dc114", + "metadata": {}, + "source": [ + "### Изменение размерности\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "f5283672", + "metadata": {}, + "source": [ + "#### Метод .reshape()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2e275f4", + "metadata": {}, + "outputs": [], + "source": [ + "arr_3d_resize: np.ndarray = np.arange(12).reshape(2, 2, 3)\n", + "print(arr_3d_resize)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2b5c3a9", + "metadata": {}, + "outputs": [], + "source": [ + "arr_2d_resize: np.ndarray = arr_3d_resize.reshape(2, 6)\n", + "print(arr_2d_resize)" + ] + }, + { + "cell_type": "markdown", + "id": "9b10a2df", + "metadata": {}, + "source": [ + "#### Функция np.resize() и метод .resize()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91040600", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.resize(arr_2d_resize, (3, 6)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a3130bc1", + "metadata": {}, + "outputs": [], + "source": [ + "arr_2d_copy: np.ndarray = arr_2d_resize.copy()\n", + "\n", + "print(arr_2d_copy.resize(4, 6))\n", + "print(arr_2d_copy)" + ] + }, + { + "cell_type": "markdown", + "id": "82d2259d", + "metadata": {}, + "source": [ + "#### Методы .flatten() и .ravel()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6dc7088e", + "metadata": {}, + "outputs": [], + "source": [ + "# .flatten() переводит (\"вытягивает\") массив в одно измерение и\n", + "# создает копию исходного массива (как метод .copy())\n", + "print(arr_3d_resize.flatten())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23747d3a", + "metadata": {}, + "outputs": [], + "source": [ + "# .ravel() делает то же самое,\n", + "# но не создает копию исходного массива и поэтому быстрее чем .flatten()\n", + "print(arr_3d_resize.ravel())" + ] + }, + { + "cell_type": "markdown", + "id": "ff209bf3", + "metadata": {}, + "source": [ + "#### np.newaxis - добавляет измерение в массиве\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6597daf1", + "metadata": {}, + "outputs": [], + "source": [ + "vector_expand: np.ndarray = np.array([1, 2, 3])\n", + "print(vector_expand.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67c4efcf", + "metadata": {}, + "outputs": [], + "source": [ + "row_expanded: np.ndarray = vector_expand[np.newaxis, :]\n", + "print(row_expanded)\n", + "print(row_expanded.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8eead82e", + "metadata": {}, + "outputs": [], + "source": [ + "col_expanded: np.ndarray = vector_expand[:, np.newaxis]\n", + "print(col_expanded)\n", + "print(col_expanded.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "6c028dcf", + "metadata": {}, + "source": [ + "#### Функция np.expand_dims() - добавляет измерение по параметру axis\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "08a8a474", + "metadata": {}, + "outputs": [], + "source": [ + "matrix_expand: np.ndarray = np.arange(1, 5).reshape(2, 2)\n", + "print(matrix_expand)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "777f4120", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.expand_dims(matrix_expand, axis=0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec34a9da", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.expand_dims(matrix_expand, axis=1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56782183", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.expand_dims(matrix_expand, axis=2))" + ] + }, + { + "cell_type": "markdown", + "id": "3a12e020", + "metadata": {}, + "source": [ + "#### Функция np.squeeze() - сжимает первое и последнее измерение, удаляет по сути\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5860fa20", + "metadata": {}, + "outputs": [], + "source": [ + "arr_4d_squeeze: np.ndarray = np.arange(9).reshape(1, 3, 3, 1)\n", + "print(arr_4d_squeeze)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "daadf7ff", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.squeeze(arr_4d_squeeze))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "df6f2286", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.squeeze(arr_4d_squeeze).shape)" + ] + }, + { + "cell_type": "markdown", + "id": "2cbc7740", + "metadata": {}, + "source": [ + "### Объединение массивов\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "01285422", + "metadata": {}, + "source": [ + "#### Функция np.concatenate()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2dcc3860", + "metadata": {}, + "outputs": [], + "source": [ + "mat_a: np.ndarray = np.arange(4).reshape(2, 2)\n", + "mat_b: np.ndarray = np.arange(4, 8).reshape(2, 2)\n", + "\n", + "print(mat_a)\n", + "print(mat_b)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "676a3e0f", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.concatenate((mat_a, mat_b), axis=0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6129904", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.concatenate((mat_a, mat_b), axis=1))" + ] + }, + { + "cell_type": "markdown", + "id": "e17ede04", + "metadata": {}, + "source": [ + "#### Функция np.stack()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "546543d9", + "metadata": {}, + "outputs": [], + "source": [ + "# Отличие функции np.stack() от np.concatenate() в том,\n", + "# что при объединении массивов мы добавляем новое измерение\n", + "print(np.stack((mat_a, mat_b), axis=0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b47a0743", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.stack((mat_a, mat_b), axis=1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa32ca3e", + "metadata": {}, + "outputs": [], + "source": [ + "print(np.stack((mat_a, mat_b), axis=2))" + ] + }, + { + "cell_type": "markdown", + "id": "edd09790", + "metadata": {}, + "source": [ + "### Фильтр (маска) массива\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "907a9b66", + "metadata": {}, + "source": [ + "#### Логическая маска (Boolean mask)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4144274", + "metadata": {}, + "outputs": [], + "source": [ + "vector_mask: np.ndarray = np.array([1, 3, -2, -5, 4, -10, 11])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98d14f51", + "metadata": {}, + "outputs": [], + "source": [ + "print(vector_mask > 0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78d9e7a2", + "metadata": {}, + "outputs": [], + "source": [ + "# применим маску к исходному массиву\n", + "print(vector_mask[vector_mask > 0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "afc54532", + "metadata": {}, + "outputs": [], + "source": [ + "# отфильтрованные значения можно заполнить, например, нулями\n", + "vector_mask[vector_mask < 0] = 0\n", + "print(vector_mask)" + ] + }, + { + "cell_type": "markdown", + "id": "df48595a", + "metadata": {}, + "source": [ + "## Документация\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "922a2137", + "metadata": {}, + "outputs": [], + "source": [ + "# вывод справки по функции с помощью знака вопроса\n", + "# print? или ?print" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccfc926c", + "metadata": {}, + "outputs": [], + "source": [ + "help(print)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f10ac5ca", + "metadata": {}, + "outputs": [], + "source": [ + "# поиск по ключевому слову в документации библиотеки Numpy\n", + "# результаты отсортированы по важности\n", + "# np.lookfor('randint')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_15_iterators.ipynb b/python_issue/makarov/chapter_15_iterators.ipynb new file mode 100644 index 00000000..defaac6c --- /dev/null +++ b/python_issue/makarov/chapter_15_iterators.ipynb @@ -0,0 +1,723 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "58f7ecce", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Iterators and generators.\"\"\"\n", + "from itertools import chain, count, cycle\n", + "\n", + "# pylint: disable=invalid-name" + ] + }, + { + "cell_type": "markdown", + "id": "57f18b54", + "metadata": {}, + "source": [ + "## Итерируемый объект и итератор\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6f6766b9", + "metadata": {}, + "outputs": [], + "source": [ + "for value_1 in [1, 2, 3]:\n", + " print(value_1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09964b64", + "metadata": {}, + "outputs": [], + "source": [ + "temp_iterator = iter([1, 2, 3])\n", + "print(temp_iterator)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf8dcf10", + "metadata": {}, + "outputs": [], + "source": [ + "iterable_object: list[int] = [1, 2, 3]\n", + "\n", + "list_iterator = iter(iterable_object)\n", + "print(list_iterator)\n", + "print()\n", + "\n", + "print(next(list_iterator))\n", + "print(next(list_iterator))\n", + "print(next(list_iterator))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c5735da", + "metadata": {}, + "outputs": [], + "source": [ + "for element in iterable_object:\n", + " print(element)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2bf07293", + "metadata": {}, + "outputs": [], + "source": [ + "iterable_numbers: list[int] = [1, 2, 3]\n", + "\n", + "iterator_a = iter(iterable_numbers)\n", + "iterator_b = iter(iterable_numbers)\n", + "\n", + "print(f\"A: {next(iterator_a)}\")\n", + "print(f\"A: {next(iterator_a)}\")\n", + "print(f\"A: {next(iterator_a)}\")\n", + "print(f\"B: {next(iterator_b)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "08ce2066", + "metadata": {}, + "outputs": [], + "source": [ + "print(iterable_numbers)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9ecce69", + "metadata": {}, + "outputs": [], + "source": [ + "iterator_a_list: list[int] = list(iterator_a)\n", + "iterator_b_list: list[int] = list(iterator_b)\n", + "print(iterator_a_list, iterator_b_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b3836617", + "metadata": {}, + "outputs": [], + "source": [ + "for number_value in [1, 1, 2, 3]:\n", + " print(number_value)" + ] + }, + { + "cell_type": "markdown", + "id": "6ca38c0a", + "metadata": {}, + "source": [ + "## Отсутствие \"обратного хода\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb16d415", + "metadata": {}, + "outputs": [], + "source": [ + "iterator_c = iter(iterable_numbers)\n", + "\n", + "for first_item in iterator_c:\n", + " print(first_item)\n", + " break\n", + "\n", + "for remaining_item in iterator_c:\n", + " print(remaining_item)" + ] + }, + { + "cell_type": "markdown", + "id": "d9142478", + "metadata": {}, + "source": [ + "## Функция zip()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f445d9ad", + "metadata": {}, + "outputs": [], + "source": [ + "zipped_pairs = zip(iterable_numbers, iterable_numbers)\n", + "print(zipped_pairs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5761f5df", + "metadata": {}, + "outputs": [], + "source": [ + "iterator_tuple = zip(iterable_numbers, iterable_numbers)\n", + "\n", + "print(next(iterator_tuple))\n", + "print(next(iterator_tuple))\n", + "print(next(iterator_tuple))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e3a9fb4", + "metadata": {}, + "outputs": [], + "source": [ + "for pair in zip(iterable_numbers, iterable_numbers):\n", + " print(pair)" + ] + }, + { + "cell_type": "markdown", + "id": "3da8f42d", + "metadata": {}, + "source": [ + "## Примеры итераторов\n", + "### Возведение в квадрат\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46d25ccc", + "metadata": {}, + "outputs": [], + "source": [ + "class Square:\n", + " \"\"\"Iterator returning squared values from a sequence.\"\"\"\n", + "\n", + " def __init__(self, seq: list[int] | tuple[int, ...]) -> None:\n", + " \"\"\"Initialize iterator with sequence.\"\"\"\n", + " self._seq = seq\n", + " self._idx = 0\n", + "\n", + " def __iter__(self): # type: ignore[no-untyped-def]\n", + " \"\"\"Return self as iterator.\"\"\"\n", + " return self\n", + "\n", + " def __next__(self) -> int:\n", + " \"\"\"Return next squared value or raise StopIteration.\"\"\"\n", + " if self._idx >= len(self._seq):\n", + " raise StopIteration\n", + " square_result: int = self._seq[self._idx] ** 2\n", + " self._idx += 1\n", + " return square_result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82565b86", + "metadata": {}, + "outputs": [], + "source": [ + "square_iterator: Square = Square([1, 2, 3, 4, 5])\n", + "print(square_iterator)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46643a50", + "metadata": {}, + "outputs": [], + "source": [ + "for square_value in square_iterator:\n", + " print(square_value)" + ] + }, + { + "cell_type": "markdown", + "id": "3fb22da3", + "metadata": {}, + "source": [ + "## Счетчик\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b4922c6", + "metadata": {}, + "outputs": [], + "source": [ + "class Counter:\n", + " \"\"\"Simple iterator that counts from start up to stop (exclusive).\"\"\"\n", + "\n", + " def __init__(self, start: int = 3, stop: int = 9) -> None:\n", + " \"\"\"Initialize with bounds.\"\"\"\n", + " self._current = start - 1\n", + " self._stop = stop\n", + "\n", + " def __iter__(self): # type: ignore[no-untyped-def]\n", + " \"\"\"Return self as iterator.\"\"\"\n", + " return self\n", + "\n", + " def __next__(self) -> int:\n", + " \"\"\"Return next number or raise StopIteration.\"\"\"\n", + " self._current += 1\n", + " if self._current >= self._stop:\n", + " raise StopIteration\n", + " return self._current" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ccb2999", + "metadata": {}, + "outputs": [], + "source": [ + "counter_instance: Counter = Counter()\n", + "print(counter_instance)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "770265e3", + "metadata": {}, + "outputs": [], + "source": [ + "print(next(counter_instance))\n", + "print(next(counter_instance))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee306597", + "metadata": {}, + "outputs": [], + "source": [ + "for count_value in counter_instance:\n", + " print(count_value)" + ] + }, + { + "cell_type": "markdown", + "id": "01bab639", + "metadata": {}, + "source": [ + "## Класс Iterator модуля collections.abc\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1975251", + "metadata": {}, + "outputs": [], + "source": [ + "class Counter2:\n", + " \"\"\"Iterator implementing the Iterator protocol explicitly.\"\"\"\n", + "\n", + " def __init__(self, start: int = 3, stop: int = 9) -> None:\n", + " \"\"\"Initialize with bounds.\"\"\"\n", + " self._current = start - 1\n", + " self._stop = stop\n", + "\n", + " def __iter__(self): # type: ignore[no-untyped-def]\n", + " \"\"\"Return self as iterator.\"\"\"\n", + " return self\n", + "\n", + " def __next__(self) -> int:\n", + " \"\"\"Return next number or raise StopIteration.\"\"\"\n", + " self._current += 1\n", + " if self._current >= self._stop:\n", + " raise StopIteration\n", + " return self._current" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52b01a80", + "metadata": {}, + "outputs": [], + "source": [ + "for count_value in Counter2():\n", + " print(count_value)" + ] + }, + { + "cell_type": "markdown", + "id": "237d708c", + "metadata": {}, + "source": [ + "## Бесконечный итератор\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "620a3c8b", + "metadata": {}, + "outputs": [], + "source": [ + "class FibIterator:\n", + " \"\"\"Iterator producing Fibonacci numbers.\"\"\"\n", + "\n", + " def __init__(self) -> None:\n", + " \"\"\"Initialize starting values.\"\"\"\n", + " self._idx = 0\n", + " self._current = 0\n", + " self._next = 1\n", + "\n", + " def __iter__(self): # type: ignore[no-untyped-def]\n", + " \"\"\"Return self as iterator.\"\"\"\n", + " return self\n", + "\n", + " def __next__(self) -> int:\n", + " \"\"\"Return next Fibonacci number.\"\"\"\n", + " if self._idx < 0:\n", + " raise StopIteration\n", + " self._idx += 1\n", + " self._current, self._next = (self._next, self._current + self._next)\n", + " return self._current" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "79860182", + "metadata": {}, + "outputs": [], + "source": [ + "fib_limit: int = 10\n", + "\n", + "for fib_value in FibIterator():\n", + " print(fib_value)\n", + " fib_limit -= 1\n", + " if fib_limit == 0:\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "fdb84369", + "metadata": {}, + "source": [ + "## Генератор\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4d0c329", + "metadata": {}, + "outputs": [], + "source": [ + "def sequence(count_limit: int) -> list[int]:\n", + " \"\"\"Return list of integers from 1 to n inclusive.\"\"\"\n", + " res: list[int] = [x for x in range(1, count_limit + 1)]\n", + " return res\n", + "\n", + "\n", + "sequence(5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37f2fd0d", + "metadata": {}, + "outputs": [], + "source": [ + "def sequence_gen(count_limit: int): # type: ignore[no-untyped-def]\n", + " \"\"\"Yield integers from 1 to n inclusive.\"\"\"\n", + " yield from range(1, count_limit + 1)\n", + "\n", + "\n", + "sequence_gen(5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9e44491", + "metadata": {}, + "outputs": [], + "source": [ + "seq_5 = sequence_gen(5)\n", + "\n", + "print(next(seq_5))\n", + "print(next(seq_5))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48001c18", + "metadata": {}, + "outputs": [], + "source": [ + "for number in seq_5:\n", + " print(number)" + ] + }, + { + "cell_type": "markdown", + "id": "f6a55569", + "metadata": {}, + "source": [ + "## Generator comprehension\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91fa49cc", + "metadata": {}, + "outputs": [], + "source": [ + "gen_expr = (x for x in range(1, 5 + 1))\n", + "print(gen_expr)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0f3f0878", + "metadata": {}, + "outputs": [], + "source": [ + "gen_expr_list: list[int] = list(x for x in range(1, 5 + 1))\n", + "print(gen_expr_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec456aa3", + "metadata": {}, + "outputs": [], + "source": [ + "sum_gen: int = sum(x for x in range(1, 5 + 1))\n", + "print(sum_gen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9efb9190", + "metadata": {}, + "outputs": [], + "source": [ + "contains_value: bool = 5 in (x for x in range(1, 5 + 1))\n", + "print(contains_value)" + ] + }, + { + "cell_type": "markdown", + "id": "8da60232", + "metadata": {}, + "source": [ + "## Модуль itertools\n" + ] + }, + { + "cell_type": "markdown", + "id": "28a2d3a5", + "metadata": {}, + "source": [ + "## Функция count()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7235a24c", + "metadata": {}, + "outputs": [], + "source": [ + "natural_numbers = count(start=1, step=0.5)\n", + "\n", + "for num in natural_numbers:\n", + " print(num)\n", + " if num == 2:\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f89a03d7", + "metadata": {}, + "outputs": [], + "source": [ + "list_let: list[str] = [\"a\", \"b\", \"c\", \"d\"]\n", + "for enumerated_letter in zip(count(start=1), list_let):\n", + " print(enumerated_letter)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b4d12c9", + "metadata": {}, + "outputs": [], + "source": [ + "def quadratic(value: int | float) -> float:\n", + " \"\"\"Return quadratic expression result.\"\"\"\n", + " return value**2 + value - 2\n", + "\n", + "\n", + "f_x = map(quadratic, count())\n", + "print(next(f_x), next(f_x), next(f_x))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b321bf7", + "metadata": {}, + "outputs": [], + "source": [ + "for mapped_value in f_x:\n", + " print(mapped_value)\n", + " if mapped_value > 10:\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "99f73ccc", + "metadata": {}, + "source": [ + "??????? ???????? ? ???????????? ?? ???????.\n" + ] + }, + { + "cell_type": "markdown", + "id": "a16f632d", + "metadata": {}, + "source": [ + "???? ?? ?????? ? ?????????????? cycle (?????? ????).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c92c7d9", + "metadata": {}, + "outputs": [], + "source": [ + "cycle_numbers: list[int] = [1, 2, 3]\n", + "cycle_iterator_numbers = cycle(cycle_numbers)\n", + "\n", + "cycle_nums_limit: int = 5\n", + "for number in cycle_iterator_numbers:\n", + " print(number)\n", + " cycle_nums_limit -= 1\n", + " if cycle_nums_limit == 0:\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "54f9b097", + "metadata": {}, + "outputs": [], + "source": [ + "string_value: str = \"Python\"\n", + "cycle_iterator_chars = cycle(string_value)\n", + "\n", + "cycle_chars_limit: int = 10\n", + "for char in cycle_iterator_chars:\n", + " print(char)\n", + " cycle_chars_limit -= 1\n", + " if cycle_chars_limit == 0:\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6b540fd", + "metadata": {}, + "outputs": [], + "source": [ + "chain_iterator = chain([\"abc\", \"d\", \"e\", \"f\"], \"abc\", [1, 2, 3])\n", + "print(chain_iterator)" + ] + }, + { + "cell_type": "markdown", + "id": "eb6d9465", + "metadata": {}, + "source": [ + "????????? ???????? ????????? chain ???????.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "696ce36d", + "metadata": {}, + "outputs": [], + "source": [ + "flatten_letters: list[str] = list(chain.from_iterable([\"abc\", \"def\"]))\n", + "print(flatten_letters)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e05b7cbd", + "metadata": {}, + "outputs": [], + "source": [ + "sum_numbers: int = sum(chain.from_iterable([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))\n", + "print(sum_numbers)" + ] + } + ], + "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.14.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_16_decorators.ipynb b/python_issue/makarov/chapter_16_decorators.ipynb new file mode 100644 index 00000000..a8f423ba --- /dev/null +++ b/python_issue/makarov/chapter_16_decorators.ipynb @@ -0,0 +1,1285 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "28839556", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Decorators.\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ec50d3e", + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import annotations\n", + "\n", + "import functools\n", + "import time\n", + "from collections.abc import Callable\n", + "from typing import ParamSpec, Protocol, TypeVar\n", + "\n", + "Params = ParamSpec(\"Params\")\n", + "Arguments = TypeVar(\"Arguments\")\n", + "T = TypeVar(\"T\")" + ] + }, + { + "cell_type": "markdown", + "id": "1e12dbbb", + "metadata": {}, + "source": [ + "## Декораторы\n", + "### Объекты первого класса\n", + "#### Присвоение функции переменной" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0214f716", + "metadata": {}, + "outputs": [], + "source": [ + "def say_hello_basic(name: str) -> None:\n", + " \"\"\"Print greeting with provided name.\"\"\"\n", + " print(f\"Hello, {name}!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20a6b837", + "metadata": {}, + "outputs": [], + "source": [ + "say_hello_function = say_hello_basic\n", + "say_hello_function(\"Alexey\")" + ] + }, + { + "cell_type": "markdown", + "id": "06728021", + "metadata": {}, + "source": [ + "## Передача функции в качестве аргумента другой функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a8444af7", + "metadata": {}, + "outputs": [], + "source": [ + "def simple_calculator(\n", + " operation: Callable[[float, float], float],\n", + " first_number: float,\n", + " second_number: float,\n", + ") -> float:\n", + " \"\"\"Calculate result using provided binary operation.\"\"\"\n", + " return operation(first_number, second_number)\n", + "\n", + "\n", + "def add(first_number: float, second_number: float) -> float:\n", + " \"\"\"Return sum of numbers.\"\"\"\n", + " return first_number + second_number\n", + "\n", + "\n", + "def subtract(first_number: float, second_number: float) -> float:\n", + " \"\"\"Return difference of numbers.\"\"\"\n", + " return first_number - second_number\n", + "\n", + "\n", + "def multiply(first_number: float, second_number: float) -> float:\n", + " \"\"\"Return product of numbers.\"\"\"\n", + " return first_number * second_number\n", + "\n", + "\n", + "def divide(first_number: float, second_number: float) -> float:\n", + " \"\"\"Return division result of numbers.\"\"\"\n", + " return first_number / second_number" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1722c926", + "metadata": {}, + "outputs": [], + "source": [ + "print(simple_calculator(divide, 33, 3))" + ] + }, + { + "cell_type": "markdown", + "id": "02e19d58", + "metadata": {}, + "source": [ + "## Внутренние функции\n", + "### Вызов внутренней функции\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e133dbf1", + "metadata": {}, + "outputs": [], + "source": [ + "def outer() -> None:\n", + " \"\"\"Print messages from outer and inner functions.\"\"\"\n", + " print(\"out function call\")\n", + "\n", + " def inner() -> None:\n", + " \"\"\"Print inner function call message.\"\"\"\n", + " print(\"inner function call\")\n", + "\n", + " inner()\n", + "\n", + "\n", + "outer()" + ] + }, + { + "cell_type": "markdown", + "id": "9ae979bc", + "metadata": {}, + "source": [ + "## Возвращение функции из функции и замыкание\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "edac3ce3", + "metadata": {}, + "outputs": [], + "source": [ + "class MultiplierCallable(Protocol):\n", + " \"\"\"Protocol defining callable multiplier function.\"\"\"\n", + "\n", + " def __call__(self, number: int) -> int:\n", + " \"\"\"Callable signature defining multiplier behavior.\"\"\"\n", + " raise NotImplementedError\n", + "\n", + "\n", + "def create_multiplier(factor: int) -> MultiplierCallable:\n", + " \"\"\"Create multiplier closure for demonstration purposes.\"\"\"\n", + "\n", + " def multiplier(number: int) -> int:\n", + " \"\"\"Multiply number by predefined factor.\"\"\"\n", + " return number * factor\n", + "\n", + " return multiplier\n", + "\n", + "\n", + "double_multiplier: MultiplierCallable = create_multiplier(factor=2)\n", + "triple_multiplier: MultiplierCallable = create_multiplier(factor=3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce851649", + "metadata": {}, + "outputs": [], + "source": [ + "print(double_multiplier)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9d48b77", + "metadata": {}, + "outputs": [], + "source": [ + "print((double_multiplier(number=2), triple_multiplier(number=2)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca25e61c", + "metadata": {}, + "outputs": [], + "source": [ + "def create_multiplier_2(factor: int) -> Callable[[int], int]:\n", + " \"\"\"Create multiplier using a nested function for demonstration purposes.\"\"\"\n", + "\n", + " def multiplier(number: int) -> int:\n", + " \"\"\"Multiply number by predefined factor.\"\"\"\n", + " return factor * number\n", + "\n", + " return multiplier" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dbf2ed83", + "metadata": {}, + "outputs": [], + "source": [ + "triple_multiplier_v2 = create_multiplier_2(factor=3)\n", + "print(triple_multiplier_v2(2))" + ] + }, + { + "cell_type": "markdown", + "id": "c2d0ea41", + "metadata": {}, + "source": [ + "## Знакомство с декораторами\n", + "### Простой декоратор\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3fef06a6", + "metadata": {}, + "outputs": [], + "source": [ + "def simple_decorator(\n", + " func: Callable[Params, Arguments],\n", + ") -> Callable[Params, Arguments]:\n", + " \"\"\"Decorate function by adding text before and after execution.\"\"\"\n", + "\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments:\n", + " \"\"\"Wrap function call and print surrounding text.\"\"\"\n", + " print(\"Text before func().\")\n", + " result = func(*args, **kwargs)\n", + " print(\"Text after func().\")\n", + " return result\n", + "\n", + " return wrapper\n", + "\n", + "\n", + "def say_hello_decorated() -> None:\n", + " \"\"\"Print simple greeting.\"\"\"\n", + " print(\"Hello!\")\n", + "\n", + "\n", + "say_hello_decorated = simple_decorator(say_hello_decorated)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8226560", + "metadata": {}, + "outputs": [], + "source": [ + "say_hello_decorated()" + ] + }, + { + "cell_type": "markdown", + "id": "fe7fa7bd", + "metadata": {}, + "source": [ + "## Конструкция @decorator\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f61132fa", + "metadata": {}, + "outputs": [], + "source": [ + "@simple_decorator\n", + "def say_hi() -> None:\n", + " \"\"\"Print repeated greeting.\"\"\"\n", + " print(\"Hello, again...\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31e80f06", + "metadata": {}, + "outputs": [], + "source": [ + "say_hi()" + ] + }, + { + "cell_type": "markdown", + "id": "80824ed5", + "metadata": {}, + "source": [ + "## Функции с аргументами\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "920f91e6", + "metadata": {}, + "outputs": [], + "source": [ + "@simple_decorator\n", + "def say_hello_with_name_simple(name: str) -> None:\n", + " \"\"\"Print greeting with provided name.\"\"\"\n", + " print(f\"Hello, {name}!\")\n", + "\n", + "\n", + "say_hello_with_name_simple(\"Alex\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "79183218", + "metadata": {}, + "outputs": [], + "source": [ + "def decorator_with_name_argument(func: Callable[[str], None]) -> Callable[[str], None]:\n", + " \"\"\"Decorate function expecting a single name argument.\"\"\"\n", + "\n", + " def wrapper(name: str) -> None:\n", + " \"\"\"Wrap function call and print surrounding text.\"\"\"\n", + " print(\"Text before func().\")\n", + " func(name)\n", + " print(\"Text after func().\")\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "817a2b89", + "metadata": {}, + "outputs": [], + "source": [ + "@decorator_with_name_argument\n", + "def say_hello_with_name_logged(name: str) -> None:\n", + " \"\"\"Print greeting with provided name.\"\"\"\n", + " print(f\"Hello, {name}!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03031dcd", + "metadata": {}, + "outputs": [], + "source": [ + "say_hello_with_name_logged(\"Alex\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a401d87", + "metadata": {}, + "outputs": [], + "source": [ + "def decorator_with_arguments(\n", + " func: Callable[Params, Arguments],\n", + ") -> Callable[Params, Arguments]:\n", + " \"\"\"Decorate function printing text before and after call.\"\"\"\n", + "\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments:\n", + " \"\"\"Wrap function call and print surrounding text.\"\"\"\n", + " print(\"Text before func().\")\n", + " result = func(*args, **kwargs)\n", + " print(\"Text after func().\")\n", + " return result\n", + "\n", + " return wrapper\n", + "\n", + "\n", + "@decorator_with_arguments\n", + "def say_hello_with_argument(name: str) -> None:\n", + " \"\"\"Print greeting with provided name.\"\"\"\n", + " print(f\"Hello, {name}!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "748e1665", + "metadata": {}, + "outputs": [], + "source": [ + "say_hello_with_argument(\"Alex\")" + ] + }, + { + "cell_type": "markdown", + "id": "88a0fc1c", + "metadata": {}, + "source": [ + "## Возвращение значения декорируемой функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2e0a712", + "metadata": {}, + "outputs": [], + "source": [ + "def another_decorator(func: Callable[[str], str]) -> Callable[[str], None]:\n", + " \"\"\"Decorate function by printing text before call.\"\"\"\n", + "\n", + " def wrapper(name: str) -> None:\n", + " \"\"\"Wrap function call and print inner text.\"\"\"\n", + " print(\"Inner function text\")\n", + " func(name)\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b4185f61", + "metadata": {}, + "outputs": [], + "source": [ + "@another_decorator\n", + "def return_name_silent(name: str) -> str:\n", + " \"\"\"Return provided name.\"\"\"\n", + " return name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00d46a93", + "metadata": {}, + "outputs": [], + "source": [ + "returned_value: str | None = return_name_silent(\"Alex\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b0062fb", + "metadata": {}, + "outputs": [], + "source": [ + "print(returned_value)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "990a7275", + "metadata": {}, + "outputs": [], + "source": [ + "def another_decorator_verbose(\n", + " func: Callable[[str], Arguments],\n", + ") -> Callable[[str], Arguments]:\n", + " \"\"\"Decorate function by printing text and returning result.\"\"\"\n", + "\n", + " def wrapper(name: str) -> Arguments:\n", + " \"\"\"Wrap function call, print text, and return result.\"\"\"\n", + " print(\"����� ���������� �������.\")\n", + " return func(name)\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8556b18d", + "metadata": {}, + "outputs": [], + "source": [ + "@another_decorator_verbose\n", + "def return_name_verbose(name: str) -> str:\n", + " \"\"\"Return provided name.\"\"\"\n", + " return name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "091e8e3d", + "metadata": {}, + "outputs": [], + "source": [ + "returned_value_verbose: str = return_name_verbose(\"Alex\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4bbefa5", + "metadata": {}, + "outputs": [], + "source": [ + "print(returned_value_verbose)" + ] + }, + { + "cell_type": "markdown", + "id": "381ce1b7", + "metadata": {}, + "source": [ + "## Декоратор @functools.wraps\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a352897", + "metadata": {}, + "outputs": [], + "source": [ + "def square_basic(value: int) -> int:\n", + " \"\"\"Return square of the given number.\"\"\"\n", + " return value * value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "71e9fb56", + "metadata": {}, + "outputs": [], + "source": [ + "print((square_basic.__name__, square_basic.__doc__))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1992ae6", + "metadata": {}, + "outputs": [], + "source": [ + "def repeat_twice(\n", + " func: Callable[Params, Arguments],\n", + ") -> Callable[Params, Arguments]:\n", + " \"\"\"Decorate function to run twice.\"\"\"\n", + "\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments:\n", + " result = func(*args, **kwargs)\n", + " return result\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8db5d417", + "metadata": {}, + "outputs": [], + "source": [ + "@repeat_twice\n", + "def square_repeated(value: int) -> int:\n", + " \"\"\"Return square of the given number.\"\"\"\n", + " return value * value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f389b3d9", + "metadata": {}, + "outputs": [], + "source": [ + "square_repeated(3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "192e3d0c", + "metadata": {}, + "outputs": [], + "source": [ + "print((square_repeated.__name__, square_repeated.__doc__))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6edfefd", + "metadata": {}, + "outputs": [], + "source": [ + "def repeat_twice_with_wraps(\n", + " func: Callable[Params, Arguments],\n", + ") -> Callable[Params, Arguments]:\n", + " \"\"\"Decorate function by repeating execution twice with wraps.\"\"\"\n", + "\n", + " @functools.wraps(func)\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments:\n", + " \"\"\"Wrap function call, execute twice, and return result.\"\"\"\n", + " func(*args, **kwargs)\n", + " return func(*args, **kwargs)\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c98e8e98", + "metadata": {}, + "outputs": [], + "source": [ + "@repeat_twice_with_wraps\n", + "def square_wrapped(value: int) -> None:\n", + " \"\"\"Return square of the given number.\"\"\"\n", + " print(value * value)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ac9eb47", + "metadata": {}, + "outputs": [], + "source": [ + "print((square_wrapped.__name__, square_wrapped.__doc__))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "834bb144", + "metadata": {}, + "outputs": [], + "source": [ + "print(getattr(square_wrapped, \"__wrapped__\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d64a9c28", + "metadata": {}, + "outputs": [], + "source": [ + "def repeat_twice_updated(\n", + " func: Callable[Params, Arguments],\n", + ") -> Callable[Params, Arguments]:\n", + " \"\"\"Decorate function by repeating execution twice and preserving metadata.\"\"\"\n", + "\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments:\n", + " \"\"\"Wrap function call, execute twice, and return result.\"\"\"\n", + " func(*args, **kwargs)\n", + " return func(*args, **kwargs)\n", + "\n", + " functools.update_wrapper(wrapper, func)\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bba41989", + "metadata": {}, + "outputs": [], + "source": [ + "@repeat_twice_updated\n", + "def power_repeated(base_value: float, exponent: float) -> int | float:\n", + " \"\"\"Return base raised to exponent.\"\"\"\n", + " result: int | float = base_value**exponent\n", + " return result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20a0ea56", + "metadata": {}, + "outputs": [], + "source": [ + "power_repeated(2, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e8e90370", + "metadata": {}, + "outputs": [], + "source": [ + "print(power_repeated.__doc__)" + ] + }, + { + "cell_type": "markdown", + "id": "258ce396", + "metadata": {}, + "source": [ + "## Примеры декораторов\n", + "### Создание логов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ae8990f", + "metadata": {}, + "outputs": [], + "source": [ + "def logging(func: Callable[Params, Arguments]) -> Callable[Params, Arguments]:\n", + " \"\"\"Decorate function with logging.\"\"\"\n", + "\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments:\n", + " \"\"\"Wrap function call and log arguments and result.\"\"\"\n", + " print(f\"Calling {func.__name__} with args: {args}, kwargs: {kwargs}\")\n", + " result = func(*args, **kwargs)\n", + " print(f\"{func.__name__} returned: {result}\")\n", + " return result\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6328baf0", + "metadata": {}, + "outputs": [], + "source": [ + "@logging\n", + "def power_logged(base_value: int, exponent: int) -> int | float:\n", + " \"\"\"Return power of a number.\"\"\"\n", + " result: int | float = base_value**exponent\n", + " return result\n", + "\n", + "\n", + "power_logged(5, 3)" + ] + }, + { + "cell_type": "markdown", + "id": "c5a456fb", + "metadata": {}, + "source": [ + "## Время исполнения функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73d8eb90", + "metadata": {}, + "outputs": [], + "source": [ + "def timer(func: Callable[Params, Arguments]) -> Callable[Params, Arguments]:\n", + " \"\"\"Wrap function to measure execution time.\"\"\"\n", + "\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments:\n", + " \"\"\"Wrap function call, measure duration, and return result.\"\"\"\n", + " start_time = time.time()\n", + " result = func(*args, **kwargs)\n", + " end_time = time.time()\n", + " print(f\"{func.__name__} executed in {end_time - start_time:.4f} seconds\")\n", + " return result\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d99fe88a", + "metadata": {}, + "outputs": [], + "source": [ + "@timer\n", + "def delayed_function_timed(delay_time: float) -> str:\n", + " \"\"\"Delay execution for specified time.\"\"\"\n", + " time.sleep(delay_time)\n", + " return \"execution completed\"\n", + "\n", + "\n", + "delayed_function_timed(2)" + ] + }, + { + "cell_type": "markdown", + "id": "03c807f2", + "metadata": {}, + "source": [ + "## Типы методов\n", + "### Методы экземпляра\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7aa92785", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClassBasic:\n", + " \"\"\"Represent basic cat data.\"\"\"\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Initialize instance attributes.\"\"\"\n", + " self.color: str = color\n", + " self.type_: str = \"cat\"\n", + "\n", + " def info(self) -> None:\n", + " \"\"\"Print cat information.\"\"\"\n", + " print(self.color, self.type_, sep=\", \")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2472f049", + "metadata": {}, + "outputs": [], + "source": [ + "cat_basic = CatClassBasic(color=\"black\")\n", + "cat_basic.info()" + ] + }, + { + "cell_type": "markdown", + "id": "d30c89c6", + "metadata": {}, + "source": [ + "## Методы класса\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b13c7d37", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClassWithSpecies:\n", + " \"\"\"Represent cat data with species information.\"\"\"\n", + "\n", + " species: str = \"Cat\"\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Initialize instance attributes.\"\"\"\n", + " self.color: str = color\n", + "\n", + " def info(self) -> None:\n", + " \"\"\"Print cat color.\"\"\"\n", + " print(self.color)\n", + "\n", + " @classmethod\n", + " def get_species(cls) -> None:\n", + " \"\"\"Print species name.\"\"\"\n", + " print(cls.species)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85c64955", + "metadata": {}, + "outputs": [], + "source": [ + "print(CatClassWithSpecies.species)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46690f45", + "metadata": {}, + "outputs": [], + "source": [ + "CatClassWithSpecies.get_species()" + ] + }, + { + "cell_type": "markdown", + "id": "c09a8edf", + "metadata": {}, + "source": [ + "## Статические методы\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8adf1cbc", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClassWithConverter:\n", + " \"\"\"Represent cat data with conversion utility.\"\"\"\n", + "\n", + " species: str = \"Cat\"\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Initialize instance attributes.\"\"\"\n", + " self.color: str = color\n", + "\n", + " def info(self) -> None:\n", + " \"\"\"Print cat color.\"\"\"\n", + " print(self.color)\n", + "\n", + " @classmethod\n", + " def get_species(cls) -> None:\n", + " \"\"\"Print species name.\"\"\"\n", + " print(cls.species)\n", + "\n", + " @staticmethod\n", + " def convert_to_pounds(weight_kg: float) -> None:\n", + " \"\"\"Convert kilograms to pounds and print result.\"\"\"\n", + " print(f\"{weight_kg} kg is approximately {weight_kg * 2.205} pounds\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1da5aa35", + "metadata": {}, + "outputs": [], + "source": [ + "CatClassWithConverter.convert_to_pounds(4)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48e4eae4", + "metadata": {}, + "outputs": [], + "source": [ + "cat_with_converter = CatClassWithConverter(\"gray\")\n", + "cat_with_converter.convert_to_pounds(12)" + ] + }, + { + "cell_type": "markdown", + "id": "43cb14dd", + "metadata": {}, + "source": [ + "## Декорирование класса\n", + "### Декорирование методов\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd8d6001", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClassDecorated:\n", + " \"\"\"Represent cat data with decorated methods.\"\"\"\n", + "\n", + " color: str\n", + " type_: str\n", + "\n", + " @logging\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Initialize instance attributes.\"\"\"\n", + " self.color = color\n", + " self.type_ = \"cat\"\n", + "\n", + " @timer\n", + " def info(self) -> None:\n", + " \"\"\"Print cat information with delay.\"\"\"\n", + " time.sleep(2)\n", + " print(self.color, self.type_, sep=\", \")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52fc21b1", + "metadata": {}, + "outputs": [], + "source": [ + "cat_decorated = CatClassDecorated(\"black\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f324709d", + "metadata": {}, + "outputs": [], + "source": [ + "cat_decorated.info()" + ] + }, + { + "cell_type": "markdown", + "id": "34406ca4", + "metadata": {}, + "source": [ + "## Декорирование всего класса\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b9a8c99a", + "metadata": {}, + "outputs": [], + "source": [ + "@timer\n", + "class CatClassTimed:\n", + " \"\"\"Represent cat data with timed methods.\"\"\"\n", + "\n", + " weight: float | int | None = None\n", + " color: str\n", + " type_: str\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Initialize instance attributes.\"\"\"\n", + " self.color = color\n", + " self.type_ = \"cat\"\n", + "\n", + " def info(self) -> None:\n", + " \"\"\"Print cat information with delay.\"\"\"\n", + " time.sleep(2)\n", + " print(self.color, self.type_, sep=\", \")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0e63abb", + "metadata": {}, + "outputs": [], + "source": [ + "cat_timed = CatClassTimed(\"grey\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2da29db8", + "metadata": {}, + "outputs": [], + "source": [ + "cat_timed.info()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b781159", + "metadata": {}, + "outputs": [], + "source": [ + "setattr(cat_timed, \"weight\", 5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "75083940", + "metadata": {}, + "outputs": [], + "source": [ + "print((cat_timed.weight, getattr(cat_timed, \"weight\")))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad42ce6d", + "metadata": {}, + "outputs": [], + "source": [ + "def add_attribute(\n", + " attribute_name: str, attribute_value: str\n", + ") -> Callable[[type[T]], type[T]]:\n", + " \"\"\"Decorate class by adding specified attribute.\"\"\"\n", + "\n", + " def wrapper(cls: type[T]) -> type[T]:\n", + " \"\"\"Attach attribute to class and return the class.\"\"\"\n", + " setattr(cls, attribute_name, attribute_value)\n", + " return cls\n", + "\n", + " return wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37e55be4", + "metadata": {}, + "outputs": [], + "source": [ + "@add_attribute(\"species\", \"cat\")\n", + "class CatClassAttributed:\n", + " \"\"\"Represent cat data with added attributes.\"\"\"\n", + "\n", + " species: str = \"cat\"\n", + " color: str\n", + " type_: str\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Initialize instance attributes.\"\"\"\n", + " self.color = color\n", + " self.type_ = \"cat\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "072a2df0", + "metadata": {}, + "outputs": [], + "source": [ + "print(CatClassAttributed.species)" + ] + }, + { + "cell_type": "markdown", + "id": "93b21995", + "metadata": {}, + "source": [ + "## Несколько декораторов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b9176367", + "metadata": {}, + "outputs": [], + "source": [ + "@logging\n", + "@timer\n", + "def delayed_function_logged_timed(delay_time: float) -> str:\n", + " \"\"\"Delay execution with logging and timing.\"\"\"\n", + " time.sleep(delay_time)\n", + " return \"execution completed\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2f046ea9", + "metadata": {}, + "outputs": [], + "source": [ + "delayed_function_logged_timed(2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67fbc7bf", + "metadata": {}, + "outputs": [], + "source": [ + "def delayed_function_plain(delay_time: float) -> str:\n", + " \"\"\"Delay execution for specified time.\"\"\"\n", + " time.sleep(delay_time)\n", + " return \"execution completed\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef1aa482", + "metadata": {}, + "outputs": [], + "source": [ + "delayed_function_wrapped = logging(timer(delayed_function_plain))\n", + "delayed_function_wrapped(2)" + ] + }, + { + "cell_type": "markdown", + "id": "6f358cd8", + "metadata": {}, + "source": [ + "## Декораторы с аргументами\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "390d0049", + "metadata": {}, + "outputs": [], + "source": [ + "def repeat(\n", + " repeat_count: int,\n", + ") -> Callable[[Callable[Params, None]], Callable[Params, None]]:\n", + " \"\"\"Create decorator repeating function calls.\"\"\"\n", + "\n", + " def inner_decorator(func: Callable[Params, None]) -> Callable[Params, None]:\n", + " \"\"\"Wrap function to repeat calls the specified number of times.\"\"\"\n", + "\n", + " @functools.wraps(func)\n", + " def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> None:\n", + " \"\"\"Wrap function call and repeat execution.\"\"\"\n", + " for _ in range(repeat_count):\n", + " func(*args, **kwargs)\n", + "\n", + " return wrapper\n", + "\n", + " return inner_decorator" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab2974aa", + "metadata": {}, + "outputs": [], + "source": [ + "@repeat(repeat_count=3)\n", + "def say_hello_repeated(name: str) -> None:\n", + " \"\"\"Print greeting with provided name.\"\"\"\n", + " print(f\"Hello, {name}!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eea52157", + "metadata": {}, + "outputs": [], + "source": [ + "say_hello_repeated(\"Alex\")" + ] + } + ], + "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.14.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_1_pandas.ipynb b/python_issue/makarov/chapter_1_pandas.ipynb new file mode 100644 index 00000000..c1c8c067 --- /dev/null +++ b/python_issue/makarov/chapter_1_pandas.ipynb @@ -0,0 +1,1180 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "3c9dc453", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Pandas library.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "33a5fcfd", + "metadata": {}, + "source": [ + "## Библиотека Pandas\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2c093fc7", + "metadata": {}, + "outputs": [], + "source": [ + "import sqlite3 as sql\n", + "\n", + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "id": "e158cac9", + "metadata": {}, + "source": [ + "## Объекты DataFrame и Series\n", + "### Создание датафрейма\n", + "#### Способ 1. Создание датафрейма из файла" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2793b85", + "metadata": {}, + "outputs": [], + "source": [ + "csv_zip = pd.read_csv(\"/Users/dayal/Downloads/train.csv\")\n", + "csv_zip.head(3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5d3befdf", + "metadata": {}, + "outputs": [], + "source": [ + "excel_data = pd.read_excel(\"/Users/dayal/Downloads/iris.xlsx\", sheet_name=0)\n", + "excel_data.head(3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57ffa94c", + "metadata": {}, + "outputs": [], + "source": [ + "html_data = pd.read_html(\n", + " \"https://en.wikipedia.org/wiki/World_population\",\n", + " storage_options={\"User-Agent\": \"Mozilla/5.0\"},\n", + ")\n", + "html_data[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "824c3f95", + "metadata": {}, + "outputs": [], + "source": [ + "len(excel_data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c47c92d", + "metadata": {}, + "outputs": [], + "source": [ + "html_data[0]" + ] + }, + { + "cell_type": "markdown", + "id": "1f7c0261", + "metadata": {}, + "source": [ + "#### Способ 2. Подключение к базе данных SQL\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4f03e908", + "metadata": {}, + "outputs": [], + "source": [ + "conn = sql.connect(\"/Users/dayal/Downloads/chinook.db\")\n", + "\n", + "sql_data = pd.read_sql(\"SELECT * FROM tracks;\", conn)\n", + "\n", + "sql_data.head(3)" + ] + }, + { + "cell_type": "markdown", + "id": "2eba7e23", + "metadata": {}, + "source": [ + "#### Способ 3. Создание датафрейма из словаря\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "841a651d", + "metadata": {}, + "outputs": [], + "source": [ + "country: np.ndarray = np.array(\n", + " [\n", + " \"China\",\n", + " \"Vietnam\",\n", + " \"United Kingdom\",\n", + " \"Russia\",\n", + " \"Argentina\",\n", + " \"Bolivia\",\n", + " \"South Africa\",\n", + " ]\n", + ")\n", + "capital: list[str] = [\n", + " \"Beijing\",\n", + " \"Hanoi\",\n", + " \"London\",\n", + " \"Moscow\",\n", + " \"Buenos Aires\",\n", + " \"Sucre\",\n", + " \"Pretoria\",\n", + "]\n", + "population: list[int] = [1400, 97, 67, 144, 45, 12, 59]\n", + "area: list[float] = [9.6, 0.3, 0.2, 17.1, 2.8, 1.1, 1.2]\n", + "sea: list[int] = [1] * 5 + [0, 1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95fa6206", + "metadata": {}, + "outputs": [], + "source": [ + "countries_dict: dict[str, list[str] | list[int] | list[float]] = {}\n", + "\n", + "countries_dict[\"country\"] = list(country)\n", + "countries_dict[\"capital\"] = capital\n", + "countries_dict[\"population\"] = population\n", + "countries_dict[\"area\"] = area\n", + "countries_dict[\"sea\"] = sea" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b59f59f", + "metadata": {}, + "outputs": [], + "source": [ + "countries = pd.DataFrame(countries_dict)\n", + "countries" + ] + }, + { + "cell_type": "markdown", + "id": "8ab512ee", + "metadata": {}, + "source": [ + "#### Способ 4. Создание датафрейма из 2D массива Numpy\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ef37d52", + "metadata": {}, + "outputs": [], + "source": [ + "arr = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]])\n", + "\n", + "pd.DataFrame(arr)" + ] + }, + { + "cell_type": "markdown", + "id": "0d5a3ae7", + "metadata": {}, + "source": [ + "## Структура и свойства датафрейма\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0816402", + "metadata": {}, + "outputs": [], + "source": [ + "countries.columns" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7982c280", + "metadata": {}, + "outputs": [], + "source": [ + "countries.index" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ad80058", + "metadata": {}, + "outputs": [], + "source": [ + "countries.values" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8210d8ea", + "metadata": {}, + "outputs": [], + "source": [ + "countries.axes[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4189e447", + "metadata": {}, + "outputs": [], + "source": [ + "countries.axes[1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17a568db", + "metadata": {}, + "outputs": [], + "source": [ + "countries.ndim, countries.shape, countries.size" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "063beee3", + "metadata": {}, + "outputs": [], + "source": [ + "countries.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7a81b65", + "metadata": {}, + "outputs": [], + "source": [ + "countries.memory_usage()" + ] + }, + { + "cell_type": "markdown", + "id": "3335bf25", + "metadata": {}, + "source": [ + "## Индекс\n", + "### Присвоение индекса\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8d8876f", + "metadata": {}, + "outputs": [], + "source": [ + "custom_index: list[str] = [\"CN\", \"VN\", \"GB\", \"RU\", \"AR\", \"BO\", \"ZA\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20756fd9", + "metadata": {}, + "outputs": [], + "source": [ + "countries = pd.DataFrame(countries_dict, index=custom_index)\n", + "countries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eec6aac3", + "metadata": {}, + "outputs": [], + "source": [ + "countries.reset_index(inplace=True)\n", + "countries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a667dae", + "metadata": {}, + "outputs": [], + "source": [ + "countries.set_index(\"index\", inplace=True)\n", + "countries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07d8e2c6", + "metadata": {}, + "outputs": [], + "source": [ + "countries.reset_index(drop=True, inplace=True)\n", + "countries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c67a1fac", + "metadata": {}, + "outputs": [], + "source": [ + "countries.index = pd.Index(custom_index)\n", + "countries" + ] + }, + { + "cell_type": "markdown", + "id": "20ebe559", + "metadata": {}, + "source": [ + "## Многоуровневый индекс\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20a37055", + "metadata": {}, + "outputs": [], + "source": [ + "rows: list[tuple[str, str]] = [\n", + " (\"Asia\", \"CN\"),\n", + " (\"Asia\", \"VN\"),\n", + " (\"Europe\", \"GB\"),\n", + " (\"Europe\", \"RU\"),\n", + " (\"S. America\", \"AR\"),\n", + " (\"S. America\", \"BO\"),\n", + " (\"Africa\", \"ZA\"),\n", + "]\n", + "\n", + "cols: list[tuple[str, str]] = [\n", + " (\"names\", \"country\"),\n", + " (\"names\", \"capital\"),\n", + " (\"data\", \"population\"),\n", + " (\"data\", \"area\"),\n", + " (\"data\", \"sea\"),\n", + "]\n", + "\n", + "custom_multindex = pd.MultiIndex.from_tuples(rows, names=[\"region\", \"code\"])\n", + "custom_multicols = pd.MultiIndex.from_tuples(cols)\n", + "\n", + "countries.index = pd.Index(custom_multindex)\n", + "countries.columns = custom_multicols\n", + "\n", + "countries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec279325", + "metadata": {}, + "outputs": [], + "source": [ + "custom_cols = [\"country\", \"capital\", \"population\", \"area\", \"sea\"]\n", + "\n", + "countries.index = pd.Index(custom_index)\n", + "countries.columns = custom_cols\n", + "\n", + "countries" + ] + }, + { + "cell_type": "markdown", + "id": "c99e0468", + "metadata": {}, + "source": [ + "## Преобразование в другие форматы\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc3b5b4f", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.to_dict())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4468b272", + "metadata": {}, + "outputs": [], + "source": [ + "countries.to_numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4f8cce1", + "metadata": {}, + "outputs": [], + "source": [ + "countries.to_csv(\"countries.csv\", index=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "db26f235", + "metadata": {}, + "outputs": [], + "source": [ + "countries.country.tolist()" + ] + }, + { + "cell_type": "markdown", + "id": "fa5f8b7d", + "metadata": {}, + "source": [ + "## Создание Series\n", + "### Создание Series из списка\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "421a18d9", + "metadata": {}, + "outputs": [], + "source": [ + "country_list: list[str] = [\n", + " \"China\",\n", + " \"South Africa\",\n", + " \"United Kingdom\",\n", + " \"Russia\",\n", + " \"Argentina\",\n", + " \"Vietnam\",\n", + " \"Australia\",\n", + "]\n", + "\n", + "country_series = pd.Series(country_list, dtype=str)\n", + "country_series" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d9bef8f", + "metadata": {}, + "outputs": [], + "source": [ + "country_series.iloc[0]" + ] + }, + { + "cell_type": "markdown", + "id": "c815e657", + "metadata": {}, + "source": [ + "## Создание Series из словаря\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d76dd2c1", + "metadata": {}, + "outputs": [], + "source": [ + "country_dict: dict[str, str] = {\n", + " \"CN\": \"China\",\n", + " \"ZA\": \"South Africa\",\n", + " \"GB\": \"United Kingdom\",\n", + " \"RU\": \"Russia\",\n", + " \"AR\": \"Argentina\",\n", + " \"VN\": \"Vietnam\",\n", + " \"AU\": \"Australia\",\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21ec391c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "pandas.core.series.Series" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "country_series_2: pd.Series[float] = pd.Series(country_dict)\n", + "country_series_2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9eba8364", + "metadata": {}, + "outputs": [], + "source": [ + "country_series_2.loc[\"RU\"]" + ] + }, + { + "cell_type": "markdown", + "id": "7ee4814b", + "metadata": {}, + "source": [ + "## Доступ к строкам и столбцам\n", + "### Циклы в датафрейме\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ba80c06a", + "metadata": {}, + "outputs": [], + "source": [ + "for column in countries:\n", + " print(column)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a8a5523", + "metadata": {}, + "outputs": [], + "source": [ + "for index, row in countries.iterrows():\n", + " print(index)\n", + " print(row)\n", + " print(\"...\")\n", + " print(type(row))\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbf0ada3", + "metadata": {}, + "outputs": [], + "source": [ + "for _, row in countries.iterrows():\n", + " print(row[\"capital\"] + \" is the capital if \" + row[\"country\"])\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "d0b78e49", + "metadata": {}, + "source": [ + "## Доступ к столбцам\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c5726eb", + "metadata": {}, + "outputs": [], + "source": [ + "countries[\"capital\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ccfb612", + "metadata": {}, + "outputs": [], + "source": [ + "countries.capital" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dfc4f16", + "metadata": {}, + "outputs": [], + "source": [ + "type(countries.capital)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57886a88", + "metadata": {}, + "outputs": [], + "source": [ + "countries[[\"capital\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72eaa805", + "metadata": {}, + "outputs": [], + "source": [ + "countries[[\"capital\", \"area\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e4d7c4f", + "metadata": {}, + "outputs": [], + "source": [ + "countries.filter(items=[\"capital\", \"population\"])" + ] + }, + { + "cell_type": "markdown", + "id": "2025fef2", + "metadata": {}, + "source": [ + "## Доступ к строкам\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e98ef47e", + "metadata": {}, + "outputs": [], + "source": [ + "countries[1:5]" + ] + }, + { + "cell_type": "markdown", + "id": "db3c76a6", + "metadata": {}, + "source": [ + "## Методы .loc[] и .iloc[]\n", + "### Метод .loc[]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "369583af", + "metadata": {}, + "outputs": [], + "source": [ + "countries.loc[[\"CN\", \"RU\", \"VN\"], [\"capital\", \"population\", \"area\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e058e623", + "metadata": {}, + "outputs": [], + "source": [ + "countries.loc[:, [\"capital\", \"population\", \"area\"]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3dd242e9", + "metadata": {}, + "outputs": [], + "source": [ + "countries.loc[:, [False, False, False, False, True]]" + ] + }, + { + "cell_type": "markdown", + "id": "6b475413", + "metadata": {}, + "source": [ + "## Метод .get_loc()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f823381e", + "metadata": {}, + "outputs": [], + "source": [ + "countries.index.get_loc(\"RU\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbc3cf21", + "metadata": {}, + "outputs": [], + "source": [ + "countries.columns.get_loc(\"country\")" + ] + }, + { + "cell_type": "markdown", + "id": "eccf5fc5", + "metadata": {}, + "source": [ + "## Метод .iloc[]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f838b8e7", + "metadata": {}, + "outputs": [], + "source": [ + "countries.iloc[[0, 3, 5], [0, 1, 2]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ae5515e6", + "metadata": {}, + "outputs": [], + "source": [ + "countries.iloc[:3, -2:]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b7e2fc8a", + "metadata": {}, + "outputs": [], + "source": [ + "countries[[\"population\", \"area\"]].iloc[[0, 3]]" + ] + }, + { + "cell_type": "markdown", + "id": "1e58bcb8", + "metadata": {}, + "source": [ + "## Доступ по многоуровневому индексу\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0501825a", + "metadata": {}, + "outputs": [], + "source": [ + "countries.index = pd.Index(custom_multindex)\n", + "countries.columns = custom_multicols\n", + "\n", + "countries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c2964a74", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.loc[\"Asia\", \"CN\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d613238", + "metadata": {}, + "outputs": [], + "source": [ + "print(\n", + " countries.loc[\n", + " (\"Asia\", \"CN\"), [(\"data\", \"population\"), (\"data\", \"area\"), (\"data\", \"sea\")]\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "daf99657", + "metadata": {}, + "outputs": [], + "source": [ + "countries.loc[(\"Asia\", [\"CN\", \"VN\"]), :]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e56949b", + "metadata": {}, + "outputs": [], + "source": [ + "countries.loc[\"Asia\", :]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b9a5ccbe", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.loc[:, [(\"names\", \"country\"), (\"data\", \"population\")]])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9005c782", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.iloc[3, [2, 3, 4]])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "60e15c22", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.xs(\"Europe\", level=\"region\", axis=0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b171cc5", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.xs((\"names\", \"country\"), axis=1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbc44511", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.xs(\"Europe\", axis=0).loc[:, (\"names\", slice(None))])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81798367", + "metadata": {}, + "outputs": [], + "source": [ + "countries.index = pd.Index(custom_index)\n", + "countries.columns = custom_cols\n", + "\n", + "countries" + ] + }, + { + "cell_type": "markdown", + "id": "44fb621b", + "metadata": {}, + "source": [ + "## Метод .at[]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4c0e62d", + "metadata": {}, + "outputs": [], + "source": [ + "countries.at[\"CN\", \"capital\"]" + ] + }, + { + "cell_type": "markdown", + "id": "96181ddb", + "metadata": {}, + "source": [ + "## Фильтры\n", + "### Логическая маска\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "66146a08", + "metadata": {}, + "outputs": [], + "source": [ + "countries.population > 1000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "575cb9f9", + "metadata": {}, + "outputs": [], + "source": [ + "countries[countries.population > 1000]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ae7ba6a", + "metadata": {}, + "outputs": [], + "source": [ + "countries[(countries.population > 50) & (countries.area < 2)]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a9c7615", + "metadata": {}, + "outputs": [], + "source": [ + "population_mask = countries.population > 70\n", + "area_mask: pd.Series[bool] = countries.population < 50\n", + "\n", + "mask: pd.Series[bool] = population_mask | area_mask\n", + "\n", + "countries[mask]" + ] + }, + { + "cell_type": "markdown", + "id": "3e9aa091", + "metadata": {}, + "source": [ + "## Метод .query()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5fa73113", + "metadata": {}, + "outputs": [], + "source": [ + "countries.query(\"population > 50 and area < 2\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7bb113ed", + "metadata": {}, + "outputs": [], + "source": [ + "countries.query('country == \"United Kingdom\"')" + ] + }, + { + "cell_type": "markdown", + "id": "3b5820e3", + "metadata": {}, + "source": [ + "## Другие способы фильтрации\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7298a4d8", + "metadata": {}, + "outputs": [], + "source": [ + "keyword_list = [\"Beijing\", \"Moscow\", \"Hanoi\"]\n", + "\n", + "print(countries[countries.capital.isin(keyword_list)])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ddff5aa", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries[~countries.country.str.startswith(\"A\")])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7303d18", + "metadata": {}, + "outputs": [], + "source": [ + "countries.nlargest(3, \"population\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82468def", + "metadata": {}, + "outputs": [], + "source": [ + "countries.area.argmax()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "acfbd12f", + "metadata": {}, + "outputs": [], + "source": [ + "print(countries.iloc[[countries.area.argmax()]])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04d5ef94", + "metadata": {}, + "outputs": [], + "source": [ + "countries.loc[countries.population > 90, :]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "01e0002c", + "metadata": {}, + "outputs": [], + "source": [ + "countries.filter(like=\"ZA\", axis=0)" + ] + }, + { + "cell_type": "markdown", + "id": "bb25ba4b", + "metadata": {}, + "source": [ + "## Сортировка\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b572e696", + "metadata": {}, + "outputs": [], + "source": [ + "countries.sort_values(by=\"population\", inplace=False, ascending=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f75dcbeb", + "metadata": {}, + "outputs": [], + "source": [ + "countries.sort_values(by=[\"area\", \"population\"], inplace=False, ascending=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4cfb597c", + "metadata": {}, + "outputs": [], + "source": [ + "countries.sort_index()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_1_variables_in_python.ipynb b/python_issue/makarov/chapter_1_variables_in_python.ipynb new file mode 100644 index 00000000..5cb44e65 --- /dev/null +++ b/python_issue/makarov/chapter_1_variables_in_python.ipynb @@ -0,0 +1,298 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "35abf7c3", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Variables in Python.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "18bf192c", + "metadata": {}, + "source": [ + "## Переменные в Питоне" + ] + }, + { + "cell_type": "markdown", + "id": "b827dbee", + "metadata": {}, + "source": [ + "### Создание (объявление) переменных\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbac710f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "15\n" + ] + } + ], + "source": [ + "x_var: int = 15\n", + "print(x_var)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32bd5c4b", + "metadata": {}, + "outputs": [], + "source": [ + "y_var: str = \"Я программирую на Питоне\"\n", + "print(y_var)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b5cd62f", + "metadata": {}, + "outputs": [], + "source": [ + "a_var: str = \"Python\"\n", + "b_var: str = \"C++\"\n", + "c_var: str = \"PHP\"\n", + "\n", + "print(a_var, b_var, c_var)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbe8adf6", + "metadata": {}, + "outputs": [], + "source": [ + "x_var_1 = y_var_1 = z_var_1 = \"same value\"\n", + "print(x_var_1, y_var_1, z_var_1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d48fbf87", + "metadata": {}, + "outputs": [], + "source": [ + "my_list: list[str] = [\"tomatoes\", \"cucumbers\", \"potatoes\"]\n", + "a_var_1, b_var_1, c_var_1 = my_list\n", + "print(a_var_1, b_var_1, c_var_1)" + ] + }, + { + "cell_type": "markdown", + "id": "c07c1643", + "metadata": {}, + "source": [ + "### Автоматическое определение типа данных\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c2e67869", + "metadata": {}, + "outputs": [], + "source": [ + "x_var_2: int = 256\n", + "y_var_2: float = 0.25\n", + "z_var_2: str = \"just text\"\n", + "\n", + "# Как узнать тип переменной в Питоне\n", + "print(type(x_var_2), type(y_var_2), type(z_var_2))" + ] + }, + { + "cell_type": "markdown", + "id": "ba450cb8", + "metadata": {}, + "source": [ + "### Присвоение и преобразование типа данных" + ] + }, + { + "cell_type": "markdown", + "id": "c7b34325", + "metadata": {}, + "source": [ + "#### Присвоение типа данных\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e53ae78c", + "metadata": {}, + "outputs": [], + "source": [ + "x_var_3: str = str(25)\n", + "y_var_3: int = int(25)\n", + "z_var_3: float = float(25)\n", + "\n", + "print(type(x_var_3), type(y_var_3), type(z_var_3))" + ] + }, + { + "cell_type": "markdown", + "id": "2dd4516c", + "metadata": {}, + "source": [ + "#### Изменение типа данных" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efe7770a", + "metadata": {}, + "outputs": [], + "source": [ + "# Изменение типа данных\n", + "print(type(int(\"25\")))\n", + "print(type(float(\"2.5\")))\n", + "print(int(\"36.6\"))\n", + "print(type(int(\"36.6\")))\n", + "print(type(str(25)))\n", + "print(str)" + ] + }, + { + "cell_type": "markdown", + "id": "630c4c59", + "metadata": {}, + "source": [ + "### Именование переменных" + ] + }, + { + "cell_type": "markdown", + "id": "a5f7b4e6", + "metadata": {}, + "source": [ + "#### Допустимые имена переменных" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8a2cb5ad", + "metadata": {}, + "outputs": [], + "source": [ + "# variable: str = \"just variable\"\n", + "# _variable: str = \"just variable\"\n", + "variable_: str = \"just variable\"\n", + "my_variable: str = \"just variable\"\n", + "My_variable_123: str = \"just variable\"" + ] + }, + { + "cell_type": "markdown", + "id": "44d0a79a", + "metadata": {}, + "source": [ + "#### Имя переменной состоит из нескольких слов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1e2c0817", + "metadata": {}, + "outputs": [], + "source": [ + "# camelCaseVariable: str = \"camel case variable\"\n", + "# PascalCaseVariable: str = \"pascal case variable\"\n", + "snake_case_variable: str = \"snake case variable\"" + ] + }, + { + "cell_type": "markdown", + "id": "f2a00820", + "metadata": {}, + "source": [ + "#### Недопустимые названия переменной" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a777333", + "metadata": {}, + "outputs": [], + "source": [ + "# my-variable = 'WRONG'\n", + "# 123variable = 'WRONG'\n", + "# my variable = 'WRONG'" + ] + }, + { + "cell_type": "markdown", + "id": "89367e62", + "metadata": {}, + "source": [ + "### Как конвертировать список чисел в строки \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51439cda", + "metadata": {}, + "outputs": [], + "source": [ + "list_: list[int] = [1, 2, 3]\n", + "str(list_) # -> Wrong answer\n", + "\n", + "# 1\n", + "list_str: list[str] = []\n", + "\n", + "for i in list_:\n", + " list_str.append(str(i))\n", + "\n", + "print(list_str)\n", + "\n", + "# 2\n", + "print([str(x) for x in list_])\n", + "\n", + "# 3\n", + "print(list(map(str, list_)))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_2_data_types_in_python.ipynb b/python_issue/makarov/chapter_2_data_types_in_python.ipynb new file mode 100644 index 00000000..b9c36f14 --- /dev/null +++ b/python_issue/makarov/chapter_2_data_types_in_python.ipynb @@ -0,0 +1,605 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "id": "b19c46ef", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Data types in Python.'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"Data types in Python.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "c33121e2", + "metadata": {}, + "source": [ + "## Типы данных в Питоне\n" + ] + }, + { + "cell_type": "markdown", + "id": "c6264de4", + "metadata": {}, + "source": [ + "### Работа с числами\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "02e57699", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25 2.5 (3+25j)\n" + ] + } + ], + "source": [ + "a_var: int = 25\n", + "b_var: float = 2.5\n", + "c_var: complex = 3 + 25j\n", + "\n", + "print(a_var, b_var, c_var)" + ] + }, + { + "cell_type": "markdown", + "id": "9ed671a1", + "metadata": {}, + "source": [ + "##### Экспоненциальная запись, 2 умножить на 10 в степени 3\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "733fc284", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2000.0\n", + "\n" + ] + } + ], + "source": [ + "d_var: float = 2e3\n", + "print(d_var)\n", + "print(type(d_var))" + ] + }, + { + "cell_type": "markdown", + "id": "b6964bce", + "metadata": {}, + "source": [ + "#### Арифметические операции" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8bc45a8a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4 2 4 2.0 8\n" + ] + } + ], + "source": [ + "# Ниже закомментил потому что линтеры сильно ругаются на операции итак понятные\n", + "print(2 + 2, 4 - 2, 2 * 2, 4 / 2, 2**3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cecaadd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "1\n" + ] + } + ], + "source": [ + "print(7 // 2)\n", + "print(7 % 2)" + ] + }, + { + "cell_type": "markdown", + "id": "28b67761", + "metadata": {}, + "source": [ + "#### Операторы сравнения\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a35c5d42", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "True\n" + ] + } + ], + "source": [ + "# print(2 == 4)\n", + "# print(2 != 4)" + ] + }, + { + "cell_type": "markdown", + "id": "8a5e48a7", + "metadata": {}, + "source": [ + "#### Логические операции" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1c98e18", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n", + "False\n" + ] + } + ], + "source": [ + "# print(4 > 2 and 2 != 3)\n", + "# print(4 < 2 or 2 == 2)\n", + "# print(not (4 == 4))" + ] + }, + { + "cell_type": "markdown", + "id": "d92c9161", + "metadata": {}, + "source": [ + "#### Перевод чисел в другую систему счисления\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "61e3409a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0b11001\n", + "25\n" + ] + } + ], + "source": [ + "d_var_1: int = 25\n", + "\n", + "bin_d: str = bin(d_var_1)\n", + "print(bin_d)\n", + "\n", + "print(int(bin_d, 2))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "20dee5dc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0o31\n", + "25\n" + ] + } + ], + "source": [ + "d_var_2: int = 25\n", + "\n", + "oct_d: str = oct(d_var_2)\n", + "print(oct_d)\n", + "\n", + "print(int(oct_d, 8))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "4a2a223a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0x19\n", + "25\n" + ] + } + ], + "source": [ + "d_var_3: int = 25\n", + "\n", + "hex_d: str = hex(d_var_3)\n", + "print(hex_d)\n", + "\n", + "print(int(hex_d, 16))" + ] + }, + { + "cell_type": "markdown", + "id": "c5f2534a", + "metadata": {}, + "source": [ + "### Строковые данные" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "48123d13", + "metadata": {}, + "outputs": [], + "source": [ + "string_1: str = \"string\"\n", + "string_2: str = \"also string\"\n", + "\n", + "multi_string: str = \"\"\"Мы все учились понемногу\n", + "Чему-нибудь и как-нибудь,\n", + "Так воспитаньем, слава богу,\n", + "У нас немудрено блеснуть.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "1fb4df4e", + "metadata": {}, + "source": [ + "#### Длина строки" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "ddcd6683", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "105" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(multi_string)" + ] + }, + { + "cell_type": "markdown", + "id": "71e03dcc", + "metadata": {}, + "source": [ + "#### Объединение строк\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "b8adbff7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'programming on python'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a_var_3: str = \"programming\"\n", + "b_var_3: str = \"on\"\n", + "c_var_3: str = \"python\"\n", + "a_var_3 + \" \" + b_var_3 + \" \" + c_var_3" + ] + }, + { + "cell_type": "markdown", + "id": "bebabc0e", + "metadata": {}, + "source": [ + "#### Индекс символа в строке и Срезы строк" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "b7a1da48", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "М\n", + ".\n", + "все\n", + "Мы\n", + "все учились понемногу\n", + "Чему-нибудь и как-нибудь,\n", + "Так воспитаньем, слава богу,\n", + "У нас немудрено блеснуть.\n" + ] + } + ], + "source": [ + "print(multi_string[0])\n", + "print(multi_string[-1])\n", + "\n", + "print(multi_string[3:6])\n", + "print(multi_string[:2])\n", + "print(multi_string[3:])" + ] + }, + { + "cell_type": "markdown", + "id": "94f16604", + "metadata": {}, + "source": [ + "#### Циклы в строках" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "49fe9505", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "P\n", + "y\n", + "t\n", + "h\n", + "o\n", + "n\n" + ] + } + ], + "source": [ + "for i in \"Python\":\n", + " print(i)" + ] + }, + { + "cell_type": "markdown", + "id": "ce5f2281", + "metadata": {}, + "source": [ + "#### Методы .strip() и .split()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "a697fe63", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "15 489 302\n", + "15 849 302\n" + ] + } + ], + "source": [ + "print(\"********15 489 302**************\".strip(\"*\"))\n", + "\n", + "print(\" 15 849 302 \".strip())" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "e708bb77", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Мы', 'все', 'учились', 'понемногу', 'Чему-нибудь', 'и', 'как-нибудь,', 'Так', 'воспитаньем,', 'слава', 'богу,', 'У', 'нас', 'немудрено', 'блеснуть.']\n" + ] + } + ], + "source": [ + "print(multi_string.split())" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "ba7d9094", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "15" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(multi_string.split())" + ] + }, + { + "cell_type": "markdown", + "id": "43c5c63f", + "metadata": {}, + "source": [ + "#### Замена символа в строке" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "87a9cb5f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "20.25\n", + "\n" + ] + } + ], + "source": [ + "data_var_3: str = \"20,25\"\n", + "\n", + "data_var_3_clean: str = data_var_3.replace(\",\", \".\")\n", + "\n", + "data_var_3_float: float = float(data_var_3_clean)\n", + "print(data_var_3_float)\n", + "print(type(data_var_3_float))" + ] + }, + { + "cell_type": "markdown", + "id": "52cc77db", + "metadata": {}, + "source": [ + "### Логические значения" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "29bb3007", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "bool" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "var_var_3: bool = False\n", + "type(var_var_3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42c4823f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "var is false\n" + ] + } + ], + "source": [ + "if var_var_3 is True:\n", + " print(\"var is true\")\n", + "else:\n", + " print(\"var is false\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_3_conditions_and_cycles.ipynb b/python_issue/makarov/chapter_3_conditions_and_cycles.ipynb new file mode 100644 index 00000000..b0d8e165 --- /dev/null +++ b/python_issue/makarov/chapter_3_conditions_and_cycles.ipynb @@ -0,0 +1,573 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "dac1bf78", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Conditions and cycles.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "e3d2a04a", + "metadata": {}, + "source": [ + "## Условия и циклы. Продолжение" + ] + }, + { + "cell_type": "markdown", + "id": "5a38d22b", + "metadata": {}, + "source": [ + "#### Множественные условия (multi-way decisions)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "60b0211a", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "x_var: int = 42\n", + "\n", + "if x_var < 10:\n", + " print(\"Small\")\n", + "elif x_var < 100:\n", + " print(\"Medium\")\n", + "else:\n", + " print(\"Large\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fba08276", + "metadata": {}, + "outputs": [], + "source": [ + "x_var_1: str = input()\n", + "\n", + "x_int = int(x_var_1)\n", + "\n", + "if x_int < 10:\n", + " print(\"Small\")\n", + "elif x_int < 100:\n", + " print(\"Medium\")\n", + "else:\n", + " print(\"Large\")" + ] + }, + { + "cell_type": "markdown", + "id": "a1799ef1", + "metadata": {}, + "source": [ + "#### Вложенные условия (nested decisions)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d083e770", + "metadata": {}, + "outputs": [], + "source": [ + "y_var: str = input(\"Введите число: \")\n", + "\n", + "if len(y_var) != 0:\n", + " y_int = int(y_var)\n", + " if y_int < 10:\n", + " print(\"Small\")\n", + " elif y_int < 100:\n", + " print(\"Medium\")\n", + " else:\n", + " print(\"Large\")\n", + "else:\n", + " print(\"Ввод пустой\")" + ] + }, + { + "cell_type": "markdown", + "id": "9f654a62", + "metadata": {}, + "source": [ + "#### Несколько условий в одном выражении с операторами and или or" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1b88bdf5", + "metadata": {}, + "outputs": [], + "source": [ + "z_var: int = 42\n", + "\n", + "if 10 < z_var < 100:\n", + " print(\"Medium\")\n", + "else:\n", + " print(\"Small or Large\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "199494b4", + "metadata": {}, + "outputs": [], + "source": [ + "z_var_1: int = 2\n", + "\n", + "if z_var_1 < 10 or z_var_1 > 100:\n", + " print(\"Small or Large\")\n", + "else:\n", + " print(\"Medium\")" + ] + }, + { + "cell_type": "markdown", + "id": "862318da", + "metadata": {}, + "source": [ + "#### Проверка вхождения элемента в объект с in / not in\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c712580", + "metadata": {}, + "outputs": [], + "source": [ + "sentence: str = \"To be, or not to be, that is the question\"\n", + "word: str = \"question\"\n", + "\n", + "if word in sentence:\n", + " print(\"Слово найдено\")" + ] + }, + { + "cell_type": "markdown", + "id": "4576ec41", + "metadata": {}, + "source": [ + "## Циклы в Питоне" + ] + }, + { + "cell_type": "markdown", + "id": "f7084f8a", + "metadata": {}, + "source": [ + "### Цикл for Основные операции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1af4b4b3", + "metadata": {}, + "outputs": [], + "source": [ + "number_list: list[int] = [2, 3, 4, 6, 7]\n", + "number: int = 5\n", + "\n", + "if number not in number_list:\n", + " print(\"Такого числа в списке нет\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ade6451d", + "metadata": {}, + "outputs": [], + "source": [ + "d_var: dict[str, int] = {\"apple\": 3, \"tomato\": 6, \"carrot\": 2}\n", + "\n", + "if \"apple\" in d_var:\n", + " print(\"Нашлись\")\n", + "\n", + "if 6 in d_var.values():\n", + " print(\"Есть\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2386c7e", + "metadata": {}, + "outputs": [], + "source": [ + "number_list_1: list[int] = [1, 2, 3]\n", + "\n", + "for number in number_list_1:\n", + " print(number)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11fc2480", + "metadata": {}, + "outputs": [], + "source": [ + "d_var_1: dict[str, list[int | str]] = {\n", + " \"apple\": [3, \"kg\"],\n", + " \"tomato\": [6, \"pcs\"],\n", + " \"carrot\": [2, \"kg\"],\n", + "}\n", + "\n", + "for k_var_1, v_var_1 in d_var_1.items():\n", + " print(k_var_1, v_var_1)\n", + "\n", + "for v_var_2 in d_var_1.values():\n", + " print(v_var_2[0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3a1f234", + "metadata": {}, + "outputs": [], + "source": [ + "number_array: np.ndarray = np.array([1, 2, 3])\n", + "\n", + "for number in number_array:\n", + " print(number)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3c0f9c91", + "metadata": {}, + "outputs": [], + "source": [ + "clients_1: dict[int, dict[str, int | str]] = {\n", + " 1: {\"name\": \"Анна\", \"age\": 24, \"sex\": \"male\", \"revenue\": 12000},\n", + " 2: {\"name\": \"Илья\", \"age\": 18, \"sex\": \"female\", \"revenue\": 8000},\n", + "}\n", + "\n", + "for id_var_1, info in clients_1.items():\n", + "\n", + " print(\"client ID:\" + str(id_var_1))\n", + "\n", + " for k_var, v_var in info.items():\n", + " print(k_var + \": \" + str(v_var))\n", + "\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "2694495c", + "metadata": {}, + "source": [ + "#### Функция range()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19d1d1f2", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(5):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46a90fd2", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1, 6):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22760e8f", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(0, 6, 2):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "480111ba", + "metadata": {}, + "outputs": [], + "source": [ + "months: list[str] = [\n", + " \"Январь\",\n", + " \"Февраль\",\n", + " \"Март\",\n", + " \"Апрель\",\n", + " \"Май\",\n", + " \"Июнь\",\n", + " \"Июль\",\n", + " \"Август\",\n", + " \"Сентябрь\",\n", + " \"Октябрь\",\n", + " \"Ноябрь\",\n", + " \"Декабрь\",\n", + "]\n", + "sales: list[int] = [47, 75, 79, 94, 123, 209, 233, 214, 197, 130, 87, 55]\n", + "\n", + "for i, month in enumerate(months):\n", + " print(month, sales[i])" + ] + }, + { + "cell_type": "markdown", + "id": "79d424c4", + "metadata": {}, + "source": [ + "### Последовательность в обратном порядке\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15f5f8a0", + "metadata": {}, + "outputs": [], + "source": [ + "my_list: list[int] = [0, 1, 2, 3, 4]\n", + "\n", + "for i in reversed(my_list):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7330a855", + "metadata": {}, + "outputs": [], + "source": [ + "for i in reversed(range(5)):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b12052ef", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(4, 0, -1):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51dbda6f", + "metadata": {}, + "outputs": [], + "source": [ + "r_var: range = range(5)\n", + "\n", + "sorted_values: list[int] = sorted(r_var, reverse=True)\n", + "\n", + "for i in sorted_values:\n", + " print(i)" + ] + }, + { + "cell_type": "markdown", + "id": "303dbe72", + "metadata": {}, + "source": [ + "#### Функция enumerate()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e0f49465", + "metadata": {}, + "outputs": [], + "source": [ + "days: list[str] = [\n", + " \"Понедельник\",\n", + " \"Вторник\",\n", + " \"Среда\",\n", + " \"Четверг\",\n", + " \"Пятница\",\n", + " \"Суббота\",\n", + " \"Воскресенье\",\n", + "]\n", + "\n", + "for i, day in enumerate(days):\n", + " print(i, day)\n", + "\n", + "for i, day in enumerate(days, 1):\n", + " print(i, day)" + ] + }, + { + "cell_type": "markdown", + "id": "f106aeaa", + "metadata": {}, + "source": [ + "### Цикл while\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b389f3d1", + "metadata": {}, + "outputs": [], + "source": [ + "i_var: int = 0\n", + "\n", + "while i_var < 3:\n", + " print(\"Текущее значение счетчика: \" + str(i))\n", + " i_var = i_var + 1\n", + " print(\"Новое значение счетчика :\" + str(i))\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0e226430", + "metadata": {}, + "outputs": [], + "source": [ + "i_var_1: int = 0\n", + "\n", + "while i_var_1 < 3:\n", + " print(i_var_1)\n", + " i_var_1 += 1" + ] + }, + { + "cell_type": "markdown", + "id": "60028634", + "metadata": {}, + "source": [ + "### Break, continue\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "80956c03", + "metadata": {}, + "outputs": [], + "source": [ + "clients_1_var: dict[int, dict[str, int | str]] = {\n", + " 1: {\"name\": \"Анна\", \"age\": 24, \"sex\": \"male\", \"revenue\": 12000},\n", + " 2: {\"name\": \"Илья\", \"age\": 18, \"sex\": \"female\", \"revenue\": 8000},\n", + "}\n", + "\n", + "for id_var, info in clients_1_var.items():\n", + " print(id_var, info)\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42dfacb8", + "metadata": {}, + "outputs": [], + "source": [ + "x_var_2: int = 6\n", + "\n", + "while x_var_2 != 0:\n", + " print(x_var_2)\n", + " x_var_2 -= 1\n", + " if x_var_2 == 3:\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b158f43", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1, 11):\n", + " if i % 2 != 0:\n", + " continue\n", + " print(i)" + ] + }, + { + "cell_type": "markdown", + "id": "5933443f", + "metadata": {}, + "source": [ + "### Форматирование строк через f-строки и метод .format()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7fd259dd", + "metadata": {}, + "outputs": [], + "source": [ + "days_1: list[str] = [\n", + " \"Понедельник\",\n", + " \"Вторник\",\n", + " \"Среда\",\n", + " \"Четверг\",\n", + " \"Пятница\",\n", + " \"Суббота\",\n", + " \"Воскресенье\",\n", + "]\n", + "\n", + "monday: str = days_1[0]\n", + "print(monday)\n", + "\n", + "print(f\"{monday} - день тяжелый\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_4_files.ipynb b/python_issue/makarov/chapter_4_files.ipynb new file mode 100644 index 00000000..c1151404 --- /dev/null +++ b/python_issue/makarov/chapter_4_files.ipynb @@ -0,0 +1,254 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "4e429e18", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Files.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "f18bbc6a", + "metadata": {}, + "source": [ + "### Подгрузка файлов\n" + ] + }, + { + "cell_type": "markdown", + "id": "884d1ab7", + "metadata": {}, + "source": [ + "#### Способ 2. Через модуль files библиотеки google.colab" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b450f72", + "metadata": {}, + "outputs": [], + "source": [ + "# from google.colab import files - only in google.colab\n", + "import os\n", + "\n", + "import pandas as pd\n", + "\n", + "files: int = 0\n", + "# uploaded: int = files.upload()" + ] + }, + { + "cell_type": "markdown", + "id": "4e4e3794", + "metadata": {}, + "source": [ + "#### Модуль os и метод .walk()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc093751", + "metadata": {}, + "outputs": [], + "source": [ + "for dirpath, _, filenames in os.walk(\"/content/\"):\n", + " for filename in filenames:\n", + " print(os.path.join(dirpath, filename))" + ] + }, + { + "cell_type": "markdown", + "id": "b5752a1c", + "metadata": {}, + "source": [ + "#### Команда !ls\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "170cac8a", + "metadata": {}, + "outputs": [], + "source": [ + "!ls" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1d90ac0c", + "metadata": {}, + "outputs": [], + "source": [ + "!ls /content/sample_data/" + ] + }, + { + "cell_type": "markdown", + "id": "b8aac618", + "metadata": {}, + "source": [ + "### Чтение из переменной uploaded\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b5a54366", + "metadata": {}, + "outputs": [], + "source": [ + "# type(uploaded[\"test.csv\"])" + ] + }, + { + "cell_type": "markdown", + "id": "98b5b5eb", + "metadata": {}, + "source": [ + "#### Пример работы с объектом bytes\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b302e272", + "metadata": {}, + "outputs": [], + "source": [ + "# uploaded_str: str = uploaded[\"test.csv\"].decode()\n", + "# print(type(uploaded_str))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c37ffe88", + "metadata": {}, + "outputs": [], + "source": [ + "# print(uploaded_str[:35])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2235be0c", + "metadata": {}, + "outputs": [], + "source": [ + "# uploaded_list: str = uploaded_str.split(\"\\r\\n\")\n", + "# type(uploaded_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91e12b64", + "metadata": {}, + "outputs": [], + "source": [ + "# for i, line in enumerate(uploaded_list):\n", + "# print(line)\n", + "# if i == 3:\n", + "# break" + ] + }, + { + "cell_type": "markdown", + "id": "15a2f894", + "metadata": {}, + "source": [ + "#### Использование функции open() и конструкции with open()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e5613d8", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"/content/train.csv\", encoding=\"utf-8\") as f1:\n", + " print(f1.read(142))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a26d2e2", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"/content/train.csv\", encoding=\"utf-8\") as f2:\n", + " for i, line in enumerate(f2):\n", + " print(line.strip())\n", + " if i == 3:\n", + " break\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10e3ec9a", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"/content/train.csv\", encoding=\"utf-8\") as f3:\n", + " for i, line in enumerate(f3):\n", + " print(line.strip())\n", + " if i == 3:\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "862a8e05", + "metadata": {}, + "source": [ + "#### Чтение через библиотеку Pandas\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e43997b4", + "metadata": {}, + "outputs": [], + "source": [ + "train: pd.DataFrame = pd.read_csv(\"/content/train.csv\")\n", + "train.head(3)\n", + "test: pd.DataFrame = pd.read_csv(\"/content/test.csv\")\n", + "test.head(3)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_5_date_and_time_in_python.ipynb b/python_issue/makarov/chapter_5_date_and_time_in_python.ipynb new file mode 100644 index 00000000..2bc997e1 --- /dev/null +++ b/python_issue/makarov/chapter_5_date_and_time_in_python.ipynb @@ -0,0 +1,574 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "12c8371c", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Date and time in Python.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "6642bd1d", + "metadata": {}, + "source": [ + "## Дата и время в Питоне" + ] + }, + { + "cell_type": "markdown", + "id": "91d1d53b", + "metadata": {}, + "source": [ + "### Модуль datetime" + ] + }, + { + "cell_type": "markdown", + "id": "447a959f", + "metadata": {}, + "source": [ + "#### Импорт модуля и класса datetime\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ef8a1b1", + "metadata": {}, + "outputs": [], + "source": [ + "import datetime\n", + "\n", + "import pandas as pd\n", + "import pytz\n", + "\n", + "print(datetime.datetime.now())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3d21aef7", + "metadata": {}, + "outputs": [], + "source": [ + "print(datetime.datetime.now())" + ] + }, + { + "cell_type": "markdown", + "id": "be938c5b", + "metadata": {}, + "source": [ + "#### Объект datetime и функция now()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "a7760df4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2025-12-09 09:50:18.678632\n", + "\n" + ] + } + ], + "source": [ + "cur_dt: datetime.datetime = datetime.datetime.now()\n", + "print(cur_dt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e81712e9", + "metadata": {}, + "outputs": [], + "source": [ + "print(\n", + " cur_dt.year,\n", + " cur_dt.month,\n", + " cur_dt.day,\n", + " cur_dt.hour,\n", + " cur_dt.minute,\n", + " cur_dt.second,\n", + " cur_dt.microsecond,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b85c58e6", + "metadata": {}, + "outputs": [], + "source": [ + "print(cur_dt.weekday, cur_dt.isoweekday)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a9c2c11", + "metadata": {}, + "outputs": [], + "source": [ + "print(cur_dt.tzinfo)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d216be77", + "metadata": {}, + "outputs": [], + "source": [ + "dt_moscow: datetime.datetime = datetime.datetime.now(pytz.timezone(\"Europe/Moscow\"))\n", + "print(dt_moscow)\n", + "print(dt_moscow.tzinfo)" + ] + }, + { + "cell_type": "markdown", + "id": "38c4b906", + "metadata": {}, + "source": [ + "#### Timestamp\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ae8b032", + "metadata": {}, + "outputs": [], + "source": [ + "timestamp: float = datetime.datetime.now().timestamp()\n", + "print(timestamp)\n", + "print(datetime.datetime.fromtimestamp(timestamp))" + ] + }, + { + "cell_type": "markdown", + "id": "da01aa43", + "metadata": {}, + "source": [ + "#### Создание объекта datetime вручную\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7feaccbd", + "metadata": {}, + "outputs": [], + "source": [ + "hb: datetime.datetime = datetime.datetime(1991, 2, 20)\n", + "print(hb)\n", + "print(hb.year)\n", + "print(datetime.datetime.timestamp(hb))" + ] + }, + { + "cell_type": "markdown", + "id": "081abd5c", + "metadata": {}, + "source": [ + "### Преобразование строки в объект datetime и обратно" + ] + }, + { + "cell_type": "markdown", + "id": "2d4b0917", + "metadata": {}, + "source": [ + "### Строка -> datetime через .strptime()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1af9888e", + "metadata": {}, + "outputs": [], + "source": [ + "str_to_dt: str = \"2007-12-02 12:30:45\"\n", + "type(str_to_dt)\n", + "\n", + "res_dt: datetime.datetime = datetime.datetime.strptime(str_to_dt, \"%Y-%m-%d %H:%M:%S\")\n", + "print(res_dt)\n", + "print(type(res_dt))" + ] + }, + { + "cell_type": "markdown", + "id": "efc65c5b", + "metadata": {}, + "source": [ + "### Datetime -> строка через .strftime()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78ddb9d1", + "metadata": {}, + "outputs": [], + "source": [ + "dt_to_str: datetime.datetime = datetime.datetime(2002, 11, 19)\n", + "print(type(dt_to_str))\n", + "\n", + "res_str: str = datetime.datetime.strftime(dt_to_str, \"%A, %B %d, %Y\")\n", + "\n", + "print(res_str)\n", + "print(type(res_str))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34af38f6", + "metadata": {}, + "outputs": [], + "source": [ + "dt_to_str.strftime(\"%A, %B %d, %Y\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "646c124b", + "metadata": {}, + "outputs": [], + "source": [ + "datetime.datetime.now().strftime(\"%Y-%m-%d\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "477d7a46", + "metadata": {}, + "outputs": [], + "source": [ + "datetime.datetime.now().strftime(\"%c\")" + ] + }, + { + "cell_type": "markdown", + "id": "52c1f3da", + "metadata": {}, + "source": [ + "### Сравнение и арифметика дат\n" + ] + }, + { + "cell_type": "markdown", + "id": "52f2213e", + "metadata": {}, + "source": [ + "#### Сравнение дат" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "659df035", + "metadata": {}, + "outputs": [], + "source": [ + "date1: datetime.datetime = datetime.datetime(1905, 6, 30)\n", + "date2: datetime.datetime = datetime.datetime(1916, 5, 11)\n", + "\n", + "# date1 < date2\n", + "# date1 > date2" + ] + }, + { + "cell_type": "markdown", + "id": "b6020ecf", + "metadata": {}, + "source": [ + "#### Календарный и алфавитный порядок дат\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "174a8370", + "metadata": {}, + "outputs": [], + "source": [ + "# \"2007-12-02\" > \"2002-11-19\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6992b657", + "metadata": {}, + "outputs": [], + "source": [ + "# datetime.datetime(2007, 12, 2) > datetime.datetime(2002, 11, 19)" + ] + }, + { + "cell_type": "markdown", + "id": "48b23223", + "metadata": {}, + "source": [ + "#### Промежуток времени и класс timedelta\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99ac12eb", + "metadata": {}, + "outputs": [], + "source": [ + "diff: datetime.timedelta = date2 - date1\n", + "print(diff)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7594c503", + "metadata": {}, + "outputs": [], + "source": [ + "type(diff)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4f6b146a", + "metadata": {}, + "outputs": [], + "source": [ + "print(diff.days)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a63d8ea", + "metadata": {}, + "outputs": [], + "source": [ + "datetime.timedelta(days=1)" + ] + }, + { + "cell_type": "markdown", + "id": "ed3d2fee", + "metadata": {}, + "source": [ + "#### Арифметика дат\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f1688854", + "metadata": {}, + "outputs": [], + "source": [ + "future: datetime.datetime = datetime.datetime(2070, 1, 1)\n", + "future" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e000554a", + "metadata": {}, + "outputs": [], + "source": [ + "time_travel_var: datetime.timedelta = datetime.timedelta(days=365) * 170\n", + "\n", + "past_var: datetime.datetime = future - time_travel_var\n", + "past_var" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a50ce805", + "metadata": {}, + "outputs": [], + "source": [ + "# datetime.datetime(2070, 1, 1) - datetime.datetime(1900, 1, 1)\n", + "time_travel: datetime.timedelta = datetime.timedelta(days=62092)\n", + "\n", + "past: datetime.datetime = future - time_travel\n", + "past" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "984335ea", + "metadata": {}, + "outputs": [], + "source": [ + "cur_date: datetime.datetime = datetime.datetime(2021, 1, 1)\n", + "end_date: datetime.datetime = datetime.datetime(2021, 1, 10)\n", + "\n", + "while cur_date <= end_date:\n", + " print(cur_date.strftime(\"%b %d, %Y\"))\n", + " cur_date += datetime.timedelta(days=1)" + ] + }, + { + "cell_type": "markdown", + "id": "4d3e2c56", + "metadata": {}, + "source": [ + "### Дата и обработка ошибок" + ] + }, + { + "cell_type": "markdown", + "id": "ad07b7b0", + "metadata": {}, + "source": [ + "#### Конструкция try/except и оператор pass\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0972949", + "metadata": {}, + "outputs": [], + "source": [ + "numbers: list[str] = [\"5\", \"10\", \"a\", \"15\", \"10\"]\n", + "\n", + "total: int = 0\n", + "\n", + "for number in numbers:\n", + " try:\n", + " total += int(number)\n", + " except ValueError:\n", + " pass\n", + "\n", + "total" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b32ee7c6", + "metadata": {}, + "outputs": [], + "source": [ + "total_var: int = 0\n", + "\n", + "for number in numbers:\n", + " try:\n", + " total_var += int(number)\n", + " except ValueError:\n", + " print(f\"Элемент '{number}' обработать не удалось\")\n", + "\n", + "total_var" + ] + }, + { + "cell_type": "markdown", + "id": "3f0469b6", + "metadata": {}, + "source": [ + "#### Обработка нескольких форматов дат\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42ed8530", + "metadata": {}, + "outputs": [], + "source": [ + "temp: pd.DataFrame = pd.read_csv(\"temperature.csv\")\n", + "temp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b7d1ef4", + "metadata": {}, + "outputs": [], + "source": [ + "formats_var: list[str] = [\"%Y-%m-%d\", \"%Y-%m-%-d\", \"%Y-%m\"]\n", + "\n", + "counter: int = 0\n", + "\n", + "for d_var in temp.Date:\n", + " for format_var in formats_var:\n", + " try:\n", + " print(datetime.datetime.strptime(d_var, format_var))\n", + " counter += 1\n", + " except ValueError:\n", + " pass\n", + "\n", + "print(\"Не отобразилось записей:\", len(temp) - counter)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a6cb86d", + "metadata": {}, + "outputs": [], + "source": [ + "temp_parsed: pd.DataFrame = pd.read_csv(\n", + " \"temperature.csv\", index_col=\"Date\", parse_dates=True\n", + ")\n", + "temp_parsed" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4fb4feea", + "metadata": {}, + "outputs": [], + "source": [ + "type(temp_parsed.index)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_6_functions.ipynb b/python_issue/makarov/chapter_6_functions.ipynb new file mode 100644 index 00000000..5fbb0d26 --- /dev/null +++ b/python_issue/makarov/chapter_6_functions.ipynb @@ -0,0 +1,1013 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "fd74efb8", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Functions in Python.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "3b354284", + "metadata": {}, + "source": [ + "## Функции в Питоне" + ] + }, + { + "cell_type": "markdown", + "id": "2ca0ded8", + "metadata": {}, + "source": [ + "### Встроенные функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a6487ab", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "np.random.seed(42)\n", + "height: list[np.float64] = list(np.round(np.random.normal(180, 10, 1000)))\n", + "height" + ] + }, + { + "cell_type": "markdown", + "id": "cbe2b58a", + "metadata": {}, + "source": [ + "### Параметры и аргументы функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a38ce06", + "metadata": {}, + "outputs": [], + "source": [ + "plt.hist(height, bins=10)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a850b21f", + "metadata": {}, + "outputs": [], + "source": [ + "plt.hist(bins=10, x=height)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbb2c5a2", + "metadata": {}, + "outputs": [], + "source": [ + "plt.hist(height)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b411a442", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"first string\")\n", + "print()\n", + "print(\"second string\")" + ] + }, + { + "cell_type": "markdown", + "id": "5c6d5be6", + "metadata": {}, + "source": [ + "### Функции и методы\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec160f2c", + "metadata": {}, + "outputs": [], + "source": [ + "some_string: str = \"machine learning\"\n", + "some_string.title()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5335445", + "metadata": {}, + "outputs": [], + "source": [ + "# some_list: list[str] = [\"machine\", \"learning\"]\n", + "# some_list.title() -> wrong" + ] + }, + { + "cell_type": "markdown", + "id": "0ef50196", + "metadata": {}, + "source": [ + "### Собственные функции в Питоне" + ] + }, + { + "cell_type": "markdown", + "id": "ff88bedf", + "metadata": {}, + "source": [ + "### Объявление и вызов функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46799e44", + "metadata": {}, + "outputs": [], + "source": [ + "def double(x_var: int | float) -> int | float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " res_var: int | float = x_var * 2\n", + " return res_var\n", + "\n", + "\n", + "double(2)" + ] + }, + { + "cell_type": "markdown", + "id": "8dec5352", + "metadata": {}, + "source": [ + "### Пустое тело функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "024cf1d3", + "metadata": {}, + "outputs": [], + "source": [ + "# def only_return():\n", + "# \"\"\"\n", + "# Temporary training function used to practice Python syntax,\n", + "\n", + "# typing, and code style. Not intended for production use.\n", + "# \"\"\"\n", + "# return\n", + "\n", + "\n", + "# only_return()\n", + "\n", + "# print(only_return())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b4941f3", + "metadata": {}, + "outputs": [], + "source": [ + "# def only_pass():\n", + "# \"\"\"\n", + "# Temporary training function used to practice Python syntax,\n", + "\n", + "# typing, and code style. Not intended for production use.\n", + "# \"\"\"\n", + "# pass\n", + "\n", + "\n", + "# only_pass()" + ] + }, + { + "cell_type": "markdown", + "id": "bc45cde6", + "metadata": {}, + "source": [ + "### Функция print() вместо return\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dbfe860c", + "metadata": {}, + "outputs": [], + "source": [ + "def double_print(x_var_1: int | float) -> None:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " res: int | float = x_var_1 * 2\n", + " print(res)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1da4076a", + "metadata": {}, + "outputs": [], + "source": [ + "double_print(5)" + ] + }, + { + "cell_type": "markdown", + "id": "cb6da6b3", + "metadata": {}, + "source": [ + "#### Параметры собственных функций\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18e48afe", + "metadata": {}, + "outputs": [], + "source": [ + "def calc_sum(x_var_2: int | float, y_var_2: int | float) -> int | float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return x_var_2 + y_var_2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "83515955", + "metadata": {}, + "outputs": [], + "source": [ + "calc_sum(1, y_var_2=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22089bf9", + "metadata": {}, + "outputs": [], + "source": [ + "def calc_sum_default(x_var_3: int | float = 1, y_var_3: int | float = 2) -> int | float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return x_var_3 + y_var_3\n", + "\n", + "\n", + "calc_sum_default()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c98e7a7", + "metadata": {}, + "outputs": [], + "source": [ + "def print_string() -> None:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " print(\"some string\")\n", + "\n", + "\n", + "print_string()" + ] + }, + { + "cell_type": "markdown", + "id": "44bc9c8e", + "metadata": {}, + "source": [ + "### Аннотация функции\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a848c8a2", + "metadata": {}, + "outputs": [], + "source": [ + "def f(x_var_4: float = 3.5) -> int:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return int(x_var_4)\n", + "\n", + "\n", + "f.__annotations__\n", + "\n", + "f()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "399781d3", + "metadata": {}, + "outputs": [], + "source": [ + "def f_1(x_var_5: float) -> float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return float(x_var_5)\n", + "\n", + "\n", + "f_1(3)" + ] + }, + { + "cell_type": "markdown", + "id": "fc223b44", + "metadata": {}, + "source": [ + "### Дополнительные возможности\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "832e8f1f", + "metadata": {}, + "outputs": [], + "source": [ + "print(calc_sum(1, 2) * 2)\n", + "print(calc_sum(1, 2) > 2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5fc19356", + "metadata": {}, + "outputs": [], + "source": [ + "def first_letter() -> str:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return \"Python\"\n", + "\n", + "\n", + "print(first_letter()[0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73a741b4", + "metadata": {}, + "outputs": [], + "source": [ + "def use_input() -> int:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " user_input: int = int(input(\"Введите число: \"))\n", + " result: int = user_input**2\n", + " return result\n", + "\n", + "\n", + "use_input()" + ] + }, + { + "cell_type": "markdown", + "id": "ad553a42", + "metadata": {}, + "source": [ + "### Результат вызова функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44bee447", + "metadata": {}, + "outputs": [], + "source": [ + "def create_list(x_var_6: int) -> list[int]:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " list_var_3: list[int] = []\n", + " for i in range(x_var_6):\n", + " list_var_3.append(i)\n", + "\n", + " return list_var_3\n", + "\n", + "\n", + "create_list(5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f8ebfdd7", + "metadata": {}, + "outputs": [], + "source": [ + "def tuple_f() -> tuple[str, int]:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " string_var_7: str = \"Python\"\n", + " x_var_7: int = 42\n", + " return (string_var_7, x_var_7)\n", + "\n", + "\n", + "(a_var_7, b_var_7) = tuple_f()\n", + "\n", + "print(a_var_7, b_var_7)\n", + "print(type(a_var_7), type(b_var_7))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cfcf3a0", + "metadata": {}, + "outputs": [], + "source": [ + "c_var_7: tuple[str, int] = tuple_f()\n", + "\n", + "print(type(c_var_7))\n", + "print(c_var_7)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "451dc314", + "metadata": {}, + "outputs": [], + "source": [ + "def is_divisible(x_var_8: int) -> bool:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return x_var_8 % 2 == 0\n", + "\n", + "\n", + "is_divisible(10)" + ] + }, + { + "cell_type": "markdown", + "id": "0f26789c", + "metadata": {}, + "source": [ + "### Использование библиотек\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "225987ce", + "metadata": {}, + "outputs": [], + "source": [ + "def mean_f(x_var_9: list[int]) -> float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " mean_val: float = float(np.mean(x_var_9))\n", + " return mean_val + 1.0\n", + "\n", + "\n", + "x_var_10: list[int] = [1, 2, 3]\n", + "mean_f(x_var_10)" + ] + }, + { + "cell_type": "markdown", + "id": "cb959893", + "metadata": {}, + "source": [ + "### Глобальные и локальные переменные\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6da7ef51", + "metadata": {}, + "outputs": [], + "source": [ + "global_name: str = \"Петр\"\n", + "\n", + "\n", + "def show_name() -> None:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " print(global_name)\n", + "\n", + "\n", + "show_name()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d6ba6790", + "metadata": {}, + "outputs": [], + "source": [ + "def show_local_name() -> None:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " local_name_1: str = \"Алена\"\n", + " print(local_name_1)\n", + "\n", + "\n", + "show_local_name()\n", + "# local_name вне функции не существует" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c7e6bd7", + "metadata": {}, + "outputs": [], + "source": [ + "# def make_global():\n", + "# \"\"\"\n", + "# Temporary training function used to practice Python syntax, typing, and code style.\n", + "#\n", + "# Not intended for production use.\n", + "# \"\"\"\n", + "#\n", + "# global local_name\n", + "# local_name: str = \"Алена\"\n", + "# print(local_name)\n", + "\n", + "\n", + "# make_global()\n", + "# local_name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa573c9b", + "metadata": {}, + "outputs": [], + "source": [ + "local_number: int = 5\n", + "\n", + "\n", + "# def print_number():\n", + "# \"\"\"\n", + "# Temporary training function used to practice Python syntax,\n", + "# typing, and code style. Not intended for production use.\n", + "# \"\"\"\n", + "# local_number = 10\n", + "# print(\"Local number =\", local_number)\n", + "\n", + "\n", + "# print_number()\n", + "print(\"Global number =\", local_number)" + ] + }, + { + "cell_type": "markdown", + "id": "8b82cb41", + "metadata": {}, + "source": [ + "### Lambda-функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33ef3a85", + "metadata": {}, + "outputs": [], + "source": [ + "# lf = lambda a_var_10, b_var_10: a_var_10 * b_var_10\n", + "\n", + "# lf(2, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2832e1c7", + "metadata": {}, + "outputs": [], + "source": [ + "def normal_f(a_var_11: int, b_var_11: int) -> int:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return a_var_11 * b_var_11\n", + "\n", + "\n", + "normal_f(2, 3)" + ] + }, + { + "cell_type": "markdown", + "id": "4ff68c13", + "metadata": {}, + "source": [ + "#### Lambda-функция внутри функции filter()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "93992660", + "metadata": {}, + "outputs": [], + "source": [ + "nums: list[int] = [15, 27, 17, 9, 19, 2, 1, 4]\n", + "\n", + "# criterion = lambda n_var_11: True if (n_var_11 > 10) else False\n", + "\n", + "# list(filter(criterion, nums))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e752482d", + "metadata": {}, + "outputs": [], + "source": [ + "# list(filter(lambda n_var_12: True if (n_var_12 > 10) else False, nums))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4dee6fbc", + "metadata": {}, + "outputs": [], + "source": [ + "def is_criterion_2(n_var_13: int) -> bool:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return n_var_13 > 10\n", + "\n", + "\n", + "list(filter(is_criterion_2, nums))" + ] + }, + { + "cell_type": "markdown", + "id": "301b8fbe", + "metadata": {}, + "source": [ + "#### Lambda-функция внутри функции sorted()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "021afabf", + "metadata": {}, + "outputs": [], + "source": [ + "indices_distances: list[tuple[int, float]] = [\n", + " (901, 0.0),\n", + " (1002, 0.2298440568634488),\n", + " (442, 0.25401128310081567),\n", + "]\n", + "\n", + "def key_var(x_var_11: tuple[int, float]) -> float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return x_var_11[1]\n", + "\n", + "sorted(indices_distances, key=key_var, reverse=False)" + ] + }, + { + "cell_type": "markdown", + "id": "84da1d27", + "metadata": {}, + "source": [ + "#### Немедленно вызываемые функции\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b1e73ab", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100\n" + ] + } + ], + "source": [ + "def square(x_var_12: int | float) -> int | float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return x_var_12 * x_var_12\n", + "\n", + "print(square(10))" + ] + }, + { + "cell_type": "markdown", + "id": "b71e6de8", + "metadata": {}, + "source": [ + "### *args и **kwargs" + ] + }, + { + "cell_type": "markdown", + "id": "e82eff0e", + "metadata": {}, + "source": [ + "#### *args\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eb19a6dc", + "metadata": {}, + "outputs": [], + "source": [ + "def mean(a_var_14: int, b_var_14: int) -> float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " return (a_var_14 + b_var_14) / 2\n", + "\n", + "\n", + "mean(1, 2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbe79191", + "metadata": {}, + "outputs": [], + "source": [ + "def mean_1(list_1: list[int]) -> float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " total: int = 0\n", + " for i in list_1:\n", + " total += i\n", + "\n", + " return total / len(list_1)\n", + "\n", + "\n", + "list_var_1: list[int] = [1, 2, 3, 4, 5, 6, 7, 8]\n", + "\n", + "mean_1(list_var_1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9398ca68", + "metadata": {}, + "outputs": [], + "source": [ + "# mean(1, 2) -> WRONG, only lists" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8f49ab96", + "metadata": {}, + "outputs": [], + "source": [ + "def mean_2(*nums_var_1: int) -> float:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " total_var_1: int = 0\n", + " for i in nums_var_1:\n", + " total_var_1 += i\n", + "\n", + " return total_var_1 / len(nums_var_1)\n", + "\n", + "\n", + "list_var_2: list[int] = [1, 2, 3, 4, 5, 6, 7, 8]\n", + "\n", + "mean_2(1, 2, 3, 4, 5)\n", + "mean_2(*[3, 4, 7, 8, 11, 22])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ad3c506", + "metadata": {}, + "outputs": [], + "source": [ + "def test_type(*nums_var: int | float) -> None:\n", + " \"\"\"Temporary training function used to practice Python syntax and typing.\"\"\"\n", + " for num in nums_var:\n", + " print(type(num))\n", + "\n", + "\n", + "test_type(1, 3, 5, 12)\n", + "test_type(*list_var_2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36c73d2f", + "metadata": {}, + "outputs": [], + "source": [ + "a_var_15: list[int] = [1, 2, 3, 4]\n", + "b_var_15: list[int] = [*a_var_15, 4, 5, 6, 7]\n", + "b_var_15" + ] + }, + { + "cell_type": "markdown", + "id": "235e3e7b", + "metadata": {}, + "source": [ + "#### **kwargs\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8fbf0259", + "metadata": {}, + "outputs": [], + "source": [ + "def f_3(**kwargs: int) -> dict[str, int]:\n", + " \"\"\"Temporary training function used to practice Python syntax and typing.\"\"\"\n", + " return kwargs\n", + "\n", + "\n", + "f_3(a=1, b=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70eac7e8", + "metadata": {}, + "outputs": [], + "source": [ + "def simple_stats(*nums_var_3: int | float, **params: bool) -> None:\n", + " \"\"\"\n", + " Temporary training function used to practice Python syntax, typing, and code style.\n", + "\n", + " Not intended for production use.\n", + " \"\"\"\n", + " if \"mean\" in params and params[\"mean\"]:\n", + " print(f\"mean: \\t{np.round(np.mean(nums_var_3), 3)}\")\n", + "\n", + " if \"std\" in params and params[\"std\"]:\n", + " print(f\"std: \\t{np.round(np.std(nums_var_3), 3)}\")\n", + "\n", + "\n", + "simple_stats(5, 10, 15, 20, mean=True, std=True)\n", + "print()\n", + "simple_stats(5, 20, 10, 11, mean=True, std=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d635c9e2", + "metadata": {}, + "outputs": [], + "source": [ + "list_var: list[int] = [5, 12, 18, 22]\n", + "settings: dict[str, bool] = {\"mean\": True, \"std\": True}\n", + "\n", + "simple_stats(*list_var, **settings)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b17c3d7", + "metadata": {}, + "outputs": [], + "source": [ + "simple_stats(5, 10, 14, 19, 25, 22, mean=True, std=True, median=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb b/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb new file mode 100644 index 00000000..23cff81b --- /dev/null +++ b/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb @@ -0,0 +1,1127 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "ba842dfd", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Lists, tuples, and sets.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "46c565b0", + "metadata": {}, + "source": [ + "# Списки, кортежи и множества" + ] + }, + { + "cell_type": "markdown", + "id": "d4fa303f", + "metadata": {}, + "source": [ + "## Списки" + ] + }, + { + "cell_type": "markdown", + "id": "34216001", + "metadata": {}, + "source": [ + "### Основы работы со списками\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8f3a9876", + "metadata": {}, + "outputs": [], + "source": [ + "from nltk import PorterStemmer\n", + "\n", + "some_list_1: list[str] = []\n", + "some_list_2: list[str] = []\n", + "\n", + "print(some_list_1, some_list_2)\n", + "\n", + "number_three: list[int | str | list[str] | dict[str, int]] = [\n", + " 3,\n", + " \"number three\",\n", + " [\"number\", \"three\"],\n", + " {\"number\": 3},\n", + "]\n", + "print(number_three)\n", + "\n", + "len(number_three)" + ] + }, + { + "cell_type": "markdown", + "id": "78ffa9ae", + "metadata": {}, + "source": [ + "### Индекс и срез списка\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1b7f3b99", + "metadata": {}, + "outputs": [], + "source": [ + "abc_list: list[str] = [\"a\", \"b\", \"c\", \"d\", \"e\"]\n", + "\n", + "print(abc_list[0], abc_list[-1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6e77dfe", + "metadata": {}, + "outputs": [], + "source": [ + "salary_list: list[list[str | int]] = [\n", + " [\"Anna\", 90000],\n", + " [\"Igor\", 85000],\n", + " [\"Alex\", 95000],\n", + "]\n", + "\n", + "salary_list[1][0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "432208e5", + "metadata": {}, + "outputs": [], + "source": [ + "abc_list.index(\"c\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70034934", + "metadata": {}, + "outputs": [], + "source": [ + "salary_list[0].index(90000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad9f825a", + "metadata": {}, + "outputs": [], + "source": [ + "days_list: list[str] = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"]\n", + "\n", + "days_list[1:5]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62f5c0c6", + "metadata": {}, + "outputs": [], + "source": [ + "days_list[:5:2]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d68bdd81", + "metadata": {}, + "outputs": [], + "source": [ + "\"Mon\" in days_list" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b3b88d0", + "metadata": {}, + "outputs": [], + "source": [ + "if \"Tue\" in days_list:\n", + " print(\"Такое слово есть\")" + ] + }, + { + "cell_type": "markdown", + "id": "2760de8c", + "metadata": {}, + "source": [ + "### Добавление, замена и удаление элементов списка\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6a13acd", + "metadata": {}, + "outputs": [], + "source": [ + "weekdays: list[str] = [\"Monday\", \"Tuesday\"]\n", + "\n", + "weekdays.append(\"Thursday\")\n", + "weekdays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78ddad2b", + "metadata": {}, + "outputs": [], + "source": [ + "weekdays.insert(2, \"Wednesday\")\n", + "weekdays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ae6adcc", + "metadata": {}, + "outputs": [], + "source": [ + "weekdays[3] = \"Friday\"\n", + "weekdays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a805eb8", + "metadata": {}, + "outputs": [], + "source": [ + "weekdays.remove(\"Friday\")\n", + "weekdays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "064930b0", + "metadata": {}, + "outputs": [], + "source": [ + "del weekdays[2]\n", + "weekdays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b76ac9a7", + "metadata": {}, + "outputs": [], + "source": [ + "weekdays.pop(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34ff990a", + "metadata": {}, + "outputs": [], + "source": [ + "weekdays" + ] + }, + { + "cell_type": "markdown", + "id": "dccb7590", + "metadata": {}, + "source": [ + "### Сложение списков\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b45274c", + "metadata": {}, + "outputs": [], + "source": [ + "more_weekdays: list[str] = [\"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\"]\n", + "\n", + "weekdays.extend(more_weekdays)\n", + "weekdays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5cf808cc", + "metadata": {}, + "outputs": [], + "source": [ + "weekend: list[str] = [\"Saturday\", \"Sunday\"]\n", + "\n", + "print(weekdays + weekend)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e43339f", + "metadata": {}, + "outputs": [], + "source": [ + "[\"Monday\"] * 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad37732e", + "metadata": {}, + "outputs": [], + "source": [ + "[\"Monday\"] * 2 + [\"Tuesday\"] * 2" + ] + }, + { + "cell_type": "markdown", + "id": "ae23f021", + "metadata": {}, + "source": [ + "### Распаковка списков" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "362f08fb", + "metadata": {}, + "outputs": [], + "source": [ + "week: list[str] = [\n", + " \"Monday\",\n", + " \"Tuesday\",\n", + " \"Wednesday\",\n", + " \"Thursday\",\n", + " \"Friday\",\n", + " \"Saturday\",\n", + " \"Sunday\",\n", + "]\n", + "\n", + "mon = week[0]\n", + "mon" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27c693bf", + "metadata": {}, + "outputs": [], + "source": [ + "mon_1, tue_1, wed_1 = week[0:3]\n", + "mon_1, tue_1, wed_1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "acfa136d", + "metadata": {}, + "outputs": [], + "source": [ + "mon_1, *_ = week\n", + "mon_1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cdb139ef", + "metadata": {}, + "outputs": [], + "source": [ + "mon_1, *days, sun_1 = week\n", + "mon_1, sun_1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6bb960f7", + "metadata": {}, + "outputs": [], + "source": [ + "days" + ] + }, + { + "cell_type": "markdown", + "id": "144ed1d8", + "metadata": {}, + "source": [ + "### Сортировка списков\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59e4d845", + "metadata": {}, + "outputs": [], + "source": [ + "nums: list[int] = [25, 10, 30, 20, 5, 15]\n", + "sorted(nums)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d5e0d0b0", + "metadata": {}, + "outputs": [], + "source": [ + "sorted_nums: list[int] = sorted(nums)\n", + "sorted_nums" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88a3735b", + "metadata": {}, + "outputs": [], + "source": [ + "nums.sort(reverse=True)\n", + "nums" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e9fea08", + "metadata": {}, + "outputs": [], + "source": [ + "print(nums)\n", + "nums.reverse()\n", + "print(nums)" + ] + }, + { + "cell_type": "markdown", + "id": "2a498d55", + "metadata": {}, + "source": [ + "#### Переменная не изменяется при этом\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5add9cb0", + "metadata": {}, + "outputs": [], + "source": [ + "reversed(nums)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "896c6913", + "metadata": {}, + "outputs": [], + "source": [ + "list(reversed(nums))" + ] + }, + { + "cell_type": "markdown", + "id": "4b40760e", + "metadata": {}, + "source": [ + "### Преобразование списка в строку\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "205263fd", + "metadata": {}, + "outputs": [], + "source": [ + "str_list: list[str] = [\"P\", \"y\", \"t\", \"h\", \"o\", \"n\"]\n", + "joined_str: str = \"\".join(str_list)\n", + "joined_str" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc9e864b", + "metadata": {}, + "outputs": [], + "source": [ + "joined_str_: str = \"_\".join(str_list)\n", + "joined_str_" + ] + }, + { + "cell_type": "markdown", + "id": "b9757253", + "metadata": {}, + "source": [ + "### Арифметика в списках\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6817e14f", + "metadata": {}, + "outputs": [], + "source": [ + "nums_: list[int] = [3, 2, 1, 4, 5, 12, 3, 3, 7, 9, 11, 15]\n", + "\n", + "nums_.count(3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bfa52d8d", + "metadata": {}, + "outputs": [], + "source": [ + "print(min(nums_), max(nums_), sum(nums_))" + ] + }, + { + "cell_type": "markdown", + "id": "821fdfc7", + "metadata": {}, + "source": [ + "### List comprehension\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09efed42", + "metadata": {}, + "outputs": [], + "source": [ + "names: list[str] = [\"Arthur\", \"Anton\", \"Alex\", \"Boris\", \"Victor\", \"Eugene\"]\n", + "a_names_var: list[str] = []\n", + "\n", + "for name in names:\n", + " if name.startswith(\"a\"):\n", + " a_names_var.append(name)\n", + "\n", + "a_names_var" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98d1198d", + "metadata": {}, + "outputs": [], + "source": [ + "a_names: list[str] = [name for name in names if name.startswith(\"a\")]\n", + "a_names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "68db46c1", + "metadata": {}, + "outputs": [], + "source": [ + "lower_names: list[str] = [name.lower() for name in names]\n", + "lower_names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4f0fc25", + "metadata": {}, + "outputs": [], + "source": [ + "replace_name: list[str] = [name if name != \"Victor\" else \"Vlad\" for name in names]\n", + "replace_name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0db8a4e4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['pari', 'visit', 'lot', 'museum', 'first', 'went', 'louvr', 'largest', 'art', 'museum', 'world', 'alway', 'interest', 'art', 'spent', 'mani', 'hour', 'museum', 'enourm', 'week', 'would', 'enough']\n", + "\n" + ] + } + ], + "source": [ + "lemmatized: list[str] = [\n", + " \"paris\",\n", + " \"visited\",\n", + " \"lot\",\n", + " \"museum\",\n", + " \"first\",\n", + " \"went\",\n", + " \"louvre\",\n", + " \"largest\",\n", + " \"art\",\n", + " \"museum\",\n", + " \"world\",\n", + " \"always\",\n", + " \"interested\",\n", + " \"art\",\n", + " \"spent\",\n", + " \"many\",\n", + " \"hour\",\n", + " \"museum\",\n", + " \"enormous\",\n", + " \"week\",\n", + " \"would\",\n", + " \"enough\",\n", + "]\n", + "\n", + "\n", + "porter: PorterStemmer = PorterStemmer()\n", + "\n", + "stemmed_p: list[str] = [porter.stem(s) for s in lemmatized]\n", + "print(stemmed_p)\n", + "print(type(porter))" + ] + }, + { + "cell_type": "markdown", + "id": "c95281f4", + "metadata": {}, + "source": [ + "## Кортежи" + ] + }, + { + "cell_type": "markdown", + "id": "574b0528", + "metadata": {}, + "source": [ + "### Основы работы с кортежами\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4179035f", + "metadata": {}, + "outputs": [], + "source": [ + "tuple_1: tuple[()] = ()\n", + "tuple_2: tuple[()] = ()\n", + "print(tuple_1, tuple_2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e943490", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "letters_tuple: tuple[str, str, str] = (\"a\", \"b\", \"c\")\n", + "print(letters_tuple[0])\n", + "# letters[0] = 'd' -> WRONG" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a19e26c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['d', 'b', 'c']" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "letters_list: list[str] = list(letters_tuple)\n", + "letters_list[0] = \"d\"\n", + "print(letters_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14fd4d92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tuple" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let_a_tuple: tuple[str] = (\"a\",)\n", + "print(type(let_a_tuple))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4dce464", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "str" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let_a_str: str = \"a\"\n", + "print(type(let_a_str))" + ] + }, + { + "cell_type": "markdown", + "id": "01770972", + "metadata": {}, + "source": [ + "#### Функция enumerate()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "843dcaed", + "metadata": {}, + "outputs": [], + "source": [ + "companies: list[str] = [\"Microsoft\", \"Apple\", \"Tesla\"]\n", + "\n", + "for company in enumerate(companies):\n", + " print(company, type(company))" + ] + }, + { + "cell_type": "markdown", + "id": "1833bcab", + "metadata": {}, + "source": [ + "#### Просмотр элементов словаря\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c72341af", + "metadata": {}, + "outputs": [], + "source": [ + "shopping_dict: dict[str, int] = {\"cucumber\": 3, \"tomato\": 2, \"onion\": 1, \"potato\": 2}\n", + "\n", + "for item in shopping_dict.items():\n", + " print(item)" + ] + }, + { + "cell_type": "markdown", + "id": "5dee273c", + "metadata": {}, + "source": [ + "#### Распаковка кортежей\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0679f840", + "metadata": {}, + "outputs": [], + "source": [ + "a_var, b_var, c_var = (\"a\", \"b\", \"c\")\n", + "print(a_var)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d48168d", + "metadata": {}, + "outputs": [], + "source": [ + "for index_value, company_name in enumerate(companies):\n", + " print(index_value, company_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b61dc72", + "metadata": {}, + "outputs": [], + "source": [ + "for k_var, v_var in shopping_dict.items():\n", + " print(k_var, v_var)" + ] + }, + { + "cell_type": "markdown", + "id": "25e63903", + "metadata": {}, + "source": [ + "#### Функция zip()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab9d84ff", + "metadata": {}, + "outputs": [], + "source": [ + "names_list: list[str] = [\"Arthur\", \"Anton\", \"Alex\", \"Boris\", \"Victor\", \"Eugene\"]\n", + "income: list[int] = [97000, 110000, 95000, 84000, 140000, 120000]\n", + "\n", + "zip(names_list, income)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fea11292", + "metadata": {}, + "outputs": [], + "source": [ + "list(zip(names_list, income))" + ] + }, + { + "cell_type": "markdown", + "id": "fee251ce", + "metadata": {}, + "source": [ + "### Множества\n" + ] + }, + { + "cell_type": "markdown", + "id": "89694efb", + "metadata": {}, + "source": [ + "### Создание множества" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a25ee83", + "metadata": {}, + "outputs": [], + "source": [ + "set_1: set[str] = set()\n", + "set_2: set[str] = {\"a\", \"b\", \"c\"}\n", + "set_3: set[str] = {\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"}\n", + "print(set_1, set_2, set_3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de853a5c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "not_a_set: dict[str | int, str | int] = {}\n", + "print(type(not_a_set))" + ] + }, + { + "cell_type": "markdown", + "id": "9e994aad", + "metadata": {}, + "source": [ + "#### Добавление и удаление элементов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94d6a24e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a', 'e', 'o', 'y', 'э', 'ю', 'я', 'ё'}" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vowels: set[str] = {\"a\", \"o\", \"ie\", \"e\", \"y\", \"io\", \"iu\"}\n", + "\n", + "vowels.add(\"ia\")\n", + "print(vowels)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dfde063e", + "metadata": {}, + "outputs": [], + "source": [ + "vowels.update({\"i\", \"ii\"})\n", + "print(vowels)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c168615f", + "metadata": {}, + "outputs": [], + "source": [ + "vowels.add(\"cha\")\n", + "print(vowels)\n", + "\n", + "vowels.discard(\"cha\")\n", + "print(vowels)" + ] + }, + { + "cell_type": "markdown", + "id": "914b23d8", + "metadata": {}, + "source": [ + "#### Теория множеств в Питоне\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fa65f60f", + "metadata": {}, + "outputs": [], + "source": [ + "# равны если имеют одинаковые элементы, порядок не важен\n", + "{\"a\", \"b\", \"c\"} == {\"c\", \"a\", \"b\"}" + ] + }, + { + "cell_type": "markdown", + "id": "ce055406", + "metadata": {}, + "source": [ + "#### Мощность множества\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ba313d2", + "metadata": {}, + "outputs": [], + "source": [ + "len({\"a\", \"b\", \"c\"})" + ] + }, + { + "cell_type": "markdown", + "id": "99884b76", + "metadata": {}, + "source": [ + "#### Проверка есть ли элемент в множестве\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bedd6feb", + "metadata": {}, + "outputs": [], + "source": [ + "a_var in {\"a\", \"b\", \"c\"}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a8e3fb0c", + "metadata": {}, + "outputs": [], + "source": [ + "# или наоборот\n", + "a_var not in {\"a\", \"b\", \"c\"}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90ebef1d", + "metadata": {}, + "outputs": [], + "source": [ + "set_a: set[str] = {\"a\", \"b\", \"c\"}\n", + "set_b: set[str] = {\"a\", \"b\", \"c\", \"d\", \"e\"}\n", + "\n", + "set_a.issubset(set_b)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a7d7ca4", + "metadata": {}, + "outputs": [], + "source": [ + "set_b.issuperset(set_a)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3611689", + "metadata": {}, + "outputs": [], + "source": [ + "nlp: set[str] = {\"Анна\", \"Николай\", \"Павел\", \"Оксана\"}\n", + "cv: set[str] = {\"Николай\", \"Евгений\", \"Ольга\", \"Оксана\"}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "828382bf", + "metadata": {}, + "outputs": [], + "source": [ + "# Все участники\n", + "print(nlp.union(cv))\n", + "print(nlp | cv)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7adf2073", + "metadata": {}, + "outputs": [], + "source": [ + "# И там и там\n", + "print(nlp.intersection(cv))\n", + "print(nlp & cv)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31efd7ff", + "metadata": {}, + "outputs": [], + "source": [ + "# Только nlp или и там и там\n", + "print(nlp.difference(cv))\n", + "print(nlp - cv)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7037fc3", + "metadata": {}, + "outputs": [], + "source": [ + "# Или там или там но не одновременно везде\n", + "print(nlp.symmetric_difference(cv))\n", + "print(nlp ^ cv)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_8_dictionary_in_python.ipynb b/python_issue/makarov/chapter_8_dictionary_in_python.ipynb new file mode 100644 index 00000000..7a786e4f --- /dev/null +++ b/python_issue/makarov/chapter_8_dictionary_in_python.ipynb @@ -0,0 +1,1255 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "e4b87432", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Dictionary in Python.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "17a0651e", + "metadata": {}, + "source": [ + "## Словарь в Питоне" + ] + }, + { + "cell_type": "markdown", + "id": "c116e657", + "metadata": {}, + "source": [ + "### Понятие словаря" + ] + }, + { + "cell_type": "markdown", + "id": "2006a583", + "metadata": {}, + "source": [ + "#### Создание словаря\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "653901c1", + "metadata": {}, + "outputs": [], + "source": [ + "# Способ 3. Модуль collections\n", + "from collections import Counter\n", + "from pprint import pprint\n", + "\n", + "import numpy as np\n", + "\n", + "dict_1: dict[str, int] = {}\n", + "dict_2: dict[str, int] = {}\n", + "print(dict_1, dict_2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e7efe6ea", + "metadata": {}, + "outputs": [], + "source": [ + "company = {\"name\": \"Tayota\", \"founded\": 1937, \"founder\": \"Kiichiro Toyoda\"}\n", + "company" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65399121", + "metadata": {}, + "outputs": [], + "source": [ + "tickers = dict([[\"TYO\", \"Toyota\"], [\"TSLA\", \"Tesla\"], [\"f\", \"Ford\"]])\n", + "tickers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c33cd37c", + "metadata": {}, + "outputs": [], + "source": [ + "keys = (\"k1\", \"k2\", \"k3\")\n", + "value = 0\n", + "\n", + "empty_values = dict.fromkeys(keys, value)\n", + "empty_values" + ] + }, + { + "cell_type": "markdown", + "id": "e7be1362", + "metadata": {}, + "source": [ + "### Ключи и значения словаря" + ] + }, + { + "cell_type": "markdown", + "id": "f3235491", + "metadata": {}, + "source": [ + "#### Виды значений словаря\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa5d266c", + "metadata": {}, + "outputs": [], + "source": [ + "value_types = {\n", + " \"k1\": 123,\n", + " \"k2\": \"string\",\n", + " \"k3\": np.nan,\n", + " \"k4\": True,\n", + " \"k5\": None,\n", + " \"k6\": [1, 2, 3],\n", + " \"k7\": np.array([1, 2, 3]),\n", + " \"k8\": {1: \"v1\", 2: \"v2\", 3: \"v3\"},\n", + "}\n", + "\n", + "value_types" + ] + }, + { + "cell_type": "markdown", + "id": "7520d35c", + "metadata": {}, + "source": [ + "#### Методы .keys(), .values() и .items()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "743531b7", + "metadata": {}, + "outputs": [], + "source": [ + "person = {\"first name\": \"Ivan\", \"last name\": \"Ivanov\", \"born\": 1980, \"dept\": \"IT\"}\n", + "\n", + "print(person.keys())\n", + "print(person.values())\n", + "print(person.items())" + ] + }, + { + "cell_type": "markdown", + "id": "9c28843a", + "metadata": {}, + "source": [ + "#### Использование цикла for\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e7ef90af", + "metadata": {}, + "outputs": [], + "source": [ + "for k_var, v_var in person.items():\n", + " print(k_var, v_var)" + ] + }, + { + "cell_type": "markdown", + "id": "52fe3ffe", + "metadata": {}, + "source": [ + "#### Доступ по ключу и метод .get()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d8466a5f", + "metadata": {}, + "outputs": [], + "source": [ + "person[\"last name\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da97d7dd", + "metadata": {}, + "outputs": [], + "source": [ + "# если такого ключа нет, Питон выдаст ошибку\n", + "# person['education']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2985a07f", + "metadata": {}, + "outputs": [], + "source": [ + "print(person.get(\"education\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "06c61e5c", + "metadata": {}, + "outputs": [], + "source": [ + "person.get(\"born\")" + ] + }, + { + "cell_type": "markdown", + "id": "d2eccd94", + "metadata": {}, + "source": [ + "#### Проверка вхождения ключа и значения в словарь\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5e331e5", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"born\" in person)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53ba8c45", + "metadata": {}, + "outputs": [], + "source": [ + "print(1980 in person.values())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2a7e872", + "metadata": {}, + "outputs": [], + "source": [ + "print((\"born\", 1980) in person.items())" + ] + }, + { + "cell_type": "markdown", + "id": "7db04457", + "metadata": {}, + "source": [ + "### Операции со словарями" + ] + }, + { + "cell_type": "markdown", + "id": "ba5a13e5", + "metadata": {}, + "source": [ + "#### Добавление и изменение элементов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d007a7b7", + "metadata": {}, + "outputs": [], + "source": [ + "person[\"languages\"] = [\"Python\", \"C++\"]\n", + "person" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c29829ba", + "metadata": {}, + "outputs": [], + "source": [ + "person[\"languages\"] = [\"Python\"]\n", + "person" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4a20e58e", + "metadata": {}, + "outputs": [], + "source": [ + "new_elements = {\"job\": \"programmer\", \"experience\": 7}\n", + "\n", + "person.update(new_elements)\n", + "person" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c0597b8", + "metadata": {}, + "outputs": [], + "source": [ + "person.setdefault(\"last name\", \"Petrov\")\n", + "person" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "781b9b98", + "metadata": {}, + "outputs": [], + "source": [ + "person.setdefault(\"f_languages\", [\"Russian\", \"English\"])\n", + "person" + ] + }, + { + "cell_type": "markdown", + "id": "b8f6ece0", + "metadata": {}, + "source": [ + "#### Удаление элементов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9acdf9de", + "metadata": {}, + "outputs": [], + "source": [ + "person.pop(\"dept\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17f6d04b", + "metadata": {}, + "outputs": [], + "source": [ + "person" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9427c668", + "metadata": {}, + "outputs": [], + "source": [ + "del person[\"born\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51e45ff9", + "metadata": {}, + "outputs": [], + "source": [ + "person.popitem()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dca847f4", + "metadata": {}, + "outputs": [], + "source": [ + "person.clear()\n", + "person" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "391a84b5", + "metadata": {}, + "outputs": [], + "source": [ + "del person" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd4d5d96", + "metadata": {}, + "outputs": [], + "source": [ + "# убедимся, что такого словаря больше нет\n", + "# person" + ] + }, + { + "cell_type": "markdown", + "id": "dae9a190", + "metadata": {}, + "source": [ + "#### Сортировка словарей\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a845bd04", + "metadata": {}, + "outputs": [], + "source": [ + "dict_to_sort = {\"k2\": 30, \"k1\": 20, \"k3\": 10}\n", + "\n", + "sorted(dict_to_sort)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8f2c7412", + "metadata": {}, + "outputs": [], + "source": [ + "sorted(dict_to_sort.values())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce2d80ff", + "metadata": {}, + "outputs": [], + "source": [ + "dict_to_sort.items()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "094d56ed", + "metadata": {}, + "outputs": [], + "source": [ + "sorted(dict_to_sort.items(), key=lambda x: x[0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "63300fa5", + "metadata": {}, + "outputs": [], + "source": [ + "sorted(dict_to_sort.items(), key=lambda x: x[1])" + ] + }, + { + "cell_type": "markdown", + "id": "feca9a80", + "metadata": {}, + "source": [ + "### Копирование словарей\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "149b5e66", + "metadata": {}, + "outputs": [], + "source": [ + "original = {\"first course\": 174, \"second course\": 131}" + ] + }, + { + "cell_type": "markdown", + "id": "61d4b399", + "metadata": {}, + "source": [ + "#### Копирование с помощью метода .copy()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "467686ee", + "metadata": {}, + "outputs": [], + "source": [ + "new_1 = original.copy()\n", + "new_1[\"Third course\"] = 117\n", + "\n", + "print(original)\n", + "print(new_1)" + ] + }, + { + "cell_type": "markdown", + "id": "69e15b9b", + "metadata": {}, + "source": [ + "#### Копирование через оператор присваивания = (так делать не стоит!)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6130f92", + "metadata": {}, + "outputs": [], + "source": [ + "new_2 = original\n", + "\n", + "new_2.clear()\n", + "\n", + "# из исходного словаря данные также удалились\n", + "print(original)\n", + "print(new_2)" + ] + }, + { + "cell_type": "markdown", + "id": "6a8a3609", + "metadata": {}, + "source": [ + "### Функция dir()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32acd99f", + "metadata": {}, + "outputs": [], + "source": [ + "some_dict = {\"k\": 1}\n", + "\n", + "print(dir(some_dict)[:11])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b90e68f", + "metadata": {}, + "outputs": [], + "source": [ + "print(some_dict) # ==\n", + "# some_dict.__str__() # ==" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24fbeb64", + "metadata": {}, + "outputs": [], + "source": [ + "# в большинстве случаев нас будут интересовать методы без '__'\n", + "print(dir(some_dict)[-11:])" + ] + }, + { + "cell_type": "markdown", + "id": "8164fb60", + "metadata": {}, + "source": [ + "### Dict comprehension\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1845ebf0", + "metadata": {}, + "outputs": [], + "source": [ + "source_dict = {\"k1\": 2, \"k2\": 4, \"k3\": 6}\n", + "\n", + "print({k_var_1: v_var_1 * 2 for (k_var_1, v_var_1) in source_dict.items()})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d40bee7b", + "metadata": {}, + "outputs": [], + "source": [ + "print({k_var_2.upper(): v_var_2 for (k_var_2, v_var_2) in source_dict.items()})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a9a4690", + "metadata": {}, + "outputs": [], + "source": [ + "print(\n", + " {k_var_3: v_var_3 for (k_var_3, v_var_3) in source_dict.items() if 2 < v_var_3 < 6}\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "469bf524", + "metadata": {}, + "outputs": [], + "source": [ + "new_dict = {}\n", + "\n", + "for k_var_4, v_var_4 in source_dict.items():\n", + " if 2 < v_var_4 < 6:\n", + " new_dict[k_var_4] = v_var_4\n", + "\n", + "new_dict" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70076cf6", + "metadata": {}, + "outputs": [], + "source": [ + "print(\n", + " {\n", + " k_var_5: (\"even\" if v_var_5 % 2 else \"odd\")\n", + " for (k_var_5, v_var_5) in source_dict.items()\n", + " }\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18e945ba", + "metadata": {}, + "outputs": [], + "source": [ + "source_dict = {\"k1\": 2, \"k2\": 4, \"k3\": 6}\n", + "\n", + "{k: 0 for k in keys}" + ] + }, + { + "cell_type": "markdown", + "id": "a9f9f8c2", + "metadata": {}, + "source": [ + "## Дополнительные примеры" + ] + }, + { + "cell_type": "markdown", + "id": "8ab27c2b", + "metadata": {}, + "source": [ + "### lambda-функции, функции map() и zip()" + ] + }, + { + "cell_type": "markdown", + "id": "741f2939", + "metadata": {}, + "source": [ + "#### Пример со списком" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b33151ff", + "metadata": {}, + "outputs": [], + "source": [ + "words = [\"apple\", \"banana\", \"fig\", \"blackberry\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "190e9fe4", + "metadata": {}, + "outputs": [], + "source": [ + "length = list(map(len, words))\n", + "length" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "76f43139", + "metadata": {}, + "outputs": [], + "source": [ + "dict(zip(words, length)) # ==" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b986e370", + "metadata": {}, + "outputs": [], + "source": [ + "dict(zip(words, [len(word) for word in words]))" + ] + }, + { + "cell_type": "markdown", + "id": "0507ebfd", + "metadata": {}, + "source": [ + "#### Пример со словарем\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40f54f42", + "metadata": {}, + "outputs": [], + "source": [ + "height_feet = {\"Alex\": 6.1, \"Jerry\": 5.4, \"Ben\": 5.8}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e46fea0", + "metadata": {}, + "outputs": [], + "source": [ + "metres = list(map(lambda x: x * 0.3048, height_feet.values()))\n", + "metres" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4cb1f4d4", + "metadata": {}, + "outputs": [], + "source": [ + "dict(zip(height_feet.keys(), np.round(metres, 2))) # ==" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d66d794e", + "metadata": {}, + "outputs": [], + "source": [ + "print(\n", + " {\n", + " k_var_10: np.round(v_var_10 * 0.3048, 2)\n", + " for (k_var_10, v_var_10) in height_feet.items()\n", + " }\n", + ")\n", + "# ==" + ] + }, + { + "cell_type": "markdown", + "id": "f1ee7937", + "metadata": {}, + "source": [ + "#### Вложенные словари\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9871c4d2", + "metadata": {}, + "outputs": [], + "source": [ + "employees: dict[str, dict[str, str | int | float]] = {\n", + " \"id1\": {\n", + " \"first name\": \"Александр\",\n", + " \"last name\": \"Иванов\",\n", + " \"age\": 30,\n", + " \"job\": \"программист\",\n", + " },\n", + " \"id2\": {\n", + " \"first name\": \"Ольга\",\n", + " \"last name\": \"Петрова\",\n", + " \"age\": 35,\n", + " \"job\": \"ML-engineer\",\n", + " },\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e980c36b", + "metadata": {}, + "outputs": [], + "source": [ + "for v_var_7 in employees.values():\n", + " print(v_var_7)" + ] + }, + { + "cell_type": "markdown", + "id": "3b66dda9", + "metadata": {}, + "source": [ + "#### Базовый операции" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "06f019e7", + "metadata": {}, + "outputs": [], + "source": [ + "employees[\"id3\"] = {\n", + " \"first name\": \"Дарья\",\n", + " \"last name\": \"Некрасова\",\n", + " \"age\": 27,\n", + " \"job\": \"веб-дизайнер\",\n", + "}\n", + "\n", + "pprint(employees)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4fb76c04", + "metadata": {}, + "outputs": [], + "source": [ + "employees[\"id3\"][\"age\"] = 26\n", + "\n", + "pprint(employees)" + ] + }, + { + "cell_type": "markdown", + "id": "ec9e636c", + "metadata": {}, + "source": [ + "### Циклы for" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89ca0e4a", + "metadata": {}, + "outputs": [], + "source": [ + "for info in employees.values():\n", + " for k_var_6, v_var_6 in info.items():\n", + " if k_var_6 == \"age\":\n", + " info[k_var_6] = float(v_var_6)\n", + "\n", + "pprint(employees)" + ] + }, + { + "cell_type": "markdown", + "id": "165a5f6a", + "metadata": {}, + "source": [ + "#### Вложенные словари и dict comprehension\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "868eeb56", + "metadata": {}, + "outputs": [], + "source": [ + "pprint({id: info for id, info in employees.items()})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6499db83", + "metadata": {}, + "outputs": [], + "source": [ + "pprint(\n", + " {\n", + " emp_id: {\n", + " k_var_7: (int(v_var_7) if k_var_7 == \"age\" else v_var_7)\n", + " for k_var_7, v_var_7 in info.items()\n", + " }\n", + " for emp_id, info in employees.items()\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "4e37abf5", + "metadata": {}, + "source": [ + "#### Частота слов в тексте\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d402ff6", + "metadata": {}, + "outputs": [], + "source": [ + "corpus = \"\"\"When we were in Paris we visited a lot of museums. We first went to \n", + " the Louvre, the largest art museum in the world. I have always been \n", + " interested in art so I spent many hours \n", + " there. The museum is enormous, so a week there would not be enough.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "36c24d50", + "metadata": {}, + "source": [ + "#### Предварительная обработка текста" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da29847e", + "metadata": {}, + "outputs": [], + "source": [ + "words = corpus.split()\n", + "print(words)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19145e2a", + "metadata": {}, + "outputs": [], + "source": [ + "words = [word.strip(\",\").strip(\".\").lower() for word in words]\n", + "words" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d107f85", + "metadata": {}, + "outputs": [], + "source": [ + "# Способ 1. Условие if-else\n", + "bow_1: dict[str, int] = {}\n", + "\n", + "for word in words:\n", + " if word in bow_1:\n", + " bow_1[word] += 1\n", + " else:\n", + " bow_1[word] = 1\n", + "\n", + "print(sorted(bow_1.items(), key=lambda x: x[1], reverse=True)[:6])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0245046d", + "metadata": {}, + "outputs": [], + "source": [ + "# Способ 2. Метод .get()\n", + "bow_2: dict[str, int] = {}\n", + "\n", + "for word in words:\n", + " bow_2[word] = bow_2.get(word, 0) + 1\n", + "\n", + "print(sorted(bow_2.items(), key=lambda x: x[1], reverse=True)[:6])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "472767cf", + "metadata": {}, + "outputs": [], + "source": [ + "bow_3 = Counter(words)\n", + "bow_3.most_common(6)" + ] + }, + { + "cell_type": "markdown", + "id": "f643ee43", + "metadata": {}, + "source": [ + "## Изменяемые и неизменяемые типы данных\n" + ] + }, + { + "cell_type": "markdown", + "id": "76797208", + "metadata": {}, + "source": [ + "### Неизменяемый тип данных\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea6374af", + "metadata": {}, + "outputs": [], + "source": [ + "string = \"Python\"\n", + "print(id(string), type(string), string)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69db1cdb", + "metadata": {}, + "outputs": [], + "source": [ + "string = string + \" is cool\"\n", + "print(id(string), type(string), string)" + ] + }, + { + "cell_type": "markdown", + "id": "28d537fa", + "metadata": {}, + "source": [ + "### Изменяемый тип данных\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec737026", + "metadata": {}, + "outputs": [], + "source": [ + "lst = [1, 2, 3]\n", + "print(id(lst), type(lst), lst)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "273bdc03", + "metadata": {}, + "outputs": [], + "source": [ + "lst.append(4)\n", + "print(id(lst), type(lst), lst)" + ] + }, + { + "cell_type": "markdown", + "id": "15b47e5f", + "metadata": {}, + "source": [ + "#### Копирование объектов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b2957cc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('python is cool', 'python')" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "string = \"python\"\n", + "string2 = string\n", + "string2 = string2 + \" is cool\"\n", + "\n", + "string2, string" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "9973f08b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(False, False)" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "string == string2, string is string2" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "de1c443d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([1, 2, 3, 4], [1, 2, 3, 4])" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lst = [1, 2, 3]\n", + "\n", + "lst2 = lst\n", + "lst2.append(4)\n", + "\n", + "lst, lst2" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "83da799c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, True)" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lst == lst2, lst is lst2" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "22f8132e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([1, 2, 3], [1, 2, 3, 4])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lst = [1, 2, 3]\n", + "lst2 = lst.copy()\n", + "\n", + "lst2.append(4)\n", + "\n", + "lst, lst2" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "4c15b5be", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([1, 2, 3, 4], [1, 2, 3, 4], True, False)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lst.append(4)\n", + "\n", + "lst, lst2, lst == lst2, lst is lst2" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/makarov/chapter_9_classes_and_objects_in_python.ipynb b/python_issue/makarov/chapter_9_classes_and_objects_in_python.ipynb new file mode 100644 index 00000000..b165888c --- /dev/null +++ b/python_issue/makarov/chapter_9_classes_and_objects_in_python.ipynb @@ -0,0 +1,974 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "ba84b5ab", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"Classes and objects in Python.\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "e5c58758", + "metadata": {}, + "source": [ + "## Классы и объекты в Питоне" + ] + }, + { + "cell_type": "markdown", + "id": "ea5e33be", + "metadata": {}, + "source": [ + "### Создание класса" + ] + }, + { + "cell_type": "markdown", + "id": "f6a1693c", + "metadata": {}, + "source": [ + "#### Создание класса и метод .__init__()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8838f641", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "\n", + "class CatClass:\n", + " \"\"\"Temporary training function.\"\"\"\n", + "\n", + " def __init__(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.color = \"undefined\"" + ] + }, + { + "cell_type": "markdown", + "id": "fc1a9ad9", + "metadata": {}, + "source": [ + "#### Создание объекта\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "87e607e8", + "metadata": {}, + "outputs": [], + "source": [ + "matroskin_f: CatClass = CatClass()\n", + "\n", + "print(type(matroskin_f))" + ] + }, + { + "cell_type": "markdown", + "id": "a9be3cf1", + "metadata": {}, + "source": [ + "#### Атрибуты класса\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "717c1b56", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClass1:\n", + " \"\"\"Temporary training function.\"\"\"\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.color = color\n", + " self.type_ = \"cat\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "75558a37", + "metadata": {}, + "outputs": [], + "source": [ + "matroskin_1: CatClass1 = CatClass1(\"grey\")\n", + "\n", + "print(matroskin_1.color, matroskin_1.type_)" + ] + }, + { + "cell_type": "markdown", + "id": "846b195c", + "metadata": {}, + "source": [ + "#### Методы класса\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "648dd852", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClass2:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.color = color\n", + " self.type_ = \"cat\"\n", + "\n", + " def meow(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " for _ in range(3):\n", + " print(\"meow\")\n", + "\n", + " def info(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(self.color, self.type_)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fd30aef0", + "metadata": {}, + "outputs": [], + "source": [ + "matroskin_2: CatClass2 = CatClass2(\"gray\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d44b0286", + "metadata": {}, + "outputs": [], + "source": [ + "matroskin_2.meow()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ed66d3fc", + "metadata": {}, + "outputs": [], + "source": [ + "matroskin_2.info()" + ] + }, + { + "cell_type": "markdown", + "id": "88be939b", + "metadata": {}, + "source": [ + "### Принципы ООП\n" + ] + }, + { + "cell_type": "markdown", + "id": "169e2fd0", + "metadata": {}, + "source": [ + "#### Инкапсуляция" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21cd5d3c", + "metadata": {}, + "outputs": [], + "source": [ + "matroskin_2.type_ = \"dog\"\n", + "print(matroskin_2.type_)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "db0270fa", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClass3:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.color = color\n", + " self.type_ = \"cat\"\n", + "\n", + "\n", + "matroskin_3: CatClass3 = CatClass3(\"gray\")\n", + "matroskin_3.type_ = \"dog\"\n", + "print(matroskin_3.type_)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f883957", + "metadata": {}, + "outputs": [], + "source": [ + "class CatClass4:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, color: str) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.color = color\n", + " self.__type_ = \"cat\"\n", + "\n", + " def set_type(self, new_type: str) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.__type_ = new_type\n", + "\n", + " def get_type(self) -> str:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " return self.__type_\n", + "\n", + "\n", + "matroskin_4: CatClass4 = CatClass4(\"grey\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f87c8d68", + "metadata": {}, + "outputs": [], + "source": [ + "matroskin_4.set_type(\"dog\")\n", + "print(matroskin_4.get_type())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52f1f40b", + "metadata": {}, + "outputs": [], + "source": [ + "# matroskin_4.__type_ ERROR" + ] + }, + { + "cell_type": "markdown", + "id": "5280ebdb", + "metadata": {}, + "source": [ + "### Наследование классов\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "a57007b1", + "metadata": {}, + "source": [ + "#### Создание родительского класса и класса-потомка" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fd4c3c80", + "metadata": {}, + "outputs": [], + "source": [ + "class Animal:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, weight: float, length: int) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.weight = weight\n", + " self.length = length\n", + "\n", + " def eat(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"Eating\")\n", + "\n", + " def sleep(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"Sleeping\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd8394a7", + "metadata": {}, + "outputs": [], + "source": [ + "class Bird(Animal):\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def move(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"Flying\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ba56afe2", + "metadata": {}, + "outputs": [], + "source": [ + "pigeon: Bird = Bird(0.3, 30)\n", + "print(pigeon.weight, pigeon.length)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95bc039d", + "metadata": {}, + "outputs": [], + "source": [ + "pigeon.eat()\n", + "pigeon.move()" + ] + }, + { + "cell_type": "markdown", + "id": "8c5fe957", + "metadata": {}, + "source": [ + "#### Функция super()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cffbec5b", + "metadata": {}, + "outputs": [], + "source": [ + "class Bird2(Animal):\n", + " \"\"\"Temporary training function.\"\"\"\n", + "\n", + " def __init__(self, weight: float, length: int, flying_speed: int) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " super().__init__(weight, length)\n", + " self.flying_speed = flying_speed\n", + "\n", + " def move(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"Flying\")\n", + "\n", + "\n", + "pigeon_2: Bird2 = Bird2(0.3, 30, 100)\n", + "\n", + "print(pigeon_2.weight, pigeon_2.length, pigeon_2.flying_speed)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eec3f2b0", + "metadata": {}, + "outputs": [], + "source": [ + "pigeon_2.sleep()\n", + "pigeon_2.move()" + ] + }, + { + "cell_type": "markdown", + "id": "338cd8d2", + "metadata": {}, + "source": [ + "#### Переопределение класса\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51f5992a", + "metadata": {}, + "outputs": [], + "source": [ + "class Flightless(Bird2):\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, weight: float, length: int, running_speed: int) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " super().__init__(weight, length, flying_speed=0)\n", + " self.running_speed = running_speed\n", + "\n", + " def move(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"Running\")\n", + "\n", + "\n", + "ostrich: Flightless = Flightless(60.0, 200, 60)\n", + "print(ostrich.running_speed)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc3115bd", + "metadata": {}, + "outputs": [], + "source": [ + "ostrich.move()\n", + "ostrich.eat()" + ] + }, + { + "cell_type": "markdown", + "id": "6c704051", + "metadata": {}, + "source": [ + "#### Множественное наследование\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26a827af", + "metadata": {}, + "outputs": [], + "source": [ + "class Fish:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def swim(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"Swimming\")\n", + "\n", + "\n", + "class Bird3:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def fly(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"Flying\")\n", + "\n", + "\n", + "class SwimmingBird(Bird3, Fish):\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def demo(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.fly()\n", + " self.swim()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "63c3936c", + "metadata": {}, + "outputs": [], + "source": [ + "duck: SwimmingBird = SwimmingBird()\n", + "duck.fly()\n", + "duck.swim()" + ] + }, + { + "cell_type": "markdown", + "id": "2cb0d011", + "metadata": {}, + "source": [ + "#### Полиморфизм\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9adcacf0", + "metadata": {}, + "outputs": [], + "source": [ + "# + для цифр это сложение, для строк слияние\n", + "print(2 + 2)\n", + "print(\"classes\" + \" and \" + \"objects\")" + ] + }, + { + "cell_type": "markdown", + "id": "7df52245", + "metadata": {}, + "source": [ + "#### Полиморфизм функций\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "506e0aa9", + "metadata": {}, + "outputs": [], + "source": [ + "# len можно применять ко многим последовательностям значений\n", + "\n", + "print(len(\"programming in Python\"))\n", + "print(len([\"programming\", \"in\", \"Python\"]))\n", + "print(len({0: \"programming\", 1: \"in\", 2: \"Python\"}))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "389402d3", + "metadata": {}, + "outputs": [], + "source": [ + "print(len(np.array([1, 2, 3])))" + ] + }, + { + "cell_type": "markdown", + "id": "bb3f37eb", + "metadata": {}, + "source": [ + "#### Полиморфизм классов\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37af53d1", + "metadata": {}, + "outputs": [], + "source": [ + "# Создадим объекты с одинаковыми атрибутами и методами\n", + "\n", + "\n", + "class CatClass5:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, name: str, color: str) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.name = name\n", + " self._type_ = \"cat\"\n", + " self.color = color\n", + "\n", + " def info(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\n", + " f\"My name is {self.name}, i'm {self._type_}, color of my wool {self.color}\"\n", + " )\n", + "\n", + " def sound(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"I can meow\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2d90b72", + "metadata": {}, + "outputs": [], + "source": [ + "class DogClass:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, name: str, color: str) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.name = name\n", + " self._type_ = \"dog\"\n", + " self.color = color\n", + "\n", + " def info(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\n", + " f\"My name is {self.name}, i'm {self._type_}, color of my wool {self.color}\"\n", + " )\n", + "\n", + " def sound(self) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " print(\"I can bark\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7541170f", + "metadata": {}, + "outputs": [], + "source": [ + "cat: CatClass5 = CatClass5(\"Barsik\", \"black\")\n", + "dog: DogClass = DogClass(\"Barbos\", \"gray\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eeb5371c", + "metadata": {}, + "outputs": [], + "source": [ + "for animal in (cat, dog):\n", + " animal.info()\n", + " animal.sound()\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "2fcf7323", + "metadata": {}, + "source": [ + "### Парадигмы программирования\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b4d03f2", + "metadata": {}, + "outputs": [], + "source": [ + "patients: list[dict[str, int | str]] = [\n", + " {\"name\": \"Николай\", \"height\": 178},\n", + " {\"name\": \"Иван\", \"height\": 182},\n", + " {\"name\": \"Алексей\", \"height\": 190},\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "b01e2717", + "metadata": {}, + "source": [ + "#### Процедурное программирование\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3642da26", + "metadata": {}, + "outputs": [], + "source": [ + "total: int = 0\n", + "count_var: int = 0\n", + "\n", + "for patient in patients:\n", + " height_val: int = int(patient[\"height\"])\n", + " total += height_val\n", + " count_var += 1\n", + "\n", + "total / count_var" + ] + }, + { + "cell_type": "markdown", + "id": "324c67fa", + "metadata": {}, + "source": [ + "#### Объектно-ориентированное программирование\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b70cfe3", + "metadata": {}, + "outputs": [], + "source": [ + "class DataClass:\n", + " \"\"\"Temporary training class.\"\"\"\n", + "\n", + " def __init__(self, data: list[dict[str, int | str]]) -> None:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " self.data = data\n", + "\n", + " def count_average(self, metric: str) -> float:\n", + " \"\"\"Temporary training function.\"\"\"\n", + " total_sum: int = 0\n", + " count: int = 0\n", + "\n", + " for item in self.data:\n", + " total_sum += int(item[metric])\n", + " count += 1\n", + "\n", + " return total_sum / count" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c0d04a4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "183.33333333333334\n" + ] + } + ], + "source": [ + "data_object = DataClass(patients)\n", + "print(data_object.count_average(\"height\"))" + ] + }, + { + "cell_type": "markdown", + "id": "c80181b6", + "metadata": {}, + "source": [ + "#### Функциональное программирование\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "748ee67d", + "metadata": {}, + "source": [ + "#### Функция map()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2fa70e74", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[178, 182, 190]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "heights: list[int] = [int(p[\"height\"]) for p in patients]\n", + "print(heights)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f7f95642", + "metadata": {}, + "outputs": [], + "source": [ + "print(sum(heights) / len(heights))" + ] + }, + { + "cell_type": "markdown", + "id": "caa114fe", + "metadata": {}, + "source": [ + "#### Функция einsum()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4779e125", + "metadata": {}, + "outputs": [], + "source": [ + "a_arr: np.ndarray = np.array([[0, 1, 2], [3, 4, 5]])\n", + "\n", + "b_arr: np.ndarray = np.array([[5, 4], [3, 2], [1, 0]])\n", + "\n", + "print(np.einsum(\"ij, jk -> ik\", a_arr, b_arr))" + ] + }, + { + "cell_type": "markdown", + "id": "616095d0", + "metadata": {}, + "source": [ + "### Классы и объекты в машинном обучении\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "d44f9b4d", + "metadata": {}, + "source": [ + "#### Готовые классы в библиотеке sklearn" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1e1fb6ff", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(numpy.ndarray, numpy.ndarray)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X_ax: np.ndarray = np.array(\n", + " [\n", + " 1.48,\n", + " 1.49,\n", + " 1.49,\n", + " 1.50,\n", + " 1.51,\n", + " 1.52,\n", + " 1.52,\n", + " 1.53,\n", + " 1.53,\n", + " 1.54,\n", + " 1.55,\n", + " 1.56,\n", + " 1.57,\n", + " 1.57,\n", + " 1.58,\n", + " 1.58,\n", + " 1.59,\n", + " 1.60,\n", + " 1.61,\n", + " 1.62,\n", + " 1.63,\n", + " 1.64,\n", + " 1.65,\n", + " 1.65,\n", + " 1.66,\n", + " 1.67,\n", + " 1.67,\n", + " 1.68,\n", + " 1.68,\n", + " 1.69,\n", + " 1.70,\n", + " 1.70,\n", + " 1.71,\n", + " 1.71,\n", + " 1.71,\n", + " 1.74,\n", + " 1.75,\n", + " 1.76,\n", + " 1.77,\n", + " 1.77,\n", + " 1.78,\n", + " ]\n", + ")\n", + "y_ax: np.ndarray = np.array(\n", + " [\n", + " 29.1,\n", + " 30.0,\n", + " 30.1,\n", + " 30.2,\n", + " 30.4,\n", + " 30.6,\n", + " 30.8,\n", + " 30.9,\n", + " 31.0,\n", + " 30.6,\n", + " 30.7,\n", + " 30.9,\n", + " 31.0,\n", + " 31.2,\n", + " 31.3,\n", + " 32.0,\n", + " 31.4,\n", + " 31.9,\n", + " 32.4,\n", + " 32.8,\n", + " 32.8,\n", + " 33.3,\n", + " 33.6,\n", + " 33.0,\n", + " 33.9,\n", + " 33.8,\n", + " 35.0,\n", + " 34.5,\n", + " 34.7,\n", + " 34.6,\n", + " 34.2,\n", + " 34.8,\n", + " 35.5,\n", + " 36.0,\n", + " 36.2,\n", + " 36.3,\n", + " 36.6,\n", + " 36.8,\n", + " 36.8,\n", + " 37.0,\n", + " 38.5,\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6a8a208", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "numpy.ndarray" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X_2D: np.ndarray = X_ax.reshape(-1, 1)\n", + "X_2D" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python_issue/oop_molchanov.ipynb b/python_issue/oop_molchanov.ipynb new file mode 100644 index 00000000..88caeb71 --- /dev/null +++ b/python_issue/oop_molchanov.ipynb @@ -0,0 +1,1375 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "f769bd69", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Lesson 0.'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"Describe object-oriented lesson examples.\"\"\"\n", + "from __future__ import annotations\n", + "\n", + "from typing import ClassVar\n", + "\n", + "import requests\n", + "from requests import Response" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c8055d44", + "metadata": {}, + "outputs": [], + "source": [ + "google_response: Response = requests.get(\"https://www.google.ru\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bf218ca0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "requests.models.Response" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(type(google_response))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "0d343119", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['__attrs__',\n", + " '__bool__',\n", + " '__class__',\n", + " '__delattr__',\n", + " '__dict__',\n", + " '__dir__',\n", + " '__doc__',\n", + " '__enter__',\n", + " '__eq__',\n", + " '__exit__',\n", + " '__format__',\n", + " '__ge__',\n", + " '__getattribute__',\n", + " '__getstate__',\n", + " '__gt__',\n", + " '__hash__',\n", + " '__init__',\n", + " '__init_subclass__',\n", + " '__iter__',\n", + " '__le__',\n", + " '__lt__',\n", + " '__module__',\n", + " '__ne__',\n", + " '__new__',\n", + " '__nonzero__',\n", + " '__reduce__',\n", + " '__reduce_ex__',\n", + " '__repr__',\n", + " '__setattr__',\n", + " '__setstate__',\n", + " '__sizeof__',\n", + " '__str__',\n", + " '__subclasshook__',\n", + " '__weakref__',\n", + " '_content',\n", + " '_content_consumed',\n", + " '_next',\n", + " 'apparent_encoding',\n", + " 'close',\n", + " 'connection',\n", + " 'content',\n", + " 'cookies',\n", + " 'elapsed',\n", + " 'encoding',\n", + " 'headers',\n", + " 'history',\n", + " 'is_permanent_redirect',\n", + " 'is_redirect',\n", + " 'iter_content',\n", + " 'iter_lines',\n", + " 'json',\n", + " 'links',\n", + " 'next',\n", + " 'ok',\n", + " 'raise_for_status',\n", + " 'raw',\n", + " 'reason',\n", + " 'request',\n", + " 'status_code',\n", + " 'text',\n", + " 'url']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(dir(google_response))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28a7e164", + "metadata": {}, + "outputs": [], + "source": [ + "# Lesson 1." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "353f86e0", + "metadata": {}, + "outputs": [], + "source": [ + "class PersonLesson1:\n", + " \"\"\"Represent lesson 1 person with a default name.\"\"\"\n", + "\n", + " name: ClassVar[str] = \"Ivan\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55726ff9", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson1.name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21c192aa", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson1.__name__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90227064", + "metadata": {}, + "outputs": [], + "source": [ + "print(dir(PersonLesson1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "01a7c7e5", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson1.__class__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c54d79d2", + "metadata": {}, + "outputs": [], + "source": [ + "lesson1_person: PersonLesson1 = PersonLesson1()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62d02b72", + "metadata": {}, + "outputs": [], + "source": [ + "print(lesson1_person.__class__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b3a24960", + "metadata": {}, + "outputs": [], + "source": [ + "print(lesson1_person.__class__.__name__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2462f4e", + "metadata": {}, + "outputs": [], + "source": [ + "print(type(lesson1_person))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a99ae77", + "metadata": {}, + "outputs": [], + "source": [ + "cloned_person: PersonLesson1 = type(lesson1_person)()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c37ad71", + "metadata": {}, + "outputs": [], + "source": [ + "print(id(lesson1_person))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d173a7e8", + "metadata": {}, + "outputs": [], + "source": [ + "print(id(cloned_person))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3756c5bb", + "metadata": {}, + "outputs": [], + "source": [ + "# Lesson 2." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f0ea46a", + "metadata": {}, + "outputs": [], + "source": [ + "class PersonLesson2:\n", + " \"\"\"Represent lesson 2 person with mutable attributes.\"\"\"\n", + "\n", + " name: ClassVar[str] = \"Ivan\"\n", + " age: ClassVar[int]\n", + " dob: ClassVar[str]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b222ac2d", + "metadata": {}, + "outputs": [], + "source": [ + "print(dir(PersonLesson2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52e3eb1c", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson2.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f68d679d", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson2.name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52cf1974", + "metadata": {}, + "outputs": [], + "source": [ + "PersonLesson2.age = 123" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "190064b1", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson2.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "621b21c6", + "metadata": {}, + "outputs": [], + "source": [ + "print(getattr(PersonLesson2, \"name\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d8937a8", + "metadata": {}, + "outputs": [], + "source": [ + "setattr(PersonLesson2, \"dob\", \"123\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f63ddea2", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson2.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bad43aa8", + "metadata": {}, + "outputs": [], + "source": [ + "delattr(PersonLesson2, \"dob\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e9ea464", + "metadata": {}, + "outputs": [], + "source": [ + "class PersonLesson2Method:\n", + " \"\"\"Represent lesson 2 person with a plain function-style method.\"\"\"\n", + "\n", + " name: ClassVar[str] = \"Ivan\"\n", + "\n", + " def hello(self: PersonLesson2Method) -> None:\n", + " \"\"\"Say hello without binding to an instance.\"\"\"\n", + " print(\"hello!\")\n", + "\n", + "\n", + "PersonLesson2Method.hello(PersonLesson2Method())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61c32f6b", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson2Method.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1c4b50c8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Lesson 3.'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Lesson 3." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cfa2b32c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'__module__': '__main__', 'name': 'Ivan', '__dict__': , '__weakref__': , '__doc__': None}\n" + ] + } + ], + "source": [ + "class PersonLesson3:\n", + " \"\"\"Represent lesson 3 person for attribute experiments.\"\"\"\n", + "\n", + " name: str = \"Ivan\"\n", + " age: int\n", + "\n", + "\n", + "print(PersonLesson3.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "aef8ab49", + "metadata": {}, + "outputs": [], + "source": [ + "first_person: PersonLesson3 = PersonLesson3()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8fc8ca33", + "metadata": {}, + "outputs": [], + "source": [ + "second_person: PersonLesson3 = PersonLesson3()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "01158253", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4491262544" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(id(first_person))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "0070e1a6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4491056336" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(id(second_person))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "b2d994ed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(first_person.name == second_person.name)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "2859d9a3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(id(first_person.name) == id(second_person.name))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "90db6853", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{}" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(first_person.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "11198492", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(second_person.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "b7e87d25", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "mappingproxy({'__module__': '__main__',\n", + " 'name': 'Ivan',\n", + " '__dict__': ,\n", + " '__weakref__': ,\n", + " '__doc__': None})" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(PersonLesson3.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "c3b561b7", + "metadata": {}, + "outputs": [], + "source": [ + "first_person.name = \"Oleg\"\n", + "second_person.name = \"Dima\"" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "262ac3e4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'Oleg'}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(first_person.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "841bdc59", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'Dima'}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(second_person.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "837554ae", + "metadata": {}, + "outputs": [], + "source": [ + "second_person.age = 25" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "4aeafd05", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'Dima', 'age': 25}" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(second_person.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "656f74ae", + "metadata": {}, + "outputs": [], + "source": [ + "# first_person.age -> no attr" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "ab37a655", + "metadata": {}, + "outputs": [], + "source": [ + "fresh_person_one: PersonLesson3 = PersonLesson3()\n", + "fresh_person_two: PersonLesson3 = PersonLesson3()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "7c2f0dbf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('Ivan', 'Ivan')" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print((fresh_person_one.name, fresh_person_two.name))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "e5493f11", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('Dayal', 'Dayal')" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "PersonLesson3.name = \"Dayal\"\n", + "\n", + "print((fresh_person_one.name, fresh_person_two.name))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5d62ddb8", + "metadata": {}, + "outputs": [], + "source": [ + "# Lesson 4." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28cdd207", + "metadata": {}, + "outputs": [], + "source": [ + "class PersonLesson4:\n", + " \"\"\"Represent lesson 4 person with a simple greeter.\"\"\"\n", + "\n", + " def hello(self: PersonLesson4) -> None:\n", + " \"\"\"Say hello from the class namespace.\"\"\"\n", + " print(\"Hello!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e7ffb1b", + "metadata": {}, + "outputs": [], + "source": [ + "print(PersonLesson4.hello)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3be9fee", + "metadata": {}, + "outputs": [], + "source": [ + "greeting_person: PersonLesson4 = PersonLesson4()\n", + "print(greeting_person.hello)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c58fd7d3", + "metadata": {}, + "outputs": [], + "source": [ + "print(hex(id(greeting_person)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a0f12c5", + "metadata": {}, + "outputs": [], + "source": [ + "PersonLesson4.hello(greeting_person)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e53b989b", + "metadata": {}, + "outputs": [], + "source": [ + "# greeting_person.hello()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d8fefab8", + "metadata": {}, + "outputs": [], + "source": [ + "print(type(greeting_person.hello))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "468e4ca7", + "metadata": {}, + "outputs": [], + "source": [ + "print(type(PersonLesson4.hello))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f1026cf0", + "metadata": {}, + "outputs": [], + "source": [ + "print((id(PersonLesson4.hello), id(greeting_person.hello)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a5350ff", + "metadata": {}, + "outputs": [], + "source": [ + "print(dir(PersonLesson4.hello))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70cb34de", + "metadata": {}, + "outputs": [], + "source": [ + "print(dir(greeting_person.hello))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac0a8e6a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Person at 0x108076290>" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(greeting_person.hello.__self__) # type: ignore[attr-defined]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "c2ff4e2d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0x108076290'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(hex(id(greeting_person)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ec1b95b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(greeting_person.hello.__func__) # type: ignore[attr-defined]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "4eb93b2b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<__main__.Person object at 0x10860be90>\n" + ] + } + ], + "source": [ + "class PersonLesson4BoundInspector:\n", + " \"\"\"Inspect bound method internals via a person.\"\"\"\n", + "\n", + " def hello(self: PersonLesson4BoundInspector) -> None:\n", + " \"\"\"Display the instance reference.\"\"\"\n", + " print(self)\n", + "\n", + "\n", + "inspected_person: PersonLesson4BoundInspector = PersonLesson4BoundInspector()\n", + "inspected_person.hello()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "80e7390b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0x10860be90'" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(hex(id(inspected_person)))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "33afc292", + "metadata": {}, + "outputs": [], + "source": [ + "class PersonLesson4Self:\n", + " \"\"\"Display instance reference through self.\"\"\"\n", + "\n", + " def hello(self: PersonLesson4Self) -> None:\n", + " \"\"\"Display the instance reference through self.\"\"\"\n", + " print(self)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f59d2b30", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "68b95714", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Lesson 5.'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Lesson 5." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0c407113", + "metadata": {}, + "outputs": [], + "source": [ + "class PersonLesson5Placeholder:\n", + " \"\"\"Serve as a placeholder person for lesson 5.\"\"\"\n", + "\n", + " name: str" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4212aef5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Ivan'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "person_with_dynamic_attr: PersonLesson5Placeholder = PersonLesson5Placeholder()\n", + "person_with_dynamic_attr.name = \"Ivan\"\n", + "print(person_with_dynamic_attr.name)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "3225d29b", + "metadata": {}, + "outputs": [], + "source": [ + "class PersonLesson5Named:\n", + " \"\"\"Store and display a name.\"\"\"\n", + "\n", + " def __init__(self, name: str) -> None:\n", + " \"\"\"Initialize a person with a provided name.\"\"\"\n", + " self.name: str = name\n", + "\n", + " def display(self) -> None:\n", + " \"\"\"Print the stored name.\"\"\"\n", + " print(self.name)\n", + "\n", + "\n", + "named_person: PersonLesson5Named = PersonLesson5Named(\"Dayal\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "9f752d3d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'Dayal'}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(named_person.__dict__)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "0fdd3652", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Dayal'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(named_person.name)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "c7d58350", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Lesson 6.'" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Lesson 6." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "00745531", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Goodbye\n" + ] + } + ], + "source": [ + "class PersonLesson6:\n", + " \"\"\"Provide instance and static greetings.\"\"\"\n", + "\n", + " def hello(self: PersonLesson6) -> None:\n", + " \"\"\"Greet from an instance method.\"\"\"\n", + " print(\"Hello!\")\n", + "\n", + " @staticmethod\n", + " def goodbye() -> None:\n", + " \"\"\"Say goodbye without binding to an instance.\"\"\"\n", + " print(\"Goodbye\")\n", + "\n", + "\n", + "person_for_goodbye: PersonLesson6 = PersonLesson6()\n", + "person_for_goodbye.goodbye() # call works after making goodbye static" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "49b0d44e", + "metadata": {}, + "outputs": [], + "source": [ + "greeter_one: PersonLesson6 = PersonLesson6()\n", + "greeter_two: PersonLesson6 = PersonLesson6()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "dd0b5ec9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello!\n", + "Goodbye\n" + ] + } + ], + "source": [ + "greeter_one.hello()\n", + "greeter_one.goodbye()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "16795c89", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(4387908864, 4387908864)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print((id(greeter_one.hello), id(greeter_two.hello)))" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "6100fa85", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(4382620576, 4382620576)" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print((id(greeter_one.goodbye), id(greeter_two.goodbye)))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "ebca7cef", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({}, {})" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print((greeter_one.__dict__, greeter_two.__dict__))" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "eff945e7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "function" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(type(greeter_one.goodbye))" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "08c1ccbf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Goodbye\n" + ] + } + ], + "source": [ + "PersonLesson6.goodbye()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "myenv", + "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.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a0c4a130cba7dde88adf014fbcfe25f4a9a189ab Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 10 Dec 2025 13:32:39 +0300 Subject: [PATCH 21/24] [TASK] Python (https://github.com/SENATOROVAI/python/issues/1) closes https://github.com/SENATOROVAI/python/issues/1 --- ...chapter_4_choosing_understandable_names.py | 245 +++++++ ...ta_science_and_programming_fundamentals.py | 237 ++++++ .../chapter_2_introduction_to_python.py | 211 ++++++ .../makarov/chapter_10_numpy_array.py | 657 +++++++++++++++++ python_issue/makarov/chapter_15_iterators.py | 339 +++++++++ python_issue/makarov/chapter_16_decorators.py | 679 ++++++++++++++++++ python_issue/makarov/chapter_1_pandas.py | 385 ++++++++++ .../makarov/chapter_1_variables_in_python.py | 108 +++ .../makarov/chapter_2_data_types_in_python.py | 148 ++++ .../chapter_3_conditions_and_cycles.py | 287 ++++++++ python_issue/makarov/chapter_4_files.py | 86 +++ .../chapter_5_date_and_time_in_python.py | 213 ++++++ python_issue/makarov/chapter_6_functions.py | 584 +++++++++++++++ .../chapter_7_lists_tuples_and_sets.py | 384 ++++++++++ .../makarov/chapter_8_dictionary_in_python.py | 435 +++++++++++ ...chapter_9_classes_and_objects_in_python.py | 515 +++++++++++++ python_issue/oop_molchanov.py | 301 ++++++++ 17 files changed, 5814 insertions(+) create mode 100644 python_issue/clean_code/chapter_4_choosing_understandable_names.py create mode 100644 python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.py create mode 100644 python_issue/made-easy/chapter_2_introduction_to_python.py create mode 100644 python_issue/makarov/chapter_10_numpy_array.py create mode 100644 python_issue/makarov/chapter_15_iterators.py create mode 100644 python_issue/makarov/chapter_16_decorators.py create mode 100644 python_issue/makarov/chapter_1_pandas.py create mode 100644 python_issue/makarov/chapter_1_variables_in_python.py create mode 100644 python_issue/makarov/chapter_2_data_types_in_python.py create mode 100644 python_issue/makarov/chapter_3_conditions_and_cycles.py create mode 100644 python_issue/makarov/chapter_4_files.py create mode 100644 python_issue/makarov/chapter_5_date_and_time_in_python.py create mode 100644 python_issue/makarov/chapter_6_functions.py create mode 100644 python_issue/makarov/chapter_7_lists_tuples_and_sets.py create mode 100644 python_issue/makarov/chapter_8_dictionary_in_python.py create mode 100644 python_issue/makarov/chapter_9_classes_and_objects_in_python.py create mode 100644 python_issue/oop_molchanov.py diff --git a/python_issue/clean_code/chapter_4_choosing_understandable_names.py b/python_issue/clean_code/chapter_4_choosing_understandable_names.py new file mode 100644 index 00000000..e7cf8790 --- /dev/null +++ b/python_issue/clean_code/chapter_4_choosing_understandable_names.py @@ -0,0 +1,245 @@ +"""Choosing understandable names.""" + +# *Имена формально называются идентификаторами* +# +# +# ### Схемы регистра имен +# +# +# Так как в идентификаторах Python различается регистр символов и они не могут содержать пробельные +# символы, программисты используют несколько схем в идентификаторах, состоящих из нескольких слов. +# +# +# 1. Змеиный регистр (snake_case) разделяет слова символом подчеркивания, который напоминает ползущую +# между словами змею. В этом случае все буквы записываются в нижнем регистре, а константы часто +# записываются в верхнем змеином регистре (UPPER_SNAKE_CASE). +# +# 2. Верблюжий регистр (camelCase) — слова записываются в нижнем регистре, но второе и следующие +# слова начинаются с заглавной. Эта схема в большин- +# стве случаев подразумевает, что первое слово начинается с буквы нижнего регистра. +# Буквы верхнего регистра напоминают верблюжьи горбы. +# +# 3. Схема Pascal (PascalCase) — названа так, потому что применяется в языке программирования Pascal +# Аналогична схеме верблюжьего регистра, но первое слово в ней тоже начинается с заглавной. +# +# +# ### Соглашения об именах PEP 8 +# +# +# - **Символы в идентификаторах**: +# - Должны быть **ASCII-символами** (латинские буквы без диакритических знаков) +# +# +# - **Стили именования**: +# - **Модули**: короткие, только строчные буквы (`lowercase`) +# - **Классы**: записываются в **PascalCase** (CapWords). +# - **Константы**: записываются в **UPPER_SNAKE_CASE** (все заглавные с подчёркиваниями). +# - **Функции, методы и переменные**: записываются в **snake_case** (строчные с подчёркиваниями). +# +# +# - **Специальные аргументы**: +# - Первый аргумент **метода экземпляра** — всегда `self` (в нижнем регистре) +# - Первый аргумент **метода класса** — всегда `cls` (в нижнем регистре) +# +# +# - **Атрибуты классов**: +# - **Приватные** атрибуты начинаются с символа подчёркивания (`_`) +# - **Публичные** атрибуты **не начинаются** с подчёркивания +# +# +# - **Гибкость применения правил**: +# - PEP 8 **не обязателен к неукоснительному соблюдению** +# - Допустимо использовать идентификаторы на других языках +# - Можно использовать другие стили (например, camelCase), если это улучшает читаемость +# +# - **Главный принцип читаемости**: +# - Важнее не выбор конкретной схемы именования, а **последовательность её применения** в рамках проекта или модуля +# +# +# ### Длина имен +# +# +# **Рекомендации по выбору имён переменных и функций** +# +# **Общий принцип** +# - Код читают чаще, чем пишут → **предпочтение более длинным, понятным именам**, +# даже если их дольше вводить +# +# +# **Слишком короткие имена — проблема читаемости** +# +# +# - **Одно- или двухбуквенные имена** (например, `g`) неясны: неизвестно, какое слово они обозначают +# +# +# - **Сокращения** (`mon` → monitor/month/monster?) вводят в заблуждение +# +# +# - **Однословные имена** (`start`) не указывают контекст: начало чего? +# +# +# - Такие имена могут быть понятны автору в момент написания, +# но **непонятны другим или самому через время** +# +# +# **Допустимые исключения для коротких имён** +# +# +# - `i`, `j`, `k` — для индексов в циклах `for` +# +# +# - `x`, `y` — для декартовых координат +# +# +# - Иногда допустимы `w`/`h` (width/height) или `n` (number), +# но это **не всегда очевидно** другим +# +# +# **Слишком длинные имена — когда это оправдано** +# +# +# - Чем **шире область видимости** (например, глобальная переменная в большом проекте), +# тем **более содержательным должно быть имя** +# +# +# - Пример: `payment` — нормально для локальной переменной; +# `salesClientMonthlyPayment` — лучше для глобального контекста +# +# +# - **Уточняющие слова устраняют неоднозначность** → лучше перестраховаться, чем недоговорить +# +# +# **Не пропускайте буквы** +# +# +# - Имена вроде `memcpy` или `strcmp` (из C) **устарели** и плохо читаются +# +# +# - Имя должно быть **произносимым и понятным** +# +# +# - Предпочтение **естественным фразам**: `number_of_trials` лучше, чем `number_trials` +# +# +# **Префиксы: когда полезны, а когда избыточны** +# +# +# - **Избыточные префиксы**: +# - `catWeight` в классе `Cat` — излишне, так как `weight` и так относится к кошке +# - **Венгерская нотация** (`strName`, `iVacationDays`) — устарела: +# современные IDE и типизация делают её ненужной +# +# +# - **Полезные префиксы**: +# - `is_`, `has_` для **логических значений**: +# `is_vehicle`, `has_key()` → код читается как естественный язык +# - **Единицы измерения** в имени (`weight_kg`, `speed_mph`) — **не венгерская нотация** +# Пример: ошибка Mars Climate Orbiter (1999) из-за путаницы между +# фунтами и ньютонами обошлась в $125 млн +# +# +# **Последовательные числовые суффиксы — признак плохого дизайна** +# +# +# - Имена вроде `payment1`, `payment2`, `payment3` **не объясняют различий** +# +# +# - Лучшие альтернативы: +# - Объединить в коллекцию: `payments = [p1, p2, p3]` +# - Передавать параметр: `makePayment(priority=1, amount)` +# - Использовать осмысленные имена: `makeHighPriorityPayment()`, `make1stQuarterPayment()` +# +# +# - Числовые суффиксы допустимы **только при веской причине**, а не из лени +# +# +# **Выбирайте имена, пригодные для поиска** +# +# +# - Короткие и обобщённые имена (`num`, `a`, `email`) вызывают **ложные совпадения** +# при поиске (Ctrl+F) +# +# +# - **Уникальные, конкретные имена** проще найти и понять: +# - Вместо `email` → `emailAddress`, `replyToAddress`, `downloadEmailAttachment` +# +# +# - Даже при наличии инструментов рефакторинга в IDE, **пишите так, будто их нет** — +# это стимулирует выбор более осмысленных имён +# +# +# ## Не заменяйте встроенные имена +# +# +# - **Никогда не используйте встроенные имена Python** (например, `list`, `set`, `str`, `open`) +# **в качестве имён своих переменных**. +# - Это **перезаписывает встроенные функции**, что может привести к ошибкам. +# - Пример: после `list = ['cat', 'dog']` вызов `list(range(5))` вызовет +# `TypeError: 'list' object is not callable`. +# +# +# - **Как проверить, является ли имя встроенным**: +# - Введите имя в интерактивной оболочке Python. +# - Если возвращается объект (например, ``), имя занято. +# - Попробуйте импортировать как модуль. +# - `NameError` или `ModuleNotFoundError` означают, что имя свободно. +# +# +# - **Часто переопределяемые встроенные имена** (избегайте их!): +# - `all`, `any`, `date`, `email`, `file`, `format`, `hash`, `id`, `input`, `list`, `min`, +# `max`, `object`, `open`, `random`, `set`, `str`, `sum`, `test`, `type`. +# +# +# - **Не называйте свои `.py`-файлы так же, как сторонние модули**. +# - Пример: файл `pyperclip.py` в рабочей директории **перекрывает** установленный +# модуль `pyperclip`. +# - При `import pyperclip` импортируется ваш файл, а не настоящий модуль → +# вызов `pyperclip.copy()` завершится ошибкой `AttributeError`. +# +# +# - **Общее правило**: избегайте конфликтов имён с встроенными функциями, модулями и сторонними +# библиотеками — это частая причина неочевидных ошибок, особенно `AttributeError` при отсутствии +# ожидаемых функций. +# +# +# ## Итоги +# +# ### Плохие примеры имён +# - **`data`** — бессодержательно, так как *все* переменные содержат данные. +# - **`var`** — тавтология (аналог клички «Собака» для собаки). +# - **`temp`** — неинформативно; все переменные временные по своей природе. +# - Такие имена распространены, но их **следует избегать**. +# +# ### Хорошая альтернатива +# - Вместо обобщённых имён используйте **конкретные и описательные**: +# - Например: `temperatureVariance` вместо `tempVarData`. +# +# ### Основные принципы выбора имён +# - Выбор имён не связан с алгоритмами, но **критически важен для читаемости кода**. +# - Следуйте рекомендациям PEP 8: +# - Модули — `lowercase`. +# - Классы — `PascalCase`. +# - Функции/переменные — `snake_case`. +# - Константы — `UPPER_SNAKE_CASE`. +# - Имена **не должны быть слишком короткими или слишком длинными**. +# - Лучше слегка избыточное, чем недостаточно содержательное имя. +# +# ### Требования к хорошему имени +# - **Лаконичное**, но **информативное**. +# - **Уникальное** — легко находится через поиск (Ctrl+F). +# - **Понятное** даже тем, для кого английский не родной. +# - **Без шуток, каламбуров и культурных отсылок** — они не универсальны и часто непонятны. +# - **Прямолинейное, традиционное, без юмора**. +# +# ### Избегайте конфликтов с встроенными именами +# - Не используйте имена, зарезервированные стандартной библиотекой Python: +# - `all`, `any`, `date`, `email`, `file`, `format`, `hash`, `id`, `input`, `list`, `min`, +# `max`, `object`, `open`, `random`, `set`, `str`, `sum`, `test`, `type`. +# - Их переопределение вызывает **скрытые и трудноуловимые ошибки**. +# +# ### Главный вывод +# - Компьютеру безразличны имена — они нужны **людям**. +# - Хорошо читаемый код → понятный код → легко изменяемый код → проще исправлять ошибки и +# добавлять функции. +# - **Понятные имена — основа качественного программного обеспечения.** +# diff --git a/python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.py b/python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.py new file mode 100644 index 00000000..2e298b10 --- /dev/null +++ b/python_issue/made-easy/chapter_1_introduction_to_data_science_and_programming_fundamentals.py @@ -0,0 +1,237 @@ +"""Introduction to Data Science and Programming Fundamentals.""" + +# # Введение в Data Science +# +# +# **Data Science** - это научная дисциплина, которая включает в себя извлечение информации +# из огромных объемов данных с использованием различных научных +# методов, алгоритмов и процессов. Эта наука помогает обнаруживать в необработанных +# данных скрытые закономерности. +# +# +# Эта наука помогает нам: +# - задавать правильные вопросы; +# - находить основную причину проблемы; +# - находить закономерности среди, на первый взгляд, хаотичных необработанных +# данных; +# - создавать модели для предиктивного анализа; +# - визуализировать и отображать результаты с помощью графиков, информацион- +# ных панелей и т. д.; +# - наделять машины интеллектом; +# - определять лояльность клиентов с помощью анализа настроений; +# - принимать более качественные и быстрые решения; +# - рекомендовать правильный продукт нужному клиенту для развития нашего бизнеса. +# +# +# **Машинное обучение** - это инструмент для извлечения знаний из данных. +# В машинном обучении модели могут обучаться на данных самостоятельно или +# поэтапно: обучение с учителем, т. е. на данных, подготовленных человеком, или +# обучение без учителя, в котором работа ведется над хаотичными и неорганизованными +# данными. +# +# **Глубокое обучение** - это создание многослойных нейронных сетей в областях, +# где требуется более продвинутый или быстрый анализ, а традиционное машинное +# обучение не справляется. Под глубиной понимается наличие более одного +# скрытого слоя нейронов в сети, которые проводят математические вычисления. +# +# **Большие данные** - это работа с огромными объемами часто неструктурированных +# данных. Специфика этой сферы - инструменты и системы, способ1;1ые +# выдерживать высокие нагрузки. +# +# +# **Статистика** +# Статистика лежит в основе Data Science. Правильная обработка статистики +# может помочь вам извлечь больше информации и получить более значимые +# результаты. +# +# **Базы данных** +# Будучи специалистом по данным, вам необходимо понимать, как работают базы +# данных, как ими управлять и как извлекать из них данные. +# +# **Моделирование** +# Математические модели позволяют выполнять вычисления и прогнозы на основе +# того, что вы уже знаете о данных. Моделирование также относится к машинному +# обучению и включает определение того, какой алгоритм больше подходит +# для решения данной проблемы и как обучать эти модели. +# +# +# **Программирование** - это идеи, преобразованные в пошаговые +# инструкции, понятные компьютеру. Такая пошаговая инструкция называется **алгоритмом**. +# +# **Алгоритм** - это конечная последовательность четко определенных, +# реализуемых компьютером инструкций для решения какой-то проблемы или +# для выполнения вычислений. Алгоритмы всегда однозначны и используются для +# вычислений, обработки данных, автоматизированных решений и других задач. +# +# +# ### Реальный пример алгоритма +# +# +# Шаг 1: Начало. +# Шаг 2: Возьмите ковшик и налейте в него один стакан воды. +# Шаг 3: Зажгите конфорку и поставьте на нее ковшик. +# Шаг 4: Доведите воду до кипения. +# Шаг 5: Добавьте в кипящую воду две столовые ложки сахара и две столовые ложки чайных листьев. +# Шаг 6: Добавьте в кипящую смесь одну чашку молока. +# Шаг 7: Варите содержимое в течение одной минуты. +# Шаг 8: Выключите конфорку. +# Шаг 9: Процедите чай через сито. +# Шаг 10: Разлейте чай по чашкам и подавайте. +# Шаг 11: Конец. +# +# +# Алгоритмы можно изображать в графической форме с использованием определенных +# обозначений. Полученное изображение называется блок-схемой. +# В блок-схемах для представления различных функций программ используются +# некоторые стандартные символы. +# +# +# Компилятор - это программа, преобразующая исходный код в машинный. +# +# Интерпретатор - это компьютерная программа, +# которая непосредственно выполняет инструкции, написанные на языке +# программирования, без предварительной компиляции в программу на машинном +# языке. + +# 1.5.1. Ответьте на вопросы +# +# 1. Какие предметные области входят в Data Science? Что между ними общего и +# в чем различие? +# +# Программирование +# Статистика +# Базы данных +# Моделирование +# +# Общее - работа с данными как с основным объектом +# Различия - фокус на разных моментах, разные выходные данные и задачи которые они решают +# +# 2. Как вы понимаете термин «алгоритм»? Как алгоритмы связаны с блок-схемами? +# +# Алгоритм - конечная последовательность четко определенных, +# реализуемых компьютером инструкций для решения какой-то проблемы +# +# Иногда алгоритмы изображаются в графической форме, используя определенные обозначения, +# графический вид алгоритма и есть блок-схема +# +# 3. Какую программу можно назвать хорошей? Запишите все характеристики, какие +# удастся придумать. +# +# Хорошая программа обладает следующими характеристиками: корректностью, надёжностью, читаемостью, +# поддерживаемостью, тестируемостью, эффективностью, безопасностью, удобством использования, +# расширяемостью, переносимостью и соблюдением принятых стандартов кодирования. +# +# 4. Какой язык понимает компьютер? +# +# Машинный код +# +# 5. Чем языки программирования отличаются от языков, на которых мы говорим? +# +# Языки программирования строго формализованы, однозначны и предназначены для общения с машиной, +# тогда как естественные языки гибкие, многозначные и служат для общения между людьми. +# +# +# 1.5.2. Правда или ложь +# +# 1. Машинное обучение - это инструмент для извлечения знаний из данных. +# Правда +# +# 2. Глубокое обучение - это то же самое, что машинное обучение. +# Ложь, глубокое обучение — подмножество машинного обучения +# +# 3. Все инженеры-программисты также могут считаться специалистами по данным. +# Ложь +# +# 4. Статистика - важный инструмент для специалистов по данным. +# Правда +# +# 5. Компьютер может принимать решения, выходящие за рамки данных ему инструкций, +# подстраиваясь под изменения среды. +# Ложь, строго по заданной инструкции +# +# 6. Компьютеры понимают языки программирования «как есть». +# Ложь, компьютер «понимает» только машинный код; языки программирования преобразуются +# в него с помощью компиляторов/интерпретаторов +# +# 7. Некоторые языки программирования компилируются, некоторые интерпретируются, +# а некоторые используют и то и другое. +# Правда +# +# 8. Все программы выполняются последовательно. +# Правда +# +# 9. В IDЕ есть встроенный текстовый редактор. +# Правда +# +# 10. Компиляторы и интерпретаторы - это такие механизмы, наподобие привода +# для компакт-дисков. +# Ложь +# +# +# 1.5.3. Практические задания +# +# 1. Напишите алгоритм для расчета простых процентов от некоторой суммы. +# Шаг 1. Начало +# Шаг 2. Введите число, сумму, от которой будет браться процент и сохраните ее в start_sum +# Шаг 3. Введите число, процент, который будет браться от суммы и сохраните ее в percent +# Шаг 4. Проведите вычисление, start_sum / 100 * percent и сохраним ее в final_percent +# Шаг 5. Выведите final_percent +# Шаг 6. Конец +# +# 2. Напишите алгоритм для вычисления площади прямоугольника. +# Шаг 1. Начало +# Шаг 2. Введите число, ширину, сохраните в rectangular_width +# Шаг 3. Введите число, длину, сохраните в rectangular_height +# Шаг 4. Проведите вычисление height * width и сохраните в rectangular_area +# Шаг 5. Выведите rectangular_area +# Шаг 6. Конец +# +# 3. Напишите алгоритм вычисления периметра круга. +# Шаг 1. Начало +# Шаг 2. Введите число, радиус, сохраните в circle_radius +# Шаг 3. Проведите вычисление 2 * \Pi * circle_radius, сохраните в circle_area +# Шаг 4. Выведите circle_area +# Шаг 5. Конец +# +# 4. Напишите алгоритм, который находит все простые числа меньше 100. +# Шаг 1. Начало +# Шаг 2. Создайте список всех простых чисел от 2 до 100 не включительно +# Шаг 3. Берем первое число в созданном списке записываем в simple_digit +# Шаг 4. Выводим simple_digit +# Шаг 5. Удаляем simple_digit из списка +# Шаг 6. Удаляем все числа кратные simple_digit +# Шаг 7. Возвращаемся к шагу 3 +# Шаг 8. Конец +# +# 5. Напишите алгоритм превращения предложения, написанного в верхнем регистре, +# в обычный для предложений регистр. +# Шаг 1. Начало +# Шаг 2. Создайте переменную index и присваиваем значение 1 +# Шаг 3. Проведите вычисление index + 1 +# Шаг 4. Поменяйте регистр буквы номер index с верхнего на нижний +# Шаг 5. Проверьте что значение index не больше длинны предложения если больше то перейдите к шагу 6 +# если меньше то перейдите к шагу 3 +# Шаг 6. Конец +# +# 6. Составьте блок-схему приготовления льда из кипяченой воды с помощью холодильника. +# +# ![image.png](attachment:image.png) +# +# 7. Составьте блок-схему для нахождения суммы всех четных чисел меньше ста. +# +# ![image-3.png](attachment:image-3.png) +# +# 8. Составьте блок-схему для вычисления квадрата всех нечетных чисел от 1 до 15 +# включительно. +# +# ![image-4.png](attachment:image-4.png) +# +# 9. Составьте блок-схему вывода таблицы умножения на 3. +# +# ![Снимок экрана 2025-10-05 185114.png]() +# +# 10. Составьте блок-схему для расчета сложных процентов (с капитализацией). +# +# ![image-5.png](attachment:image-5.png) + +# diff --git a/python_issue/made-easy/chapter_2_introduction_to_python.py b/python_issue/made-easy/chapter_2_introduction_to_python.py new file mode 100644 index 00000000..a7495ca3 --- /dev/null +++ b/python_issue/made-easy/chapter_2_introduction_to_python.py @@ -0,0 +1,211 @@ +"""Introduction to Python.""" + +# # Введение в Python +# +# +# **Python** - это бесплатный интерпретируемый высокоуровневый язык программирования +# общего назначения с открытым исходным кодом. +# +# Что касается популярности, то самыми популярными языками программирования +# для специалистов по данным являются: +# - Python +# - С++ +# - R +# - Java +# - SQL +# - Matlab +# +# +# Программы, написанные на Python, обычно намного короче таких же программ на С, С++ или Java +# по нескольким причинам. +# - Типы данных высокого уровня позволяют записывать сложные операции в одну +# строку. +# +# - Группировка операторов выполняется с помощью отступов, а не с помощью +# скобок в начале и конце блока. +# +# - Объявление переменных или аргументов не требуется. +# +# +# ## Философия Python +# +# +# - Красивое лучше, чем уродливое. +# - Явное лучше, чем неявное. +# - Простое лучше, чем сложное. +# - Сложное лучше, чем запутанное. +# - Читаемость имеет значение. +# +# +# ## Преимущества Python +# +# +# - Простота +# - Легкость в изучении +# - Свободны й и открытый исходный код +# - Высокоуровневость +# - Портативность +# - Интерпретируемость +# - Объектная ориентированность +# - Расширяемость +# - Встраиваемость +# - Внушительные библиотеки +# +# +# ## Дистрибутив Anaconda +# +# +# Anaconda - это самый простой и наиболее часто используемый способ +# установки Python и других необходимых пакетов. Он находится в свободном +# доступе и прост в установке. +# +# Он является отраслевым стандартом в области разработки, тестирования +# и машинного обучения и позволяет специалистам по данным: +# - быстро загрузить более 1 500 пакетов Python/R, предназначенных для задач анализа +# данных; +# +# - управлять библиотеками, зависимостями и средами с помощью Conda; +# +# - разрабатывать и обучать модели машинного обучения и глубокого обучения +# с помощью пакетов Scikit-leam, TensorFlow и Theano; +# +# - выполнять эффективный и масштабируемый анализ данных с помощью Dask, +# NumPy, Pandas и Numba; +# +# - визуализировать результаты с помощью Matplotlib, Bokeh, Datashader и Holoviews. +# +# +# ## Запуск Python через командную строку +# +# +# Командная строка - это приложение, которое позволяет запускать команды для +# просмотра папок и файлов, выполнения скриптов и, конечно, для работы с Python. +# +# Консоль (она же терминШL или командная строка) - это текстовый способ взаимодействия +# с вашей ОС, точно такой же, по существу, как рабочий стол и мышь, +# которые тоже являются способом взаимодействия с системой. +# +# +# ## Jupyter Notebook +# +# +# **Jupyter Notebook** - это интерактивная вычислительная веб-платформа. В ее документах +# сочетаются выполняемый код, математические уравнения, обычный +# текст, средства визуализации, интерактивные информационные панели и другие +# мультимедийные средства. Этот инструмент становится очень полезным, когда необходимо +# опубликовать результаты анализа данных (а это нужно в большинстве +# случаев). Здесь вы можете писать код и документацию, создавать диаграммы и +# давать пояснения - и все в одном месте. +# +# Этот редактор расширяет консольный подход к интерактивным вычислениям в качественно +# новом направлении и сконструирован как веб-приложение, подходящее +# для записи всего вычислительного процесса: разработки, документирования и выполнения +# кода, а также передачи результатов. Jupyter Notebook объединяет в себе +# два компонента: +# +# - веб-приложение - инструмент на основе браузера, предназначенный для интерактивного +# создания документов, сочетающий в себе пояснительный текст, +# математические вычисления и мультимедийный вывод результатов; +# +# - документы Notebook, содержащие все видимое в веб-браузере, включая входные +# и выходные данные вычислений, пояснительный текст, математические данные, +# изображения и мультимедийные представления объектов. + +# 2.12.1. Ответьте на вопросы +# +# 1. Python - это программное обеспечение с открытым исходным кодом. Это то +# же самое, что и бесплатное ПО? +# Открытый исходный код позволяет гибко настраивать его под себя, пользователи могут изучать, +# изменять и распространять его. Если говорить о бесплатном ПО, то это верно для питона, но +# тут слово free скорее используется в значении свободный +# +# 2. У всех ли бесплатных программ открытый исходный код? А если нет, то в чем +# разница? +# Нет не у всех бесплатных программ открытый исходный код, опять же тут идет разница между +# freeware и free software, бесплатное не означает открытое +# +# 3. Python поддерживает динамическую типизацию. Что это такое? +# В Python значение, на которое указывает переменная, имеет определенный тип +# данных, но сама переменная не имеет строгого типа. +# +# 4. Назовите 5 самых популярных языков программирования для специалистов по +# анализу данных. +# Python, R, SQL, C++, Java, Matlab +# +# 5. В чем заключается преимущество Python по сравнению с языком С? +# Преимущество Python перед языком C заключается в его простоте, читаемости и высокой +# производительности разработки: Python позволяет писать меньше кода для решения той же +# задачи благодаря высокоуровневым конструкциям и богатой стандартной библиотеке. +# В то время как C требует ручного управления памятью и более детального описания процессов, +# Python автоматизирует многие низкоуровневые операции, что ускоряет написание и отладку программ, +# особенно в областях вроде анализа данных, веб-разработки и машинного обучения. +# +# 6. Python портативен. Что в этом контексте означает «портативность»? +# Python можно использовать на разных типах машин, +# независимо от аппаратных средств или ограничений операционной системы +# +# 7. В чем разница между «расширяемым» и «встраиваемым» языком? +# Расширяемый язык можно дополнить кодом на другом языке программирования +# Встраиваемый язык можно добавить в программу на другом языке программирования +# +# 8. В чем смысл IDE? Чем она отличается от командной строки? +# IDE — это полный рабочий стол программиста со всеми удобствами, +# а командная строка — инструмент для выполнения команд, без встроенной поддержки разработки +# +# 9. Как открыть существующий документ Jupyter Notebook? Чем эта процедура отличается +# от открытия РDF-файла или текстового файла? +# - Запустить Jupyter Notebook или JupyterLab из командной строки +# (например, командой `jupyter notebook` или `jupyter lab`). +# - В открывшемся веб-интерфейсе (в браузере) перейти в папку, где находится нужный .ipynb-файл. +# - Кликнуть по имени файла — он откроется в интерактивной среде, +# где можно запускать ячейки кода, редактировать их и видеть результаты выполнения. +# +# +# 10. В чем разница между «ячейками разметки Markdown» и «ячейками кода» +# в Jupyter Notebook? Для чего они нужны? +# Ячейка кода позволяет редактировать и писать новый код с выделением синтаксиса +# цветом и заполнением табуляцией. Используемый вами язык программирования +# зависит от ядра, а ядро по умолчанию (IPython) запускает код Python. +# +# Язык Markdown - это простой способ выполнить разметку +# текста и указать, какой текст нужно выделить курсивом, какой жирным шрифтом, +# где вставить список и т. д. +# При выполнении ячейки Markdown разметка Markdown преобразуется в соответствующий +# форматированный текст. Markdown также допускает форматирование +# с помощью НТМL-кода. +# +# +# 2.12.2. Правда или ложь +# +# 1. Язык программирования Python был назван в честь змеи питон. +# Ложь, назван в честь шоу «Летающий цирк Монти Пайтона» +# +# 2. Python - это высокоуровневый язык общего назначения. +# Правда +# +# 3. Python компилируется и не интерпретируется. +# Ложь, Python — интерпретируемый язык +# +# 4. В Python команда два + два вернет Четыре. +# Правда, 2 + 2 выведет 4, если написать словами то получится "двадва" +# +# 5. Консоль IPython аналогична окну командной строки. +# Правда +# +# 6. Графики, выводимые в документе Jupyter Notebook, отображаются внутри +# самого документа. +# Правда +# +# 7. В комплекте с пакетом Aлaconda идут браузеры Chrome и Firefox. +# Ложь +# +# 8. «Простое лучше, чем сложное» - это одна из философий Python. +# Правда +# +# 9. Аббревиатура FLOSS означает «Free/Libre and Open Source Software». +# Правда +# +# 10. Python поддерживает ТОЛЬКО объектно-ориентированное программирование. +# Ложь, Python — мультипарадигменный язык +# +# diff --git a/python_issue/makarov/chapter_10_numpy_array.py b/python_issue/makarov/chapter_10_numpy_array.py new file mode 100644 index 00000000..2b127753 --- /dev/null +++ b/python_issue/makarov/chapter_10_numpy_array.py @@ -0,0 +1,657 @@ +"""Numpy array.""" + +import matplotlib.pyplot as plt +import numpy as np +from scipy.sparse import csr_matrix + +# ## Массив Numpy + +# ### Как создать массив Numpy + +# #### Функция np.array() +# +# + +arr_list = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) +print(arr_list) + +arr_tuple = np.array((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0)) +print(arr_tuple) + +# #### Функция np.arange() +# + +arr_range_full = np.arange(10) +print(arr_range_full) + +arr_main = np.arange(2, 10, 2) +print(arr_main) + +# в arange() тип float допускается +print(np.arange(2, 5.5, 0.5)) + +# #### Тип данных элементов массива +# + +# Можно указать явно тип данных массива +arr_f = np.array((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0), float) +print(arr_f) +print(arr_f.dtype) + +# ### Свойства (атрибуты) массива +# + +print(arr_main) + +# #### Количество измерений +# + +print(arr_main.ndim) + +# #### Количество элементов в каждом измерении +# + +print(arr_main.shape) + +# #### Общее количество элементов во всех измерениях +# + +print(arr_main.size) + +# #### Tип данных массива +# + +print(arr_main.dtype) + +print(arr_main.nbytes) + +print(arr_main.size * arr_main.itemsize) + +# ### Измерения массива +# +# + +# #### Массив с нулевым измерением + +arr_0d_scalar = np.array(42) +print(arr_0d_scalar.ndim) +print(arr_0d_scalar.shape) +print(arr_0d_scalar.size) + +# #### Одномерный массив (вектор) +# + +arr_1d_vector = np.array([42, 15, 52, 63, 94]) +print(arr_1d_vector.ndim) +print(arr_1d_vector.shape) +print(arr_1d_vector.size) + +# #### Двумерный массив (матрица) +# + +arr_2d_matrix = np.array([[42, 15, 52, 63], [94, 22, 53, 15]]) +print(arr_2d_matrix.ndim) +print(arr_2d_matrix.shape) +print(arr_2d_matrix.size) + +# такая матрица имеет три строки с один элементом в каждой +column = np.array([[1], [2], [3]]) +print(column) + +print(column.shape) + +# такая матрица имеет три строки с один элементом в каждой +row = np.array([[1, 2, 3]]) +print(row) + +print(row.shape) + +# #### Трехмерный массив +# + +arr_3d_info = np.arange(12).reshape(2, 2, 3) +print(arr_3d_info) + +print(arr_3d_info.ndim) +print(arr_3d_info.shape) +print(arr_3d_info.size) + +# ### Другие способы создания массивов +# +# + +# #### Функция np.zeros() + +print(np.zeros(5)) + +print(np.zeros((2, 3))) + +# #### Функция np.ones() +# + +print(np.ones((2, 3))) + +# #### Функция np.full() +# + +print(np.full((2, 3), 4)) + +# Функция np.empty() +print(np.empty((3, 2))) + +# #### Функции np.zeros_like(), np.ones_like(), np.full_like(), np.empty_like() +# + +base_matrix = np.arange(1, 7).reshape(2, 3) +print(base_matrix) + +print(np.zeros_like(base_matrix)) + +print(np.ones_like(base_matrix)) + +print(np.full_like(base_matrix, 10)) + +print(np.empty_like(base_matrix)) + +# #### Функция np.linspspace() +# + +print(np.linspace(0, 0.9, 10)) + +print(np.arange(0, 1, 0.1)) + +# + +plt.figure(figsize=(8, 6)) + +x_line = np.linspace(-5, 5, 5000) +y_parabola = x_line**2 + +plt.grid() + +plt.plot(x_line, y_parabola) + +plt.xlabel("x", fontsize=14) +plt.ylabel("y", fontsize=14) + +plt.show() + +print(x_line[:10]) +# - + +# #### Функции np.random.rand() и np.random.randint() +# + +print(np.random.rand(4, 3)) + +print(np.random.randint(-3, 3, size=(2, 3, 2))) + + +# #### np.fromfunction() +# + + +# + +def power(base_val: float, exp_val: float) -> float: + """Temporary training function.""" + return float(base_val**exp_val) + + +print(np.fromfunction(power, (3, 3))) +# - + +print(np.fromfunction(lambda row_idx, col_idx: row_idx == col_idx, (3, 3))) + +# ### Матрица в формате csr и метод .toarray() +# + +matrix_sparse_data = np.array( + [[2, 0, 0, 1, 0, 0, 0], [0, 0, 3, 0, 0, 2, 0], [0, 0, 0, 1, 0, 0, 0]] +) +print(matrix_sparse_data) + +# #### Доля нулевых значений +# + +print(1.0 - np.count_nonzero(matrix_sparse_data) / matrix_sparse_data.size) + +# + +csr_matrix_data: csr_matrix = csr_matrix(matrix_sparse_data) + +print(csr_matrix_data) +# - + +dense_data = csr_matrix_data.toarray() +print(dense_data) + +# ### Индексы и срезы +# +# + +# #### Индекс элемента массива + +matrix_2x3 = np.array([[1, 2, 3], [4, 5, 6]]) +print(matrix_2x3) +print(matrix_2x3.shape) +print(matrix_2x3[0]) +print(matrix_2x3[0][0]) +print(matrix_2x3[0][1]) + +# ### Срез массива +# +# + +# #### Массив 1D + +vector_1_to_8 = np.arange(1, 9) +print(vector_1_to_8) + +print(vector_1_to_8[1:6:2]) + +# #### Массив 2D +# + +matrix_2x4 = np.arange(1, 9).reshape(2, 4) +print(matrix_2x4) + +print(matrix_2x4[0, :2]) +print(matrix_2x4[:, 1]) +print(matrix_2x4[0, 0]) +print(matrix_2x4[-1, -1]) +print(matrix_2x4[1, ::2]) + +# #### Массив 3D +# + +tensor_4x2x2 = np.arange(16).reshape(4, 2, -1) +print(tensor_4x2x2) + +print(tensor_4x2x2[2][1][0]) +print() +print(tensor_4x2x2[2:, 1, :]) +print() +print(tensor_4x2x2[:2]) +print() +print(tensor_4x2x2[:, 0, :]) + +# ### Оси массива +# +# + +# #### Массив 2D + +arr_2d_sum = np.array([[1, 2], [3, 4]]) +print(arr_2d_sum) +print(arr_2d_sum.shape) + +# Сложение вдоль первой оси (axis = 0) +print(np.sum(arr_2d_sum, axis=0)) + +# Сложение вдоль второй оси (axis = 1) +print(np.sum(arr_2d_sum, axis=1)) + +# Сложение вдоль обеих осей (axis = (0, 1)) +print(np.sum(arr_2d_sum, axis=(0, 1))) +print(np.sum(arr_2d_sum)) +print(np.sum(arr_2d_sum, axis=None)) + +# Отрицательные значения в параметре axis +print(np.sum(arr_2d_sum, axis=-1)) +print(np.sum(arr_2d_sum, axis=-2)) + +# ### Массив 3D +# + +arr_3d_sum = np.arange(12).reshape(2, 2, 3) +print(arr_3d_sum) + +# применим np.sum() с параметром axis = 0 +print(np.sum(arr_3d_sum, axis=0)) # == +print() +print(arr_3d_sum[0]) +print() +print(arr_3d_sum[1]) +print() +print(arr_3d_sum[0] + arr_3d_sum[1]) # == + +# + +sum_axis0 = np.zeros((2, 3)) + +for row_idx in range(2): + sum_axis0 += arr_3d_sum[row_idx] + +print(sum_axis0) +# - + +# Сложение вдоль второй оси (axis = 1) +print(np.sum(arr_3d_sum, axis=1)) + +print(arr_3d_sum[0][0] + arr_3d_sum[0][1]) + +print(arr_3d_sum[1][0] + arr_3d_sum[1][1]) + +# + +sum_axis1 = np.zeros((2, 3)) + +for row_idx in range(2): + for col_idx in range(2): + sum_axis1[row_idx] += arr_3d_sum[row_idx][col_idx] + +print(sum_axis1) +# - + +# Сложение вдоль третьей оси (axis = 2) +print(np.sum(arr_3d_sum, axis=2)) + +print(arr_3d_sum[0][0][0] + arr_3d_sum[0][0][1] + arr_3d_sum[0][0][2]) +print(arr_3d_sum[0][1][0] + arr_3d_sum[0][1][1] + arr_3d_sum[0][1][2]) +print(arr_3d_sum[1][0][0] + arr_3d_sum[1][0][1] + arr_3d_sum[1][0][2]) +print(arr_3d_sum[1][1][0] + arr_3d_sum[1][1][1] + arr_3d_sum[1][1][2]) + +# + +sum_axis2 = np.zeros((2, 2)) + +for plane_idx in range(2): + for row_idx in range(2): + for value in arr_3d_sum[plane_idx][row_idx]: + sum_axis2[plane_idx][row_idx] += value + +print(sum_axis2) +# - + +print(arr_3d_sum) + +# Сложение вдоль первой и второй осей (axis = (0, 1)) +print(np.sum(arr_3d_sum, axis=(0, 1))) # == + +# + +sum_axes0_1 = np.zeros((2, 3)) + +for plane_idx in range(2): + sum_axes0_1 += arr_3d_sum[plane_idx] + +print(sum_axes0_1) + +# + +sum_axis0_after = np.zeros(3) + +for row_idx in range(2): + sum_axis0_after += sum_axes0_1[row_idx] + +print(sum_axis0_after) + +# + +sum_axis_all = np.zeros(3) + +for plane_idx in range(2): + for row_idx in range(2): + sum_axis_all += arr_3d_sum[plane_idx][row_idx] + +print(sum_axis_all) +# - + +# Сложение вдоль всех трех осей (axis = (0, 1, 2)) +print(np.sum(arr_3d_sum, axis=(0, 1, 2))) # == +print(np.sum(arr_3d_sum)) # == + +# + +sum_axis_all_int: int = 0 + +for plane_idx in range(2): + for row_idx in range(2): + for depth_idx in range(3): + sum_axis_all_int += arr_3d_sum[plane_idx][row_idx][depth_idx] + +print(sum_axis_all_int) +# - + +# ### Операции с массивами +# +# + +# #### Функция len() + +arr_3d_reshape = np.arange(12).reshape(2, 2, -1) +print(arr_3d_reshape) + +print(len(arr_3d_reshape)) + +print(len(arr_3d_reshape[0][0])) + +# #### Вхождение в массив +# + +print(3 in arr_3d_reshape) + +print(11 not in arr_3d_reshape) + +# #### Распаковка массива +# + +matrix_3x9 = np.arange(1, 28).reshape(3, 9) +print(matrix_3x9) + +# + +first_row, second_row, third_row = matrix_3x9 + +print(first_row) +print(second_row) +print(third_row) + +# + +first_value, *middle_values, last_value = matrix_3x9[0] + +print(first_value) +print(middle_values) +print(last_value) +# - + +# ### Изменение элементов массива +# + +arr_2d_mutable = np.array([[1, 2, 3], [4, 5, 6]]) +print(arr_2d_mutable) + +# заменим первый элемент первой строки по его индексу +arr_2d_mutable[0][0] = 2 +print(arr_2d_mutable) + +# запишем значение 1 в первую строку +arr_2d_mutable[0] = 1 +print(arr_2d_mutable) + +# запишем 0 в третий столбец массива +arr_2d_mutable[:, 2] = 0 +print(arr_2d_mutable) + +arr_3d_filled = np.arange(12).reshape(2, 2, 3) +print(arr_3d_filled) + +# при такой операции размер среза должен совпадать +# с количеством передаваемых значений +arr_3d_filled[1, :, 1] = [0, 1] +print(arr_3d_filled) + +# заменим все элементы массива на число семь +arr_3d_filled.fill(7) +print(arr_3d_filled) + +# ### Сортировка массива и обратный порядок его элементов +# +# + +# #### Функция np.sort() + +matrix_sort = np.array([[4, 8, 2], [2, 3, 1]]) +print(matrix_sort) + +print(np.sort(matrix_sort)) + +print(np.sort(matrix_sort, axis=1)) + +print(np.sort(matrix_sort, axis=0)) + +print(np.sort(matrix_sort, axis=None)) + +# Обратный порядок элементов массива через оператор среза +print(np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[::-1]) + +print(np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[-3:3:-1]) + +matrix_slice = np.array([[4, 8, 2], [2, 3, 1], [1, 7, 2]]) +print(matrix_slice) + +print(matrix_slice[::-1, ::-1]) + +print(matrix_slice[::-1]) + +print(matrix_slice[:, ::-1]) + +# Обратный порядок через функцию np.flip() +print(np.flip(matrix_slice)) + +print(np.flip(matrix_slice, axis=0)) + +print(np.flip(matrix_slice, axis=1)) + +# #### Сортировка в убывающем порядке +# + +vector_sort = np.array([4, 2, 6, 1, 7, 3, 5]) +# мы можем последовательно применить np.sort() и оператор среза +vector_sort.sort() +print(vector_sort[::-1]) + +# изменение стало постоянным +vector_sort.sort() +print(vector_sort[::-1]) + +# ### Изменение размерности +# +# + +# #### Метод .reshape() + +arr_3d_resize = np.arange(12).reshape(2, 2, 3) +print(arr_3d_resize) + +arr_2d_resize = arr_3d_resize.reshape(2, 6) +print(arr_2d_resize) + +# #### Функция np.resize() и метод .resize() +# + +print(np.resize(arr_2d_resize, (3, 6))) + +# + +arr_2d_copy = arr_2d_resize.copy() + +print(arr_2d_copy.resize(4, 6)) +print(arr_2d_copy) +# - + +# #### Методы .flatten() и .ravel() +# + +# .flatten() переводит ("вытягивает") массив в одно измерение и +# создает копию исходного массива (как метод .copy()) +print(arr_3d_resize.flatten()) + +# .ravel() делает то же самое, +# но не создает копию исходного массива и поэтому быстрее чем .flatten() +print(arr_3d_resize.ravel()) + +# #### np.newaxis - добавляет измерение в массиве +# + +vector_expand = np.array([1, 2, 3]) +print(vector_expand.shape) + +row_expanded = vector_expand[np.newaxis, :] +print(row_expanded) +print(row_expanded.shape) + +col_expanded = vector_expand[:, np.newaxis] +print(col_expanded) +print(col_expanded.shape) + +# #### Функция np.expand_dims() - добавляет измерение по параметру axis +# + +matrix_expand = np.arange(1, 5).reshape(2, 2) +print(matrix_expand) + +print(np.expand_dims(matrix_expand, axis=0)) + +print(np.expand_dims(matrix_expand, axis=1)) + +print(np.expand_dims(matrix_expand, axis=2)) + +# #### Функция np.squeeze() - сжимает первое и последнее измерение, удаляет по сути +# + +arr_4d_squeeze = np.arange(9).reshape(1, 3, 3, 1) +print(arr_4d_squeeze) + +print(np.squeeze(arr_4d_squeeze)) + +print(np.squeeze(arr_4d_squeeze).shape) + +# ### Объединение массивов +# +# + +# #### Функция np.concatenate() + +# + +mat_a = np.arange(4).reshape(2, 2) +mat_b = np.arange(4, 8).reshape(2, 2) + +print(mat_a) +print(mat_b) +# - + +print(np.concatenate((mat_a, mat_b), axis=0)) + +print(np.concatenate((mat_a, mat_b), axis=1)) + +# #### Функция np.stack() + +# Отличие функции np.stack() от np.concatenate() в том, +# что при объединении массивов мы добавляем новое измерение +print(np.stack((mat_a, mat_b), axis=0)) + +print(np.stack((mat_a, mat_b), axis=1)) + +print(np.stack((mat_a, mat_b), axis=2)) + +# ### Фильтр (маска) массива +# +# + +# #### Логическая маска (Boolean mask) + +vector_mask = np.array([1, 3, -2, -5, 4, -10, 11]) + +print(vector_mask > 0) + +# применим маску к исходному массиву +print(vector_mask[vector_mask > 0]) + +# отфильтрованные значения можно заполнить, например, нулями +vector_mask[vector_mask < 0] = 0 +print(vector_mask) + +# ## Документация +# + +# + +# вывод справки по функции с помощью знака вопроса +# print? или ?print +# - + +help(print) + +# + +# поиск по ключевому слову в документации библиотеки Numpy +# результаты отсортированы по важности +# np.lookfor('randint') diff --git a/python_issue/makarov/chapter_15_iterators.py b/python_issue/makarov/chapter_15_iterators.py new file mode 100644 index 00000000..b50cb4c4 --- /dev/null +++ b/python_issue/makarov/chapter_15_iterators.py @@ -0,0 +1,339 @@ +# + +"""Iterators and generators.""" +from itertools import chain, count, cycle + +# pylint: disable=invalid-name +# - + +# ## Итерируемый объект и итератор +# + +for value_1 in [1, 2, 3]: + print(value_1) + +temp_iterator = iter([1, 2, 3]) +print(temp_iterator) + +# + +iterable_object: list[int] = [1, 2, 3] + +list_iterator = iter(iterable_object) +print(list_iterator) +print() + +print(next(list_iterator)) +print(next(list_iterator)) +print(next(list_iterator)) +# - + +for element in iterable_object: + print(element) + +# + +iterable_numbers: list[int] = [1, 2, 3] + +iterator_a = iter(iterable_numbers) +iterator_b = iter(iterable_numbers) + +print(f"A: {next(iterator_a)}") +print(f"A: {next(iterator_a)}") +print(f"A: {next(iterator_a)}") +print(f"B: {next(iterator_b)}") +# - + +print(iterable_numbers) + +iterator_a_list: list[int] = list(iterator_a) +iterator_b_list: list[int] = list(iterator_b) +print(iterator_a_list, iterator_b_list) + +for number_value in [1, 1, 2, 3]: + print(number_value) + +# ## Отсутствие "обратного хода" +# + +# + +iterator_c = iter(iterable_numbers) + +for first_item in iterator_c: + print(first_item) + break + +for remaining_item in iterator_c: + print(remaining_item) +# - + +# ## Функция zip() +# + +zipped_pairs = zip(iterable_numbers, iterable_numbers) +print(zipped_pairs) + +# + +iterator_tuple = zip(iterable_numbers, iterable_numbers) + +print(next(iterator_tuple)) +print(next(iterator_tuple)) +print(next(iterator_tuple)) +# - + +for pair in zip(iterable_numbers, iterable_numbers): + print(pair) + + +# ## Примеры итераторов +# ### Возведение в квадрат +# + + +class Square: + """Iterator returning squared values from a sequence.""" + + def __init__(self, seq: list[int] | tuple[int, ...]) -> None: + """Initialize iterator with sequence.""" + self._seq = seq + self._idx = 0 + + def __iter__(self): # type: ignore[no-untyped-def] + """Return self as iterator.""" + return self + + def __next__(self) -> int: + """Return next squared value or raise StopIteration.""" + if self._idx >= len(self._seq): + raise StopIteration + square_result: int = self._seq[self._idx] ** 2 + self._idx += 1 + return square_result + + +square_iterator: Square = Square([1, 2, 3, 4, 5]) +print(square_iterator) + +for square_value in square_iterator: + print(square_value) + + +# ## Счетчик +# + + +class Counter: + """Simple iterator that counts from start up to stop (exclusive).""" + + def __init__(self, start: int = 3, stop: int = 9) -> None: + """Initialize with bounds.""" + self._current = start - 1 + self._stop = stop + + def __iter__(self): # type: ignore[no-untyped-def] + """Return self as iterator.""" + return self + + def __next__(self) -> int: + """Return next number or raise StopIteration.""" + self._current += 1 + if self._current >= self._stop: + raise StopIteration + return self._current + + +counter_instance: Counter = Counter() +print(counter_instance) + +print(next(counter_instance)) +print(next(counter_instance)) + +for count_value in counter_instance: + print(count_value) + + +# ## Класс Iterator модуля collections.abc +# + + +class Counter2: + """Iterator implementing the Iterator protocol explicitly.""" + + def __init__(self, start: int = 3, stop: int = 9) -> None: + """Initialize with bounds.""" + self._current = start - 1 + self._stop = stop + + def __iter__(self): # type: ignore[no-untyped-def] + """Return self as iterator.""" + return self + + def __next__(self) -> int: + """Return next number or raise StopIteration.""" + self._current += 1 + if self._current >= self._stop: + raise StopIteration + return self._current + + +for count_value in Counter2(): + print(count_value) + + +# ## Бесконечный итератор +# + + +class FibIterator: + """Iterator producing Fibonacci numbers.""" + + def __init__(self) -> None: + """Initialize starting values.""" + self._idx = 0 + self._current = 0 + self._next = 1 + + def __iter__(self): # type: ignore[no-untyped-def] + """Return self as iterator.""" + return self + + def __next__(self) -> int: + """Return next Fibonacci number.""" + if self._idx < 0: + raise StopIteration + self._idx += 1 + self._current, self._next = (self._next, self._current + self._next) + return self._current + + +# + +fib_limit: int = 10 + +for fib_value in FibIterator(): + print(fib_value) + fib_limit -= 1 + if fib_limit == 0: + break + + +# - + +# ## Генератор +# + + +# + +def sequence(count_limit: int) -> list[int]: + """Return list of integers from 1 to n inclusive.""" + res: list[int] = [x for x in range(1, count_limit + 1)] + return res + + +sequence(5) + + +# + +def sequence_gen(count_limit: int): # type: ignore[no-untyped-def] + """Yield integers from 1 to n inclusive.""" + yield from range(1, count_limit + 1) + + +sequence_gen(5) + +# + +seq_5 = sequence_gen(5) + +print(next(seq_5)) +print(next(seq_5)) +# - + +for number in seq_5: + print(number) + +# ## Generator comprehension +# + +gen_expr = (x for x in range(1, 5 + 1)) +print(gen_expr) + +gen_expr_list: list[int] = list(x for x in range(1, 5 + 1)) +print(gen_expr_list) + +sum_gen: int = sum(x for x in range(1, 5 + 1)) +print(sum_gen) + +contains_value: bool = 5 in (x for x in range(1, 5 + 1)) +print(contains_value) + +# ## Модуль itertools +# + +# ## Функция count() +# + +# + +natural_numbers = count(start=1, step=0.5) + +for num in natural_numbers: + print(num) + if num == 2: + break +# - + +list_let: list[str] = ["a", "b", "c", "d"] +for enumerated_letter in zip(count(start=1), list_let): + print(enumerated_letter) + + +# + +def quadratic(value: int | float) -> float: + """Return quadratic expression result.""" + return value**2 + value - 2 + + +f_x = map(quadratic, count()) +print(next(f_x), next(f_x), next(f_x)) +# - + +for mapped_value in f_x: + print(mapped_value) + if mapped_value > 10: + break + +# ??????? ???????? ? ???????????? ?? ???????. +# + +# ???? ?? ?????? ? ?????????????? cycle (?????? ????). +# + +# + +cycle_numbers: list[int] = [1, 2, 3] +cycle_iterator_numbers = cycle(cycle_numbers) + +cycle_nums_limit: int = 5 +for number in cycle_iterator_numbers: + print(number) + cycle_nums_limit -= 1 + if cycle_nums_limit == 0: + break + +# + +string_value: str = "Python" +cycle_iterator_chars = cycle(string_value) + +cycle_chars_limit: int = 10 +for char in cycle_iterator_chars: + print(char) + cycle_chars_limit -= 1 + if cycle_chars_limit == 0: + break +# - + +chain_iterator = chain(["abc", "d", "e", "f"], "abc", [1, 2, 3]) +print(chain_iterator) + +# ????????? ???????? ????????? chain ???????. +# + +flatten_letters: list[str] = list(chain.from_iterable(["abc", "def"])) +print(flatten_letters) + +sum_numbers: int = sum(chain.from_iterable([[1, 2, 3], [4, 5, 6], [7, 8, 9]])) +print(sum_numbers) diff --git a/python_issue/makarov/chapter_16_decorators.py b/python_issue/makarov/chapter_16_decorators.py new file mode 100644 index 00000000..6f7df151 --- /dev/null +++ b/python_issue/makarov/chapter_16_decorators.py @@ -0,0 +1,679 @@ +"""Decorators.""" + +# + +from __future__ import annotations + +import functools +import time +from collections.abc import Callable +from typing import ParamSpec, Protocol, TypeVar + +Params = ParamSpec("Params") +Arguments = TypeVar("Arguments") +T = TypeVar("T") + + +# - + +# ## Декораторы +# ### Объекты первого класса +# #### Присвоение функции переменной + + +def say_hello_basic(name: str) -> None: + """Print greeting with provided name.""" + print(f"Hello, {name}!") + + +say_hello_function = say_hello_basic +say_hello_function("Alexey") + + +# ## Передача функции в качестве аргумента другой функции +# + + +# + +def simple_calculator( + operation: Callable[[float, float], float], + first_number: float, + second_number: float, +) -> float: + """Calculate result using provided binary operation.""" + return operation(first_number, second_number) + + +def add(first_number: float, second_number: float) -> float: + """Return sum of numbers.""" + return first_number + second_number + + +def subtract(first_number: float, second_number: float) -> float: + """Return difference of numbers.""" + return first_number - second_number + + +def multiply(first_number: float, second_number: float) -> float: + """Return product of numbers.""" + return first_number * second_number + + +def divide(first_number: float, second_number: float) -> float: + """Return division result of numbers.""" + return first_number / second_number + + +# - + +print(simple_calculator(divide, 33, 3)) + + +# ## Внутренние функции +# ### Вызов внутренней функции +# +# + + +# + +def outer() -> None: + """Print messages from outer and inner functions.""" + print("out function call") + + def inner() -> None: + """Print inner function call message.""" + print("inner function call") + + inner() + + +outer() + + +# - + +# ## Возвращение функции из функции и замыкание +# + + +# + +class MultiplierCallable(Protocol): + """Protocol defining callable multiplier function.""" + + def __call__(self, number: int) -> int: + """Callable signature defining multiplier behavior.""" + raise NotImplementedError + + +def create_multiplier(factor: int) -> MultiplierCallable: + """Create multiplier closure for demonstration purposes.""" + + def multiplier(number: int) -> int: + """Multiply number by predefined factor.""" + return number * factor + + return multiplier + + +double_multiplier: MultiplierCallable = create_multiplier(factor=2) +triple_multiplier: MultiplierCallable = create_multiplier(factor=3) +# - + +print(double_multiplier) + +print((double_multiplier(number=2), triple_multiplier(number=2))) + + +def create_multiplier_2(factor: int) -> Callable[[int], int]: + """Create multiplier using a nested function for demonstration purposes.""" + + def multiplier(number: int) -> int: + """Multiply number by predefined factor.""" + return factor * number + + return multiplier + + +triple_multiplier_v2 = create_multiplier_2(factor=3) +print(triple_multiplier_v2(2)) + + +# ## Знакомство с декораторами +# ### Простой декоратор +# + + +# + +def simple_decorator( + func: Callable[Params, Arguments], +) -> Callable[Params, Arguments]: + """Decorate function by adding text before and after execution.""" + + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments: + """Wrap function call and print surrounding text.""" + print("Text before func().") + result = func(*args, **kwargs) + print("Text after func().") + return result + + return wrapper + + +def say_hello_decorated() -> None: + """Print simple greeting.""" + print("Hello!") + + +say_hello_decorated = simple_decorator(say_hello_decorated) +# - + +say_hello_decorated() + + +# ## Конструкция @decorator +# + + +@simple_decorator +def say_hi() -> None: + """Print repeated greeting.""" + print("Hello, again...") + + +say_hi() + + +# ## Функции с аргументами +# + + +# + +@simple_decorator +def say_hello_with_name_simple(name: str) -> None: + """Print greeting with provided name.""" + print(f"Hello, {name}!") + + +say_hello_with_name_simple("Alex") + + +# - + + +def decorator_with_name_argument(func: Callable[[str], None]) -> Callable[[str], None]: + """Decorate function expecting a single name argument.""" + + def wrapper(name: str) -> None: + """Wrap function call and print surrounding text.""" + print("Text before func().") + func(name) + print("Text after func().") + + return wrapper + + +@decorator_with_name_argument +def say_hello_with_name_logged(name: str) -> None: + """Print greeting with provided name.""" + print(f"Hello, {name}!") + + +say_hello_with_name_logged("Alex") + + +# + +def decorator_with_arguments( + func: Callable[Params, Arguments], +) -> Callable[Params, Arguments]: + """Decorate function printing text before and after call.""" + + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments: + """Wrap function call and print surrounding text.""" + print("Text before func().") + result = func(*args, **kwargs) + print("Text after func().") + return result + + return wrapper + + +@decorator_with_arguments +def say_hello_with_argument(name: str) -> None: + """Print greeting with provided name.""" + print(f"Hello, {name}!") + + +# - + +say_hello_with_argument("Alex") + + +# ## Возвращение значения декорируемой функции +# + + +def another_decorator(func: Callable[[str], str]) -> Callable[[str], None]: + """Decorate function by printing text before call.""" + + def wrapper(name: str) -> None: + """Wrap function call and print inner text.""" + print("Inner function text") + func(name) + + return wrapper + + +@another_decorator +def return_name_silent(name: str) -> str: + """Return provided name.""" + return name + + +returned_value: str | None = return_name_silent("Alex") + +print(returned_value) + + +def another_decorator_verbose( + func: Callable[[str], Arguments], +) -> Callable[[str], Arguments]: + """Decorate function by printing text and returning result.""" + + def wrapper(name: str) -> Arguments: + """Wrap function call, print text, and return result.""" + print("����� ���������� �������.") + return func(name) + + return wrapper + + +@another_decorator_verbose +def return_name_verbose(name: str) -> str: + """Return provided name.""" + return name + + +returned_value_verbose: str = return_name_verbose("Alex") + +print(returned_value_verbose) + + +# ## Декоратор @functools.wraps +# + + +def square_basic(value: int) -> int: + """Return square of the given number.""" + return value * value + + +print((square_basic.__name__, square_basic.__doc__)) + + +def repeat_twice( + func: Callable[Params, Arguments], +) -> Callable[Params, Arguments]: + """Decorate function to run twice.""" + + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments: + result = func(*args, **kwargs) + return result + + return wrapper + + +@repeat_twice +def square_repeated(value: int) -> int: + """Return square of the given number.""" + return value * value + + +square_repeated(3) + +print((square_repeated.__name__, square_repeated.__doc__)) + + +def repeat_twice_with_wraps( + func: Callable[Params, Arguments], +) -> Callable[Params, Arguments]: + """Decorate function by repeating execution twice with wraps.""" + + @functools.wraps(func) + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments: + """Wrap function call, execute twice, and return result.""" + func(*args, **kwargs) + return func(*args, **kwargs) + + return wrapper + + +@repeat_twice_with_wraps +def square_wrapped(value: int) -> None: + """Return square of the given number.""" + print(value * value) + + +print((square_wrapped.__name__, square_wrapped.__doc__)) + +print(getattr(square_wrapped, "__wrapped__")) + + +def repeat_twice_updated( + func: Callable[Params, Arguments], +) -> Callable[Params, Arguments]: + """Decorate function by repeating execution twice and preserving + metadata.""" + + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments: + """Wrap function call, execute twice, and return result.""" + func(*args, **kwargs) + return func(*args, **kwargs) + + functools.update_wrapper(wrapper, func) + return wrapper + + +@repeat_twice_updated +def power_repeated(base_value: float, exponent: float) -> int | float: + """Return base raised to exponent.""" + result: int | float = base_value**exponent + return result + + +power_repeated(2, 3) + +print(power_repeated.__doc__) + + +# ## Примеры декораторов +# ### Создание логов +# + + +def logging(func: Callable[Params, Arguments]) -> Callable[Params, Arguments]: + """Decorate function with logging.""" + + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments: + """Wrap function call and log arguments and result.""" + print(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}") + result = func(*args, **kwargs) + print(f"{func.__name__} returned: {result}") + return result + + return wrapper + + +# + +@logging +def power_logged(base_value: int, exponent: int) -> int | float: + """Return power of a number.""" + result: int | float = base_value**exponent + return result + + +power_logged(5, 3) + + +# - + +# ## Время исполнения функции +# + + +def timer(func: Callable[Params, Arguments]) -> Callable[Params, Arguments]: + """Wrap function to measure execution time.""" + + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> Arguments: + """Wrap function call, measure duration, and return result.""" + start_time = time.time() + result = func(*args, **kwargs) + end_time = time.time() + print(f"{func.__name__} executed in {end_time - start_time:.4f} seconds") + return result + + return wrapper + + +# + +@timer +def delayed_function_timed(delay_time: float) -> str: + """Delay execution for specified time.""" + time.sleep(delay_time) + return "execution completed" + + +delayed_function_timed(2) + + +# - + +# ## Типы методов +# ### Методы экземпляра +# + + +class CatClassBasic: + """Represent basic cat data.""" + + def __init__(self, color: str) -> None: + """Initialize instance attributes.""" + self.color: str = color + self.type_: str = "cat" + + def info(self) -> None: + """Print cat information.""" + print(self.color, self.type_, sep=", ") + + +cat_basic = CatClassBasic(color="black") +cat_basic.info() + + +# ## Методы класса +# + + +class CatClassWithSpecies: + """Represent cat data with species information.""" + + species: str = "Cat" + + def __init__(self, color: str) -> None: + """Initialize instance attributes.""" + self.color: str = color + + def info(self) -> None: + """Print cat color.""" + print(self.color) + + @classmethod + def get_species(cls) -> None: + """Print species name.""" + print(cls.species) + + +print(CatClassWithSpecies.species) + +CatClassWithSpecies.get_species() + + +# ## Статические методы +# + + +class CatClassWithConverter: + """Represent cat data with conversion utility.""" + + species: str = "Cat" + + def __init__(self, color: str) -> None: + """Initialize instance attributes.""" + self.color: str = color + + def info(self) -> None: + """Print cat color.""" + print(self.color) + + @classmethod + def get_species(cls) -> None: + """Print species name.""" + print(cls.species) + + @staticmethod + def convert_to_pounds(weight_kg: float) -> None: + """Convert kilograms to pounds and print result.""" + print(f"{weight_kg} kg is approximately {weight_kg * 2.205} pounds") + + +CatClassWithConverter.convert_to_pounds(4) + +cat_with_converter = CatClassWithConverter("gray") +cat_with_converter.convert_to_pounds(12) + + +# ## Декорирование класса +# ### Декорирование методов +# +# + + +class CatClassDecorated: + """Represent cat data with decorated methods.""" + + color: str + type_: str + + @logging + def __init__(self, color: str) -> None: + """Initialize instance attributes.""" + self.color = color + self.type_ = "cat" + + @timer + def info(self) -> None: + """Print cat information with delay.""" + time.sleep(2) + print(self.color, self.type_, sep=", ") + + +cat_decorated = CatClassDecorated("black") + +cat_decorated.info() + + +# ## Декорирование всего класса +# + + +@timer +class CatClassTimed: + """Represent cat data with timed methods.""" + + weight: float | int | None = None + color: str + type_: str + + def __init__(self, color: str) -> None: + """Initialize instance attributes.""" + self.color = color + self.type_ = "cat" + + def info(self) -> None: + """Print cat information with delay.""" + time.sleep(2) + print(self.color, self.type_, sep=", ") + + +cat_timed = CatClassTimed("grey") + +cat_timed.info() + +setattr(cat_timed, "weight", 5) + +print((cat_timed.weight, getattr(cat_timed, "weight"))) + + +def add_attribute( + attribute_name: str, attribute_value: str +) -> Callable[[type[T]], type[T]]: + """Decorate class by adding specified attribute.""" + + def wrapper(cls: type[T]) -> type[T]: + """Attach attribute to class and return the class.""" + setattr(cls, attribute_name, attribute_value) + return cls + + return wrapper + + +@add_attribute("species", "cat") +class CatClassAttributed: + """Represent cat data with added attributes.""" + + species: str = "cat" + color: str + type_: str + + def __init__(self, color: str) -> None: + """Initialize instance attributes.""" + self.color = color + self.type_ = "cat" + + +print(CatClassAttributed.species) + + +# ## Несколько декораторов +# + + +@logging +@timer +def delayed_function_logged_timed(delay_time: float) -> str: + """Delay execution with logging and timing.""" + time.sleep(delay_time) + return "execution completed" + + +delayed_function_logged_timed(2) + + +def delayed_function_plain(delay_time: float) -> str: + """Delay execution for specified time.""" + time.sleep(delay_time) + return "execution completed" + + +delayed_function_wrapped = logging(timer(delayed_function_plain)) +delayed_function_wrapped(2) + + +# ## Декораторы с аргументами +# + + +def repeat( + repeat_count: int, +) -> Callable[[Callable[Params, None]], Callable[Params, None]]: + """Create decorator repeating function calls.""" + + def inner_decorator(func: Callable[Params, None]) -> Callable[Params, None]: + """Wrap function to repeat calls the specified number of times.""" + + @functools.wraps(func) + def wrapper(*args: Params.args, **kwargs: Params.kwargs) -> None: + """Wrap function call and repeat execution.""" + for _ in range(repeat_count): + func(*args, **kwargs) + + return wrapper + + return inner_decorator + + +@repeat(repeat_count=3) +def say_hello_repeated(name: str) -> None: + """Print greeting with provided name.""" + print(f"Hello, {name}!") + + +say_hello_repeated("Alex") diff --git a/python_issue/makarov/chapter_1_pandas.py b/python_issue/makarov/chapter_1_pandas.py new file mode 100644 index 00000000..67462a89 --- /dev/null +++ b/python_issue/makarov/chapter_1_pandas.py @@ -0,0 +1,385 @@ +"""Pandas library.""" + +# ## Библиотека Pandas +# + +# + +import sqlite3 as sql + +import numpy as np +import pandas as pd + +# - + +# ## Объекты DataFrame и Series +# ### Создание датафрейма +# #### Способ 1. Создание датафрейма из файла + +csv_zip = pd.read_csv("/Users/dayal/Downloads/train.csv") +csv_zip.head(3) + +excel_data = pd.read_excel("/Users/dayal/Downloads/iris.xlsx", sheet_name=0) +excel_data.head(3) + +html_data = pd.read_html( + "https://en.wikipedia.org/wiki/World_population", + storage_options={"User-Agent": "Mozilla/5.0"}, +) +html_data[0] + +len(excel_data) + +html_data[0] + +# #### Способ 2. Подключение к базе данных SQL +# + +# + +conn = sql.connect("/Users/dayal/Downloads/chinook.db") + +sql_data = pd.read_sql("SELECT * FROM tracks;", conn) + +sql_data.head(3) +# - + +# #### Способ 3. Создание датафрейма из словаря +# + +country = np.array( + [ + "China", + "Vietnam", + "United Kingdom", + "Russia", + "Argentina", + "Bolivia", + "South Africa", + ] +) +capital: list[str] = [ + "Beijing", + "Hanoi", + "London", + "Moscow", + "Buenos Aires", + "Sucre", + "Pretoria", +] +population: list[int] = [1400, 97, 67, 144, 45, 12, 59] +area: list[float] = [9.6, 0.3, 0.2, 17.1, 2.8, 1.1, 1.2] +sea: list[int] = [1] * 5 + [0, 1] + +# + +countries_dict: dict[str, list[str] | list[int] | list[float]] = {} + +countries_dict["country"] = list(country) +countries_dict["capital"] = capital +countries_dict["population"] = population +countries_dict["area"] = area +countries_dict["sea"] = sea +# - + +countries = pd.DataFrame(countries_dict) +countries + +# #### Способ 4. Создание датафрейма из 2D массива Numpy +# + +# + +arr = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]]) + +pd.DataFrame(arr) +# - + +# ## Структура и свойства датафрейма +# + +countries.columns + +countries.index + +countries.values + +countries.axes[0] + +countries.axes[1] + +countries.ndim, countries.shape, countries.size + +countries.dtypes + +countries.memory_usage() + +# ## Индекс +# ### Присвоение индекса +# + +custom_index: list[str] = ["CN", "VN", "GB", "RU", "AR", "BO", "ZA"] + +countries = pd.DataFrame(countries_dict, index=custom_index) +countries + +countries.reset_index(inplace=True) +countries + +countries.set_index("index", inplace=True) +countries + +countries.reset_index(drop=True, inplace=True) +countries + +countries.index = pd.Index(custom_index) +countries + +# ## Многоуровневый индекс +# + +# + +rows: list[tuple[str, str]] = [ + ("Asia", "CN"), + ("Asia", "VN"), + ("Europe", "GB"), + ("Europe", "RU"), + ("S. America", "AR"), + ("S. America", "BO"), + ("Africa", "ZA"), +] + +cols: list[tuple[str, str]] = [ + ("names", "country"), + ("names", "capital"), + ("data", "population"), + ("data", "area"), + ("data", "sea"), +] + +custom_multindex = pd.MultiIndex.from_tuples(rows, names=["region", "code"]) +custom_multicols = pd.MultiIndex.from_tuples(cols) + +countries.index = pd.Index(custom_multindex) +countries.columns = custom_multicols + +countries + +# + +custom_cols = ["country", "capital", "population", "area", "sea"] + +countries.index = pd.Index(custom_index) +custom_cols_int = custom_cols +custom_cols_list_str: list[str] = [str(col) for col in custom_cols_int] + +countries +# - + +# ## Преобразование в другие форматы +# + +print(countries.to_dict()) + +countries.to_numpy() + +countries.to_csv("countries.csv", index=False) + +countries.country.tolist() + +# ## Создание Series +# ### Создание Series из списка +# + +# + +country_list: list[str] = [ + "China", + "South Africa", + "United Kingdom", + "Russia", + "Argentina", + "Vietnam", + "Australia", +] + +country_series = pd.Series(country_list, dtype=str) +country_series +# - + +country_series.iloc[0] + +# ## Создание Series из словаря +# + +country_dict: dict[str, str] = { + "CN": "China", + "ZA": "South Africa", + "GB": "United Kingdom", + "RU": "Russia", + "AR": "Argentina", + "VN": "Vietnam", + "AU": "Australia", +} + +country_series_2: pd.Series[float] = pd.Series(country_dict) +country_series_2 + +country_series_2.loc["RU"] + +# ## Доступ к строкам и столбцам +# ### Циклы в датафрейме +# + +for column in countries: + print(column) + +for index, row in countries.iterrows(): + print(index) + print(row) + print("...") + print(type(row)) + break + +for _, row in countries.iterrows(): + print(row["capital"] + " is the capital if " + row["country"]) + break + +# ## Доступ к столбцам +# + +countries["capital"] + +countries.capital + +type(countries.capital) + +countries[["capital"]] + +countries[["capital", "area"]] + +countries.filter(items=["capital", "population"]) + +# ## Доступ к строкам +# + +countries[1:5] + +# ## Методы .loc[] и .iloc[] +# ### Метод .loc[] +# + +countries.loc[["CN", "RU", "VN"], ["capital", "population", "area"]] + +countries.loc[:, ["capital", "population", "area"]] + +countries.loc[:, [False, False, False, False, True]] + +# ## Метод .get_loc() +# + +countries.index.get_loc("RU") + +countries.columns.get_loc("country") + +# ## Метод .iloc[] +# + +countries.iloc[[0, 3, 5], [0, 1, 2]] + +countries.iloc[:3, -2:] + +countries[["population", "area"]].iloc[[0, 3]] + +# ## Доступ по многоуровневому индексу +# + +# + +countries.index = pd.Index(custom_multindex) +countries.columns = custom_multicols + +countries +# - + +print(countries.loc["Asia", "CN"]) + +print( + countries.loc[ + ("Asia", "CN"), [("data", "population"), ("data", "area"), ("data", "sea")] + ] +) + +countries.loc[("Asia", ["CN", "VN"]), :] + +countries.loc["Asia", :] + +print(countries.loc[:, [("names", "country"), ("data", "population")]]) + +print(countries.iloc[3, [2, 3, 4]]) + +print(countries.xs("Europe", level="region", axis=0)) + +print(countries.xs(("names", "country"), axis=1)) + +print(countries.xs("Europe", axis=0).loc[:, ("names", slice(None))]) + +# + +countries.index = pd.Index(custom_index) + +countries +# - + +# ## Метод .at[] +# + +countries.at["CN", "capital"] + +# ## Фильтры +# ### Логическая маска +# + +countries.population > 1000 + +countries[countries.population > 1000] + +countries[(countries.population > 50) & (countries.area < 2)] + +# + +population_mask = countries.population > 70 +area_mask: pd.Series[bool] = countries.population < 50 + +mask: pd.Series[bool] = population_mask | area_mask + +countries[mask] +# - + +# ## Метод .query() +# + +countries.query("population > 50 and area < 2") + +countries.query('country == "United Kingdom"') + +# ## Другие способы фильтрации +# + +# + +keyword_list = ["Beijing", "Moscow", "Hanoi"] + +print(countries[countries.capital.isin(keyword_list)]) +# - + +print(countries[~countries.country.str.startswith("A")]) + +countries.nlargest(3, "population") + +countries.area.argmax() + +print(countries.iloc[[countries.area.argmax()]]) + +countries.loc[countries.population > 90, :] + +countries.filter(like="ZA", axis=0) + +# ## Сортировка +# + +countries.sort_values(by="population", inplace=False, ascending=True) + +countries.sort_values(by=["area", "population"], inplace=False, ascending=False) + +countries.sort_index() diff --git a/python_issue/makarov/chapter_1_variables_in_python.py b/python_issue/makarov/chapter_1_variables_in_python.py new file mode 100644 index 00000000..68f189fd --- /dev/null +++ b/python_issue/makarov/chapter_1_variables_in_python.py @@ -0,0 +1,108 @@ +"""Variables in Python.""" + +# ## Переменные в Питоне + +# ### Создание (объявление) переменных +# + +x_var: int = 15 +print(x_var) + +y_var: str = "Я программирую на Питоне" +print(y_var) + +# + +a_var: str = "Python" +b_var: str = "C++" +c_var: str = "PHP" + +print(a_var, b_var, c_var) +# - + +x_var_1 = y_var_1 = z_var_1 = "same value" +print(x_var_1, y_var_1, z_var_1) + +my_list: list[str] = ["tomatoes", "cucumbers", "potatoes"] +a_var_1, b_var_1, c_var_1 = my_list +print(a_var_1, b_var_1, c_var_1) + +# ### Автоматическое определение типа данных +# + +# + +x_var_2: int = 256 +y_var_2: float = 0.25 +z_var_2: str = "just text" + +# Как узнать тип переменной в Питоне +print(type(x_var_2), type(y_var_2), type(z_var_2)) +# - + +# ### Присвоение и преобразование типа данных + +# #### Присвоение типа данных +# + +# + +x_var_3: str = str(25) +y_var_3: int = int(25) +z_var_3: float = float(25) + +print(type(x_var_3), type(y_var_3), type(z_var_3)) +# - + +# #### Изменение типа данных + +# Изменение типа данных +print(type(int("25"))) +print(type(float("2.5"))) +print(int("36.6")) +print(type(int("36.6"))) +print(type(str(25))) +print(str) + +# ### Именование переменных + +# #### Допустимые имена переменных + +# variable: str = "just variable" +# _variable: str = "just variable" +variable_: str = "just variable" +my_variable: str = "just variable" +My_variable_123: str = "just variable" + +# #### Имя переменной состоит из нескольких слов +# + +# camelCaseVariable: str = "camel case variable" +# PascalCaseVariable: str = "pascal case variable" +snake_case_variable: str = "snake case variable" + +# #### Недопустимые названия переменной + +# + +# my-variable = 'WRONG' +# 123variable = 'WRONG' +# my variable = 'WRONG' +# - + +# ### Как конвертировать список чисел в строки +# + +# + +list_: list[int] = [1, 2, 3] +str(list_) # -> Wrong answer + +# 1 +list_str: list[str] = [] + +for i in list_: + list_str.append(str(i)) + +print(list_str) + +# 2 +print([str(x) for x in list_]) + +# 3 +print(list(map(str, list_))) diff --git a/python_issue/makarov/chapter_2_data_types_in_python.py b/python_issue/makarov/chapter_2_data_types_in_python.py new file mode 100644 index 00000000..642e1e55 --- /dev/null +++ b/python_issue/makarov/chapter_2_data_types_in_python.py @@ -0,0 +1,148 @@ +"""Data types in Python.""" + +# ## Типы данных в Питоне +# + +# ### Работа с числами +# + +# + +a_var: int = 25 +b_var: float = 2.5 +c_var: complex = 3 + 25j + +print(a_var, b_var, c_var) +# - + +# ##### Экспоненциальная запись, 2 умножить на 10 в степени 3 +# + +d_var: float = 2e3 +print(d_var) +print(type(d_var)) + +# #### Арифметические операции + +# Ниже закомментил потому что линтеры сильно ругаются на операции итак понятные +print(2 + 2, 4 - 2, 2 * 2, 4 / 2, 2**3) + +print(7 // 2) +print(7 % 2) + +# #### Операторы сравнения +# + +# + +# print(2 == 4) +# print(2 != 4) +# - + +# #### Логические операции + +# + +# print(4 > 2 and 2 != 3) +# print(4 < 2 or 2 == 2) +# print(not (4 == 4)) +# - + +# #### Перевод чисел в другую систему счисления +# + +# + +d_var_1: int = 25 + +bin_d: str = bin(d_var_1) +print(bin_d) + +print(int(bin_d, 2)) + +# + +d_var_2: int = 25 + +oct_d: str = oct(d_var_2) +print(oct_d) + +print(int(oct_d, 8)) + +# + +d_var_3: int = 25 + +hex_d: str = hex(d_var_3) +print(hex_d) + +print(int(hex_d, 16)) +# - + +# ### Строковые данные + +# + +string_1: str = "string" +string_2: str = "also string" + +multi_string: str = """Мы все учились понемногу +Чему-нибудь и как-нибудь, +Так воспитаньем, слава богу, +У нас немудрено блеснуть.""" +# - + +# #### Длина строки + +len(multi_string) + +# #### Объединение строк +# + +a_var_3: str = "programming" +b_var_3: str = "on" +c_var_3: str = "python" +a_var_3 + " " + b_var_3 + " " + c_var_3 + +# #### Индекс символа в строке и Срезы строк + +# + +print(multi_string[0]) +print(multi_string[-1]) + +print(multi_string[3:6]) +print(multi_string[:2]) +print(multi_string[3:]) +# - + +# #### Циклы в строках + +for i in "Python": + print(i) + +# #### Методы .strip() и .split() + +# + +print("********15 489 302**************".strip("*")) + +print(" 15 849 302 ".strip()) +# - + +print(multi_string.split()) + +len(multi_string.split()) + +# #### Замена символа в строке + +# + +data_var_3: str = "20,25" + +data_var_3_clean: str = data_var_3.replace(",", ".") + +data_var_3_float: float = float(data_var_3_clean) +print(data_var_3_float) +print(type(data_var_3_float)) +# - + +# ### Логические значения + +var_var_3: bool = False +type(var_var_3) + +if var_var_3 is True: + print("var is true") +else: + print("var is false") diff --git a/python_issue/makarov/chapter_3_conditions_and_cycles.py b/python_issue/makarov/chapter_3_conditions_and_cycles.py new file mode 100644 index 00000000..3a570724 --- /dev/null +++ b/python_issue/makarov/chapter_3_conditions_and_cycles.py @@ -0,0 +1,287 @@ +"""Conditions and cycles.""" + +# ## Условия и циклы. Продолжение + +# #### Множественные условия (multi-way decisions) +# + +# + +import numpy as np + +x_var: int = 42 + +if x_var < 10: + print("Small") +elif x_var < 100: + print("Medium") +else: + print("Large") + +# + +x_var_1: str = input() + +x_int = int(x_var_1) + +if x_int < 10: + print("Small") +elif x_int < 100: + print("Medium") +else: + print("Large") +# - + +# #### Вложенные условия (nested decisions) +# + +# + +y_var: str = input("Введите число: ") + +if len(y_var) != 0: + y_int = int(y_var) + if y_int < 10: + print("Small") + elif y_int < 100: + print("Medium") + else: + print("Large") +else: + print("Ввод пустой") +# - + +# #### Несколько условий в одном выражении с операторами and или or + +# + +z_var: int = 42 + +if 10 < z_var < 100: + print("Medium") +else: + print("Small or Large") + +# + +z_var_1: int = 2 + +if z_var_1 < 10 or z_var_1 > 100: + print("Small or Large") +else: + print("Medium") +# - + +# #### Проверка вхождения элемента в объект с in / not in +# + +# + +sentence: str = "To be, or not to be, that is the question" +word: str = "question" + +if word in sentence: + print("Слово найдено") +# - + +# ## Циклы в Питоне + +# ### Цикл for Основные операции +# + +# + +number_list: list[int] = [2, 3, 4, 6, 7] +number: int = 5 + +if number not in number_list: + print("Такого числа в списке нет") + +# + +d_var: dict[str, int] = {"apple": 3, "tomato": 6, "carrot": 2} + +if "apple" in d_var: + print("Нашлись") + +if 6 in d_var.values(): + print("Есть") + +# + +number_list_1: list[int] = [1, 2, 3] + +for number in number_list_1: + print(number) + +# + +d_var_1: dict[str, list[int | str]] = { + "apple": [3, "kg"], + "tomato": [6, "pcs"], + "carrot": [2, "kg"], +} + +for k_var_1, v_var_1 in d_var_1.items(): + print(k_var_1, v_var_1) + +for v_var_2 in d_var_1.values(): + print(v_var_2[0]) + +# + +number_array = np.array([1, 2, 3]) + +for number in number_array: + print(number) + +# + +clients_1: dict[int, dict[str, int | str]] = { + 1: {"name": "Анна", "age": 24, "sex": "male", "revenue": 12000}, + 2: {"name": "Илья", "age": 18, "sex": "female", "revenue": 8000}, +} + +for id_var_1, info in clients_1.items(): + + print("client ID:" + str(id_var_1)) + + for k_var, v_var in info.items(): + print(k_var + ": " + str(v_var)) + + print() +# - + +# #### Функция range() +# + +for i in range(5): + print(i) + +for i in range(1, 6): + print(i) + +for i in range(0, 6, 2): + print(i) + +# + +months: list[str] = [ + "Январь", + "Февраль", + "Март", + "Апрель", + "Май", + "Июнь", + "Июль", + "Август", + "Сентябрь", + "Октябрь", + "Ноябрь", + "Декабрь", +] +sales: list[int] = [47, 75, 79, 94, 123, 209, 233, 214, 197, 130, 87, 55] + +for i, month in enumerate(months): + print(month, sales[i]) +# - + +# ### Последовательность в обратном порядке +# + +# + +my_list: list[int] = [0, 1, 2, 3, 4] + +for i in reversed(my_list): + print(i) +# - + +for i in reversed(range(5)): + print(i) + +for i in range(4, 0, -1): + print(i) + +# + +r_var: range = range(5) + +sorted_values: list[int] = sorted(r_var, reverse=True) + +for i in sorted_values: + print(i) +# - + +# #### Функция enumerate() +# + +# + +days: list[str] = [ + "Понедельник", + "Вторник", + "Среда", + "Четверг", + "Пятница", + "Суббота", + "Воскресенье", +] + +for i, day in enumerate(days): + print(i, day) + +for i, day in enumerate(days, 1): + print(i, day) +# - + +# ### Цикл while +# + +# + +i_var: int = 0 + +while i_var < 3: + print("Текущее значение счетчика: " + str(i)) + i_var = i_var + 1 + print("Новое значение счетчика :" + str(i)) + print() + +# + +i_var_1: int = 0 + +while i_var_1 < 3: + print(i_var_1) + i_var_1 += 1 +# - + +# ### Break, continue +# + +# + +clients_1_var: dict[int, dict[str, int | str]] = { + 1: {"name": "Анна", "age": 24, "sex": "male", "revenue": 12000}, + 2: {"name": "Илья", "age": 18, "sex": "female", "revenue": 8000}, +} + +for id_var, info in clients_1_var.items(): + print(id_var, info) + break + +# + +x_var_2: int = 6 + +while x_var_2 != 0: + print(x_var_2) + x_var_2 -= 1 + if x_var_2 == 3: + break +# - + +for i in range(1, 11): + if i % 2 != 0: + continue + print(i) + +# ### Форматирование строк через f-строки и метод .format() +# + +# + +days_1: list[str] = [ + "Понедельник", + "Вторник", + "Среда", + "Четверг", + "Пятница", + "Суббота", + "Воскресенье", +] + +monday: str = days_1[0] +print(monday) + +print(f"{monday} - день тяжелый") diff --git a/python_issue/makarov/chapter_4_files.py b/python_issue/makarov/chapter_4_files.py new file mode 100644 index 00000000..d2d176c4 --- /dev/null +++ b/python_issue/makarov/chapter_4_files.py @@ -0,0 +1,86 @@ +"""Files.""" + +# ### Подгрузка файлов +# + +# #### Способ 2. Через модуль files библиотеки google.colab + +# + +# from google.colab import files - only in google.colab +import os + +import pandas as pd + +files: int = 0 +# uploaded: int = files.upload() +# - + +# #### Модуль os и метод .walk() +# + +for dirpath, _, filenames in os.walk("/content/"): + for filename in filenames: + print(os.path.join(dirpath, filename)) + +# #### Команда !ls +# + +# !ls + +# !ls /content/sample_data/ + +# ### Чтение из переменной uploaded +# + +# + +# type(uploaded["test.csv"]) +# - + +# #### Пример работы с объектом bytes +# + +# + +# uploaded_str: str = uploaded["test.csv"].decode() +# print(type(uploaded_str)) + +# + +# print(uploaded_str[:35]) + +# + +# uploaded_list: str = uploaded_str.split("\r\n") +# type(uploaded_list) + +# + +# for i, line in enumerate(uploaded_list): +# print(line) +# if i == 3: +# break +# - + +# #### Использование функции open() и конструкции with open() +# + +with open("/content/train.csv", encoding="utf-8") as f1: + print(f1.read(142)) + + +with open("/content/train.csv", encoding="utf-8") as f2: + for i, line in enumerate(f2): + print(line.strip()) + if i == 3: + break + + +with open("/content/train.csv", encoding="utf-8") as f3: + for i, line in enumerate(f3): + print(line.strip()) + if i == 3: + break + +# #### Чтение через библиотеку Pandas +# + +train: pd.DataFrame = pd.read_csv("/content/train.csv") +train.head(3) +test: pd.DataFrame = pd.read_csv("/content/test.csv") +test.head(3) diff --git a/python_issue/makarov/chapter_5_date_and_time_in_python.py b/python_issue/makarov/chapter_5_date_and_time_in_python.py new file mode 100644 index 00000000..6821c292 --- /dev/null +++ b/python_issue/makarov/chapter_5_date_and_time_in_python.py @@ -0,0 +1,213 @@ +"""Date and time in Python.""" + +# ## Дата и время в Питоне + +# ### Модуль datetime + +# #### Импорт модуля и класса datetime +# + +# + +import datetime + +import pandas as pd +import pytz + +print(datetime.datetime.now()) +# - + +print(datetime.datetime.now()) + +# #### Объект datetime и функция now() +# + +cur_dt: datetime.datetime = datetime.datetime.now() +print(cur_dt) + +print( + cur_dt.year, + cur_dt.month, + cur_dt.day, + cur_dt.hour, + cur_dt.minute, + cur_dt.second, + cur_dt.microsecond, +) + +print(cur_dt.weekday, cur_dt.isoweekday) + +print(cur_dt.tzinfo) + +dt_moscow: datetime.datetime = datetime.datetime.now(pytz.timezone("Europe/Moscow")) +print(dt_moscow) +print(dt_moscow.tzinfo) + +# #### Timestamp +# + +timestamp: float = datetime.datetime.now().timestamp() +print(timestamp) +print(datetime.datetime.fromtimestamp(timestamp)) + +# #### Создание объекта datetime вручную +# + +hb: datetime.datetime = datetime.datetime(1991, 2, 20) +print(hb) +print(hb.year) +print(datetime.datetime.timestamp(hb)) + +# ### Преобразование строки в объект datetime и обратно + +# ### Строка -> datetime через .strptime() +# + +# + +str_to_dt: str = "2007-12-02 12:30:45" +type(str_to_dt) + +res_dt: datetime.datetime = datetime.datetime.strptime(str_to_dt, "%Y-%m-%d %H:%M:%S") +print(res_dt) +print(type(res_dt)) +# - + +# ### Datetime -> строка через .strftime() +# + +# + +dt_to_str: datetime.datetime = datetime.datetime(2002, 11, 19) +print(type(dt_to_str)) + +res_str: str = datetime.datetime.strftime(dt_to_str, "%A, %B %d, %Y") + +print(res_str) +print(type(res_str)) +# - + +dt_to_str.strftime("%A, %B %d, %Y") + +datetime.datetime.now().strftime("%Y-%m-%d") + +datetime.datetime.now().strftime("%c") + +# ### Сравнение и арифметика дат +# + +# #### Сравнение дат + +# + +date1: datetime.datetime = datetime.datetime(1905, 6, 30) +date2: datetime.datetime = datetime.datetime(1916, 5, 11) + +# date1 < date2 +# date1 > date2 +# - + +# #### Календарный и алфавитный порядок дат +# + +# + +# "2007-12-02" > "2002-11-19" + +# + +# datetime.datetime(2007, 12, 2) > datetime.datetime(2002, 11, 19) +# - + +# #### Промежуток времени и класс timedelta +# + +diff: datetime.timedelta = date2 - date1 +print(diff) + +type(diff) + +print(diff.days) + +datetime.timedelta(days=1) + +# #### Арифметика дат +# + +future: datetime.datetime = datetime.datetime(2070, 1, 1) +future + +# + +time_travel_var: datetime.timedelta = datetime.timedelta(days=365) * 170 + +past_var: datetime.datetime = future - time_travel_var +past_var + +# + +# datetime.datetime(2070, 1, 1) - datetime.datetime(1900, 1, 1) +time_travel: datetime.timedelta = datetime.timedelta(days=62092) + +past: datetime.datetime = future - time_travel +past + +# + +cur_date: datetime.datetime = datetime.datetime(2021, 1, 1) +end_date: datetime.datetime = datetime.datetime(2021, 1, 10) + +while cur_date <= end_date: + print(cur_date.strftime("%b %d, %Y")) + cur_date += datetime.timedelta(days=1) +# - + +# ### Дата и обработка ошибок + +# #### Конструкция try/except и оператор pass +# + +# + +numbers: list[str] = ["5", "10", "a", "15", "10"] + +total: int = 0 + +for number in numbers: + try: + total += int(number) + except ValueError: + pass + +total + +# + +total_var: int = 0 + +for number in numbers: + try: + total_var += int(number) + except ValueError: + print(f"Элемент '{number}' обработать не удалось") + +total_var +# - + +# #### Обработка нескольких форматов дат +# + +temp: pd.DataFrame = pd.read_csv("temperature.csv") +temp + +# + +formats_var: list[str] = ["%Y-%m-%d", "%Y-%m-%-d", "%Y-%m"] + +counter: int = 0 + +for d_var in temp.Date: + for format_var in formats_var: + try: + print(datetime.datetime.strptime(d_var, format_var)) + counter += 1 + except ValueError: + pass + +print("Не отобразилось записей:", len(temp) - counter) +# - + +temp_parsed: pd.DataFrame = pd.read_csv( + "temperature.csv", index_col="Date", parse_dates=True +) +temp_parsed + +type(temp_parsed.index) diff --git a/python_issue/makarov/chapter_6_functions.py b/python_issue/makarov/chapter_6_functions.py new file mode 100644 index 00000000..98d1f099 --- /dev/null +++ b/python_issue/makarov/chapter_6_functions.py @@ -0,0 +1,584 @@ +"""Functions in Python.""" + +# ## Функции в Питоне + +# ### Встроенные функции +# + +# + +import matplotlib.pyplot as plt +import numpy as np + +np.random.seed(42) +height: list[np.float64] = list(np.round(np.random.normal(180, 10, 1000))) +height +# - + +# ### Параметры и аргументы функции +# + +plt.hist(height, bins=10) +plt.show() + +plt.hist(bins=10, x=height) +plt.show() + +plt.hist(height) +plt.show() + +print("first string") +print() +print("second string") + +# ### Функции и методы +# + +some_string: str = "machine learning" +some_string.title() + + +# + +# some_list: list[str] = ["machine", "learning"] +# some_list.title() -> wrong +# - + +# ### Собственные функции в Питоне + +# ### Объявление и вызов функции +# + + +# + +def double(x_var: int | float) -> int | float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + res_var: int | float = x_var * 2 + return res_var + + +double(2) +# - + +# ### Пустое тело функции +# + +# + +# def only_return(): +# """ +# Temporary training function used to practice Python syntax, + +# typing, and code style. Not intended for production use. +# """ +# return + + +# only_return() + +# print(only_return()) + +# + +# def only_pass(): +# """ +# Temporary training function used to practice Python syntax, + +# typing, and code style. Not intended for production use. +# """ +# pass + + +# only_pass() +# - + +# ### Функция print() вместо return +# + + +def double_print(x_var_1: int | float) -> None: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + res: int | float = x_var_1 * 2 + print(res) + + +double_print(5) + + +# #### Параметры собственных функций +# + + +def calc_sum(x_var_2: int | float, y_var_2: int | float) -> int | float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return x_var_2 + y_var_2 + + +calc_sum(1, y_var_2=2) + + +# + +def calc_sum_default(x_var_3: int | float = 1, y_var_3: int | float = 2) -> int | float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return x_var_3 + y_var_3 + + +calc_sum_default() + + +# + +def print_string() -> None: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + print("some string") + + +print_string() + + +# - + +# ### Аннотация функции +# +# + + +# + +def f(x_var_4: float = 3.5) -> int: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return int(x_var_4) + + +f.__annotations__ + +f() + + +# + +def f_1(x_var_5: float) -> float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return float(x_var_5) + + +f_1(3) +# - + +# ### Дополнительные возможности +# + +print(calc_sum(1, 2) * 2) +print(calc_sum(1, 2) > 2) + + +# + +def first_letter() -> str: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return "Python" + + +print(first_letter()[0]) + + +# + +def use_input() -> int: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + user_input: int = int(input("Введите число: ")) + result: int = user_input**2 + return result + + +use_input() + + +# - + +# ### Результат вызова функции +# + + +# + +def create_list(x_var_6: int) -> list[int]: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + list_var_3: list[int] = [] + for i in range(x_var_6): + list_var_3.append(i) + + return list_var_3 + + +create_list(5) + + +# + +def tuple_f() -> tuple[str, int]: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + string_var_7: str = "Python" + x_var_7: int = 42 + return (string_var_7, x_var_7) + + +(a_var_7, b_var_7) = tuple_f() + +print(a_var_7, b_var_7) +print(type(a_var_7), type(b_var_7)) + +# + +c_var_7: tuple[str, int] = tuple_f() + +print(type(c_var_7)) +print(c_var_7) + + +# + +def is_divisible(x_var_8: int) -> bool: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return x_var_8 % 2 == 0 + + +is_divisible(10) + + +# - + +# ### Использование библиотек +# + + +# + +def mean_f(x_var_9: list[int]) -> float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + mean_val: float = float(np.mean(x_var_9)) + return mean_val + 1.0 + + +x_var_10: list[int] = [1, 2, 3] +mean_f(x_var_10) +# - + +# ### Глобальные и локальные переменные +# + +# + +global_name: str = "Петр" + + +def show_name() -> None: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + print(global_name) + + +show_name() + + +# + +def show_local_name() -> None: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + local_name_1: str = "Алена" + print(local_name_1) + + +show_local_name() +# local_name вне функции не существует + +# + +# def make_global(): +# """ +# Temporary training function used to practice Python syntax, typing, and code style. +# +# Not intended for production use. +# """ +# +# global local_name +# local_name: str = "Алена" +# print(local_name) + + +# make_global() +# local_name + +# + +local_number: int = 5 + + +# def print_number(): +# """ +# Temporary training function used to practice Python syntax, +# typing, and code style. Not intended for production use. +# """ +# local_number = 10 +# print("Local number =", local_number) + + +# print_number() +print("Global number =", local_number) + + +# - + +# ### Lambda-функции +# + +# + +# lf = lambda a_var_10, b_var_10: a_var_10 * b_var_10 + +# lf(2, 3) + + +# + +def normal_f(a_var_11: int, b_var_11: int) -> int: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return a_var_11 * b_var_11 + + +normal_f(2, 3) +# - + +# #### Lambda-функция внутри функции filter() +# + +# + +nums: list[int] = [15, 27, 17, 9, 19, 2, 1, 4] + +# criterion = lambda n_var_11: True if (n_var_11 > 10) else False + +# list(filter(criterion, nums)) + +# + +# list(filter(lambda n_var_12: True if (n_var_12 > 10) else False, nums)) + + +# + +def is_criterion_2(n_var_13: int) -> bool: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return n_var_13 > 10 + + +list(filter(is_criterion_2, nums)) +# - + +# #### Lambda-функция внутри функции sorted() +# + +# + +indices_distances: list[tuple[int, float]] = [ + (901, 0.0), + (1002, 0.2298440568634488), + (442, 0.25401128310081567), +] + + +def key_var(x_var_11: tuple[int, float]) -> float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return x_var_11[1] + + +sorted(indices_distances, key=key_var, reverse=False) + + +# - + +# #### Немедленно вызываемые функции +# + + +# + +def square(x_var_12: int | float) -> int | float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return x_var_12 * x_var_12 + + +print(square(10)) + + +# - + +# ### *args и **kwargs + +# #### *args +# + + +# + +def mean(a_var_14: int, b_var_14: int) -> float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + return (a_var_14 + b_var_14) / 2 + + +mean(1, 2) + + +# + +def mean_1(list_1: list[int]) -> float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + total: int = 0 + for i in list_1: + total += i + + return total / len(list_1) + + +list_var_1: list[int] = [1, 2, 3, 4, 5, 6, 7, 8] + +mean_1(list_var_1) + + +# + +# mean(1, 2) -> WRONG, only lists + + +# + +def mean_2(*nums_var_1: int) -> float: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + total_var_1: int = 0 + for i in nums_var_1: + total_var_1 += i + + return total_var_1 / len(nums_var_1) + + +list_var_2: list[int] = [1, 2, 3, 4, 5, 6, 7, 8] + +mean_2(1, 2, 3, 4, 5) +mean_2(*[3, 4, 7, 8, 11, 22]) + + +# + +def test_type(*nums_var: int | float) -> None: + """Temporary training function used to practice Python syntax and + typing.""" + for num in nums_var: + print(type(num)) + + +test_type(1, 3, 5, 12) +test_type(*list_var_2) +# - + +a_var_15: list[int] = [1, 2, 3, 4] +b_var_15: list[int] = [*a_var_15, 4, 5, 6, 7] +b_var_15 + + +# #### **kwargs +# + + +# + +def f_3(**kwargs: int) -> dict[str, int]: + """Temporary training function used to practice Python syntax and + typing.""" + return kwargs + + +f_3(a=1, b=2) + + +# + +def simple_stats(*nums_var_3: int | float, **params: bool) -> None: + """Temporary training function used to practice Python syntax, typing, and + code style. + + Not intended for production use. + """ + if "mean" in params and params["mean"]: + print(f"mean: \t{np.round(np.mean(nums_var_3), 3)}") + + if "std" in params and params["std"]: + print(f"std: \t{np.round(np.std(nums_var_3), 3)}") + + +simple_stats(5, 10, 15, 20, mean=True, std=True) +print() +simple_stats(5, 20, 10, 11, mean=True, std=False) + +# + +list_var: list[int] = [5, 12, 18, 22] +settings: dict[str, bool] = {"mean": True, "std": True} + +simple_stats(*list_var, **settings) +# - + +simple_stats(5, 10, 14, 19, 25, 22, mean=True, std=True, median=True) diff --git a/python_issue/makarov/chapter_7_lists_tuples_and_sets.py b/python_issue/makarov/chapter_7_lists_tuples_and_sets.py new file mode 100644 index 00000000..648f5e36 --- /dev/null +++ b/python_issue/makarov/chapter_7_lists_tuples_and_sets.py @@ -0,0 +1,384 @@ +"""Lists, tuples, and sets.""" + +# # Списки, кортежи и множества + +# ## Списки + +# ### Основы работы со списками +# + +# + +from nltk import PorterStemmer + +some_list_1: list[str] = [] +some_list_2: list[str] = [] + +print(some_list_1, some_list_2) + +number_three: list[int | str | list[str] | dict[str, int]] = [ + 3, + "number three", + ["number", "three"], + {"number": 3}, +] +print(number_three) + +len(number_three) +# - + +# ### Индекс и срез списка +# + +# + +abc_list: list[str] = ["a", "b", "c", "d", "e"] + +print(abc_list[0], abc_list[-1]) + +# + +salary_list: list[list[str | int]] = [ + ["Anna", 90000], + ["Igor", 85000], + ["Alex", 95000], +] + +salary_list[1][0] +# - + +abc_list.index("c") + +salary_list[0].index(90000) + +# + +days_list: list[str] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] + +days_list[1:5] +# - + +days_list[:5:2] + +"Mon" in days_list + +if "Tue" in days_list: + print("Такое слово есть") + +# ### Добавление, замена и удаление элементов списка +# + +# + +weekdays: list[str] = ["Monday", "Tuesday"] + +weekdays.append("Thursday") +weekdays +# - + +weekdays.insert(2, "Wednesday") +weekdays + +weekdays[3] = "Friday" +weekdays + +weekdays.remove("Friday") +weekdays + +del weekdays[2] +weekdays + +weekdays.pop(1) + +weekdays + +# ### Сложение списков +# + +# + +more_weekdays: list[str] = ["Tuesday", "Wednesday", "Thursday", "Friday"] + +weekdays.extend(more_weekdays) +weekdays + +# + +weekend: list[str] = ["Saturday", "Sunday"] + +print(weekdays + weekend) +# - + +["Monday"] * 2 + +["Monday"] * 2 + ["Tuesday"] * 2 + +# ### Распаковка списков + +# + +week: list[str] = [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday", +] + +mon = week[0] +mon +# - + +mon_1, tue_1, wed_1 = week[0:3] +mon_1, tue_1, wed_1 + +mon_1, *_ = week +mon_1 + +mon_1, *days, sun_1 = week +mon_1, sun_1 + +days + +# ### Сортировка списков +# + +nums: list[int] = [25, 10, 30, 20, 5, 15] +sorted(nums) + +sorted_nums: list[int] = sorted(nums) +sorted_nums + +nums.sort(reverse=True) +nums + +print(nums) +nums.reverse() +print(nums) + +# #### Переменная не изменяется при этом +# + +reversed(nums) + +list(reversed(nums)) + +# ### Преобразование списка в строку +# + +str_list: list[str] = ["P", "y", "t", "h", "o", "n"] +joined_str: str = "".join(str_list) +joined_str + +joined_str_: str = "_".join(str_list) +joined_str_ + +# ### Арифметика в списках +# + +# + +nums_: list[int] = [3, 2, 1, 4, 5, 12, 3, 3, 7, 9, 11, 15] + +nums_.count(3) +# - + +print(min(nums_), max(nums_), sum(nums_)) + +# ### List comprehension +# + +# + +names: list[str] = ["Arthur", "Anton", "Alex", "Boris", "Victor", "Eugene"] +a_names_var: list[str] = [] + +for name in names: + if name.startswith("a"): + a_names_var.append(name) + +a_names_var +# - + +a_names: list[str] = [name for name in names if name.startswith("a")] +a_names + +lower_names: list[str] = [name.lower() for name in names] +lower_names + +replace_name: list[str] = [name if name != "Victor" else "Vlad" for name in names] +replace_name + +# + +lemmatized: list[str] = [ + "paris", + "visited", + "lot", + "museum", + "first", + "went", + "louvre", + "largest", + "art", + "museum", + "world", + "always", + "interested", + "art", + "spent", + "many", + "hour", + "museum", + "enormous", + "week", + "would", + "enough", +] + + +porter: PorterStemmer = PorterStemmer() + +stemmed_p: list[str] = [porter.stem(s) for s in lemmatized] +print(stemmed_p) +print(type(porter)) +# - + +# ## Кортежи + +# ### Основы работы с кортежами +# + +tuple_1: tuple[()] = () +tuple_2: tuple[()] = () +print(tuple_1, tuple_2) + +letters_tuple: tuple[str, str, str] = ("a", "b", "c") +print(letters_tuple[0]) +# letters[0] = 'd' -> WRONG + +letters_list: list[str] = list(letters_tuple) +letters_list[0] = "d" +print(letters_list) + +let_a_tuple: tuple[str] = ("a",) +print(type(let_a_tuple)) + +let_a_str: str = "a" +print(type(let_a_str)) + +# #### Функция enumerate() +# + +# + +companies: list[str] = ["Microsoft", "Apple", "Tesla"] + +for company in enumerate(companies): + print(company, type(company)) +# - + +# #### Просмотр элементов словаря +# + +# + +shopping_dict: dict[str, int] = {"cucumber": 3, "tomato": 2, "onion": 1, "potato": 2} + +for item in shopping_dict.items(): + print(item) +# - + +# #### Распаковка кортежей +# + +a_var, b_var, c_var = ("a", "b", "c") +print(a_var) + +for index_value, company_name in enumerate(companies): + print(index_value, company_name) + +for k_var, v_var in shopping_dict.items(): + print(k_var, v_var) + +# #### Функция zip() +# + +# + +names_list: list[str] = ["Arthur", "Anton", "Alex", "Boris", "Victor", "Eugene"] +income: list[int] = [97000, 110000, 95000, 84000, 140000, 120000] + +zip(names_list, income) +# - + +list(zip(names_list, income)) + +# ### Множества +# + +# ### Создание множества + +set_1: set[str] = set() +set_2: set[str] = {"a", "b", "c"} +set_3: set[str] = {"a", "b", "c", "d", "e", "f"} +print(set_1, set_2, set_3) + +not_a_set: dict[str | int, str | int] = {} +print(type(not_a_set)) + +# #### Добавление и удаление элементов +# + +# + +vowels: set[str] = {"a", "o", "ie", "e", "y", "io", "iu"} + +vowels.add("ia") +print(vowels) +# - + +vowels.update({"i", "ii"}) +print(vowels) + +# + +vowels.add("cha") +print(vowels) + +vowels.discard("cha") +print(vowels) +# - + +# #### Теория множеств в Питоне +# + +# равны если имеют одинаковые элементы, порядок не важен +{"a", "b", "c"} == {"c", "a", "b"} + +# #### Мощность множества +# + +len({"a", "b", "c"}) + +# #### Проверка есть ли элемент в множестве +# + +a_var in {"a", "b", "c"} + +# или наоборот +a_var not in {"a", "b", "c"} + +# + +set_a: set[str] = {"a", "b", "c"} +set_b: set[str] = {"a", "b", "c", "d", "e"} + +set_a.issubset(set_b) +# - + +set_b.issuperset(set_a) + +nlp: set[str] = {"Анна", "Николай", "Павел", "Оксана"} +cv: set[str] = {"Николай", "Евгений", "Ольга", "Оксана"} + +# Все участники +print(nlp.union(cv)) +print(nlp | cv) + +# И там и там +print(nlp.intersection(cv)) +print(nlp & cv) + +# Только nlp или и там и там +print(nlp.difference(cv)) +print(nlp - cv) + +# Или там или там но не одновременно везде +print(nlp.symmetric_difference(cv)) +print(nlp ^ cv) diff --git a/python_issue/makarov/chapter_8_dictionary_in_python.py b/python_issue/makarov/chapter_8_dictionary_in_python.py new file mode 100644 index 00000000..97d18051 --- /dev/null +++ b/python_issue/makarov/chapter_8_dictionary_in_python.py @@ -0,0 +1,435 @@ +"""Dictionary in Python.""" + +# ## Словарь в Питоне + +# ### Понятие словаря + +# #### Создание словаря +# + +# + +# Способ 3. Модуль collections +from collections import Counter +from pprint import pprint + +import numpy as np + +dict_1: dict[str, int] = {} +dict_2: dict[str, int] = {} +print(dict_1, dict_2) +# - + +company = {"name": "Tayota", "founded": 1937, "founder": "Kiichiro Toyoda"} +company + +tickers = dict([["TYO", "Toyota"], ["TSLA", "Tesla"], ["f", "Ford"]]) +tickers + +# + +keys = ("k1", "k2", "k3") +value = 0 + +empty_values = dict.fromkeys(keys, value) +empty_values +# - + +# ### Ключи и значения словаря + +# #### Виды значений словаря +# + +# + +value_types = { + "k1": 123, + "k2": "string", + "k3": np.nan, + "k4": True, + "k5": None, + "k6": [1, 2, 3], + "k7": np.array([1, 2, 3]), + "k8": {1: "v1", 2: "v2", 3: "v3"}, +} + +value_types +# - + +# #### Методы .keys(), .values() и .items() +# + +# + +person = {"first name": "Ivan", "last name": "Ivanov", "born": 1980, "dept": "IT"} + +print(person.keys()) +print(person.values()) +print(person.items()) +# - + +# #### Использование цикла for +# + +for k_var, v_var in person.items(): + print(k_var, v_var) + +# #### Доступ по ключу и метод .get() +# + +person["last name"] + +# + +# если такого ключа нет, Питон выдаст ошибку +# person['education'] +# - + +print(person.get("education")) + +person.get("born") + +# #### Проверка вхождения ключа и значения в словарь +# + +print("born" in person) + +print(1980 in person.values()) + +print(("born", 1980) in person.items()) + +# ### Операции со словарями + +# #### Добавление и изменение элементов +# + +person["languages"] = ["Python", "C++"] +person + +person["languages"] = ["Python"] +person + +# + +new_elements = {"job": "programmer", "experience": 7} + +person.update(new_elements) +person +# - + +person.setdefault("last name", "Petrov") +person + +person.setdefault("f_languages", ["Russian", "English"]) +person + +# #### Удаление элементов +# + +person.pop("dept") + +person + +del person["born"] + +person.popitem() + +person.clear() +person + +del person + +# + +# убедимся, что такого словаря больше нет +# person +# - + +# #### Сортировка словарей +# + +# + +dict_to_sort = {"k2": 30, "k1": 20, "k3": 10} + +sorted(dict_to_sort) +# - + +sorted(dict_to_sort.values()) + +dict_to_sort.items() + +sorted(dict_to_sort.items(), key=lambda x: x[0]) + +sorted(dict_to_sort.items(), key=lambda x: x[1]) + +# ### Копирование словарей +# + +original = {"first course": 174, "second course": 131} + +# #### Копирование с помощью метода .copy() +# + +# + +new_1 = original.copy() +new_1["Third course"] = 117 + +print(original) +print(new_1) +# - + +# #### Копирование через оператор присваивания = (так делать не стоит!) +# + +# + +new_2 = original + +new_2.clear() + +# из исходного словаря данные также удалились +print(original) +print(new_2) +# - + +# ### Функция dir() +# + +# + +some_dict = {"k": 1} + +print(dir(some_dict)[:11]) +# - + +print(some_dict) # == +# some_dict.__str__() # == + +# в большинстве случаев нас будут интересовать методы без '__' +print(dir(some_dict)[-11:]) + +# ### Dict comprehension +# + +# + +source_dict = {"k1": 2, "k2": 4, "k3": 6} + +print({k_var_1: v_var_1 * 2 for (k_var_1, v_var_1) in source_dict.items()}) +# - + +print({k_var_2.upper(): v_var_2 for (k_var_2, v_var_2) in source_dict.items()}) + +print( + {k_var_3: v_var_3 for (k_var_3, v_var_3) in source_dict.items() if 2 < v_var_3 < 6} +) + +# + +new_dict = {} + +for k_var_4, v_var_4 in source_dict.items(): + if 2 < v_var_4 < 6: + new_dict[k_var_4] = v_var_4 + +new_dict +# - + +print( + { + k_var_5: ("even" if v_var_5 % 2 else "odd") + for (k_var_5, v_var_5) in source_dict.items() + } +) + +# + +source_dict = {"k1": 2, "k2": 4, "k3": 6} + +{k: 0 for k in keys} +# - + +# ## Дополнительные примеры + +# ### lambda-функции, функции map() и zip() + +# #### Пример со списком + +words = ["apple", "banana", "fig", "blackberry"] + +length = list(map(len, words)) +length + +dict(zip(words, length)) # == + +dict(zip(words, [len(word) for word in words])) + +# #### Пример со словарем +# + +height_feet = {"Alex": 6.1, "Jerry": 5.4, "Ben": 5.8} + +metres = list(map(lambda x: x * 0.3048, height_feet.values())) +metres + +dict(zip(height_feet.keys(), np.round(metres, 2))) # == + +print( + { + k_var_10: np.round(v_var_10 * 0.3048, 2) + for (k_var_10, v_var_10) in height_feet.items() + } +) +# == + +# #### Вложенные словари +# + +employees: dict[str, dict[str, str | int | float]] = { + "id1": { + "first name": "Александр", + "last name": "Иванов", + "age": 30, + "job": "программист", + }, + "id2": { + "first name": "Ольга", + "last name": "Петрова", + "age": 35, + "job": "ML-engineer", + }, +} + +for v_var_7 in employees.values(): + print(v_var_7) + +# #### Базовый операции + +# + +employees["id3"] = { + "first name": "Дарья", + "last name": "Некрасова", + "age": 27, + "job": "веб-дизайнер", +} + +pprint(employees) + +# + +employees["id3"]["age"] = 26 + +pprint(employees) +# - + +# ### Циклы for + +# + +for info in employees.values(): + for k_var_6, v_var_6 in info.items(): + if k_var_6 == "age": + info[k_var_6] = float(v_var_6) + +pprint(employees) +# - + +# #### Вложенные словари и dict comprehension +# + +pprint({id: info for id, info in employees.items()}) + +pprint( + { + emp_id: { + k_var_7: (int(v_var_7) if k_var_7 == "age" else v_var_7) + for k_var_7, v_var_7 in info.items() + } + for emp_id, info in employees.items() + } +) + +# #### Частота слов в тексте +# + +corpus = """When we were in Paris we visited a lot of museums. We first went to + the Louvre, the largest art museum in the world. I have always been + interested in art so I spent many hours + there. The museum is enormous, so a week there would not be enough.""" + +# #### Предварительная обработка текста + +words = corpus.split() +print(words) + +words = [word.strip(",").strip(".").lower() for word in words] +words + +# + +# Способ 1. Условие if-else +bow_1: dict[str, int] = {} + +for word in words: + if word in bow_1: + bow_1[word] += 1 + else: + bow_1[word] = 1 + +print(sorted(bow_1.items(), key=lambda x: x[1], reverse=True)[:6]) + +# + +# Способ 2. Метод .get() +bow_2: dict[str, int] = {} + +for word in words: + bow_2[word] = bow_2.get(word, 0) + 1 + +print(sorted(bow_2.items(), key=lambda x: x[1], reverse=True)[:6]) +# - + +bow_3 = Counter(words) +bow_3.most_common(6) + +# ## Изменяемые и неизменяемые типы данных +# + +# ### Неизменяемый тип данных +# + +string = "Python" +print(id(string), type(string), string) + +string = string + " is cool" +print(id(string), type(string), string) + +# ### Изменяемый тип данных +# + +lst = [1, 2, 3] +print(id(lst), type(lst), lst) + +lst.append(4) +print(id(lst), type(lst), lst) + +# #### Копирование объектов +# + +# + +string = "python" +string2 = string +string2 = string2 + " is cool" + +string2, string +# - + +string == string2, string is string2 + +# + +lst = [1, 2, 3] + +lst2 = lst +lst2.append(4) + +lst, lst2 +# - + +lst == lst2, lst is lst2 + +# + +lst = [1, 2, 3] +lst2 = lst.copy() + +lst2.append(4) + +lst, lst2 + +# + +lst.append(4) + +lst, lst2, lst == lst2, lst is lst2 diff --git a/python_issue/makarov/chapter_9_classes_and_objects_in_python.py b/python_issue/makarov/chapter_9_classes_and_objects_in_python.py new file mode 100644 index 00000000..cd351a4b --- /dev/null +++ b/python_issue/makarov/chapter_9_classes_and_objects_in_python.py @@ -0,0 +1,515 @@ +"""Classes and objects in Python.""" + +# ## Классы и объекты в Питоне + +# ### Создание класса + +# #### Создание класса и метод .__init__() + +# + +import numpy as np + + +class CatClass: + """Temporary training function.""" + + def __init__(self) -> None: + """Temporary training function.""" + self.color = "undefined" + + +# - + +# #### Создание объекта +# + +# + +matroskin_f: CatClass = CatClass() + +print(type(matroskin_f)) + + +# - + +# #### Атрибуты класса +# + + +class CatClass1: + """Temporary training function.""" + + def __init__(self, color: str) -> None: + """Temporary training function.""" + self.color = color + self.type_ = "cat" + + +# + +matroskin_1: CatClass1 = CatClass1("grey") + +print(matroskin_1.color, matroskin_1.type_) + + +# - + +# #### Методы класса +# + + +class CatClass2: + """Temporary training class.""" + + def __init__(self, color: str) -> None: + """Temporary training function.""" + self.color = color + self.type_ = "cat" + + def meow(self) -> None: + """Temporary training function.""" + for _ in range(3): + print("meow") + + def info(self) -> None: + """Temporary training function.""" + print(self.color, self.type_) + + +matroskin_2: CatClass2 = CatClass2("gray") + +matroskin_2.meow() + +matroskin_2.info() + +# ### Принципы ООП +# + +# #### Инкапсуляция + +matroskin_2.type_ = "dog" +print(matroskin_2.type_) + + +# + +class CatClass3: + """Temporary training class.""" + + def __init__(self, color: str) -> None: + """Temporary training function.""" + self.color = color + self.type_ = "cat" + + +matroskin_3: CatClass3 = CatClass3("gray") +matroskin_3.type_ = "dog" +print(matroskin_3.type_) + + +# + +class CatClass4: + """Temporary training class.""" + + def __init__(self, color: str) -> None: + """Temporary training function.""" + self.color = color + self.__type_ = "cat" + + def set_type(self, new_type: str) -> None: + """Temporary training function.""" + self.__type_ = new_type + + def get_type(self) -> str: + """Temporary training function.""" + return self.__type_ + + +matroskin_4: CatClass4 = CatClass4("grey") +# - + +matroskin_4.set_type("dog") +print(matroskin_4.get_type()) + + +# + +# matroskin_4.__type_ ERROR +# - + +# ### Наследование классов +# +# +# + +# #### Создание родительского класса и класса-потомка + + +class Animal: + """Temporary training class.""" + + def __init__(self, weight: float, length: int) -> None: + """Temporary training function.""" + self.weight = weight + self.length = length + + def eat(self) -> None: + """Temporary training function.""" + print("Eating") + + def sleep(self) -> None: + """Temporary training function.""" + print("Sleeping") + + +class Bird(Animal): + """Temporary training class.""" + + def move(self) -> None: + """Temporary training function.""" + print("Flying") + + +pigeon: Bird = Bird(0.3, 30) +print(pigeon.weight, pigeon.length) + +pigeon.eat() +pigeon.move() + + +# #### Функция super() + + +# + +class Bird2(Animal): + """Temporary training function.""" + + def __init__(self, weight: float, length: int, flying_speed: int) -> None: + """Temporary training function.""" + super().__init__(weight, length) + self.flying_speed = flying_speed + + def move(self) -> None: + """Temporary training function.""" + print("Flying") + + +pigeon_2: Bird2 = Bird2(0.3, 30, 100) + +print(pigeon_2.weight, pigeon_2.length, pigeon_2.flying_speed) +# - + +pigeon_2.sleep() +pigeon_2.move() + + +# #### Переопределение класса +# + + +# + +class Flightless(Bird2): + """Temporary training class.""" + + def __init__(self, weight: float, length: int, running_speed: int) -> None: + """Temporary training function.""" + super().__init__(weight, length, flying_speed=0) + self.running_speed = running_speed + + def move(self) -> None: + """Temporary training function.""" + print("Running") + + +ostrich: Flightless = Flightless(60.0, 200, 60) +print(ostrich.running_speed) +# - + +ostrich.move() +ostrich.eat() + + +# #### Множественное наследование +# + + +# + +class Fish: + """Temporary training class.""" + + def swim(self) -> None: + """Temporary training function.""" + print("Swimming") + + +class Bird3: + """Temporary training class.""" + + def fly(self) -> None: + """Temporary training function.""" + print("Flying") + + +class SwimmingBird(Bird3, Fish): + """Temporary training class.""" + + def demo(self) -> None: + """Temporary training function.""" + self.fly() + self.swim() + + +# - + +duck: SwimmingBird = SwimmingBird() +duck.fly() +duck.swim() + +# #### Полиморфизм +# +# + +# # + для цифр это сложение, для строк слияние +print(2 + 2) +print("classes" + " and " + "objects") + +# #### Полиморфизм функций +# +# + +# + +# len можно применять ко многим последовательностям значений + +print(len("programming in Python")) +print(len(["programming", "in", "Python"])) +print(len({0: "programming", 1: "in", 2: "Python"})) +# - + +print(len(np.array([1, 2, 3]))) + +# #### Полиморфизм классов +# + +# + +# Создадим объекты с одинаковыми атрибутами и методами + + +class CatClass5: + """Temporary training class.""" + + def __init__(self, name: str, color: str) -> None: + """Temporary training function.""" + self.name = name + self._type_ = "cat" + self.color = color + + def info(self) -> None: + """Temporary training function.""" + print( + f"My name is {self.name}, i'm {self._type_}, color of my wool {self.color}" + ) + + def sound(self) -> None: + """Temporary training function.""" + print("I can meow") + + +# - + + +class DogClass: + """Temporary training class.""" + + def __init__(self, name: str, color: str) -> None: + """Temporary training function.""" + self.name = name + self._type_ = "dog" + self.color = color + + def info(self) -> None: + """Temporary training function.""" + print( + f"My name is {self.name}, i'm {self._type_}, color of my wool {self.color}" + ) + + def sound(self) -> None: + """Temporary training function.""" + print("I can bark") + + +cat: CatClass5 = CatClass5("Barsik", "black") +dog: DogClass = DogClass("Barbos", "gray") + +for animal in (cat, dog): + animal.info() + animal.sound() + print() + +# ### Парадигмы программирования +# + +patients: list[dict[str, int | str]] = [ + {"name": "Николай", "height": 178}, + {"name": "Иван", "height": 182}, + {"name": "Алексей", "height": 190}, +] + +# #### Процедурное программирование +# + +# + +total: int = 0 +count_var: int = 0 + +for patient in patients: + height_val: int = int(patient["height"]) + total += height_val + count_var += 1 + +total / count_var + + +# - + +# #### Объектно-ориентированное программирование +# + + +class DataClass: + """Temporary training class.""" + + def __init__(self, data: list[dict[str, int | str]]) -> None: + """Temporary training function.""" + self.data = data + + def count_average(self, metric: str) -> float: + """Temporary training function.""" + total_sum: int = 0 + count: int = 0 + + for item in self.data: + total_sum += int(item[metric]) + count += 1 + + return total_sum / count + + +data_object = DataClass(patients) +print(data_object.count_average("height")) + +# #### Функциональное программирование +# +# + +# #### Функция map() + +heights: list[int] = [int(p["height"]) for p in patients] +print(heights) + +print(sum(heights) / len(heights)) + +# #### Функция einsum() + +# + +a_arr = np.array([[0, 1, 2], [3, 4, 5]]) + +b_arr = np.array([[5, 4], [3, 2], [1, 0]]) + +print(np.einsum("ij, jk -> ik", a_arr, b_arr)) +# - + +# ### Классы и объекты в машинном обучении +# +# + +# #### Готовые классы в библиотеке sklearn + +X_ax = np.array( + [ + 1.48, + 1.49, + 1.49, + 1.50, + 1.51, + 1.52, + 1.52, + 1.53, + 1.53, + 1.54, + 1.55, + 1.56, + 1.57, + 1.57, + 1.58, + 1.58, + 1.59, + 1.60, + 1.61, + 1.62, + 1.63, + 1.64, + 1.65, + 1.65, + 1.66, + 1.67, + 1.67, + 1.68, + 1.68, + 1.69, + 1.70, + 1.70, + 1.71, + 1.71, + 1.71, + 1.74, + 1.75, + 1.76, + 1.77, + 1.77, + 1.78, + ] +) +y_ax = np.array( + [ + 29.1, + 30.0, + 30.1, + 30.2, + 30.4, + 30.6, + 30.8, + 30.9, + 31.0, + 30.6, + 30.7, + 30.9, + 31.0, + 31.2, + 31.3, + 32.0, + 31.4, + 31.9, + 32.4, + 32.8, + 32.8, + 33.3, + 33.6, + 33.0, + 33.9, + 33.8, + 35.0, + 34.5, + 34.7, + 34.6, + 34.2, + 34.8, + 35.5, + 36.0, + 36.2, + 36.3, + 36.6, + 36.8, + 36.8, + 37.0, + 38.5, + ] +) + +X_2D = X_ax.reshape(-1, 1) +X_2D diff --git a/python_issue/oop_molchanov.py b/python_issue/oop_molchanov.py new file mode 100644 index 00000000..49f65384 --- /dev/null +++ b/python_issue/oop_molchanov.py @@ -0,0 +1,301 @@ +# + +"""Describe object-oriented lesson examples.""" +from __future__ import annotations + +from typing import ClassVar + +import requests +from requests import Response + +# - + +google_response: Response = requests.get("https://www.google.ru") + +print(type(google_response)) + +print(dir(google_response)) + + +# + +# Lesson 1. +# - + + +class PersonLesson1: + """Represent lesson 1 person with a default name.""" + + name: ClassVar[str] = "Ivan" + + +print(PersonLesson1.name) + +print(PersonLesson1.__name__) + +print(dir(PersonLesson1)) + +print(PersonLesson1.__class__) + +lesson1_person: PersonLesson1 = PersonLesson1() + +print(lesson1_person.__class__) + +print(lesson1_person.__class__.__name__) + +print(type(lesson1_person)) + +cloned_person: PersonLesson1 = type(lesson1_person)() + +print(id(lesson1_person)) + +print(id(cloned_person)) + + +# + +# Lesson 2. +# - + + +class PersonLesson2: + """Represent lesson 2 person with mutable attributes.""" + + name: ClassVar[str] = "Ivan" + age: ClassVar[int] + dob: ClassVar[str] + + +print(dir(PersonLesson2)) + +print(PersonLesson2.__dict__) + +print(PersonLesson2.name) + +PersonLesson2.age = 123 + +print(PersonLesson2.__dict__) + +print(getattr(PersonLesson2, "name")) + +setattr(PersonLesson2, "dob", "123") + +print(PersonLesson2.__dict__) + +delattr(PersonLesson2, "dob") + + +# + +class PersonLesson2Method: + """Represent lesson 2 person with a plain function-style method.""" + + name: ClassVar[str] = "Ivan" + + def hello(self: PersonLesson2Method) -> None: + """Say hello without binding to an instance.""" + print("hello!") + + +PersonLesson2Method.hello(PersonLesson2Method()) +# - + +print(PersonLesson2Method.__dict__) + + +# + +# Lesson 3. + + +# + +class PersonLesson3: + """Represent lesson 3 person for attribute experiments.""" + + name: str = "Ivan" + age: int + + +print(PersonLesson3.__dict__) +# - + +first_person: PersonLesson3 = PersonLesson3() + +second_person: PersonLesson3 = PersonLesson3() + +print(id(first_person)) + +print(id(second_person)) + +print(first_person.name == second_person.name) + +print(id(first_person.name) == id(second_person.name)) + +print(first_person.__dict__) + +print(second_person.__dict__) + +print(PersonLesson3.__dict__) + +first_person.name = "Oleg" +second_person.name = "Dima" + +print(first_person.__dict__) + +print(second_person.__dict__) + +second_person.age = 25 + +print(second_person.__dict__) + +# + +# first_person.age -> no attr +# - + +fresh_person_one: PersonLesson3 = PersonLesson3() +fresh_person_two: PersonLesson3 = PersonLesson3() + +print((fresh_person_one.name, fresh_person_two.name)) + +# + +PersonLesson3.name = "Dayal" + +print((fresh_person_one.name, fresh_person_two.name)) + + +# + +# Lesson 4. +# - + + +class PersonLesson4: + """Represent lesson 4 person with a simple greeter.""" + + def hello(self: PersonLesson4) -> None: + """Say hello from the class namespace.""" + print("Hello!") + + +print(PersonLesson4.hello) + +greeting_person: PersonLesson4 = PersonLesson4() +print(greeting_person.hello) + +print(hex(id(greeting_person))) + +PersonLesson4.hello(greeting_person) + +# + +# greeting_person.hello() +# - + +print(type(greeting_person.hello)) + +print(type(PersonLesson4.hello)) + +print((id(PersonLesson4.hello), id(greeting_person.hello))) + +print(dir(PersonLesson4.hello)) + +print(dir(greeting_person.hello)) + +print(greeting_person.hello.__self__) # type: ignore[attr-defined] + +print(hex(id(greeting_person))) + +print(greeting_person.hello.__func__) # type: ignore[attr-defined] + + +# + +class PersonLesson4BoundInspector: + """Inspect bound method internals via a person.""" + + def hello(self: PersonLesson4BoundInspector) -> None: + """Display the instance reference.""" + print(self) + + +inspected_person: PersonLesson4BoundInspector = PersonLesson4BoundInspector() +inspected_person.hello() +# - + +print(hex(id(inspected_person))) + + +class PersonLesson4Self: + """Display instance reference through self.""" + + def hello(self: PersonLesson4Self) -> None: + """Display the instance reference through self.""" + print(self) + + +# + +# Lesson 5. +# - + + +class PersonLesson5Placeholder: + """Serve as a placeholder person for lesson 5.""" + + name: str + + +person_with_dynamic_attr: PersonLesson5Placeholder = PersonLesson5Placeholder() +person_with_dynamic_attr.name = "Ivan" +print(person_with_dynamic_attr.name) + + +# + +class PersonLesson5Named: + """Store and display a name.""" + + def __init__(self, name: str) -> None: + """Initialize a person with a provided name.""" + self.name: str = name + + def display(self) -> None: + """Print the stored name.""" + print(self.name) + + +named_person: PersonLesson5Named = PersonLesson5Named("Dayal") +# - + +print(named_person.__dict__) + +print(named_person.name) + + +# + +# Lesson 6. + + +# + +class PersonLesson6: + """Provide instance and static greetings.""" + + def hello(self: PersonLesson6) -> None: + """Greet from an instance method.""" + print("Hello!") + + @staticmethod + def goodbye() -> None: + """Say goodbye without binding to an instance.""" + print("Goodbye") + + +person_for_goodbye: PersonLesson6 = PersonLesson6() +person_for_goodbye.goodbye() # call works after making goodbye static +# - + +greeter_one: PersonLesson6 = PersonLesson6() +greeter_two: PersonLesson6 = PersonLesson6() + +greeter_one.hello() +greeter_one.goodbye() + +print((id(greeter_one.hello), id(greeter_two.hello))) + +print((id(greeter_one.goodbye), id(greeter_two.goodbye))) + +print((greeter_one.__dict__, greeter_two.__dict__)) + +print(type(greeter_one.goodbye)) + +PersonLesson6.goodbye() From 08b717296cb8e403844e4d0788005260d1c8de56 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 10 Dec 2025 22:27:59 +0300 Subject: [PATCH 22/24] refactor: restructure collections and comprehensions for readability --- .../chapter_7_lists_tuples_and_sets.ipynb | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb b/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb index 23cff81b..58bfed37 100644 --- a/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb +++ b/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb @@ -525,7 +525,14 @@ "metadata": {}, "outputs": [], "source": [ - "names: list[str] = [\"Arthur\", \"Anton\", \"Alex\", \"Boris\", \"Victor\", \"Eugene\"]\n", + "names: list[str] = [\n", + " \"Arthur\",\n", + " \"Anton\",\n", + " \"Alex\",\n", + " \"Boris\",\n", + " \"Victor\",\n", + " \"Eugene\",\n", + "]\n", "a_names_var: list[str] = []\n", "\n", "for name in names:\n", @@ -564,7 +571,7 @@ "metadata": {}, "outputs": [], "source": [ - "replace_name: list[str] = [name if name != \"Victor\" else \"Vlad\" for name in names]\n", + "replace_name: list[str] = [\"Vlad\" if name == \"Victor\" else name for name in names]\n", "replace_name" ] }, @@ -766,12 +773,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "c72341af", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('cucumber', 3)\n", + "('tomato', 2)\n", + "('onion', 1)\n", + "('potato', 2)\n" + ] + } + ], "source": [ - "shopping_dict: dict[str, int] = {\"cucumber\": 3, \"tomato\": 2, \"onion\": 1, \"potato\": 2}\n", + "shopping_dict: dict[str, int] = {\n", + " \"cucumber\": 3,\n", + " \"tomato\": 2,\n", + " \"onion\": 1,\n", + " \"potato\": 2,\n", + "}\n", "\n", "for item in shopping_dict.items():\n", " print(item)" @@ -833,7 +856,14 @@ "metadata": {}, "outputs": [], "source": [ - "names_list: list[str] = [\"Arthur\", \"Anton\", \"Alex\", \"Boris\", \"Victor\", \"Eugene\"]\n", + "names_list: list[str] = [\n", + " \"Arthur\",\n", + " \"Anton\",\n", + " \"Alex\",\n", + " \"Boris\",\n", + " \"Victor\",\n", + " \"Eugene\",\n", + "]\n", "income: list[int] = [97000, 110000, 95000, 84000, 140000, 120000]\n", "\n", "zip(names_list, income)" From 1d4a560002fe1185ded09e778c96fbe18dd83176 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 10 Dec 2025 22:35:16 +0300 Subject: [PATCH 23/24] chore: temporarily comment out problematic function --- .../chapter_7_lists_tuples_and_sets.ipynb | 5 +-- .../chapter_7_lists_tuples_and_sets.py | 31 ++++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb b/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb index 58bfed37..ea070fdb 100644 --- a/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb +++ b/python_issue/makarov/chapter_7_lists_tuples_and_sets.ipynb @@ -571,8 +571,9 @@ "metadata": {}, "outputs": [], "source": [ - "replace_name: list[str] = [\"Vlad\" if name == \"Victor\" else name for name in names]\n", - "replace_name" + "# replace_name: list[str] =\n", + "# [\"Vlad\" if name == \"Victor\" else name for name in names]\n", + "# replace_name" ] }, { diff --git a/python_issue/makarov/chapter_7_lists_tuples_and_sets.py b/python_issue/makarov/chapter_7_lists_tuples_and_sets.py index 648f5e36..a1dbca29 100644 --- a/python_issue/makarov/chapter_7_lists_tuples_and_sets.py +++ b/python_issue/makarov/chapter_7_lists_tuples_and_sets.py @@ -182,7 +182,14 @@ # # + -names: list[str] = ["Arthur", "Anton", "Alex", "Boris", "Victor", "Eugene"] +names: list[str] = [ + "Arthur", + "Anton", + "Alex", + "Boris", + "Victor", + "Eugene", +] a_names_var: list[str] = [] for name in names: @@ -198,8 +205,10 @@ lower_names: list[str] = [name.lower() for name in names] lower_names -replace_name: list[str] = [name if name != "Victor" else "Vlad" for name in names] -replace_name +# + +# replace_name: list[str] = +# ["Vlad" if name == "Victor" else name for name in names] +# replace_name # + lemmatized: list[str] = [ @@ -272,7 +281,12 @@ # # + -shopping_dict: dict[str, int] = {"cucumber": 3, "tomato": 2, "onion": 1, "potato": 2} +shopping_dict: dict[str, int] = { + "cucumber": 3, + "tomato": 2, + "onion": 1, + "potato": 2, +} for item in shopping_dict.items(): print(item) @@ -294,7 +308,14 @@ # # + -names_list: list[str] = ["Arthur", "Anton", "Alex", "Boris", "Victor", "Eugene"] +names_list: list[str] = [ + "Arthur", + "Anton", + "Alex", + "Boris", + "Victor", + "Eugene", +] income: list[int] = [97000, 110000, 95000, 84000, 140000, 120000] zip(names_list, income) From 3abfa778f846ba4d14aea056b966ffcf0fc9d5d0 Mon Sep 17 00:00:00 2001 From: Dayal Date: Wed, 10 Dec 2025 22:41:20 +0300 Subject: [PATCH 24/24] style: fix formatting for pre-commit --- python_issue/makarov/chapter_7_lists_tuples_and_sets.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python_issue/makarov/chapter_7_lists_tuples_and_sets.py b/python_issue/makarov/chapter_7_lists_tuples_and_sets.py index a1dbca29..7784ae54 100644 --- a/python_issue/makarov/chapter_7_lists_tuples_and_sets.py +++ b/python_issue/makarov/chapter_7_lists_tuples_and_sets.py @@ -55,7 +55,6 @@ # - days_list[:5:2] - "Mon" in days_list if "Tue" in days_list: