Домашнє завдання

Асинхронність — базово

Предметна область тут інша, ніж у лекції, — навмисно. У практиці ми «завантажували звіти», тут працюємо з чергою листів для розсилки: на кожен лист поштовий сервіс відповідає із затримкою, і затримки різні.

Мережу не використовуємо взагалі. Кожне звернення до сервісу імітуємо через asyncio.sleep — для механіки циклу подій різниці немає жодної, а завдання не залежить від інтернету й не турбує чужі сервери.

Усе роби в окремому файлі rozsylka.py або в новому зошиті — практику не редагуй, вона знадобиться для звірки.

Якщо працюєш у зошиті. asyncio.run() там впаде з RuntimeError — пиши await прямо в клітинці. Якщо працюєш у файлі .py — навпаки, await на верхньому рівні не можна, загортай усе в async def головна() і запускай через asyncio.run(головна()). Обидва способи розібрані в практиці.


рівень 1Рівень 1 — База

Зміряй секундоміром різницю між послідовним очікуванням і asyncio.gather.

  1. Напиши корутину надіслати(адреса, затримка): чекає затримка секунд і повертає рядок f"{адреса}: доставлено".
  2. Зроби список із п'яти адрес із затримками 0.1, 0.2, 0.3, 0.4, 0.5.
  3. Надішли їх послідовно — циклом із await усередині — і заміряй час через time.perf_counter().
  4. Надішли ті самі п'ять через asyncio.gather і заміряй час знову.
  5. Надрукуй обидва числа й відношення одного до одного.

Зроблено, якщо:


рівень 2Рівень 2 — Плюс

Додай помилки й перепиши все на сучасний спосіб.

  1. Перепиши запуск із gather на async with asyncio.TaskGroup(). Результати бери з обʼєктів задач через .result() після виходу з блоку.
  2. Додай шосту адресу "поштова-скринька-переповнена" із затримкою 0.1, яка кидає ConnectionError("скринька переповнена").
  3. Зроби так, щоб кожна успішна задача перед return дописувала свою адресу в список доставлені.
  4. Злови ExceptionGroup через except* і надрукуй: скільки задач упало, скільки встигло дійти до кінця й скільки часу протривала група.
  5. Зроби другий варіант того самого — через asyncio.gather(..., return_exceptions=True) — і надрукуй, чим два списки відрізняються.

Зроблено, якщо:


рівень 3Рівень 3 — Виклик

Знайди межу застосовності числами, а не словами.

  1. Побудуй табличку «кількість задач → загальний час» для 1, 2, 4, 8, 16, 32, 128 і 512 задач, кожна із затримкою 0.1 секунди. Для кожного рядка порахуй накладні витрати: вимір − 0.1.
  2. Зроби другу таку саму табличку, де замість await asyncio.sleep(0.1) кожна задача виконує обчислення приблизно на ті самі 0,1 секунди (наприклад, суму квадратів у циклі — підбери межу під свою машину).
  3. Постав дослід із time.sleep(0.1) замість asyncio.sleep(0.1) для 8 задач і заміряй час.
  4. Зміряй, скільки триває варіант із time.sleep, загорнутий у asyncio.to_thread.
  5. Напиши висновок на пʼять речень: за яких умов асинхронність варта ускладнення коду, а за яких ні. Спирайся на свої числа, а не на числа з лекції.

Зроблено, якщо:


Підказки