💻 Практические примеры

⚡ Минимальный рабочий пример

text = "Python"
for char in text:
    print(char, end=" ")
print()
# P y t h o n

Этот код выводит символы строки через пробел. В примерах ниже — более сложные задачи из практикума.

Практикум 4 — это 13 задач на один и тот же приём: перебор символов или чисел циклом for с накоплением результата (в строке, счётчике или множестве). Ниже — 11 примеров от простого к сложному, охватывающих все ключевые техники практикума: работу с ord()/chr(), ранний выход через break, аккумулятор и типичные ловушки на границах. Значения строк и чисел здесь заданы напрямую вместо input(), чтобы код можно было запустить целиком и сверить с реальным выводом — в интерактивной версии первая строка каждого примера заменяется на input(...).

Пример 1. Перевёрнутая лестница

Рисуем линию из звёздочек убывающей длины с помощью range(height, 0, -1).

📄 examples/reverse_stairs.py
height = 5   # в интерактивной версии: int(input("Введите высоту лестницы: "))

for i in range(height, 0, -1):
    print("*" * i)

Что происходит:

  1. Высота задана числом (в интерактивной версии — читается и преобразуется через int()).
  2. range(height, 0, -1) генерирует числа от height до 1 включительно, убывая.
  3. Оператор * повторяет строку "*" нужное число раз.

Пример 2. Проверка текста на ASCII

Проверяем, что код каждого символа не превышает 127, и прерываем цикл при первом нарушении.

📄 examples/ascii_check.py
text = "Python"
all_ascii = True
for char in text:
    if ord(char) > 127:
        all_ascii = False
        break
print("Все символы ASCII:", all_ascii)   # True

text = "Привет"
all_ascii = True
for char in text:
    if ord(char) > 127:
        all_ascii = False
        break
print("Все символы ASCII:", all_ascii)   # False — кириллица выходит за код 127
Проверить по документации: в Python есть метод str.isascii(), который делает то же самое. Для учебной задачи полезно понять логику вручную, но в реальном коде достаточно text.isascii().

Пример 3. Вывод строки с интервалами

Символы выводятся через пробел, но без лишнего пробела в конце. Авторское решение использует индекс и end — а это именно ошибка 7 из раздела «Ошибки», если забыть проверку последнего индекса.

📄 examples/spaced_output.py
text = "Python"

for i in range(len(text)):
    if i == len(text) - 1:
        print(text[i], end="")
    else:
        print(text[i], end=" ")
print()
# P y t h o n

Современный вариант:

📄 examples/spaced_output_modern.py
text = "Python"
print(*text, sep=" ")
# P y t h o n
Проверить по документации: распаковка аргументов *text в print() и параметр sep выходят за рамки исходной практики.

Пример 4. Проверка скобок

Считаем баланс открывающих и закрывающих круглых скобок. Если баланс уходит в минус — скобки расставлены неправильно, и цикл можно прервать раньше.

📄 examples/parenthesis_balance.py
text = "(a+b)*(c-d)"
balance = 0
for char in text:
    if char == "(":
        balance += 1
    elif char == ")":
        balance -= 1
    if balance < 0:
        break
print("Скобки расставлены правильно?", balance == 0)   # True

text = "(a+b)(*((c-d)"
balance = 0
for char in text:
    if char == "(":
        balance += 1
    elif char == ")":
        balance -= 1
    if balance < 0:
        break
print("Скобки расставлены правильно?", balance == 0)   # False

Почему так: баланс, оставшийся положительным (> 0) в конце, тоже означает ошибку — открывающих скобок больше, чем закрывающих. Проверка balance == 0 (а не просто «баланс не уходил в минус») ловит оба случая сразу.

Пример 5. Символ с минимальным кодом

Классический паттерн «текущий рекорд»: берём первый элемент как стартовое предположение и обновляем его при более подходящем варианте.

📄 examples/min_char.py
text = "Hello!"
min_char = text[0]
for char in text:
    if ord(char) < ord(min_char):
        min_char = char
print("Минимальный символ:", min_char)   # !

Что происходит: код символа "!" (33) меньше кодов всех букв, поэтому он и становится минимальным. Тот же паттерн (стартовое значение + обновление при более подходящем) уже встречался в уроке 16 и снова появится в примере 7 практикума 8 при поиске самого лёгкого животного.

Пример 6. Чётные и нечётные цифры числа

Число читается как строка, чтобы перебрать цифры по одной; каждая цифра проверяется на чётность и добавляется в одну из двух строк-аккумуляторов.

📄 examples/even_odd_digits.py
number = "238947203429"
even_digits = ""
odd_digits = ""
for digit in number:
    if int(digit) % 2 == 0:
        even_digits += digit
    else:
        odd_digits += digit
print("Число из чётных цифр:", even_digits if even_digits else "0")
print("Число из нечётных цифр:", odd_digits if odd_digits else "0")
# Число из чётных цифр: 2842042
# Число из нечётных цифр: 39739

number = "482262"
even_digits = ""
odd_digits = ""
for digit in number:
    if int(digit) % 2 == 0:
        even_digits += digit
    else:
        odd_digits += digit
print("Число из чётных цифр:", even_digits if even_digits else "0")
print("Число из нечётных цифр:", odd_digits if odd_digits else "0")
# Число из чётных цифр: 482262
# Число из нечётных цифр: 0 — нечётных цифр не нашлось совсем

Почему так: even_digits if even_digits else "0" — пустая строка ложна в логическом контексте, поэтому выражение подставляет "0", только если аккумулятор так и остался пустым. Без этой проверки вывод для 482262 был бы просто пустой строкой, а не 0, как требует условие.

Пример 7. Строка из диапазона Unicode

ord() и chr() — взаимно обратные функции: одна переводит символ в код, другая код обратно в символ. Здесь используется только вторая.

📄 examples/unicode_range.py
start_code = 65
end_code = 70
symbols = ""
for code in range(start_code, end_code + 1):
    symbols += chr(code)
print("Символы:", symbols)   # ABCDEF

Как проверить себя: range(start_code, end_code + 1), а не range(start_code, end_code) — иначе последний символ (F, код 70) потеряется. Это та же ловушка границ range(), что в ошибке 1 из раздела «Ошибки».

Пример 8. Длина каждого слова в строке

Слово накапливается посимвольно, пока не встретится пробел — а после цикла нужно не забыть вывести последнее слово, если строка не заканчивается пробелом.

📄 examples/word_lengths.py
text = "Программирование это весело"
word = ""
for char in text:
    if char != " ":
        word += char
    else:
        if word:
            print(f"Слово: {word}, Длина: {len(word)}")
            word = ""
if word:
    print(f"Слово: {word}, Длина: {len(word)}")
# Слово: Программирование, Длина: 16
# Слово: это, Длина: 3
# Слово: весело, Длина: 6

Почему так: внутри цикла слово печатается только при встрече пробела — значит, слово перед самым концом строки (после которого пробела уже не будет) никогда не попадёт под это условие. Строка if word: print(...) после цикла — обязательная «подчистка хвоста», это прямое исправление ошибки 8 из раздела «Ошибки».

Пример 9. Проверка палиндрома с фильтрацией

Оставляем только русские и английские буквы, приводим к нижнему регистру и сравниваем строку с её перевёрнутой копией.

📄 examples/palindrome_filter.py
text = "А роза упала на лапу Азора"
filtered_text = ""

for char in text:
    if ("A" <= char <= "Z") or ("a" <= char <= "z") or \
       ("А" <= char <= "Я") or ("а" <= char <= "я"):
        if "A" <= char <= "Z":
            char = chr(ord(char) + 32)
        elif "А" <= char <= "Я":
            char = chr(ord(char) + 32)
        filtered_text += char

is_palindrome = filtered_text == filtered_text[::-1]
print("Палиндром?", is_palindrome)   # True
Проверить по документации: методы str.isalpha() и str.lower() распознают буквы любого алфавита и позволяют записать фильтрацию короче. Это выходит за рамки исходной практики, но рекомендуется в современном коде.

Пример 10. Проверка на панграмму через set

Панграмма — фраза, где встречаются все буквы алфавита хотя бы раз. Вместо ручного перебора 26 кодов букв удобно собирать встреченные буквы в множество: повторы отфильтруются сами.

📄 examples/pangram_check.py
text = "The quick brown fox jumps over the lazy dog"
seen_letters = set()
for char in text.lower():
    if "a" <= char <= "z":
        seen_letters.add(char)
print("Содержит все буквы алфавита?", len(seen_letters) == 26)   # True

text = "The quick brown fox jumps"
seen_letters = set()
for char in text.lower():
    if "a" <= char <= "z":
        seen_letters.add(char)
print("Содержит все буквы алфавита?", len(seen_letters) == 26)   # False

Что происходит: set.add() просто ничего не делает, если элемент там уже есть — поэтому seen_letters никогда не станет больше 26 элементов (по числу букв английского алфавита), и сравнение len(seen_letters) == 26 заменяет собой перебор диапазона ord("a")..ord("z"), подсказанный в задании.

Пример 11. Счётчик букв, цифр и остальных символов

Три отдельных счётчика вместо трёх отдельных проходов по строке — каждый символ классифицируется один раз за один проход.

📄 examples/char_counter.py
text = "Python 3.12!"
letters = 0
digits = 0
others = 0
for char in text:
    if ("a" <= char <= "z") or ("A" <= char <= "Z"):
        letters += 1
    elif "0" <= char <= "9":
        digits += 1
    else:
        others += 1
print("Букв:", letters)              # 6
print("Цифр:", digits)                # 3
print("Остальных символов:", others)  # 3 — пробел и обе точки
Проверить по документации: тот же результат короче даёт связка методов str.isalpha() и str.isdigit() вместо ручных диапазонов "a"<=char<="z". Это выходит за рамки исходной практики.

Оставшиеся две задачи практикума — сравнение строк по числу уникальных символов (задание 11) и проверка одинакового сдвига между строками (задание 13) — используют те же приёмы аккумулятора и ord()/chr(); полный разбор — в «Решениях».

Как запустить в VS Code

  1. Создайте файл example.py в папке урока.
  2. Скопируйте код из примера выше.
  3. Откройте терминал в VS Code (Ctrl + `).
  4. Убедитесь, что активировано виртуальное окружение: venv\Scripts\activate (Windows) или source venv/bin/activate (Mac/Linux).
  5. Запустите: python example.py