Зачем решать задачи на функции
Задачи на функции нужны, чтобы научиться делить программу на части: каждая функция решает одну маленькую задачу, получает данные через параметры и отдаёт результат через return. Так код становится короче и понятнее.
Пока программа занимает десять строк, функции кажутся лишними. Но как только одно и то же действие нужно в трёх местах — проверить, простое ли число, перевести секунды в часы, найти наибольший делитель, — копирование кода превращается в ловушку. Ошибку придётся исправлять в каждой копии, и одну обязательно забудешь. Функция решает эту проблему: логика записана один раз, а вызывать её можно сколько угодно, с разными значениями.
Есть и вторая причина. Функцию можно проверить отдельно от остальной программы: передать ей несколько значений и посмотреть, что она вернёт. Именно так работает автопроверка в этом наборе, и так же программисты тестируют большие проекты. Вспомогательные алгоритмы входят в программу 9 класса по федеральной образовательной программе основного общего образования[1], а в Python они записываются как раз через def.
Набор идёт от простого к сложному. Первые две функции содержат одну строку с return. Дальше появляются функции с условиями и циклами внутри: простое число, НОД, максимум из двух. Последние задачи на функции требуют связать две функции между собой: одна вызывает другую и использует её ответ.
Задачи на функции полезно решать даже тем, кто уже уверенно пишет циклы. Привычка выносить проверку или формулу в отдельную функцию делает решения короче и на уроке, и на экзамене. По материалам ФИПИ задание 16 ОГЭ по информатике — программа на универсальном языке, и Python там разрешён[2]; аккуратно разбитая на функции программа читается и проверяется легче. Через день-два вернитесь к тем же задачам на функции и решите их без подсказок: исследование Roediger и Karpicke показало, что самопроверка закрепляет навык прочнее, чем перечитывание готового кода[3].
Как устроена функция: def, параметры, return
Функция в Python состоит из 4 частей: слова def, имени, параметров в скобках и тела с отступом. Внутри тела команда return возвращает результат тому, кто функцию вызвал.
| Часть | Пример | Зачем |
| Заголовок | def area(a, b): | имя и список входных данных |
| Параметры | a, b | переменные, которые получат значения при вызове |
| Тело | строки с отступом 4 пробела | вычисления |
| Возврат | return a * b | отдать ответ и выйти из функции |
| Вызов | area(3, 4) | запустить функцию с конкретными значениями |
Определение функции само по себе ничего не делает: Python запоминает её и идёт дальше. Код внутри выполнится только при вызове. Поэтому функцию нужно описать выше места, где её вызывают, иначе программа остановится с NameError. Как устроены параметры, значения по умолчанию и область видимости, подробно рассказано в официальной документации Python[4] и в статье о функциях в Python.
Как тренажёр проверяет задачи на функции
В каждой из 8 задач заготовка уже содержит заголовок функции и нижнюю часть программы: ввод, вызов и печать. Ваша задача — написать тело функции вместо слова pass.
Тренажёр запускает всю программу целиком на нескольких наборах входных данных и сравнивает напечатанное с ожидаемым. Поэтому функция должна работать для любых допустимых значений, а не только для примера из условия: для функции проверки простоты тесты включают 1, 2 и большое простое число.
Слово pass — пустая команда, она нужна, чтобы заготовка запускалась без ошибок. Если оставить её, функция вернёт специальное значение None, и тест покажет «None» в строке «Получилось». Это частый первый результат, и пугаться его не нужно: значит, функция вызвалась, но ничего не вернула. Нижнюю часть заготовки лучше не менять — она подаёт тестовые данные и печатает ответ в нужном формате.
Разбор: простое число и ранний return
Простое число — это натуральное число больше 1, у которого ровно 2 делителя: единица и оно само. Функция проверки ищет делитель и, найдя его, сразу возвращает False.
def is_prime(n):
if n < 2:
return False
d = 2
while d * d <= n:
if n % d == 0:
return False
d += 1
return True
print(is_prime(97), is_prime(91))
True False
Здесь работают два приёма. Первый — ранний выход: return прекращает работу функции немедленно, поэтому после найденного делителя цикл не продолжается. Второй — граница перебора: если у числа есть делитель больше корня, то есть и парный ему меньше корня, поэтому проверять до d * d <= n достаточно. Для 97 это 8 проверок вместо 95. Строка return True стоит после цикла без отступа внутри него: до неё программа дойдёт, только если ни один делитель не нашёлся.
Разбор: НОД по алгоритму Евклида
Алгоритм Евклида находит наибольший общий делитель за несколько шагов: пару (a, b) заменяют на (b, a % b), пока второе число не станет 0. Оставшееся первое число и есть НОД.
| Шаг | a | b | a % b |
| 1 | 100 | 75 | 25 |
| 2 | 75 | 25 | 0 |
| 3 | 25 | 0 | — ответ 25 |
Запись a, b = b, a % b обновляет обе переменные одновременно, без временной. Решение уложилось в четыре строки, и теперь gcd можно вызывать где угодно: для сокращения дробей, для НОК через формулу a * b // gcd(a, b). Ещё больше упражнений на делители и простые числа собрано в наборе задач на числа и цифры.
Разбор: функция внутри функции
Функция может вызывать другую функцию — так большая задача собирается из маленьких проверенных деталей. В задаче про время two отвечает только за две цифры, а hms — за всё остальное.
def two(x):
if x < 10:
return "0" + str(x)
return str(x)
def hms(sec):
return str(sec // 3600) + ":" + two(sec % 3600 // 60) + ":" + two(sec % 60)
print(hms(3725))
Если в выводе ошибка с нулями, искать её надо в two, если с часами — в hms. Так же устроена задача о днях в году: days не повторяет правило високосного года, а спрашивает is_leap. Руководство PEP 8 советует давать функциям имена строчными буквами через подчёркивание[5], и это помогает: понятное имя вроде is_leap подсказывает, что ответом будет «да» или «нет».
print или return: главная путаница
Print показывает значение на экране, а return отдаёт его программе. Это 2 разных действия, и def с print вместо return возвращает None.
| print внутри | return внутри | |
| Что видно на экране | значение | ничего, пока не напечатать результат |
| Можно ли сложить результат с числом | нет, будет ошибка с None | да |
| Можно ли передать в другую функцию | нет | да, как max2(max2(a, b), c) |
Правило простое: вспомогательный блок считает и возвращает, а печатает основная программа. Тогда его можно использовать где угодно — в условии, в формуле, в другом вызове.
Когда отдельная функция не нужна
Отдельная функция не нужна, если действие выполняется один раз и занимает пару строк. Вот 4 случая, когда этот набор рано или не по адресу.
- Не освоены if и циклы. Внутри половины задач стоят условия и while — сначала стоит решить по 8 упражнений на эти темы.
- Действие из 1–2 строк встречается один раз. Отдельный def только удлинит программу.
- Ребёнку 9–10 лет, и он работает в Scratch. Там аналог — собственные блоки из категории «Другие блоки».
- Нужно хранить данные и действия вместе, например у 5 персонажей игры. Для этого есть классы — следующая ступень.
«Изменения переменной внутри def видны снаружи». Это миф для обычного присваивания: переменная, созданная внутри, живёт только там. Чтобы передать значение наружу, используют return.
«Return можно написать только один раз и только в конце». Не подтверждается: return может стоять в нескольких местах, и первый выполненный завершает работу.
Чего делать нельзя
Нельзя обращаться к имени раньше, чем Python дошёл до её определения: имя ещё не существует. Ещё шесть правил:
- Нельзя забывать скобки при вызове:
areaбез скобок — это сама функция, а не её результат. - Не следует печатать ответ внутри, если по условию его нужно вернуть.
- Не стоит передавать меньше аргументов, чем параметров — Python сообщит о TypeError.
- Не стоит писать код после return в той же ветке: он никогда не выполнится.
- Не допускается давать def то же имя, что и переменной, в той же программе — одно имя затрёт другое.
- Нельзя оставлять pass в готовом решении: результатом будет None.
Сообщения об ошибках, связанных с вызовами, разобраны на странице про ошибку TypeError. А применить этот приём в небольшом проекте можно в статье о калькуляторе на Python, где каждая операция оформлена отдельно.
Источники
[1] Приказ Минпросвещения России от 18.05.2023 № 370 «Об утверждении федеральной образовательной программы основного общего образования».
[2] ФИПИ. Методические рекомендации для обучающихся по организации индивидуальной подготовки к ОГЭ 2026 года. Информатика. М., 2026.
[3] Roediger H. L., Karpicke J. D. Test-enhanced learning: Taking memory tests improves long-term retention // Psychological Science. 2006. Vol. 17, № 3. P. 249–255.
[4] The Python Tutorial (официальная документация Python 3). Python Software Foundation.
[5] van Rossum G., Warsaw B., Coghlan N. PEP 8 — Style Guide for Python Code. Python Software Foundation, 2001.
Вопросы и ответы
Чем параметр отличается от аргумента?
Параметр — имя в заголовке def, аргумент — конкретное значение при вызове. В area(3, 4) аргументы 3 и 4 попадают в параметры a и b.
Можно ли обойтись без параметров?
Да, тогда скобки пустые: def hello():. Вызывать её всё равно нужно со скобками — hello().
Можно ли вернуть два значения?
Можно: return q, r вернёт пару, и её удобно разложить по переменным — a, b = divide(17, 5).
Что такое None?
Это особое значение «ничего». Его возвращает любой def без return или с пустым return.
Нужно ли комментировать каждый def?
К коротким с понятным именем — нет. К сложным полезна строка документации в тройных кавычках сразу под заголовком.
Где это встречается в школьной информатике?
В 9 классе их называют вспомогательными алгоритмами. В Школьном алгоритмическом языке их записывают отдельными алгоритмами со словом «алг».