Цикли з лічильником
У цьому уроці ми навчимося реалізовувати повторення, для яких зарані відома їх кількість
В нашому реальному житті нам часто доводиться не тільки приймати рішення, що робити, в залежності від обставин, а й, інколи, виконувати одну й ту саму дію декілька разів. (Ну як у цьому контексті знову не згадати про нашу славну Чорнобаївку з її рахунком уже 18:0 на користь доблесних українських Збройних Сил! 🤣) Прикладів таких повторюваних дій можна наводити величезну кількість: щоранку, коли ми снідаємо, ми робимо один і той самий рух ложкою, коли йдемо до школи, повторюємо одні й ті самі рухи ногами, а в школі теж маємо повтори: дзвоник → урок → дзвоник → перерва → дзвоник → урок → ... і так далі...
Ви вже знаєте, що такі повторювані процеси називаються циклічними, а сукупності цих взаємопов'язаних процесів, що утворює закінчене коло дій - циклами. Під закінченим колом дій розуміють такий їх перелік, після якого весь цей перелік знову повторюється спочатку.
Так, в останньому прикладі закінченим колом дій є перелік:
дзвоник
урок
дзвоник
перерва
Після перерви знову лунає дзвінок і знову починається урок, а потім знову дзвінок і знову перерва і так по колу. Після кроку 4 усе знову повертається до виконання кроку 1 і т.д.
В програмуванні будь-який цикл складається з двох частин:
Умова циклу (критерій, який визначає виконувати цикл чи не виконувати)
Тіло циклу (список команд, які утворюють закінчене коло дій)
Розберемося з найочевиднішим і найпростішим типом циклів - цикл з лічильником.
Такі цикли використовуються тоді, коли зарані ВІДОМА КІЛЬКІСТЬ ПОВТОРІВ.
Якщо у вас сьогодні шість уроків, тоді тіло циклу
дзвоник
урок
дзвоник
перерва
повториться шість разів.
Блок-схема циклу з лічильником має такий вигляд:
Пригадаймо, що в середовищі Scratch цикл з лічильником оформлювався спеціальним блоком "Повторити..."
...а скрипт малювання квадрата мав такий вигляд:
Розгляньте уважно цей скрипт, розберіться, де в ньому який компонент і прослідкуйте виконання кожної команди, клікнувши на зеленому прапорці у вбудованому Scratch-проекті.
Аналогічно до Scratch, у Python теж можна створити цикл, який буде виконуватися певну кількість разів.
В цілому, структура циклу з лічильником в Python має такий вигляд:
for i in range(...):
<тіло циклу>
Умова циклу
Перший рядок for i in range(...) (range - з англ. "діапазон") задає, скільки разів буде виконано повторювані дії. Тут у дужках має бути розміщене число, яке й буде показувати, скільки разів потрібно повторити тіло циклу. Змінна i виступає лічильником кількості повторів ("тіло циклу виконується перший раз, тіло циклу виконується другий раз, тіло циклу виконується третій раз..."). Так, наприклад, якщо в умові циклу ми запишемо for i in range(5), то це означає, що тіло циклу виконуватиметься 5 разів.
УВАГА! Ось у цьому місці потрібно бути дуже уважним. Особливо, якщо змінна i буде використовуватися не тільки як лічильник, а й "братиме участь" у якихось обчисленнях в тілі циклу чи кількість повторів буде обчислюватися за якоюсь формулою. Річ у тім, що коли ми "запускаємо" цикл і в дужках ставимо число 5, то це означає, що змінна i по черзі набуватиме значень не від 1 до 5, а від 0 до 4, тобто: 0,1,2,3,4 - усього 5 різних значень! Тобто, насправді, програма виконує повтор №0, потім повтор №1, повтор №2 і т.д. Число в дужках вказує на таке значення лічильника, при якому тіло циклу уже НЕ виконується! Коли значення лічильника доходить до "межі" - числа, зазначеного в дужках, тоді відбувається т.зв. "вихід з циклу". Програма перестрибує на виконання команд, розміщених після нього.
Лічильник не обов'язково потрібно позначати саме буквою i, але в усіх випадках ця змінна обов'язково повинна бути цілим числом (адже номер по порядку не може бути дробовим, не буває, наприклад, три з половиною рази, правда ж!)
Отже, яким буде значення лічильника i циклу, заданого умовою for i in range(10) після виходу з циклу?
Оскільки лічильник послідовно набуває значень від 0 до n-1, то в даному випадку після завершення повторів і виходу з циклу, змінна i буде дорівнювати 9.
Можете виконати перевірку цього факту, запустивши на виконання такий простий код:
for i in range(10):
print(i)
print(i)
for i in range(...) є скороченою формою запису умови циклу з лічильником. Окрім неї існує ще й повна форма і вона має такий вигляд: for i in range(<start>, <stop>, <step>):
<start> - на першому місці повної форми ставиться початкове значення лічильника (висновок: не обов'язково починати відлік з нуля, більше того, початок відліку може бути позначений навіть від'ємним, хоча й обов'язково ЦІЛИМ, числом!)
<stop> - значення лічильника, при якому виконання циклу вже НЕ відбувається
<step> - крок лічильника. При використанні неповної форми умови циклу цей крок завжди дорівнює 1. У повній же формі умови циклу з лічильником цей крок може бути будь-яким (і навіть від'ємним) але обов'язково цілим числом. Якщо у вашому циклі крок лічильника буде дорівнювати 1, то його можна зовсім не зазначати: for i in range(1,10): лічильник циклу послідовно набуватиме значень 1,2,3,...,9.
Якщо крок лічильника додатний, тоді лічильник послідовно набуватиме значень від меншого до більшого за зростанням і виконання циклу припиниться, коли значення лічильника буде рівним або більшим за число зупинки <stop>.
Якщо крок лічильника від'ємний, тоді лічильник послідовно набуватиме значень від більшого до меншого за спаданням і виконання циклу припиниться, коли значення лічильника буде рівним або меншим за число зупинки.
Якщо <stop> менший ніж <start>, а <step> додатний або навпаки <stop> більший ніж <start>, а <step> від'ємний, тоді отримаємо "вічний" цикл, який не завершиться ніколи.
Скільки разів будуть виконані цикли, описані умовами:
for i in range(8)
for i in range(3, 9, 2)
for i in range(-2, 9, 2)
for i in range(-1, -10, -3)
for i in range(5, -5, 2)
Відповідь:
8 разів
3 рази (i=3, i=3+2=5, i=5+2=7, при i=7+2=9 - вихід з циклу)
6 разів (i=-2, i=-2+2=0, i=0+2=2, i=2+2=4, i=4+2=6, i=6+2=8, при і=8+2=10>9 - вихід з циклу)
2 рази (і=-1-3=-4, і=-4-3=-7, при і=-7-3=-10 - вихід з циклу)
безліч разів (і=5+2=7, і=7+2=9, і=9+2=11... - цикл ніколи не завершиться, бо значення лічильника змінюються в протилежному від значення <stop> напрямку)
Між іншим: значення лічильника циклу, заданого у повній формі можуть бути виражені й від'ємними (але обов'язково цілими) числами. Так, наприклад, цикл for i in range(-10,0) так само буде виконаний 10 разів, як і цикл for i in range(10).
Тіло циклу
Тут усе просто й складно водночас. Просто, тому що оформлення тіла циклу не потребує якихось особливих позначень і прийомів. Команди тіла циклу перелічуються після двокрапки, якою завершується умова циклу, кожна з цих команд пишеться з відступом.
Складність же полягає у тому, щоб визначити, а ЩО САМЕ слід записати у тіло циклу. Щоб не помилитися при складанні тіла циклу, слід просто розібратися в тому, ЯКІ САМЕ команди утворюють закінчене коло дій, ЯКІ САМЕ дії будуть повторюватися і ПІСЛЯ ЯКОЇ команди усе треба починати спочатку.
Завдання 28
Скласти програму для виведення стількох зірочок, скільки їх "попросить" користувач, увівши з клавіатури їх кількість
Суть програми така: користувач вводить якесь ціле число, а програма виводить стільки зірочок, скільки показує це число, тобто, якщо, наприклад, користувач написав число 10, то програма виводить послідовність з десяти зірочок: **********.
Для розв'язування задачі треба знайти відповідь на два питання:
Скільки разів буде повторюватися дія? (Відповідь: стільки разів, скільки написав користувач)
Яка дія (чи послідовність дій) буде повторюватися? (Відповідь: малювання зірочки)
Отже, якщо кількість повторів позначимо змінною n, то маємо, що цикл виконуватиметься n разів (for i in range(n+1):, а в тілі циклу - лише одна дія: print('*').
В принципі, уже працює, щоправда, зірочки виводяться не в рядок, а в стовпчик. Причина в тому, що за промовчанням функція print виводить усе, що їй наказано надрукувати, з нового рядка. Щоб наступний символ друкувався в тому ж рядку, що й попередній, треба просто її уточнити:
Функція print може містити ще й деякі аргументи, за допомогою яких можна організувати виведення. Аргумент end за промовчанням має значення '\n', що означає завершувати кожне виведення переведенням курсора на новий рядок, а ми змінили це значення на '' (порожній рядок). Тепер після виведення попередньої зірочки виведення завершується друкуванням порожнього рядка (а, насправді, не друкуванням нічого!).
Якщо ви скористаєтесь таблицею ASCII і вставите між лапками якийсь інший символ (див. рядок 3), то зможете малювати і його також:
Тепер спробуйте виконати наступну задачу самостійно.
Завдання 29
Скласти програму, яка виведе в рядок 10 разів слово "Привіт!"
Відповідь:
for i in range(10):
print('Привіт!', end=' ')
На відміну від попередньої задачі кількість повторень ми вже не запитуємо, тому що ця кількість задана в умові, а, значить, і змінна n, і запитання про "А скільки?.." нам не потрібні, тому з тексту програми їх прибрано. Ну у слова "Привіт!" повинні бути написані не встик одне до одного, тому в end ставимо не порожній рядок '', а пробіл ' '.
ПІДСУМКИ
Отже, про цикл з лічильником слід запам'ятати:
Цикл з лічильником, як і будь-який інший цикл складається з умови й тіла циклу.
Цикл з лічильником використовується тоді, коли зарані відома кількість повторень.
Умовою циклу з лічильником є кількість повторів цього циклу.
Цикл з лічильником оформлюється у вигляді for i in range(<stop>): <тіло циклу> або for i in range(<start>,<stop>,<step>): <тіло циклу> де i - лічильник кількості повторень команд тіла циклу.
У скороченій формі умови циклу команди тіла циклу повторюються стільки разів, скільки зазначено у дужках, у повній формі умови циклу - усе залежить від того, з якого номера почилається відлік і на який крок переходить до наступного.
Тіло циклу може складатися з однієї команди, а може з декількох. У будь-якому випадку усі уоманди тіла циклу пишуть після двокрапки з відступом.
ДОМАШНЄ ЗАВДАННЯ
Програма "просить" користувача ввести своє улюблене слово й ціле число - кількість повторень цього слова, після чого виводить це слово потрібну кількість разів у рядок через пробіл.
Підказки:
Дана задача є комбінацією завдань 28 і 29 та прийому, використаного в завданні 18. Щоб запам'ятати слово, потрібно, зрозуміло, задати саме таку змінну, яка може помістити це слово. Оскільки це слово - текстова величина, то при її зчитуванні з клавіатури ані int(), ані float() не потрібні. Для того ж, щоб запам'ятати кількість повторів - отут уже потрібно конвертувати (в int чи float - здогадаєтеся самостійно?). Ну, а якщо виводити треба саме це слово, яке "ховається" під змінною word, то в тіло циклу треба записати це так само, як при виведенні числової змінної: print(word, end=...). Усе інше - як в завданнях на виведення зірочок і слова "Привіт!". Скомбінуйте ці два завдання й у вас усе вийде! Успіху!