# Домашнє завдання · Тема 24 · Скрипти командного рядка

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

Усі три рівні — про один і той самий файл `pohoda.py`. Ми більше не пишемо код у зошиті:
кожен рівень закінчується тим, що ти **запускаєш скрипт із термінала** й дивишся, що він
відповів.

Дані для роботи зроби сам — маленький CSV на 6-8 рядків, щоб підсумок можна було
порахувати в голові й звірити:

```
misto,data,temperatura,opady
Київ,2026-07-01,24.5,0.0
Львів,2026-07-01,21.0,3.2
Київ,2026-07-02,27.1,0.0
...
```

Працюй у власній теці. Тимчасові файли з практики видалилися самі — тут ти господар.

---

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

Напиши `pohoda.py`, який приймає **один позиційний аргумент** — шлях до CSV — і друкує
середню температуру. Додай необовʼязковий `-m` / `--misto`: якщо його передали, рахуй
лише по рядках цього міста.

Обовʼязково:

- увесь код у функції `main()`, яка **повертає** код виходу;
- унизу файлу `if __name__ == "__main__": sys.exit(main())`;
- результат — у `stdout`, повідомлення про помилки — у `stderr`;
- якщо файл не відкрився — повідомлення в `stderr` і `return 1`.

**Зроблено, якщо:** усі чотири команди нижче поводяться саме так, як написано, і ти
перевірив кожну через `echo $?` (у PowerShell — `echo $LASTEXITCODE`):

| команда | що має статися |
|---|---|
| `python3 pohoda.py dani.csv` | середня температура по всіх рядках, код `0` |
| `python3 pohoda.py dani.csv --misto Київ` | середня лише по Києву, код `0` |
| `python3 pohoda.py` | повідомлення про брак аргументу, код `2` |
| `python3 pohoda.py nemaye.csv` | твоє повідомлення в `stderr`, код `1` |

---

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

Доростимо скрипт до утиліти, яку не соромно дати колезі.

1. Додай `-d` / `--dija` з `choices=["serednya", "maksymum", "minimum"]` і типовим
   значенням `serednya`.
2. Додай `-t` / `--tochnist` із `type=int` і `default=1`.
3. Додай прапорець `--tyho` (`action="store_true"`), який прибирає з виводу весь текст —
   лишається голе число.
4. У кожен `help=` встав `%(default)s` там, де є типове значення.
5. Додай `description=` — одне речення про те, що робить скрипт.

Потім **не заглядаючи у власний код**, запусти `python3 pohoda.py -h` і прочитай, що
вийшло. Якщо з довідки незрозуміло, як користуватись скриптом, — виправляй тексти
`help=`, а не додавай пояснення в `print`.

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

- `python3 pohoda.py dani.csv -d maksymum -t 0 --tyho` друкує рівно одне число без
  жодного слова, і його можна передати далі: `python3 pohoda.py dani.csv --tyho | cat`
  дає той самий рядок;
- `python3 pohoda.py dani.csv -d medi` завершується кодом `2`, і в повідомленні видно
  перелік дозволених значень (ти цього переліку руками не писав);
- `python3 pohoda.py dani.csv > rezultat.txt` кладе у файл **тільки** результат, а
  службові повідомлення (якщо вони в тебе є) лишаються на екрані;
- у виводі `-h` є рядок `-h, --help`, якого ти не додавав.

---

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

Три окремі задачі. Кожну можна зробити незалежно.

**А. Конвеєр.** Навчи скрипт читати зі `stdin`, коли замість імені файлу передали
одинокий дефіс `-`. Перевір роботу в справжньому конвеєрі:

```
cat dani.csv | python3 pohoda.py - --misto Львів
```

**Б. Власна перевірка типу.** Напиши функцію `nevidjemne_cile(tekst)`, яка повертає
`int`, а на відʼємному числі кидає `argparse.ArgumentTypeError` зі своїм поясненням
українською. Підстав її в `type=` для `--tochnist`.

**В. Кілька файлів і підкоманди.** Або зроби позиційний аргумент `nargs="+"` і навчи
скрипт рахувати спільний підсумок по кількох файлах, або розбий утиліту на дві
підкоманди через `add_subparsers()`: `pohoda.py temperatura dani.csv` і
`pohoda.py opady dani.csv`, кожна зі своїм набором аргументів.

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

- **А:** `cat dani.csv | python3 pohoda.py -` дає точно той самий рядок, що й
  `python3 pohoda.py dani.csv`, і код виходу в обох випадках `0`;
- **Б:** `python3 pohoda.py dani.csv --tochnist -1` завершується кодом `2`, а в `stderr`
  видно **твоє** повідомлення, а не стандартне `invalid int value`;
- **В:** для `nargs="+"` — сума по двох файлах дорівнює сумі підсумків по кожному
  окремо (перевір `assert`-ом у окремому файлі-тесті); для підкоманд — `pohoda.py -h`
  показує перелік підкоманд, а `pohoda.py opady -h` показує довідку саме цієї
  підкоманди.

---

## Підказки

- Не гадай, що вийшло, — питай скрипт: `python3 pohoda.py -h` після кожної зміни
  показує актуальний стан справ, бо збирається з того самого опису, що й розбір.
- Найшвидший спосіб побачити, що саме приїхало в аргументах, — тимчасово поставити
  `print(args, file=sys.stderr)` одразу після `parse_args()`. У `Namespace` видно всі
  поля разом із підставленими типовими значеннями.
- Функція для `type=` приймає **один рядок** і повертає готове значення. Щоб
  повідомлення вийшло людським, кидай саме `argparse.ArgumentTypeError`: `ValueError`
  теж спрацює, але текст argparse замінить своїм.
- Щоб перевірити розділення потоків, не треба нічого рахувати: `python3 pohoda.py
  dani.csv > /dev/null` має лишити на екрані **тільки** службові повідомлення, а
  `python3 pohoda.py dani.csv 2> /dev/null` — **тільки** результат.
- Якщо не хочеться щоразу писати `python3`: перший рядок `#!/usr/bin/env python3`
  плюс `chmod +x pohoda.py` — і скрипт запускається як `./pohoda.py dani.csv`.
