⚖️ Современный стиль повторения

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

Классический: базовые циклы while с конкатенацией строк, повторяющийся input() и вложенные условия.

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

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

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

Исходный материал уроков 12–14 даёт фундаментальные паттерны: счётчик, цикл с input(), конкатенация строк, явные индексы. Эти примеры остаются корректными, но в современном коде их можно записать короче.

📄 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].

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

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(count) + " numbers.")

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

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

Проверяйте исключительные случаи в начале тела и переходите к следующей итерации, чтобы уменьшить вложенность.

📄 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}")

4. Срезы вместо ручного цикла

Для переворота строки или проверки палиндрома современный код использует срез [::-1].

📄 examples/modern_slice.py
# Classic loop version
text = input("Enter a word: ")
reversed_text = ""
index = len(text) - 1
while index >= 0:
    reversed_text += text[index]
    index -= 1
print(f"Reversed: {reversed_text}")

# Modern version
text = input("Enter a word: ")
print(f"Reversed: {text[::-1]}")
Преимущества современного стиля:
  • Меньше дублирования кода.
  • Условия читаются как «правила входа» в итерацию.
  • f-strings нагляднее и быстрее конкатенации.
  • Срезы делают код короче для типовых операций со строками.

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

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