Към съдържанието
wannacode

Параметри и return

Проблем

Една бележка, различни суми

Искаш функция, която печата последния ред на бележката: „Общо: … €“. Но сумата е различна за всяка поръчка.

Функциите от миналия урок печатат винаги едно и също. Функция print_total() няма откъде да знае сумата. Не искаш и функции за всяка сума поотделно. Трябва начин да подадеш сумата на функцията, когато я викаш.

Идеята

Параметри: какво получава функцията

Напиши в скобите име за това, което функцията очаква. Това е параметър. Вътре във функцията той е обикновена променлива.

При извикването слагаш в скобите стойността. Тя се казва аргумент.

def print_total(total):
print(f"Общо: {total} €")
print_total(12.5)
print_total(4.2)
Изход
Общо: 12.5 €
Общо: 4.2 €

total е параметърът. 12.5 и 4.2 са аргументите. Функцията е една, а печата различни суми.

Тип пред параметъра не се пише: Python не проверява какво подаваш. Ако подадеш текст вместо число, функцията ще го отпечата, без да се оплаче. Затова името на параметъра трябва да казва ясно какво се очаква.

Ако параметрите са няколко, разделяш ги със запетая. Аргументите се подават в същия ред.

Пробвай

По място, не по име

Какво ще отпечата програмата?

def print_line(item, qty):
print(f"{item}: {qty} бр.")
coffee = "Кафе"
qty = 3
print_line(coffee, 2)
Отговор

Проблем

Защо цената не се намали?

Написал си функция за 10% отстъпка и си я извикал:

def apply_discount(price):
price = price * 0.9
price = 100
apply_discount(price)
print(price) # 100
Изход
100

Цената пак е 100. Функцията не дава грешка, а отстъпката я няма. Къде отиде?

Виж го

Функцията получава стойността

def apply_discount(price):
price = price * 0.9
price = 100
apply_discount(price)
print(price) # 100
Стъпка по стъпка, с думи
  1. В програмата има променлива price = 100.
  2. Викаш apply_discount(price): за функцията се заделя нова памет.
  3. Нейният параметър price получава стойността 100.
  4. Функцията смята 100 * 0.9 = 90 и записва новото число в своето price.
  5. Функцията свършва и паметта ѝ изчезва, заедно с нейното price.
  6. А price в програмата си е 100.

При извикването функцията не получава самата променлива price, а нейната стойност, в своя собствена променлива price. Редът price = price * 0.9 слага новото число 90 в променливата на функцията. Когато функцията свърши, паметта ѝ изчезва, а с нея и това 90. Отвън нищо не се е променило: все едно функцията е получила копие. Това се казва предаване по стойност.

Двете променливи се казват еднакво (price) нарочно: точно това обърква на практика. Името няма значение, всяка функция има своите променливи.

По-точно, за любопитните

Точно казано, Python не копира числото. Параметърът сочи същото число 100, което сочи и price отвън. Но число не може да се промени на място: price = … само насочва името на функцията към друго число, а price отвън си сочи 100. Затова за числата и текста резултатът е като при копие. При списъците е друго: функцията може да промени самия списък (например с append), и промяната се вижда и отвън:

def add_item(items):
items.append("мляко")
cart = ["хляб"]
add_item(cart)
print(cart)
Изход
['хляб', 'мляко']

Идеята

return: функцията връща резултат

Поправката е функцията да върне новата цена. В тялото пишеш return и стойността. Тип на резултата не се пише: def е същото, независимо дали функцията връща нещо.

def apply_discount(price):
return price * 0.9
price = 100
price = apply_discount(price)
print(price) # 90.0
Стъпка по стъпка, с думи
  1. В програмата: price = 100.
  2. Викаш apply_discount(price): заделя се памет за функцията.
  3. Параметърът price получава стойността 100.
  4. return price * 0.9: резултатът е 90.
  5. Резултатът се връща в програмата и се записва в price.
  6. Сега price в програмата е 90.

Извикването apply_discount(price) вече е стойност. Можеш да я запишеш в променлива (както тук), да я отпечаташ или да смяташ с нея.

По-точно, за любопитните
  • Функция без return също връща нещо: None, стойността „нищо“. Ако отпечаташ резултата на първата версия, която само намаляваше своето копие, ще видиш точно това:
def apply_discount(price):
price = price * 0.9
print(apply_discount(100))
Изход
None
  • Може да пишеш и return без стойност. Той просто приключва функцията.
  • Функцията може да върне няколко стойности наведнъж: изброяваш ги със запетая след return, а при извикването ги записваш в толкова променливи:
def get_limits():
return 1, 10
low, high = get_limits()
print(low, high)
Изход
1 10

Пробвай

Какъв е резултатът?

Функцията смята ДДС от 20% върху цената. Какво трябва да пише на празното място, за да получи резултата този, който я вика?

def vat(price):
     price * 0.2

Пробвай

Върнато, но изгубено

Какво ще отпечата програмата?

def reserve(seats):
seats = seats - 2
print(f"вътре: {seats}")
return seats
seats = 10
reserve(seats)
print(f"отвън: {seats}")
Отговор

Идеята

return приключва функцията

Магазинът не взима доставка за поръчки от 50 € нагоре. Иначе доставката е 4,99 €:

def shipping_cost(total):
if total >= 50:
return 0
return 4.99
print(shipping_cost(62.0))
print(shipping_cost(18.5))
Изход
0
4.99

Щом стигне до return, функцията свършва веднага. Затова при 62 € вторият return не се изпълнява и не ни трябва else.

Функция с резултат трябва да върне стойност по всеки път. Но Python не го проверява. Ако махнеш последния ред, програмата върви, а за поръчка от 18,50 € функцията стига до края си без return и връща None:

def shipping_cost(total):
if total >= 50:
return 0
print(shipping_cost(62.0))
print(shipping_cost(18.5))
Изход
0
None

Грешка няма, затова такъв пропуск се хваща трудно. Гледай изхода и пробвай всеки път през функцията.

Пробвай

Намери грешката

Членовете на клуба имат 10% отстъпка, останалите плащат пълната цена. Но отстъпка получават всички. На кой ред е грешката?

Избери реда с грешката.

Упражнение

Функции, които смятат

Реши задачите в редактора си. Всяка функция получава каквото ѝ трябва като параметри и връща резултата. Печата се извън функциите, в редовете под тях.

1. Средно аритметично. Функция average(values) връща средното на числата в списъка. Под нея прочети от клавиатурата колко са числата, после самите числа.

Вход
5
10
15
20
25
30
Изход
Средно аритметично: 20.0

2. Просто число. Функция is_prime(n) връща дали числото е просто (дели се само на 1 и на себе си). За 7 връща True, за 12 False.

3. Температури. Функции to_fahrenheit(c) и to_celsius(f). F = C · 9 / 5 + 32. Прочети температура и мерна единица (C или F) и отпечатай превърнатата.

Вход
100
C
Изход
100.0 C = 212.0 F

4. Калкулатор. Функция calculate(a, b, op) връща резултата за +, -, * или /. Операцията се избира с if.

Вход
10
5
+
Изход
10.0 + 5.0 = 15.0

5. Триъгълник с параметър. Обещахме го в миналия урок. Функция print_triangle(height) извежда правоъгълен триъгълник от звездички с височина height. За 3:

Изход
*
* *
* * *
По-точно, за любопитните

В Python / винаги дава дробно число, затова 5 / 9 е 0.5555…, а не 0, както в Java и C#. Целочисленото деление е //:

print(5 / 9)
print(7 // 2)
Изход
0.5555555555555556
3

Упражнение

Функции за списъци

Всяка задача е една функция, която получава списък (или дума) и връща резултат. Накрая ги събери в една програма.

  1. total, sum_even и sum_odd: сумата на всички, на четните и на нечетните числа в списъка.
  2. reverse: връща нов списък с числата в обратен ред.
  3. largest и smallest: най-голямото и най-малкото число.
  4. is_palindrome(word): дали думата се чете еднакво отпред назад и отзад напред.
  5. sum_diagonals и sum_diagonals_once: сумата по двата диагонала на квадратна матрица, с централния елемент два пъти и веднъж.
  6. Всичко заедно: за списъка [1, 2, 3, 4, 5], числото 7 (с is_prime от горната карта), думите „капак“ и „АБВГД“ и матрицата 3 × 3 с числата от 1 до 9.

В Python sum, max и min вече са вградени функции. Ако кръстиш своята функция sum, тя скрива вградената в цялата програма. Затова нашите се казват total, largest и smallest.

Изход от задача 6
Сума: 15, Четни: 6, Нечетни: 9
Обърнат: [5, 4, 3, 2, 1]
Макс: 5, Мин: 1
7 е просто: True
капак: True, АБВГД: False
Сума с повторение: 30, Сума без повторение: 25

Тест

Провери се

1. В def vat(price): кое е параметърът?
2. Функцията дава нова стойност на своя параметър. Какво става с променливата, подадена при извикването?
3. Какво прави return?
4. Функцията стига до края си, без да мине през return. Какво връща?
5. Какво прави редът price = apply_discount(price)?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·