На этой странице вы узнаете
- Как обхитрить учителя по математике?
- Как функции могут пригодиться на практике?
- Куда деть return, если он нам не нужен?
Оцените по 10-бальной шкале, как сильно вы любите делать домашнюю работу по математике? Возможно, кто-то даст 10. Но точно будут те, кто оценит не выше, чем 2, а может даже -2. Хорошая новость — вам не придется ее делать.
Постановка задачи
Прежде чем приступать к практике, советуем посмотреть статьи:
Если все готовы, приглашаем применить полученные знания и написать программу, которая сама сделает домашнее задание за нас.

Дисклеймер: мы не пропагандируем бойкотирование домашней работы по математике и отказ от ручного решения задач! Эта статья написана с целью показать вам примеры работы функций и рекурсий на практике и не более. Знания важны. Все-таки на контрольной ноутбук под партой не спрячешь.

| Как обхитрить учителя по математике? Например, на дом нам задали: 1. Найти площадь треугольника по формуле Герона. 2. Найти решение квадратного уравнения. 3. Творческое задание. Всё такое разное… Или нет? Любую из этих задач можно решить с помощью программирования, и учитель даже не поймет вашей хитрости. Этим мы сейчас и займемся. |
Если вы сталкиваетесь с задачами, которые кажутся сложными или непонятными, обратитесь к ссылкам на учебник по математике, которые представлены в этой же статье. Они могут помочь вам разобраться и найти более подробную информацию о теме, которую вы изучаете.
Не будем медлить — за дело!
Пишем функции
| Как функции могут пригодиться на практике? Нет-нет, давайте зададим более правильный для начала вопрос: а зачем нам функции? Код ведь можно написать и без них. Можно. Но написав функцию один раз, мы сможем использовать ее в будущем сколько угодно раз. Например, если нам будет дан не один треугольник и не одно квадратное уравнение. Вот поэтому функции очень полезны для решения наших практических нужд. |
Пойдем по порядку — начнем с поиска площади треугольника по формуле Герона. Вкратце вспомним ее: площадь треугольника со сторонами a, b, c равна \(\sqrt{p*(p-a)*(p-b)*(p-c)}\), где p — полупериметр треугольника.
Что понадобится нашей функции?
- На вход ей нужно дать три числа — стороны треугольника.
- Внутри описать нахождение его площади.
- Вернуть значение площади (для этого используется команда return).
В программе Python есть несколько вариантов извлечения квадратного корня, например:
- возведение в степень 0.5;
- использование функции sqrt из модуля math.

Второй способ мы рассматривали в предыдущей статье, сейчас попробуем первый.
def tr_square(a, b, c):
p = (a + b + c) / 2
sq = (p * (p - a) * (p - b) * (p - c)) ** 0.5
return sq
Теперь мы можем вычислить площадь любого треугольника:
| print(tr_square(3, 4, 5)) | Вывод: 6.0 |
| print(tr_square(25, 30, 15)) | Вывод: 187.08286933869707 |
| print(tr_square(100, 100, 100)) | Вывод: 4330.127018922193 |
Первая задача решена.
И сразу переходим ко второй — поиску решения квадратного уравнения. Будет чуть интереснее, так как все зависит от дискриминанта. Любое квадратное уравнение имеет вид \(a*x^2+b*x+c=0\), и значение дискриминанта будет равно \(D=b^2-4*a*c\).
- Если дискриминант окажется меньше 0, решений нет.
- Если он равен 0, решение будет одно.
- Если он больше 0, решений будет два.

Что понадобится нашей функции?
- На вход ей нужно дать три числа — коэффициенты уравнения.
- Внутри описать нахождение дискриминанта.
- В зависимости от значения дискриминанта найти и вернуть решение уравнения.
def quadratic(a, b, c):
D = b**2 - 4 * a * c
if D < 0:
return "Нет ответа в целых числах"
elif D == 0:
x = -b / (2 * a)
return x
else:
x1 = (-b + D ** 0.5) / (2 * a)
x2 = (-b - D ** 0.5) / (2 * a)
return (x1, x2)
Если честно, это не очень хороший код. Он однозначно рабочий. Но загвоздка заключается в том, что в одном из трех случаев мы вернем различные типы данных:
- при D < 0 — строку с сообщением;
- при D = 0 — одно число;
- при D > 0 — массив с двумя числами.
Многие другие языки такого вообще не разрешают, повезло, что Python так лоялен. Если нам надо будет использовать решение квадратного уравнения дальше (например, в задаче по физике), обязательно проверяем, какое именно значение нам вышло.
| Куда деть return, если он нам не нужен? Если нам достаточно вывести значение на экран, return можно опустить. Вместо него лучше поставить print, который выведет нам результат на экран и сразу его забудет. |
def quadratic(a, b, c):
D = b**2 - 4 * a * c
if D < 0:
print("Нет ответа в целых числах")
elif D == 0:
x = -b / (2 * a)
print("Один корень:", x)
else:
x1 = (-b + D ** 0.5) / (2 * a)
x2 = (-b - D ** 0.5) / (2 * a)
print("Два корня:", x1, x2)
Запуская этот вариант, мы не должны вызывать print, только саму функцию. Print уже внутри нее. Но, повторим еще раз, записать таким образом результат в переменную мы не сможем. А если это и не было нужно, то нам же легче. Но важно отметить, что в больших проектах есть свои правила написания кода, и прописывать print в функцию не совсем корректно, но мы пишем код для себя в рамках экзамена, поэтому это дозволительно!
| Уравнение | Вызов функции | Вывод |
| x2+5x+6=0 | quadratic(1, 5, 6) | Два корня: -2.0 -3.0 |
| 40×2-56=0 | quadratic(40, 0, -56) | Два корня: 1.1832159566199232 -1.1832159566199232 |
| 4×2+4x+1=0 | quadratic(4, 4, 1) | Один корень: -8.0 |
| 8×2+2x+2=0 | quadratic(8, 2, 2) | Нет ответа в целых числах |
Еще одним немаловажным аспектом практики работы с функциями является рекурсия. Именно о ней мы и поговорим далее.
Пишем рекурсию
Последнее творческое задание состоит в следующем: найти, сколькими вариантами можно получить число 256 из числа 1, используя всего две операции — умножить на 2 и прибавить 5.
Мы могли бы использовать «наглый» перебор — просто подставлять эти операции в разном порядке, пока не наткнемся на ту, что даст нам 256. Мы бы нашли:
- 1 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 = 256;
- (1 * 2 + 5 + 5 + 5 + 5 + 5 + 5) * 2 * 2 * 2 = 256.
Как быстро нам надоест — вопрос хороший, но рано или поздно это произойдет точно.
Пример рекурсии вы наверняка встречали в жизни, когда играли с матрешкой. Начиная с большой матрешки, рано или поздно мы дойдем до маленькой, и будем производить вычисления, отталкиваясь от ее значения.

Давайте подумаем, как можно реализовать решение программой?
Мы можем находить промежуточные значения. Например, в 256 можно попасть из 128:
128 * 2 = 256
и из 251:
251 + 5 = 256.
Значит, из 128 и 251 есть по 1 варианту получения итогового числа.
Считаем дальше: в 128 можно попасть из 64 и 123, а в 251 — из 246.
Получается, в 128 еще можно попасть двумя вариантами, а в 246 — одним…
Похоже на рекурсию? Конечно, похоже — чтобы найти итоговый результат, надо найти промежуточные. В этом рекурсия хороша.
Логика рекурсии может быть следующей:
- На вход даем два числа — начальное значение и конечное.
- Если начальное стало равно конечному, значит, мы нашли еще один вариант получения конечного и возвращаем 1.
- Если начальное значение стало больше конечного, значит, мы пошли «не тем путем», который не нужно учитывать, так что возвращаем 0.
Например, если бы мы 200 умножили на 2 и получили бы 400, к 256 мы бы уже никак не вернулись. - Если начальное значение меньше итогового, мы должны посчитать результаты побольше, прибавив к начальному 5 или умножив его на 2, и сложить их.
Пункт 4 будет той самой рекурсией, которая будет считать промежуточные значения, а пункты 2 и 3 будут условиями остановки рекурсии.
def art_task(n1, n2):
if n1 == n2:
return 1
elif n1 > n2:
return 0
else:
return art_task(n1+5, n2) + art_task(n1*2, n2)
Чтобы найти ответ на задачу, вызываем эту функцию, передавая ей в качестве начального значения 1, а в качестве конечного — 256, и выводим его на экран.
| print(art_task(1, 256)) | Вывод: 658 |
Удивляемся тому, как мы должны были найти 658 вариантов руками. Вписываем ответ и спокойно идем заниматься другими делами — домашняя работа по математике выполнена.
Потренируемся применять полученные навыки на примере задачи 16 номера ЕГЭ.
Задание. Алгоритм вычисления значения функции F(n), где n – натуральное число, задан следующими соотношениями:
F(1) = 1
F(n) = F(n–1) * n, при n >1
Чему равно значение функции F(10)? В ответе запишите только натуральное число. Решение. Для решения данного задания воспользуемся Python, напишем код. На самом деле нужно просто переписать то, что дано в условии задания, в функцию!
def F(n):
if n==1:
return 1
if n>1:
return F(n-1) * n
Мы прописали функцию F(n), а затем переписали условия в код с помощью if и return.
Теперь нам нужно найти значение функции F(10):
print(F(10))
Полный код программы:
def F(n):
if n==1:
return 1
if n>1:
return F(n-1) * n
print(F(10))
Ответ:3628800
Надеемся, что теперь написание и применение функций стало вам намного понятнее. Помимо того, что работа рекурсивных функций напрямую связана с заданием №16 из ЕГЭ, их применение очень сильно облегчит вам решение других задач на программирование.
Навык работы с ними также пригодится в дальнейшем пути программиста, так как функции являются важной и неотъемлемой частью почти любой программы. А пока приглашаем вас продолжить изучение программирования и познакомиться с не менее интересной статьей «Работа со строками в Python».
Фактчек
- Функции необходимы для многократного использования одного и того же фрагмента кода. Это делает программу легче в реализации и меньше по объему.
- Функция может не иметь команды return, но тогда нужно найти другой способ получить результат ее работы. Один из вариантов — команда print в функции. Так, результат будет сразу выведен на экран, но в самой программе не будет сохранен.
Проверь себя
Задание 1.
Найдите строку с ошибкой в коде с функцией, которая находит квадрат переданного ей числа:
def sq(x, 2):
return x ** 2
print(sq(5))
- Ошибка в первой строчке — функции не нужно передавать двойку.
- Ошибка во второй строчке — такая запись некорректна, ответ сначала обязательно нужно посчитать в отдельную переменную.
- Ошибка в третьей строчке — команда print не нужна, функция и так выведет ответ на экран.
- В этом коде нет ошибок.
Задание 2.
Выберите строчку, которая должна стоять на месте пропуска, чтобы функция, которая находит площадь треугольника по формуле \(S=a*h/2/\), работала корректно:
S = a * h / 2
return S
- def f(a, h, S):
- def f():
- print(f())
- def f(a, h):
Задание 3.
В чем заключается ошибка в реализации следующей рекурсии?
def recursion(x):
if x >20:
return recursion(x + 2)
elif x ==20:
return recursion(x * 2) + recursion(x - 6)
else:
return recursion(x / 3)
- Неправильная инициализация рекурсии.
- Эта рекурсия будет работать бесконечно, так как нет рекурсивного выхода.
- Ошибка в 5 строчке — складывать две рекурсии невозможно, эта запись некорректна.
- В одной функции не может быть несколько команд return.
Задание 4.
Какое значение будет выведено после выполнения данного кода?
def recdef add_numbers(a, b):
return a + b
def multiply_numbers(a, b):
return a * b
result = add_numbers(3, 4) + multiply_numbers(2, 5)
print(result)
Ответ: 1. — 1; 2. — 4; 3. — 2.