Умскул учебник стремится стать лучше! Если вы наткнулись на ошибку или неточность в нашем материале - просто сообщите нам, мы будем благодарны!
Информатика

Практика работы с функциями

6.5.2022
2667

На этой странице вы узнаете

  • Как обхитрить учителя по математике?
  • Как функции могут пригодиться на практике?
  • Куда деть return, если он нам не нужен?

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

Постановка задачи

Прежде чем приступать к практике, советуем посмотреть статьи:  

Если все готовы, приглашаем применить полученные знания и написать программу, которая сама сделает домашнее задание за нас.

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

Как обхитрить учителя по математике?

Например, на дом нам задали:

1. Найти площадь треугольника по формуле Герона.
2. Найти решение квадратного уравнения.
3. Творческое задание.

Всё такое разное… Или нет? Любую из этих задач можно решить с помощью программирования, и учитель даже не поймет вашей хитрости. Этим мы сейчас и займемся.

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

Не будем медлить — за дело!

Пишем функции

Как функции могут пригодиться на практике?

Нет-нет, давайте зададим более правильный для начала вопрос: а зачем нам функции? Код ведь можно написать и без них.

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

Пойдем по порядку — начнем с поиска площади треугольника по формуле Герона. Вкратце вспомним ее: площадь треугольника со сторонами a, b, c равна \(\sqrt{p*(p-a)*(p-b)*(p-c)}\), где p — полупериметр треугольника.

Что понадобится нашей функции?

  1. На вход ей нужно дать три числа — стороны треугольника.
  2. Внутри описать нахождение его площади.
  3. Вернуть значение площади (для этого используется команда 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\).

  1. Если дискриминант окажется меньше 0, решений нет.
  2. Если он равен 0, решение будет одно.
  3. Если он больше 0, решений будет два.

Что понадобится нашей функции?

  1. На вход ей нужно дать три числа — коэффициенты уравнения.
  2. Внутри описать нахождение дискриминанта.
  3. В зависимости от значения дискриминанта найти и вернуть решение уравнения.

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)

Если честно, это не очень хороший код. Он однозначно рабочий. Но загвоздка заключается в том, что в одном из трех случаев мы вернем различные типы данных:

  1. при D < 0 — строку с сообщением;
  2. при D = 0 — одно число;
  3. при 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=0quadratic(1, 5, 6)Два корня: -2.0 -3.0
40×2-56=0quadratic(40, 0, -56)Два корня: 1.1832159566199232 -1.1832159566199232
4×2+4x+1=0quadratic(4, 4, 1)Один корень: -8.0
8×2+2x+2=0quadratic(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. На вход даем два числа — начальное значение и конечное.
  2. Если начальное стало равно конечному, значит, мы нашли еще один вариант получения конечного и возвращаем 1.
  3. Если начальное значение стало больше конечного, значит, мы пошли «не тем путем», который не нужно учитывать, так что возвращаем 0.
    Например, если бы мы 200 умножили на 2 и получили бы 400, к 256 мы бы уже никак не вернулись.
  4. Если начальное значение меньше итогового, мы должны посчитать результаты побольше, прибавив к начальному 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))

  1. Ошибка в первой строчке — функции не нужно передавать двойку.
  2. Ошибка во второй строчке — такая запись некорректна, ответ сначала обязательно нужно посчитать в отдельную переменную.
  3. Ошибка в третьей строчке — команда print не нужна, функция и так выведет ответ на экран.
  4. В этом коде нет ошибок.

Задание 2.
Выберите строчку, которая должна стоять на месте пропуска, чтобы функция, которая находит площадь треугольника по формуле \(S=a*h/2/\), работала корректно:


	S = a * h / 2
	return S

  1. def f(a, h, S):
  2. def f():
  3. print(f())
  4. 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)

  1. Неправильная инициализация рекурсии.
  2. Эта рекурсия будет работать бесконечно, так как нет рекурсивного выхода.
  3. Ошибка в 5 строчке — складывать две рекурсии невозможно, эта запись некорректна.
  4. В одной функции не может быть несколько команд 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.

Понравилась статья? Оцени:
Читайте также:

Читать статьи — хорошо, а готовиться к экзаменам
в самой крупной онлайн-школе — еще эффективнее.

50 000
Количество
учеников
1510
Количество
стобальников
>15000
Сдали на 90+
баллов