📝 Практические задания

⚡ Задания в двух словах

  • Задание 1 — рекурсивная сумма чисел списка с валидацией.
  • Задание 2 — рекурсивный реверс строки.
  • Задание 3 — максимальная глубина вложенности списка.
  • Задание 4 — сумма продаж по дереву подразделений.
  • Задание 5 — плоский формат вложенного словаря.

🏋️ Раздел тренировки

Выполните задания в одном или нескольких файлах. Каждая функция должна проверять входные данные и возбуждать исключение при нарушении условий. Вызовы функций обработайте через try/except.

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

Задание 1. Сумма чисел списка

Условие: напишите рекурсивную функцию, которая вычисляет сумму всех чисел в списке. Функция должна проверять:

  • аргумент должен быть списком;
  • все элементы списка должны быть числами.

Если данные не валидны, необходимо выбрасывать исключение. При вызове функции обработайте возможное исключение.

Данные:

numbers = [1, 2, 3, 4, 5]

Пример вывода:

15

Подсказка: используйте guard clause с isinstance и рекурсивный шаг numbers[0] + recursive_sum(numbers[1:]).

Задание 2. Реверс строки

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

Данные:

text = "recursion"

Пример вывода:

noisrucer

Подсказка: базовый случай — строка длиной 0 или 1 символ.

Задание 3. Глубина вложенности списка

Условие: напишите рекурсивную функцию, которая определяет максимальную глубину вложенности списка. Функция должна проверять:

  • аргумент должен быть списком;
  • вложенные структуры, если они есть, также должны быть списками.

Если данные не валидны, необходимо выбрасывать исключение. При вызове функции обработайте возможное исключение.

Данные:

nested_list = [1, [2, [3, [4, [5]]]], 6, [[7, 8], 9]]

Пример вывода:

Максимальная глубина: 5

Подсказка: для каждого элемента, являющегося списком, рекурсивно считайте глубину и берите максимум.

Задание 4. Сумма продаж

Условие: есть дерево подразделений внутри компании (каждое подразделение может содержать «дочерние» отделы). Напишите рекурсивную функцию, которая подсчитывает суммарные продажи для всех отделов. Функция должна проверять:

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

Если данные не валидны, необходимо выбрасывать исключение. При вызове функции обработайте возможное исключение.

Данные:

company_structure = {
    "dept_name": "Head Office",
    "sales": 100,
    "sub_departments": [
        {
            "dept_name": "Sales Department",
            "sales": 200,
            "sub_departments": [
                {"dept_name": "B2B Sales", "sales": 120}
            ]
        },
        {
            "dept_name": "IT Department",
            "sales": 150,
            "sub_departments": [
                {
                    "dept_name": "DevOps",
                    "sales": 300,
                    "sub_departments": [
                        {"dept_name": "Cloud Infrastructure", "sales": 180}
                    ]
                },
                {"dept_name": "QA Department", "sales": 90}
            ]
        }
    ]
}

Пример вывода:

Общая сумма продаж: 1140

Подсказка: используйте department.get("sub_departments") и рекурсивно складывайте продажи дочерних отделов.

Задание 5. Читабельный формат словаря

Условие: дан вложенный словарь. Напишите рекурсивную функцию, которая преобразует его в «плоский» формат, где в ключе будет содержаться полный путь к значению.

Данные:

data = {
    "user": {
        "id": 123,
        "info": {
            "name": "Alice",
            "location": {
                "city": "Berlin",
                "coordinates": {"lat": 52.52, "lon": 13.405}
            },
            "hobby": ["swimming", "drawing"]
        }
    },
    "score": 95
}

Пример вывода:

Данные для анализа:
user.id : 123
user.info.name : Alice
user.info.location.city : Berlin
user.info.location.coordinates.lat : 52.52
user.info.location.coordinates.lon : 13.405
user.info.hobby : ['swimming', 'drawing']
score : 95

Подсказка: передайте текущий префикс в рекурсивный вызов и собирайте ключ через f"{prefix}.{key}".

Проверка понимания

Выберите один вариант ответа. После клика правильный ответ подсветится зелёным.

Вопрос 1

Что важнее всего в практическом задании?

Вопрос 2

Как безопаснее двигаться в практикуме?

Вопрос 3

Что делать, если решение не совпадает с ожидаемым результатом?

Вопрос 4

Какой стиль имён переменных обычно рекомендует PEP 8?

Вопрос 5

Зачем использовать f-strings в современном Python?

Вопрос 6

Когда полезен ранний возврат из функции?