02: умовні оператори

Зошит для семінару: Open In Colab

Умови

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

flowchart TD
  A[mark = 3] --> B{"mark менше 10?"}
  B -->|Так| D["print('Це нормально')"]
  D --> F{"mark менше 6?"}
  F -->|Так| G["print('Погано')"]
  F -->|Ні| H["'Нічого не робимо'"]
  B -->|Ні| C{"mark == 10"}
  C -->|Так| E["print('Відмінно')"]
  C -->|Ні| I["'Нічого не робимо'"]

Умови (if) дають змогу виконувати код тільки в разі істинності якогось логічного виразу.

Простіше кажучи, “якщо вірно, що…, то зробити …”.

Найпростіший приклад використання if - це виведення якоїсь фрази за умовою.

x = 1
if x == 1: # Вираз дорівнює True, ця умова істинна
    print('That is true!') # Фраза виводиться
if x != 1: # Вираз дорівнює False, ця умова хибна
    print('That is true!') # Фраза не виводиться

Зверніть увагу, що код, який знаходиться всередині умови, виділяється відступом у 4 пробіли або табуляцією (працює не у всіх IDE, але в Jupyter все буде добре).

Інакше програма не зрозуміє, що він відноситься до умови.

if x == 1:
print('That is true!')

А що робити, якщо в тому випадку, коли умова не істинна, ми теж хочемо здійснювати якусь дію? Для цього в нас є ключове слово else (“то”).

if x != 1:
    print('That is true!')
else:
    print('That is false!')

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

Для прикладу давайте розв’яжемо просту задачу - знайти мінімум із двох введених чисел. Поки що нічого нового:

a = input('Введіть перше число: ')
b = input('Введіть друге число: ')
if a < b:
    min_n = a
else:
    min_n = b
print('Мінімум дорівнює', min_n)

А тепер ускладнимо завдання, додавши третій варіант розвитку подій - якщо числа рівні, будемо друкувати ‘Рівні числа’.

Можна розв’язати цю задачу за допомогою вкладених умов:

a = input('Введіть перше число: ')
b = input('Введіть друге число: ')
if a < b: 
    print(a)
else:
    if a > b: # зверніть увагу, тут одна умова міститься всередині іншої, і код нижче писатиметься після подвійного відступу
        print(b)
    else:
        print('Рівні числа:', a)

Непогано, але можна спростити цей розв’язок за допомогою конструкції else if (або elif), яка дає змогу в разі хибності умови одразу ж написати ще одну перевірку.

Ось як виглядатиме розв’язання нашої задачі за допомогою elif:

a = input('Введите первое число: ')
b = input('Введите второе число: ')
if a < b: 
    print(a)
elif a > b: 
    print(b)
else:
    print('Равные числа:', a)

Завдання для тренування

Розпродаж

У магазині проходить акція:

  • На всі товари дешевше 1000 грн. знижка 15%
  • На всі товари дорожче 1000, але дешевше 5000 грн. знижка 20%
  • На всі товари дорожче 5000 грн. знижка 25%

Введення
Ціле невід’ємне число - ціна товару в рублях

Виведення
Ціле невід’ємне число - знижка на товар у рублях

# місце для рішення

Хитрощі множення

Для множення двозначного числа на 11 є цікава хитрість: результат добутку можна отримати, якщо між першою і другою цифрою вихідного числа вписати суму цих цифр. Наприклад, 15 * 11 = 1 1+5 5 = 165 або 34 * 11 = 3 3+4 4 = 374. Реалізуйте програму, яка множила б двозначні числа на 11, використовуючи цю хитрість. Користуватися оператором множення не можна.

Формат введення:
Вводиться двозначне число.
Формат виведення:
Програма повинна вивести відповідь на задачу.

Тест 1
Приклад введення:
15
Виведення:
165

Тест 2
Приклад введення:
66
Висновок:
726

# ваше рішення тут

Цикл while

Досить часто завдання вимагають від нас кілька разів виконати однотипний код.

Якщо писати кілька разів одні й ті самі рядки, це захаращує програму. Іноді кілька разів перетворюється на багато (100 або 10000). А іноді це число взагалі залежить від параметрів введення.

Впоратися з цим допомагають цикли. На цьому семінарі ми попрацюємо з циклом while (поки)

Принцип використання циклу while: записуємо логічний вираз і деякий код. Код виконуватиметься доти, доки логічний вираз правильний.

Наприклад, давайте надрукуємо всі цілі числа від 1 до 10.

i = 1 
while i <= 10:
    print(i) 
    i += 1 

Тут ми використовували запис i += 1. Він еквівалентний i = i + 1.
Аналогічно можна записувати й інші арифметичні операції: наприклад, -=

Зверніть увагу, що код усередині циклу (той, який ми хочемо повторно виконувати), виділяється відступом.

Оператори break і continue.

Циклами можна керувати за допомогою операторів break, continue.

Break усередині циклу дає змогу перервати його виконання й одразу ж перейти до коду, який іде після циклу (або завершити програму).

У цьому випадку ми можемо написати відразу після циклу секцію else (синтаксис при цьому такий самий, як і в умовах).
Код, написаний після else, буде виконуватися, якщо цикл завершився “природним шляхом” (тобто не був перерваний за допомогою break).

Задача

Розглянемо приклад задачі, яку можна розв’язати з використанням break.

Нехай студент склав 5 предметів під час сесії і ми хочемо дізнатися, чи є в нього перескладання

Формат введення
До п’яти оцінок від 1 до 10

Формат виведення
Якщо хоча б одна з оцінок менша за 4, завершуємо програму і друкуємо ‘YES’ (перескладання є)
Якщо всі п’ять оцінок більші за 3, друкуємо ‘NO’ (студент закрив сесію без пересдач)

i = 1
while i <= 5:
    mark = int(input("Введіть оцінку: "))
    if mark < 4:
        print('YES')
        break
    i += 1
else: # else перебуває на тому ж рівні відступу, що й while, тому відноситься саме до циклу, а не до умови всередині циклу
    print ('NO')

Оператор continue дає змогу одразу ж перейти на нову ітерацію циклу, не виконуючи код, який написаний усередині циклу нижче за нього.

Оператор continue дає змогу одразу ж перейти на нову ітерацію циклу, не виконуючи код, який написаний усередині циклу нижче за нього.

i = 1
retakes = 0
while i <= 5:
    mark = int(input("Введіть оцінку: "))
    i += 1
    if mark >= 4: # якщо перескладання немає, одразу ж ідемо перевіряти змінну i, без збільшення змінної retakes
        continue
    retakes += 1
print("Разом перескладань:", retakes)

Операторами break і continue не варто зловживати, це може погіршити читабельність коду.

Наприклад, у попередньому прикладі ми б упоралися і без continue:

i = 1
retakes = 0
while i <= 5:
    mark = int(input("Введіть оцінку: "))
    i += 1
    if mark < 4:
        retakes += 1
print("Разом перездач:", retakes)

Функція range

Давайте розв’яжемо задачу - на вхід подається число N, потрібно згенерувати список від 1 до N.

i = 1
myList = []
N = int(input())

while i <= N
    myList.append(i)
    i += 1
    
print(myList)

Непогано, але python пропонує нам готове рішення - вбудовану функцію range().

range(N) повертає діапазон чисел від 0 до N - 1.

myRange = range(10)
print(myRange[0], myRange[8], myRange[-1])

Є одне але - range повертає не список і не кортеж, це стає зрозуміло, якщо спробувати надрукувати результат.

print(myRange)
print(type(myRange))

Виручає старе добре перетворення типів.

print(list(myRange))
print(tuple(myRange))

Функція range поводиться дуже схоже на зрізи.
range(N, M) поверне діапазон від N до M - 1.
range(N, M, i) поверне діапазон від N до M - 1 з кроком i.

print(list(range(1, 5)))
print(list(range(1, 10, 2)))
print(list(range(-5, -1)))
print(list(range(-5, -10, -2)))

Цикл for

Ми вже вміємо писати цикли за допомогою оператора while, але тепер ми готові познайомитися зі ще одним способом.

Давайте згадаємо про наш список студентів і виведемо їхні імена по черзі. Для початку вже знайомим способом.

students = ['Гаррі Поттер', 'Рон Візлі', 'Герміона Ґрейнджер']

i = 0
while i < len(students):
    print(students[i])
    i += 1

А тепер напишемо те саме за допомогою циклу for.

Тепер ми будемо перебирати список students, дістаючи з нього по одному елементу.

students = ['Гаррі Поттер', 'Рон Візлі', 'Герміона Ґрейнджер']

for student in students:
    print(student)

У прикладі вище на кожному кроці цикл for дістає черговий елемент зі списку students і зберігає його у змінну student.

Зверніть увагу, що змінну student нам не треба створювати заздалегідь, вона створюється прямо під час роботи циклу.

Одержаний код набагато коротший і простіший за варіант із використанням while.

Цикл for може перебирати й елементи range, це дає нам ще один спосіб розв’язання задачі.

students = ['Гаррі Поттер', 'Рон Візлі', 'Герміона Ґрейнджер']

for i in range(len(students)): # тут не треба перетворювати range на список або кортеж
    print(students[i])

Цикл for може перебирати і кортежі, і навіть рядки.

myStr = 'Hello'

for char in myStr:
    print(char)