Продвинутые возможности

Отладка и обработка ошибок в ноутбуке

Содержание курса

Простые методы отладки

Наиболее доступный способ – добавить выводы (print), чтобы проверить, что происходит в коде:

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

  • Если цикл застрял или идёт не так, можно печатать прогресс (но осторожно с частотой, чтобы не завалить вывод).

  • Можно печатать входные аргументы функции в начале, чтобы убедиться, что она вызывается с тем, чем вы думаете.

Например, код:

def find_max(nums):
    max_val = 0
    for num in nums:
        if num > max_val:
            max_val = num
    return max_val

print(find_max([-1, -5, -3]))

Ожидаем получить -1, а функция вернёт 0 (неправильно, ведь 0 не был в списке). Почему? Потому что мы инициализировали max_val = 0, а список только отрицательный. Чтобы понять, можно добавить print:

def find_max(nums):
    max_val = 0
    for num in nums:
        print(f"Сравниваю {num} и {max_val}")
        if num > max_val:
            max_val = num
            print(f"Новый максимум: {max_val}")
    return max_val

Теперь вызов покажет:

Сравниваю -1 и 0  
(условие -1 > 0 ложно, max_val остаётся 0)  
Сравниваю -5 и 0  
...  
Сравниваю -3 и 0  
...

Видно, что проблема – начальное значение 0 не подходит для отрицательных. Решение – инициализировать max_val = float('-inf') или взять первый элемент. Так мы локализовали ошибку.

Использование нескольких ячеек для отладки: Вы можете разбить код на части и выполнять поэтапно. Например, функцию писать в одной ячейке, а вызовы – в другой. Тогда легче перезапускать только функцию, не трогая остальной код, и не перезапуская трудоёмкие шаги.

Restart Kernel & Run All при странном поведении: Иногда ошибки вызваны загрязнённым состоянием (например, у вас осталась переменная из старого запуска, и вы случайно на неё опираетесь, хотя в свежем ноутбуке её бы не было). Если ноутбук ведёт себя непредсказуемо, сделайте Kernel -> Restart & Run All. Если после этого появляются ошибки – значит, что-то не было определено или последовательность нарушена. Это поможет поймать зависимость, о которой вы могли не догадываться.

Логирование (logging): В крупных проектах вместо print часто используют модуль logging, чтобы контролировать уровень вывода (DEBUG, INFO, WARNING, ERROR). В ноутбуке для простоты можно обойтись print-ами, но если проект большой, можно настроить logging и выводить сообщения через него.

Unit-тесты в ноутбуке: Если у вас есть важные функции, стоит писать короткие тесты (assert) после них. Пример:

def add(a, b): 
    return a + b

# Тесты
assert add(2, 3) == 5
assert add("ab", "cd") == "abcd"

Если все хорошо, эти ассерты ничего не делают. Если что-то неверно, вылетит AssertionError. Это сразу сигнал разработчику.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

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