Функции
Функции - это часть кода, к которой мы обращаемся по имени.
Нужны для:
- повторное использование кода (а не его copy-paste);
- разбить задачу на подзадачи
Вы уже пользовались функциями языка python. Это print(), input(), int(), float().
Можно написать функцию самим.
Простая функция
Напишем функцию, у которой нет аргументов и которая ничего не возвращает. Придумаем имя функции hi. Функция печатает hello.
# делаем функцию.
# def - ключевое слово
# hi - придумали (сами) имя функции
def hi():
print("hello") # код функции пишем с отступами
# закончились отступы - закончилась функция.
hi() # вызов функции hi, функция печатает hello
hi() # вызов функции hi, функция печатает hello
Не забывайте : после )
Передаем в функцию числа
Напишем вычисление периметра и площади прямоугольника через функции. Тогда можно будет просто посчитать периметр и площадь разных прямоугольников в одной программе.
У функции могут быть аргументы. Для вычисления периметра и площади прямоугольника нужно передать функции стороны прямоугольника.
Один раз создали функцию. Много раз можем использовать функцию.
def perimetr(a, b): # создали первую функцию perimetr, в нее передают два числа a и b
res = (a+b)*2
return res # возвращает число
# первая функция закончилась
def area(a, b): # создали другую функцию area, в нее передают два числа a и b
res = a*b
return res
p = perimetr(3,5) # результат функции perimetr поместили в переменную p
print("Периметр = %d" % (p)) # напечатали p (Периметр = 16)
s = area(3,5) # результат функции area поместили в переменную s
print("Площадь = %d" % (s)) # напечатали s (Площадь = 15)
# можно сразу печатать результат функции
print("Периметр = %d" % (perimetr(3,5)))
print("Площадь = %d" % (area(3,5)))
p = perimetr(3.3, 5) # функция может считать и дробные числа
print("Периметр = %f" % (p)) # напечатали p по формату %f (Периметр = 16.6)
s = area(3.3, 5) # результат функции area поместили в переменную s
print("Площадь = %f" % (s)) # напечатали s по формату %f (Площадь = 16.5)
Возвращаем несколько значений
Функция может возвращать несколько значений. Их пишут через запятую (,)
На самом деле передается один кортеж (tuple). TODO: ссылку на главу с новым термином.
Функции height передаем рост в сантиметрах, а возвращает функция рост в метрах и сантиметрах
def height(h): # функция height, в нее передают одно число h
m = h // 100 # подсчитали рост в метрах
sm = h % 100 # подсчитали рост в сантиметрах
return m, sm # вернули сразу метры и сантиметры
# дальше программа. Пользуемся функцией height и проверяем ее.
# мой рост 169 см. Посчитаем его в метрах и сантиметрах
mym, mysm = height(169) # результаты функции поместили в переменные mym и mysm
print("мой рост %d метров %d сантиметров" % (mym, mysm))
you = int(input()) # прочитали ваш рост
ym, ysm = height(you) # результаты функции поместили в переменные ym и ysm
print("ваш рост %d метров %d сантиметров" % (ym, ysm))
Функция вызывает функцию
Напишем программу, которая по координатам 2 точек на плоскости считает расстояние между ними.
from math import sqrt
def length(x1, y1, x2, y2): # создали функцию length
dx = x1 - x2
dy = y1 - y2
res = sqrt(dx*dx + dy*dy)
return res
x1, y1, x2, y2 = map(int, input().split()) # прочитали сразу много чисел из 1 строки
dist = length(x1, y1, x2, y2) # результат работы функции length записали в dist
print(dist)
Функция length(x1, y1, x2, y2) считает расстояние между 2 точками на плоскости.
Теперь напишем другую программу. Которая по координатам 3 точек на плоскости считает площадь треугольника по формуле Герона.
Нужно писать мало кода. Возьмем старую функцию length и используем ее.
from math import sqrt
def length(x1, y1, x2, y2): # функция length уже написана и проверена
dx = x1 - x2
dy = y1 - y2
res = sqrt(dx*dx + dy*dy) # из функции length вызываем функцию sqrt
return res
def area3(x1, y1, x2, y2, x3, y3): # новая функция area3
a = length(x1, y1, x2, y2) # из функции area3 вызываем функцию length
b = length(x1, y1, x3, y3) # из функции area3 вызываем функцию length
c = length(x3, y3, x2, y2) # из функции area3 вызываем функцию length
p = (a+b+c)/2 # записываем формулы
res = sqrt(p*(p-a)*(p-b)*(p-c))
return res
x1, y1, x2, y2, x3, y3 = map(int, input().split())
s = area3(x1, y1, x2, y2, x3, y3)
print(s)
Не обязательные аргументы
Задача: написать функцию, которая считает расстояние до точки (x,y) на плоскости от начала координат (0,0)
Вариант 1. Самый плохой, потому что нужно писать много кода и отлаживать его. Можем ошибиться при написании формулы.
def length0(x, y): # создали функцию length0
res = sqrt(x*x + y*y)
return res
Вариант 2. Лучше. Пишем еще одну функцию, которая использует функцию length
def length0(x, y): # создали функцию length0
return length(x, y, 0, 0)
Вариант 3. Хорошо. Не нужно писать новый код.
Когда пишем функцию length(x1, y1, x2, y2) записываем в x2 и y2 значения по умолчанию 0. Аргументы x2 и y2 стали не обязательными. Можно вызвать функцию без этих аргументов, а она будет работать так, будто их значение 0.
Значение по умолчанию можно сделать любое. Не обязательно 0.
def length(x1, y1, x2=0, y2=0): # создали функцию length
dx = x1 - x2
dy = y1 - y2
res = sqrt(dx*dx + dy*dy)
return res
Когда вызываем функцию length, можем передавать все параметры, а можем не передавать x2 и y2. Тогда их значение будет по умолчанию 0.
d = length(3, 4, 3, -4) # расстояние между точками (3, 4) и (3, -4)
d = length(3, 4, 3) # расстояние между точками (3, 4) и (3, 0)
d = length(3, 4) # расстояние между точками (3, 4) и (0, 0)
Именованные аргументы
Мы передавали аргументы в функцию по их позиции.
d = length(3, 4, 3, -4) # расстояние между точками (3, 4) и (3, -4)
И понимали, что -4 - это значение аргумента y2.
Можно передавать аргументы в функцию по имени аргумента.
d = length(3, 4, x2=5, y2=-4) # расстояние между точками (3, 4) и (5, -4)
d = length(3, 4, y2=5, x2=-4) # расстояние между точками (3, 4) и (-4, 5)
# порядок вызова аргументов по имени НЕ важен
d = length(x1=3, x2=4, y1=5, y2=-4) # расстояние между точками (3, 5) и (4, -4)
# это тоже работает, потому что аргументы вызваны по имени и порядок не важен
d = length(3, y1=4, x2=5, y2=-4) # расстояние между точками (3, 4) и (5, -4)
# любой аргумент можно вызвать по имени
d = length(x1=3, 4, x2=3, y2=-4) # ОШИБКА! сначала аргумент по имени, потом - нет.
Если вызван аргумент по имени, все аргументы после него должны вызваться по имени
Проверить функцию - assert
Напишем функцию вычисления периметра и проверим, что она правильная.
def perimetr(a, b): # создали первую функцию perimetr, в нее передают два числа a и b
res = (a+b) # Ошибка! Забыли *2
return res # возвращает число
# Проверим функцию perimetr
print(perimetr(3,5)) # периметр должен быть равен 16
Программа напечатает 8. Мы посмотрим на perimetr(3,5) и посчитаем, что периметр должен равняться 16.
Нашли, что функция perimetr работает неправильно. Надо исправить.
И проверить еще раз.
Легче проверять, если печатать что посчитали и какое число должно быть.
print(perimetr(3,5), 16) # должно напечатать 16 и 16
print(perimetr(7,2), 18) # должно напечатать 18 и 18
print(perimetr(5,5), 25) # должно напечатать 25 и 25
Печатаются числа. Надо посмотреть, что числа одинаковые. Если числа разные - ошибка.
Можно заставить проверять компьютер. assert(выражение) - проверяет, правильное выражение или нет. Если правильное, то ничего не делает. Если неправильное, печатает где ошибка.
assert(perimetr(3,5)==16) # проверить, что perimetr(3,5) вернул 16
assert(perimetr(7,2)==18) # проверить, что perimetr(7,2) вернул 18
assert(perimetr(5,5)==25) # проверить, что perimetr(5,5) вернул 25
Если функция возвращает несколько значений, то их пишем в ( ) через ,
Функция msm из роста в сантиметрах (157) вычисляет рост в метрах (1) и сантиметрах (57). Возвращает метры и сантиметры (1, 57)
Напишем функцию и проверим ее.
def msm(h):
m = h//100
sm = h % 100
return m, sm
print(msm(157), 1, 57) # напечатает (1 57) 1 57 - можно проверить глазами
assert(msm(157))==(1, 57)) # программа сама проверит, что msm(157) вернет 1 и 57