Ошибки новичков в Python: 62% случаются до запуска. Срез 2 884 отправок тренажёра

Исследование Автор:
содержание
Трейсбек Python с обведённой кавычкой-ёлочкой в print(«Привет») и столбики: синтаксис и отступы 62%, имена 18%, типы 12%

С 20 июня по 12 сентября 2026 года 323 человека отправили в судью Koddo 2 884 решения на Python. У 686 отправок судья сохранил текст ошибки, и у 468 из них это исключение Python. Мы разобрали, какие именно, на каких задачах и что люди после этого спрашивают у ИИ-ассистента. Главный результат: 62% исключений случаются до того, как программа начала работать. Это SyntaxError и IndentationError, то есть кавычки, двоеточия и отступы, а не логика.

Срез небольшой и касается только учеников Koddo, в основном начинающих. Но такие данные никто в рунете не публикует, поэтому мы решили выложить свои вместе с таблицей и методом. Повторим через год.

Как считали

Единица счёта — отправка кода на проверку, а не отдельный тест. Одна отправка проверяется десятком тестов, и если функция падает с NameError, судья пишет NameError десять раз. Считать по тестам значит завысить ошибки внутри функций в разы, поэтому мы брали первый тест с непустым stderr каждой отправки и последнюю строку его вывода. AssertionError самих тестов, то есть «ответ не совпал», в ошибки не входит: это неверный результат, а не исключение.

Из выборки исключены тестовые аккаунты команды. Отправки «просто запустить» без проверки (571 штука) вошли в общий счёт, но не в статистику вердиктов. У 218 отправок последняя строка stderr не была исключением: в 196 случаях хотя бы один тест упёрся в лимит времени, ещё 22 — сбой контейнера. Они посчитаны отдельно и в таблице ниже не участвуют.

Две трети ошибок — до запуска

Из 468 исключений 229 — SyntaxError и 63 — IndentationError. Вместе 292 отправки, 62%. Программа в них не выполнила ни одной строки: Python остановился на разборе текста.

Срез / 01

Семейства исключений в 468 отправках с ошибкой

Семейства исключений в 468 отправках с ошибкойДо запуска, SyntaxError и IndentationError: 292 отправки, 62%. Имена, NameError и UnboundLocalError: 82, 18%. Типы и вызовы, TypeError и AttributeError: 66, 14%. Данные, IndexError, ValueError и ZeroDivisionError: 20, 4%. Ввод и окружение, EOFError, RecursionError и ModuleNotFoundError: 8, 2%.семействоотправок с исключением из 468до запускаSyntaxError, IndentationError292 · 62%именаNameError, UnboundLocalError82 · 18%типы и вызовыTypeError, AttributeError66 · 14%данныеIndexError, ValueError, ZeroDivisionError20 · 4%ввод и окружение8 · 2%
Три из пяти исключений новичок получает до первой выполненной строки: синтаксис и отступы дают 62%, имена ещё 18%, а ошибки данных и ввода вместе не набирают и десятой части.

Полное распределение по классам исключений:

ИсключениеОтправокДоля
SyntaxError22949%
NameError7215%
IndentationError6313%
TypeError5512%
IndexError112%
AttributeError112%
UnboundLocalError102%
EOFError61%
ValueError51%
ZeroDivisionError41%
RecursionError, ModuleNotFoundError20%

Для сравнения: в вопросах на Stack Overflow и в учебниках синтаксическим ошибкам отводят пару страниц, а разбор TypeError и ValueError растягивают на главы. По нашим данным у новичка всё наоборот: TypeError встречается вчетверо реже, чем SyntaxError.

Что именно ломается в синтаксисе

Сообщение invalid syntax без уточнений дали 111 отправок, каждая четвёртая ошибка среза. Это самая бесполезная строка Python: она означает «не смог разобрать», а причину надо искать самому, часто на строке выше. Остальные синтаксические сообщения конкретнее и складываются в короткий список привычек, которые приносят с собой из чата, текстового редактора и других языков.

СообщениеОтправокЧто за этим стоит
expected ':'31двоеточие после if, for, def
unexpected indent30лишний отступ после копирования
unterminated string literal20незакрытая кавычка, апостроф внутри '...'
expected an indented block18тело блока без отступа
invalid character '«' (U+00AB) и похожие16кавычки-ёлочки, тире и кириллица из чата
unindent does not match any outer indentation level15табы и пробелы вперемешку
Perhaps you forgot a comma?10запятая между элементами
Maybe you meant '==' or ':='9= в условии
Missing parentheses in call to 'print'8print "x" из Python 2
'return' outside function4return выпал из тела функции

Отдельно стоит invalid character: 16 отправок с кодом, в котором стоят «ёлочки», длинное тире или русская буква вместо латинской. Код в таких случаях набран не в редакторе, а скопирован из мессенджера или документа, где кавычки заменяются автоматически. Python на это отвечает кодом символа вида U+00AB, который ничего не говорит человеку без таблицы Unicode. И print без скобок из Python 2 всё ещё встречается: восемь раз за лето.

Эти сообщения мы собрали в расшифровщик ошибок Python: вставляешь трейсбек, получаешь перевод, причину и исправление. Словарь построен на этом срезе, поэтому первыми там стоят именно эти строки.

NameError: опечатки и порядок строк

72 отправки упали с name 'x' is not defined, ещё 10 с UnboundLocalError. Вместе это 18% исключений, второе семейство после синтаксиса. За NameError в решениях новичков стоят три ситуации: опечатка в имени (pritn, nmae), обращение к переменной раньше строки, где она создаётся, и текст без кавычек, когда print(привет) пишут вместо print("привет"). Начиная с Python 3.10 интерпретатор сам предлагает похожее имя после Did you mean:, и в большинстве трейсбеков среза эта подсказка была верной.

UnboundLocalError выглядит страшнее, но причина одна: внутри функции переменной присваивают значение, обычно через count += 1, и Python считает её локальной. Как это устроено, разобрано в статье про области видимости.

Задачи, на которых спотыкаются

Доля отправок с падением сильно зависит от задачи. Ниже задачи, по которым набралось не меньше 40 проверенных отправок, отсортированные по доле ошибок выполнения.

ЗадачаОтправокУпали с ошибкойРешены
Разбор длительности5355%13%
Бегущее среднее задержки7946%37%
Закупка под лимит бюджета4144%46%
Приветствие в баннере31241%40%
Свободные места6537%29%
Инициалы для аватарки6535%31%
Рейтинг звёздами5135%39%
Сумма позиции в корзине28626%48%

«Приветствие в баннере» — вторая задача пути для начинающих, и на ней 161 человек сделал 312 отправок: почти две на каждого, и 41% из них упали. Задача просит прочитать имя и напечатать строку Привет, Аня!. Всё, что в ней можно сломать, относится к первому семейству: кавычки, склейка строки с переменной, print без скобок. «Разбор длительности» из пути для продолжающих ломается ещё чаще, но там причина в парсинге строк вида 1h 30m, и до решения дошли 13% отправок.

Первая попытка решает

Из 1 324 пар «человек и задача» с хотя бы одной проверкой 945, то есть 71%, были решены с первой отправки. Девять из десяти решённых задач закрываются не позже второй попытки. Обратная сторона: 173 пары, 13%, так и остались нерешёнными, и в среднем на них потратили 2,6 отправки, после чего человек ушёл. Промежуточной зоны почти нет: либо решил сразу, либо после двух-трёх неудач бросил.

Для тренажёра это означает, что первая ошибка должна объясняться понятно, потому что третьей попытки часто не будет.

Что спрашивают у ассистента

За тот же период ИИ-ассистент получил 2 132 вопроса от 319 человек в 749 сессиях. У ассистента четыре режима, и распределение по ним говорит о поведении больше, чем тексты вопросов:

  • общий чат — 1 916 сообщений, 90%;
  • подсказка к задаче — 161, 8%;
  • пошаговый разбор — 44, 2%;
  • «объясни ошибку» — 21 сообщение, 1%.

Режим, созданный ровно для трейсбеков, открывают реже всего. При этом слово «решение» или «реши» встречается в 210 вопросах, каждом десятом, «почему» в 170, а «ошибка» только в 43. Люди приносят ассистенту не текст ошибки, а просьбу дать ответ. Это второй аргумент за инструмент, который принимает трейсбек и отвечает без диалога.

Что с этим делать

  • Читать последнюю строку трейсбека. Она называет тип ошибки и текст. В 62% случаев этого достаточно, чтобы понять, что программа не запустилась, и искать кавычку или двоеточие, а не логику.
  • Набирать код в редакторе, а не вставлять из чата. Ёлочки, тире и неразрывные пробелы дают 16 из 229 синтаксических ошибок, и все они выглядят одинаково непонятно.
  • Проверять первое исключение расшифровщиком. Расшифровщик ошибок Python переводит 82 сообщения из этого среза и показывает исправление на примере.
  • Преподавателям: первые две задачи курса стоит давать со стартовым кодом, где кавычки и print() уже на месте. Мы так и сделали для «Приветствия в баннере» в начале сентября, и следующий срез покажет, изменилась ли доля падений.

Ограничения

  • Выборка — ученики одной платформы, в основном путь для начинающих. Доли исключений у людей с опытом другие.
  • Считалась первая ошибка отправки. Если код падал по-разному на разных тестах, вторая причина не учтена.
  • Синтаксические ошибки судья видит только при отправке. Часть из них люди ловят раньше в редакторе и до судьи не доносят, поэтому доля 62% скорее занижена.
  • Нерешённые задачи не отличают «бросил» от «отложил»: срез снят на конкретный день.
  • Тестовые аккаунты команды исключены по флагу в базе, а не по домену почты.

Данные и процедура повторения

Все агрегаты — в CSV: скачать таблицу среза. В файле только счётчики по классам исключений, сообщениям, задачам, месяцам и режимам ассистента. Ни кода учеников, ни идентификаторов, ни текстов вопросов в нём нет.

Чтобы повторить срез на своих данных, достаточно четырёх правил: одна отправка — одна ошибка; берётся первый тест с непустым stderr; класс исключения — последняя строка вида XxxError: текст; проверки самого тестового набора (AssertionError) исключаются. Нормализация сообщений: имена в кавычках и числа заменяются на заглушки, иначе name 'x' is not defined расползётся на сотни строк.

Короткий ответ

По 2 884 отправкам на Python в судью Koddo за июнь–сентябрь 2026 года 62% исключений новичков — это SyntaxError и IndentationError, ещё 18% — NameError и UnboundLocalError, и только 12% — TypeError. Самое частое сообщение — invalid syntax без уточнений, 111 раз. 71% задач решаются с первой отправки, 13% не решаются вовсе. Ассистенту приносят просьбу дать решение в каждом десятом вопросе, а режим объяснения ошибки открывают в 1% случаев.

Как цитировать

Koddo. «Ошибки новичков в Python: 62% случаются до запуска. Срез 2 884 отправок тренажёра». Данные судьи Koddo за 20 июня — 12 сентября 2026 года. https://koddo.ru/articles/python-beginner-errors-2026. Таблица: https://koddo.ru/datasets/python-beginner-errors-2026-09-12.csv.

Числа привязаны к окну дат и к аудитории платформы. Следующий срез выйдет через год по той же методике, тогда сравнение будет корректным.

Частые вопросы

Почему так мало ValueError и IndexError, о которых пишут во всех учебниках?

Потому что до них новичок не доходит. Чтобы получить IndexError, программа должна запуститься, дойти до списка и обратиться к нему. Большинство отправок среза останавливались раньше: на кавычке, двоеточии или отступе.

Считались ли ошибки в песочнице и уроках?

Нет, только отправки в судью из задач и тренажёра. Песочница Python работает в браузере и ничего не отправляет на сервер, поэтому её ошибки в базе не появляются.

Где посмотреть перевод конкретной ошибки?

В расшифровщике ошибок Python: вставь трейсбек или последнюю строку, и он покажет перевод, причины и исправление. Разборы отдельных классов есть в справочнике: SyntaxError, IndentationError, NameError, TypeError и ValueError.