1  Функції та змінні

Data Miorsh Ihor Miroshnychenko Youtube Monobank

1.1 Функції

Швидше за все, більшість з вас, ніколи раніше не програмували, тому давайте почнемо з основ. Давайте відкриємо Visual Studio Code, або VS Code, яка є дуже популярною програмою для написання коду в наш час. Вам не обов’язково писати код за допомогою саме цього інструменту. Насправді, все, що нам потрібно в кінці дня - це так званий текстовий редактор, програма для написання тексту. Внизу екрану знаходиться так зване вікно терміналу, це інтерфейс командного рядка, або інтерфейс CLI, до базового комп’ютера, будь то ваш Mac або ПК, або навіть якийсь сервер у хмарі. Давайте напишемо наступний код у вікні терміналу:

Terminal
code hello.py

Як ми скоро побачимо, будь-яка програма, яку ви пишете на Python, зазвичай має ім’я файлу, яке закінчується на .py, щоб вказати комп’ютеру, що це дійсно програма, написана на Python.

Після виконання коду з’явиться нове вікно з назвою hello.py. Давайте напишемо наступний код у файлі print('Привіт, світ!'). Навіть якщо ви ніколи раніше не програмували, швидше за все, ви можете здогадатися, що буде робити ця проста програма. Для того, щоб запустити програму, натисніть на стрілку у верхньому правому куті вікна або поверніться до вікна терміналу та виконайте наступну команду:

Terminal
python hello.py

Що це означає? Виявляється, що коли я пишу код на такій мові, як Python, мені потрібно інтерпретувати код зверху вниз, зліва направо, щоб комп’ютер розумів, що необхідно робити. Зрештою, навіть якщо ви не дуже багато знаєте про комп’ютери, ви, напевно, чули, що комп’ютери розуміють лише нулі та одиниці, так звану двійкову систему числення. Що ж, якщо це так, то щось не дуже схоже, що print('Привіт, світ!') є нулями та одиницями. Ми повинні якось перевести це в нулі та одиниці, які розуміє комп’ютер. Отже, Python - це не лише мова, якою ми будемо писати код, це також програма, інакше відома як інтерпретатор, яку ви безкоштовно встановлюєте на власний комп’ютер. І ви можете запустити цей інтерпретатор, передавши йому на вхід ім’я вашого файлу, у нашому випадку hello.py. І тоді цей інтерпретатор, займеться процесом його читання зверху вниз, зліва направо, і ефективно переведе його в ті нулі та одиниці, які комп’ютер може зрозуміти. Тож давайте виконаємо цю команду і якщо я нічого не переплутав, я побачу на екрані першу програму:

print('Привіт, світ!')
Привіт, світ!

А тепер давайте зробимо крок назад і подумаємо, що ж ми щойно зробили, і що ж ми бачимо на екрані? Перш за все, у більшості мов програмування ви маєте доступ до того, що називається функціями.

Функція (анг. functions) - це дія або дієслово, яке дозволяє вам робити щось у програмі. Загалом, будь-яка мова постачається з певним наперед визначеним набором функцій, деяких базових дій або дієслів, які комп’ютер вже знає. А ви можете використовувати ці функції за власним бажанням, щоб змусити комп’ютер виконувати ці дії. Програма hello.py, про яку йде мова, використовує одну функцію. І ви, мабуть, можете здогадатися, що мова йде про функцію print(). Дана функція друку, звичайно, не друкує якийсь наперед визначений рядок тексту. Вона друкує те, що ви їй передаєте. І тут ми знайомимось з ще однією частиною термінології у світі програмування, а саме аргументи.

Аргументи (анг. arguments) - це вхідні дані для функції, які якимось чином впливають на її поведінку. Розробники Python, звичайно, не знали, що саме ми з вами захочемо надрукувати на екрані. Тому вони розробили цю функцію друку з можливістю приймати на вхід деякий рядок тексту щоб ця функція в кінцевому підсумку надрукувала його на екрані. Наша програма hello.py виводить на екранПривіт, світ!. І це, як правило, у програмуванні називається побічним ефектом (анг. side effects). Він може бути візуальним, звуковим, виконувати запису файл або базу даних тощо.

Отже, я написав першу програму. Все пройшло за планом. Я не зробив жодної помилки. Але, чесно кажучи, коли ви вчитеся програмувати, і навіть коли ви навчилися програмувати, через роки ви будете робити помилки. І ці помилки відносяться до терміну, який ви, можливо, вже знаєте, а саме до багів. Баг (анг. bugs) - це помилка у програмі. Вони можуть приймати найрізноманітніші форми і наша задача навчитися виправляти їх. Ми розглянемо багато інструментів, як розумових, так і технічних, за допомогою яких ви зможете вирішити ці проблеми.

Тож дозвольте мені зараз навмисно зробити помилку: припустимо, що я забув дописати закриваючі дужки в кінці коду. Код на 99% правильний. Але навіть такі маленькі, здавалося б, незначні деталі, на які ми з вами насправді не звертаємо уваги якщо надсилаємо електронного листа чи текстове повідомлення, це просто друкарська помилка. Нічого страшного. Для комп’ютера це буде великою проблемою. Комп’ютер сприйме вас буквально. І якщо ви не закінчите свою думку так, як очікує мова програмування, вона не обов’язково запуститься взагалі:

print('Привіт, світ!'
  Cell In[3], line 1
    print('Привіт, світ!'
                         ^
SyntaxError: incomplete input

Ця помилка, на щастя, досить проста, вона говорить про те, що відкрита дужка ніколи не була закрита. І тепер інтуїтивно зрозуміло, що мені потрібно зробити - закрити її. На жаль, іноді повідомлення про помилки будуть не такими зручними для користувача.

А тепер давайте розглянемо, як ми можемо покращити цю програму. Давайте почнемо вдосконалювати цю програму, щоб зробити її більш інтерактивною - чи можу я змусити програму сказати щось на кшталт "Привіт, Гаррі", "Привіт, Герміоно", "Привіт, Рон" або будь-яке інше ім’я користувача? Для цього я повернуся до hello.py і додам ще один рядок коду на самому початку, який просто запитає ім’я користувача.

print('Як тебе звати?')
print('Привіт, світ!')

Але насправді мені потрібна інша функція, щоб отримати дані від користувача. І чудово, що в Python є функція з назвою input(). Якщо почитати документацію до функції цієї функції, виявляється, що вона приймає аргумент - рядок, який буде виведений на екран. Тож я можу покращити попередній код і записати наступне:

input('Як тебе звати? ') # Гаррі
print('Привіт, світ!')
Привіт, світ!

На жаль, програма нічого не робить з введеним ім’ям. Гаразд, чи можу я виправити це? Я можу перейти до рядка 2 і змінити світ на Гаррі:

input('Як тебе звати? ') # Гаррі
print('Привіт, Гаррі')
Привіт, Гаррі

Звичайно, програма працює не так, як передбачалося: уявімо, що наш користувач - це Герміона:

input('Як тебе звати? ') # Герміона
print('Привіт, Гаррі')
Привіт, Гаррі

Це називається “закодувати” або “жорсткий код” (анг. hard-code, hard coding) - я записав буквальне ім’я в середині коду.

Отже, нам потрібен якийсь спосіб отримати назад те, що ввів користувач, і, зрештою, щось з цим зробити. Для цього ми скористаємося ще однією особливістю програмування, а саме особливістю деяких функцій, яка полягає в тому, що вони можуть повертати значення (анг. return values). Метафорично кажучи, нам потрібно, щоб функція отримувала вхідні дані від користувача, а потім передавала їх мені, щоб я міг щось з ними зробити. Але якщо це буде передано мені, я хочу це кудись помістити, щоб потім надрукувати на екрані. Мені потрібно зробити еквівалент того, якби я взяв аркуш паперу, записав на ньому ім’я, щоб потім ввести його як вхідні дані у функцію друку. І для цього нам знадобиться ще одна особливість програмування, а саме змінні.

1.2 Змінні

Швидше за все, більшість з вас знайомі зі змінними ще з уроків математики: x, y, z і тому подібне. Програмування має таку саму здатність створити змінну, в даному випадку, в пам’яті комп’ютера. І ця змінна може зберігати значення, число, якийсь текст, навіть зображення, відео чи щось інше. Змінна - це просто контейнер для якогось значення всередині комп’ютера або всередині вашої програми.

При виборі імені змінної давайте дотримуватись певних правил, щоб наш код виконувався без помилок та його було зручно читати:

  • Ім’я змінної починається з літери;
  • Для імен змінних використовуватимемо маленькі літери з підкресленням замість пробілу;
  • Ім’я змінної не повинно співпадати з назвою ключових слів Python. Наприклад, назвати змінну if або True – погана ідея. Ключових слів не так багато, з частиною ми скоро познайомимося.
```{python}
False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield
```

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

name = input('Як тебе звати? ') # Гаррі
print('Привіт, name')
Привіт, name

Вочевидь це не те, що я очікував. Нам потрібен інший спосіб виводити значення всередині змінної, а не лише слово name. Дозвольте мені спробувати зробити це кількома різними способами.

У першому випадку я приберу запис name з другого рядка, і залишу змінну print(name) окремим рядком. Цього разу я буду більш уважним і не буду брати name у лапки, тому що ми вже бачили, що подвійні лапки означають буквально роздрукувати 'n-a-m-e':

name = input('Як тебе звати? ') # Гаррі
print('Привіт,')
print(name)
Привіт,
Гаррі

Гаразд, це працює, хоча і не так добре як хотілося. Принаймні, я вирішив проблему, просто поки що не дуже добре.

Але дозвольте мені зробити крок назад і представити кілька інших концепцій, з якими ми повинні бути знайомі, оскільки наші програми стають довшими, і вони вже не обмежуються одним, двома або навіть трьома рядками. Зрештою, наші програми стануть десятками рядків, можливо, навіть сотнями рядків. Давайте закладемо основу для успіху. Виявляється, що Python та багато інших мов програмування підтримують те, що називається коментарями.

Коментарі (анг. comments) - це примітки до вашого коду. Для включення коментарів до коду Python як правило, використовується символ хешу #. Це дозволяє вам писати еквівалент примітки до коду, але так, щоб не порушити ваш код. Комп’ютер фактично ігнорує ваші коментарі.

Тож я хочу додати кілька коментарів до попередньої програми:

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт,')
print(name)

Щойно я прокоментував кожен шматок коду. Навіщо? Ну по-перше, якщо я завтра вранці прокинусь і забуду все, що відбувалося минулого дня, зручно, маючи коментарі, зрозуміти що саме робить ця програма, щоб не читати сам код. По-друге, якщо ви допустили помилку, ви можете прочитати, що ви мали на увазі, коли писали код. А потім ви можете подивитися на код і з’ясувати, чи робить він зараз те, що ви хотіли. Це не є необхідним для такої маленької програми, як зараз. - з одного-двох-трьох рядків цілком очевидно, що робить програма. Але якщо ви звикнете коментувати свій код, це буде корисно, щоб нагадувати собі та іншим про те, що ви задумали і що робить ваш код.

А що якщо необхідно написати коментар, який займе декілька рядків? В такому випадку можна використати спеціальну техніку використовуючи потрійні лапки (одинарні або подвійні):

'''
Запитати користувача про ім'я
і вивести привітання
'''
name = input('Як тебе звати? ') # Гаррі
print('Привіт,')
print(name)

Коментарі також можуть слугувати своєрідним списком справ для вас самих. У програмуванні є таке поняття як псевдокод.

Псевдокод (анг. pseudocode) - це неформальна форма запису. Це просто використання природної мови, щоб висловити свої думки лаконічно, методично, алгоритмічно тощо. Тож, наприклад, якби я сьогодні не був впевнений, як я хочу написати цю програму, але я знав, що я хочу зробити, я міг би просто написавши наступне в hello.py:

# Запитати користувача про ім'я

# Вивести привітання

І вже після цього приступити до написання повноцінного коду. Отже, псевдокод - це гарний спосіб структурувати список справ, особливо якщо ви поки не знаєте, як писати код.

Гаразд, давайте повернемося до нашої програми і спробуємо ще вдосконалити її. У програмуванні іноді існує багато способів вирішити одну і ту ж проблему. І ось один із способів вирішити цю проблему: давайте у середині функції print() “додамо” змінну name. Це не додавання як таке, я не додаю числа, очевидно, але я хочу додати ім’я людини до рядка тексту:

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт,' + name)
Привіт,Гаррі

Так краще, але тут є невелика помилка, хоча і естетична. Тут не вистачає пробілу, але давайте просто скористаємося інтуїцією: якщо я пропускаю пробіл після коми, чому б мені просто не додати його вручну?

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт, ' + name) # додали пробіл після коми
Привіт, Гаррі

А тепер, якщо подивитися уважніше, ви могли помітити, що я поставив цей, здавалося б, зайвий пробіл у першому рядку мого коду після знаку питання: name = input('Як тебе звати? '). Це теж було просто для естетики. Я хотів перемістити курсор користувача на один пробіл праворуч, щоб коли користувач вводив своє ім’я, він не був одразу поруч з тим самим знаком питання.

Але є й інші способи зробити це. Виявляється, що деякі функції, зокрема print(), приймають декілька аргументів. І виявляється, що якщо ви відокремлюєте входи у функцію, так звані аргументи функції, комою, ви можете передати декілька аргументів. Тобто я можу передати 'Привіт, ' і name як два окремих аргументи функції print():

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт, ', name)
Привіт,  Гаррі

Гаразд, я трохи перестарався. Тепер у мене чомусь два пробіли. Виявляється, коли ви передаєте на друк кілька аргументів, програма автоматично вставляє пробіл для вас. Тож, якщо мені не потрібен додатковий пробіл, мені не потрібно вставляти додатковий пробіл у рядок:

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт,', name)
Привіт, Гаррі

Тепер все виглядає граматично так, як я хотів би. Який з цих підходів кращий? Останній підхід використовує функцію print() з двома аргументами, 'Привіт,' і змінна name. Попередня версія, нагадаю, технічно використовувала один аргумент, хоча це виглядало трохи дивно. Тоді це був один аргумент в тому сенсі, що комп’ютер, як і математики, спочатку виконує те, що знаходиться всередині круглих дужок. Тож, якщо всередині дужок у вас є рядок тексту, 'Привіт,' який мені потрібно додати, то у вас є +, який означає не додавання як таке, а конкатенацію, щоб з’єднати те, що зліва, і те, що справа. І все це відбувається динамічно.

1.3 Рядки

Дозвольте мені повернутися до коду, про який йде мова, і подивитися, чи зможемо ми показати вам пару інших способів вирішення тієї ж проблеми, підкресливши, той факт, що ми працюємо з рядками (анг. ‘strings’). Для таких даних у Python є окремий тип даних str - послідовність тексту.

Давайте повернемося до одного з попередніх варіантів написання програми з подвійним використанням функції print():

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт, ')
print(name)
Привіт, 
Гаррі

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

print(*objects, sep=' ', end='\n', file=None, flush=False)

З нього випливає наступне: - назва функції: print; - *objects означає, що функія може приймати будь-яку кількість об’єктів; - sep=' ' (скорочено від англ. separator) - родільник, який використовується для розділення об’єктів, які виводяться. За замовчуванням це пробіл; - end='\n' - символ, який виводиться після останнього об’єкта. За замовчуванням це символ нового рядка (\n).

Примітка

Документація до Python доступна на docs.python.org.

Тепер ми знаємо, що функція print() приймає аргумент end, який використовується для визначення символу, який виводиться після останнього об’єкта. Тому, якщо ми хочемо вивести 'Привіт, ' та 'Гаррі' на одному рядку, нам потрібно використати функцію print() двічі, передаючи аргумент end у першому виклику функції print():

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт, ', end='')
print(name)
Привіт, Гаррі

В той же час, якщо ми хочемо використати функцію print() для виведення декількох об’єктів, ми можемо використати аргумент sep для визначення роздільника між об’єктами:

# Запитати користувача про ім'я
name = input('Як тебе звати? ') # Гаррі

# Вивести привітання
print('Привіт', name, sep=', ')
Привіт, Гаррі

У випадках, коли нам необхідно використовувати апострофи або лапки в середині тексту, ми можемо використовувати різні види лапок, щоб уникнути помилки.

print("Привіт, 'Гаррі'")
print('Привіт, "Гаррі"')

Ще однією технікою є використання символу \ перед апострофом або лапками, які ми хочемо використати в тексті. Це називається екрануванням (англ. escaping).

print('Привіт, \'Гаррі\'')
print("Привіт, \"Гаррі\"")

1.3.1 f-рядки

f-рядки (англ. formatted string) - це рядки, які містять вирази, які обчислюються. Щоб створити f-рядок, ми використовуємо літеру f перед відкриваючою лапкою або апострофом. Вирази, які ми хочемо обчислити, ми пишемо в фігурних дужках {}. Якщо повернутися до нашого прикладу, ми можемо використати f-рядки, щоб вивести ім’я разом зі словом 'Привіт':

f-рядки роблять код більш читабельним і зручним, особливо коли ви працюєте з багатьма змінними і значеннями. Якщо ви працюєте з більш ранньою версією Python, то корисно знати і про інші методи форматування.

  1. За допомогою оператора %

Цей спосіб форматування рядків уже застарів, але все ще використовується в деяких старих проектах. Синтаксис схожий на форматування рядків у мові C, де %s використовується для вставки рядка, а %d для вставки числа:

name = "Гаррі"
age = 11
print("My name is %s and I am %d years old" % (name, age))
My name is Гаррі and I am 11 years old
  1. За допомогою методу format

Це метод рядка, який дає змогу форматувати текст, замінюючи вхідні аргументи всередині фігурних дужок {}. Ось приклад використання методу format():

name = "Гаррі"
age = 11
print("Моє ім'я {}. Мені {} років.".format(name, age))
Моє ім'я Гаррі. Мені 11 років.

Знаки {} у рядку були замінені на змінні, які були передані в метод format(). Це дає змогу створювати динамічні рядки, які змінюються залежно від змінних, переданих у метод format(). Можна використовувати індекси для заміни змінних:

name = "Гаррі"
age = 11
print("Моє ім'я {1}. Мені {0} років.".format(name, age))
Моє ім'я 11. Мені Гаррі років.

Тут ми використовували індекс 1 для заміни змінної age, індекс 0 - для змінної name. Це може бути корисно, якщо потрібно змінювати порядок виведення змінних у рядку. Крім того, можна використовувати іменовані аргументи для заміни:

print("Моє ім'я {name}. Мені {age} років.".format(name='Гаррі', age=11))
Моє ім'я Гаррі. Мені 11 років.

1.3.2 Методи рядків

Навіть коли ми виконували відносно прості операції, ми, як правило, покладалися на те, що користувач буде вводити саме те, що ми хочемо, щоб він ввів. Однак, це не означає, що результат вводу буде виглядати так, як ми хочемо. Чесно кажучи, ми з вами маємо звичку на веб-сайтах і в додатках часто випадково натискати пробіл, або на початку введення, або в кінці. Можливо, через те, що пробіл дуже велика клавіша, досить часто трапляються випадкові пробіли до або після введення даних користувачем. Також, ми з вами, безумовно, маємо звичку не завжди писати слова з великої літери, як слід. Якщо ми надсилаємо текстові повідомлення, ми, ймовірно, трохи поспішаємо і просто надсилаємо все в нижньому регістрі. Ми з вами не можемо покладатися на те, що нам обов’язково вдасться надрукувати все правильно, коли ми користуємося якимось програмним забезпеченням, чи то додатком, чи то веб-сайтом, чи чимось іншим.

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

Давайте повернемося до нашого прикладу, але цього разу я спеціальну напишу ім’я користувача з маленької літери та з зайвими пробілами на початку і у кінці:

Як бачите, ім’я виводиться з пробілами на початку і в кінці. Якщо ми хочемо видалити пробіли з початку і кінця рядка, ми можемо використати метод .strip():

Вже краще, але що робити з ім’ям, яке введене з маленької літери? Ми можемо використати метод .capitalize(), щоб перетворити першу літеру рядка на велику:

Тепер розглянемо приклад, коли користувач вводить не тільки ім’я, але і прізвище:

Метод .capitalize() перетворює першу літеру рядка на велику. Але якщо нам необхідно записати і ім’я, і прізвище з великої літери? Ми можемо використати метод .title():

З іншої сторони, якщо ми хочемо вивести тільки ім’я, а користувач ввів ім’я та прізвище, ми можемо використати метод .split(). Цього разу я не буду додавати зайвих пробілів до імені:

1.3.3 Спеціальні символи в рядках

Ми вже знаємо, що для створення рядка достатньо використовувати подвійні чи одинарні лапки. Все, що знаходиться всередині лапок, сприйматиметься як рядок.

string1 = 'Привіт, світ!'
string2 = "Моє ім'я Гаррі"

Якщо ми виведемо string1 і string2 на друк за допомогою функції print(), то побачимо на екрані всі символи, які ми помістили всередині лапок. Але це завжди так. У Python, як і в більшості мов програмування, у рядках можуть бути використані спеціальні символи. Вони називаються екранованими послідовностями.

Ось деякі з найбільш часто використовуваних екранованих послідовностей у Python:

  • \n — перенесення рядка
  • \t - табуляція
  • \' - одинарна лапка
  • \" - подвійна лапка
  • \\ — зворотний слеш

Розберемо їх використання відразу на прикладі:

string1 = '\'Ґрифіндор\' - чемпіон з квідичу!\n1996 – 1997'
print(string1)
'Ґрифіндор' - чемпіон з квідичу!
1996 – 1997

Таким чином, коли у рядку з’являється зворотний слеш \, програма чекає після нього спеціальний символ. Сам зворотний слеш не виводиться на друк. А символ після слеша вже інтерпретується, наприклад, як перенесення рядка чи відступ.

Подивіться ще приклади:

print("Привіт\nсвіт!")
Привіт
світ!
print("C:\\Users\\user\\Desktop\\file.txt")
C:\Users\user\Desktop\file.txt
print("Ім'я:\tГаррі")
Ім'я:   Гаррі
print('Кам\'яні стіни, як і в «Ґрінґотсі», освітлювали смолоскипи')
Кам'яні стіни, як і в «Ґрінґотсі», освітлювали смолоскипи
print("Кам'яні стіни, як і в «Ґрінґотсі», освітлювали смолоскипи")
Кам'яні стіни, як і в «Ґрінґотсі», освітлювали смолоскипи
Примітка

Документація до методів рядків у Python доступна за посиланням.

1.4 Цілі числа

Цілі числа, int (англ. integer) - це окремий тип даних у Python. Цілі числа можуть бути додатніми, від’ємними або нулем. Наприклад, 1, -1 та 0 - цілі числа. Цілі числа можна додавати, віднімати, множити та ділити. Крім того є ще декілька операцій, які можна виконувати з цілими числами, такі як піднесення до степеня, взяття остачі від ділення та інші. Давайте розглянемо їх:

  • +: додавання
  • -: віднімання
  • *: множення
  • **: зведення в ступінь
  • /: ділення
  • //: цілочислове ділення, арифметична операція, результатом якої є ціла частина частки, отриманого поділом одного цілого числа на інше ціле число
  • %: залишок від ділення

Давайте подивимось, чи зможемо ми створити власний маленький калькулятор. Цього разу ми створемо файл calculator.py та запишемо у нього наступний код:

Terminal
code calculator.py

Для початку ми попросимо користувача ввести перше число, а потім друге. Після цього ми виведемо результат додавання, віднімання, множення та ділення цих чисел. Давайте запустимо наш файл та перевіримо, чи працює наш калькулятор:

# Запитати користувача про перше число
first_number = input('Введіть перше число: ') # '1'

# Запитати користувача про друге число
second_number = input('Введіть друге число: ') # '2'

# Вивести результат додавання
print(f'Результат додавання: {first_number} + {second_number} = {first_number + second_number}')
Результат додавання: 1 + 2 = 3

Що тут відбувається? Чому результат додавання двох чисел дорівнює 12? Це тому, що ми використали метод input(), який завжди повертає рядок. Щоб вирішити цю проблему, нам потрібно перетворити рядок у ціле число. Для цього ми можемо використати функцію int(). Давайте виправимо наш код та перевіримо, чи працює наш калькулятор:

# Запитати користувача про перше число
first_number = int(input('Введіть перше число: ')) # '1'

# Запитати користувача про друге число
second_number = int(input('Введіть друге число: ')) # '2'

# Вивести результат додавання
print(f'Результат додавання: {first_number} + {second_number} = {first_number + second_number}')
Результат додавання: 1 + 2 = 3

Взагалі то ми можемо написати весь наш калькулятор у одному рядку:

print(f'Результат додавання: {int(input("Введіть перше число: ")) + int(input("Введіть друге число: "))}')
Результат додавання: 3

Однак далеко не завжди перетворення типів проходить без помилок, наприклад, ми не зможемо зробити таке перетворення:

a = 'my number is 42'
b = int(a) # отримаємо помилку
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[37], line 2
      1 a = 'my number is 42'
----> 2 b = int(a) # отримаємо помилку

ValueError: invalid literal for int() with base 10: 'my number is 42'

Це означає, що рядок 'my number is 42' не може бути відразу представлена як ціле число. Ми могли б взяти з цього рядка лише число 42 і перевести його до цілого числа. Скоро ми навчимося так робити.

Примітка

Якщо ви хочете дізнатися більше про цілі числа, то можете прочитати документацію.

1.4.1 Рядки та їх незмінюваність

Рядки належать до незмінних об’єктів у Python. Які практичні наслідки виникають з того факту, що рядки, на відміну від списків, є незмінними об’єктами?

Щоб показати, що рядки є незмінюваними об’єктами, ми можемо використати такий приклад коду:

my_string = "abcde"
my_string[0] = "f"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[38], line 2
      1 my_string = "abcde"
----> 2 my_string[0] = "f"

TypeError: 'str' object does not support item assignment

Коли ми запустимо цей код, ми отримаємо повідомлення про помилку TypeError, яке свідчить про те, що рядковий об’єкт не підтримує присвоєння елементу. Це відбувається тому, що в Python рядки - це незмінні об’єкти, їх не можна змінювати після створення. Якщо ми хочемо створити новий рядок на основі існуючого, то ми повинні створити новий об’єкт рядка. Наприклад, ми можемо створити новий рядок, який замінює перший символ рядка “a” на символ “f”, використовуючи такий код:

my_string = "abcde"
new_string = "f" + my_string[1:]
print(new_string)
fbcde

Це створить новий рядок через використання рядка "f" і всіх символів з оригінального рядка, починаючи з індексу 1. Результатом буде рядок "fbcde" - новий рядок, який ми можемо використовувати далі в нашій програмі.

Щоб остаточно закріпити відмінності в роботі зі змінюваними і незмінюваними об’єктами, давайте порівняємо списки і рядки:

my_str = "Hello, world!"
print(my_str.lower()) # поверне нам новий рядок
hello, world!
my_list = [3, 2, 1]
print(my_list.append(4)) # нічого не поверне, змінить my_list
print(my_list)
None
[3, 2, 1, 4]

Жоден метод не змінить змінну my_str, а ось різні методи списків можуть змінити структуру списку my_list.

1.5 Числа з плаваючою комою

Python також підтримує числа з плаваючою комою (англ. floating point numbers). Це числа, які мають дробову частину. Наприклад, 3.14 - число з плаваючою комою. Щоб використати число з плаваючою комою, ми можемо використати тип float. Зараз наш калькулятор дещо наївно припускає, що користувач буде вводити лише цілі числа. Давайте виправимо це:

# Запитати користувача про перше число
first_number = float(input('Введіть перше число: ')) # '1.2'

# Запитати користувача про друге число
second_number = float(input('Введіть друге число: ')) # '3.4'

# Вивести результат додавання
print(f'Результат додавання: {first_number} + {second_number} = {first_number + second_number}')
Результат додавання: 1.2 + 3.4 = 4.6
Примітка

Якщо ви хочете дізнатися більше про числа з плаваючою комою, то можете прочитати документацію.

Припустимо, що я не хочу, щоб остаточна відповідь була значенням з плаваючою комою, наприклад, 4.6. Я був би радий, якби ми просто округлили до найближчого цілого. Щоб це зробити, ми можемо використати функцію round(). Для початку давайте ознайомимося з документацією:

round(number, ndigits=None)

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

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

# Запитати користувача про перше число
first_number = float(input('Введіть перше число: ')) # '1.2'

# Запитати користувача про друге число
second_number = float(input('Введіть друге число: ')) # '3.4'

# Вивести результат додавання
print(f'Результат додавання: {first_number} + {second_number} = {round(first_number + second_number)}')
Результат додавання: 1.2 + 3.4 = 5

Давайте цього разу додамо 1 до 999:

# Запитати користувача про перше число
first_number = float(input('Введіть перше число: ')) # '1'

# Запитати користувача про друге число
second_number = float(input('Введіть друге число: ')) # '999'

# Вивести результат додавання
print(f'Результат додавання: {first_number} + {second_number} = {round(first_number + second_number)}')
Результат додавання: 1 + 999 = 1000

Відповідь, звісно, тут має бути і є 1000, незалежно від того, округляємо ми чи ні. Це просто арифметика з цілими числами. Але в США, як правило, форматують довгі числа, ставлячи коми після або перед кожною трійкою цифр. В інших країнах все навпаки, там замість цього ставлять крапки та коми. Це системні налаштування.

Що, якщо я хочу, щоб це було виведено як 1,000, просто щоб було трохи зрозуміліше, що це саме тисяча? Якщо ви хочете, щоб Python вивів число з комами, для цього є спеціальна нотація з використанням двокрапки. Давайте спробуємо це:

# Запитати користувача про перше число
first_number = float(input('Введіть перше число: ')) # '1'

# Запитати користувача про друге число
second_number = float(input('Введіть друге число: ')) # '999'

# Вивести результат додавання
print(f'Результат додавання: {first_number} + {second_number} = {first_number + second_number:,}')
Результат додавання: 1 + 999 = 1,000

Давайте модифікуємо наш калькулятор, щоб він виконував ділення:

# Запитати користувача про перше число
first_number = float(input('Введіть перше число: ')) # '2'

# Запитати користувача про друге число
second_number = float(input('Введіть друге число: ')) # '3'

# Вивести результат ділення
print(f'Результат ділення: {first_number} / {second_number} = {first_number / second_number}')
Результат ділення: 2 / 3 = 0.6666666666666666

Що, якщо я хочу, щоб результат ділення був округлений до 2 знаків після коми? Ми знову повертаємось до функції round(), але цього разу ми передаємо другий аргумент, який вказує, до якого знаку після коми ми хочемо округлити. Давайте спробуємо це:

# Запитати користувача про перше число
first_number = float(input('Введіть перше число: ')) # '2'

# Запитати користувача про друге число
second_number = float(input('Введіть друге число: ')) # '3'

# Вивести результат ділення
print(f'Результат ділення: {first_number} / {second_number} = {round(first_number / second_number, 2)}')
Результат ділення: 2 / 3 = 0.67

Але є інший спосіб зробити це, який може бути трохи зрозумілішим. Якщо ви хочете, щоб Python вивів число з комами, для цього є спеціальна нотація з використанням двокрапки. Для цього я додам запис 0.2f після двокрапки всередині f-рядку:

# Запитати користувача про перше число
first_number = float(input('Введіть перше число: ')) # '2'

# Запитати користувача про друге число
second_number = float(input('Введіть друге число: ')) # '3'

# Вивести результат ділення
print(f'Результат ділення: {first_number} / {second_number} = {first_number / second_number:.2f}')
Результат ділення: 2 / 3 = 0.67
Примітка

Іноді для розв’язання задачі нам потрібно створити змінну і зберегти в ній нескінченність у математичному сенсі слова. Для цього нам допоможе така форма запису:

x = float('inf')

Аналогічно до позитивної нескінченності float('inf'), float('-inf') є спеціальним значенням для чисел із плаваючою крапкою з негативною нескінченністю.

1.6 Власні функції

Ми вже знаємо, що Python має вбудовані функції, такі як print(), input(), round() та інші. Але Python також дозволяє нам створювати власні функції. До цього моменту ми вже декілька разів писали програми, які просто казали “привіт”. І кожного разу я використовую print(), але хіба не було б чудово, якби ми могли просто викликати функцію hello(), яка б просто віталася за нас? Давайте спробуємо це зробити:

name = input('Введіть ваше ім\'я: ') # 'Гаррі'
hello()
print(name)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[49], line 2
      1 name = 'Гаррі'
----> 2 hello()
      3 print(name)

NameError: name 'hello' is not defined

І от ми отримали помилку, що функція hello() не визначена. Це означає, що ми не можемо викликати функцію, яку ми не визначили. Давайте визначимо функцію hello(). Для цього ми використаємо ключове слово def від англійського define (визначити). Давайте спробуємо це зробити:

def hello():
    print('Привіт,')

name = input('Введіть ваше ім\'я: ') # 'Гаррі'
hello()
print(name)
Привіт,
Гаррі

Чому б нам не подумати про те, як ми могли б параметризувати ту ж саму функцію? Тобто, чи можемо ми налаштувати hello(), щоб воно приймало ім’я користувача як вхідні дані, щоб ми могли сказати не тільки привітання, але й ім’я людини в одному рядку. Для цього нам потрібно передати ім’я як аргумент у функцію hello(). Давайте спробуємо це зробити:

def hello(name):
    print('Привіт,', name)

name = input('Введіть ваше ім\'я: ') # 'Гаррі'
hello(name)
Привіт, Гаррі

Зверніть увагу на відступи в нашому коді. Вони дуже важливі. Вони показують, що функція hello() належить до блоку коду, який починається з def hello(name): і закінчується з print('Привіт,', name). Відступ дорівнює 4 пробілам або одного табулятора. Це дуже важливо, оскільки в Python відступи використовуються для визначення блоків коду. Якщо ви не використовуєте правильні відступи, то ви отримаєте помилку:

name = 'Гаррі'

def hello(name):
print('Привіт,', name)

hello(name)
  Cell In[52], line 4
    print('Привіт,', name)
    ^
IndentationError: expected an indented block after function definition on line 3

Черговість записів у коді також важлива. Якщо ви спробуєте викликати функцію hello() до того, як ви її визначите, то ви отримаєте помилку:

hello(name)

name = 'Гаррі'

def hello(name):
    print('Привіт,', name)
Привіт, Гаррі

Інтерпретатор Python сприйматиме вас буквально. І якщо ви використовуєте функцію, вона вже повинна існувати на момент її виклику.

Тепер давайте додамо значення за замовчування до функції hello(). Це означає, що якщо ми не передамо ім’я у функцію hello(), то вона використовуватиме значення за замовчуванням. Давайте спробуємо це зробити:

def hello(name='світ'):
    print('Привіт,', name)

hello()
Привіт, світ

Але ми можемо зануритися глибше і назвати свою функцію main(). Це не обов’язкова вимога, але це певна конвенція у світі програмування. Це означає, що це головна функція, яка виконується, коли ми запускаємо нашу програму. Давайте спробуємо це зробити:

def main():
    name = input('Введіть ваше ім\'я: ') # 'Гаррі'
    hello(name)

def hello(name):
    print('Привіт,', name)

main()
Привіт, Гаррі

Викликаючи головну функцію main() таким чином, це позбавляє мене від проблем з порядком записів у коді. Таким чином, я можу організувати свій код і впорядкувати його.

А тепер дозвольте мені зробити ще одну технічну помилку. Я спробую прибрати значення name у функції hello():

def main():
    name = 'Гаррі'
    hello()

def hello():
    print('Привіт,', name)

main()
Привіт, Гаррі

Але заковика в тому, що name тепер існує тільки в main(). Ця проблема називається областю видимості (англ. scope). Це означає, що змінні, які ви визначаєте всередині функції, не будуть доступні за межами цієї функції. Це означає, що name не існує всередині функції hello().

До цього наші функції не повертали нічого. Вони просто виводили щось на екран. Але що, якщо ми хочемо, щоб функція повертала значення? Для цього ми використовуємо ключове слово return. Давайте спробуємо це зробити на нашому калькуляторі. Напишемо функцію, яка буде повертати квадрат числа. Цю задачу можна вирішити різними шляхами, тож я пропоную паралельно познайомитися з новою функцією pow(), яка приймає два аргументи і повертає перший аргумент, піднесений до степеня, який вказаний другим аргументом. Давайте спробуємо це зробити:

Лістинг 1.1: calculator.py
def main():
    x = int(input('Введіть число: ')) # '2'
    print(f'Число {x} в квадраті дорівнює {square(x)}')

def square(n):
    return pow(n, 2)

main()
Число 2 в квадраті дорівнює 4

1.7 Інтерактивний режим

Виявляється, у Python не обов’язково писати код у файлі на кшталт hello.py, а потім запускати його у вікні терміналу. Однією з особливостей, яка багатьом подобається в Python, є те, що він підтримує так званий інтерактивний режим (англ. interactive mode). Щоб запустити Python у інтерактивному режимі, відкрийте термінал та напишіть python:

Terminal
> python
Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

Як бачите, з’явився новий символ >>>. Це означає, що Python готовий приймати команди. Наприклад, якщо я напишу print('Hello, world!') та натисну Enter, то Python виведе рядок 'Hello, world!':

Terminal
>>> print('Привіт, світ!')
Привіт, світ!

Також, якщо я напишу 2 + 2 та натисну Enter, то Python виведе результат додавання двох чисел:

Terminal
>>> 2 + 2
4

Щоб вийти з інтерактивного режиму, напишіть exit() та натисніть Enter:

Terminal
>>> exit()
>

1.8 Завдання

Завдання 1.1
Давайте запрограмуємо кота! Створіть три змінні:

  1. cat_name з рядком як мінімум із двох символів
  2. cat_age з невід’ємним числом
  3. is_fluffy з True абоFalse`
Рішення
cat_name = 'Azmodan'
cat_age = 2
is_fluffy = True

Завдання 1.2
Давайте напишемо програму для пошуку довжини гіпотенузи. Створіть змінні a та b, в яких будуть записані довжини катетів прямокутного трикутника. Після чого розрахуйте c і збережіть у ній довжину гіпотенузи цього трикутника.

Для розрахунку довжини гіпотенузи використовуйте теорему Піфагора. А операція квадратного кореня аналогічна зведенню в ступінь 0.5.

Рішення
c = (a**2 + b**2)**0.5

Завдання 1.3
У змінній father_age зберігається вік батька, а змінної son_age — вік сина. Порахуйте, через скільки років батько буде вдвічі старшим за сина. Результат збережіть змінну result.

Приклад:

father_age = 20
son_age = 3
result = 14

father_age = 30.5
son_age = 5.1
result = 20.3
Рішення
father_age = 20
son_age = 3
result = father_age - 2 * son_age

Завдання 1.4
Задані дійсні числа a, b та с – сторони трикутника. Обчисліть периметр та площу трикутника. Результат збережіть у змінні perimeter та area відповідно.

Приклад:

a = 3
b = 4
c = 5

perimeter = 12
area = 6

\[ S = \sqrt{p(p-a)(p-b)(p-c)} \] \[ p = \frac{a+b+c}{2} \]

Периметр – це сума довжин усіх сторін. Площу трикутника по трьох сторонах можна обчислити за допомогою формули Герона. Квадратний корінь - це зведення у ступінь 0.5.

А ви знали, що Формула Герона міститься в «Метриці» Герона Олександрійського (I століття н. е.) і названа на його честь (хоча вона була відома ще Архімеду). Герон цікавився трикутниками з цілими сторонами, площі яких теж є цілими, такі трикутники звуться героновими, найпростішим героновим трикутником є єгипетський трикутник.

Рішення
a = 3
b = 4
c = 5

perimeter = a + b + c
p = perimeter * 0.5
area = (p * (p-a) * (p - b) * (p - c)) ** 0.5

Завдання 1.5
У змінну n збережено ціле число – кількість секунд. Напишіть програму, яка конвертує задану кількість секунд n на години, хвилини та секунди. Результат збережіть у змінні hours, minutes, seconds.

Тобто спочатку потрібно порахувати, скільки в число n помістилося цілих годин, цілих хвилин і скільки після цього залишилося секунд. Розглянемо приклад:

n = 125

hours = 0
minutes = 2
seconds  = 5

Вам може допомогти цілочислове ділення // залишок від ділення %.

Рішення
n = 125
hours = n // 3600
minutes = (n % 3600) // 60
seconds = n % 60

Завдання 1.6
У змінній price_new зберігається ціна кілограма бананів у числовому форматі, а змінної price_old — ціна кілограма бананів рік тому. Обчисліть, скільки відсотків за модулем змінилася ціна протягом року. Результат збережіть у змінну result. Результат округліть до двох знаків після коми.

Приклад:

price_new = 89.99 
price_old = 75.50
result = 19.19


price_new = 24
price_old = 72
result = 66.67
Рішення
price_new = 89.99
price_old = 75.50
result = round(abs(price_new - price_old) / price_old * 100, 2)

Завдання 1.7
Створіть змінні:

  • a зі значенням 5 типу int
  • b зі значенням '10' типу str
  • c із значенням True типу bool.

У змінну my_sum збережіть суму трьох змінних, які ви створили, перетворивши b і з типу int.

Рішення
a = 5
b = '10'
c = True
my_sum = a + int(b) + int(c)

Завдання 1.8
У змінній a збережено число з десятковою частиною у форматі рядка, наприклад '3.14'. У змінну збережіть цілу частину з числа змінної a.

Приклади:

a = '3.14'
c = 3

a = '99.9'
c = 99

a = '0.33'
c = 0

Все, що нам потрібно зробити, це перекласти змінну a в int. Відразу рядок '3.14' в int перекласти не вийде, подумайте, який тип потрібно перевести змінну на першому етапі?

Рішення
a = '3.14'
c = int(float(a))

Завдання 1.9
У змінній x збережено ціле позитивне число. Обчисліть x + x0x0x. Результат збережіть змінну result.

Тобто якщо x = 2, то потрібно обчислити 2 + 20202.

Спробуйте скласти два рядки за допомогою знака +

Рішення
x = 2
result = x + int(str(x) + '0' + str(x) + '0' + str(x))

# або
result = x + int(f'{x}0{x}0{x}') # але про це пізніше

Завдання 1.10
Збережіть у змінний square рядок, який виводить на екран прямокутник 4 х 4, сформований із зірочок, розділених пробілом.

print(square)

* * * *
* * * *
* * * *
* * * *
Рішення
square = '* * * *\n' * 4

Завдання 1.11
У змінній x міститься число з десятковою частиною але у форматі рядка. У змінну y збережіть ціле число, яке дорівнює десятковій частині числа x.

Приклад:

```{python}
x = 3.14 
y = 14 

x = 2.02 
y = 2
```

Подумайте, які методи рядків допоможуть нам у цьому завданні.

Рішення
x = 3.14

y = int(str(x).split('.')[1])

Завдання 1.12
У змінну a збережено деяке речення, у якому можуть бути додані зайві пробіли. Напишіть програму, яка прибиратиме з a зайві пропуски і зберігатиме результат у змінну result. Усі слова мають бути розділені одним пропуском, а на початку та наприкінці речення пропусків бути не повинно.

Приклад:

```{python}
a = "Я вивчаю нову мову програмування.   "
result = "Я вивчаю нову мову програмування."
```
Рішення
a = "Я вивчаю нову мову програмування.   "

result = ' '.join(a.split())

Завдання 1.13
Напишіть програму, ґрунтуючись на введенні та виведенні в прикладах. Введенням буде рядок a. Результат збережіть у result.

Приклад:

```{python}
a = "div*2"
result = "<div></div><div></div>"

a = "p*1" 
result = "<p></p>"

a = "li*3"
result = "<li></li><li></li><li></li>"
```
Рішення
a = "div*2"

string, number = a.split('*')
result = f"<{string}></{string}>" * int(number)

Завдання 1.14
Напишіть програму, яка прийматиме рядок зі слів і повертатиме рядок, у якому ці слова будуть відсортовані в лексикографічному порядку. Початковий рядок міститься у змінній x, результат збережіть у result.

Приклад:

```{python}
x = 'Світ надзвичайно широкий має укладисті далі'
result = 'Світ далі має надзвичайно широкий укладисті'
```
Рішення
x = 'Світ надзвичайно широкий має укладисті далі'

result = ' '.join(sorted(x.split()))

Завдання 1.15
Порахуйте, скільки разів у реченні x зустрічається рядок y. Результат збережіть у змінну result.

Приклад:

```{python}
x = 'На підвіконні у вітальні в бабусі росли квіти, квіти були червоні та жовті, дуже гарні квіти.'
y = 'квіти'
result = 3
```
Рішення
x = 'На підвіконні у вітальні в бабусі росли квіти, квіти були червоні та жовті, дуже гарні квіти.'
y = 'квіти'

result = x.count(y)

Завдання 1.16
Напишіть програму, яка прийматиме номер кредитної картки card і повертатиме номер картки, у якому буде видно тільки останні 4 цифри. Інші цифри мають замінюватися зірочками. Результат збережіть у result.

Приклад:

```{python}
card = '5468350018455833'
result = '************5833'
```
Рішення
card = '5468350018455833'

result = '*' * 12 + card[-4:]

Завдання 1.17
У змінній а збережено речення. Видаліть із речення всі входження слова або символу b. Результат збережіть у result.

Приклад:

```{python}
a = 'Вечірнє сонце, дякую за день!'
b = 'e'
result = 'Вчірнє сонц, дякую за днь!'
```
Рішення
a = 'Вечірнє сонце, дякую за день!'
b = 'е'

result = a.replace(b, '')

Data Miorsh Ihor Miroshnychenko Youtube Monobank