Модуль 2 · Урок 5 із 58

Типи, перетворення та числова точність

Тип — це не підпис біля змінної, а набір допустимих операцій і поведінки значення під час виконання. Навчимося бачити фактичний runtime type, перетворювати дані лише на межі системи й не плутати красивий output із точною арифметикою.

int / floatbool / NoneConversionPrecision

Безпечна практика модуля 2

Пакет містить тільки синтетичний rule router, decision table та локальні tests. Жодних реальних звернень, персональних даних, secrets, мережевих викликів або зовнішніх залежностей.

Завантажити практичний пакет →

Значення, тип і контракт

Python має динамічну типізацію: ім’я можна прив’язати до об’єкта одного типу, а згодом — до іншого. Це не означає, що типів немає. Навпаки, кожен об’єкт має конкретний runtime type, який визначає доступні операції. Перед арифметикою або порівнянням запитайте: звідки прийшло значення, який тип має зараз і який тип потрібен внутрішній логіці.

intЦілі числа без фіксованої машинної межі, доки вистачає пам’яті.
floatДвійкове наближення дійсного числа; зручне для вимірювань, але не гарантує десяткової точності.
boolДва значення — True і False; у прикладному коді використовуйте їх як логіку, не як приховані 1 і 0.
NoneОкремий singleton для «значення відсутнє», а не порожній рядок, нуль або помилка.
strТекст. Навіть рядок "42" не стає числом без явного перетворення.
type evidencetype() допомагає досліджувати, а isinstance() — перевіряти допустимий тип у контрольованій межі.

Перетворюйте на вході, далі працюйте з одним типом

CLI, HTTP і CSV часто передають текст. Хороша межа системи читає сире значення, нормалізує пробіли, виконує одне явне перетворення, перевіряє доменні межі й лише тоді передає типізоване значення в бізнес-логіку. Не розкидайте int() або float() по всьому коду — тоді незрозуміло, де саме значення стало валідним.

raw_minutes = " 45 "
minutes = int(raw_minutes.strip())

if minutes < 5 or minutes > 240:
    print("Тривалість поза дозволеним діапазоном")
else:
    print(f"Сесію заплановано на {minutes} хв.")

Перетворення відповідає лише на питання «чи має текст форму числа». Перевірка меж відповідає на інше: «чи дозволене це число в нашому сценарії». Значення -20 успішно перетвориться на int, але може бути неприйнятним для тривалості.

None — це відсутність, а не нуль

Якщо optional-значення ще не визначене, використовуйте None і перевіряйте identity через is None. Нуль може бути повністю валідним результатом, а порожній рядок — навмисним текстом. Змішування цих станів руйнує аналітику й умови.

discount_percent = None

if discount_percent is None:
    print("Знижку ще не розраховано")
elif discount_percent == 0:
    print("Розраховано: знижки немає")
else:
    print(f"Знижка: {discount_percent}%")
Контракт станів

None — невідомо або відсутнє; 0 — відоме нульове значення; False — негативний логічний результат. Документуйте ці стани окремо.

Чому 0.1 + 0.2 не обов’язково дорівнює 0.3

float зберігає числа у двійковому форматі. Багато десяткових дробів не мають точного двійкового представлення, тому після операцій залишається мала похибка. Форматування .2f змінює відображення, а не внутрішнє значення.

from math import isclose

observed = 0.1 + 0.2
expected = 0.3

print(observed)                         # 0.30000000000000004
print(observed == expected)             # False
print(isclose(observed, expected))      # True

Для фізичних вимірювань порівнюйте з обґрунтованою толерантністю. Для грошей оберіть явну політику: наприклад, зберігайте найменші одиниці як int або використовуйте десятковий тип із визначеним округленням. «Просто округлити в print» недостатньо.

Практика: таблиця меж

До коду складіть decision table для тривалості сесії: порожній текст, abc, 0, 4, 5, 45, 240 і 241. Для кожного case запишіть raw input, очікуваний тип після conversion, допустимість і очікуваний output. Запустіть лише після того, як очікування зафіксоване.

Happy pathЗвичайне значення всередині діапазону.
BoundaryРівно мінімум і рівно максимум.
OutsideНа одиницю нижче та вище межі.
RepresentationПробіли, знак, десятковий текст для цілого поля.
MissingПорожній input або None як окремий стан.
EvidenceЗбережіть команду, input, expected і observed без секретів.

Типові помилки

  • Порівнювати число з рядком: minutes > "30".
  • Використовувати bool("False") як parser: будь-який непорожній рядок truthy.
  • Вважати 0, False, "" і None одним бізнес-станом.
  • Порівнювати результати float-обчислень через точну рівність без аналізу похибки.
  • Показати два знаки після коми й зробити висновок, що збережене значення стало точним.

Методичні джерела

Урок, сценарії, пояснення й вправи створені SEOWORK. Посилання ведуть лише на офіційну документацію Python.

Практична перевірка · урок 5 з 47

Закріпіть матеріал уроку

Три сценарні питання. Для зарахування уроку потрібно дати щонайменше дві правильні відповіді.

1. CLI отримав raw_minutes=' 45 '. Яка послідовність найкраще розділяє representation і domain validation?
2. Знижку ще не розраховано, але нульова знижка є валідним результатом. Яке початкове значення зберігає цю різницю?
3. Чому bool('False') не можна використовувати як надійний parser текстового boolean-поля?