├── .gitignore ├── chatbot ├── __init__.py ├── main.py ├── requirements.txt ├── screenshots │ ├── Screenshot at 2019-07-15 21-33-28.png │ └── Screenshot at 2019-07-15 21-33-37.png └── tests │ ├── __init__.py │ └── test_vk_bot.py ├── lesson_001 ├── 01_os_info.py ├── 02_screeshot_pycharm.txt ├── 03_three_commits.txt ├── __init__.py ├── os_info.txt └── red_hat │ ├── 01_jorney_begin.txt │ ├── 02_unexpected_meet.txt │ ├── 03_murder.txt │ ├── 04_second_victim.txt │ └── 05_retribution.txt ├── lesson_002 ├── 00_distance.py ├── 01_circle.py ├── 02_operations.py ├── 03_favorite_movies.py ├── 04_my_family.py ├── 05_zoo.py ├── 06_songs_list.py ├── 07_secret.py ├── 08_garden.py ├── 09_shopping.py ├── 10_store.py └── __init__.py ├── lesson_003 ├── 00_bubbles.py ├── 01_days_in_month.py ├── 02_envelop.py ├── 03_division.py ├── 04_student.py ├── 05_store.py ├── 06_rainbow.py ├── 07_wall.py ├── 08_smile.py ├── 09_resolve_conflicts.txt ├── __init__.py ├── examples │ ├── 05_rainbow_01.jpg │ ├── 05_rainbow_02.jpg │ ├── 06_wall.jpg │ └── 07_smile.jpg └── lecture_snippets │ ├── 01_execution_flow.py │ ├── 02_if.py │ ├── 03_code_style.py │ ├── 04_while.py │ ├── 05_for.py │ └── 06_functions.py ├── lesson_004 ├── 02_global_color.py ├── 03_shape_select.py ├── 04_fractal.py ├── 05_snowfall.py ├── __init__.py ├── lecture_snippets │ ├── 01_scope.py │ ├── 02_calls_and_defaults.py │ ├── 03_arbitrary_params.py │ ├── 04_recursion.py │ └── 05_builtin.py ├── practice │ ├── 01_triangle.py │ ├── 02_fractal.py │ └── 02_snowflake.py ├── results │ ├── exercise_01_shapes.jpg │ ├── exercise_02_global_color.jpg │ ├── exercise_03_shape_select.jpg │ ├── exercise_04_fractal_01.jpg │ └── exercise_04_fractal_02.jpg └── shapes.py ├── lesson_005 ├── 01_inhabitants.py ├── 02_district.py ├── 03_burger.py ├── 04_painting.py ├── __init__.py ├── district │ ├── __init__.py │ ├── central_street │ │ ├── __init__.py │ │ ├── house1 │ │ │ ├── __init__.py │ │ │ ├── room1.py │ │ │ └── room2.py │ │ └── house2 │ │ │ ├── __init__.py │ │ │ ├── room1.py │ │ │ └── room2.py │ └── soviet_street │ │ ├── __init__.py │ │ ├── house1 │ │ ├── __init__.py │ │ ├── room1.py │ │ └── room2.py │ │ └── house2 │ │ ├── __init__.py │ │ ├── room1.py │ │ └── room2.py ├── my_burger.py ├── painting │ ├── __init__.py │ ├── building.py │ ├── rainbow.py │ ├── smile.py │ ├── snowfall.py │ ├── sun.py │ ├── tree.py │ └── wall.py ├── python_snippets │ ├── 01_modules.py │ ├── 02_imports.py │ ├── 03_pyc_files.py │ ├── 04_packages.py │ ├── module_1.py │ ├── module_2.py │ ├── module_3.py │ ├── my_math.py │ └── package_1 │ │ ├── __init__.py │ │ ├── module_1.py │ │ ├── module_3.py │ │ └── subpackage │ │ ├── __init__.py │ │ ├── module_2.py │ │ └── module_4.py ├── results │ └── 04_painting.jpg ├── room_1.py └── room_2.py ├── lesson_006 ├── 01_mastermind.py ├── 02_snowfall_module.py ├── __init__.py ├── mastermind_engine.py ├── python_snippets │ ├── 01_namespace.py │ ├── 02_scope.py │ ├── 03_practice_faqs.py │ ├── 04_practice.py │ ├── __init__.py │ ├── math.py │ ├── module_1.py │ └── nim_engine.py └── snowfall.py ├── lesson_007 ├── 01_snowfall.py ├── 02_alchemy.py ├── 03_man_ans_cat.py ├── __init__.py └── python_snippets │ ├── 01_objects_and_classes.py │ ├── 02_attrs_and_methods.py │ ├── 03_self_param.py │ ├── 04_special_methods.py │ ├── 05_operator_overloading.py │ ├── 06_class_attrs.py │ ├── 07_class_namespace.py │ └── 08_practice.py ├── lesson_008 ├── 01_family.py ├── __init__.py └── python_snippets │ ├── 01_inheritance.py │ ├── 02_parent_attrs.py │ ├── 03_redefinition.py │ ├── 04_super.py │ ├── 05_multiple_inheritance.py │ ├── 06_theory.py │ └── 07_practice.py ├── lesson_009 ├── .gitignore ├── 01_char_stat.py ├── 02_log_parser.py ├── 03_files_arrange.py ├── __init__.py ├── events.txt ├── icons.zip └── python_snippets │ ├── 01_strings_and_bytes.py │ ├── 02_files.py │ ├── 03_file_seek.py │ ├── 04_file_usage.py │ ├── 05_files_in_OS.py │ ├── 06_format.py │ ├── 07_practice.py │ ├── byron.txt │ ├── pushkin.txt │ ├── pushkin_cp1251.txt │ └── voyna-i-mir.txt.zip ├── lesson_010 ├── 01_fifth_element.py ├── 02_groundhog_day.py ├── 03_registration_log.py ├── __init__.py ├── python_snippets │ ├── 01_exception.py │ ├── 02_try_except.py │ ├── 03_raise.py │ ├── 04_libs_exceptions.py │ ├── 05_warnings.py │ ├── 06_practice.py │ ├── __init__.py │ └── calc.txt └── registrations.txt ├── lesson_011 ├── 01_shapes.py ├── 02_prime_numbers.py ├── 03_log_parser.py ├── 04_error_log_decorator.py ├── __init__.py ├── events.txt └── python_snippets │ ├── 01_functional_style.py │ ├── 02_def_on_fly.py │ ├── 03_comprehensions.py │ ├── 04_iterators.py │ ├── 05_generators.py │ ├── 06_decorators.py │ ├── 06_decorators_adv.py │ ├── 07_libs_and_recipes.py │ ├── 08_practice_1.py │ ├── 08_practice_2.py │ ├── __init__.py │ └── calc.txt ├── lesson_012 ├── .gitignore ├── 01_volatility.py ├── 02_volatility_with_threads.py ├── 03_volatility_with_processes.py ├── __init__.py ├── python_snippets │ ├── 01_parallel_computing.py │ ├── 02_threads.py │ ├── 03_locks.py │ ├── 04_queues.py │ ├── 05_processes.py │ ├── 06_practice.py │ ├── 06_practice_02.py │ ├── 06_practice_03.py │ ├── __init__.py │ ├── extractor.py │ └── utils.py └── utils.py ├── lesson_013 ├── 01_ticket.py ├── __init__.py ├── font │ └── ofont.ru_Franklin Gothic Medium Cond.ttf ├── images │ ├── ticket_sample.png │ └── ticket_template.png ├── python_snippets │ ├── 01_python_package_index.py │ ├── 02_virtualenvs.py │ ├── 03_several_pythons.py │ ├── 04_introspection.py │ ├── 05_lib_usage.py │ ├── 06_practice.py │ ├── __init__.py │ ├── fonts │ │ └── ofont_ru_DS Eraser2.ttf │ └── post_card.jpg └── requirements.txt ├── lesson_014 ├── 01_score.py ├── __init__.py ├── bowling.py ├── python_snippets │ ├── 01_debugging.py │ ├── 02_tests_intro.py │ ├── 03_writing_tests.py │ ├── 04_logging.py │ ├── 05_practice.py │ ├── __init__.py │ ├── family.py │ ├── handling_external_data.py │ ├── my_sort.py │ ├── primes.py │ ├── primes_package │ │ ├── __init__.py │ │ ├── log_settings.py │ │ ├── main.py │ │ └── primes.py │ ├── test_my_sort.py │ └── tests │ │ ├── 01_debugging.py │ │ ├── 02_tests_intro.py │ │ ├── 03_writing_tests.py │ │ ├── 04_logging.py │ │ ├── 05_practice.py │ │ ├── __init__.py │ │ ├── test_child.py │ │ ├── test_handling_external_data.py │ │ ├── test_my_sort.py │ │ └── test_wife.py └── tests │ ├── __init__.py │ └── test_complex.py ├── lesson_015 ├── 01_dungeon.py ├── __init__.py ├── python_snippets │ ├── 01_decimal.py │ ├── 02_date_and_time.py │ ├── 03_regexp.py │ ├── 04_csv.py │ ├── 05_json.py │ ├── 06_practice.py │ ├── __init__.py │ └── external_data │ │ ├── Andys_goods.txt │ │ ├── Bond.json │ │ ├── BondByMonth.csv │ │ ├── BondDetail.csv │ │ ├── Dom#2.json │ │ ├── Dom.json │ │ ├── Indiana_stash.csv │ │ ├── Randalls_money.txt │ │ ├── Tools for archaeological excavations.csv │ │ ├── demo.xml │ │ ├── houses.csv │ │ ├── json_todos.json │ │ ├── json_todos_formatted.json │ │ └── yaml_example.yaml └── rpg.json └── lesson_016 ├── 01_weather.py ├── __init__.py ├── db ├── __init__.py └── models.py ├── python_snippets ├── 01_network.py ├── 02_parsing.py ├── 03_images.py ├── 04_databases.py ├── 05_practice.py ├── __init__.py └── external_data │ ├── Mustached.db │ ├── Northwind.sl3 │ ├── fonts │ └── Aller Cyrillic.ttf │ ├── girl.jpg │ ├── haarcascade_frontalface_default.xml │ ├── many_faces.png │ ├── mm_andy.jpg │ ├── mm_cropped.jpg │ ├── mm_effects.jpg │ ├── mm_paste.jpg │ ├── mm_resize_rotate.jpg │ ├── music.db │ ├── photos │ ├── 0bmFUg4BDepQDQu-.jpg │ ├── 11e260bb-e48d-4505-8.png │ ├── 1Group_21.png │ ├── 1Icon.png │ ├── 1Mask_Group.png │ ├── 1R.png │ ├── 1skillbox.png │ ├── 70365621.gif │ ├── 76249.jpg │ ├── Diplom.png │ ├── G8g3oMCuUKKfjDDy.png │ ├── Group.png │ ├── Group.svg │ ├── Group_191.svg │ ├── Group_199_1.svg │ ├── Group_21.png │ ├── Group_4.png │ ├── Group_931.png │ ├── Group_932.png │ ├── Group_933.png │ ├── Group_934.png │ ├── Icon.png │ ├── KY6TJB0bJplcmjBv.JPG │ ├── Label.png │ ├── Mask_Group.png │ ├── Play_button.png │ ├── R.png │ ├── Shape.svg │ ├── _.png │ ├── _Python-.png │ ├── css-27ed92378a434e4c.png │ ├── diploma_computer1.png │ ├── efwsegf.gif │ ├── face.svg │ ├── fb.png │ ├── feec3fe7e8589b6c1d02.jpg │ ├── image_2.png │ ├── instagram_1_.svg │ ├── javascript-11a1e6401.png │ ├── logo.svg │ ├── noun_995397_cc_1-1.png │ ├── noun_995397_cc_1.png │ ├── rostelekom.png │ ├── skillbox.png │ ├── skillbox.svg │ ├── telegram_2_.svg │ ├── upload-8d532ba0-f2e9.png │ ├── user.svg │ ├── vk.svg │ ├── vtb-na-shapku.jpg │ └── xml-71b14942886ab4b1.png │ ├── photos_results │ ├── 1Mask_Group.png │ ├── Mask_Group.png │ ├── diploma_computer1.png │ ├── image_2.png │ └── upload-8d532ba0-f2e9.png │ ├── probe.jpg │ ├── spidyquotes │ ├── scrapy.cfg │ └── spidyquotes │ │ ├── __init__.py │ │ ├── items.py │ │ ├── middlewares.py │ │ ├── pipelines.py │ │ ├── settings.py │ │ └── spiders │ │ ├── __init__.py │ │ └── spidy.py │ └── weather_img │ ├── cloud.jpg │ ├── rain.jpg │ ├── snow.jpg │ └── sun.jpg └── weather_cards ├── -weather-report-png-1200_630.png ├── CLOUD.jpg ├── RAIN.jpg ├── SNOW.jpg └── SUN.jpg /chatbot/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/chatbot/__init__.py -------------------------------------------------------------------------------- /chatbot/main.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import vk_api 3 | from vk_api.bot_longpoll import VkBotEventType, VkBotLongPoll 4 | from vk_api.utils import get_random_id 5 | 6 | try: 7 | from config import TOKEN, GROUP_ID 8 | except ImportError: 9 | exit('DO cp config.txt config.default.txt') 10 | 11 | 12 | def log_settings(log): 13 | fh_formatter = logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s', datefmt='%m-%d-%Y %H:%M:%S') 14 | fh = logging.FileHandler(filename='vkBot.log', delay=True) 15 | fh.setLevel(level=logging.WARNING) 16 | fh.setFormatter(fh_formatter) 17 | 18 | sh_formatter = logging.Formatter(fmt='%(levelname)s: %(message)s', datefmt='%m-%d-%Y %H:%M:%S') 19 | sh = logging.StreamHandler() 20 | sh.setLevel(level=logging.WARNING) 21 | sh.setFormatter(sh_formatter) 22 | 23 | log.setLevel(logging.DEBUG) 24 | log.addHandler(fh) 25 | log.addHandler(sh) 26 | 27 | 28 | class Bot: 29 | ''' 30 | Эхо Бот 31 | ''' 32 | 33 | def __init__(self, token, group_id): 34 | self.log = logging.getLogger('vkBot') 35 | log_settings(self.log) 36 | 37 | self.token = token 38 | self.group_id = group_id 39 | self.vk = vk_api.VkApi(token=token) 40 | self.longpoll = VkBotLongPoll(vk=self.vk, group_id=self.group_id) 41 | self.api = self.vk.get_api() 42 | 43 | def start(self): 44 | self.log.info('Бот запущен.') 45 | for event in self.longpoll.listen(): 46 | try: 47 | self.on_event(event) 48 | except Exception as exc: 49 | self.log.exception(f'ошибка {exc}') 50 | 51 | def on_event(self, event: VkBotEventType): 52 | ''' 53 | Событие при получении сообщения 54 | :param event: VkBotMessageEvent 55 | :return: None 56 | ''' 57 | if event.type == VkBotEventType.MESSAGE_NEW: 58 | self.log.info('Бот получил сообщение %s', event.object.text) 59 | self.api.messages.send(message=event.object.text, 60 | random_id=get_random_id(), 61 | peer_id=event.object.peer_id) 62 | else: 63 | self.log.warning('Я ещё не умею работать с данными методами %s', event.type) 64 | 65 | 66 | if __name__ == '__main__': 67 | bot = Bot(token=TOKEN, group_id=GROUP_ID) 68 | bot.start() 69 | 70 | # Оставил тудушки в файле requirements - их надо поправить к следующему дз тогда. 71 | # а так зачет! 72 | -------------------------------------------------------------------------------- /chatbot/requirements.txt: -------------------------------------------------------------------------------- 1 | vk-api==11.5.0 -------------------------------------------------------------------------------- /chatbot/screenshots/Screenshot at 2019-07-15 21-33-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/chatbot/screenshots/Screenshot at 2019-07-15 21-33-28.png -------------------------------------------------------------------------------- /chatbot/screenshots/Screenshot at 2019-07-15 21-33-37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/chatbot/screenshots/Screenshot at 2019-07-15 21-33-37.png -------------------------------------------------------------------------------- /chatbot/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/chatbot/tests/__init__.py -------------------------------------------------------------------------------- /chatbot/tests/test_vk_bot.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from unittest.mock import Mock, patch, ANY 3 | 4 | from vk_api.bot_longpoll import VkBotMessageEvent, VkBotEventType 5 | 6 | from ..main import Bot 7 | 8 | 9 | class TestBot(unittest.TestCase): 10 | RAW_EVENT = {'type': VkBotEventType.MESSAGE_NEW, 11 | 'object': {'date': 1565551500, 'from_id': 4145622, 'id': 194, 'out': 0, 'peer_id': 4145622, 12 | 'text': 'test', 'conversation_message_id': 194, 'fwd_messages': [], 'important': False, 13 | 'random_id': 0, 'attachments': [], 'is_hidden': False}, 14 | 'group_id': 184332451} 15 | 16 | def test_bot_start(self): 17 | count = 5 18 | obj = [{'a': 1}] 19 | events = [obj] * count 20 | 21 | long_poller_mock = Mock(return_value=events) 22 | long_poller_listen_mock = Mock() 23 | long_poller_listen_mock.listen = long_poller_mock 24 | 25 | with patch('main.vk_api.VkApi'), patch('main.VkBotLongPoll', return_value=long_poller_listen_mock): 26 | bot = Bot('', '') 27 | bot.on_event = Mock() 28 | bot.start() 29 | 30 | bot.on_event.assert_called() 31 | bot.on_event.assert_any_call(obj) 32 | assert bot.on_event.call_count == count 33 | 34 | def test_on_event(self): 35 | event = VkBotMessageEvent(raw=self.RAW_EVENT) 36 | 37 | send_mock = Mock() 38 | 39 | with patch('main.vk_api.VkApi'), patch('main.VkBotLongPoll'): 40 | bot = Bot('', '') 41 | bot.api = Mock() 42 | bot.api.messages.send = send_mock 43 | 44 | bot.on_event(event) 45 | 46 | send_mock.assert_called_once_with(message=self.RAW_EVENT['object']['text'], 47 | random_id=ANY, 48 | peer_id=self.RAW_EVENT['object']['peer_id']) 49 | 50 | # зачет! -------------------------------------------------------------------------------- /lesson_001/01_os_info.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Нужно собрать информацию об операционной системе и версии пайтона 4 | 5 | import platform 6 | import sys 7 | 8 | info = 'OS info is \n{}\n\nPython version is {} {}'.format( 9 | platform.uname(), sys.version, platform.architecture()) 10 | print(info) 11 | 12 | with open('os_info.txt', 'w', encoding='utf8') as ff: 13 | ff.write(info) 14 | 15 | # Зачет! -------------------------------------------------------------------------------- /lesson_001/02_screeshot_pycharm.txt: -------------------------------------------------------------------------------- 1 | # Необходимо сделать скриншот экрана с работающим PyCharm. 2 | # Для скриншотов желательно использовать сервис joxi.ru 3 | # (или аналогичный, позволяющий делиться ссылками на скриншоты) 4 | 5 | # В PyCharm должен быть открыт файл 01_os_info.py 6 | # а внизу виден результат выполнения этого файла. 7 | 8 | https://yadi.sk/i/YxRMR27O6uJR_g 9 | 10 | # Зачет! -------------------------------------------------------------------------------- /lesson_001/03_three_commits.txt: -------------------------------------------------------------------------------- 1 | # Привести сказку про Красную шапочку (файлы в директории lesson_001/red_hat) к нормальному виду за 3 коммита 2 | # Обратите внимание что в один коммит попадает несколько файлов. 3 | 4 | # WARNING для знающих git: БЕЗ веток/реквестов/етс. Да, все коммият в мастер, да на производстве так не делают. 5 | # Это задание для начинающих, мы изучаем git с минимальным порогом входа - все методики будут потом. 6 | # Знающие, не выпендривайтесь, а покажите что вы знаете основы. Если не хватает драйва, делайте все в консоли ;) 7 | 8 | ########################################################################################## 9 | # ВНИМАНИЕ! После того как __ВСЯ__ домашняя работа сделана и запушена на сервер, # 10 | # нужно зайти в ЛМС (LMS - Learning Management System ) по адресу http://go.skillbox.ru # 11 | # и оформить попытку сдачи ДЗ! Без этого ДЗ не будет проверяться! # 12 | # Как оформить попытку сдачи смотрите видео - https://youtu.be/qVpN0L-C3LU # 13 | ########################################################################################## 14 | 15 | # Зачет! -------------------------------------------------------------------------------- /lesson_001/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_001/os_info.txt: -------------------------------------------------------------------------------- 1 | OS info is 2 | uname_result(system='Linux', node='MintComp', release='4.15.0-43-generic', version='#46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018', machine='x86_64', processor='x86_64') 3 | 4 | Python version is 3.7.1 (default, Oct 22 2018, 11:21:55) 5 | [GCC 8.2.0] ('64bit', 'ELF') -------------------------------------------------------------------------------- /lesson_001/red_hat/01_jorney_begin.txt: -------------------------------------------------------------------------------- 1 | Жила-была маленькая девочка. Мать любила ее без памяти, а бабушка еще больше. 2 | Ко дню рождения внучки подарила ей бабушка красную шапочку. 3 | С тех пор девочка всюду в ней ходила. Соседи так про нее и говорили: 4 | - Вот Красная Шапочка идет! 5 | Как-то раз испекла мама пирожок и сказала дочке: 6 | - Сходи-ка, Красная Шапочка, к бабушке, снеси ей пирожок и горшочек масла 7 | да узнай, здорова ли она. 8 | Собралась Красная Шапочка и пошла к бабушке. 9 | -------------------------------------------------------------------------------- /lesson_001/red_hat/02_unexpected_meet.txt: -------------------------------------------------------------------------------- 1 | Идет она лесом, а навстречу ей - серый Волк. 2 | - Куда ты идешь. Красная Шапочка? - спрашивает Волк. 3 | - Иду к бабушке и несу ей пирожок и горшочек масла. 4 | - А далеко живет твоя бабушка? 5 | - Далеко, - отвечает Красная Шапочка. - Вон в той деревне, за мельницей, в первом домике с края. 6 | - Ладно, - говорит Волк, - я тоже хочу проведать твою бабушку. Я по этой дороге пойду, 7 | а ты ступай по той. Посмотрим, кто из нас раньше придет. 8 | Сказал это Волк и побежал, что было духу, по самой короткой дорожке. 9 | -------------------------------------------------------------------------------- /lesson_001/red_hat/03_murder.txt: -------------------------------------------------------------------------------- 1 | А Красная Шапочка пошла по самой длинной дороге. Шла она не торопясь, по пути останавливалась, 2 | рвала цветы и собирала в букеты. Не успела она еще до мельницы дойти, а Волк 3 | уже прискакал к бабушкиному домику и стучится в дверь: 4 | Тук-тук! 5 | - Кто там? - спрашивает бабушка. 6 | -Это я, внучка ваша, Красная Шапочка, - отвечает Волк, - я к вам в гости пришла, 7 | пирожок принесла и горшочек масла. 8 | А бабушка была в то время больна и лежала в постели. Она подумала, 9 | что это и в самом деле Красная Шапочка, и крикнула: 10 | - Дерни за веревочку, дитя мое, дверь и откроется! 11 | Волк дернул за веревочку - дверь и открылась. 12 | Бросился Волк на бабушку и разом проглотил ее. Он был очень голоден, 13 | потому что три дня ничего не ел. Потом закрыл дверь, 14 | улегся на бабушкину постель и стал поджидать Красная Шапочка. 15 | -------------------------------------------------------------------------------- /lesson_001/red_hat/04_second_victim.txt: -------------------------------------------------------------------------------- 1 | Скоро она пришла и постучалась: 2 | Тук-тук! 3 | - Кто там? - спрашивает Волк. А голос у него грубый, хриплый. 4 | Красная Шапочка испугалась было, но потом подумала, что бабушка охрипла от простуды, и ответила: 5 | - Это я, внучка ваша. Принесла вам пирожок и горшочек масла! 6 | Волк откашлялся и сказал потоньше: 7 | - Дерни за веревочку, дитя мое, дверь и откроется. 8 | Красная Шапочка дернула за веревочку - дверь и открылась. Вошла девочка в домик, 9 | а Волк спрятался под одеяло и говорит: 10 | - Положи-ка, внучка, пирожок на стол, горшочек на полку поставь, а сама приляг рядом со мной! 11 | Красная Шапочка прилегла рядом с Волком и спрашивает: 12 | - Бабушка, почему у вас такие большие руки? 13 | - Это чтобы покрепче обнять тебя, дитя мое. 14 | - Бабушка, почему у вас такие большие уши? 15 | - Чтобы лучше слышать, дитя мое. 16 | - Бабушка, почему у вас такие большие глаза? 17 | - Чтобы лучше видеть, дитя мое. 18 | - Бабушка, почему у вас такие большие зубы? 19 | - А это чтоб скорее съесть тебя, дитя мое! 20 | Не успела Красная Шапочка и охнуть, как Волк бросился на нее и проглотил. -------------------------------------------------------------------------------- /lesson_001/red_hat/05_retribution.txt: -------------------------------------------------------------------------------- 1 | Но, по счастью, в это время проходили мимо домика дровосеки с топорами на плечах. 2 | Услышали они шум, вбежали в домик и убили Волка. А потом распороли ему брюхо, 3 | и оттуда вышла Красная Шапочка, а за ней и бабушка - обе целые и невредимые. -------------------------------------------------------------------------------- /lesson_002/00_distance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Есть словарь координат городов 5 | 6 | sites = { 7 | 'Moscow': (550, 370), 8 | 'London': (510, 510), 9 | 'Paris': (480, 480), 10 | } 11 | 12 | # Составим словарь словарей расстояний между ними 13 | # расстояние на координатной сетке - корень из (x1 - x2) ** 2 + (y1 - y2) ** 2 14 | 15 | distances = {} 16 | 17 | distances = {'Moscow': {'London': round(((sites['Moscow'][0] - sites['London'][0]) ** 2 18 | + (sites['Moscow'][1] - sites['London'][1]) ** 2) ** 0.5 19 | , 2), 20 | 'Paris': round(((sites['Moscow'][0] - sites['Paris'][0]) ** 2 21 | + (sites['Moscow'][1] - sites['Paris'][1]) ** 2) ** 0.5 22 | , 2), 23 | }, 24 | 'London': {'Moscow': round(((sites['London'][0] - sites['Moscow'][0]) ** 2 25 | + (sites['London'][1] - sites['Moscow'][1]) ** 2) ** 0.5 26 | , 2), 27 | 28 | 'Paris': round(((sites['London'][0] - sites['Paris'][0]) ** 2 29 | + (sites['London'][1] - sites['Paris'][1]) ** 2) ** 0.5 30 | , 2), 31 | }, 32 | 33 | 'Paris': {'Moscow': round(((sites['Paris'][0] - sites['Moscow'][0]) ** 2 34 | + (sites['Paris'][1] - sites['Moscow'][1]) ** 2) ** 0.5 35 | , 2), 36 | 37 | 'London': round(((sites['Paris'][0] - sites['London'][0]) ** 2 38 | + (sites['Paris'][1] - sites['London'][1]) ** 2) ** 0.5 39 | , 2), 40 | } 41 | } 42 | 43 | print(distances) 44 | 45 | # Зачет! -------------------------------------------------------------------------------- /lesson_002/01_circle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Есть значение радиуса круга 5 | radius = 42 6 | 7 | # Выведите на консоль значение прощади этого круга с точностю до 4-х знаков после запятой 8 | # подсказки: 9 | # формулу можно подсмотреть в интернете, 10 | # пи возьмите равным 3.1415926 11 | # точность указывается в функции round() 12 | 13 | pi = 3.1415926 14 | print(round(pi*radius**2,4)) 15 | 16 | # Далее, пусть есть координаты точки 17 | point = (23, 34) 18 | 19 | # где 23 - координата х, 34 - координата у 20 | 21 | # Еслт точка point лежит внутри того самого круга (radius = 42), то выведите на консоль True, 22 | # Или False, если точка лежит вовне круга. 23 | # подсказки: 24 | # нужно определить расстояние от этой точки до начала координат (0, 0) 25 | # формула так же есть в интернете 26 | # квадратный корень - это возведение в степень 0.5 27 | # операции сравнения дают булевы константы True и False 28 | 29 | distance = round(((0-point[0])**2+(0-point[1])**2)**0.5, 2) 30 | print(distance <= radius) 31 | 32 | 33 | # Аналогично для другой точки 34 | point_2 = (30, 30) 35 | # Если точка point_2 лежит внутри круга (radius = 42), то выведите на консоль True, 36 | # Или False, если точка лежит вовне круга. 37 | 38 | distance = round(((0-point_2[0])**2+(0-point_2[1])**2)**0.5, 2) 39 | print(distance <= radius) 40 | 41 | 42 | # Пример вывода на консоль: 43 | # 44 | # 77777.7777 45 | # False 46 | # False 47 | 48 | 49 | # Зачет! -------------------------------------------------------------------------------- /lesson_002/02_operations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Расставьте знаки операций "плюс", "минус", "умножение" (другие использовать нельзя!) и скобки 5 | # между числами "1 2 3 4 5" так, что бы получилось число "25". Порядок чисел нужно сохранить. 6 | 7 | # Пример для чисел "1 2 3" и "9" 8 | result = (1 + 2) * 3 9 | print(result) 10 | 11 | result =(((1 * 2) + 3) * 4) + 5 12 | print(result) 13 | 14 | # Зачет! -------------------------------------------------------------------------------- /lesson_002/03_favorite_movies.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Есть строка с перечислением фильмов 5 | 6 | my_favorite_movies = 'Терминатор, Пятый элемент, Аватар, Чужие, Назад в будущее' 7 | 8 | # Выведите на консоль с помощью индексации строки, последовательно: 9 | # первый фильм 10 | # последний 11 | # второй 12 | # второй с конца 13 | 14 | # Переопределять my_favorite_movies и использовать .split() нельзя. 15 | # Запятая не должна выводиться. 16 | 17 | print(my_favorite_movies[0:10]) 18 | print(my_favorite_movies[-15:]) 19 | print(my_favorite_movies[12:25]) 20 | print(my_favorite_movies[-22:-17]) 21 | 22 | # Зачет! -------------------------------------------------------------------------------- /lesson_002/04_my_family.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Создайте списки: 5 | 6 | # моя семья (минимум 3 элемента, есть еще дедушки и бабушки, если что) 7 | my_family = ['мама', 'папа', 'жена', 'дочь'] 8 | 9 | 10 | # список списков приблизителного роста членов вашей семьи 11 | my_family_height = [ 12 | # ['имя', рост], 13 | ['Люда',160], 14 | ['Игорь',170], 15 | ['Марина',176], 16 | ['Анна',90] 17 | ] 18 | 19 | # Выведите на консоль рост отца в формате 20 | # Рост отца - ХХ см 21 | 22 | print('Рост: '+my_family[1]+' -', my_family_height[1][1],'см.') 23 | 24 | # Выведите на консоль общий рост вашей семьи как сумму ростов всех членов 25 | # Общий рост моей семьи - ХХ см 26 | 27 | sum_height = 0 28 | sum_height += my_family_height[0][1] 29 | sum_height += my_family_height[1][1] 30 | sum_height += my_family_height[2][1] 31 | sum_height += my_family_height[3][1] 32 | 33 | print('Общий рост моей семьи -', sum_height, 'см.') 34 | 35 | # Зачет! -------------------------------------------------------------------------------- /lesson_002/05_zoo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # есть список животных в зоопарке 5 | 6 | zoo = ['lion', 'kangaroo', 'elephant', 'monkey', ] 7 | 8 | # посадите медведя (bear) между львом и кенгуру 9 | # и выведите список на консоль 10 | zoo.insert(2,'bear') 11 | print(zoo) 12 | 13 | # добавьте птиц из списка birds в последние клетки зоопарка 14 | birds = ['rooster', 'ostrich', 'lark', ] 15 | # и выведите список на консоль 16 | zoo.extend(birds) 17 | print(zoo) 18 | 19 | # уберите слона 20 | # и выведите список на консоль 21 | zoo.remove('elephant') 22 | print(zoo) 23 | 24 | # выведите на консоль в какой клетке сидит лев (lion) и жаворонок (lark). 25 | # Номера при выводе должны быть понятны простому человеку, не программисту. 26 | print(zoo.index('lion')+1) 27 | print(zoo.index('lark')+1) 28 | 29 | # Зачет! 30 | 31 | -------------------------------------------------------------------------------- /lesson_002/06_songs_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Есть список песен группы Depeche Mode со временем звучания с точносттю до долей минут 5 | 6 | violator_songs_list = [ 7 | ['World in My Eyes', 4.86], 8 | ['Sweetest Perfection', 4.43], 9 | ['Personal Jesus', 4.56], 10 | ['Halo', 4.9], 11 | ['Waiting for the Night', 6.07], 12 | ['Enjoy the Silence', 4.20], 13 | ['Policy of Truth', 4.76], 14 | ['Blue Dress', 4.29], 15 | ['Clean', 5.83], 16 | ] 17 | 18 | # распечатайте общее время звучания трех песен: 'Halo', 'Enjoy the Silence' и 'Clean' в формате 19 | # Три песни звучат ХХХ минут 20 | # Обратите внимание, что делать много вычислений внутри print() - плохой стиль. 21 | # Лучше заранее вычислить необходимое, а затем в print(xxx, yyy, zzz) 22 | 23 | sum_sound_time = 0 24 | sum_sound_time += violator_songs_list[3][1] 25 | sum_sound_time += violator_songs_list[5][1] 26 | sum_sound_time += violator_songs_list[8][1] 27 | 28 | print('Три песни звучат', round(sum_sound_time, 2), 'минут') 29 | 30 | 31 | # Есть словарь песен группы Depeche Mode 32 | violator_songs_dict = { 33 | 'World in My Eyes': 4.76, 34 | 'Sweetest Perfection': 4.43, 35 | 'Personal Jesus': 4.56, 36 | 'Halo': 4.30, 37 | 'Waiting for the Night': 6.07, 38 | 'Enjoy the Silence': 4.6, 39 | 'Policy of Truth': 4.88, 40 | 'Blue Dress': 4.18, 41 | 'Clean': 5.68, 42 | } 43 | 44 | # распечатайте общее время звучания трех песен: 'Sweetest Perfection', 'Policy of Truth' и 'Blue Dress' 45 | # А другие три песни звучат ХХХ минут 46 | 47 | sum_sound_time = 0 48 | sum_sound_time += violator_songs_dict['Sweetest Perfection'] 49 | sum_sound_time += violator_songs_dict['Policy of Truth'] 50 | sum_sound_time += violator_songs_dict['Blue Dress'] 51 | 52 | print('А другие три песни звучат', round(sum_sound_time, 2), 'минут') 53 | 54 | # Зачет! 55 | -------------------------------------------------------------------------------- /lesson_002/07_secret.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # есть зашифрованное сообщение 5 | 6 | secret_message = [ 7 | 'квевтфпп6щ3стмзалтнмаршгб5длгуча', 8 | 'дьсеы6лц2бане4т64ь4б3ущея6втщл6б', 9 | 'т3пплвце1н3и2кд4лы12чф1ап3бкычаь', 10 | 'ьд5фму3ежородт9г686буиимыкучшсал', 11 | 'бсц59мегщ2лятьаьгенедыв9фк9ехб1а', 12 | ] 13 | 14 | 15 | # ключ к расшифровке: 16 | # первое слово - 4-я буква 17 | # второе слово - буквы с 10 по 13, включительно 18 | # третье слово - буквы с 6 по 15, включительно, через одну 19 | # четвертое слово - буквы с 8 по 13, включительно, в обратном порядке 20 | # пятое слово - буквы с 17 по 21, включительно, в обратном порядке 21 | # 22 | # Требуется задать конкретные индексы, например secret_message[3][12:23:4] 23 | # Если нужны вычисления и разные пробы - делайте это в консоли пайтона, тут нужен только результат 24 | 25 | mes = '' 26 | mes = secret_message[0][3] 27 | print(mes) 28 | mes = secret_message[1][9:13] 29 | print(mes) 30 | mes = secret_message[2][5:15:2] 31 | print(mes) 32 | mes = secret_message[3][12:6:-1] 33 | print(mes) 34 | mes = secret_message[4][20:15:-1] 35 | print(mes) 36 | 37 | # Зачет! -------------------------------------------------------------------------------- /lesson_002/08_garden.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # в саду сорвали цветы 5 | garden = ('ромашка', 'роза', 'одуванчик', 'ромашка', 'гладиолус', 'подсолнух', 'роза', ) 6 | 7 | # на лугу сорвали цветы 8 | meadow = ('клевер', 'одуванчик', 'ромашка', 'клевер', 'мак', 'одуванчик', 'ромашка', ) 9 | 10 | # создайте множество цветов, произрастающих в саду и на лугу 11 | # garden_set = 12 | # meadow_set = 13 | garden_set = set(garden) 14 | meadow_set = set(meadow) 15 | 16 | # выведите на консоль все виды цветов 17 | print(garden_set.union(meadow_set)) 18 | 19 | # выведите на консоль те, которые растут и там и там 20 | print(garden_set & meadow_set) 21 | 22 | # выведите на консоль те, которые растут в саду, но не растут на лугу 23 | print(garden_set.difference(meadow_set)) 24 | 25 | # выведите на консоль те, которые растут на лугу, но не растут в саду 26 | print(meadow_set.difference(garden_set)) 27 | 28 | # Зачет! -------------------------------------------------------------------------------- /lesson_002/09_shopping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Есть словарь магазинов с распродажами 5 | 6 | shops = { 7 | 'ашан': 8 | [ 9 | {'name': 'печенье', 'price': 10.99}, 10 | {'name': 'конфеты', 'price': 34.99}, 11 | {'name': 'карамель', 'price': 45.99}, 12 | {'name': 'пирожное', 'price': 67.99} 13 | ], 14 | 'пятерочка': 15 | [ 16 | {'name': 'печенье', 'price': 9.99}, 17 | {'name': 'конфеты', 'price': 32.99}, 18 | {'name': 'карамель', 'price': 46.99}, 19 | {'name': 'пирожное', 'price': 59.99} 20 | ], 21 | 'магнит': 22 | [ 23 | {'name': 'печенье', 'price': 11.99}, 24 | {'name': 'конфеты', 'price': 30.99}, 25 | {'name': 'карамель', 'price': 41.99}, 26 | {'name': 'пирожное', 'price': 62.99} 27 | ], 28 | } 29 | 30 | # Создайте словарь цен на продкты следующего вида (писать прямо в коде) 31 | sweets = { 32 | 'печенье': [ 33 | {'shop': 'ашан', 'price': 10.99}, 34 | {'shop': 'пятерочка', 'price': 9.99} 35 | ], 36 | 'конфеты': [ 37 | {'shop': 'пятерочка', 'price': 32.99}, 38 | {'shop': 'магнит', 'price': 30.99} 39 | ], 40 | 'карамель': [ 41 | {'shop': 'ашан', 'price': 45.99}, 42 | {'shop': 'магнит', 'price': 41.99} 43 | ], 44 | 'пирожное': [ 45 | {'shop': 'пятерочка', 'price': 59.99}, 46 | {'shop': 'магнит', 'price': 62.99} 47 | ] 48 | } 49 | print(sweets) 50 | # Указать надо только по 2 магазина с минимальными ценами 51 | 52 | # Зачет! 53 | -------------------------------------------------------------------------------- /lesson_002/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_003/00_bubbles.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import random 3 | import time 4 | 5 | import simple_draw as sd 6 | 7 | sd.resolution = (1200, 800) 8 | 9 | 10 | def draw_buble(position, radius=50, step = 5, color=sd.COLOR_GREEN, width=1): 11 | 12 | for y in range(3): 13 | sd.circle(center_position=position, radius=radius, color=color, width=width) 14 | radius += step 15 | 16 | # Нарисовать пузырек - три вложенных окружностей с шагом 5 пикселей 17 | buble_position = sd.get_point(300, 300) 18 | draw_buble(position=buble_position, radius=50) 19 | 20 | time.sleep(1) 21 | sd.clear_screen() 22 | 23 | # Написать функцию рисования пузырька, принммающую 2 (или более) параметра: точка рисовании и шаг 24 | buble_position = sd.get_point(600, 300) 25 | draw_buble(position=buble_position, radius=70, step=10, color=sd.COLOR_RED, width=2) 26 | 27 | time.sleep(1) 28 | sd.clear_screen() 29 | 30 | # Нарисовать 10 пузырьков в ряд 31 | for x in range(100, 1001, 100): 32 | buble_position = sd.get_point(x, 500) 33 | draw_buble(position=buble_position, radius=30, color=sd.COLOR_YELLOW) 34 | 35 | time.sleep(1) 36 | sd.clear_screen() 37 | 38 | # # Нарисовать три ряда по 10 пузырьков 39 | for y in range(100, 301, 100): 40 | for x in range(100, 1001, 100): 41 | buble_position = sd.get_point(x, y) 42 | draw_buble(position=buble_position, radius=30, color=sd.COLOR_WHITE) 43 | 44 | time.sleep(1) 45 | sd.clear_screen() 46 | # # Нарисовать 100 пузырьков в произвольных местах экрана случайными цветами 47 | for _ in range(100): 48 | buble_position = sd.random_point() 49 | step = random.randint(3, 10) 50 | time.sleep(0.1) 51 | draw_buble(position=buble_position, radius=50, step=step, color=sd.random_color(), width=1) 52 | 53 | sd.pause() 54 | 55 | 56 | # Зачет! -------------------------------------------------------------------------------- /lesson_003/01_days_in_month.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # (if/elif/else) 4 | 5 | # По номеру месяца вывести кол-во дней в нем (без указания названия месяца, в феврале 28 дней) 6 | # Результат проверки вывести на консоль 7 | # Если номер месяца некорректен - сообщить об этом 8 | 9 | # Номер месяца получать от пользователя следующим образом 10 | 11 | months_day_count = {'1': 31, 12 | '2': 28, 13 | '3': 31, 14 | '4': 30, 15 | '5': 31, 16 | '6': 30, 17 | '7': 31, 18 | '8': 31, 19 | '9': 30, 20 | '10': 31, 21 | '11': 30, 22 | '12': 31, 23 | } 24 | 25 | 26 | user_input = input("Введите, пожалуйста, номер месяца: ") 27 | if user_input.isdigit(): 28 | month = int(user_input) 29 | 30 | if 1 <= month <= 12: 31 | day_count = months_day_count[user_input] 32 | print('Вы ввели', month) 33 | print('Кол-во дней в месяце:', day_count) 34 | else: 35 | print('Месяца с таким номер не существует.') 36 | else: 37 | print('Необходимо ввести число.') 38 | 39 | # Зачет! -------------------------------------------------------------------------------- /lesson_003/03_division.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # (цикл while) 4 | 5 | # даны целые положительные числа a и b (a > b) 6 | # Определить результат целочисленного деления a на b, с помощью цикла while, 7 | # __НЕ__ используя стандартную операцию целочисленного деления (// и %) 8 | # Формат вывода: 9 | # Целочисленное деление ХХХ на YYY дает ZZZ 10 | 11 | a, b = 179, 37 12 | 13 | i = a 14 | int_div = 0 15 | while i >= 0: 16 | i -= b 17 | if i > 0: 18 | int_div += 1 19 | 20 | print('Целочисленное деление', a, 'на', b, 'дает', int_div) 21 | 22 | # Зачет! -------------------------------------------------------------------------------- /lesson_003/04_student.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # (цикл while) 4 | 5 | # Ежемесячная стипендия студента составляет educational_grant руб., а расходы на проживание превышают стипендию 6 | # и составляют expenses руб. в месяц. Рост цен ежемесячно увеличивает расходы на 3%, кроме первого месяца 7 | # Составьте программу расчета суммы денег, которую необходимо единовременно попросить у родителей, 8 | # чтобы можно было прожить учебный год (10 месяцев), используя только эти деньги и стипендию. 9 | # Формат вывода: 10 | # Студенту надо попросить ХХХ.ХХ рублей 11 | 12 | educational_grant, expenses = 10000, 12000 13 | i = 0 14 | student_income = educational_grant 15 | months_expenses = 0 16 | money_needs = 0 17 | 18 | while i < 10: 19 | 20 | if i == 0: 21 | months_expenses = expenses 22 | elif i >= 1: 23 | months_expenses *= 1.03 24 | i += 1 25 | diference = round(months_expenses-student_income, 2) 26 | money_needs += diference 27 | print('Расходы в', i, 'месяце:', diference, ', Итого за', i, 'мес.:', round(money_needs,2)) 28 | 29 | print('Студенту надо попросить', money_needs, 'рублей') 30 | 31 | # Зачет! -------------------------------------------------------------------------------- /lesson_003/05_store.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Есть словарь кодов товаров 4 | 5 | goods = { 6 | 'Лампа': '12345', 7 | 'Стол': '23456', 8 | 'Диван': '34567', 9 | 'Стул': '45678', 10 | } 11 | 12 | # Есть словарь списков количества товаров на складе. 13 | 14 | store = { 15 | '12345': [ 16 | {'quantity': 27, 'price': 42}, 17 | ], 18 | '23456': [ 19 | {'quantity': 22, 'price': 510}, 20 | {'quantity': 32, 'price': 520}, 21 | ], 22 | '34567': [ 23 | {'quantity': 2, 'price': 1200}, 24 | {'quantity': 1, 'price': 1150}, 25 | ], 26 | '45678': [ 27 | {'quantity': 50, 'price': 100}, 28 | {'quantity': 12, 'price': 95}, 29 | {'quantity': 43, 'price': 97}, 30 | ], 31 | } 32 | 33 | # Рассчитать на какую сумму лежит каждого товара на складе. 34 | # 35 | # Вывести суммарную стоимость каждого товара на складе c помощью циклов 36 | # То есть: всего по лампам, стульям, етс. 37 | # Формат строки вывода: "<товар> - <кол-во> шт, стоимость <общая стоимость> руб" 38 | # 39 | # Алгоритм должен получиться приблизительно такой: 40 | # 41 | # цикл for по товарам с получением кода и названия товара 42 | # инициализация переменных для подсчета количества и стоимости товара 43 | # получение списка на складе по коду товара 44 | # цикл for по списку на складе 45 | # подсчет количества товара 46 | # подсчет стоимости товара 47 | # вывод на консоль количества и стоимости товара на складе 48 | 49 | item_of_goods = [] 50 | 51 | for product_name, product_code in goods.items(): 52 | 53 | product_quantity = 0 54 | product_value = 0 55 | 56 | for position in store[product_code]: 57 | product_quantity += position['quantity'] 58 | product_value += position['quantity'] * position['price'] 59 | 60 | print(product_name, '-', product_quantity, 'шт, стоимость', product_value, 'руб') 61 | 62 | # Зачет! 63 | 64 | -------------------------------------------------------------------------------- /lesson_003/06_rainbow.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # (цикл for) 4 | 5 | import simple_draw as sd 6 | 7 | rainbow_colors = (sd.COLOR_RED, sd.COLOR_ORANGE, sd.COLOR_YELLOW, sd.COLOR_GREEN, 8 | sd.COLOR_CYAN, sd.COLOR_BLUE, sd.COLOR_PURPLE) 9 | 10 | # Нарисовать радугу: 7 линий толщиной 4 с шагом 5 из точки (50, 50) в точку (550, 550) 11 | 12 | step = 0 13 | for color in rainbow_colors: 14 | start_point = sd.get_point(50+step, 50) 15 | end_point = sd.get_point(550+step, 550) 16 | sd.line(start_point=start_point, end_point=end_point, color=color, width=4) 17 | step += 5 18 | 19 | 20 | sd.sleep(3) 21 | # Усложненное задание, делать по желанию. 22 | # Нарисовать радугу дугами от окружности (cсм sd.circle) за нижним краем экрана, 23 | # поэкспериментировать с параметрами, что бы было красиво 24 | 25 | step = 0 26 | for color in rainbow_colors[::-1]: 27 | start_point = sd.get_point(660, -50) 28 | sd.circle(center_position=start_point, radius=500+step, color=color, width=30) 29 | step += 30 30 | 31 | sd.pause() 32 | 33 | # Зачет! -------------------------------------------------------------------------------- /lesson_003/07_wall.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # (цикл for) 4 | import simple_draw as sd 5 | 6 | # Нарисовать стену из кирпичей. Размер кирпича - 100х50 7 | # Использовать вложенные циклы for 8 | 9 | sd.resolution = (800, 800) 10 | sd.background_color = sd.COLOR_DARK_ORANGE 11 | 12 | # размер кирпича 13 | x = 100 14 | y = 50 15 | 16 | half_brick = x // 2 17 | 18 | brick_x_count = sd.resolution[0] // x 19 | brick_y_count = sd.resolution[1] // y 20 | 21 | start_x = 0 22 | start_y = 0 23 | end_x = start_x + x 24 | end_y = start_y + y 25 | 26 | for brick_y in range(brick_y_count): 27 | 28 | # определяем кол-во кирпичей в ряду 29 | if brick_y % 2 == 1: 30 | x_count += 1 31 | else: 32 | x_count = brick_x_count 33 | 34 | for brick_x in range(x_count): 35 | 36 | if brick_y % 2 == 1: 37 | if brick_x == 0: 38 | start_position = sd.get_point(start_x, start_y) 39 | end_position = sd.get_point(end_x-half_brick, end_y) 40 | elif brick_x == x_count-1: 41 | start_position = sd.get_point(start_x-half_brick, start_y) 42 | end_position = sd.get_point(end_x-x, end_y) 43 | else: 44 | start_position = sd.get_point(start_x-half_brick, start_y) 45 | end_position = sd.get_point(end_x-half_brick, end_y) 46 | else: 47 | start_position = sd.get_point(start_x, start_y) 48 | end_position = sd.get_point(end_x, end_y) 49 | 50 | sd.rectangle(left_bottom=start_position, right_top=end_position, color=sd.COLOR_BLACK, width=1) 51 | 52 | # двигаем кирпич по x 53 | start_x += x 54 | end_x += x 55 | 56 | sd.sleep(0.03) 57 | 58 | # возвращаем по х в исходное положение 59 | start_x = 0 60 | end_x = x 61 | 62 | # двигаем кирпич по y 63 | start_y = end_y 64 | end_y += y 65 | 66 | sd.pause() 67 | 68 | # Зачет! -------------------------------------------------------------------------------- /lesson_003/09_resolve_conflicts.txt: -------------------------------------------------------------------------------- 1 | Жили-были старик со старухой. Надумали они как-то испечь колобок. 2 | 3 | Старик старухе и говорит: 4 | — Поди-ка, старуха, по коробу поскреби, по сусеку помети, не наскребешь ли муки на колобок. 5 | 6 | Старуха так и сделала: по коробу поскребла, по сусеку помела и наскребла муки горсти две. 7 | Замесила тесто, скатала колобок, испекла и положило на окошко стынуть. 8 | Скучно стало колобку на окне лежать, он взял да и покатился — с окна на лавку, 9 | с лавки на травку, с травки на дорожку — и дальше по дорожке. 10 | 11 | Катится колобок, а навстречу ему заяц: 12 | — Колобок, колобок, я тебя съем! 13 | — Не ешь меня, заяц, я тебе песенку спою: я колобок, по коробу скребен, по сусеку метен, 14 | я от дедушки ушел, я от бабушки ушел, от тебя, зайца, не хитро уйти! 15 | И покатился колобок дальше — только заяц его и видел! 16 | 17 | Катится колобок, а навстречу ему волк: 18 | — Колобок, колобок, я тебя съем! 19 | — Не ешь меня, волк, я тебе песенку спою: я колобок, по коробу скребен, по сусеку метен, 20 | я от дедушки ушел, я от бабушки ушел, я от зайца ушел, а от тебя, волк, не трудно уйти! 21 | И покатился колобок дальше! 22 | 23 | Катится колобок, а навстречу ему медведь: 24 | — Колобок, колобок, я тебя съем! 25 | — Не съешь, медведь! Я колобок, по коробу скребен, по сусеку метен, 26 | я от дедушки ушел, я от бабушки ушел, я от зайца ушел, я волка ушел и от тебя, медведь, легко уйду! 27 | Медведь только его и видел. 28 | 29 | Катится колобок дальше, а навстречу ему хитрая лиса: 30 | — Здравствуй, колобок! Какой ты румяный, хороший! 31 | 32 | Колобок обрадовался, что его хвалят и запел свою песенку. А лиса и говорит: 33 | — Какая славная песня, только стара я стала, плохо слышу, сядь ко мне на нос да спой еще разок. 34 | 35 | Прыгнул он лисе на нос и запел: я колобок, по коробу скребен, по... 36 | А лиса его — ам! И съела! 37 | 38 | # Зачет! -------------------------------------------------------------------------------- /lesson_003/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_003/examples/05_rainbow_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_003/examples/05_rainbow_01.jpg -------------------------------------------------------------------------------- /lesson_003/examples/05_rainbow_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_003/examples/05_rainbow_02.jpg -------------------------------------------------------------------------------- /lesson_003/examples/06_wall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_003/examples/06_wall.jpg -------------------------------------------------------------------------------- /lesson_003/examples/07_smile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_003/examples/07_smile.jpg -------------------------------------------------------------------------------- /lesson_003/lecture_snippets/01_execution_flow.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Поток выполнения программ 4 | 5 | print('дратути!') 6 | x = 34 7 | y = 43 8 | print(x * y) 9 | print('дотвидания!') 10 | 11 | # Посложнее программа 12 | 13 | print('дратути!') 14 | my_family_height = [ 15 | ['мама', 168], 16 | ['папа', 186], 17 | ['я', 200], 18 | ] 19 | total_height = my_family_height[0][1] 20 | total_height += my_family_height[1][1] 21 | total_height += my_family_height[2][1] 22 | print('Общий рост моей семьи', total_height) 23 | print('дотвидания!') 24 | -------------------------------------------------------------------------------- /lesson_003/lecture_snippets/02_if.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Условный оператор (ветвление потока выполнения) 4 | 5 | # if <условие>: 6 | # <блок кода 1> 7 | 8 | x = 38 9 | 10 | print('дратути!') 11 | if x < 0: 12 | print('Меньше нуля') 13 | print('дотвидания!') 14 | 15 | # операторы сравнения 16 | # > 17 | # < 18 | # >= 19 | # <= 20 | # == 21 | # != 22 | 23 | # группировка условий 24 | # or 25 | # and 26 | # not 27 | 28 | 29 | # примеры 30 | a, b = 10, 5 31 | 32 | if a > b: 33 | print('a > b') 34 | 35 | if a > b and a > 0: 36 | print('успех') 37 | 38 | if (a > b) and (a > 0 or b < 1000): 39 | print('успех') 40 | 41 | if 5 < b and b < 10: 42 | print('успех') 43 | 44 | 45 | # можно сравнивать - числа, строки, списки, вообще - переменные одного типа 46 | 47 | if '34' > '123': 48 | print('успех') 49 | 50 | if '123' > '12': 51 | print('успех') 52 | 53 | if [1, 2] > [1, 1]: 54 | print('успех') 55 | 56 | # что нельзя сравнивать - разные типы 57 | if '6' > 5: 58 | print('успех') 59 | 60 | if [5, 6] > 5: 61 | print('успех') 62 | 63 | # но 64 | if '6' != 5: 65 | print('успех') 66 | 67 | # Блок иначе 68 | # if <условие>: 69 | # <блок кода 1> 70 | # else: 71 | # <блок кода 2> 72 | 73 | x = 38 74 | 75 | print('дратути!') 76 | if x < 0: 77 | print('Меньше нуля') 78 | else: 79 | print('Больше нуля') 80 | print('дотвидания!') 81 | 82 | 83 | # множественный выбор (аналог CASE) 84 | 85 | # if <условие>: 86 | # <блок кода 1> 87 | # elif <условие>: 88 | # <блок кода 2> 89 | # elif <условие>: 90 | # <блок кода 3> 91 | # else: 92 | # <блок кода 4> 93 | 94 | print('дратути!') 95 | if x < 0: 96 | print('Меньше нуля') 97 | elif x == 0: 98 | print('Равно нулю') 99 | elif x == 1: 100 | print('Равно единице') 101 | else: 102 | print('Больше нуля, но не равно единице') 103 | print('дотвидания!') 104 | 105 | # блок кода - может быть много операторов и даже вложенные 106 | print('дратути!') 107 | if x < 0: 108 | print('Меньше нуля') 109 | result = -1 110 | elif x == 0: 111 | print('Равно нулю') 112 | result = 0 113 | elif x == 1: 114 | print('Равно единице') 115 | result = 1 116 | else: 117 | print('Больше нуля, но не равно единице') 118 | if x == 42: 119 | print('Вау!') 120 | result = 42 121 | print('дотвидания!') 122 | 123 | # Трехместное выражение - короткая запись для простого случая 124 | 125 | # if x < 0: 126 | # result = 'Меньше нуля' 127 | # else: 128 | # result = 'Больше нуля' 129 | result = 'Меньше нуля' if x < 0 else 'Больше нуля' 130 | -------------------------------------------------------------------------------- /lesson_003/lecture_snippets/04_while.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Цикл while (повторение части кода) 4 | 5 | # while <условие>: 6 | # <блок кода> 7 | 8 | print('дратути!') 9 | i = 1 10 | while i < 10: 11 | i = i * 2 12 | print(i) 13 | print('дотвидания!') 14 | 15 | # последовательность Фибоначи 1, 1, 2, 3, 5, 8, 13, 21, ... 16 | f1, f2 = 1, 1 17 | while f2 < 1000: 18 | print(f2) 19 | next_f2 = f1 + f2 20 | next_f1 = f2 21 | f1, f2 = next_f1, next_f2 22 | 23 | # else 24 | i = 1 25 | while i < 10: 26 | i *= 2 27 | print(i) 28 | else: 29 | print('i >= 10') 30 | print('дотвиданя!') 31 | 32 | # break 33 | my_pets = ['cat', 'dog', 'hamster'] 34 | i = 0 35 | while i < len(my_pets): 36 | pet = my_pets[i] 37 | print('Проверяем ', pet) 38 | if pet == 'cat': 39 | print('Ура, кот найден!') 40 | i += 1 41 | print('дотвиданя!') 42 | 43 | 44 | # continue 45 | my_pets = ['lion', 'dog', 'skunk', 'hamster', 'cat', 'monkey'] 46 | i = -1 47 | while i < len(my_pets): 48 | i += 1 49 | if i == 2: 50 | continue 51 | pet = my_pets[i] 52 | print('Проверяем ', pet) 53 | if pet == 'cat': 54 | print('Ура, кот найден!') 55 | break 56 | print('дотвиданя!') 57 | 58 | 59 | # else, break and continue - все вместе 60 | f1, f2, count = 0, 1, 0 61 | while f2 < 10000: 62 | count += 1 63 | if count > 27: 64 | print('Итераций больше чем 27. Прерываюсь.') 65 | break 66 | f1, f2 = f2, f1 + f2 67 | if f2 < 1000: 68 | continue 69 | print(f2) 70 | else: 71 | print('Было', count, 'итераций') 72 | 73 | 74 | # корректный ввод пользователя 75 | while True: 76 | user_input = input('Введите 42 >> ') 77 | result = int(user_input) 78 | if result == 42: 79 | print('Спасибо за сотрудничество!') 80 | break 81 | else: 82 | print('Я просил 42, а Вы ввели', result, 'Попробуйте еще раз...') 83 | 84 | 85 | -------------------------------------------------------------------------------- /lesson_004/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_004/lecture_snippets/01_scope.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Пространство имен (namespace) - место где живут переменные 4 | 5 | # Глобальное пространство имен 6 | a, b = 1, 2 7 | print('global:', a+b) 8 | 9 | 10 | def simple(): 11 | print('simple:', a + b) 12 | 13 | 14 | simple() 15 | 16 | 17 | # Локальное пространство - имена локальных в функции переменных 18 | a, b = 1, 2 19 | print('global:', a+b) 20 | 21 | 22 | def simple(): 23 | # Локальное пространство имен имен появляется в момент вызова функции 24 | c, d = 3, 4 25 | print('simple:', c + d) 26 | 27 | 28 | def simple_2(): 29 | # Локальное пространство имен 30 | x, y = 3, 4 31 | print('simple_2:', x + y) 32 | # print('simple_2:', c + d) 33 | 34 | simple() 35 | simple_2() 36 | print('global:', c + d) 37 | 38 | # Операторы управления потоком не создают локального пространства имен 39 | if 2 > 1: 40 | e, f = 5, 6 41 | print('if:', e + f) 42 | # else: 43 | # e, f = 7, 8 44 | print('global:', e + f) 45 | 46 | for elem in [1, 2, 3]: 47 | print('for:', elem) 48 | e, f = 5, 6 49 | print('global:', elem) 50 | print('global:', e + f) 51 | e, f = 0, 0 52 | 53 | 54 | # перекрытие глобальных переменных 55 | a, b = 1, 2 56 | print('global:', a+b) 57 | 58 | 59 | def simple(): 60 | # Локальное пространство имен 61 | a, b = 3, 4 62 | print('simple:', a + b) 63 | 64 | 65 | simple() 66 | print('global', a+b) 67 | 68 | 69 | # Если переменной нет в локальном namespace, то значение берется из глобального namespace 70 | a, b = 1, 2 71 | print('global:', a+b) 72 | 73 | def simple(): 74 | # Локальное пространство имен 75 | b = 4 76 | print('simple:', a + b) 77 | 78 | 79 | simple() 80 | print('global', a+b) 81 | 82 | 83 | # если в функции есть присвоение - это будет локальная переменная 84 | def simple(): 85 | # Локальное пространство имен 86 | print('simple:', a + b) 87 | a = 9 88 | print('simple:', a + b) 89 | 90 | 91 | # параметры - это локальные переменные 92 | def simple_3(a, b): 93 | print('simple:', a + b) 94 | 95 | 96 | a, b = 2, 2 97 | print('global', a+b) 98 | simple_3(a=3, b=4) 99 | 100 | 101 | # будет целый урок посвященный пространствам имен и областям видимости 102 | -------------------------------------------------------------------------------- /lesson_004/lecture_snippets/03_arbitrary_params.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | # Произвольное число параметров 5 | print(1, 2, 3, 4, 5, 56, 6,) 6 | 7 | 8 | # Произвольное число позиционных параметров 9 | def print_them_all_v1(*args): 10 | print('print_them_all_v1') 11 | print('тип args:', type(args)) 12 | print(args) 13 | for i, arg in enumerate(args): 14 | print('позиционный параметр:', i, arg) 15 | 16 | 17 | print_them_all_v1(2, 'привет', 5.6) 18 | 19 | # распаковка 20 | my_favorite_pets = ['lion', 'elephant', 'monkey', 'cat', 'horse'] 21 | print_them_all_v1(my_favorite_pets) 22 | print_them_all_v1(*my_favorite_pets) 23 | 24 | 25 | # Произвольное число именованных параметров 26 | def print_them_all_v2(**kwargs): 27 | print('print_them_all_v2') 28 | print('тип kwargs:', type(kwargs)) 29 | print(kwargs) 30 | for key, value in kwargs.items(): 31 | print('именованный аргумент:', key, '=', value) 32 | 33 | 34 | print_them_all_v2(name='Вася', address='Moscow') 35 | 36 | # распаковка 37 | my_friend = {'name': 'Вася', 'address': 'Moscow', 'age': 25} 38 | print_them_all_v2(**my_friend) 39 | 40 | 41 | # неправильные вызовы 42 | print_them_all_v1(name='Вася', address='Moscow') 43 | print_them_all_v2('Вася', 'Moscow', 25) 44 | 45 | 46 | # Комбинация 47 | def print_them_all_v3(*args, **kwargs): 48 | print('print_them_all_v3') 49 | print('тип args:', type(args)) 50 | print(args) 51 | for i, arg in enumerate(args): 52 | print('позиционный параметр:', i, arg) 53 | print('тип kwargs:', type(kwargs)) 54 | print(kwargs) 55 | for key, value in kwargs.items(): 56 | print('именованный аргумент:', key, '=', value) 57 | 58 | 59 | print_them_all_v3('Вася', 'Moscow', 25) 60 | print_them_all_v3(name='Вася', address='Moscow') 61 | 62 | print_them_all_v3(1000, 'рублей', name='Вася', address='Moscow') 63 | 64 | my_friend = {'name': 'Вася', 'address': 'Moscow'} 65 | print_them_all_v3(1000, 'рублей', **my_friend) 66 | 67 | 68 | # При создании функции можно указывать как обычные параметры, так и произвольные параметры 69 | def print_them_all_v4(a, b=5, *args, **kwargs): 70 | print('print_them_all_v4') 71 | print('a и b:', a, b) 72 | print('тип args:', type(args)) 73 | print(args) 74 | for i, arg in enumerate(args): 75 | print('позиционный параметр:', i, arg) 76 | print('тип kwargs:', type(kwargs)) 77 | print(kwargs) 78 | for key, value in kwargs.items(): 79 | print('именованный аргумент:', key, '=', value) 80 | 81 | 82 | print_them_all_v4(5, 6, 7, 8, cat='мяу!') 83 | print_them_all_v4(5, b=8, cat='мяу!') 84 | print_them_all_v4(5, cat='мяу!', address='Moscow') 85 | 86 | 87 | -------------------------------------------------------------------------------- /lesson_004/lecture_snippets/04_recursion.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Рекурсия - это вызов функцией самой себя 4 | 5 | # Рассмотрим на примере факториала 6 | # факториал N - произведение всех целых от 1 до N 7 | 8 | # например факториал 9 9 | # 9! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 10 | # 9! = 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 11 | # 9! = 9 * (8 * 7 * 6 * 5 * 4 * 3 * 2 * 1) 12 | # 9! = 9 * 8! 13 | # 9! = 9 * factorial(8) 14 | 15 | # факториал 2 16 | # 2! = 2 * factorial(1) 17 | # 1! == 1 18 | 19 | # в общем случае 20 | # N * factorial(N-1) 21 | 22 | 23 | def factorial(n): 24 | if n == 1: 25 | return 1 26 | factorial_n_minus_1 = factorial(n=n - 1) 27 | return n * factorial_n_minus_1 28 | 29 | 30 | print(factorial(9)) 31 | 32 | 33 | # рекурсия часто используется для обхода деревьев 34 | html_dom = { 35 | 'html': { 36 | 'head': { 37 | 'title': 'Колобок', 38 | }, 39 | 'body': { 40 | 'h2': 'Привет!', 41 | 'div': 'Хочешь, я расскажу тебе сказку?', 42 | 'p': 'Жили-были старик со старухой...', 43 | } 44 | } 45 | } 46 | 47 | 48 | def find_element(tree, element_name): 49 | if element_name in tree: 50 | return tree[element_name] 51 | for key, sub_tree in tree.items(): 52 | if isinstance(sub_tree, dict): 53 | result = find_element(tree=sub_tree, element_name=element_name) 54 | if result: 55 | break 56 | else: 57 | result = None 58 | return result 59 | 60 | 61 | res = find_element(tree=html_dom, element_name='title') 62 | print(res) 63 | -------------------------------------------------------------------------------- /lesson_004/practice/01_triangle.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # pip install simple_draw 4 | 5 | import simple_draw as sd 6 | 7 | # нарисовать треугольник из точки (300, 300) с длиной стороны 200 8 | length = 200 9 | point = sd.get_point(300, 300) 10 | 11 | # v1 = sd.get_vector(start_point=point, angle=0, length=200, width=3) 12 | # v1.draw() 13 | # 14 | # v2 = sd.get_vector(start_point=v1.end_point, angle=120, length=200, width=3) 15 | # v2.draw() 16 | # 17 | # v3 = sd.get_vector(start_point=v2.end_point, angle=240, length=200, width=3) 18 | # v3.draw() 19 | 20 | # определить функцию рисования треугольника из заданной точки с заданным наклоном 21 | def triangle(point, angle=0): 22 | v1 = sd.get_vector(start_point=point, angle=angle, length=200, width=3) 23 | v1.draw() 24 | 25 | v2 = sd.get_vector(start_point=v1.end_point, angle=angle + 120, length=200, width=3) 26 | v2.draw() 27 | 28 | v3 = sd.get_vector(start_point=v2.end_point, angle=angle + 240, length=200, width=3) 29 | v3.draw() 30 | 31 | 32 | point_0 = sd.get_point(300, 300) 33 | 34 | for angle in range(0, 361, 30): 35 | triangle(point=point_0, angle=angle) 36 | 37 | sd.pause() 38 | 39 | -------------------------------------------------------------------------------- /lesson_004/practice/02_fractal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | sd.resolution = (600, 800) 6 | 7 | # нарисовать ветку дерева из точки (300, 5) вертикально вверх длиной 100 8 | 9 | point_0 = sd.get_point(300, 5) 10 | 11 | 12 | # сделать функцию рисования ветки из заданной точки, 13 | # заданной длины, с заданным наклоном 14 | # def branch(point, angle, length): 15 | # v1 = sd.get_vector(start_point=point, angle=angle, length=length, width=3) 16 | # v1.draw() 17 | # return v1.end_point 18 | 19 | # angle_0 = 90 20 | # length_0 = 200 21 | # next_point = branch(point=point_0, angle=angle_0, length=length_0) 22 | # next_angle = angle_0 - 30 23 | # next_length = length_0 * .75 24 | # next_point = branch(point=next_point, angle=next_angle, length=next_length) 25 | # next_angle = next_angle - 30 26 | # next_length = next_length * .75 27 | # next_point = branch(point=next_point, angle=next_angle, length=next_length) 28 | 29 | # написать цикл рисования ветвей с постоянным уменьшением длины на 25% и отклонением на 30 градусов 30 | # angle_0 = 90 31 | # length_0 = 200 32 | # 33 | # next_angle = angle_0 34 | # next_length = length_0 35 | # next_point = point_0 36 | # 37 | # while next_length > 1: 38 | # next_point = branch(point=next_point, angle=next_angle, length=next_length) 39 | # next_angle = next_angle - 30 40 | # next_length = next_length * .75 41 | 42 | # сделать функцию branch рекурсивной 43 | 44 | def branch(point, angle, length, delta): 45 | if length < 1: 46 | return 47 | v1 = sd.get_vector(start_point=point, angle=angle, length=length, width=3) 48 | v1.draw() 49 | next_point = v1.end_point 50 | next_angle = angle - delta 51 | next_length = length * .75 52 | branch(point=next_point, angle=next_angle, length=next_length, delta=delta) 53 | 54 | 55 | for delta in range(0, 51, 10): 56 | branch(point=point_0, angle=90, length=150, delta=delta) 57 | for delta in range(-50, 1, 10): 58 | branch(point=point_0, angle=90, length=150, delta=delta) 59 | 60 | 61 | sd.pause() 62 | 63 | -------------------------------------------------------------------------------- /lesson_004/practice/02_snowflake.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | sd.resolution = (1200, 600) 6 | # познакомится с параметрами библиотечной функции рисования снежинки sd.snowflake() 7 | 8 | # sd.snowflake(center=point_0, length=200, factor_a=0.5) 9 | 10 | # реализовать падение одной снежинки 11 | y = 500 12 | x = 100 13 | 14 | y2 = 450 15 | x2 = 150 16 | while True: 17 | sd.clear_screen() 18 | point = sd.get_point(x, y) 19 | sd.snowflake(center=point, length=50) 20 | y -= 10 21 | if y < 50: 22 | break 23 | x = x + 10 24 | 25 | point2 = sd.get_point(x2, y2) 26 | sd.snowflake(center=point2, length=30) 27 | y2 -= 10 28 | if y2 < 50: 29 | break 30 | x2 = x2 + 20 31 | 32 | sd.sleep(0.1) 33 | if sd.user_want_exit(): 34 | break 35 | 36 | # реализовать падение одной снежинки из произвольного места экрана 37 | 38 | # реализовать падение одной снежинки с ветром - смещение в сторону 39 | 40 | 41 | sd.pause() 42 | -------------------------------------------------------------------------------- /lesson_004/results/exercise_01_shapes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_004/results/exercise_01_shapes.jpg -------------------------------------------------------------------------------- /lesson_004/results/exercise_02_global_color.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_004/results/exercise_02_global_color.jpg -------------------------------------------------------------------------------- /lesson_004/results/exercise_03_shape_select.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_004/results/exercise_03_shape_select.jpg -------------------------------------------------------------------------------- /lesson_004/results/exercise_04_fractal_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_004/results/exercise_04_fractal_01.jpg -------------------------------------------------------------------------------- /lesson_004/results/exercise_04_fractal_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_004/results/exercise_04_fractal_02.jpg -------------------------------------------------------------------------------- /lesson_004/shapes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | # Написать функции рисования равносторонних геометрических фигур: 6 | # - треугольника 7 | # - квадрата 8 | # - пятиугольника 9 | # - шестиугольника 10 | # Все функции должны принимать 3 параметра: 11 | # - точка начала рисования 12 | # - угол наклона 13 | # - длина стороны 14 | 15 | # Нарисовать все фигуры 16 | # Выделить общую часть алгоритма рисования в отдельную функцию 17 | # Придумать, как устранить разрыв в начальной точке фигуры 18 | 19 | # Пригодятся функции 20 | # sd.get_point() 21 | # sd.get_vector() 22 | # sd.line() 23 | # Результат решения см lesson_004/results/exercise_01_shapes.jpg 24 | 25 | def draw_figure(start_point, side_count, angle, length): 26 | vector = start_point 27 | angle_step = 360 / side_count 28 | step = angle_step 29 | for side in range(side_count): 30 | if side == 0: 31 | vector = sd.get_vector(start_point=vector, angle=angle, length=length+3) 32 | elif side == side_count-1: 33 | sd.line(vector.end_point, start_point) 34 | break 35 | else: 36 | vector = sd.get_vector(start_point=vector.end_point, angle=angle + step, length=length) 37 | step += angle_step 38 | vector.draw() 39 | 40 | 41 | def draw_triangle(start_point, angle=0, length=100): 42 | side = 3 43 | draw_figure(start_point=start_point, side_count=side, angle=angle, length=length) 44 | 45 | 46 | def draw_quadrate(start_point, angle=0, length=100): 47 | side = 4 48 | draw_figure(start_point=start_point, side_count=side, angle=angle, length=length) 49 | 50 | 51 | def draw_pentagon(start_point, angle=0, length=100): 52 | side = 5 53 | draw_figure(start_point=start_point, side_count=side, angle=angle, length=length) 54 | 55 | 56 | def draw_hexagon(start_point, angle=0, length=100): 57 | side = 6 58 | draw_figure(start_point=start_point, side_count=side, angle=angle, length=length) 59 | 60 | 61 | if __name__ == '__main__': 62 | point = sd.get_point(400, 400) 63 | draw_triangle(start_point=point, angle=20, length=100) 64 | 65 | point = sd.get_point(100, 400) 66 | draw_quadrate(start_point=point, angle=20, length=100) 67 | 68 | point = sd.get_point(400, 100) 69 | draw_pentagon(start_point=point, angle=20, length=100) 70 | 71 | point = sd.get_point(100, 100) 72 | draw_hexagon(start_point=point, angle=20, length=100) 73 | 74 | sd.pause() 75 | 76 | # Зачет! -------------------------------------------------------------------------------- /lesson_005/01_inhabitants.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Вывести на консоль жителей комнат (модули room_1 и room_2) 4 | # Формат: В комнате room_1 живут: ... 5 | 6 | import room_1 as rm1 7 | import room_2 as rm2 8 | 9 | inhabitant = ', '.join(rm1.folks) 10 | print('В комнате room_1 живут:', inhabitant) 11 | inhabitant = ', '.join(rm2.folks) 12 | print('В комнате room_2 живут:', inhabitant) 13 | 14 | # Зачет! -------------------------------------------------------------------------------- /lesson_005/02_district.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Составить список всех живущих на районе и Вывести на консоль через запятую 4 | # Формат вывода: На районе живут ... 5 | # подсказка: для вывода элементов списка через запятую можно использовать функцию строки .join() 6 | # https://docs.python.org/3/library/stdtypes.html#str.join 7 | 8 | from district.central_street.house1 import room1 as central_house1_room1, room2 as central_house1_room2 9 | from district.central_street.house2 import room1 as central_house2_room1, room2 as central_house2_room2 10 | from district.soviet_street.house1 import room1 as soviet_house1_room1, room2 as soviet_house1_room2 11 | from district.soviet_street.house2 import room1 as soviet_house2_room1, room2 as soviet_house2_room2 12 | 13 | 14 | inhabitant = ', ' 15 | my_list = [] 16 | my_list.extend(central_house1_room1.folks) 17 | my_list.extend(central_house1_room2.folks) 18 | my_list.extend(central_house2_room1.folks) 19 | my_list.extend(central_house2_room2.folks) 20 | 21 | my_list.extend(soviet_house1_room1.folks) 22 | my_list.extend(soviet_house1_room2.folks) 23 | my_list.extend(soviet_house2_room1.folks) 24 | my_list.extend(soviet_house2_room2.folks) 25 | 26 | print('На районе живут', inhabitant.join(my_list)) 27 | 28 | # Зачет! -------------------------------------------------------------------------------- /lesson_005/03_burger.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Создать модуль my_burger. В нем определить функции добавления инградиентов: 4 | # - булочки 5 | # - котлеты 6 | # - огурчика 7 | # - помидорчика 8 | # - майонеза 9 | # - сыра 10 | # В каждой функции выводить на консоль что-то вроде "А теперь добавим ..." 11 | 12 | # В этом модуле создать рецепт двойного чизбургера (https://goo.gl/zA3goZ) 13 | # с помощью фукций из my_burger и вывести на консоль. 14 | 15 | # Создать рецепт своего бургера, по вашему вкусу. 16 | # Если не хватает инградиентов - создать соответствующие функции в модуле my_burger 17 | from pprint import pprint 18 | 19 | from my_burger import take_bun, take_chop, take_cucumber, take_tomato, take_mayonnaise, take_ketchup, take_chease 20 | 21 | 22 | def cook_burger(): 23 | 24 | print('\nРецепт двойного чизбургера: \n') 25 | 26 | take_bun() 27 | take_chop() 28 | take_chease() 29 | take_chop() 30 | take_chease() 31 | take_cucumber() 32 | take_tomato() 33 | take_mayonnaise() 34 | take_ketchup() 35 | take_bun() 36 | 37 | 38 | def cook_my_burger(): 39 | 40 | print('\nРецепт любимого бургера: \n ') 41 | take_bun() 42 | take_mayonnaise() 43 | take_chop() 44 | take_chease() 45 | take_cucumber() 46 | take_tomato() 47 | take_ketchup() 48 | take_bun() 49 | 50 | 51 | cook_burger() 52 | cook_my_burger() 53 | 54 | # Зачет! -------------------------------------------------------------------------------- /lesson_005/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/central_street/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/central_street/house1/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/central_street/house1/room1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ['Степан', 'Ярослав', 'Михаил', 'Артём', ] 4 | -------------------------------------------------------------------------------- /lesson_005/district/central_street/house1/room2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ['Ольга Бузова', 'Земфира', 'Гнойный', 'Муммий Тролль', ] 4 | -------------------------------------------------------------------------------- /lesson_005/district/central_street/house2/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/central_street/house2/room1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = [] 4 | -------------------------------------------------------------------------------- /lesson_005/district/central_street/house2/room2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ['Мария', 'Ольга', 'Анна', 'Геннадий', ] 4 | -------------------------------------------------------------------------------- /lesson_005/district/soviet_street/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/soviet_street/house1/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/soviet_street/house1/room1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ['Ван', 'Ли', 'Пенг', 'Сянцзян', 'Хенг', 'Чонгкун', 'Яочуан', 'Ли', ] 4 | -------------------------------------------------------------------------------- /lesson_005/district/soviet_street/house1/room2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ['Владимир Владимирович', 'Дмитрий Анатольевич', ] 4 | -------------------------------------------------------------------------------- /lesson_005/district/soviet_street/house2/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/district/soviet_street/house2/room1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ['Джамшут', 'Равшан', ] 4 | -------------------------------------------------------------------------------- /lesson_005/district/soviet_street/house2/room2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ['Волочкова', 'Чехова', 'Нагиев', 'Джигурда', ] 4 | -------------------------------------------------------------------------------- /lesson_005/my_burger.py: -------------------------------------------------------------------------------- 1 | def take_bun(): 2 | print('Кладем булочку') 3 | 4 | 5 | def take_chop(): 6 | print('Кладем котлетку') 7 | 8 | 9 | def take_cucumber(): 10 | print('Добавляем тоненько нарезанных огурчиков') 11 | 12 | 13 | def take_tomato(): 14 | print('Добавляем слой тоненько нарезанных помидоров') 15 | 16 | 17 | def take_mayonnaise(): 18 | print('Майонез по вкусу') 19 | 20 | 21 | def take_ketchup(): 22 | print('Кечуп по вкусу') 23 | 24 | 25 | def take_chease(): 26 | print('Сверху ломтик сыра') 27 | -------------------------------------------------------------------------------- /lesson_005/painting/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # import simple_draw as sd 3 | # from smile import draw_smile 4 | # 5 | # 6 | # sd.resolution = (800, 800) 7 | # draw_smile.SMILE_SIZE = 50 -------------------------------------------------------------------------------- /lesson_005/painting/rainbow.py: -------------------------------------------------------------------------------- 1 | 2 | import simple_draw as sd 3 | 4 | rainbow_colors = [sd.COLOR_RED, sd.COLOR_ORANGE, sd.COLOR_YELLOW, sd.COLOR_GREEN, 5 | sd.COLOR_CYAN, sd.COLOR_BLUE, sd.COLOR_PURPLE] 6 | 7 | 8 | def draw_line_rainbow(start_x=0, end_x=100): 9 | 10 | step = 0 11 | 12 | for color in rainbow_colors: 13 | start_point = sd.get_point(start_x+step, start_x) 14 | end_point = sd.get_point(end_x+step, end_x) 15 | sd.line(start_point=start_point, end_point=end_point, color=color, width=5) 16 | step += 5 17 | 18 | 19 | def draw_rainbow(x=0, y=0, radius=500, width=6, game_tick=0,): 20 | step = 0 21 | 22 | for num, color in enumerate(rainbow_colors): 23 | 24 | start_point = sd.get_point(x, -y) 25 | sd.circle(center_position=start_point, radius=radius+step, color=color, width=width+1) 26 | step += width 27 | 28 | if game_tick % 3 == 0: 29 | rainbow_colors.append(rainbow_colors[0]) 30 | rainbow_colors.remove(rainbow_colors[0]) 31 | 32 | 33 | if __name__ == '__main__': 34 | 35 | tick = 0 36 | step = 0 37 | 38 | while True: 39 | tick += 1 40 | sd.start_drawing() 41 | step += 5 42 | draw_rainbow(width=10, game_tick=tick) 43 | sd.finish_drawing() 44 | 45 | sd.sleep(0.01) 46 | 47 | if sd.user_want_exit(): 48 | break 49 | 50 | 51 | -------------------------------------------------------------------------------- /lesson_005/painting/sun.py: -------------------------------------------------------------------------------- 1 | import simple_draw as sd 2 | 3 | 4 | tick = 0 5 | sun_start_point = sd.get_point(100, 100) 6 | sun_size_step = 5 7 | 8 | 9 | def draw_sun(start_point, 10 | radius=0, 11 | length=100, 12 | rays_count=9, 13 | move_step=1, 14 | size_step=1, 15 | color=sd.COLOR_YELLOW): 16 | 17 | rays_angle = 360 // rays_count 18 | point = start_point 19 | print(radius) 20 | sd.circle(center_position=point, radius=length, width=0, color=sd.background_color) 21 | 22 | # if point.y < sd.resolution[1]: 23 | next_point = sd.get_point(point.x+move_step, point.y+move_step) 24 | # else: 25 | # next_point = point 26 | 27 | rays_step = rays_angle 28 | 29 | for i in range(0, rays_count): 30 | length_rays = length 31 | if i % sd.random_number(1, 3) == 0: 32 | length_rays = 0 33 | 34 | vector = sd.get_vector(start_point=next_point, angle=rays_step, length= length_rays - size_step, width=2) 35 | rays_step += rays_angle 36 | vector.draw(color=color) 37 | 38 | sd.circle(center_position=next_point, radius=radius + 20 - size_step, width=0, color=sd.background_color) 39 | 40 | sd.circle(center_position=next_point, radius=radius - size_step, width=0, color=color) 41 | 42 | return next_point 43 | 44 | 45 | if __name__ == '__main__': 46 | 47 | while True: 48 | 49 | sd.start_drawing() 50 | tick += 1 51 | 52 | if tick % 5 == 0: 53 | sun_size_step += 2 54 | # sun_size_step = 5 55 | 56 | sun_start_point = draw_sun(start_point=sun_start_point, radius=100, length=200, rays_count=36, 57 | move_step=2, size_step=sun_size_step, color=sd.COLOR_YELLOW) 58 | 59 | sd.sleep(0.05) 60 | sd.finish_drawing() 61 | 62 | if sd.user_want_exit(): 63 | break 64 | -------------------------------------------------------------------------------- /lesson_005/painting/tree.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | sd.resolution = (1200, 800) 6 | 7 | x = 1000 8 | y = 30 9 | root_point = sd.get_point(x, y) 10 | root_angle = 90 11 | root_color = (38, 34, 26) 12 | 13 | 14 | def draw_simetric_branches(point, angle, length=100, set_day=None): 15 | 16 | if length < 10: 17 | return 18 | 19 | vector = sd.get_vector(start_point=point, angle=angle, length=length, width=5) 20 | vector.draw(root_color) 21 | 22 | next_point = vector.end_point 23 | if length < 30: 24 | if set_day == 'morning': 25 | sd.circle(next_point, 7, sd.COLOR_DARK_GREEN, width=0) 26 | sd.circle(next_point, 4, sd.COLOR_WHITE, width=0) 27 | elif set_day == 'afternoon': 28 | sd.circle(next_point, 7, sd.COLOR_DARK_GREEN, width=0) 29 | sd.circle(next_point, 2, sd.COLOR_WHITE, width=0) 30 | elif set_day == 'evening': 31 | sd.circle(next_point, 7, sd.COLOR_DARK_GREEN, width=0) 32 | sd.circle(next_point, 3, sd.COLOR_WHITE, width=0) 33 | else: 34 | sd.circle(next_point, 7, sd.COLOR_WHITE, width=0) 35 | 36 | delta = 30 37 | length *= 0.75 38 | 39 | next_angle = angle - delta 40 | draw_simetric_branches(next_point, next_angle, length, set_day) 41 | 42 | next_angle = angle + delta 43 | draw_simetric_branches(next_point, next_angle, length, set_day) 44 | 45 | 46 | def draw_branches(point, angle, length=100): 47 | if length < 10: 48 | return 49 | 50 | vector = sd.get_vector(start_point=point, angle=angle, length=length, width=2) 51 | vector.draw() 52 | 53 | next_point = vector.end_point 54 | 55 | delta = 30 56 | delta_deviation = delta * 0.4 57 | delta += sd.random_number(-delta_deviation, delta_deviation) 58 | 59 | length = length * 0.75 60 | length_deviation = round(length * 0.2) 61 | length += sd.random_number(0, length_deviation) 62 | length = round(length) 63 | 64 | next_angle = round(angle + delta) 65 | draw_branches(next_point, next_angle, length) 66 | 67 | next_angle = round(angle - delta) 68 | draw_branches(next_point, next_angle, length) 69 | 70 | 71 | if __name__ == '__main__': 72 | 73 | root_point = sd.get_point(1000, 30) 74 | draw_simetric_branches(point=root_point, angle=root_angle, length=70, set_day=True) 75 | 76 | root_point = sd.get_point(500, 30) 77 | draw_branches(point=root_point, angle=root_angle, length=50) 78 | 79 | sd.pause() 80 | 81 | -------------------------------------------------------------------------------- /lesson_005/painting/wall.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | 6 | wall_size = (400, 400) 7 | # sd.resolution = wall_size 8 | # sd.background_color = sd.COLOR_DARK_ORANGE 9 | 10 | # размер кирпича 11 | brick_sizer_x = 40 12 | brick_sizer_y = 20 13 | 14 | half_brick = brick_sizer_x // 2 15 | 16 | 17 | def draw_wall(pos_x=0, pos_y=0): 18 | 19 | brick_x_count = wall_size[0] // brick_sizer_x # sd.resolution[0] // x 20 | brick_y_count = wall_size[1] // brick_sizer_y # sd.resolution[1] // y 21 | x_count = brick_x_count 22 | start_x = pos_x 23 | start_y = pos_y 24 | 25 | for brick_y in range(brick_y_count): 26 | 27 | end_x = start_x + brick_sizer_x 28 | end_y = start_y + brick_sizer_y 29 | 30 | # определяем кол-во кирпичей в ряду 31 | if brick_y % 2 == 1: 32 | x_count += 1 33 | else: 34 | x_count = brick_x_count 35 | 36 | for brick_x in range(x_count): 37 | 38 | if brick_y % 2 == 1: 39 | if brick_x == 0: 40 | start_position = sd.get_point(start_x, start_y) 41 | end_position = sd.get_point(end_x-half_brick, end_y) 42 | elif brick_x == x_count-1: 43 | start_position = sd.get_point(start_x-half_brick, start_y) 44 | end_position = sd.get_point(end_x - brick_sizer_x, end_y) 45 | else: 46 | start_position = sd.get_point(start_x-half_brick, start_y) 47 | end_position = sd.get_point(end_x-half_brick, end_y) 48 | else: 49 | start_position = sd.get_point(start_x, start_y) 50 | end_position = sd.get_point(end_x, end_y) 51 | 52 | sd.rectangle(left_bottom=start_position, right_top=end_position, color=sd.COLOR_DARK_ORANGE, width=0) 53 | sd.rectangle(left_bottom=start_position, right_top=end_position, color=sd.COLOR_BLACK, width=1) 54 | 55 | # двигаем кирпич по x 56 | start_x += brick_sizer_x 57 | end_x += brick_sizer_x 58 | 59 | # sd.sleep(0.03) 60 | 61 | # возвращаем по х в исходное положение 62 | start_x = pos_x 63 | 64 | # двигаем кирпич по y 65 | start_y = end_y 66 | end_y += brick_sizer_y 67 | 68 | 69 | if __name__ == '__main__': 70 | 71 | draw_wall(100, 100) 72 | 73 | sd.pause() 74 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/01_modules.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Модуль — это файл, содержащий определения и выражения на Python. 4 | # Именем файла является имя модуля с добавленным суффиксом .py 5 | # Так распространяется код пайтона - его библиотеки - в простейшем случае 6 | 7 | # Что бы иметь доступ к коду модуля из другого модуля надо его импортировать 8 | import module_1 9 | 10 | # Это действие НЕ переводит имена определённых в модуле переменных в текущее пространство имен, 11 | # в нем появляется лишь имя модуля - module_1. Используя его вы можете получить доступ к коду: 12 | 13 | import module_1 14 | print(module_1.variable_1) 15 | module_1.function1() 16 | 17 | # По факту module_1 - это переменная, указывающая на модуль 18 | # С помощью dir() можно получить список имен, определенных в модуле 19 | import module_1 20 | print(dir(module_1)) 21 | 22 | ### 23 | # При импорте выполняются все операторы python. Если в модуле есть что-то, 24 | # кроме определения переменных и функция (в будущем - классов), 25 | # то этот код выполнится 26 | 27 | import module_2 28 | 29 | 30 | ### 31 | # Внутри модуля, имя модуля (в качестве строки) доступно 32 | # в виде значения глобальной переменной с именем __name__. 33 | 34 | import module_2 35 | 36 | # Когда вы запускаете модуль Python из командной строки 37 | # > python module_3.py 38 | # то код в этом модуле будет исполнен в момент его импортирования, 39 | # но значение __name__ будет установлено как "__main__". 40 | # Это значит, что добавляя этот код в конец сценария: 41 | 42 | if __name__ == "__main__": 43 | print("Меня вызвали!") 44 | 45 | # вы можете сделать возможным запуск файла и в качестве сценария и в качестве импортируемого модуля 46 | 47 | 48 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/02_imports.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Способы импортирования кода 4 | 5 | # Импорт всего модуля как имени в пространство имен текущего модуля 6 | 7 | import module_1 8 | 9 | # Импорт всего модуля с другим именем (синонимом) 10 | import module_1 as first_module 11 | # чаще всего используется для сокращения 12 | # или если в разных библиотеках есть модули с одинаковыми именами 13 | 14 | # Можно импортировать конкретный элемент в пространство имен текущего модуля 15 | from module_1 import function1, variable_1 16 | function1() 17 | print(variable_1) 18 | # При таком импорте все равно выполняется весь пайтон-код импортируемого модуля 19 | 20 | # Можно импортировать конктретный элемент с другим именем (синонимом) 21 | from module_1 import function1 as f1, variable_1 as v1 22 | f1() 23 | print(v1) 24 | # чаще всего используется если в разных модулях есть элементы с одинаковыми именами 25 | 26 | 27 | ### 28 | # Импортировать все имена из модуля в пространство имен текущего модуля 29 | from module_1 import * 30 | # Плохой стиль! потому что получается мешанина из собственных имен и имен в модуле 31 | # и все зависит от того что было определено позже 32 | 33 | 34 | def function1(): 35 | print('Hey!') 36 | 37 | from module_3 import * 38 | 39 | function1() 40 | 41 | 42 | ### 43 | # Python поставляется с библиотекой стандартных модулей 44 | # полный список http://docs.python.org/3/library/index.html 45 | 46 | import math 47 | print(math.sin(90)) 48 | 49 | 50 | ### 51 | # Модули для импорта ищутся в текущем каталоге а затем в каталогах, 52 | # указанных в переменной окружения PYTHONPATH, потом - в директории инсталляции пайтона 53 | 54 | import my_math 55 | print(my_math.cos(90)) 56 | 57 | 58 | # В действительности, поиск модулей производится в списке каталогов, 59 | # передающемся в списке sys.path из модуля sys 60 | 61 | import sys 62 | for path in sys.path: 63 | print(path) 64 | 65 | ### 66 | # Обычно все импорты указываются в начале модуля, но можно импортировать и в коде функций, 67 | # тогда имена из модуля попадают в локальное пространство имен, в глобальном не видны. 68 | # то есть import - вычислимый оператор 69 | 70 | def some_func(): 71 | from math import sin 72 | return sin(0) 73 | 74 | print(some_func()) 75 | print(sin(0)) 76 | # под капотом: импорт выполяется один раз и хранится внутри пайтона, 77 | # замедления при множественном вызове не происходит 78 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/03_pyc_files.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # „Скомпилированные“ файлы Python - .pyc 4 | 5 | # Интерпретатор Python применяет один важный приём для ускорения запуска программы: 6 | # если в каталоге __pycache__, где располагается файл с некоторым модулем spam.py, 7 | # находится также файл spam.pyc, предполагается, что это уже скомпилированная 8 | # в байт-код («byte-compiled») версия модуля spam. В файле spam.pyc зафиксировано 9 | # время изменения файла spam.py версии, использовавшейся для создания spam.pyc. 10 | # Если версии не совпадают — файл .pyc игнорируется. 11 | 12 | # Если сценарий запущен за счёт передачи его имени командной строке, 13 | # > python -m module_1 14 | # его байт-код никогда не будет записан в файл .pyc 15 | 16 | # Можно распространять библиотеки кода Python в том виде, 17 | # из которого трудно восстановить исходный код. 18 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/module_1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | variable_1 = 'Hello!' 4 | 5 | 6 | def function1(): 7 | print('Hey!') 8 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/module_2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | variable_1 = 'Hello!' 4 | 5 | 6 | def function1(): 7 | print('Hey!') 8 | 9 | 10 | print("Всем привет в этом чате!!!1") 11 | 12 | # print("Module name is", __name__) 13 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/module_3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | variable_1 = 'Hello!' 4 | 5 | 6 | def function1(): 7 | print('Hey!') 8 | 9 | 10 | print("Всем привет в этом чате!") 11 | 12 | # print("Module name is", __name__) 13 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/my_math.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | def cos(alpha): 5 | print('Тут должно быть вычисление косинуса', alpha) 6 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/package_1/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | def function3(): 5 | print('Я function3 из package_1/__init__.py') 6 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/package_1/module_1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | def function1(): 5 | print('Я function1 из package_1.module_1') 6 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/package_1/module_3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from .module_1 import function1 4 | 5 | 6 | def function4(): 7 | print('Я function4 из package_1.module_3 вызываю function1') 8 | function1() 9 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/package_1/subpackage/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/package_1/subpackage/module_2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | def function2(): 5 | print('Я function2 из package_1.subpackage.module_2') 6 | 7 | -------------------------------------------------------------------------------- /lesson_005/python_snippets/package_1/subpackage/module_4.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from ..module_1 import function1 4 | 5 | 6 | def function5(): 7 | print('Я function5 из package_1.subpackage.module_4 вызываю function1') 8 | function1() 9 | -------------------------------------------------------------------------------- /lesson_005/results/04_painting.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_005/results/04_painting.jpg -------------------------------------------------------------------------------- /lesson_005/room_1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ["Яна", "Алёна", ] 4 | -------------------------------------------------------------------------------- /lesson_005/room_2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | folks = ["Иннокентий Петрович", ] 4 | -------------------------------------------------------------------------------- /lesson_006/02_snowfall_module.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | # На основе кода из lesson_004/05_snowfall.py 6 | # сделать модуль snowfall.py в котором реализовать следующие функции 7 | # создать_снежинки(N) - создает N снежинок 8 | # нарисовать_снежинки_цветом(color) - отрисовывает все снежинки цветом color 9 | # сдвинуть_снежинки() - сдвигает снежинки на один шаг 10 | # номера_достигших_низа_экрана() - выдает список номеров снежинок, которые вышли за границу экрана 11 | # удалить_снежинки(номера) - удаляет снежинки с номерами из списка 12 | # 13 | # В текущем модуле реализовать главный цикл падения снежинок, 14 | # обращаясь ТОЛЬКО к функциям модуля snowfall 15 | 16 | # создать_снежинки(N) 17 | # нарисовать_снежинки_цветом(color=sd.background_color) 18 | # сдвинуть_снежинки() 19 | # нарисовать_снежинки_цветом(color) 20 | # если есть номера_достигших_низа_экрана() то 21 | # удалить_снежинки(номера) 22 | # создать_снежинки(count) 23 | 24 | from snowfall import create_snowflakes, \ 25 | draw_snowflakes, \ 26 | move_snowflakes, \ 27 | remove_snowflakes, \ 28 | get_down_snowflakes 29 | 30 | snowflakes_count = 5 31 | 32 | create_snowflakes(snowflakes_count=snowflakes_count) 33 | 34 | while True: 35 | 36 | sd.start_drawing() 37 | draw_snowflakes(color=sd.background_color) 38 | move_snowflakes() 39 | draw_snowflakes(color=sd.COLOR_WHITE) 40 | 41 | down_snowflakes = get_down_snowflakes() 42 | 43 | if len(down_snowflakes) > 0: 44 | remove_snowflakes(num_snowflake=down_snowflakes) 45 | create_snowflakes(snowflakes_count=len(down_snowflakes)) 46 | 47 | sd.sleep(0.05) 48 | sd.finish_drawing() 49 | 50 | if sd.user_want_exit(): 51 | break 52 | 53 | # Зачет! -------------------------------------------------------------------------------- /lesson_006/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_006/mastermind_engine.py: -------------------------------------------------------------------------------- 1 | from random import randint as rnd 2 | 3 | _hidden_numbers = [] 4 | 5 | 6 | def generate_number(): 7 | number = [] 8 | for i in range(4): 9 | if i == 0: 10 | number.append(rnd(1, 9)) 11 | else: 12 | number.append(rnd(0, 9)) 13 | return number 14 | 15 | 16 | def make_number(): 17 | _hidden_numbers.clear() 18 | _hidden_numbers.extend(generate_number()) 19 | return _hidden_numbers 20 | 21 | 22 | def check_number(number): 23 | result = {'bulls': 0, 'cows': 0} 24 | chk_numbers = [] 25 | 26 | for char in map(int, number): 27 | chk_numbers.append(char) 28 | 29 | for pos, hidden_number in enumerate(_hidden_numbers): 30 | for chk_pos, number in enumerate(chk_numbers): 31 | if hidden_number == number: 32 | if pos == chk_pos: 33 | result['bulls'] += 1 34 | continue 35 | else: 36 | result['cows'] += 1 37 | 38 | return result 39 | 40 | 41 | if __name__ == '__main__': 42 | make_number() 43 | bull, cow = check_number('1234') 44 | print(bull, cow) 45 | -------------------------------------------------------------------------------- /lesson_006/python_snippets/01_namespace.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Пространство имён (namespace) — это набор связей имён с объектами 4 | # (а под капотом - словарь!) 5 | 6 | # Примеры пространств имён: 7 | # - локальные имена при вызове функции 8 | # - глобальные имена в модуле 9 | # - набор встроенных имён: функций вроде abs() print() 10 | 11 | 12 | ### 13 | # пространство имен текущего модуля 14 | # то что использовали с самого начала и не задумывались 15 | 16 | x = 'GLOBO' 17 | 18 | 19 | def func_1(): 20 | x = 'LOCO' 21 | print('x in f1 =', x) 22 | 23 | 24 | print('x =', x) 25 | 26 | ### 27 | # пространство имен внешнего модуля 28 | 29 | import module_1 30 | 31 | # Доступ к именам происходит через точку после имени пространства имен - имени модуля 32 | # Вообще, когда используется точка, то говорят о доступе к атрибутам обьекта 33 | # У обьекта модуль есть аттрибуты - переменные из его пространства имен 34 | 35 | print(module_1.x) 36 | module_1.func_2() 37 | 38 | ### 39 | # Мы можем добавлять или изменять значения переменных в пространстве имен модуля 40 | 41 | module_1.abc = 'some string' 42 | 43 | module_1.x = 'INJECTO' 44 | 45 | print(module_1.x) 46 | module_1.func_2() 47 | 48 | # И даже удалять! 49 | del x 50 | del module_1.x 51 | module_1.func_2() 52 | 53 | # Такой подход называется манки патчингом (Monkey patch, см. https://goo.gl/yyxnH7) 54 | # Мы у готового модуля что-то меняем внутри и надеемся что он будет работать 55 | # Понятно, что изменения будут сохраняться только в рамках текущего запуска программы, 56 | # в исходниках ничего не меняется 57 | 58 | 59 | ### 60 | # Оператор global указывает что переменная берется из пространства имен текущего модуля 61 | 62 | def func_3(): 63 | global x 64 | x = 'LOCO' 65 | print('x in f1 =', x) 66 | 67 | 68 | # print(x) 69 | func_3() 70 | print(x) 71 | 72 | ### 73 | # globals() - встроенная функция, которая возвращает словарь глобальных имен 74 | 75 | 76 | some_string = 'какая? да никакая! никакусенькая...' 77 | 78 | print(globals()) 79 | 80 | 81 | ### 82 | # locals() - встроенная функция, которая возвращает словарь локального пространства имен 83 | 84 | def func_4(): 85 | x = 'LOCO' 86 | print(locals()) 87 | 88 | 89 | print(globals()) 90 | 91 | func_4() -------------------------------------------------------------------------------- /lesson_006/python_snippets/03_practice_faqs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ########## 4 | import simple_draw as sd 5 | 6 | rainbow_colors = (sd.COLOR_RED, sd.COLOR_ORANGE, sd.COLOR_YELLOW, sd.COLOR_GREEN, 7 | sd.COLOR_CYAN, sd.COLOR_BLUE, sd.COLOR_PURPLE) 8 | 9 | ########## 10 | # Нарисовать радугу: 7 линий толщиной 4 с шагом 5 из точки (50, 50) в точку (550, 550) 11 | 12 | # x, y = 50, 50 13 | # for color in rainbow_colors: 14 | # start_point = sd.get_point(x, y) 15 | # end_point = sd.get_point(x + 500, y + 500) 16 | # sd.line(start_point=start_point, end_point=end_point, color=color, width=4) 17 | # x += 5 18 | 19 | 20 | # width = 4 21 | # step = 5 + width 22 | # for item, x in enumerate(range(50, 50 + step * 7, step)): 23 | # color = rainbow_colors[item] 24 | # sd.line(start_point=sd.get_point(x, 50), end_point=sd.get_point(x + 500, 550), width=width, color=color) 25 | 26 | ########## 27 | # Нарисовать стену из кирпичей. Размер кирпича - 100х50 28 | # использовать вложенные циклы for 29 | 30 | brick_x, brick_y = 200, 50 31 | 32 | row = 0 33 | for y in range(0, sd.resolution[1], brick_y): 34 | row += 1 35 | for x in range(0, sd.resolution[0], brick_x): 36 | x0 = x if row % 2 else x + brick_x // 3 37 | left_bottom = sd.get_point(x0, y) 38 | right_top = sd.get_point(x0 + brick_x, y + brick_y) 39 | sd.rectangle(left_bottom=left_bottom, right_top=right_top, width=1) 40 | 41 | sd.pause() 42 | -------------------------------------------------------------------------------- /lesson_006/python_snippets/04_practice.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | # Ним — математическая игра, в которой два игрока по очереди берут предметы, 5 | # разложенные на несколько кучек. За один ход может быть взято любое количество предметов 6 | # (большее нуля) из одной кучки. Выигрывает игрок, взявший последний предмет. 7 | # В классическом варианте игры число кучек равняется трём. 8 | 9 | # Составить модуль, реализующий функциональность игры. 10 | # Функции управления игрой 11 | # разложить_камни() 12 | # взять_из_кучи(NN, KK) 13 | # положение_камней() - возвращает список [XX, YY, ZZ, ...] - текущее расположение камней 14 | # есть_конец_игры() - возвращает True если больше ходов сделать нельзя 15 | # 16 | # 17 | # В текущем модуле (lesson_006/python_snippets/04_practice.py) реализовать логику работы с пользователем: 18 | # начало игры, 19 | # вывод расположения камней 20 | # ввод первым игроком хода - позицию и кол-во камней 21 | # вывод расположения камней 22 | # ввод вторым игроком хода - позицию и кол-во камней 23 | # вывод расположения камней 24 | 25 | from nim_engine import put_stones, get_bunches, is_gameover, take_from_bunch 26 | from termcolor import cprint, colored 27 | 28 | put_stones() 29 | user_number = 1 30 | while True: 31 | cprint('Текущая позиция', color='green') 32 | cprint(get_bunches(), color='green') 33 | user_color = 'blue' if user_number == 1 else 'yellow' 34 | cprint('Ход игрока {}'.format(user_number), color=user_color) 35 | pos = input(colored('Откуда берем?', color=user_color)) 36 | qua = input(colored('Сколько берем?', color=user_color)) 37 | step_successed = take_from_bunch(position=int(pos), quantity=int(qua)) 38 | if step_successed: 39 | user_number = 2 if user_number == 1 else 1 40 | else: 41 | cprint('Невозможный ход!', color='red') 42 | if is_gameover(): 43 | break 44 | 45 | cprint('Выйграл игрок номер {}'.format(user_number), color='red') -------------------------------------------------------------------------------- /lesson_006/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_006/python_snippets/math.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | def cos(alpha): 5 | print('Тут должно быть вычисление косинуса', alpha) 6 | -------------------------------------------------------------------------------- /lesson_006/python_snippets/module_1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | x = 'MODO' 4 | 5 | 6 | def func_2(): 7 | print('Call module_1.func_2() x =', x) 8 | -------------------------------------------------------------------------------- /lesson_006/python_snippets/nim_engine.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | MAX_BUNCHES = 5 4 | MAX_BUNCHE_SIZE = 20 5 | 6 | _holder = {} 7 | _sorted_keys = None 8 | 9 | 10 | def put_stones(): 11 | """ расположить камни на игровой поверхности """ 12 | global _holder, _sorted_keys 13 | _holder = {} 14 | for i in range(1, MAX_BUNCHES + 1): 15 | _holder[i] = randint(1, MAX_BUNCHE_SIZE) 16 | _sorted_keys = sorted(_holder.keys()) 17 | 18 | 19 | def take_from_bunch(position, quantity): 20 | if position in _holder: 21 | _holder[position] -= quantity 22 | return True 23 | else: 24 | return False 25 | 26 | 27 | def get_bunches(): 28 | res = [] 29 | for key in _sorted_keys: 30 | res.append(_holder[key]) 31 | return res 32 | 33 | 34 | def is_gameover(): 35 | return sum(_holder.values()) == 0 36 | -------------------------------------------------------------------------------- /lesson_006/snowfall.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | sd.resolution = (1200, 800) 6 | snowflake_size = {'min': 5, 'max': 20} 7 | 8 | _snowflakes = {} 9 | _down_snowflakes = [] 10 | 11 | 12 | def create_snowflakes(snowflakes_count=1): 13 | new_snowflakes = {} 14 | y = 700 15 | len_dict = 0 16 | 17 | for key, value in _snowflakes.items(): 18 | new_snowflakes[len_dict] = value 19 | len_dict += 1 20 | 21 | for i in range(snowflakes_count): 22 | new_snowflakes[len_dict + i] = {'length': sd.random_number(snowflake_size['min'], snowflake_size['max']), 23 | 'x': sd.random_number(0, sd.resolution[0]), 24 | 'y': y, 25 | 'factor_a': sd.random_number(1, 10)/10, 26 | 'factor_b': sd.random_number(1, 10)/10, 27 | 'factor_c': sd.random_number(1, 120) 28 | } 29 | 30 | _snowflakes.update(new_snowflakes) 31 | _down_snowflakes.clear() 32 | 33 | 34 | def remove_snowflakes(num_snowflake): 35 | _new_snowflakes = {k: v for k, v in _snowflakes.items() if k not in num_snowflake} 36 | _snowflakes.clear() 37 | _snowflakes.update(_new_snowflakes) 38 | 39 | 40 | def draw_snowflakes(color=sd.COLOR_WHITE): 41 | for snowflake_num, snowflake_parameter in _snowflakes.items(): 42 | start_point = sd.get_point(x=snowflake_parameter['x'], y=snowflake_parameter['y']) 43 | sd.snowflake(center=start_point, 44 | length=snowflake_parameter['length'], 45 | color=color, 46 | factor_a=snowflake_parameter['factor_a'], 47 | factor_b=snowflake_parameter['factor_b'], 48 | factor_c=snowflake_parameter['factor_c']) 49 | 50 | 51 | def move_snowflakes(): 52 | for snowflake_num, snowflake_parameter in _snowflakes.items(): 53 | snowflake_parameter['x'] += sd.random_number(0, 2) 54 | snowflake_parameter['y'] -= snowflake_size['max'] + 1 - snowflake_parameter['length'] 55 | 56 | 57 | def get_down_snowflakes(): 58 | for snowflake_num, snowflake_parameter in _snowflakes.items(): 59 | if snowflake_parameter['y'] < 0: 60 | _down_snowflakes.append(snowflake_num) 61 | 62 | return _down_snowflakes 63 | -------------------------------------------------------------------------------- /lesson_007/01_snowfall.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | 5 | 6 | # Шаг 1: Реализовать падение снежинки через класс. Внести в методы: 7 | # - создание снежинки с нужными параметрами 8 | # - отработку изменений координат 9 | # - отрисовку 10 | 11 | sd.resolution = (1200, 800) 12 | snowflakes = {} 13 | tick = 0 14 | 15 | 16 | class Snowflake: 17 | size = {'min': 5, 'max': 20} 18 | 19 | def __init__(self): 20 | self.length = sd.random_number(Snowflake.size['min'], Snowflake.size['max']) 21 | self.x = sd.random_number(0, sd.resolution[0]) 22 | self.y = sd.randint(sd.resolution[1] - 100, sd.resolution[1] + 100) 23 | self.factor_a = sd.random_number(1, 10) / 10 24 | self.factor_b = sd.random_number(1, 10) / 10 25 | self.factor_c = sd.random_number(1, 120) 26 | 27 | def draw(self, color=sd.COLOR_WHITE): 28 | start_point = sd.get_point(x=self.x, y=self.y) 29 | sd.snowflake(center=start_point, 30 | length=self.length, 31 | color=color, 32 | factor_a=self.factor_a, 33 | factor_b=self.factor_b, 34 | factor_c=self.factor_c) 35 | 36 | def hide(self, color=sd.background_color): 37 | self.draw(color) 38 | 39 | def move(self): 40 | self.x += sd.random_number(0, 2) 41 | self.y -= Snowflake.size['max'] + 1 - self.length 42 | 43 | 44 | def run_snowfall(snowflakes_count=0): 45 | """Запуск снегопада""" 46 | if len(snowflakes) != snowflakes_count: 47 | snowflakes[len(snowflakes)] = Snowflake() 48 | 49 | for num, snowflake in snowflakes.items(): 50 | snowflake.hide() 51 | snowflake.move() 52 | snowflake.draw() 53 | 54 | if snowflake.y < 0: 55 | snowflakes[num] = Snowflake() 56 | 57 | 58 | if __name__ == '__main__': 59 | while True: 60 | tick += 1 61 | sd.start_drawing() 62 | 63 | if tick < 50: 64 | run_snowfall(snowflakes_count=20) 65 | elif tick > 50: 66 | run_snowfall(snowflakes_count=50) 67 | 68 | sd.sleep(0.05) 69 | sd.finish_drawing() 70 | 71 | if sd.user_want_exit(): 72 | break 73 | 74 | # Зачет! -------------------------------------------------------------------------------- /lesson_007/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_007/python_snippets/01_objects_and_classes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Одинаковые объекты описываются одним классом 4 | my_car = Toyota() 5 | 6 | # Объекты имеют свойства, к которым можно доступиться с помощью точки 7 | print(my_car.color) 8 | "Бордовый металлик" 9 | print(my_car.price) 10 | "1 000 000 руб" 11 | print(my_car.max_velocity) 12 | "200 км/ч" 13 | print(my_car.engine_rpm) 14 | 0 15 | print(my_car.current_velocity) 16 | "0 км/ч" 17 | 18 | # Объекты имеют действия, которые с ними можно производить. 19 | # Некоторые свойства объектов могут менятся после действий над объектами 20 | my_car.start() # завели машину 21 | print(my_car.engine_rpm) 22 | 900 23 | my_car.go() # поехали 24 | print(my_car.engine_rpm) 25 | 2000 26 | print(my_car.current_velocity) 27 | "20 км/ч" 28 | 29 | 30 | # В Python свойства называются атрибутами, а действия - методами 31 | # Ссылки на атрибуты и методы используют синтаксис, 32 | # использующийся для всех ссылок на атрибуты в Python: объект.имя. 33 | 34 | 35 | # Простейшая форма определения класса 36 | # class ClassName: 37 | # < выражение - 1 > 38 | # . 39 | # . 40 | # . 41 | # < выражение - N > 42 | 43 | 44 | # например 45 | class Toyota: 46 | 47 | def __init__(self): 48 | self.color = "Бордовый металлик" 49 | self.price = "1 000 000 руб" 50 | self.max_velocity = "200 км/ч" 51 | self.current_velocity = "0 км/ч" 52 | self.engine_rpm = 0 53 | 54 | def start(self): 55 | self.engine_rpm = 5000 56 | 57 | def go(self): 58 | self.current_velocity = "20 км/ч" 59 | 60 | 61 | # Класс - это как лекало для производства объектов. 62 | produced, plan = 0, 10000 63 | stock = [] 64 | while produced < plan: 65 | new_car = Toyota() 66 | stock.append(new_car) 67 | produced += 1 68 | # мы можем произвести сколько угодно объектов 69 | 70 | 71 | # еще пример 72 | class Robot: 73 | """Простой пример класса""" 74 | 75 | def __init__(self): 76 | self.name = 'R2D2' 77 | 78 | def hello(self): 79 | print('привет мир! Я -', self.name) 80 | 81 | 82 | # создаем новый объект (экземпляра класса) 83 | # и присваиваем локальной переменной robot ссылку на него 84 | robot = Robot() 85 | robot.hello() 86 | 87 | # Помним, что переменные только ссылаются на объект 88 | 89 | some_var = robot 90 | some_var.hello() 91 | 92 | some_robot = some_var 93 | some_robot.hello() 94 | 95 | some_robot.name = 'C-3PO' 96 | some_robot.hello() 97 | 98 | robot.hello() 99 | -------------------------------------------------------------------------------- /lesson_007/python_snippets/02_attrs_and_methods.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Атрибуты объекта-экземпляра не нужно описывать — как и переменные, 4 | # они начинают существование в момент первого присваивания 5 | 6 | 7 | class Robot: 8 | 9 | def __init__(self): 10 | self.name = 'R2D2' 11 | 12 | def hello(self): 13 | print('привет мир!') 14 | 15 | 16 | robot = Robot() 17 | robot.temperature = 1 18 | while robot.temperature < 10: 19 | robot.temperature *= 2 20 | print(robot.temperature) 21 | del robot.temperature 22 | 23 | # Атрибуты сохраняются в пространстве имен каждого объекта - у разных объектов они м.б. разные 24 | 25 | robot_2 = Robot() 26 | robot_2.name = 'Валли' 27 | 28 | print(robot.name, robot_2.name) 29 | 30 | print(robot, robot_2) 31 | print(robot == robot_2, robot is robot_2) 32 | 33 | 34 | # Полезные функции для работы с атрибутами 35 | # hasattr(object, name) - проверка существования 36 | # setattr(object, name, value) - установка 37 | # delattr(object, name) - удаление 38 | # name это строка! 39 | 40 | attr_name = 'model' 41 | if hasattr(robot, attr_name): 42 | print(robot.model) 43 | else: 44 | setattr(robot, attr_name, 'android') 45 | print(robot.model) 46 | delattr(robot, attr_name) 47 | 48 | # то есть можно устанавливать атрибуты динамически, по именам 49 | for attr_name in ('weight', 'height', ): 50 | setattr(robot, attr_name, 42) 51 | print(hasattr(robot, 'weight')) 52 | print(robot.weight) 53 | 54 | # getattr(object, name, default=None) - получение атрибута 55 | print(getattr(robot, 'weight')) 56 | print(getattr(robot, 'speed', 10)) 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /lesson_007/python_snippets/03_self_param.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Отличительная особенность методов объектов от простых функций состоит в том, 4 | # что методу всегда передаётся ссылка на объект-экземпляр. 5 | # Эта первый параметр метода и обычно он называется self. 6 | # Название - не более чем соглашение: имя self не имеет абсолютно никакого 7 | # специального смысла для языка Python. Но так принято :) 8 | 9 | 10 | class Backpack: 11 | """ Рюкзак """ 12 | 13 | def add(self, item): 14 | """ Положить в рюкзак """ 15 | print("В рюкзак положили ", item) 16 | self.content = item 17 | 18 | 19 | my_backpack = Backpack() 20 | my_backpack.add(item='ноутбук') 21 | 22 | my_son_backpack = Backpack() 23 | my_son_backpack.add(item='учебник') 24 | 25 | # то есть аналогия такая, что были вызовы типа таких 26 | # add(self=my_backpack, item='ноутбук') 27 | # add(self=my_son_backpack, item='учебник') 28 | 29 | # на самом деле так и есть, просто есть понятие "связанный метод" 30 | # это метод, который привязан к объекту, жестко фиксирован self 31 | print(Backpack.add) 32 | print(my_backpack.add) 33 | 34 | 35 | # то есть следующие два вызова аналогичны 36 | my_backpack.add(item='ноутбук') 37 | Backpack.add(self=my_backpack, item='ноутбук') 38 | 39 | 40 | -------------------------------------------------------------------------------- /lesson_007/python_snippets/06_class_attrs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Аттрибуты могут иметь не только объекты, но и их классы 4 | 5 | from random import randint, choice 6 | 7 | 8 | # посчитаем леммингов 9 | class Lemming: 10 | pass 11 | 12 | 13 | total_lemmings = 0 14 | lemming_1 = Lemming() 15 | total_lemmings += 1 16 | lemming_2 = Lemming() 17 | total_lemmings += 1 18 | lemming_3 = Lemming() 19 | total_lemmings += 1 20 | 21 | family = [] 22 | family_size = randint(16, 32) 23 | while len(family) < family_size: 24 | new_lemming = Lemming() 25 | family.append(new_lemming) 26 | total_lemmings += 1 27 | print(total_lemmings) 28 | 29 | 30 | # пусть сам класс следит за количеством своих объектов 31 | class Lemming: 32 | # можно определять атрибуты на уровне класса, тогда они "привязаны" к классу 33 | total = 0 34 | 35 | def __init__(self): 36 | # обращаться - через именование класса 37 | Lemming.total += 1 38 | 39 | 40 | family = [] 41 | family_size = randint(16, 32) 42 | while len(family) < family_size: 43 | new_lemming = Lemming() 44 | family.append(new_lemming) 45 | print(Lemming.total) 46 | 47 | 48 | # или даже 49 | burrow = [] 50 | burrow_depth = randint(90, 100) 51 | while len(burrow) < burrow_depth: 52 | family = [] 53 | family_size = randint(16, 32) 54 | while len(family) < family_size: 55 | new_lemming = Lemming() 56 | family.append(new_lemming) 57 | burrow.append(family) 58 | print(Lemming.total) 59 | print(burrow) 60 | 61 | 62 | # в аттрибутах класса допустимо любое выражение пайтона 63 | class Lemming: 64 | total, names = 0, ['Peter', 'Anna', 'Nik', 'Sofi', 'Den', 'Lora', 'Bred', ] 65 | names_count = len(names) 66 | some_text = 'Варкалось, хливкие шорьки пырялись по наве...' 67 | some_var = some_text + names[-1] 68 | 69 | def __init__(self): 70 | Lemming.total += 1 71 | self.name = choice(Lemming.names) 72 | 73 | def __str__(self): 74 | return 'Lemming ' + self.name 75 | 76 | def check_class_attrs(self): 77 | print('Lemming.total', Lemming.total) 78 | print('Lemming.names', Lemming.names) 79 | print('Lemming.names_count', Lemming.names_count) 80 | print('Lemming.some_text', Lemming.some_text) 81 | print('Lemming.some_var', Lemming.some_var) 82 | 83 | 84 | new_lemming = Lemming() 85 | print('Lemming.total', Lemming.total) 86 | print('Lemming.names', Lemming.names) 87 | print('Lemming.names_count', Lemming.names_count) 88 | print('Lemming.some_text', Lemming.some_text) 89 | print('Lemming.some_var', Lemming.some_var) 90 | new_lemming.check_class_attrs() 91 | 92 | -------------------------------------------------------------------------------- /lesson_007/python_snippets/07_class_namespace.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from random import randint, choice 4 | 5 | 6 | # К атрибутам класса можно обратится и через объект 7 | class Lemming: 8 | names = ['Peter', 'Anna', 'Nik', 'Sofi', 'Den', 'Lora', 'Bred', ] 9 | tail_length = 20 10 | 11 | def __init__(self): 12 | self.name = choice(Lemming.names) 13 | 14 | def __str__(self): 15 | return 'Lemming ' + self.name + ' with tail ' + str(self.tail_length) 16 | 17 | 18 | print(Lemming.tail_length) 19 | 20 | new_lemming = Lemming() 21 | print(new_lemming.tail_length) 22 | print(new_lemming) 23 | 24 | 25 | # Атрибут объекта перекрывает атрибут класса 26 | class Lemming: 27 | names = ['Peter', 'Anna', 'Nik', 'Sofi', 'Denn', 'Lora', 'Bred', ] 28 | tail_length = 20 29 | 30 | def __init__(self): 31 | self.tail_length = randint(15, 25) 32 | self.name = choice(Lemming.names) 33 | 34 | def __str__(self): 35 | return 'Lemming ' + self.name + ' with tail ' + str(self.tail_length) 36 | 37 | 38 | print(Lemming.tail_length) 39 | 40 | new_lemming = Lemming() 41 | print(new_lemming.tail_length) 42 | print(new_lemming) 43 | 44 | 45 | # типичная ошибка 46 | class Lemming: 47 | names = ['Peter', 'Anna', 'Nik', 'Sofi', 'Denn', 'Lora', 'Bred', ] 48 | total = 0 49 | tail_length = 20 50 | 51 | def __init__(self): 52 | self.tail_length = randint(15, 25) 53 | self.name = choice(Lemming.names) 54 | self.total = self.total + 1 55 | 56 | def __str__(self): 57 | return 'Lemming ' + self.name + ' with tail ' + str(self.tail_length) 58 | 59 | 60 | burrow = [] 61 | burrow_depth = randint(90, 100) 62 | while len(burrow) < burrow_depth: 63 | family = [] 64 | family_size = randint(16, 32) 65 | while len(family) < family_size: 66 | new_lemming = Lemming() 67 | family.append(new_lemming) 68 | burrow.append(family) 69 | print(Lemming.total) 70 | print(len(burrow)) 71 | 72 | 73 | # А что с обычными переменными? все так же как для функций 74 | 75 | 76 | class SomeClass: 77 | 78 | def method_one(self): 79 | # x = 23 80 | print('method_one', x) 81 | 82 | def method_two(self): 83 | # x = 34 84 | def func_one(): 85 | # x = 56 86 | print('func_one', x) 87 | func_one() 88 | print('method_two', x) 89 | 90 | 91 | x = 12 92 | obj = SomeClass() 93 | obj.method_one() 94 | obj.method_two() 95 | print('global', x) 96 | -------------------------------------------------------------------------------- /lesson_008/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_008/python_snippets/02_parent_attrs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Ко всем ли атрибутам родительского класса можно обратиться? 4 | 5 | 6 | class Parent: 7 | class_var_1 = 12 8 | _class_var_2 = 23 9 | __class_var_3 = 34 10 | 11 | def __init__(self): 12 | self.var_1 = 45 13 | self._var_2 = 56 14 | self.__var_3 = 67 15 | 16 | def parent_method(self): 17 | print(self.class_var_1) 18 | print(self._class_var_2) 19 | print(self.__class_var_3) 20 | print(self.var_1) 21 | print(self._var_2) 22 | print(self.__var_3) 23 | 24 | 25 | class Child(Parent): 26 | 27 | def method(self): 28 | print(self.class_var_1) 29 | print(self._class_var_2) 30 | # print(self.__class_var_3) 31 | print(self.var_1) 32 | print(self._var_2) 33 | # print(self.__var_3) 34 | 35 | 36 | obj = Child() 37 | # obj.parent_method() 38 | obj.method() 39 | -------------------------------------------------------------------------------- /lesson_008/python_snippets/03_redefinition.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Переопределение атрибутов объекта и класса 4 | # - используется если у дочернего класса отличные свойства 5 | 6 | 7 | class Cat: 8 | has_tail = True 9 | woolliness = 20 # https://goo.gl/V2NcBf 10 | 11 | def __init__(self, name): 12 | self.name = name 13 | 14 | def __str__(self): 15 | return '{} {} хвост есть? {}, пушистость - {}'.format( 16 | self.__class__.__name__, self.name, self.has_tail, self.woolliness) 17 | 18 | 19 | class Bobtail(Cat): 20 | has_tail = False 21 | 22 | 23 | class Sphinx(Cat): 24 | woolliness = 1 25 | 26 | 27 | murzik = Bobtail(name='Мурзик') 28 | sonya = Sphinx(name='Соня') 29 | print(murzik) 30 | print(sonya) 31 | 32 | 33 | # Переопределение методов 34 | # - используется если у порожденного класса должно отличаться поведение 35 | class Robot: 36 | 37 | def __init__(self, model): 38 | self.model = model 39 | 40 | def __str__(self): 41 | return '{} model {}'.format(self.__class__.__name__, self.model) 42 | 43 | def operate(self): 44 | print('Робот ездит по кругу') 45 | 46 | 47 | class WarRobot(Robot): 48 | 49 | def operate(self): 50 | print('Робот охраняет военный обьект') 51 | 52 | 53 | class VacuumCleaningRobot(Robot): 54 | 55 | def operate(self): 56 | print('Робот пылесосит пол') 57 | 58 | 59 | r2d2 = WarRobot(model='R2D2') 60 | print(r2d2) 61 | r2d2.operate() 62 | 63 | roomba = VacuumCleaningRobot(model='roomba M505') 64 | print(roomba) 65 | roomba.operate() 66 | 67 | -------------------------------------------------------------------------------- /lesson_008/python_snippets/04_super.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Что делать, если нужно __дополнить__ поведение? 4 | # Дочерний класс делает то же самое, что и родительский, плюс нечто большее 5 | 6 | 7 | class Robot: 8 | 9 | def __init__(self, model): 10 | self.model = model 11 | 12 | def __str__(self): 13 | return '{} model {}'.format(self.__class__.__name__, self.model) 14 | 15 | def operate(self): 16 | print('Робот ездит по кругу') 17 | 18 | 19 | class VacuumCleaningRobot(Robot): 20 | 21 | def __init__(self, model): 22 | super().__init__(model=model) 23 | self.dust_bug = 0 24 | 25 | def operate(self): 26 | print('Робот пылесосит пол, заполенность мешка для пыли', self.dust_bug) 27 | 28 | 29 | roomba = VacuumCleaningRobot(model='roomba M505') 30 | print(roomba) 31 | roomba.operate() 32 | 33 | 34 | class WarRobot(Robot): 35 | 36 | def __init__(self, model, gun): 37 | super().__init__(model=model) 38 | self.gun = gun 39 | 40 | def operate(self): 41 | print('Робот охраняет военный обьект c помощью', self.gun) 42 | 43 | 44 | r2d2 = WarRobot(model='R2D2', gun='пулемет') 45 | print(r2d2) 46 | r2d2.operate() 47 | 48 | 49 | class SubmarineRobot(WarRobot): 50 | 51 | def operate(self): 52 | super().operate() 53 | print('Охрана ведется под водой') 54 | 55 | 56 | rc_submarine = WarRobot(model='Orbiter', gun='лазер') 57 | print(rc_submarine) 58 | rc_submarine.operate() 59 | 60 | 61 | -------------------------------------------------------------------------------- /lesson_008/python_snippets/06_theory.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Теперь немного умных слов 4 | 5 | # Класс(Class): Определенный программистом прототип программируемого 6 | # объекта с набором атрибутов(переменных и методов), которые описывают 7 | # данный объект. Доступ к аттрибутам и методам осуществляется через точку 8 | 9 | # Переменная класса(Class variable): Переменная, доступная для всех экземпляров данного 10 | # класса. Определяется внутри класса, но вне любых методов класса. 11 | 12 | # Экземпляр класса(Instance): Отдельный объект - представитель определенного класса. 13 | 14 | # Переменная экземпляра класса(Instance variable): Переменная определенная внутри 15 | # медота класса, принадлежащая только к этому классу. 16 | 17 | # Метод(Method): Особая функция, определенная внутри класса. 18 | 19 | # Наследование(Inheritance): Передача аттрибутов и методов родительского класса дочерним 20 | # классам. 21 | 22 | # Перегрузка функций(Function overloading): Изменение работы метода, унаследованного 23 | # дочерним классом от родительского класса. 24 | 25 | # Перегрузка операторов(Operator overloading): Определение работы операторов с экземплярами 26 | # данного класса. 27 | 28 | 29 | # Если хочется еще крутой теории - https://goo.gl/9JxMcn 30 | 31 | # Изученные нами принципы ООП 32 | # абстракция - выделение классов обьектов 33 | # наследование - иерархия классов 34 | # инкапсуляция - сокрытие данных внутри обьекта 35 | # полиморфизм - множественное наследование 36 | -------------------------------------------------------------------------------- /lesson_009/.gitignore: -------------------------------------------------------------------------------- 1 | python_snippets/out.txt 2 | python_snippets/voyna-i-mir.txt 3 | icons 4 | icons_by_year 5 | 6 | -------------------------------------------------------------------------------- /lesson_009/02_log_parser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | 5 | # Имеется файл events.txt вида: 6 | # 7 | # [2018-05-17 01:55:52.665804] NOK 8 | # [2018-05-17 01:56:23.665804] OK 9 | # [2018-05-17 01:56:55.665804] OK 10 | # [2018-05-17 01:57:16.665804] NOK 11 | # [2018-05-17 01:57:58.665804] OK 12 | # ... 13 | # 14 | # Напишите программу, которая считывает файл 15 | # и выводит число событий NOK за каждую минуту в другой файл в формате 16 | # 17 | # [2018-05-17 01:57] 1234 18 | # [2018-05-17 01:58] 4321 19 | # ... 20 | # 21 | # Входные параметры: файл для анализа, файл результата 22 | 23 | 24 | class LogParser: 25 | 26 | def __init__(self, file_in=None, file_out=None): 27 | self.file_in = file_in 28 | self.file_out = file_out 29 | self.log_stat = {} 30 | 31 | if not self.file_out: 32 | self.file_out = self.file_in + '.nok' 33 | 34 | if os.path.exists(self.file_out): 35 | os.remove(self.file_out) 36 | 37 | def line_parsing(self, line=None): 38 | date, time, res = line.split(' ') 39 | dt = date + ' ' + time[:5] + time[-1:] 40 | return dt, res 41 | 42 | def parse(self): 43 | with open(self.file_in, 'r') as file: 44 | for line in file: 45 | dt, res = self.line_parsing(line) 46 | res = res.replace('\n', '') 47 | if res == 'NOK': 48 | if dt not in self.log_stat.keys(): 49 | self.write() 50 | self.log_stat = {} 51 | self.log_stat[dt] = self.log_stat.setdefault(dt, 0) + 1 52 | 53 | def write(self): 54 | with open(file=self.file_out, mode='a', encoding='utf8') as file: 55 | for date, cnt in self.log_stat.items(): 56 | file.write(f'{date} {cnt} \n') 57 | 58 | 59 | if __name__ == '__main__': 60 | log = LogParser('events.txt') 61 | log.parse() 62 | 63 | # Зачет! 64 | -------------------------------------------------------------------------------- /lesson_009/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_009/icons.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_009/icons.zip -------------------------------------------------------------------------------- /lesson_009/python_snippets/03_file_seek.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import io 3 | from pprint import pprint 4 | 5 | # Файл - это упорядоченная совокупность байтов, которая хранится на диске 6 | # и/или занимает отдельную область внешней памяти 7 | 8 | 9 | # Файл можно представить как ленту на шоколадной фабрике, только вместо конфет - байты. 10 | # Лента имеет начало и конец, каждая конфета пронумерована. 11 | # И мы можем ходить вдоль ленты - брать или класть конфеты. 12 | # Если файл открыт только для чтения (посмотреть на конфеты) 13 | # - то при открытии файла стоим вначале ленты, на 0 месте, 14 | # А при самом чтении - сдвигаемся вдоль ленты на количество прочитанных конфет. 15 | # file.tell() говорит нам текущую позицию 16 | 17 | file_name = 'byron.txt' 18 | # file_name = 'pushkin.txt' 19 | file = open(file_name, mode='r', encoding='utf8') 20 | print(file.tell()) 21 | 22 | print('читаем 100 символов') 23 | file_content = file.read(100) # в символах 24 | print(file_content) 25 | print(file.tell()) # в байтах! 26 | 27 | print('читаем остальное') 28 | file_content = file.read() 29 | print(file_content) 30 | print(file.tell()) # в байтах! 31 | 32 | file.close() 33 | 34 | # Позицию чтения можно менять - переходить в начала или в коннец 35 | file_name = 'pushkin.txt' 36 | file = open(file_name, mode='r', encoding='utf8') 37 | 38 | file_content = file.read(100) # в символах 39 | print(file_content) 40 | 41 | new_position = file.seek(0, io.SEEK_SET) 42 | # io.SEEK_SET - начало файла 43 | # io.SEEK_CUR - текущая позиция 44 | # io.SEEK_END - конец файла 45 | 46 | file_content = file.read(100) # в символах 47 | print(file_content) 48 | 49 | file.close() 50 | # аналогично для записи 51 | 52 | 53 | # Свойства и функции у обьекта файл 54 | pprint(file.name) 55 | pprint(file.mode) 56 | pprint(file.encoding) 57 | pprint(file.closed) 58 | 59 | pprint(file.readable()) # файл можно читать 60 | pprint(file.writable()) # файл можно писать 61 | pprint(file.seekable()) # файл поддерживает произвольный доступ 62 | 63 | pprint(file.truncate(size=None)) 64 | pprint(file.flush()) # обычно файл буферезирован, флаш записвыает весь буфер на диск 65 | 66 | # Файлы по сути являются потоками байтов - streams. https://docs.python.org/3/library/io.html 67 | 68 | 69 | -------------------------------------------------------------------------------- /lesson_009/python_snippets/04_file_usage.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Простые формы работы с файлами 4 | 5 | # Чтение построчно - символ окончания строки - \n 6 | file_name = 'pushkin.txt' 7 | file = open(file_name, mode='r', encoding='utf8') 8 | for line in file: # если файл огромный - будет читать только строку 9 | print(line) 10 | file.close() 11 | 12 | 13 | # еще вариант 14 | file_name = 'pushkin.txt' 15 | file = open(file_name, mode='r', encoding='utf8') 16 | for line in file.readlines(): # если файл огромный - все прочитает в память, не делайте так! 17 | print(line) 18 | file.close() 19 | 20 | # еще вариант 21 | file_name = 'pushkin.txt' 22 | file = open(file_name, mode='r', encoding='utf8') 23 | line = True 24 | while line: 25 | line = file.readline() 26 | if 'красавица' in line: 27 | print('Красавица найдена в строке', line) 28 | break 29 | else: 30 | print('Тут красавиц нет') 31 | file.close() 32 | 33 | # Надо всегда следить что бы файл был закрыт при выходе из программы 34 | # Есть оператор with - полезный для работы с файлами. Он автоматически закроет файл 35 | file_name = 'pushkin.txt' 36 | with open(file_name, mode='r', encoding='utf8') as file: 37 | for line in file: 38 | print(line) 39 | print(file.closed) 40 | 41 | 42 | # with в общем случае работает с контекстными менеджерами https://goo.gl/J2TZRq 43 | class InOutBlock: 44 | 45 | def __enter__(self): 46 | print('Входим в блок кода') 47 | # TODO обратите внимание что тут надо вернуть обьект - в видео это пропущено 48 | return self 49 | 50 | def __exit__(self, exc_type, exc_val, exc_tb): 51 | print('Выходим из блока кода') 52 | 53 | def some_method(self): 54 | print('Выполяем метод обьекта InOutBlock') 55 | 56 | 57 | with InOutBlock() as in_out: 58 | # in_out = InOutBlock() 59 | print('Некоторый код') 60 | in_out.some_method() 61 | 62 | # то есть обьект файла реализует интерфейс контекстного менеджера 63 | # и закрывает файл при выходе из блока кода 64 | -------------------------------------------------------------------------------- /lesson_009/python_snippets/05_files_in_OS.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | 5 | # Все файлы лежат на диске и имеют путь в файловой системе. Как работать с файлами на уровне ОС? 6 | # Есть встроенные модули для этого: os, os.path, shutil 7 | # Пригодятся они для написания скриптов-аналогов bash (.bat файлов в Windows) 8 | 9 | path = 'C:\\Windows\\help' 10 | 11 | # Пройтись по всем файлам в директории. 12 | for dirpath, dirnames, filenames in os.walk(path): 13 | print(dirpath, dirnames, filenames) 14 | 15 | # В разных ОС путь записывается по разному: привести к нужному в этой ОС виду 16 | os.path.normpath(path) 17 | 18 | # Получить размер файла. 19 | os.path.getsize(path) 20 | 21 | # Получить дату модификации файла. 22 | os.path.getmtime(path) 23 | 24 | # вернет кол-во секунд с начала эпохи. преобразовать в года/месяца можно так 25 | import time 26 | time.gmtime(secs) # вернет тьюпл со временем https://docs.python.org/3/library/time.html#time.struct_time 27 | 28 | # сформирвать правильный путь к файлу с учетом особенностей ОС. 29 | # os.path.join(path1[, path2[, ...]]) 30 | 31 | # получить родительскую директорию 32 | os.path.dirname(path) 33 | # получить родительскую директорию текущего модуля 34 | os.path.dirname(__file__) 35 | 36 | # это самые основние, остальные см https://goo.gl/AB6aDQ 37 | 38 | 39 | # а теперь все вместе 40 | import time 41 | import os 42 | 43 | path = 'C:/Windows/help' 44 | path_normalized = os.path.normpath(path) 45 | print(path_normalized) 46 | 47 | count = 0 48 | for dirpath, dirnames, filenames in os.walk(path_normalized): 49 | print('*' * 27) 50 | print(dirpath, dirnames, filenames) 51 | print(os.path.dirname(dirpath)) 52 | count += len(filenames) 53 | for file in filenames: 54 | full_file_path = os.path.join(dirpath, file) 55 | secs = os.path.getmtime(full_file_path) 56 | file_time = time.gmtime(secs) 57 | if file_time[0] == 2013: 58 | # выводим только файлы за 2013 год 59 | print(full_file_path, secs, file_time) 60 | print(count) 61 | 62 | print(__file__, os.path.dirname(__file__)) -------------------------------------------------------------------------------- /lesson_009/python_snippets/byron.txt: -------------------------------------------------------------------------------- 1 | My soul is dark - Oh! quickly string 2 | The harp I yet can brook to hear; 3 | And let thy gentle fingers fling 4 | Its melting murmurs o'er mine ear. 5 | If in this heart a hope be dear, 6 | That sound shall charm it forth again: 7 | If in these eyes there lurk a tear, 8 | 'Twill flow, and cease to burn my brain. 9 | 10 | But bid the strain be wild and deep, 11 | Nor let thy notes of joy be first: 12 | I tell thee, minstrel, I must weep, 13 | Or else this heavy heart will burst; 14 | For it hath been by sorrow nursed, 15 | And ached in sleepless silence, long; 16 | And now 'tis doomed to know the worst, 17 | And break at once - or yield to song. 18 | -------------------------------------------------------------------------------- /lesson_009/python_snippets/pushkin.txt: -------------------------------------------------------------------------------- 1 | Зимнее утро 2 | 3 | Мороз и солнце; день чудесный! 4 | Еще ты дремлешь, друг прелестный — 5 | Пора, красавица, проснись: 6 | Открой сомкнуты негой взоры 7 | Навстречу северной Авроры, 8 | Звездою севера явись! 9 | 10 | Вечор, ты помнишь, вьюга злилась, 11 | На мутном небе мгла носилась; 12 | Луна, как бледное пятно, 13 | Сквозь тучи мрачные желтела, 14 | И ты печальная сидела — 15 | А нынче... погляди в окно: 16 | 17 | Под голубыми небесами 18 | Великолепными коврами, 19 | Блестя на солнце, снег лежит; 20 | Прозрачный лес один чернеет, 21 | И ель сквозь иней зеленеет, 22 | И речка подо льдом блестит. 23 | 24 | Вся комната янтарным блеском 25 | Озарена. Веселым треском 26 | Трещит затопленная печь. 27 | Приятно думать у лежанки. 28 | Но знаешь: не велеть ли в санки 29 | Кобылку бурую запречь? 30 | 31 | Скользя по утреннему снегу, 32 | Друг милый, предадимся бегу 33 | Нетерпеливого коня 34 | И навестим поля пустые, 35 | Леса, недавно столь густые, 36 | И берег, милый для меня. 37 | 38 | 1829 г. -------------------------------------------------------------------------------- /lesson_009/python_snippets/pushkin_cp1251.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_009/python_snippets/pushkin_cp1251.txt -------------------------------------------------------------------------------- /lesson_009/python_snippets/voyna-i-mir.txt.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_009/python_snippets/voyna-i-mir.txt.zip -------------------------------------------------------------------------------- /lesson_010/01_fifth_element.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Умножить константу BRUCE_WILLIS на пятый элемент строки, введенный пользователем 4 | 5 | BRUCE_WILLIS = 42 6 | input_data = None 7 | 8 | try: 9 | input_data = input('Если хочешь что-нибудь сделать, сделай это сам: ') 10 | leeloo = int(input_data[4]) 11 | result = BRUCE_WILLIS * leeloo 12 | print(f"- Leeloo Dallas! Multi-pass № {result}!") 13 | except ValueError as exc: 14 | print(f'Введено: <{input_data}> - Невозможно преобразовать к числу ({exc}).') 15 | except IndexError as exc: 16 | print(f'Введено: <{input_data}> - Выход за границы списка ({exc}).') 17 | except Exception: 18 | print(f'Введено: <{input_data}> - Непредвиденная ошибка.') 19 | 20 | # Ообернуть код и обработать исключительные ситуации для произвольных входных параметров 21 | # - ValueError - невозможно преобразовать к числу 22 | # - IndexError - выход за границы списка 23 | # - остальные исключения 24 | # для каждого типа исключений написать на консоль соотв. сообщение 25 | 26 | 27 | # Зачет 28 | 29 | -------------------------------------------------------------------------------- /lesson_010/02_groundhog_day.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import random 3 | # День сурка 4 | # 5 | # Напишите функцию one_day() которая возвращает количество кармы от 1 до 7 6 | # и может выкидывать исключения: 7 | # - IamGodError 8 | # - DrunkError 9 | # - CarCrashError 10 | # - GluttonyError 11 | # - DepressionError 12 | # - SuicideError 13 | # Одно из этих исключений выбрасывается с вероятностью 1 к 13 каждый день 14 | # 15 | # Функцию оберните в бесконечный цикл, выход из которого возможен только при накоплении 16 | # кармы до уровня ENLIGHTENMENT_CARMA_LEVEL. Исключения обработать и записать в лог. 17 | 18 | ENLIGHTENMENT_CARMA_LEVEL = 777 19 | carma = 0 20 | 21 | 22 | class IamGodError(Exception): 23 | pass 24 | 25 | 26 | class DrunkError(Exception): 27 | pass 28 | 29 | 30 | class CarCrashError(Exception): 31 | pass 32 | 33 | 34 | class GluttonyError(Exception): 35 | pass 36 | 37 | 38 | class DepressionError(Exception): 39 | pass 40 | 41 | 42 | class SuicideError(Exception): 43 | pass 44 | 45 | 46 | def one_day(): 47 | my_exceptions = (IamGodError('IamGod - Карма не растет'), 48 | DrunkError('Drunk - Карма не растет'), 49 | CarCrashError('CarCrash - Карма не растет'), 50 | GluttonyError('Gluttony - Карма не растет') , 51 | DepressionError('Depression - Карма не растет'), 52 | SuicideError('Suicide - Карма не растет'),) 53 | 54 | if random.randint(1, 13) == 13: 55 | raise random.choice(my_exceptions) 56 | return random.randint(1, 7) 57 | 58 | 59 | with open('02_error.log', mode='w') as file: 60 | while True: 61 | try: 62 | carma += one_day() 63 | if carma >= ENLIGHTENMENT_CARMA_LEVEL: 64 | print(carma) 65 | break 66 | except (IamGodError, DrunkError, CarCrashError, GluttonyError, DepressionError, SuicideError) as exc: 67 | error = f'Ошибка: {exc.__class__.__name__} {exc.args}' 68 | print(error) 69 | file.write(error) 70 | file.write('\n') 71 | 72 | # https://goo.gl/JnsDqu 73 | 74 | # Зачет! 75 | -------------------------------------------------------------------------------- /lesson_010/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_010/__init__.py -------------------------------------------------------------------------------- /lesson_010/python_snippets/04_libs_exceptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Зачастую библиотеки/пакеты пайтона определяют свои исключения, специфичные для их работы. 4 | 5 | # Например, для библиотеки работы с http запросами 6 | import requests 7 | 8 | url = 'http://ya.ru' 9 | try: 10 | data = requests.get(url) 11 | print(data.text) 12 | except requests.ConnectionError as exc: 13 | print(f'не могу соединится с {url} потому что {exc}') 14 | # то есть мы можем обрабатывать нештатные ситуации, 15 | # с которой библиотека не справилась (изменить адрес, к примеру, или перейти к следующему) 16 | 17 | 18 | # или для django 19 | from my_app.models import Blog 20 | 21 | try: 22 | Blog.objects.get(id=27) 23 | except Blog.DoesNotExist: 24 | print('нет такой записи блога') 25 | 26 | 27 | # или для pygame (движок диплома) 28 | import pygame 29 | 30 | 31 | def load_image(name, colorkey=None): 32 | """ 33 | Load image from file 34 | """ 35 | fullname = os.path.join(theme.PICTURES_PATH, name) 36 | try: 37 | image = pygame.image.load(fullname) 38 | except pygame.error as exc: 39 | print("Cannot load image:", fullname) 40 | raise SystemExit(exc) 41 | if colorkey is not None: 42 | if colorkey is -1: 43 | colorkey = image.get_at((0, 0)) 44 | image.set_colorkey(colorkey, RLEACCEL) 45 | return image 46 | 47 | # Таким способом мы может поймать специфичные для библиотек исключения 48 | # и принять решение что делать дальше 49 | -------------------------------------------------------------------------------- /lesson_010/python_snippets/06_practice.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Есть файл calc.txt с записями операций - текстовый калькулятор. Записи вида 4 | # 5 | # 100 + 34 6 | # 23 / 4 7 | # 8 | # то есть ОПЕРАНД_1 ОПЕРАЦИЯ ОПЕРАНД_2, разделенные пробелами. 9 | # Операндны - целые числа. Операции - арифметические, целочисленное деление и остаток от деления. 10 | # 11 | # Нужно вычислить все операции и найти сумму их результата. 12 | 13 | 14 | def calc(line): 15 | # print(f'Read line {line}', flush=True) 16 | operand_1, operation, operand_2 = line.split(' ') 17 | operand_1 = int(operand_1) 18 | operand_2 = int(operand_2) 19 | if operation == '+': 20 | value = operand_1 + operand_2 21 | elif operation == '-': 22 | value = operand_1 - operand_2 23 | elif operation == '/': 24 | value = operand_1 / operand_2 25 | elif operation == '*': 26 | value = operand_1 / operand_2 27 | elif operation == '//': 28 | value = operand_1 // operand_2 29 | elif operation == '%': 30 | value = operand_1 % operand_2 31 | else: 32 | raise ValueError('Unknown operation {operation}') 33 | return value 34 | 35 | 36 | total = 0 37 | with open('calc.txt', 'r') as ff: 38 | for line in ff: 39 | line = line[:-1] 40 | try: 41 | total += calc(line) 42 | except ValueError as exc: 43 | if 'unpack' in exc.args[0]: 44 | print(f'Не хватает операндов {exc} в строке {line}') 45 | else: 46 | print(f'Не могу преобразовать к целому {exc} в строке {line}') 47 | 48 | print(f'Total {total}') 49 | -------------------------------------------------------------------------------- /lesson_010/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_011/01_shapes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import simple_draw as sd 4 | from lesson_004 import shapes 5 | 6 | 7 | # На основе вашего кода из решения lesson_004/shapes.py сделать функцию-фабрику, 8 | # которая возвращает функции рисования треугольника, четырехугольника, пятиугольника и т.д. 9 | # 10 | # Функция рисования должна принимать параметры 11 | # - точка начала рисования 12 | # - угол наклона 13 | # - длина стороны 14 | # 15 | # Функция-фабрика должна принимать параметр n - количество сторон. 16 | 17 | 18 | def create_polygon(n): 19 | 20 | def polygon(start_point, angle, length): 21 | vector = start_point 22 | side_count = n 23 | angle_step = 360 / side_count 24 | step = angle_step 25 | for side in range(side_count): 26 | if side == 0: 27 | vector = sd.get_vector(start_point=vector, angle=angle, length=length + 3) 28 | elif side == side_count - 1: 29 | sd.line(vector.end_point, start_point) 30 | break 31 | else: 32 | vector = sd.get_vector(start_point=vector.end_point, angle=angle + step, length=length) 33 | step += angle_step 34 | vector.draw() 35 | 36 | return polygon 37 | 38 | 39 | polygon = create_polygon(n=9) 40 | polygon(start_point=sd.get_point(200, 50), angle=0, length=100) 41 | 42 | sd.pause() 43 | 44 | # Зачет! 45 | -------------------------------------------------------------------------------- /lesson_011/03_log_parser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # На основе своего кода из lesson_009/02_log_parser.py напишите итератор (или генератор) 4 | # котрый читает исходный файл events.txt и выдает число событий NOK за каждую минуту 5 | # <время> <число повторений> 6 | # 7 | # пример использования: 8 | # 9 | # grouped_events = <создание итератора/генератора> 10 | # for group_time, event_count in grouped_events: 11 | # print(f'[{group_time}] {event_count}') 12 | # 13 | # на консоли должно появится что-то вроде 14 | # 15 | # [2018-05-17 01:57] 1234 16 | 17 | import os 18 | 19 | 20 | class LogParser: 21 | 22 | def __init__(self, file_in=None, file_out=None): 23 | self.file_in = file_in 24 | self.file_out = file_out 25 | self.log_stat = {} 26 | 27 | if not self.file_out: 28 | self.file_out = self.file_in + '.nok' 29 | 30 | if os.path.exists(self.file_out): 31 | os.remove(self.file_out) 32 | 33 | def line_parsing(self, line=None): 34 | date, time, res = line.split(' ') 35 | res = res.replace('\n', '') 36 | dt = date + ' ' + time[:5] + time[-1:] 37 | return dt, res 38 | 39 | def parse(self): 40 | self.log_stat = {} 41 | with open(self.file_in, 'r') as file: 42 | for line in file: 43 | dt, res = self.line_parsing(line) 44 | 45 | if res == 'NOK': 46 | if dt not in self.log_stat.keys(): 47 | for k, v in self.log_stat.items(): 48 | yield k, v 49 | self.log_stat = {} 50 | self.log_stat[dt] = self.log_stat.setdefault(dt, 0) + 1 51 | 52 | def write_result(self): 53 | with open(file=self.file_out, mode='a', encoding='utf8') as file: 54 | for date, cnt in self.parse(): 55 | file.write(f'{date} {cnt} \n') 56 | 57 | 58 | if __name__ == '__main__': 59 | 60 | log_file_in = 'events.txt' 61 | log_file = LogParser(file_in=log_file_in) 62 | 63 | grouped_events = log_file.parse() 64 | for group_time, event_count in grouped_events: 65 | print(f'[{group_time}] {event_count}') 66 | 67 | log_file.write_result() 68 | 69 | # Зачет! 70 | -------------------------------------------------------------------------------- /lesson_011/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_011/python_snippets/08_practice_1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Погружаемся в функциональный стиль - За-заикальщик 4 | # Написать функцию которая повторяет два первых символа у строки 5 | 6 | animal = 'мишка' 7 | 8 | 9 | def stutter(text): 10 | return text[:2] + '-' + text 11 | 12 | print(stutter(animal)) 13 | 14 | # Написать функцию которая возвращет функцию повторения двух первых символов n раз 15 | 16 | 17 | def stutter_factory(n): 18 | 19 | def stutter(text): 20 | return (text[:2] + '-') * n + text 21 | 22 | return stutter 23 | 24 | stutter_2 = stutter_factory(n=2) 25 | print(stutter_2(animal)) 26 | stutter_3 = stutter_factory(n=3) 27 | print(stutter_3(animal)) 28 | 29 | # Создать массив функций и применить все функции поочередно к аргументу 30 | stutters = [stutter_factory(n=n) for n in range(1, 4)] 31 | print(stutters) 32 | result = [func(animal) for func in stutters] 33 | print(result) 34 | 35 | # Применим все функции поочередно к массиву аргументов 36 | animals = ['зайка', 'мишка', 'бегемотик'] 37 | mesh = [func(animal) for animal in animals for func in stutters] 38 | print(mesh) 39 | -------------------------------------------------------------------------------- /lesson_011/python_snippets/08_practice_2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Решим задачу прошлой практики с помощью функционального подхода 4 | # 5 | # Есть файл calc.txt с записями операций - текстовый калькулятор. Записи вида 6 | # 7 | # 100 + 34 8 | # 23 / 4 9 | # 10 | # то есть ОПЕРАНД_1 ОПЕРАЦИЯ ОПЕРАНД_2, разделенные пробелами. 11 | # Операндны - целые числа. Операции - арифметические, целочисленное деление и остаток от деления. 12 | # 13 | # Нужно вычислить все операции и найти сумму их результата. 14 | 15 | ops = { 16 | '*': lambda x, y: x + y, 17 | '/': lambda x, y: x / y, 18 | '+': lambda x, y: x + y, 19 | '-': lambda x, y: x - y, 20 | '//': lambda x, y: x // y, 21 | '%': lambda x, y: x % y, 22 | } 23 | 24 | 25 | def calc(line): 26 | # print(eval(line)) # https://habr.com/post/221937/ 27 | operand_1, operation, operand_2 = line.split(' ') 28 | operand_1 = int(operand_1) 29 | operand_2 = int(operand_2) 30 | if operation in ops: 31 | func = ops[operation] 32 | value = func(operand_1, operand_2) 33 | else: 34 | raise ValueError('Unknown operation {operation}') 35 | return value 36 | 37 | 38 | def get_lines(file_name): 39 | with open(file_name, 'r') as ff: 40 | for line in ff: 41 | if not line: 42 | continue 43 | line = line[:-1] 44 | yield line 45 | 46 | 47 | total = 0 48 | for line in get_lines(file_name='calc.txt'): 49 | try: 50 | total += calc(line) 51 | except ValueError as exc: 52 | if 'unpack' in exc.args[0]: 53 | print(f'Не хватает операндов {exc} в строке {line}') 54 | else: 55 | print(f'Не могу преобразовать к целому {exc} в строке {line}') 56 | 57 | print(f'Total {total}') 58 | 59 | -------------------------------------------------------------------------------- /lesson_011/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_012/.gitignore: -------------------------------------------------------------------------------- 1 | trades* -------------------------------------------------------------------------------- /lesson_012/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_012/python_snippets/01_parallel_computing.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Паралельные вычисления 4 | 5 | # Процессор в каждый момент времени выполняет только одну задачу (процесс) среди нескольких 6 | # Это многозадачность - см. https://goo.gl/5sHFcM (не путать с многопоточностью!) 7 | # Для пользователя все выглядит так, как будто все задачи выполняются одновременно - параллельно. 8 | # Все достигается за счет гигантского быстродействия процессоров. Если уменьшить скорость в миллион раз, 9 | # то станет видно, например, как поочередно отрисовываются окна приложений и мышка двигается рывками... 10 | # 11 | # Процессы с точки зрения ОС имеют разную память и разный стек (места вызова функций). 12 | # Когда процессор переключается на другую задачу, то старая задача "замораживается" на время 13 | # - сохраняется её область памяти и стек. Когда процессор решает вернуться к ней, то он восстанавливает 14 | # память и стек процесса и начинает с того места, где остановился в прошлый раз. 15 | # Процессы в операционной системе доступа к памяти друг друга не имеют, иначе все бы знали наши пароли. 16 | # 17 | # А что есть многопоточность? Потоки - это части одного ПРОЦЕССА (см. https://goo.gl/aDq4lc). 18 | # Сам процесс изнутри организовал себя так, что может переключать контексты выполнения СВОЕГО кода. 19 | # Процесс хранит информацию о потоках: место и контекст выполнения потока, какие обьекты создал поток, и т.п. 20 | # То есть процесс выступает в роли небольшой операционной системы для потоков. 21 | # И когда процессор начинает выполнять ПРОЦЕСС, то этот процесс внутри себя приступает к переключению ПОТОКОВ. 22 | # За счет того что процесс у потоков один, они все имеют доступ к памяти процесса. 23 | # 24 | # И начнем мы с потоков, они проще. Но это неточно... 25 | 26 | -------------------------------------------------------------------------------- /lesson_012/python_snippets/06_practice.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Задача: проверить у какого сайта "тяжелее" главная страница. 4 | # - получить html 5 | # - узнать какие CSS и JS файлы нужны для отображения 6 | # - подсчитать общий размер этих файлов 7 | # - вывести на консоль результаты 8 | 9 | import requests 10 | 11 | from extractor import LinkExtractor 12 | from utils import time_track 13 | 14 | sites = [ 15 | 'https://www.fl.ru', 16 | 'https://www.weblancer.net/', 17 | 'https://www.freelancejob.ru/', 18 | 'https://kwork.ru', 19 | 'https://work-zilla.com/', 20 | 'https://iklife.ru/udalennaya-rabota-i-frilans/poisk-raboty/vse-samye-luchshie-sajty-i-birzhi-v-internete.html', 21 | ] 22 | 23 | 24 | class PageSizer: 25 | 26 | def __init__(self, url): 27 | self.url = url 28 | self.total_bytes = 0 29 | 30 | def run(self): 31 | self.total_bytes = 0 32 | html_data = self._get_html(url=self.url) 33 | if html_data is None: 34 | return 35 | self.total_bytes += len(html_data) 36 | extractor = LinkExtractor(base_url=self.url) 37 | extractor.feed(html_data) 38 | for link in extractor.links: 39 | extra_data = self._get_html(url=link) 40 | if extra_data: 41 | self.total_bytes += len(extra_data) 42 | 43 | def _get_html(self, url): 44 | try: 45 | print(f'Go {url}...') 46 | res = requests.get(url) 47 | except Exception as exc: 48 | print(exc) 49 | else: 50 | return res.text 51 | 52 | 53 | @time_track 54 | def main(): 55 | sizers = [PageSizer(url=url) for url in sites] 56 | 57 | for sizer in sizers: 58 | sizer.run() 59 | 60 | for sizer in sizers: 61 | print(f'For url {sizer.url} need download {sizer.total_bytes//1024} Kb ({sizer.total_bytes} bytes)') 62 | 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /lesson_012/python_snippets/06_practice_02.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Задача: проверить у какого сайта "тяжелее" главная страница. 4 | # - получить html 5 | # - узнать какие CSS и JS файлы нужны для отображения 6 | # - подсчитать общий размер этих файлов 7 | # - вывести на консоль результаты 8 | import threading 9 | 10 | import requests 11 | 12 | from extractor import LinkExtractor 13 | from utils import time_track 14 | 15 | sites = [ 16 | 'https://www.fl.ru', 17 | 'https://www.weblancer.net/', 18 | 'https://www.freelancejob.ru/', 19 | 'https://kwork.ru', 20 | 'https://work-zilla.com/', 21 | 'https://iklife.ru/udalennaya-rabota-i-frilans/poisk-raboty/vse-samye-luchshie-sajty-i-birzhi-v-internete.html', 22 | ] 23 | 24 | 25 | class PageSizer(threading.Thread): 26 | 27 | def __init__(self, url, go_ahead=True, *args, **kwargs): 28 | super().__init__(*args, **kwargs) 29 | self.url = url 30 | self.go_ahead = go_ahead 31 | self.total_bytes = 0 32 | 33 | def run(self): 34 | self.total_bytes = 0 35 | html_data = self._get_html(url=self.url) 36 | if html_data is None: 37 | return 38 | self.total_bytes += len(html_data) 39 | if self.go_ahead: 40 | extractor = LinkExtractor(base_url=self.url) 41 | extractor.feed(html_data) 42 | sizers = [PageSizer(url=link, go_ahead=False) for link in extractor.links] 43 | for sizer in sizers: 44 | sizer.start() 45 | for sizer in sizers: 46 | sizer.join() 47 | for sizer in sizers: 48 | self.total_bytes += sizer.total_bytes 49 | 50 | def _get_html(self, url): 51 | try: 52 | print(f'Go {url}...') 53 | res = requests.get(url) 54 | except Exception as exc: 55 | print(exc) 56 | else: 57 | return res.text 58 | 59 | 60 | @time_track 61 | def main(): 62 | sizers = [PageSizer(url=url) for url in sites] 63 | 64 | for sizer in sizers: 65 | sizer.start() 66 | for sizer in sizers: 67 | sizer.join() 68 | 69 | for sizer in sizers: 70 | print(f'For url {sizer.url} need download {sizer.total_bytes//1024} Kb ({sizer.total_bytes} bytes)') 71 | 72 | 73 | if __name__ == '__main__': 74 | main() 75 | -------------------------------------------------------------------------------- /lesson_012/python_snippets/06_practice_03.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Задача: проверить у какого сайта "тяжелее" главная страница. 4 | # - получить html 5 | # - узнать какие CSS и JS файлы нужны для отображения 6 | # - подсчитать общий размер этих файлов 7 | # - вывести на консоль результаты 8 | import multiprocessing 9 | 10 | import requests 11 | 12 | from extractor import LinkExtractor 13 | from utils import time_track 14 | 15 | sites = [ 16 | 'https://www.fl.ru', 17 | 'https://www.weblancer.net/', 18 | 'https://www.freelancejob.ru/', 19 | 'https://kwork.ru', 20 | 'https://work-zilla.com/', 21 | 'https://iklife.ru/udalennaya-rabota-i-frilans/poisk-raboty/vse-samye-luchshie-sajty-i-birzhi-v-internete.html', 22 | ] 23 | 24 | 25 | class PageSizer(multiprocessing.Process): 26 | 27 | def __init__(self, url, collector, go_ahead=True, *args, **kwargs): 28 | super().__init__(*args, **kwargs) 29 | self.url = url 30 | self.go_ahead = go_ahead 31 | self.total_bytes = 0 32 | self.collector = collector 33 | 34 | def run(self): 35 | self.total_bytes = 0 36 | html_data = self._get_html(url=self.url) 37 | if html_data is None: 38 | return 39 | self.total_bytes += len(html_data) 40 | if self.go_ahead: 41 | extractor = LinkExtractor(base_url=self.url) 42 | extractor.feed(html_data) 43 | collector = multiprocessing.Queue() 44 | sizers = [PageSizer(url=link, go_ahead=False, collector=collector) for link in extractor.links] 45 | for sizer in sizers: 46 | sizer.start() 47 | for sizer in sizers: 48 | sizer.join() 49 | while not collector.empty(): 50 | data = collector.get() 51 | self.total_bytes += data['total_bytes'] 52 | self.collector.put(dict(url=self.url, total_bytes=self.total_bytes)) 53 | 54 | def _get_html(self, url): 55 | try: 56 | print(f'Go {url}...') 57 | res = requests.get(url) 58 | except Exception as exc: 59 | print(exc) 60 | else: 61 | return res.text 62 | 63 | 64 | @time_track 65 | def main(): 66 | collector = multiprocessing.Queue() 67 | sizers = [PageSizer(url=url, collector=collector) for url in sites] 68 | 69 | for sizer in sizers: 70 | sizer.start() 71 | for sizer in sizers: 72 | sizer.join() 73 | 74 | while not collector.empty(): 75 | data = collector.get() 76 | print(f"For url {data['url']} need download {data['total_bytes']//1024} Kb ({data['total_bytes']} bytes)") 77 | 78 | 79 | if __name__ == '__main__': 80 | main() 81 | -------------------------------------------------------------------------------- /lesson_012/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_012/python_snippets/extractor.py: -------------------------------------------------------------------------------- 1 | from html.parser import HTMLParser 2 | from urllib.parse import urljoin 3 | 4 | 5 | class LinkExtractor(HTMLParser): 6 | 7 | def __init__(self, base_url, *args, **kwargs): 8 | super().__init__(*args, **kwargs) 9 | self.base_url = base_url 10 | self.links = [] 11 | 12 | def handle_starttag(self, tag, attrs): 13 | if tag not in ('link', 'script', ): 14 | return 15 | attrs = dict(attrs) 16 | if tag == 'link': 17 | if 'rel' in attrs and attrs['rel'] == 'stylesheet': 18 | link = self._refine(attrs['href']) 19 | self.links.append(link) 20 | elif tag == 'script': 21 | if 'src' in attrs: 22 | link = self._refine(attrs['src']) 23 | self.links.append(link) 24 | 25 | def _refine(self, link): 26 | return urljoin(self.base_url, link) -------------------------------------------------------------------------------- /lesson_012/python_snippets/utils.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | 4 | def time_track(func): 5 | def surrogate(*args, **kwargs): 6 | started_at = time.time() 7 | 8 | result = func(*args, **kwargs) 9 | 10 | ended_at = time.time() 11 | elapsed = round(ended_at - started_at, 4) 12 | print(f'Функция работала {elapsed} секунд(ы)') 13 | return result 14 | return surrogate -------------------------------------------------------------------------------- /lesson_012/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from collections import OrderedDict 4 | 5 | 6 | def time_track(func): 7 | def surrogate(*args, **kwargs): 8 | started_at = time.time() 9 | 10 | result = func(*args, **kwargs) 11 | 12 | ended_at = time.time() 13 | elapsed = round(ended_at - started_at, 4) 14 | print(f'Функция работала {elapsed} секунд(ы)') 15 | return result 16 | return surrogate 17 | 18 | 19 | def print_report(tickers_dict): 20 | zero_tickers = {} 21 | tickers = {} 22 | 23 | for ticker, volatility in tickers_dict.items(): 24 | if volatility == 0: 25 | zero_tickers[ticker] = volatility 26 | else: 27 | tickers[ticker] = volatility 28 | 29 | ordered_tickers = OrderedDict(sorted(tickers.items(), key=lambda x: x[1], reverse=True)) 30 | tickers_list = list(ordered_tickers.keys()) 31 | 32 | print('Максимальная волатильность:') 33 | for secid in tickers_list[:3]: 34 | print(f'\t{secid} - {ordered_tickers[secid]:2.2f} %') 35 | 36 | print('Минимальная волатильность:') 37 | for secid in tickers_list[-3:]: 38 | print(f'\t{secid} - {ordered_tickers[secid]:2.2f} %') 39 | 40 | print('Нулевая волатильность:') 41 | print('\t', ', '.join(sorted(zero_tickers.keys())), sep='') 42 | 43 | 44 | def get_next_file(file_path): 45 | for dirpath, dirnames, filenames in os.walk(file_path): 46 | for filename in filenames: 47 | file_name = os.path.join(dirpath, filename) 48 | yield file_name 49 | -------------------------------------------------------------------------------- /lesson_013/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_013/font/ofont.ru_Franklin Gothic Medium Cond.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_013/font/ofont.ru_Franklin Gothic Medium Cond.ttf -------------------------------------------------------------------------------- /lesson_013/images/ticket_sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_013/images/ticket_sample.png -------------------------------------------------------------------------------- /lesson_013/images/ticket_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_013/images/ticket_template.png -------------------------------------------------------------------------------- /lesson_013/python_snippets/05_lib_usage.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Пример использования сторонней библиотеки на примере Pillow 4 | 5 | # Задача: сделать поздравительную открытку другу на Halloween 6 | 7 | import os 8 | from PIL import Image, ImageDraw, ImageFont, ImageColor 9 | 10 | 11 | class PostCardMaker: 12 | 13 | def __init__(self, name, template=None, font_path=None): 14 | self.name = name 15 | self.template = "post_card.jpg" if template is None else template 16 | if font_path is None: 17 | self.font_path = os.path.join("fonts", "ofont_ru_DS Eraser2.ttf") 18 | else: 19 | self.font_path = font_path 20 | 21 | def make(self, resize=False, out_path=None): 22 | im = Image.open(self.template) 23 | if resize: 24 | w, h = im.size 25 | im = im.resize((w // 2, h // 2)) 26 | draw = ImageDraw.Draw(im) 27 | font = ImageFont.truetype(self.font_path, size=26) 28 | 29 | y = im.size[1] - 10 - (10 + font.size) * 2 30 | message = f"Привет, {self.name}!" 31 | draw.text((10, y), message, font=font, fill=ImageColor.colormap['red']) 32 | 33 | y = im.size[1] - 20 - font.size 34 | message = f"С ужасным праздником тебя!" 35 | draw.text((10, y), message, font=font, fill=ImageColor.colormap['red']) 36 | 37 | # im.show() 38 | out_path = out_path if out_path else 'probe.jpg' 39 | im.save(out_path) 40 | print(f'Post card saved az {out_path}') 41 | 42 | 43 | if __name__ == '__main__': 44 | maker = PostCardMaker(name='Оля') 45 | maker.make(resize=True) 46 | -------------------------------------------------------------------------------- /lesson_013/python_snippets/06_practice.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Задача: написать чат бот по продаже напитков 4 | -------------------------------------------------------------------------------- /lesson_013/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_013/python_snippets/fonts/ofont_ru_DS Eraser2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_013/python_snippets/fonts/ofont_ru_DS Eraser2.ttf -------------------------------------------------------------------------------- /lesson_013/python_snippets/post_card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_013/python_snippets/post_card.jpg -------------------------------------------------------------------------------- /lesson_013/requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow==8.2.0 -------------------------------------------------------------------------------- /lesson_014/01_score.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Вас взяли на работу в молодой стартап. Идея стартапа - предоставлять сервис расчета результатов игр. 4 | # Начать решили с боулинга, упрощенной версии. 5 | # 6 | # Правила такие. 7 | # 8 | # Всего 10 кеглей. Игра состоит из 10 фреймов. В одном фрейме до 2х бросков, цель - сбить все кегли. 9 | # Результаты фрейма записываются символами: 10 | # «Х» – «strike», все 10 кеглей сбиты первым броском 11 | # «<число>/», например «4/» - «spare», в первый бросок сбиты 4 кегли, во второй – остальные 12 | # «<число><число>», например, «34» – в первый бросок сбито 3, во второй – 4 кегли. 13 | # вместо <число> может стоять прочерк «-», например, «-4» - ни одной кегли не было сбито за бросок (первый или второй) 14 | # Результат игры – строка с записью результатов фреймов. Символов-разделителей между фреймами нет. 15 | # Например, для игры из 3 фреймов запись результатов может выглядеть так: 16 | # «Х4/34» 17 | # Предлагается упрощенный способ подсчета количества очков: 18 | # «Х» – 20 очков, «4/» - 15 очков, «34» – сумма 3+4=7 19 | # То есть для игры «Х4/34» сумма очков равна 20+15+7=42 20 | # 21 | # Надо написать python-модуль (назвать bowling), предоставляющий API расчета количества очков: 22 | # функцию get_score, принимающую параметр game_result. Функция должна выбрасывать исключения, 23 | # когда game_result содержит некорректные данные. Использовать стандартные исключения по максимуму, 24 | # если не хватает - создать свои. 25 | # 26 | # Обязательно написать тесты на этот модуль. Расположить в папке tests. 27 | 28 | # Из текущего файла сделать консольную утилиту для определения количества очков, с помощью пакета argparse 29 | # Скрипт должен принимать параметр --result и печатать на консоль: 30 | # Количество очков для результатов ХХХ - УУУ. 31 | 32 | import argparse 33 | import bowling 34 | 35 | 36 | def console_parser(): 37 | parser = argparse.ArgumentParser(description='Утилита для расчета результата партии на основе результата бросков', 38 | add_help=True) 39 | parser.add_argument('-result', '--result', type=str, help='Результаты бросков') 40 | args = parser.parse_args() 41 | 42 | if args.result: 43 | game = bowling.Game(game_result=args.result, need_log=True) 44 | print(game.calculate_result()) 45 | else: 46 | print('Укажите параметры или воспользуйтесь --help') 47 | 48 | 49 | if __name__ == '__main__': 50 | console_parser() 51 | 52 | # При написании кода помнить, что заказчик может захотеть доработок и новых возможностей... 53 | # И, возможно, вам пригодится паттерн проектирования "Состояние", 54 | # см https://clck.ru/Fudd8 и https://refactoring.guru/ru/design-patterns/state 55 | 56 | -------------------------------------------------------------------------------- /lesson_014/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/05_practice.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Задача: 4 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/handling_external_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import requests 3 | 4 | 5 | class ExternalResourceGetter: 6 | 7 | def __init__(self, url): 8 | self.url = url 9 | self.data = None 10 | 11 | def run(self): 12 | self.data = self.get_data() 13 | result = self.proceed_data() 14 | return result 15 | 16 | def get_data(self): 17 | response = requests.get(self.url) 18 | return response.text 19 | 20 | def proceed_data(self): 21 | # max_length = 0 22 | # for line in self.data.split('\n'): 23 | # if len(line) > max_length: 24 | # max_length = len(line) 25 | max_length = max([len(line) for line in self.data.split('\n')]) 26 | return max_length 27 | 28 | 29 | if __name__ == '__main__': 30 | getter = ExternalResourceGetter(url='https://www.jetbrains.com/pycharm/') 31 | 32 | data = getter.run() 33 | print(data) 34 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/my_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | def my_sort_v1(slist): 5 | was_swap = True 6 | while was_swap: 7 | was_swap = False 8 | for i in range(len(slist) - 1): 9 | if slist[i] > slist[i + 1]: 10 | slist[i], slist[i + 1] = slist[i + 1], slist[i] 11 | was_swap = True 12 | return slist 13 | 14 | def my_sort_v2(slist): 15 | if len(slist) <= 1: 16 | return slist 17 | pivot = slist[0] 18 | less_then = [] 19 | more_then = [] 20 | for elem in slist: 21 | if elem > pivot: 22 | more_then.append(elem) 23 | elif elem < pivot: 24 | less_then.append(elem) 25 | return my_sort(less_then) + [pivot, ] + my_sort(more_then) 26 | 27 | 28 | def my_sort(slist): 29 | return list(set(sorted(slist))) 30 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/primes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import logging 3 | 4 | 5 | def prime_numbers_generator(n): 6 | prime_numbers = [] 7 | for number in range(2, n + 1): 8 | logging.debug(f'number {number}') 9 | for prime in prime_numbers: 10 | if number % prime == 0: 11 | logging.debug(f'делится на {prime}') 12 | break 13 | else: 14 | logging.debug(f'найдено новое простое {number}') 15 | prime_numbers.append(number) 16 | yield number 17 | 18 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/primes_package/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/primes_package/log_settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | log_config = { 4 | "version": 1, 5 | "formatters": { 6 | "primes_formatter": { 7 | "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" 8 | }, 9 | "main_formatter": { 10 | "format": "%(asctime)s - %(message)s" 11 | }, 12 | }, 13 | "handlers": { 14 | "primes_handler": { 15 | "class": "logging.FileHandler", 16 | "formatter": "primes_formatter", 17 | "filename": "primes.log", 18 | "encoding": "UTF-8", 19 | }, 20 | "main_handler": { 21 | "class": "logging.FileHandler", 22 | "formatter": "primes_formatter", 23 | "filename": "main.log", 24 | "encoding": "UTF-8", 25 | }, 26 | }, 27 | "loggers": { 28 | "primes": { 29 | "handlers": ["primes_handler"], 30 | "level": "DEBUG", 31 | }, 32 | "main": { 33 | "handlers": ["main_handler"], 34 | "level": "INFO", 35 | }, 36 | }, 37 | } 38 | 39 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/primes_package/main.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from primes_package.primes import prime_numbers_generator 4 | 5 | main_log = logging.getLogger('main') 6 | # main_log.setLevel(logging.DEBUG) 7 | # main_fh = logging.FileHandler("main.log", 'w', 'utf-8') 8 | # main_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') 9 | # main_fh.setFormatter(main_formatter) 10 | # main_log.addHandler(main_fh) 11 | 12 | 13 | def print_primes(n): 14 | for prime in prime_numbers_generator(n): 15 | main_log.info(f'Простое из генераторв {prime}') 16 | 17 | if __name__ == '__main__': 18 | print_primes(n=10) 19 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/primes_package/primes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import logging 3 | 4 | log = logging.getLogger('primes') 5 | # log.setLevel(logging.DEBUG) 6 | # fh = logging.FileHandler("primes.log", 'w', 'utf-8') 7 | # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 8 | # fh.setFormatter(formatter) 9 | # log.addHandler(fh) 10 | 11 | 12 | def prime_numbers_generator(n): 13 | prime_numbers = [] 14 | for number in range(2, n + 1): 15 | log.debug(f'number {number}') 16 | for prime in prime_numbers: 17 | if number % prime == 0: 18 | log.debug(f'делится на {prime}') 19 | break 20 | else: 21 | log.debug(f'найдено новое простое {number}') 22 | prime_numbers.append(number) 23 | yield number 24 | 25 | 26 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/test_my_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | import unittest 5 | from my_sort import my_sort 6 | 7 | 8 | class MySortTest(unittest.TestCase): 9 | 10 | def test_normal(self): 11 | result = my_sort([3, 4, 2, 8, 1, 6, 4]) 12 | self.assertEqual(result, [1, 2, 3, 4, 6, 8]) 13 | 14 | def test_sorted(self): 15 | result = my_sort([3, 4, 5]) 16 | self.assertEqual(result, [3, 4, 5]) 17 | 18 | def test_reversed(self): 19 | result = my_sort([3, 2, 1]) 20 | self.assertEqual(result, [1, 2, 3]) 21 | 22 | def test_empty(self): 23 | result = my_sort([]) 24 | self.assertEqual(result, []) 25 | 26 | def test_with_negative(self): 27 | result = my_sort([9, 3, -7, 2]) 28 | self.assertEqual(result, [-7, 2, 3, 9]) 29 | 30 | 31 | if __name__ == '__main__': 32 | unittest.main() 33 | 34 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/tests/05_practice.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Задача: 4 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/tests/test_child.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import unittest 3 | 4 | from family import Child, House 5 | 6 | 7 | class ChildTest(unittest.TestCase): 8 | 9 | def setUp(self): 10 | self.sweet_home = House() 11 | self.dasha = Child(name='Даша', house=self.sweet_home) 12 | 13 | def test_sleep(self): 14 | self.dasha.fullness = 30 15 | self.dasha.happiness = 100 16 | self.dasha.sleep() 17 | self.assertEqual(self.dasha.fullness, 20) 18 | self.assertEqual(self.dasha.happiness, 100) 19 | 20 | def test_act_full_up(self): 21 | self.dasha.fullness = 30 22 | self.dasha.happiness = 100 23 | self.dasha.act() 24 | self.assertEqual(self.dasha.fullness, 20) 25 | self.assertEqual(self.dasha.happiness, 100) 26 | 27 | def test_act_hungry(self): 28 | self.dasha.fullness = 10 29 | self.dasha.act() 30 | self.assertEqual(self.dasha.fullness, 20) 31 | 32 | 33 | if __name__ == '__main__': 34 | unittest.main() 35 | 36 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/tests/test_handling_external_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | import unittest 5 | from unittest.mock import Mock 6 | 7 | import handling_external_data 8 | from handling_external_data import ExternalResourceGetter 9 | 10 | _test_data = """ 11 | 1234567 12 | 12345 13 | 123456789 14 | 12 15 | """ 16 | 17 | # class FakeResult: 18 | # 19 | # def __init__(self): 20 | # self.text = _test_data 21 | 22 | 23 | # def fake_get_result(*args, **kwargs): 24 | # return FakeResult() 25 | 26 | 27 | class ExternalResourceGetterTest(unittest.TestCase): 28 | 29 | def test_normal(self): 30 | getter = ExternalResourceGetter(url='bla-bla-bla') 31 | fake_result = Mock() 32 | fake_result.text = _test_data 33 | fake_get_result = Mock(return_value=fake_result) 34 | handling_external_data.requests.get = fake_get_result 35 | result = getter.run() 36 | self.assertEqual(result, 9) 37 | 38 | 39 | if __name__ == '__main__': 40 | unittest.main() 41 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/tests/test_my_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | import unittest 5 | from my_sort import my_sort 6 | 7 | 8 | class MySortTest(unittest.TestCase): 9 | 10 | def test_normal(self): 11 | result = my_sort([3, 4, 2, 8, 1, 6, 4]) 12 | self.assertEqual(result, [1, 2, 3, 4, 4, 6, 8]) 13 | 14 | def test_sorted(self): 15 | result = my_sort([3, 4, 5]) 16 | self.assertEqual(result, [3, 4, 5]) 17 | 18 | def test_reversed(self): 19 | result = my_sort([3, 2, 1]) 20 | self.assertEqual(result, [1, 2, 3]) 21 | 22 | def test_empty(self): 23 | result = my_sort([]) 24 | self.assertEqual(result, []) 25 | 26 | def test_with_negative(self): 27 | result = my_sort([9, 3, -7, 2]) 28 | self.assertEqual(result, [-7, 2, 3, 9]) 29 | 30 | 31 | if __name__ == '__main__': 32 | unittest.main() 33 | 34 | -------------------------------------------------------------------------------- /lesson_014/python_snippets/tests/test_wife.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import unittest 3 | 4 | from family import House, Wife 5 | 6 | 7 | class WifeTest(unittest.TestCase): 8 | 9 | def setUp(self): 10 | self.sweet_home = House() 11 | self.anna = Wife(name='Анна Петровна', house=self.sweet_home) 12 | 13 | def test_act_with_shopping(self): 14 | self.sweet_home.food = 0 15 | self.anna.fullness = 30 16 | self.anna.act() 17 | self.assertEqual(self.anna.fullness, 20) 18 | self.assertEqual(self.sweet_home.food, 100) 19 | 20 | def test_act_with_buy_fur_coat(self): 21 | self.sweet_home.food = 100 22 | self.sweet_home.dirt = 0 23 | self.sweet_home.money = 1000 24 | self.anna.happiness = 10 25 | self.anna.act() 26 | self.assertEqual(self.anna.fullness, 20) 27 | self.assertEqual(self.anna.happiness, 70) 28 | self.assertEqual(self.sweet_home.money, 650) 29 | 30 | 31 | if __name__ == '__main__': 32 | unittest.main() 33 | 34 | -------------------------------------------------------------------------------- /lesson_014/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_014/tests/__init__.py -------------------------------------------------------------------------------- /lesson_014/tests/test_complex.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from bowling import Game, InputValueError, MaxFrameError, StrikeError, SpareError 3 | 4 | 5 | class BowlingTest(unittest.TestCase): 6 | 7 | def test_check_func_atr_error(self): 8 | with self.assertRaises(AttributeError): 9 | game = Game(game_result='') 10 | result = game.calculate_result() 11 | 12 | def test_check_func_atr2_error(self): 13 | with self.assertRaises(AttributeError): 14 | game = Game(game_result='X47') 15 | result = game.calculate_result() 16 | 17 | def test_check_func_max_frame_error(self): 18 | with self.assertRaises(MaxFrameError): 19 | game = Game(game_result='XXXXXXXXXXX') 20 | result = game.calculate_result() 21 | 22 | def test_check_func_symbols(self): 23 | with self.assertRaises(InputValueError): 24 | game = Game(game_result='1s2/') 25 | result = game.calculate_result() 26 | 27 | def test_check_func_spare_error(self): 28 | with self.assertRaises(SpareError): 29 | game = Game(game_result='/1') 30 | result = game.calculate_result() 31 | 32 | def test_check_func_strike_error(self): 33 | with self.assertRaises(StrikeError): 34 | game = Game(game_result='2X') 35 | result = game.calculate_result() 36 | 37 | def test_functional_game_calc(self): 38 | game = Game(game_result='X4/34--') 39 | result = game.calculate_result() 40 | self.assertEqual(result, 42, 'Не верно производятся расчеты партии !') 41 | 42 | def test_functional_strike(self): 43 | game = Game(game_result='X') 44 | result = game.calculate_result() 45 | self.assertEqual(result, 20, 'Не верно рассчитываются очки за страйк !') 46 | 47 | def test_functional_spare(self): 48 | game = Game(game_result='4/') 49 | result = game.calculate_result() 50 | self.assertEqual(result, 15, 'Не верно рассчитываются очки за спайр !') 51 | 52 | def test_functional_2_miss(self): 53 | game = Game(game_result='--') 54 | result = game.calculate_result() 55 | self.assertEqual(result, 0, 'Не верно рассчитываются очки за 2 миса !') 56 | 57 | def test_functional_2_hit(self): 58 | game = Game(game_result='12') 59 | result = game.calculate_result() 60 | self.assertEqual(result, 3, 'Не верно рассчитываются очки за 2 попадания 2 бросками !') 61 | 62 | 63 | if __name__ == '__main__': 64 | unittest.main() -------------------------------------------------------------------------------- /lesson_015/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_015/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/BondByMonth.csv: -------------------------------------------------------------------------------- 1 | month,cities,expenses_sum 2 | 01.2019,берлин,369404.31 3 | 02.2019,лондон,417846.03 4 | 03.2019,москва,3563703.56 5 | 04.2019,токио,29716243.65 6 | -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/BondDetail.csv: -------------------------------------------------------------------------------- 1 | date,city,expenses 2 | 01.01.2019,берлин,33400.30 3 | 02.01.2019,берлин,24119.02 4 | 03.01.2019,берлин,20598.21 5 | 04.01.2019,берлин,22371.32 6 | 05.01.2019,берлин,52892.92 7 | 06.01.2019,берлин,58884.37 8 | 07.01.2019,берлин,18454.01 9 | 08.01.2019,берлин,50679.42 10 | 09.01.2019,берлин,45348.56 11 | 10.01.2019,берлин,42656.18 12 | 01.02.2019,лондон,63931.75 13 | 02.02.2019,лондон,19339.68 14 | 03.02.2019,лондон,26781.75 15 | 04.02.2019,лондон,26350.00 16 | 05.02.2019,лондон,19148.41 17 | 06.02.2019,лондон,60035.71 18 | 07.02.2019,лондон,56848.41 19 | 08.02.2019,лондон,28797.62 20 | 09.02.2019,лондон,61365.87 21 | 10.02.2019,лондон,55246.83 22 | 01.03.2019,москва,297405.22 23 | 02.03.2019,москва,551556.49 24 | 03.03.2019,москва,153423.51 25 | 04.03.2019,москва,521325.97 26 | 05.03.2019,москва,485479.14 27 | 06.03.2019,москва,106031.63 28 | 07.03.2019,москва,179371.31 29 | 08.03.2019,москва,226359.31 30 | 09.03.2019,москва,614981.90 31 | 10.03.2019,москва,427769.10 32 | 01.04.2019,токио,1624235.88 33 | 02.04.2019,токио,2728934.01 34 | 03.04.2019,токио,4926611.95 35 | 04.04.2019,токио,3982568.31 36 | 05.04.2019,токио,5349076.57 37 | 06.04.2019,токио,2738006.26 38 | 07.04.2019,токио,1462296.14 39 | 08.04.2019,токио,847121.72 40 | 09.04.2019,токио,2515509.23 41 | 10.04.2019,токио,3541883.57 42 | -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/Dom#2.json: -------------------------------------------------------------------------------- 1 | { 2 | "FirstName": "Dominick", 3 | "LastName": "Cobb", 4 | "Adress": { 5 | "city": "Los Angeles", 6 | "StreetAdress": "S Olive st 617" 7 | }, 8 | "ContactDetails": { 9 | "PhoneNumbers": [ 10 | "+1 212-626-8118", 11 | "+1 212-484-4554" 12 | ], 13 | "E-mail": "inception@nolan.genii" 14 | } 15 | } -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/Dom.json: -------------------------------------------------------------------------------- 1 | {"FirstName": "Dominick", "LastName": "Cobb", "Adress": {"city": "Los Angeles", "StreetAdress": "S Olive st 617"}, "ContactDetails": {"PhoneNumbers": ["+1 212-626-8118", "+1 212-484-4554"], "E-mail": "inception@nolan.genii"}} -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/Indiana_stash.csv: -------------------------------------------------------------------------------- 1 | Name,year of discovery,quantity 2 | Ark of the covenant,1936,1 3 | Crystal skull,1957,1 4 | Sacred Lingam,1935,1 5 | the Golden cross of Coronado,1912,1 6 | the Golden cross of Coronado,1912,1 7 | the Golden cross of Coronado,1912,1 8 | -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/Tools for archaeological excavations.csv: -------------------------------------------------------------------------------- 1 | Name:,Price:,Quantity: 2 | Whip,100,1 3 | Hat,200,2 4 | Revolver,400,1 5 | -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/demo.xml: -------------------------------------------------------------------------------- 1 | 2 | Petya 3 | 23 4 | true 5 | 6 | 9 7 | 7 8 | 8 9 | 8 10 | 11 | 12 | Linux 13 | Intel Core i7-8700 14 | 64 15 | 5000 16 | 17 | 18 | -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/json_todos_formatted.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": { 3 | "num": 20, 4 | "completed": 11 5 | }, 6 | "2": { 7 | "num": 20, 8 | "completed": 8 9 | }, 10 | "3": { 11 | "num": 20, 12 | "completed": 7 13 | }, 14 | "4": { 15 | "num": 20, 16 | "completed": 6 17 | }, 18 | "5": { 19 | "num": 20, 20 | "completed": 12 21 | }, 22 | "6": { 23 | "num": 20, 24 | "completed": 6 25 | }, 26 | "7": { 27 | "num": 20, 28 | "completed": 9 29 | }, 30 | "8": { 31 | "num": 20, 32 | "completed": 11 33 | }, 34 | "9": { 35 | "num": 20, 36 | "completed": 8 37 | }, 38 | "10": { 39 | "num": 20, 40 | "completed": 12 41 | } 42 | } -------------------------------------------------------------------------------- /lesson_015/python_snippets/external_data/yaml_example.yaml: -------------------------------------------------------------------------------- 1 | Developers: 2 | martin: 3 | name: Martin D'vloper 4 | job: Developer 5 | skills: 6 | - python 7 | - perl 8 | - pascal 9 | tabitha: 10 | name: Tabitha Bitumen 11 | job: Developer 12 | skills: 13 | - lisp 14 | - fortran 15 | - erlang -------------------------------------------------------------------------------- /lesson_016/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_016/db/__init__.py: -------------------------------------------------------------------------------- 1 | from peewee import * 2 | 3 | 4 | class Database: 5 | 6 | def __init__(self, url): 7 | database_proxy = DatabaseProxy() 8 | self._db = SqliteDatabase(url) 9 | database_proxy.initialize(self._db) 10 | 11 | @property 12 | def db(self): 13 | return self._db 14 | 15 | # db = Database(url=DATABASE_PATH) 16 | -------------------------------------------------------------------------------- /lesson_016/db/models.py: -------------------------------------------------------------------------------- 1 | from lesson_016 import * 2 | 3 | 4 | class Forecast(db.Model): 5 | date = DateField(unique=True) 6 | temp = CharField() 7 | desc = CharField() 8 | 9 | class Meta: 10 | database = db 11 | 12 | 13 | @db.connection_context() 14 | def create_tables(): 15 | db.create_tables([Forecast]) 16 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/Mustached.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/Mustached.db -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/Northwind.sl3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/Northwind.sl3 -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/fonts/Aller Cyrillic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/fonts/Aller Cyrillic.ttf -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/girl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/girl.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/many_faces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/many_faces.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/mm_andy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/mm_andy.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/mm_cropped.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/mm_cropped.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/mm_effects.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/mm_effects.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/mm_paste.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/mm_paste.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/mm_resize_rotate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/mm_resize_rotate.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/music.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/music.db -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/0bmFUg4BDepQDQu-.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/0bmFUg4BDepQDQu-.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/11e260bb-e48d-4505-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/11e260bb-e48d-4505-8.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/1Group_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/1Group_21.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/1Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/1Icon.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/1Mask_Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/1Mask_Group.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/1R.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/1R.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/1skillbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/1skillbox.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/70365621.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/70365621.gif -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/76249.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/76249.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Diplom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Diplom.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/G8g3oMCuUKKfjDDy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/G8g3oMCuUKKfjDDy.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Group.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Group_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Group_21.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Group_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Group_4.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Group_931.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Group_931.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Group_932.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Group_932.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Group_933.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Group_933.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Group_934.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Group_934.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Icon.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/KY6TJB0bJplcmjBv.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/KY6TJB0bJplcmjBv.JPG -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Label.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Mask_Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Mask_Group.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Play_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/Play_button.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/R.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/R.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/Shape.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/_.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/_Python-.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/_Python-.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/css-27ed92378a434e4c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/css-27ed92378a434e4c.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/diploma_computer1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/diploma_computer1.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/efwsegf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/efwsegf.gif -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/face.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/fb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/fb.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/feec3fe7e8589b6c1d02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/feec3fe7e8589b6c1d02.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/image_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/image_2.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/instagram_1_.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/javascript-11a1e6401.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/javascript-11a1e6401.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/noun_995397_cc_1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/noun_995397_cc_1-1.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/noun_995397_cc_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/noun_995397_cc_1.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/rostelekom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/rostelekom.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/skillbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/skillbox.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/skillbox.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/telegram_2_.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/upload-8d532ba0-f2e9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/upload-8d532ba0-f2e9.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/vk.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/vtb-na-shapku.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/vtb-na-shapku.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos/xml-71b14942886ab4b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos/xml-71b14942886ab4b1.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos_results/1Mask_Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos_results/1Mask_Group.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos_results/Mask_Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos_results/Mask_Group.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos_results/diploma_computer1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos_results/diploma_computer1.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos_results/image_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos_results/image_2.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/photos_results/upload-8d532ba0-f2e9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/photos_results/upload-8d532ba0-f2e9.png -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/probe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/probe.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/spidyquotes/scrapy.cfg: -------------------------------------------------------------------------------- 1 | # Automatically created by: scrapy startproject 2 | # 3 | # For more information about the [deploy] section see: 4 | # https://scrapyd.readthedocs.io/en/latest/deploy.html 5 | 6 | [settings] 7 | default = spidyquotes.settings 8 | 9 | [deploy] 10 | #url = http://localhost:6800/ 11 | project = spidyquotes 12 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/spidyquotes/spidyquotes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/spidyquotes/spidyquotes/__init__.py -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/spidyquotes/spidyquotes/items.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define here the models for your scraped items 4 | # 5 | # See documentation in: 6 | # https://docs.scrapy.org/en/latest/topics/items.html 7 | 8 | import scrapy 9 | 10 | 11 | class SpidyquotesItem(scrapy.Item): 12 | # define the fields for your item here like: 13 | # name = scrapy.Field() 14 | pass 15 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/spidyquotes/spidyquotes/pipelines.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define your item pipelines here 4 | # 5 | # Don't forget to add your pipeline to the ITEM_PIPELINES setting 6 | # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html 7 | 8 | 9 | class SpidyquotesPipeline(object): 10 | def process_item(self, item, spider): 11 | return item 12 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/spidyquotes/spidyquotes/spiders/__init__.py: -------------------------------------------------------------------------------- 1 | # This package will contain the spiders of your Scrapy project 2 | # 3 | # Please refer to the documentation for information on how to create and manage 4 | # your spiders. 5 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/spidyquotes/spidyquotes/spiders/spidy.py: -------------------------------------------------------------------------------- 1 | import json 2 | import scrapy 3 | 4 | 5 | class SpidyQuotesSpider(scrapy.Spider): 6 | name = 'spidyquotes' 7 | quotes_base_url = 'http://spidyquotes.herokuapp.com/api/quotes?page=%s' 8 | start_urls = [quotes_base_url % 1] 9 | download_delay = 1.5 10 | 11 | def parse(self, response): 12 | data = json.loads(response.body) 13 | for item in data.get('quotes', []): 14 | yield { 15 | 'text': item.get('text'), 16 | 'author': item.get('author', {}).get('name'), 17 | 'tags': item.get('tags'), 18 | } 19 | if data['has_next']: 20 | next_page = data['page'] + 1 21 | yield scrapy.Request(self.quotes_base_url % next_page) 22 | -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/weather_img/cloud.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/weather_img/cloud.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/weather_img/rain.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/weather_img/rain.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/weather_img/snow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/weather_img/snow.jpg -------------------------------------------------------------------------------- /lesson_016/python_snippets/external_data/weather_img/sun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/python_snippets/external_data/weather_img/sun.jpg -------------------------------------------------------------------------------- /lesson_016/weather_cards/-weather-report-png-1200_630.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/weather_cards/-weather-report-png-1200_630.png -------------------------------------------------------------------------------- /lesson_016/weather_cards/CLOUD.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/weather_cards/CLOUD.jpg -------------------------------------------------------------------------------- /lesson_016/weather_cards/RAIN.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/weather_cards/RAIN.jpg -------------------------------------------------------------------------------- /lesson_016/weather_cards/SNOW.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/weather_cards/SNOW.jpg -------------------------------------------------------------------------------- /lesson_016/weather_cards/SUN.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zaboevai/python_base/c689568c926db5ff4f9cdb4f5c335fac7a434130/lesson_016/weather_cards/SUN.jpg --------------------------------------------------------------------------------