# Домашнє завдання · Що таке програмування і навіщо Python

> Лекція: [lecture.html](lecture.html) · Практика: [practice.ipynb](practice.ipynb) · Тест: [quiz.html](quiz.html)

Ця тема — про розуміння, а не про синтаксис. Тому й завдання такі: не «напиши сортування»,
а «переконайся власними очима, що машина працює так, як ми сказали».

Усе робиться в тому самому зошиті `practice.ipynb` — додай клітинки в кінець
або зроби копію файлу.

---

## 🟢 Рівень 1 — База

**Три маленькі задачі.**

1. **Своє привітання.** Створи змінні `моє_ім_я` та `улюблена_страва` і надрукуй
   одним `print` речення, яке використовує обидві. Потім зміни значення однієї зі
   змінних і надрукуй ще раз — тим самим рядком коду.
2. **Порядок вирішує.** Візьми число 12. Напиши два блоки по три рядки: у першому
   спершу відніми 2, потім поділи на 5; у другому — навпаки. Надрукуй обидва
   результати з підписами.
3. **Алгоритм побутовою мовою.** Опиши текстом (не кодом) алгоритм із 5-8 кроків
   для чогось звичного: заварити чай, дійти від дому до магазину, зібрати рюкзак.
   Умова: **жодного кроку на кшталт «за смаком» чи «доки не буде готово»** — кожен
   крок має бути перевірним. Поряд напиши, який крок було найважче зробити однозначним.

**Зроблено, якщо:** усі три клітинки виконуються без помилок; у задачі 2 два числа
різні (2 і 0.4); в алгоритмі немає жодного кроку, який виконавець міг би зрозуміти
двома різними способами.

---

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

**Колекція власних помилок.**

Зламай код навмисно **чотирма різними способами** — не тими, що були в практиці.
Кожну помилку злови через `try / except` (або познач клітинку так, щоб вона впала)
і надрукуй traceback.

Візьми чотири різні типи з цього переліку:

| Тип | Як його отримати |
|---|---|
| `ZeroDivisionError` | поділити на нуль |
| `IndexError` | звернутись до неіснуючого елемента списку |
| `ValueError` | `int("привіт")` |
| `AttributeError` | попросити в числа те, чого в нього немає |
| `KeyError` | взяти з `{"a": 1}` ключ `"b"` |
| `IndentationError` | зайвий пробіл на початку рядка (перевір через `compile`) |

Під кожним traceback напиши коментарем **три речі**: назву типу помилки, номер
винного рядка й одне речення про те, що саме сталося.

**Зроблено, якщо:** чотири різні типи помилок, для кожного надруковано справжній
traceback і є коментар із трьома пунктами; зошит виконується наскрізь без падіння.

---

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

**Заміряй свою машину й порівняй із лекцією.**

Інтерактив 6 у лекції показував **модель**: крок циклу в CPython ≈ 45 нс, елемент
векторної операції NumPy ≈ 1.2 нс. Перевір це на своєму комп'ютері.

1. Через `timeit` заміряй час `sum(range(N))` і час `масив.sum()` для NumPy
   при чотирьох значеннях `N`: 10 тисяч, 100 тисяч, 1 мільйон, 10 мільйонів.
2. Для кожного `N` порахуй **час на одну операцію в наносекундах** і надрукуй
   таблицю: `N`, час Python, час NumPy, нс на операцію для обох, відношення.
3. Відповідь словами на два питання:
   - Чи стала вартість однієї операції сталою, коли `N` зростав? Якщо на малих `N`
     NumPy виглядає гірше, ніж мав би, — чому? (Підказка: у лекції згадувалися
     сталі витрати на виклик.)
   - При якому приблизно `N` різниця між Python і NumPy перестає бути
     непомітною для людини (тобто Python починає займати більш ніж 0.1 секунди)?

**Зроблено, якщо:** таблиця з чотирьох рядків надрукована; вартість однієї операції
для NumPy на великих `N` менша, ніж на малих (і ти пояснив чому); названо порогове
`N` із числом, а не «десь багато».

**Додатково, для тих, кому мало:** порівняй байт-код двох виразів через `dis.dis` —
`2 * 3 * 4` і `x * 3 * 4`. Порахуй інструкції в кожному й поясни різницю одним абзацом.

---

## Підказки

- **Не бійся червоного тексту.** Traceback — не покарання, а звіт. Читай його знизу
  вгору: останній рядок каже *що* сталося, передостанні — *де*.
- **Одна клітинка — одна думка.** Якщо клітинка робить три речі й падає, ти не знаєш,
  на якій саме. Розділяй.
- **Для рівня 3** не міряй час одним запуском: `timeit.timeit(..., number=5)` і поділи
  на 5. Одиничний вимір легко зіпсує будь-який фоновий процес.
- **Для рівня 3** пам'ятай, що `timeit` повертає секунди. Наносекунда — це 10⁻⁹ секунди,
  тож нс на операцію = `час_у_секундах / N * 1e9`.
- Якщо щось не запускається — перевір, чи виконав ти клітинки **вище**. Змінна, створена
  в клітинці, якої ти не запускав, для Python не існує.
