├── 1.Import.Module.Package └── README.md ├── 2.Iterators.Generators.Yield └── README.md ├── 3.Decorators └── README.md ├── 4.Tests ├── README.md └── src │ └── app.py ├── 5.Regexp ├── README.md └── phonebook_raw.csv ├── 6.Web-scrapping ├── README.md └── preview.png ├── 7.Interview ├── PEP8.md └── README.md └── README.md /1.Import.Module.Package/README.md: -------------------------------------------------------------------------------- 1 | # Домашнее задание к лекции 1. «Import. Module. Package» 1. Разработать **структуру** программы «Бухгалтерия»: - main.py; - application/salary.py; - application/db/people.py. Main.py — основной модуль для запуска программы. В модуле salary.py функция calculate_salary. В модуле people.py функция get_employees. 2. Импортировать функции в модуль main.py и вызывать эти функции в конструкции. ``` if __name__ == '__main__': ``` **Сами функции реализовывать не нужно**. Достаточно добавить туда какой-либо вывод. 3. Познакомиться с модулем [datetime](https://pythonworld.ru/moduli/modul-datetime.html). При вызове функций модуля main.py выводить текущую дату. 4. Найти интересный для себя пакет на [pypi](https://pypi.org/) и в файле requirements.txt указать его с актуальной версией. При желании можно написать программу с этим пакетом. \*5. Создать рядом с файлом main.py модуль dirty_main.py и импортировать все функции с помощью конструкции (необязательное задание). ``` from package.module import * ``` --- Сдайте домашнее задание ссылкой на репозиторий [BitBucket](https://bitbucket.org/) или [GitHub](https://github.com/). Мы не сможем проверить задание, если вы пришлёте: * архивы, * скриншоты кода, * теоретический рассказ о возникших проблемах. -------------------------------------------------------------------------------- /2.Iterators.Generators.Yield/README.md: -------------------------------------------------------------------------------- 1 | # Домашнее задание к лекции 2. «Iterators. Generators. Yield» 1. Доработать класс `FlatIterator` в коде ниже. Должен получиться итератор, который принимает список списков и возвращает их плоское представление, т. е. последовательность, состоящую из вложенных элементов. Функция `test` в коде ниже также должна отработать без ошибок. ```python class FlatIterator: def __init__(self, list_of_list): ... def __iter__(self): ... return self def __next__(self): ... return item def test_1(): list_of_lists_1 = [ ['a', 'b', 'c'], ['d', 'e', 'f', 'h', False], [1, 2, None] ] for flat_iterator_item, check_item in zip( FlatIterator(list_of_lists_1), ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None] ): assert flat_iterator_item == check_item assert list(FlatIterator(list_of_lists_1)) == ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None] if __name__ == '__main__': test_1() ``` 2. Доработать функцию flat_generator. Должен получиться генератор, который принимает список списков и возвращает их плоское представление. Функция `test` в коде ниже также должна отработать без ошибок. ```python import types def flat_generator(list_of_lists): ... yield ... def test_2(): list_of_lists_1 = [ ['a', 'b', 'c'], ['d', 'e', 'f', 'h', False], [1, 2, None] ] for flat_iterator_item, check_item in zip( flat_generator(list_of_lists_1), ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None] ): assert flat_iterator_item == check_item assert list(flat_generator(list_of_lists_1)) == ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None] assert isinstance(flat_generator(list_of_lists_1), types.GeneratorType) if __name__ == '__main__': test_2() ``` 3.__*__ Необязательное задание. Написать итератор, аналогичный итератору из задания 1, но обрабатывающий списки с любым уровнем вложенности. Шаблон и тест в коде ниже: ```python class FlatIterator: def __init__(self, list_of_list): self.list_of_list = list_of_list def __iter__(self): ... return self def __next__(self): ... return item def test_3(): list_of_lists_2 = [ [['a'], ['b', 'c']], ['d', 'e', [['f'], 'h'], False], [1, 2, None, [[[[['!']]]]], []] ] for flat_iterator_item, check_item in zip( FlatIterator(list_of_lists_2), ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None, '!'] ): assert flat_iterator_item == check_item assert list(FlatIterator(list_of_lists_2)) == ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None, '!'] if __name__ == '__main__': test_3() ``` 4.__*__ Необязательное задание. Написать генератор, аналогичный генератору из задания 2, но обрабатывающий списки с любым уровнем вложенности. Шаблон и тест в коде ниже: ```python import types def flat_generator(list_of_list): ... yield ... def test_4(): list_of_lists_2 = [ [['a'], ['b', 'c']], ['d', 'e', [['f'], 'h'], False], [1, 2, None, [[[[['!']]]]], []] ] for flat_iterator_item, check_item in zip( flat_generator(list_of_lists_2), ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None, '!'] ): assert flat_iterator_item == check_item assert list(flat_generator(list_of_lists_2)) == ['a', 'b', 'c', 'd', 'e', 'f', 'h', False, 1, 2, None, '!'] assert isinstance(flat_generator(list_of_lists_2), types.GeneratorType) if __name__ == '__main__': test_4() ``` --- Домашнее задание сдавайте ссылкой на репозиторий [BitBucket](https://bitbucket.org/) или [GitHub](https://github.com/). Мы не сможем проверить, если вы пришлёте: * архивы, * скриншоты кода, * теоретический рассказ о возникших проблемах. -------------------------------------------------------------------------------- /3.Decorators/README.md: -------------------------------------------------------------------------------- 1 | # Домашнее задание к лекции 3. «Decorators» 1. Доработать декоратор `logger` в коде ниже. Должен получиться декоратор, который записывает в файл 'main.log' дату и время вызова функции, имя функции, аргументы, с которыми вызвалась, и возвращаемое значение. Функция `test_1` в коде ниже также должна отработать без ошибок. ```python import os def logger(old_function): ... def new_function(*args, **kwargs): ... return new_function def test_1(): path = 'main.log' if os.path.exists(path): os.remove(path) @logger def hello_world(): return 'Hello World' @logger def summator(a, b=0): return a + b @logger def div(a, b): return a / b assert 'Hello World' == hello_world(), "Функция возвращает 'Hello World'" result = summator(2, 2) assert isinstance(result, int), 'Должно вернуться целое число' assert result == 4, '2 + 2 = 4' result = div(6, 2) assert result == 3, '6 / 2 = 3' assert os.path.exists(path), 'файл main.log должен существовать' summator(4.3, b=2.2) summator(a=0, b=0) with open(path) as log_file: log_file_content = log_file.read() assert 'summator' in log_file_content, 'должно записаться имя функции' for item in (4.3, 2.2, 6.5): assert str(item) in log_file_content, f'{item} должен быть записан в файл' if __name__ == '__main__': test_1() ``` 2. Доработать параметризованный декоратор logger в коде ниже. Должен получиться декоратор, который записывает в файл дату и время вызова функции, имя функции, аргументы, с которыми вызвалась, и возвращаемое значение. Путь к файлу должен передаваться в аргументах декоратора. Функция `test_2` в коде ниже также должна отработать без ошибок. ```python import os def logger(path): ... def __logger(old_function): def new_function(*args, **kwargs): ... return new_function return __logger def test_2(): paths = ('log_1.log', 'log_2.log', 'log_3.log') for path in paths: if os.path.exists(path): os.remove(path) @logger(path) def hello_world(): return 'Hello World' @logger(path) def summator(a, b=0): return a + b @logger(path) def div(a, b): return a / b assert 'Hello World' == hello_world(), "Функция возвращает 'Hello World'" result = summator(2, 2) assert isinstance(result, int), 'Должно вернуться целое число' assert result == 4, '2 + 2 = 4' result = div(6, 2) assert result == 3, '6 / 2 = 3' summator(4.3, b=2.2) for path in paths: assert os.path.exists(path), f'файл {path} должен существовать' with open(path) as log_file: log_file_content = log_file.read() assert 'summator' in log_file_content, 'должно записаться имя функции' for item in (4.3, 2.2, 6.5): assert str(item) in log_file_content, f'{item} должен быть записан в файл' if __name__ == '__main__': test_2() ``` 3. Применить написанный логгер к приложению из любого предыдущего д/з. --- Домашнее задание сдавайте ссылкой на репозиторий [BitBucket](https://bitbucket.org/) или [GitHub](https://github.com/). МЫ не сможем проверить, если вы пришлёте: * архивы, * скриншоты кода, * теоретический рассказ о возникших проблемах. -------------------------------------------------------------------------------- /4.Tests/README.md: -------------------------------------------------------------------------------- 1 | # Домашнее задание к лекции 4. «Tests» ### Задача 1. Unit-tests Из курса «Python: программирование на каждый день и сверхбыстрое прототипирование» нужно протестировать программу по работе с бухгалтерией из [лекции 2.1](https://github.com/netology-code/py-homework-basic/tree/master/2.1.functions). Если у вас есть своё решение этой задачи, можно использовать его или использовать предложенный код в директории src этого задания. * Следует протестировать основные функции по получению информации о документах, добавлении и удалении элементов из словаря. Рекомендации по тестам: 1. Если у вас в функциях информация выводилась (print), то теперь её лучше возвращать (return), чтобы можно было протестировать. 2. Input можно «замокать» с помощью ```unittest.mock.patch```. Если с этим будут проблемы, то лучше переписать функции так, чтобы данные приходили через параметры. ### Задача 2. Автотест API Яндекса Проверим правильность работы Яндекс Диск REST API. Напишите тесты, проверяющие создание папки на Диске. Используя библиотеку requests, напишите unit-test на верный ответ и возможные отрицательные тесты на ответы с ошибкой. Пример положительных тестов: * код ответа соответствует 200; * результат создания папки — папка появилась в списке файлов. ### Задача 3. Не обязательная Применив selenium, напишите unit-test для авторизации на Яндексе по url: https://passport.yandex.ru/auth/. -------------------------------------------------------------------------------- /4.Tests/src/app.py: -------------------------------------------------------------------------------- 1 | documents = [ 2 | {"type": "passport", "number": "2207 876234", "name": "Василий Гупкин"}, 3 | {"type": "invoice", "number": "11-2", "name": "Геннадий Покемонов"}, 4 | {"type": "insurance", "number": "10006", "name": "Аристарх Павлов"} 5 | ] 6 | 7 | directories = { 8 | '1': ['2207 876234', '11-2', '5455 028765'], 9 | '2': ['10006'], 10 | '3': [] 11 | } 12 | 13 | 14 | def check_document_existance(user_doc_number): 15 | doc_founded = False 16 | for current_document in documents: 17 | doc_number = current_document['number'] 18 | if doc_number == user_doc_number: 19 | doc_founded = True 20 | break 21 | return doc_founded 22 | 23 | 24 | def get_doc_owner_name(): 25 | user_doc_number = input('Введите номер документа - ') 26 | print() 27 | doc_exist = check_document_existance(user_doc_number) 28 | if doc_exist: 29 | for current_document in documents: 30 | doc_number = current_document['number'] 31 | if doc_number == user_doc_number: 32 | return current_document['name'] 33 | 34 | 35 | def get_all_doc_owners_names(): 36 | users_list = [] 37 | for current_document in documents: 38 | try: 39 | doc_owner_name = current_document['name'] 40 | users_list.append(doc_owner_name) 41 | except KeyError: 42 | pass 43 | return set(users_list) 44 | 45 | 46 | def remove_doc_from_shelf(doc_number): 47 | for directory_number, directory_docs_list in directories.items(): 48 | if doc_number in directory_docs_list: 49 | directory_docs_list.remove(doc_number) 50 | break 51 | 52 | 53 | def add_new_shelf(shelf_number=''): 54 | if not shelf_number: 55 | shelf_number = input('Введите номер полки - ') 56 | if shelf_number not in directories.keys(): 57 | directories[shelf_number] = [] 58 | return shelf_number, True 59 | return shelf_number, False 60 | 61 | 62 | def append_doc_to_shelf(doc_number, shelf_number): 63 | add_new_shelf(shelf_number) 64 | directories[shelf_number].append(doc_number) 65 | 66 | 67 | def delete_doc(): 68 | user_doc_number = input('Введите номер документа - ') 69 | doc_exist = check_document_existance(user_doc_number) 70 | if doc_exist: 71 | for current_document in documents: 72 | doc_number = current_document['number'] 73 | if doc_number == user_doc_number: 74 | documents.remove(current_document) 75 | remove_doc_from_shelf(doc_number) 76 | return doc_number, True 77 | 78 | 79 | def get_doc_shelf(): 80 | user_doc_number = input('Введите номер документа - ') 81 | doc_exist = check_document_existance(user_doc_number) 82 | if doc_exist: 83 | for directory_number, directory_docs_list in directories.items(): 84 | if user_doc_number in directory_docs_list: 85 | return directory_number 86 | 87 | 88 | def move_doc_to_shelf(): 89 | user_doc_number = input('Введите номер документа - ') 90 | user_shelf_number = input('Введите номер полки для перемещения - ') 91 | remove_doc_from_shelf(user_doc_number) 92 | append_doc_to_shelf(user_doc_number, user_shelf_number) 93 | print('Документ номер "{}" был перемещен на полку номер "{}"'.format(user_doc_number, user_shelf_number)) 94 | 95 | 96 | def show_document_info(document): 97 | doc_type = document['type'] 98 | doc_number = document['number'] 99 | doc_owner_name = document['name'] 100 | print('{} "{}" "{}"'.format(doc_type, doc_number, doc_owner_name)) 101 | 102 | 103 | def show_all_docs_info(): 104 | print('Список всех документов:\n') 105 | for current_document in documents: 106 | show_document_info(current_document) 107 | 108 | 109 | def add_new_doc(): 110 | new_doc_number = input('Введите номер документа - ') 111 | new_doc_type = input('Введите тип документа - ') 112 | new_doc_owner_name = input('Введите имя владельца документа- ') 113 | new_doc_shelf_number = input('Введите номер полки для хранения - ') 114 | new_doc = { 115 | "type": new_doc_type, 116 | "number": new_doc_number, 117 | "name": new_doc_owner_name 118 | } 119 | documents.append(new_doc) 120 | append_doc_to_shelf(new_doc_number, new_doc_shelf_number) 121 | return new_doc_shelf_number 122 | 123 | 124 | def secretary_program_start(): 125 | """ 126 | ap - (all people) - команда, которая выводит список всех владельцев документов 127 | p – (people) – команда, которая спросит номер документа и выведет имя человека, которому он принадлежит; 128 | l – (list) – команда, которая выведет список всех документов в формате passport "2207 876234" "Василий Гупкин"; 129 | s – (shelf) – команда, которая спросит номер документа и выведет номер полки, на которой он находится; 130 | a – (add) – команда, которая добавит новый документ в каталог и в перечень полок, спросив его номер, тип, 131 | имя владельца и номер полки, на котором он будет храниться. 132 | d – (delete) – команда, которая спросит номер документа и удалит его из каталога и из перечня полок; 133 | m – (move) – команда, которая спросит номер документа и целевую полку и переместит его с текущей полки на целевую; 134 | as – (add shelf) – команда, которая спросит номер новой полки и добавит ее в перечень; 135 | q - (quit) - команда, которая завершает выполнение программы 136 | """ 137 | print( 138 | 'Вас приветствует программа помошник!\n', 139 | '(Введите help, для просмотра списка поддерживаемых команд)\n' 140 | ) 141 | while True: 142 | user_command = input('Введите команду - ') 143 | if user_command == 'p': 144 | owner_name = get_doc_owner_name() 145 | print('Владелец документа - {}'.format(owner_name)) 146 | elif user_command == 'ap': 147 | uniq_users = get_all_doc_owners_names() 148 | print('Список владельцев документов - {}'.format(uniq_users)) 149 | elif user_command == 'l': 150 | show_all_docs_info() 151 | elif user_command == 's': 152 | directory_number = get_doc_shelf() 153 | print('Документ находится на полке номер {}'.format(directory_number)) 154 | elif user_command == 'a': 155 | print('Добавление нового документа:') 156 | new_doc_shelf_number = add_new_doc() 157 | print('\nНа полку "{}" добавлен новый документ:'.format(new_doc_shelf_number)) 158 | elif user_command == 'd': 159 | doc_number, deleted = delete_doc() 160 | if deleted: 161 | print('Документ с номером "{}" был успешно удален'.format(doc_number)) 162 | elif user_command == 'm': 163 | move_doc_to_shelf() 164 | elif user_command == 'as': 165 | shelf_number, added = add_new_shelf() 166 | if added: 167 | print('Добавлена полка "{}"'.format(shelf_number)) 168 | elif user_command == 'help': 169 | print(secretary_program_start.__doc__) 170 | elif user_command == 'q': 171 | break 172 | 173 | 174 | if __name__ == '__main__': 175 | secretary_program_start() 176 | -------------------------------------------------------------------------------- /5.Regexp/README.md: -------------------------------------------------------------------------------- 1 | # Домашнее задание к лекции 2.2 «Regular expressions» 2 | 3 | Иногда при знакомстве мы записываем контакты в адресную книгу кое-как с мыслью, что "когда-нибудь потом все обязательно поправим". Копируем данные из интернета или из смски. Добавляем людей в разных мессенджерах. В результате получается адресная книга, в которой совершенно невозможно кого-то нормально найти: мешает множество дублей, разная запись одних и тех же имен и телефонов. 4 | 5 | Кейс основан на реальных данных из https://www.nalog.ru/opendata/, https://www.minfin.ru/ru/opendata/ 6 | 7 | Ваша задача: привести в порядок адресную книгу, используя регулярные выражения. 8 | Структура данных будет всегда такая: 9 | `lastname,firstname,surname,organization,position,phone,email` 10 | 11 | Предполагается, что: 12 | * телефон и e-mail у одного человека может быть только один; 13 | * если совпали одновременно Фамилия и Имя, это точно один и тот же человек (даже если не указано его отчество). 14 | 15 | Ваша задача: 16 | 1. Поместить Фамилию, Имя и Отчество человека в поля `lastname`, `firstname` и `surname` соответственно. В записной книжке изначально может быть Ф + ИО, ФИО, а может быть сразу правильно: Ф+И+О. _Подсказка: работайте со срезом списка (три первых элемента) при помощи `" ".join([:2])` и `split(" ")`, регулярки здесь НЕ НУЖНЫ_. 17 | 2. Привести все телефоны в формат +7(999)999-99-99. Если есть добавочный номер, формат будет такой: +7(999)999-99-99 доб.9999. _Подсказка: используйте регулярки для обработки телефонов_. 18 | 3. Объединить все дублирующиеся записи о человеке в одну. _Подсказка: группируйте записи по ФИО (если будет сложно, допускается группировать только по ФИ)_. 19 | 20 | ```python 21 | from pprint import pprint 22 | # читаем адресную книгу в формате CSV в список contacts_list 23 | import csv 24 | with open("phonebook_raw.csv", encoding="utf-8") as f: 25 | rows = csv.reader(f, delimiter=",") 26 | contacts_list = list(rows) 27 | pprint(contacts_list) 28 | 29 | # TODO 1: выполните пункты 1-3 ДЗ 30 | # ваш код 31 | 32 | # TODO 2: сохраните получившиеся данные в другой файл 33 | # код для записи файла в формате CSV 34 | with open("phonebook.csv", "w", encoding="utf-8") as f: 35 | datawriter = csv.writer(f, delimiter=',') 36 | # Вместо contacts_list подставьте свой список 37 | datawriter.writerows(contacts_list) 38 | ``` 39 | 40 | --- 41 | Домашнее задание сдавайте ссылкой на репозиторий [BitBucket](https://bitbucket.org/) или [GitHub](https://github.com/). 42 | 43 | Мы не сможем проверить, если вы пришлёте: 44 | 45 | * архивы, 46 | * скриншоты кода, 47 | * теоретический рассказ о возникших проблемах. 48 | 49 | -------------------------------------------------------------------------------- /5.Regexp/phonebook_raw.csv: -------------------------------------------------------------------------------- 1 | lastname,firstname,surname,organization,position,phone,email 2 | Усольцев Олег Валентинович,,,ФНС,главный специалист – эксперт отдела взаимодействия с федеральными органами власти Управления налогообложения имущества и доходов физических лиц,+7 (495) 913-04-78,opendata@nalog.ru 3 | Мартиняхин Виталий Геннадьевич,,,ФНС,,+74959130037, 4 | Наркаев,Вячеслав Рифхатович,,ФНС,,8 495-913-0168, 5 | Мартиняхин,Виталий,Геннадьевич,ФНС,cоветник отдела Интернет проектов Управления информационных технологий,, 6 | Лукина Ольга,,Владимировна,Минфин,,+7 (495) 983-36-99 доб. 2926,Olga.Lukina@minfin.ru 7 | Паньшин Алексей Владимирович,,,Минфин,,8(495)748-49-73,1248@minfin.ru 8 | Лагунцов Иван Алексеевич,,,Минфин,,+7 (495) 913-11-11 (доб. 0792), 9 | Лагунцов Иван,,,,,,Ivan.Laguntcov@minfin.ru 10 | Лукина,Оксана,Владимировна,Минфин,,+7 (495) 983-36-99 доб. 2929,OLukina@minfin.ru 11 | -------------------------------------------------------------------------------- /6.Web-scrapping/README.md: -------------------------------------------------------------------------------- 1 | # Домашнее задание к лекции 6. «Web-scrapping» Попробуем получать интересующие нас статьи на [Хабре](https://habr.com) самыми первыми. Нужно парсить страницу со свежими статьями ([вот эту](https://habr.com/ru/all/)) и выбирать те статьи, в которых встречается хотя бы одно из ключевых слов. Эти слова определяем в начале скрипта. Поиск вести по всей доступной preview-информации, т. е. по информации, доступной с текущей страницы. Выведите в консоль список подходящих статей в формате: <дата> – <заголовок> – <ссылка>. Пример preview: ![](preview.png) Шаблон кода: ```python ## Определяем список ключевых слов: KEYWORDS = ['дизайн', 'фото', 'web', 'python'] ## Ваш код ``` --- ## Дополнительное (необязательное) задание Улучшите скрипт так, чтобы он анализировал не только preview-информацию статьи, но и весь текст статьи целиком. Для этого потребуется получать страницы статей и искать по тексту внутри этой страницы. --- Домашнее задание сдавайте ссылкой на репозиторий [BitBucket](https://bitbucket.org/) или [GitHub](https://github.com/). Мы не сможем проверить, если вы пришлёте: - архивы, - скриншоты кода, - теоретический рассказ о возникших проблемах. -------------------------------------------------------------------------------- /6.Web-scrapping/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netology-code/py-homeworks-advanced/df26f969e60760597fd98fff1c171fa1b0c9b2a8/6.Web-scrapping/preview.png -------------------------------------------------------------------------------- /7.Interview/PEP8.md: -------------------------------------------------------------------------------- 1 | Мы устроились на новую работу. Бывший сотрудник начал разрабатывать модуль для работы с почтой, но не успел доделать его. Код рабочий. Нужно только провести рефакторинг кода. 2 | 3 | 1. Создать класс для работы с почтой; 4 | 2. Создать методы для отправки и получения писем; 5 | 3. Убрать "захардкоженный" код. Все значения должны определяться как аттрибуты класса, либо аргументы методов; 6 | 4. Переменные должны быть названы по стандарту PEP8; 7 | 5. Весь остальной код должен соответствовать стандарту PEP8; 8 | 6. Класс должен инициализироваться в конструкции. 9 | ```python 10 | if __name__ == '__main__' 11 | ``` 12 | 13 | 14 | Скрипт для работы с почтой. 15 | ```python 16 | import email 17 | import smtplib 18 | import imaplib 19 | from email.MIMEText import MIMEText 20 | from email.MIMEMultipart import MIMEMultipart 21 | 22 | 23 | GMAIL_SMTP = "smtp.gmail.com" 24 | GMAIL_IMAP = "imap.gmail.com" 25 | 26 | l = 'login@gmail.com' 27 | passwORD = 'qwerty' 28 | subject = 'Subject' 29 | recipients = ['vasya@email.com', 'petya@email.com'] 30 | message = 'Message' 31 | header = None 32 | 33 | 34 | #send message 35 | msg = MIMEMultipart() 36 | msg['From'] = l 37 | msg['To'] = ', '.join(recipients) 38 | msg['Subject'] = subject 39 | msg.attach(MIMEText(message)) 40 | 41 | ms = smtplib.SMTP(GMAIL_SMTP, 587) 42 | # identify ourselves to smtp gmail client 43 | ms.ehlo() 44 | # secure our email with tls encryption 45 | ms.starttls() 46 | # re-identify ourselves as an encrypted connection 47 | ms.ehlo() 48 | 49 | ms.login(l, passwORD) 50 | ms.sendmail(l, 51 | ms, msg.as_string()) 52 | 53 | ms.quit() 54 | #send end 55 | 56 | 57 | #recieve 58 | mail = imaplib.IMAP4_SSL(GMAIL_IMAP) 59 | mail.login(l, passwORD) 60 | mail.list() 61 | mail.select("inbox") 62 | criterion = '(HEADER Subject "%s")' % header if header else 'ALL' 63 | result, data = mail.uid('search', None, criterion) 64 | assert data[0], 'There are no letters with current header' 65 | latest_email_uid = data[0].split()[-1] 66 | result, data = mail.uid('fetch', latest_email_uid, '(RFC822)') 67 | raw_email = data[0][1] 68 | email_message = email.message_from_string(raw_email) 69 | mail.logout() 70 | #end recieve 71 | 72 | ``` 73 | 74 | 75 | 76 | --- 77 | Домашнее задание сдается ссылкой на репозиторий [BitBucket](https://bitbucket.org/) или [GitHub](https://github.com/) 78 | 79 | Не сможем проверить или помочь, если вы пришлете: 80 | * архивы; 81 | * скриншоты кода; 82 | * теоретический рассказ о возникших проблемах. 83 | -------------------------------------------------------------------------------- /7.Interview/README.md: -------------------------------------------------------------------------------- 1 | # Домашнее задание к лекции 7. «Подготовка к собеседованию» **Стек** — абстрактный тип данных, представляющий список элементов, организованных по принципу *LIFO (англ. last in — first out, «последним пришёл — первым вышел»)*. Чаще всего принцип работы стека сравнивают со стопкой тарелок: чтобы взять вторую сверху, нужно снять верхнюю. Или с магазином в огнестрельном оружии: стрельба начнётся с патрона, заряженного последним. 1. Нужно реализовать класс Stack со следующими методами: - is_empty — проверка стека на пустоту. Метод возвращает True или False; - push — добавляет новый элемент на вершину стека. Метод ничего не возвращает; - pop — удаляет верхний элемент стека. Стек изменяется. Метод возвращает верхний элемент стека; - peek — возвращает верхний элемент стека, но не удаляет его. Стек не меняется; - size — возвращает количество элементов в стеке. 2. Используя стек из задания 1, решите задачу на проверку сбалансированности скобок. Сбалансированность скобок означает, что каждый открывающий символ имеет соответствующий ему закрывающий, и пары скобок правильно вложены друг в друга. Пример сбалансированных последовательностей скобок: - ```(((([{}]))))``` - ```[([])((([[[]]])))]{()}``` - ```{{[()]}}``` Несбалансированные последовательности: - ```}{}``` - ```{{[(])]}}``` - ```[[{())}]``` Программа ожидает на вход строку со скобками. На выход сообщение: «Сбалансированно», если строка корректная, и «Несбалансированно», если строка составлена неверно. \*3. [Рефакторинг кода (необязательное задание)](PEP8.md). Задачи, которые помогут подговиться к собеседованиям, можно найти на ресурсах: - [leetcode](https://leetcode.com/), - [checkio](https://checkio.org/). --- Домашнее задание сдавайте ссылкой на репозиторий [BitBucket](https://bitbucket.org/) или [GitHub](https://github.com/). Мы не сможем проверить, если вы пришлёте: - архивы, - скриншоты кода, - теоретический рассказ о возникших проблемах. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Домашние задания на курсе «Продвинутый Python» 2 | 3 | ## Профессиональная работа с Python. 4 | 1. [Import. Module. Package](1.Import.Module.Package/) 5 | 2. [Iterators. Generators. Yield](2.Iterators.Generators.Yield/) 6 | 3. [Decorators](3.Decorators/) 7 | 8 | ## Применение Python на практике. 9 | 4. [Tests](4.Tests/) 10 | 5. [Regular expressions](5.Regexp/) 11 | 6. [Web-scrapping](6.Web-scrapping/) 12 | 7. [Подготовка к собеседованию](7.Interview/) --------------------------------------------------------------------------------