💻 Смешанные примеры

⚡ Минимальный смешанный пример

word = "python"
index = 0
while index < len(word):
    print(word[index], end="")
    index += 1
print()             # python
print(word[::-1])   # nohtyp
print(word[2:5])    # tho
КонструкцияЧто делаетПример
while / break / continue / elsebreak прерывает, continue пропускает, else — без breakwhile i <= n: ... else: ...
Срезы s[start:end:step]часть строки: включая start, не включая end, шаг steps[2:5], s[::-1]
ord() / chr()код символа Unicode ↔ символ по кодуord("A") → 65
random.randint(a, b) / random.choice(seq)случайное целое a..b включительно / случайный элемент из seqrandom.randint(1, 10)
Сравнение строклексикографически, по кодам Unicode первого отличия"Apple" < "apple" → True
Топ-3 ошибки: забыть обновить переменную цикла · выйти за границы строки по индексу · перепутать break и continue.

Примеры идут от простого к сложному: сначала перебор строки в while, затем управляющие конструкции цикла (break, continue, while/else) отдельно от строковых операций (срезы, сравнение), а в конце — связки цикла со строками и random, как в заданиях урока. Весь вывод в примерах получен реальным запуском кода. Повторяемые темы взяты из урока 12 «Цикл while» и урока 14 «Введение в строки».

Пример 1. Вывод символов строки по индексу

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

📄 examples/print_characters.py
text = input("Enter a word: ")
index = 0

while index < len(text):
    print(f"Index {index}: {text[index]}")
    index += 1

Что происходит: при вводе Hello цикл проходит по пяти символам и печатает их индексы:

Enter a word: Hello
Index 0: H
Index 1: e
Index 2: l
Index 3: l
Index 4: o

Пример 2. break и continue рядом

break и continue часто путают, поэтому важно увидеть их в одном скрипте на одних и тех же данных: первый цикл ищет первую цифру и сразу останавливается через break, второй — пропускает все цифры через continue и собирает только буквы.

📄 examples/break_continue.py
word = "sky3blue7"
digits = "0123456789"

# break: stop searching as soon as we find the first digit
position = 0
first_digit_index = -1
while position < len(word):
    if word[position] in digits:
        first_digit_index = position
        break
    position += 1

print(f"First digit index: {first_digit_index}")

# continue: skip digits, keep only letters
position = 0
letters_only = ""
while position < len(word):
    char = word[position]
    position += 1
    if char in digits:
        continue
    letters_only += char

print(f"Letters only: {letters_only}")

Что происходит: символ "3" стоит на индексе 3 — как только цикл его находит, break прерывает цикл целиком, дальше индексы 4-8 не проверяются. Во втором цикле continue пропускает только текущую цифру, но обход продолжается до конца строки — поэтому обе цифры (3 и 7) вырезаны, а буквы собраны:

First digit index: 3
Letters only: skyblue

Пример 3. Конструкция while / else: два сценария

else после while — не про «иначе», а про «цикл закончился сам, без break». Сравниваем два почти одинаковых цикла: в первом условие само становится ложным, во втором — сработавший break отменяет else.

📄 examples/while_else.py
# Scenario 1: loop finishes naturally -> else runs
counter = 1
while counter <= 3:
    print(counter)
    counter += 1
else:
    print("Loop completed without break.")

print("---")

# Scenario 2: loop exits via break -> else is skipped
counter = 1
while counter <= 3:
    print(counter)
    if counter == 2:
        break
    counter += 1
else:
    print("This will not print.")

Что происходит: в первом сценарии условие counter <= 3 становится ложным естественным путём, поэтому else выполняется. Во втором сценарии на значении counter == 2 срабатывает break — цикл прерывается досрочно, и блок else пропускается целиком:

1
2
3
Loop completed without break.
---
1
2

Пример 4. Переворот строки в цикле

Строки неизменяемы, поэтому «перевернуть» строку — значит собрать новую посимвольно, двигаясь с конца. Рядом — та же задача через срез, чтобы увидеть разницу в объёме кода.

📄 examples/reverse_string.py
word = input("Enter a word: ")
reversed_word = ""
position = len(word) - 1

while position >= 0:
    reversed_word += word[position]
    position -= 1

print(f"Reversed: {reversed_word}")
print(f"Reversed via slice: {word[::-1]}")

Что происходит: оба способа дают одинаковый результат, но цикл делает это явно по шагам, а срез word[::-1] — одной строкой:

Enter a word: Python
Reversed: nohtyP
Reversed via slice: nohtyP

Пример 5. Срезы строк s[start:end:step]

Срез — самый частый способ достать часть строки без цикла. start входит в результат, end — нет, а step задаёт направление и шаг обхода. Пропущенные индексы означают «от начала» / «до конца».

📄 examples/slicing.py
phrase = "Python programming"

print(phrase[2:5])      # from index 2 up to (not including) index 5
print(phrase[:3])       # from the start up to index 3
print(phrase[::2])      # every second character
print(phrase[::-1])     # full reverse: negative step
print(phrase[-11:-4])   # negative indices count from the end

Что происходит: каждая строка среза даёт свою часть исходной фразы "Python programming"; отрицательные индексы в последней строке отсчитываются от конца, а не от начала:

tho
Pyt
Pto rgamn
gnimmargorp nohtyP
program

Пример 6. Сравнение строк лексикографически

Строки сравниваются посимвольно по кодам Unicode: решающим становится первый отличающийся символ. Заглавные буквы имеют коды меньше строчных, поэтому регистр напрямую влияет на результат сравнения.

📄 examples/compare_strings.py
print("apple" < "banana")   # 'a' < 'b' -> True
print("Apple" < "apple")    # 'A' (65) < 'a' (97) -> True
print(ord("A"), ord("a"))

word1 = "apple"
word2 = "Apple"
print(word1 == word2)               # case-sensitive comparison
print(word1.lower() == word2.lower())  # ignore case

Что происходит: "apple" < "banana" — сравниваются первые символы 'a' и 'b'. "Apple" < "apple" — оба слова начинаются на разный регистр той же буквы, а код 'A' (65) меньше кода 'a' (97). Без приведения к одному регистру "apple" == "Apple" — False:

True
True
65 97
False
True

Пример 7. Генератор короткого пароля

Комбинируем while и random.choice(), чтобы собрать строку из случайных букв заданной длины — типичная задача, где цикл и random работают вместе.

📄 examples/simple_password.py
import random

letters = "abcdefghijklmnopqrstuvwxyz"
password = ""
length = 8
index = 0

while index < length:
    password += random.choice(letters)
    index += 1

print(f"Generated password: {password}")

Что происходит: на каждой итерации random.choice(letters) выбирает случайную букву и добавляет её к password. Результат случаен — ниже один из возможных вариантов, при повторном запуске пароль будет другим:

Generated password: krsphyjw
# один из возможных результатов — конкретные буквы меняются при каждом запуске

random.randint(): случайное целое число

random.choice() выбирает элемент из готовой последовательности, а random.randint(a, b) генерирует случайное целое число в диапазоне — например, случайный индекс списка или случайное количество попыток.

📄 examples/randint_demo.py
import random

words = ["python", "loop", "string", "random"]
random_index = random.randint(0, len(words) - 1)
print(f"Random index: {random_index}")
print(f"Chosen word: {words[random_index]}")

attempts_allowed = random.randint(3, 5)
print(f"Attempts allowed: {attempts_allowed}")

Что происходит: random.randint(0, len(words) - 1) возвращает случайный индекс от 0 до последнего допустимого включительно — верхняя граница у randint, в отличие от range, входит в диапазон. Ниже один из возможных результатов конкретного запуска:

Random index: 2
Chosen word: string
Attempts allowed: 4
# один из возможных результатов — random.randint() каждый раз выбирает новое число из диапазона

Пример 9. Поиск подстроки через цикл

Программа запрашивает строку и проверяет, содержится ли в ней слово "Python". Показаны два способа: короткий через in и явный через цикл с break — так видно, что делает in «под капотом».

📄 examples/find_python.py
text = input("Enter a line: ")
target = "Python"

# Simple way
print(f"Contains '{target}': {target in text}")

# Loop way: case-insensitive search with early exit
lower_text = text.lower()
lower_target = target.lower()
found = False
index = 0

while index <= len(lower_text) - len(lower_target):
    if lower_text[index:index + len(lower_target)] == lower_target:
        found = True
        break
    index += 1

print(f"Found via loop (case-insensitive): {found}")

Что происходит: при вводе I am learning Python! оба способа находят слово. В цикле как только срез lower_text[index:index + len(lower_target)] совпадает с искомым словом, found становится True и break сразу останавливает перебор — дальше строку можно не проверять:

Enter a line: I am learning Python!
Contains 'Python': True
Found via loop (case-insensitive): True

Пример 10. Коды символов в диапазоне

Финальный пример связывает циклы с кодировками: while перебирает числовой диапазон, а chr() превращает каждый код в символ.

📄 examples/unicode_range.py
start = int(input("Enter start code: "))
stop = int(input("Enter stop code: "))

while start <= stop:
    print(f"{start}: {chr(start)}")
    start += 1

Что происходит: для диапазона от 65 до 70 цикл печатает шесть строк — коды и соответствующие им заглавные латинские буквы:

Enter start code: 65
Enter stop code: 70
65: A
66: B
67: C
68: D
69: E
70: F

Как запустить в 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

Дальше — задания на те же темы без подсказок в коде. Если что-то не запустилось, загляните в типичные ошибки или повторите урок 16 «Цикл for» после этой repetition-сессии.