# Вспомогательные алгоритмы и функции в Python

> Разбираемся с def, параметрами и return: упаковываем повторяющийся код в функции, вызываем их в цикле и трассируем вызов по шагам на задаче про скидку.

**Информатика, 8 класс.** Урок бесплатного онлайн-самоучителя «ШкольныйГид». Обновлено: 2026-09-30.

Страница урока: https://shkolniygid.ru/informatika/8-klass/funkcii-python-8/

Кнопка «Разогрев» на микроволновке делает за тебя целую цепочку: включила печь, завела таймер на минуту, а по концу — звонок и свет. Один раз инженеры записали эту цепочку внутрь прибора, и теперь каждая кнопка запускает её одной строкой — никто не перепрошивает печь ради обеда. В программе то же самое: **def** упаковывает блок команд под именем, и после этого одно слово-вызов выполняет их все. Такая упаковка называется **функция**, а в учебнике информатики — **вспомогательный алгоритм**: маленький алгоритм внутри большого. Выигрыш двойной: код не копируют десять раз, и правка вносится в одном месте — поменяешь текст приветствия в функции, и все вызовы сразу станут новыми. В математике так же работает формула: записали один раз, подставляешь разные числа. В играх так живёт функция «нанести урон»: она одна, а вызывается на каждый удар каждого персонажа — сотни раз за минуту, и везде один и тот же проверенный код.


### def: учим программу новое слово


Объявление выглядит так: **def privet():** — слово def, имя, круглые скобки и двоеточие. Дальше с отступом идёт тело:
def privet():
    print("Здравствуйте!")
Всё: функция создана, но ещё **не выполнена**. Python при чтении def только запоминает, что такое privet, и переходит к следующей строке — так же, как ты, прочитав рецепт, не начинаешь жарить блины. Запускает тело **вызов** — имя со скобками: privet(). Вызови его трижды —
privet()
privet()
privet()
— и трижды увидишь приветствие, а код объявления остался один. Имя для функции придумываешь по тем же правилам, что и имя переменной: латиница, без пробелов, не совпадает со служебными словами. Скобки обязательны: privet без скобок — это не вызов, а просто имя, Python его молча пропустит. Отступ в теле работает так же, как в if и циклах: сдвинул строку не туда — она вылетела из функции, и программа сломается с IndentationError. В теле может быть несколько строк — Python выполнит их сверху вниз, как обычную программу. Хочешь, чтобы privet к тому же возвращала число приветствий, — допиши в конец тела return 3: тело функции устроено по тем же правилам, что и вся программа.


### Параметры и return


Функция без данных — как калькулятор без кнопок с цифрами. Данные передают через **параметры** — переменные в скобках при объявлении:
def kvad(x):
    return x * x
Здесь x — параметр: заготовка, в которую при вызове подставится конкретное значение. Вызов kvad(5) вернёт 25, kvad(9) вернёт 81, kvad(0) вернёт 0. Значение при вызове называют **аргументом**, и подставляются аргументы по порядку: у функции с двумя параметрами первый аргумент уйдёт в первый параметр, второй — во второй. Порядок безразличен, пока операция симметричная: summa(3, 2) и summa(2, 3) вернут одно и то же. Но для f(a, b): return a - b порядок решает всё: f(10, 3) вернёт 7, а f(3, 10) — минус 7. Команда **return** завершает функцию и отдаёт результат той строке, которая вызвала. Соберём формулу Пифагора: **def gipotenuza(a, b): return (a*a + b*b) ** 0.5** — вызов gipotenuza(3, 4) вернёт 5.0. Ноль на конце не опечатка: возведение в степень 0.5 всегда даёт дробный тип float, даже когда результат круглый. Возвращённое значение сразу живёт в выражениях: kvad(3) + kvad(4) даст 25 — девять плюс шестнадцать, — а запись if kvad(x) > 100: работает в условиях как обычное сравнение. Функция — это почти новая команда языка.


$$c = \sqrt{a^{2} + b^{2}}$$

*Формула, которую считает функция gipotenuza: при a = 3 и b = 4 она вернёт 5.0*


| Вызов | Что подставится | Результат |
| --- | --- | --- |
| kvad(5) | x = 5 | 25 |
| kvad(9) | x = 9 | 81 |
| kvad(0) | x = 0 | 0 |
| summa(2, 3) | a = 2, b = 3 | 5 |
| summa(10, 90) | a = 10, b = 90 | 100 |
| gipotenuza(3, 4) | a = 3, b = 4 | 5.0 |
| privet() | без параметров | печатает Здравствуйте! |


### Разбор сложного примера: функция внутри цикла


Соберём всё вместе: функция, цикл и накопитель результата. Программа считает сумму удвоенных чисел от 0 до 3:
def dv(x):
    return x * 2

k = 0
for i in range(4):
    k = k + dv(i)
print(k)
Трассируем по кругу. i = 0: вызов dv(0) возвращает 0, в k всё ещё 0. i = 1: dv(1) вернёт 2, k = 0 + 2 = 2. i = 2: dv(2) вернёт 4, k = 6. i = 3: dv(3) вернёт 6, k = 12. Цикл кончился — print печатает 12. Заметь: в k копится не результат одного вызова, а сумма результатов — каждый вызов отдавал своё число, и мы прибавляли его к общему котлу. Такой приём — накопление в цикле через функцию — встречается везде: подсчёт суммы заказов, средней температуры за неделю, общего счёта в игре.


> **Ловушка.** Первая: def без вызова ничего не делает — написал объявление и забыл вызвать, программа напечатает пустоту. Вторая: забыл return — функция вернёт **None**, и print(kvad(5)) напечатает None вместо 25. Третья: print внутри функции и return — не одно и то же. Функция с print показывает число на экране, но не отдаёт его: результат нельзя сохранить в переменную и использовать в формулах. Правило: считает — return, показывает — print, а для надёжности совмещай оба: функция и вернёт значение, и напечатает ход работы. И четвёртая: вызов выше объявления не работает — Python читает файл сверху вниз, и на строке privet() до строки def privet(): он ещё не знает такого имени: NameError.


### Собираем программу из функций


Смысл функций не в экономии строк, а в порядке: большая задача распадается на шаги с именами, и программа читается как список дел. Магазин считает итог со скидкой:
def itog(price, sale):
    return price - price * sale / 100
print(itog(400, 25))
На экране появится 300.0: скидка 25 процентов от 400 рублей — это 100 рублей, 400 − 100 = 300, а деление добавило дробный хвост. Функции вызывают из других функций и из циклов: for i in range(3): privet() трижды выполнит тело. Цикл умеет копить и результаты: если написать k = 0, а внутри цикла k = k + kvad(i), то после трёх шагов в k окажется 0 + 1 + 4 = 5 — квадраты чисел 0, 1, 2 собрались в сумму. Переменные, созданные внутри функции, — **локальные**: снаружи их не видно, поэтому имя x в функции не конфликтует с x в основной программе. Именно поэтому большие программы не разваливаются: каждый кусок живёт в своих скобках со своим набором имён. Функции сцепляются в конвейер: сделай chek(price, sale), которая вызывает itog и печатает «К оплате:», — и логика расчёта отделена от его показа на экране: поменял оформление чека — расчёт не тронул, и наоборот. И хороший тон: держи объявления функций в начале файла, выше основного кода, — тогда любой вызов ниже найдёт своё имя.


**Трассировка вызова itog(400, 25)**

1. Python встречает def itog(price, sale): и запоминает функцию — тело пока не выполнялось ни разу.
2. Вызов itog(400, 25): аргументы идут по порядку, в price попадает 400, в sale — 25.
3. Тело считает скидку в рублях: 400 * 25 / 100 = 100.0.
4. return завершает функцию и отдаёт 400 − 100.0 = 300.0.
5. print печатает 300.0: деление в Python всегда даёт дробный тип float, даже если ответ круглый.
6. Вызови itog(400, 25) ещё раз — Python повторит весь прогон с начала: функция не помнит прошлых вызовов. А переменные price и sale существуют только во время прогона: вызов завершился — их след простыл.


### Как это выглядит в контрольных


Задания на функции в проверочных работах делятся на три вида. Первый — «что выведет программа»: трассируй вызовы на бумажке, как в шагах выше, и следи за порядком аргументов — в f(10, 3) десятка уйдёт в первый параметр, а не во второй. Второй — «найди ошибку»: чаще всего забыли вызвать функцию, потеряли скобки (privet вместо privet()), вернули результат без return или вызвали функцию выше её def. Третий — «напиши функцию»: читай условие как спецификацию — имя, параметры, что возвращать; задача «посчитай площадь прямоугольника» прямо диктует def plosh(a, b): return a * b. Проверяй себя вызовом с простыми числами: plosh(3, 4) обязана вернуть 12, иначе ищи ошибку в теле.


> **Имя занято.** Редкая, но болезненная ошибка: назвать переменную тем же именем, что и функцию. Написал summa = summa(2, 2) — в переменную попало число 4, а имя функции затёрлось: следующий вызов summa(3, 3) упадёт с ошибкой, потому что summa теперь число. Python не различает «типы имён»: одно имя — одно значение в памяти. Поэтому для результата придумывай другое слово: result, total, itog.


> **Совет.** Называй функции глаголами: privet, summa, itog — имя само рассказывает, что произойдёт при вызове. Держи функцию короткой: одна функция — одно дело. Главный приём отладки: сомневаешься в большой программе — вызови функцию отдельно с простыми числами и сверь с расчётом в голове: kvad(5) обязан вернуть 25, иначе ищи ошибку в теле. И не бойся читать чужие функции: тело — те же знакомые print, if и циклы, просто со сдвигом вправо. А когда собственных функций станет мало, открой библиотеку math: import math даёт готовые sqrt и floor — чужие библиотеки устроены из тех же функций, только написаны другими людьми.


*[Интерактив: Собери пары: язык функций — доступен на странице урока]*


*[Интерактив: Верно или нет? — доступен на странице урока]*


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

### Зачем писать функции, если программа и без них работает?

Без функций повторяющийся код копируют много раз, и править его приходится в каждом месте. Функция хранит блок один раз, а вызывается сколько нужно — программа короче, понятнее и реже ломается.


### Чем параметр отличается от аргумента?

Параметр — переменная в скобках при объявлении def, заготовка без значения. Аргумент — конкретное значение, которое подставляется в параметр при вызове.


### Что вернёт функция без return?

Специальное значение None. Программа не упадёт, но результат нельзя использовать в вычислениях: print(kvad(5)) напечатает None вместо 25.


### Почему Python напечатал 300.0, а не 300?

В формуле было деление на 100, а деление в Python всегда даёт дробный тип float — даже если ответ круглый. Это то же число 300, просто с дробной точкой.


## Проверь себя (вопросы и ответы)

#### Вопрос 1: Программа: def kvad(x): return x * x; print(kvad(6)). Что выведет программа?
**Ответ:** 36

*Пояснение: kvad(6) вернёт 6 * 6 = 36, и print напечатает 36.*


#### Вопрос 2: Что делает строка def privet():
- ☐ выполняет функцию privet
- ✅ объявляет функцию privet
- ☐ удаляет функцию privet
- ☐ печатает слово privet

*Пояснение: def только объявляет и запоминает функцию; тело выполнится при вызове privet().*


#### Вопрос 3: def только описывает функцию: чтобы код в теле заработал, функцию нужно вызвать.
- ✅ Правда
- ☐ Неправда

*Пояснение: Верно: объявление запоминает функцию, а запуск происходит при вызове — имени со скобками.*


#### Вопрос 4: Функция объявлена так: def f(a, b): return a + b * 2. Чему равно f(3, 4)? Впиши число.
**Ответ:** 11

*Пояснение: a = 3, b = 4: считаем 3 + 4 * 2 = 3 + 8 = 11. Умножение выполняется раньше сложения.*


#### Вопрос 5: Что вернёт функция, в теле которой нет команды return?
- ☐ 0
- ☐ пустую строку
- ✅ None
- ☐ ошибку

*Пояснение: Без return функция возвращает None — специальное значение «ничего».*


#### Вопрос 6: Соедини термин с его ролью.
- def — объявляет функцию
- return — отдаёт результат
- аргумент — значение при вызове
- None — результат без return

*Пояснение: Четыре слова, на которых держится вся тема функций.*


#### Вопрос 7: Программа: def privet(): print("Привет!"); for i in range(3): privet(). Сколько раз напечатается Привет!?
**Ответ:** 3

*Пояснение: Цикл range(3) делает три шага, на каждом выполняется privet() — итого три печати.*


#### Вопрос 8: Вставь пропущенное.
Ключевое слово **def** объявляет функцию, а команда **return** отдаёт результат той строке, которая вызвала функцию.

*Пояснение: def объявляет функцию, return завершает её и возвращает значение вызывающей строке.*


## Тренажёр

На [странице тренажёра](https://shkolniygid.ru/informatika/8-klass/funkcii-python-8/trenazher/) — 4 типов задач с бесконечными вариантами чисел, проверкой ответа и разбором каждого шага.
