├── .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
--------------------------------------------------------------------------------