Глава 14 Функції

⏱️ Час на опанування теми: 15 хвилин

🤷 Для чого ми це вивчаємо:

🔑 Результати навчання:

  • Розуміння що таке програма, додаток та програмне забезпечення
  • Розуміння що таке алгоритм, кодування та програмування

🎈 Увага: Наразі ця глава знаходиться у стані активної розробки і ймовірно буде змінюватись і доповнюватись!


У цій главі…


Про фунцкії ми вже говорили у Главі 4. Тоді ми визначили функції, як маленькі програми або набір інструкцій, який вирішував ту чи іншу проблему. Ми також використовували вже багато різноманітних вбудованих фунцкцій – abs() для знаходження модуля числа, max() для знаходження максимума серед елементів списку, len() для знаходження кількості елементів тощо.

14.0.1 Визначаємо фунцкії

Такі фунцкії як abs(), len() тощо називаються “вбудованими” у Python функціями. Код для цих фунцкій написали розробники мови Python і ми можемо їх зразу використовувати. Те що ми не знаємо з яких саме інструкції ці фунцкії складються та як саме вони працюють – не проблема. Ми використовуємо такі фунцкії як так звані “чорні скриньки” – ми знаємо вхідні дані (аргументи) та що очікувати на виході, але не механізм всередині.

Ми можемо подивитись на такі фунцкії з математичної точки зору. Функція – це те що ми по-простому називаємо формулою. Наприклад формула площі круга з радіусом \(r\) є \(s = \pi * r^2\). У цій формулі вхідними даними є радіус r і вона поверне площу, тобто s.

Часто нам доведеться створювати наші власні фунцкії. Правильно називати їх – user-defined functions або функції, визначенні користувачем. Ми будемо використовувати скорочену версію – просто функції. Для того щоб побудувати фунцкію, нам треба чітко знати вхідні дані, алгоритм функції та вихідні дані – те, що фунцкія поверне.

Давайте побудуємо фунцкію, яка розрахує площу трикутника, використовуючи довжини його сторін. Ці довжини ми позначимо буквами a, b та c. Це й будуть вхідні дані. Коли ми визначаємо фунцкію, вхідні дані ми називаємо параметрами фунцкії. Функція повинна повернути значення площі трикутника – це вихідні дані.

Тепер поговоримо про тіло фунцкії – ті інструцкії, які реалізують алгоритм або логіку фунцкії. Для того щоб нам обчислити площу трикутнику за трьома сторонами, нам треба скористатись формулою Герона. Якщо чесно, то автор цієї книги її не пам’ятав, тому подивився у Вікіпедії. Для того, щоб її використати, нам спершу треба знайти пів-периметр за формулою:

\[ p = \frac{a + b + c}{2} \]

Далі, площа трикутника за формулою Герона буде:

\[ s = \sqrt{p(p - a)(p - b)(p - c)} \]

Наша фунцкія буде виглядати:

def compute_area(a, b, c):
    p = (a + b + c) / 2
    s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
    return s

Давайте подивимось на які частини це визначення фунцкії поділяється:

  • def: ключове слово, яке свідчить про те, що далі буде визначення фунцкії
  • compute_area: ім’я фунцкії, яке може бути будь-яким дійсним ім’ям
  • (a, b, c): параметри функції, перелічені через кому
  • :: двокрапка, що позначає початок блоку коду
  • рядки p = (a + b + c) / 2, s = (p * (p - a) * (p - b) * (p - c)) ** 0.5 та return s: тіло функції
  • return: ключове слово що зазначає об’єкт, який буде повернений

Параметри функції a, b та c – це ті змінні, які ми будемо використовувати всередині фунцкії. Від параметрів взагалі кажуче й буде залежити те, що фунцкія буде робити та те, що вона поверне. Коли ми вже працюємо всередині фунцкії, тобто всередині її тіла, ми можемо думати що параметри – це звичайні змінні.

Після того, як функція написана, цей код треба виконати. Це не означає що ми використали цю фунцкію, ми тільки її визначили. Іншими словами, ми надали Python рецепт як приготувати борщ, але ми ще не почали його готувати. Грубо кажучи, ми присвоїли набір інструкцій до імені compute_area(), але не виконали їх. Тепер фунцкія знаходиться у пам’яті Python і ми можемо її використати у будь-який час. Процес використання фунцкії називається викликати фунцкію.

14.1 Викликаємо фунцкію

Для того щоб викликати фунцкію, достатньо зазначити її ім’я та зазначити у дужках аргументи фунцкії, якщо цього вимагає фунцкія. Коли ми визначаємо функцію, a, b та c називаються параметрами, а ось коли ми викликаємо фунцкію, вони вже називаються аргументами. Давайте виклечемо фунцуію compute_area():

compute_area(3, 4, 5)
## 6.0

Коли ми викликали фунцкію, це означає що Python почав виконувати інструкції з тіла фунцкії. При чому параметри функції a, b та c прйняли значення 3, 4 та 5, відповідно.

Після того як функція виконана, Python повертається назад до того місця, звідки фунцкія була виконана.

До речі, порядок розташування клітинок у Google Colab в якої міститься визначення функції та з якої ми її визиваємо не має значення. Має значення тільки порядок за яким ми їх викликаємо – спершу ми повинні виконати клітину з визначенням фунцкії, і тільки потім ми можемо викликати цю функцію.

14.1.1 Позиційні аргументи

Як Python здогадався, що коли ми викликали compute_area(3, 4, 5), саме a дорівнювало 3, b4, а c5? Це тому що порядок за яким ми задали значення 3, 4 та 5 співпадав з порядком параметрів a, b та c у визначенні. Такий спосіб задання аргументів називається позиційним. До речі, не тільки порядок параметрів повинен співпадати з порядком аргументів, а також їхня кількість. Якщо ми спробуємо передати іншу кількість аргументів, фунцкція поверне помилку:

compute_area(3, 4)
## compute_area() missing 1 required positional argument: 'c'

14.1.2 Ключові аргументи

Також ми можемо вказати ключові аргументи у виклику функції. Для цього нам треба для зазначити ім’я параметра, оператор дорівнює =, та значення аргументу:

compute_area(a = 3, b = 4, c = 5)
## 6.0

Коли ми заначили аргументи у compute_area() таким чином, ми сказали що аргумент з ім’ям a приймає значення 3, b - 4 та c - 5.

До речі, порядок ключових аргументів при виклику фунцкії є довільний12:

compute_area(b = 4, c = 5, a = 3)
## 6.0

14.1.3 Позиційні та ключові аргументи:

Ми також можемо міксувати позиційні та ключові аргументи, але позиційні повинні бути зазначені першими:

compute_area(3, c = 5, b = 4)
## 6.0

14.2 Значення параметрів за замовчуванням

Вхідних даних, тобто параметрів фунцкії може бути скільки завгодно. І буває таке, що їх взагалі нема. Якщо параметри у фунцкії все ж таки є, вони можуть мати значення за замовуванням. Давайте розбиратися що це таке.

Якщо ви колись замовляли Coca-Cola (або Fanta чи Sprite) в McDonald’s, то пам’ятаєте, що за замовчанням працівники додають лід до напою. Якщо ж ви хочете щоб лід не додавали, ви повинні про це попросити. Так само і у Python – коли ми визначаємо функцію, ми можемо надати значення за замовчуванням для будь-якого параметру. Якщо при виклику фунцкії ми не зазначили значення відповідного аргументу, то Python використує значення за замовчуванням. Якщо ми все ж таки зазначили – то використається саме зазначенне значення.

Для того щоб надати значення за замовуванням до параметрів, нам треба у визначенні функції зазанчити спершу ім’я параметру, потім оператор = і нарешті саме значення. Давайте перепишемо визначення нашої функції compute_area() та надамо параметрам b та c значення за замовчуванням 3:

def compute_area(a, b = 3, c = 3): # зверніть увагу на значення за замовчуванням
    p = (a + b + c) / 2
    s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
    return s

Тепер ми можемо викликати цю фунцкію зазначивши тільки один аргумент a. Аргументи b та c при цьому приймуть значення за замовчуванням 3:

# За замовчуванням b = 3 та c = 3. Ми не повинні їх зазначати. 
compute_area(a = 2)
## 2.8284271247461903

Але якщо ми зазначимо не тільки a, а й b та c, то фунцкія використає саме значення які ми надали при виклику фунцкії, а не значення за замовчуванням:

compute_area(a = 3, b = 4, c = 5)
## 6.0

З параметрами пов’язані ще кілька менш важливих трюків, про які ми поговоримо у Додатку H.

14.3 Повертаємо значення

Як ми вже сказали, фунцкція може повертати якісь вихідні дані. Цими даними може бути будь-який об’єкт: число int, список list, кортеж tuple. Для того щоб повернути об’єкт, треба використати ключове слово return і після нього прописати те, що повинно повернутись. Ключове слово до речі припинить виконання фунцкії, тобто будь які інструкції після return будуть ігноруватись.

Подивимось на кілька прикладів. У ціх прикладах, ми будемо визначати фунцкії і зразу ж їх викликати. Ці фунцкції будуть максимально спрощенні, щоб ми могли сконцентруватися на тому, як вони працюють, а не на тому що вони роблять.

Приклад перший, коли фунцкія повертає число int, коли аргумент int:

def square(x):
    return x ** 2

square(2)
## 4

Ось приклад, коли фунцкія повертає кортеж tuple:

def get_extremes(x):
    # не забувайте, що ми можемо не зазначувати дужки, коли створюємо кортежі
    return min(x), max(x) 

get_extremes([1, 2, 10, -2, 3])
## (-2, 10)

А ось приклад, коли ключове слово return спричиняє передчасний вихід із фунцкії. Іншими словами, все що під return не буде виконане:

def square(x):
    return x ** 2
    print("Ця текст не буде роздрукований.")
    print("І цей теж!")

square(2)
## 4

Як бачимо ні "Ця текст не буде роздрукований." ні "І цей теж!" не було роздруковано, тому що Python ігнорував код, який був нижчий рядку з return.

Ми не мусимо зазначати ключове слово return. Мета деяких функцій може бути зосередженна не на тому щоб щось повернути, а створити якись побічний ефект (side-effect), наприклад роздрукувати щось. Ось вам приклад фунцкії, яка просто надрукує "Вставай!" на екран:

def alarm():
    print("Вставай!")

alarm()
## Вставай!

Але якщо фунція в явному вигляді нічого не повертає, вона за замовчанням поверне None. У Python, None позначає відсутність значення, тобто нічого:

def alarm():
    print("Вставай!")

returned_value = alarm()
## Вставай!
print(returned_value)
## None

У цій главі…



🤸 Вправи
1. Перетягніть ф-ції відповідно до їх виду 👾:
def avg (x, y)
min()
max()
len()
def sum(a, b):
sum()
int()
def compute_area(a, b, c):
Вбудовані
Визначені користувачем
2. На які частини поділяється визначення функції?
3. Котрий рядок коду правильно визначить функцію?
4. Що буде результатом виконання наступного коду?
def multiply(a, b): 
    result = a * b 
    return result 
    
x = multiply(2, 3)
x
Оберіть правильну відповідь:
4. Що потрібно написати замість квадратних дужок, щоб функція рахувала суму двох чисел?
def add(a, b):
  result = []
  return result
Напишіть правильну відповідь:

  1. Проте у випадку нашої фунцкії, порядок задання аргументів все одно не відіграє важливу роль.↩︎