Три рівні. Кожен наступний спирається на попередній, але братися можна за будь-який.
Пиши в окремому файлі homework_07.py або в новому зошиті — головне, щоб код
запускався й друкував результат.
Дозволено з бібліотек: math, collections. Більше нічого не треба.
Циклів, умов і власних функцій тема ще не проходила — але якщо ти вже знаєш їх
з іншого джерела, користуйся спокійно: перевіряється результат, а не засоби.
Вихідні дані для всіх рівнів:
міста = (
("Київ", 50.45, 30.52),
("Львів", 49.84, 24.03),
("Одеса", 46.48, 30.73),
("Харків", 49.99, 36.23),
)
рівень 1Рівень 1 — База
1.1 · Кома, яка все ламає
Напиши чотири рядки, які створюють: число, кортеж з одного елемента,
той самий кортеж без дужок і порожній кортеж. Надрукуй для кожного значення
його type(...).__name__ і len(...) там, де довжина існує.
Зроблено, якщо: у виводі видно, що (7) — це int, а (7,) і 7, —
однакові кортежі довжиною 1, і виконуються перевірки
assert type(без_коми) is int
assert з_комою == без_дужок and len(з_комою) == 1
assert len(порожній) == 0 and type(порожній) is tuple
1.2 · Розпакування запису міста
Візьми перший запис із міста і розпакуй його трьома різними шаблонами:
- на три окремі імена
назва, широта, довгота; - на назву й решту через зірочку:
назва, *координати; - вкладено, попередньо перепакувавши запис у форму
("Київ", (50.45, 30.52)).
Надрукуй результат кожного шаблону.
Зроблено, якщо: усі три шаблони дають ті самі числа, і це доведено:
assert (широта, довгота) == tuple(координати) == пара_з_вкладеного
assert isinstance(координати, list), "зірочка дає СПИСОК, а не кортеж"
1.3 · Спіймай обидві помилки
Спробуй змінити елемент кортежа й спробуй дописати в нього елемент.
Обидві спроби мають впасти. Випиши словами (коментарем у коді),
чим TypeError у першому випадку відрізняється від AttributeError у другому.
Зроблено, якщо: у виводі є обидва повні тексти помилок і твоє пояснення різниці між «операція заборонена для цього типу» і «такого методу не існує».
рівень 2Рівень 2 — Плюс
2.1 · Найпівнічніше місто без сортування на місці
Знайди місто з найбільшою широтою. Кортеж міста змінювати не можна —
і не вийде: у нього немає sort(). Скористайся sorted(...), який повертає
новий список, або max(...) з key.
Надрукуй назву міста-переможця та його координати парою.
Зроблено, якщо: твій код друкує Київ із парою (50.45, 30.52), а вихідний
кортеж лишився недоторканим:
assert міста[0][0] == "Київ" and len(міста) == 4
assert найпівнічніше[0] == "Київ"
Додатково поясни двома реченнями, чому sorted(міста) спрацює, а міста.sort() — ні.
2.2 · Довжина замкненого маршруту
Порахуй довжину маршруту Київ → Львів → Одеса → Харків → Київ.
Відстань між двома точками бери як math.dist(точка_1, точка_2),
а самі точки діставай із записів розпакуванням, а не індексами
(_, широта, довгота = запис).
Зроблено, якщо: результат збігається з ручним підсумовуванням чотирьох відрізків і виконується нерівність трикутника — замкнений маршрут не коротший за подвоєну пряму між найдальшою парою міст:
assert math.isclose(довжина, відрізок_1 + відрізок_2 + відрізок_3 + відрізок_4)
assert довжина >= 2 * max_пряма
2.3 · Пастка незмінності
Створи кортеж спостереження = ("Київ", [12.0, 13.5, 11.2]), де список —
це виміри температури. Зроби так, щоб:
- спроба замінити список цілком (
спостереження[1] = [...]) впала; - дописування нового виміру (
спостереження[1].append(...)) спрацювало; hash(спостереження)теж впав.
Зроблено, якщо: у виводі видно всі три результати, і ти показав числом, що адреса списку не змінилась:
адреса_до = id(спостереження[1])
спостереження[1].append(14.1)
assert id(спостереження[1]) == адреса_до, "слот кортежа мав лишитись тим самим"
assert спостереження[1] == [12.0, 13.5, 11.2, 14.1]
І поясни двома реченнями, чому hash падає саме через це.
рівень 3Рівень 3 — Виклик
3.1 · Симетричний ключ-пара
Побудуй словник відстаней, у якого ключ — пара міст, а значення — відстань
між ними. Проблема: ("Київ", "Львів") і ("Львів", "Київ") — це два різні
ключі, бо кортежі порівнюються поелементно, зліва направо.
Зроби ключ таким, щоб порядок міст не мав значення, і заповни словник для всіх шести пар із чотирьох міст.
Зроблено, якщо: у словнику рівно 6 записів, і виконується
assert len(відстані) == 6
assert ключ("Київ", "Львів") == ключ("Львів", "Київ")
assert math.isclose(відстані[ключ("Львів", "Київ")], math.dist(київ, львів))
Підказка вже була в практиці:
tuple(sorted(...)). Подумай, чому самеtuple(...), а не простоsorted(...).
3.2 · Свій namedtuple на голому кортежі
Не використовуючи collections.namedtuple, зроби «іменований доступ» до записів:
словник поля = {"назва": 0, "широта": 1, "довгота": 2} і функцію
поле(запис, імʼя), яка повертає потрібний елемент.
Потім зроби те саме через справжній namedtuple і порівняй.
Зроблено, якщо: обидва підходи дають однакові значення на всіх чотирьох
містах, і ти сформулював двома-трьома реченнями, що саме дає namedtuple
понад твій словник полів:
Місто = namedtuple("Місто", "назва широта довгота")
київ_іменований = Місто(*міста[0]) # розпакування кортежа в аргументи
assert поле(міста[0], "широта") == київ_іменований.широта
assert isinstance(київ_іменований, tuple)
assert київ_іменований == міста[0]
3.3 · Де кортеж перестає бути надійним
Досліди межу гарантії незмінності. Побудуй два кортежі однакової форми:
один із самих лише незмінних елементів, другий — зі списком усередині.
Для кожного перевір три речі: чи береться hash, чи можна покласти в множину
{...} і чи змінюється вміст після дії над внутрішнім обʼєктом.
Зроблено, якщо: результати зведені в таблицю (можна просто трьома
print-ами по рядку), усі три перевірки для другого кортежа дають «ні / ні / так»,
і сформульоване правило одним реченням: за яких умов кортеж справді гарантує
незмінність даних, а не лише незмінність набору посилань.
Підказки
- Не бійся
assert. Це не «перевірка для викладача», а спосіб зафіксувати, що саме ти вважаєш правильним. Коли він падає — ти дізнався щось нове про свій код, і це найдешевший спосіб дізнатися. - У 2.1 стеж за тим, що повертає функція.
sorted()завжди повертає список, навіть якщо на вхід дали кортеж. Якщо тобі потрібен кортеж назад — приведи явно. - У 3.1 подумай про хешованість, а не про сортування. Питання не в тому, як відсортувати два рядки, а в тому, чому результат сортування не можна покласти в ключ без перетворення.
- Помилки читай до кінця.
TypeError: 'tuple' object does not support item assignmentіAttributeError: 'tuple' object has no attribute 'append'— це дві різні історії, і плутати їх на співбесіді нічим не краще, ніж у коді.