Розгалуження

З матеріалу цього уроку ви дізнаєтесь, як "примусити" програму робити вибір своїх подальших дій

Чи доводилося вам коли-небудь приймати рішення під впливом обставин? Звісно, що так! Ми постійно це робимо! "Сходи в магазин, купи пачку масла, а якщо залишаться гроші, то ще й булочок до чаю!" Було колись щось подібне? Було! І такі ситуації трапляються з нами мало не щодня! Якщо їде машина, то потрібно зупинитися біля краю дороги і її пропустити. Якщо йде дощ, то візьми парасольку. Якщо обидва множника від'ємні, то добуток буде з "плюсом"... І так далі... Ми вирішуємо, що робити, в залежності від того, виконуються чи не виконуються певні умови. Наприклад, якщо умова "йде дощ" виконується (дійсно, йде дощ), то ми беремо парасольку, якщо умова "йде дощ" не виконується (немає дощу), то ми парасольку залишаємо вдома, бо вона нам не потрібна.

В усіх цих випадках нами "керує" конструкція якщо <умова> то <дія>, яку й називають розгалуженням. Зрозуміло, що виконання чи невиконання умови може залежати або від зовнішніх чинників (йде дощ, чи не йде), або від наших внутрішніх спонукань (хочу натиснути цю кнопку чи іншу).

Кожне таке розгалуження - це як стояти на роздоріжжі й, аналізуючи зовнішні чинники й свої внутрішні спонукання, вирішувати, що робити далі: "Ліворуч підеш - багатство здобудеш, праворуч підеш - коня втратиш, прямо підеш - об камінь довбонешся!" :)

Образ богатиря на роздоріжжі зустрічається в багатьох українських казках

ОДНАК...

Проводячи аналогію між комп'ютерними програмами й ситуаціями з реального життя, слід пам'ятати, що в реальному житті не завжди є місце справжньому вибору. Інколи буває і так, що будь-який варіант вибору приводить до одного й того самого результату. Наприклад, яку б школу для навчання ви не обрали, але у будь-якій школі доведеться вчити таблицю множення. Що називається, "без варіантів"...

До речі, такі випадки безальтернативного вибору часто стають ідеями для жартів і фотожаб:

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

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

В будь-якому разі розгалуження в мові програмування Python має такий вигляд:

if <умова>:

    <дія "плюс">

else:

    <дія "мінус">


якщо <умова, виконання чи невиконання якої перевіряється> тоді <дія "плюс" - команда чи набір команд, які повинні бути виконані якщо умова виконується> інакше <дія "мінус" - команда чи набір команд, які повинні бути виконані, якщо умова НЕ виконується>

Зверніть увагу на ОБОВ'ЯЗКОВІ двокрапки й ОБОВ'ЯЗКОВІ відступи зліва перед записом команд.

Окрім повної форми розгалуження if <умова>: <дія "+"> else: <дія "-"> використовується також і неповна: if <умова>: <дія "+">. У цьому випадку так само перевіряється виконання умови (після if). Якщо вона виконується, тоді виконується усе те, що слідує після двокрапки. Якщо ж умова не виконується, то програма шукає else, а оскільки ми його не написали, то вона його і не знаходить! Що робити, якщо умова не виконується? А невідомо! Нічого не написано! От програма нічого й не робить і переходить на наступний рядок, щоб виконати команду, яка розміщена наступною.

Схема повної форми розгалуження
Схема неповної форми розгалуження

ЗАВДАННЯ 8

Дано три кута. Перевірити, чи існує трикутник з такими кутами

Математичною моделлю цієї задачі буде відома вам з курсу геометрії теорема про суму кутів трикутника. Будемо додавати введені з клавіатури величини і порівнювати їх суму зі 180°. Якщо утворена сума дорівнює 180, то будемо виводити повідомлення, що такий трикутник існує, а в протилежному випадку - що не існує.

Ось який вигляд матиме код цієї програми:

1. a = int(input('Введіть значення першого кута: '))

2. b = int(input('Введіть значення другого кута: '))

3. c = int(input('Введіть значення третього кута: '))

4. s = a + b + c

5. if s == 180:

6.     print('Трикутник існує')

7. else:

8.     print('Трикутник не існує')

Пояснення:

Рядки 1-3: Не будемо морочити собі голову з дробовими числами, беремо усі кути цілі, тому конвертуємо уведені дані в тип даних - integer, тому перед input() ставимо функцію int().

Рядок 5: Програма перевіряє, чи обчислена сума дорівнює 180. Якщо ця умова ВИКОНУЄТЬСЯ, то спрацьовує команда, розміщена після двокрапки - виводиться повідомлення про те, що такий трикутник існує, а написане після else ігнорується. Якщо ця умова НЕ ВИКОНУЄТЬСЯ, то пропускається написане після двокрапки й виконується команда, розміщена після else - виводиться повідомлення, що такого трикутника не існує.

ЩЕ РАЗ: Зверніть увагу на те, що команди після двокрапок в обох випадках пишуться З ВІДСТУПОМ!

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

Так, можна. Оптимізуємо наш код. У рядках 1-3 команди абсолютно ідентичні і їх легко можна об'єднати в одну за допомогою такої конструкції:

a,b,c = map(int, input('Введіть кути через пробіл: ').split(' '))

Функція map() дозволяє застосувати одну й ту саму іншу функцію (в цьому випадку це функція int() конвертації уведених величин в цілочисловий формат) до кожного елемента зі списку. input().split() означає прочитування рядків з їх наступним "розрізанням" по символу, зазначеному в дужках методу .split().

Отже, цей запис означає:

Зрозуміло, що, коли записати .split(';'), тоді символом, який допомагатиме програмі розібратися, де перше число, де друге, а де третє, стане крапка з комою і т.д. і т.п.

Ще один рядок, на якому можна "зекономити" - це рядок 4. Для чого суму кутів обчислювати окремо, якщо це можна зробити в самій умові розгалуження?

Отже, з урахуванням проведеної "оптимізації" наш код тепер матиме значно коротший вигляд і поміститься лише в 5 рядків:

a,b,c = map(int,input('Введіть кути трикутника через пробіл: ').split(' '))

if a + b + c == 180:

    print('Трикутник існує')

else:

    print('Трикутник не існує')

Для тих, хто хоче знати більше

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

print('Трикутник існує' if a + b + c == 180 else 'Трикутник не існує')

Таким чином у нас буде виведено один з двох варіантів відповіді в залежності від значення умови після if. Завдяки такій конструкції наша програма узагалі вміститься лише в два рядки:

a,b,c = map(int,input('Введіть кути трикутника через пробіл: ').split(' '))

print('Трикутник існує' if a + b + c == 180 else 'Трикутник не існує')

Слід пам'ятати, що дана конструкція <Варіант1> if <Умова> else <Варіант2> завжди вимагає повної форми розгалуження, тому в разі відсутності Варіанту2 після else ставлять команду-заглушку pass:

x = 5

result = 1 if x>0 else pass

print(result)

>>>1

У цьому прикладі, якщо число додатне - буде надрукована одиниця, якщо ні - не надруковано нічого.

ЗАВДАННЯ 9

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

На перший погляд, ця задача аналогічна до попередньої. Однак, не все тут так просто. На відміну від попередньої задачі, тут випадків не два ("дорівнює 180", "не дорівнює 180"), а ТРИ:

Тому, якщо умова a>b не виконується, то у нас залишається не одна, а ще дві і з них теж треба вибирати якийсь варіант. Схематично наш вибір матиме такий вигляд:

Якщо умова a>b не виконується, тоді після else повинно з'явитися нове розгалуження з перевіркою чи a<b. І от аж тоді, якщо a не більше b і a не менше b, залишається тільки один випадок: a=b. В результаті матимемо досить складну конструкцію розгалуження в розгалуженні:

a,b = map(float, input('Введіть два числа через крапку з комою: ').split(';'))

if a > b:

    print('Перше число більше')

elif a < b:    #elif - скорочення від "else if"

    print('Друге число більше')

else:

    print('Числа рівні')

Щоб не заплутуватись, простіше керуватися таким принципом:

Такий вигляд матиме наша програма, написана з неповною формою розгалуження:

a,b = map(float, input('Введіть два числа через крапку з комою: ').split(';'))

if a > b:

    print('Перше число більше')

if a < b:

    print('Друге число більше')

if a == b:

    print('Числа рівні')

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

ЗАВДАННЯ 10

Скласти програму для перевірки, введене число додатне, від'ємне, чи дорівнює нулю

А от тепер уже самотужки :)

Варіантів тут три, тому використовуємо неповну форму розгалуження:

1. a = float(input('Введіть число: '))

2. if a > 0:

3.     print('Число додатне')

4. if a < 0:

5.     print("Число від'ємне")

6. if a == 0:

7.     print('Число дорівнює нулю')

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

ЗАВДАННЯ 11

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

Можливість обчислення значення цього виразу залежить від того, яке значення матиме змінна х, чи не перетворює вона знаменник на 0. От вам і приклад застосування розгалуження як обробника помилок. Якщо x-3=0, тоді потрібно вивести повідомлення, що виникає загроза ділення на 0, в протилежному разі - обчислюємо значення даного виразу і виводимо результат.

1. x = float(input('Введіть число: '))

2. if x-3 == 0:

3.     print('Ділення на нуль неможливе!')

4. else:

5.     y = (4*x**2)/(x-3)

6.     print(y)

Зверніть увагу на те, що після else ОБИДВІ команди (рядки 5 і 6) написані з відступом, адже якщо умова x-3==0 не виконується, то у цьому випадку потрібно виконати їх ОБИДВІ. Якщо з відступом написати тільки першу, то в разі невиконання умови буде виконана тільки вона і може вийти ось таке:

Умова розгалуження не виконується, тому програма виводить повідомлення про неможливість ділення на нуль і в else не "заходить". Але ж після else стоїть обов'язкова до виконання (бо без відступу!) команда print(y)! А що таке у? Виникає помилка!

ПІДСУМКИ

З матеріалів цього уроку вам стало відомо:

ДОМАШНЄ ЗАВДАННЯ

З клавіатури вводиться число. Якщо воно додатне - додати до нього 2 і вивести отриманий результат, якщо від'ємне - відняти від нього 3 і теж вивести результат, якщо воно дорівнює нулю - вивести повідомлення про це.

Підказка

Щоб збільшити число на 2 можна зробити так: додаємо до цього числа 2 і записуємо результат у те ж місце, яке було відведене під початкове число. Наприклад, записати таку команду: a = a+2 або a += 2

Другий спосіб - додавати число 2 в тому ж місці, де воно виводитиметься:

print(a+2)