⚖️ Старый и современный подход

⚡ Различия в двух словах

Классический: базовые циклы while с конкатенацией строк и простыми условиями — надёжная основа.

Современный: guard clauses для раннего выхода, f-strings вместо конкатенации, оператор «морж» := для чтения ввода в условии цикла.

Вывод: современные приёмы делают код короче и читаемее, но классические паттерны важно знать, чтобы понимать, как работает цикл под капотом.

📜 Классический подход из источника

Исходный материал урока даёт фундаментальные паттерны: счётчик, обратный отсчёт, накопление суммы, ввод с проверкой. Эти примеры остаются корректными и рабочими, но их можно записать в более современном стиле.

📄 examples/classic_input_loop.py
user_input = input("Enter a number (exit to stop): ")
while user_input != "exit":
    num = int(user_input)
    print("Square:", num * num)
    user_input = input("Enter a number (exit to stop): ")

Что здесь происходит: строка ввода дублируется до цикла и внутри него. Это классический способ чтения данных с предусловием, но он требует повторять вызов input() дважды.

❌ Что можно улучшить

  • Дублирование кода: приходится писать input() до цикла и в конце каждой итерации.
  • Конкатенация строк: в исходных примерах иногда используется "Введите " + str(num) + "-е число" вместо f-string.
  • Вложенные условия: без guard clauses проверки на выход и на пропуск могут создавать лишние отступы.

✅ Рекомендуемый современный вариант

1. Оператор «морж» для ввода в условии

С Python 3.8 можно присвоить значение и сразу проверить его внутри while.

📄 examples/modern_walrus_loop.py
while (user_input := input("Enter a number (exit to stop): ")) != "exit":
    num = int(user_input)
    print(f"Square: {num * num}")

Что улучшилось: вызов input() написан один раз, код короче и не дублирует приглашение.

2. f-strings вместо конкатенации

📄 examples/modern_fstrings.py
# Classic
print("You entered " + str(num) + " numbers.")

# Modern
print(f"You entered {num} numbers.")

3. Guard clauses для раннего выхода

Вместо вложенных if-else внутри цикла проверяйте исключительные случаи в начале тела и переходите к следующей итерации.

📄 examples/modern_guard_clauses.py
total = 0

while True:
    raw = input("Enter a number (0 to stop): ")
    if raw == "0":
        break

    num = int(raw)
    if num < 0:
        continue

    total += num

print(f"Total sum of positive numbers: {total}")
Преимущества современного стиля:
  • Меньше дублирования кода.
  • Условия читаются как «правила входа» в итерацию.
  • f-strings быстрее и нагляднее конкатенации.
  • Меньше вложенности — меньше ошибок с отступами.

🔢 Точность float и math.isclose

В задачах с плавающей точкой современный стиль — не сравнивать float через ==, а использовать math.isclose().

📄 examples/float_while.py
import math

x = 0.0
while not math.isclose(x, 1.0):
    x += 0.1
    print(round(x, 2))
Проверить по документации: оператор «морж» := (PEP 572), f-strings (PEP 498) и math.isclose() описаны в официальной документации Python.

🕰️ Когда классический подход ещё уместен

Классические примеры с явной инициализацией, условием и инкрементом остаются лучшим способом объяснить цикл новичкам. В production-коде современные приёмы делают программы компактнее, но понимание базового механизма обязательно для отладки бесконечных циклов и off-by-one ошибок.