<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Вопросы по прошлому занятию
Какой магический метод объекта A дает возможность сделать операцию A * B?
Как задаются поля и методы объекта класса и поля и методы объекта экземпляра этого класса? В чем разница между этими понятиями?
Для чего нужен super()?
Что такое @property?
Какой модуль Python позволяет создавать контексты без использования классов?
В чем разница между CPU-bound задачами и I/O-bound задачами?
Какие основные недостатки использования процессов вместо потоков?
Ненадолго возвращаясь к боту
Step1:  Решение задачи на sleepsort
Step2:  Асинхронность и параллельность
Параллельность - это выполнение двух фрагментов кода одновременно.
Асинхронность - это выполнение кода НЕ последовательно.
Асинхронность может быть реализована с помощью параллельности, а может - с помощью ручного переключения контекста в самом коде, с сохранением последнего состояния. Ничего не напоминает?
Когда куски кода сами решают, когда передавать управление друг другу, и не зависят от внешнего системного планировщика, то это называется "кооперативной многозадачностью", а эти куски кода - корутинами или сопрограммами.
Недостаток - долгоиграющая процедура НЕ под контролем event loop'а вешает вообще ВСЕ
Событийно-ориентированное программирование
Две основные составляющие асинхронного кода - это event loop (цикл отлова событий) и корутины
Пока корутина ждет внешнее событие - контекст переключается на другую
Помимо переключения контекста корутины могут отправлять друг другу сообщения
К сожалению, в современной реализации асинхронности в Python обычные и асинхронные функции не являются взаимозаменяемыми
Альтернативные реализации для старых версий - Gevent, Eventlet и Tornado. И еще несколько.
Asyncio
Step3:  Ключевые слова async и await
Step4:  Упражнение
Напишите асинхронную реализацию sleepsort
Step5:  Django
http
Step6:  А где там html?
Создаем папки templates и static
Я взял шаблон http
Step7:  Меняем пути в шаблоне
Ну и последнее - меняем шаблон
На верх index.html дописываем такое
<ASSISTANT_TASK:>
Python Code:
import yaml
import random
with open("answers.yaml", "r") as conf:
    config = yaml.load(conf)
    
def get_answer(message):
    lower_msg = message.lower()
    for key in config['answers']:
        if key in lower_msg:
            return random.choice(config['answers'][key])
Explanation: Вопросы по прошлому занятию
Какой магический метод объекта A дает возможность сделать операцию A * B?
Как задаются поля и методы объекта класса и поля и методы объекта экземпляра этого класса? В чем разница между этими понятиями?
Для чего нужен super()?
Что такое @property?
Какой модуль Python позволяет создавать контексты без использования классов?
В чем разница между CPU-bound задачами и I/O-bound задачами?
Какие основные недостатки использования процессов вместо потоков?
Ненадолго возвращаясь к боту
End of explanation
import random
import threading
import time
class SleepThread(threading.Thread):
    def __init__(self, num):
        super().__init__()
        self.num = num
    
    def run(self):
        time.sleep(self.num)
        print(self.num)
        
a = [random.randint(0, 10) for _ in range(10)]
threads = [SleepThread(i) for i in a]
for t in threads:
    t.start()
def sleep_print(num):
    time.sleep(num)
    print(num)
a = [random.randint(0, 10) for _ in range(10)]
threads = [
    threading.Thread(target=sleep_print, args=(i,))
    for i in a
]
for t in threads:
    t.start()
import concurrent.futures as cf
def hold_my_beer(num):
    time.sleep(num)
    return num
a = [random.randint(0, 10) for _ in range(10)]
with cf.ThreadPoolExecutor(max_workers=len(a)) as pool:
    for future in cf.as_completed([
        pool.submit(hold_my_beer, i) for i in a
    ]):
        print(future.result())
Explanation: Решение задачи на sleepsort
End of explanation
import asyncio
asyncio.Queue()  # асинхронная очередь
asyncio.sleep(10)  # асинхронный "сон"
asyncio.create_subprocess_exec()  # асинхронный subprocess
asyncio.Lock()  # асинхронный мьютекс
asyncio.ensure_future()  # ручное добавление корутины в event loop
asyncio.gather()  # дождаться окончания работы списка корутин
Explanation: Асинхронность и параллельность
Параллельность - это выполнение двух фрагментов кода одновременно.
Асинхронность - это выполнение кода НЕ последовательно.
Асинхронность может быть реализована с помощью параллельности, а может - с помощью ручного переключения контекста в самом коде, с сохранением последнего состояния. Ничего не напоминает?
Когда куски кода сами решают, когда передавать управление друг другу, и не зависят от внешнего системного планировщика, то это называется "кооперативной многозадачностью", а эти куски кода - корутинами или сопрограммами.
Недостаток - долгоиграющая процедура НЕ под контролем event loop'а вешает вообще ВСЕ
Событийно-ориентированное программирование
Две основные составляющие асинхронного кода - это event loop (цикл отлова событий) и корутины
Пока корутина ждет внешнее событие - контекст переключается на другую
Помимо переключения контекста корутины могут отправлять друг другу сообщения
К сожалению, в современной реализации асинхронности в Python обычные и асинхронные функции не являются взаимозаменяемыми
Альтернативные реализации для старых версий - Gevent, Eventlet и Tornado. И еще несколько.
Asyncio
End of explanation
import asyncio
async def hello(name):
    return "Hello, {}!".format(name)
hello("Vasya")
await hello("Vasya")
import asyncio
async def hello(name):
    return "Hello, {}!".format(name)
async def call_vasya():
    greeting = await hello("Vasya")
    return greeting
    
loop = asyncio.get_event_loop()
print(loop.run_until_complete(call_vasya()))
Explanation: Ключевые слова async и await
End of explanation
import asyncio
import random
async def hold(num):
    await asyncio.sleep(num)
    return num
a = [random.randint(0, 10) for _ in range(10)]
Explanation: Упражнение
Напишите асинхронную реализацию sleepsort
End of explanation
# hello/views.py
from django.http import HttpResponse
def index(request):
    return HttpResponse("Hello!")
# hello/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.index, name='index'),
]
# urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
    url(r'^hello/', include('hello.urls')),
    url(r'^admin/', admin.site.urls),
]
Explanation: Django
http://www.djangoproject.com/
http://djbook.ru  # немного устарело!
~$ pip install django
~$ django-admin startproject mysite
~$ python manage.py runserver
Основные термины веб-разработчика на Python
HTTP (https://ru.wikipedia.org/wiki/HTTP), оно же HyperText Transfer Protocol
сетевой порт (http://bit.ly/1Mxp4Ks) и сокет (http://bit.ly/1Oxntiq)
WSGI (https://ru.wikipedia.org/wiki/WSGI), оно же Web Server Gateway Interface
MVC (https://ru.wikipedia.org/wiki/Model-View-Controller), оно же Model-View-Controller
~$ python manage.py startapp hello
End of explanation
# Добавляем в settings.py строчки
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static")
]
# а также похожую строчку в TEMPLATES["DIRS"]:
os.path.join(BASE_DIR, "templates")
# а в urls.py делаем так:
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
urlpatterns = [
    url(r'^hello/', include('hello.urls')),
    url(r'^admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
# hello/views.py
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
    return render(request, 'index.html', {})
Explanation: А где там html?
Создаем папки templates и static
Я взял шаблон http://html5up.net/photon , можете найти и скачать любой другой
Переносим папки assets и images внутрь папки static
End of explanation
# my_application.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
    return "Hello, World!"
Explanation: Меняем пути в шаблоне
Ну и последнее - меняем шаблон
На верх index.html дописываем такое: {% load static %}
А пути к статике меняем на шаблонные теги:
    "assets/css/main.css" -> {% static 'assets/css/main.css' %}
На боевом сервере такими вещами будет заниматься не сам Django, а сервер статики, например, Nginx. Это важно!
Рекомендую еще почитать про uWSGI - https://uwsgi-docs.readthedocs.io/en/latest/
Flask
~$ pip install flask
End of explanation
<END_TASK>