🐍 Python: Практические задания

Глава 2: Циклы

📊 Прогресс:

0/0

🟢 Уровень 1: Базовые операции с циклами

Задача 1.1: Счетчик до 5
Используя цикл while, выведите числа от 1 до 5 включительно (каждое с новой строки)
💡 Подсказка:
Создайте переменную-счетчик и увеличивайте её на каждой итерации
✅ Решение:
counter = 1
while counter <= 5:
    print(counter)
    counter += 1
Задача 1.2: Приветствие списка имен
Дан список имен: ["Анна", "Петр", "Мария"]. Используя цикл for, поприветствуйте каждого
💡 Подсказка:
for name in names: ...
✅ Решение:
names = ["Анна", "Петр", "Мария"]
for name in names:
    print(f"Привет, {name}!")
Задача 1.3: Числа от 0 до 9
Используя range() и цикл for, выведите все числа от 0 до 9 (каждое с новой строки)
💡 Подсказка:
range(10) создает последовательность от 0 до 9
✅ Решение:
for number in range(10):
    print(number)
Задача 1.4: Простой break
Выведите числа от 1 до 10, но остановитесь, когда дойдете до числа 5 (число 5 выводить не нужно)
💡 Подсказка:
Используйте if и break внутри цикла
✅ Решение:
for i in range(1, 11):
    if i == 5:
        break
    print(i)

🟡 Уровень 2: Простые комбинации

Задача 2.1: Сумма чисел
Посчитайте сумму всех чисел от 1 до 10 включительно, используя цикл while
💡 Подсказка:
Создайте переменную для суммы и добавляйте к ней числа
✅ Решение:
number = 1
total = 0
while number <= 10:
    total += number
    number += 1
print(f"Сумма: {total}")
Задача 2.2: Четные числа с continue
Выведите только четные числа от 1 до 10, используя continue для пропуска нечетных
💡 Подсказка:
Проверяйте остаток от деления на 2 (число % 2)
✅ Решение:
for i in range(1, 11):
    if i % 2 != 0:
        continue
    print(i)
Задача 2.3: Индексы и значения
Дан список товаров: ["Ноутбук", "Мышь", "Клавиатура"]. Выведите их с порядковыми номерами, используя enumerate
💡 Подсказка:
enumerate возвращает пары (индекс, значение)
✅ Решение:
products = ["Ноутбук", "Мышь", "Клавиатура"]
for index, product in enumerate(products):
    print(f"{index + 1}. {product}")
Задача 2.4: Обратный отсчет
Создайте обратный отсчет от 10 до 1 используя range с отрицательным шагом. В конце выведите "Старт!"
💡 Подсказка:
range(start, stop, step) где step = -1
✅ Решение:
for i in range(10, 0, -1):
    print(f"Осталось: {i}")
print("Старт!")

🟠 Уровень 3: Средняя сложность

Задача 3.1: Валидация пароля с попытками
Дайте пользователю 3 попытки ввести правильный пароль. Правильный пароль: "admin123"
💡 Подсказка:
Используйте while с счетчиком попыток и break при успехе
✅ Решение:
attempts = 0
max_attempts = 3
correct_password = "admin123"

while attempts < max_attempts:
    password = input("Введите пароль: ")
    attempts += 1
    
    if password == correct_password:
        print("Доступ разрешен!")
        break
    else:
        print(f"Неверный пароль. Осталось попыток: {max_attempts - attempts}")
else:
    print("Доступ заблокирован!")
Задача 3.2: Поиск элемента в списке
Дан список чисел: [5, 3, -2, 8, -1, 4]. Найдите первый отрицательный элемент и выведите его индекс
💡 Подсказка:
Используйте enumerate и break при нахождении
✅ Решение:
numbers = [5, 3, -2, 8, -1, 4]
found = False

for index, num in enumerate(numbers):
    if num < 0:
        print(f"Первое отрицательное число {num} на позиции {index}")
        found = True
        break

if not found:
    print("Отрицательных чисел не найдено")
Задача 3.3: Фильтрация товаров по цене
Дан список товаров:
[{"name": "Мышь", "price": 500},
{"name": "Клавиатура", "price": 1500},
{"name": "Коврик", "price": 300},
{"name": "Монитор", "price": 15000}]

Выведите только товары дешевле 1000 рублей
💡 Подсказка:
Используйте continue для пропуска дорогих товаров
✅ Решение:
products = [
    {"name": "Мышь", "price": 500},
    {"name": "Клавиатура", "price": 1500},
    {"name": "Коврик", "price": 300},
    {"name": "Монитор", "price": 15000}
]

print("Товары дешевле 1000 руб:")
for product in products:
    if product["price"] >= 1000:
        continue
    print(f"- {product['name']}: {product['price']} руб")
Задача 3.4: Таблица умножения
Попросите пользователя ввести число и выведите таблицу умножения для этого числа от 1 до 10
💡 Подсказка:
Используйте range(1, 11) для множителей
✅ Решение:
number = int(input("Введите число для таблицы умножения: "))

for i in range(1, 11):
    result = number * i
    print(f"{number} × {i} = {result}")

🔴 Уровень 4: Продвинутые задачи

Задача 4.1: Проверка всех ссылок
Дан список URL:
["https://google.com", "http://example.com", "https://github.com", "ftp://files.com", "https://stackoverflow.com"]
Проверьте все ссылки на наличие "https://" в начале. Соберите все невалидные ссылки
💡 Подсказка:
Создайте список для невалидных URL и используйте метод startswith()
✅ Решение:
urls = [
    "https://google.com",
    "http://example.com",
    "https://github.com",
    "ftp://files.com",
    "https://stackoverflow.com"
]

invalid_urls = []
for index, url in enumerate(urls):
    if not url.startswith("https://"):
        invalid_urls.append(f"Позиция {index + 1}: {url}")

if invalid_urls:
    print("Найдены небезопасные ссылки:")
    for invalid in invalid_urls:
        print(f"  - {invalid}")
else:
    print("Все ссылки безопасны!")
Задача 4.2: Retry механизм
Реализуйте механизм повторных попыток входа в систему (максимум 5 попыток). Правильные данные: логин "admin", пароль "12345"
💡 Подсказка:
Используйте while с счетчиком и флагом успеха
✅ Решение:
attempts = 0
max_attempts = 5
success = False
correct_login = "admin"
correct_password = "12345"

while attempts < max_attempts and not success:
    attempts += 1
    print(f"\nПопытка входа {attempts} из {max_attempts}")
    
    login = input("Логин: ")
    password = input("Пароль: ")
    
    if login == correct_login and password == correct_password:
        success = True
        print("Успешный вход в систему!")
    else:
        print("Неверный логин или пароль")
        if attempts < max_attempts:
            print(f"Осталось попыток: {max_attempts - attempts}")

if not success:
    print("\nДоступ заблокирован после 5 неудачных попыток!")
Задача 4.3: Пагинация данных
Обработайте список из 25 товаров (Товар_1, Товар_2, ..., Товар_25), выводя их страницами по 5 элементов
💡 Подсказка:
Используйте вложенные циклы и срезы списка
✅ Решение:
# Создаем тестовые данные
items = [f"Товар_{i}" for i in range(1, 26)]
page_size = 5
total_pages = (len(items) + page_size - 1) // page_size

for page in range(total_pages):
    print(f"\n--- Страница {page + 1} из {total_pages} ---")
    start_index = page * page_size
    end_index = start_index + page_size
    
    for item in items[start_index:end_index]:
        print(f"  • {item}")
Задача 4.4: Поиск дубликатов
Дан список: ["яблоко", "банан", "яблоко", "груша", "банан", "яблоко", "киви"]. Найдите все дубликаты и выведите их с индексами всех вхождений
💡 Подсказка:
Используйте вложенные циклы или словарь для подсчета
✅ Решение:
items = ["яблоко", "банан", "яблоко", "груша", "банан", "яблоко", "киви"]
duplicates = {}

# Находим все позиции каждого элемента
for index, item in enumerate(items):
    if item in duplicates:
        duplicates[item].append(index)
    else:
        duplicates[item] = [index]

# Выводим только дубликаты
print("Найдены дубликаты:")
for item, positions in duplicates.items():
    if len(positions) > 1:
        print(f"'{item}' найден на позициях: {positions}")

🟣 Уровень 5: Сложные задачи

Задача 5.1: Матрица - вложенные циклы
Создайте таблицу результатов тестов для:
- Браузеры: ["Chrome", "Firefox", "Safari"]
- Тесты: ["Логин", "Регистрация", "Поиск", "Корзина", "Оплата"]
Используйте предопределенные результаты из словаря в решении
💡 Подсказка:
Используйте вложенные циклы и заранее заданные результаты
✅ Решение:
browsers = ["Chrome", "Firefox", "Safari"]
tests = ["Логин", "Регистрация", "Поиск", "Корзина", "Оплата"]

# Предопределенные результаты (True = PASS, False = FAIL)
results = {
    "Chrome": [True, True, True, False, True],
    "Firefox": [True, False, True, True, True],
    "Safari": [True, True, False, True, False]
}

print("Результаты тестирования:")
print("-" * 50)

for browser in browsers:
    print(f"\n{browser}:")
    passed = 0
    failed = 0
    
    for test_index, test in enumerate(tests):
        # Получаем результат для текущего браузера и теста
        test_passed = results[browser][test_index]
        result = "PASS" if test_passed else "FAIL"
        print(f"  {test}: {result}")
        
        if test_passed:
            passed += 1
        else:
            failed += 1
    
    print(f"  Итого: {passed} успешно, {failed} провалено")

# Общая статистика
print("\n" + "=" * 50)
print("Общая статистика:")
total_tests = len(browsers) * len(tests)
total_passed = sum(sum(results[browser]) for browser in browsers)
total_failed = total_tests - total_passed
print(f"Всего тестов: {total_tests}")
print(f"Успешно: {total_passed} ({total_passed * 100 // total_tests}%)")
print(f"Провалено: {total_failed} ({total_failed * 100 // total_tests}%)")
Задача 5.2: Polling - ожидание готовности
Реализуйте проверку статуса заказа "ORD-12345" с максимум 10 проверками. Пользователь должен вводить статус (когда введет "готов", заказ считается готовым)
💡 Подсказка:
Используйте счетчик проверок и симуляцию через input()
✅ Решение:
order_id = "ORD-12345"
max_checks = 10
checks = 0
order_ready = False

print(f"Проверка статуса заказа {order_id}")
print("Нажимайте Enter для проверки статуса (введите 'готов' когда заказ готов)")

while checks < max_checks and not order_ready:
    checks += 1
    print(f"\nПроверка {checks} из {max_checks}")
    
    # Симуляция проверки статуса
    status = input("Введите статус (или Enter для 'обработка'): ").strip()
    
    if status == "готов":
        order_ready = True
        print(f"✓ Заказ готов! Потребовалось проверок: {checks}")
    else:
        current_status = status if status else "обработка"
        print(f"Статус: {current_status}")
        
        if checks < max_checks:
            print("Заказ еще не готов, проверим позже...")

if not order_ready:
    print(f"\n✗ Заказ не готов после {max_checks} проверок")
    print("Обратитесь в службу поддержки")
Задача 5.3: Валидация формы с детальным отчетом
Дана форма с полями:
[{"name": "email", "value": "test@", "type": "email"},
{"name": "age", "value": "17", "type": "age"},
{"name": "phone", "value": "123", "type": "phone"},
{"name": "password", "value": "qwe", "type": "password"}]

Проверьте все поля и создайте подробный отчет об ошибках
💡 Подсказка:
Используйте словарь с полями и условные конструкции для проверки
✅ Решение:
form_fields = [
    {"name": "email", "value": "test@", "type": "email"},
    {"name": "age", "value": "17", "type": "age"},
    {"name": "phone", "value": "123", "type": "phone"},
    {"name": "password", "value": "qwe", "type": "password"}
]

errors = []
valid_fields = 0

print("Валидация формы:")
print("-" * 40)

for index, field in enumerate(form_fields):
    field_type = field["type"]
    field_value = field["value"]
    field_name = field["name"]
    is_valid = False
    
    # Проверка в зависимости от типа поля
    if field_type == "email":
        if "@" in field_value and "." in field_value.split("@")[-1]:
            is_valid = True
    elif field_type == "age":
        if field_value.isdigit() and int(field_value) >= 18:
            is_valid = True
    elif field_type == "phone":
        phone_digits = field_value.replace("+", "").replace("-", "")
        if len(phone_digits) >= 10 and phone_digits.isdigit():
            is_valid = True
    elif field_type == "password":
        if len(field_value) >= 8:
            is_valid = True
    
    if is_valid:
        print(f"✓ Поле '{field_name}': OK")
        valid_fields += 1
    else:
        error_msg = f"Поле '{field_name}' (позиция {index + 1}): некорректное значение '{field_value}'"
        print(f"✗ {error_msg}")
        errors.append(error_msg)

print("\n" + "=" * 40)
print(f"Результат: {valid_fields}/{len(form_fields)} полей валидны")

if errors:
    print("\nОшибки валидации:")
    for error in errors:
        print(f"  - {error}")
else:
    print("\nФорма заполнена корректно!")

Уровень 6: Тонкости и edge cases

Задача 6.1: Else в циклах
Дан список пользователей:
[{"name": "Иван", "role": "user"},
{"name": "Мария", "role": "moderator"},
{"name": "Петр", "role": "user"}]

Используйте else после цикла for для определения, был ли найден администратор
💡 Подсказка:
else выполнится только если не было break
✅ Решение:
users = [
    {"name": "Иван", "role": "user"},
    {"name": "Мария", "role": "moderator"},
    {"name": "Петр", "role": "user"}
]

print("Поиск администратора...")

for user in users:
    if user["role"] == "admin":
        print(f"Администратор найден: {user['name']}")
        break
else:
    print("Внимание: В системе нет администратора!")
    print("Назначаем первого модератора администратором...")
    
    for user in users:
        if user["role"] == "moderator":
            user["role"] = "admin"
            print(f"{user['name']} теперь администратор")
            break
Задача 6.2: Изменение списка во время итерации (правильный способ)
Дан список: ["продукт_1", "тест_данные", "продукт_2", "тест_кейс", "продукт_3"]. Удалите все элементы, содержащие слово "тест", не нарушая итерацию
💡 Подсказка:
Итерируйтесь по копии или в обратном порядке
✅ Решение:
# Способ 1: Итерация по копии
items = ["продукт_1", "тест_данные", "продукт_2", "тест_кейс", "продукт_3"]
print("Исходный список:", items)

for item in items.copy():  # Важно: items.copy()
    if "тест" in item:
        items.remove(item)
        print(f"Удален: {item}")

print("Результат:", items)

# Способ 2: Обратный порядок
items2 = ["продукт_1", "тест_данные", "продукт_2", "тест_кейс", "продукт_3"]
print("\nСпособ 2 - обратный порядок:")

for i in range(len(items2) - 1, -1, -1):
    if "тест" in items2[i]:
        removed = items2.pop(i)
        print(f"Удален: {removed}")

print("Результат:", items2)
Задача 6.3: Оптимизация вложенных циклов
Даны два списка:
- list1: ["apple", "banana", "orange", "grape", "kiwi"]
- list2: ["banana", "kiwi", "mango", "apple", "peach"]
Найдите общие элементы, используя оптимизированный подход
💡 Подсказка:
Преобразуйте один список в set для O(1) поиска
✅ Решение:
# Неоптимальный способ (для сравнения)
list1 = ["apple", "banana", "orange", "grape", "kiwi"]
list2 = ["banana", "kiwi", "mango", "apple", "peach"]

print("Неоптимальный поиск:")
common_slow = []
iterations = 0

for item1 in list1:
    for item2 in list2:
        iterations += 1
        if item1 == item2:
            common_slow.append(item1)
            break

print(f"Общие элементы: {common_slow}")
print(f"Количество сравнений: {iterations}")

# Оптимизированный способ
print("\nОптимизированный поиск:")
set2 = set(list2)  # O(n) один раз
common_fast = []
iterations_fast = 0

for item in list1:
    iterations_fast += 1
    if item in set2:  # O(1) для каждой проверки
        common_fast.append(item)

print(f"Общие элементы: {common_fast}")
print(f"Количество операций: {iterations_fast}")

💡 Полезные советы

Быстрая справка по циклам:
Частые ошибки и как их избежать:
  1. Бесконечный цикл: Всегда проверяйте, что условие в while может стать False
  2. Изменение списка в цикле: Используйте копию или обратный порядок
  3. Забытый break: Помните выходить из цикла после нахождения нужного
  4. range(n) начинается с 0: Для чисел от 1 до n используйте range(1, n+1)
  5. enumerate начинается с 0: Добавляйте 1 для человеческой нумерации