ЦИКЛ WHILE



Цикл for, также называемый циклом со счётчиком, выполняется определённое, заданное количество раз. Для того, чтобы воспользоваться циклом for, мы с вами должны обязательно знать это самое количество.

Представьте ситуацию, когда нам вдруг не известно количество повторений. Например, в программе с контролем скорости автомобилей мы можем не знать, сколько автомобилей должны проконтролировать. Но закончить работу с программой должны, например, введя число 1000. Эдакая кодовая команда. Ввёл 1000 - и цикл прекратился.

Ещё пример: представьте, вы совершаете покупки. На смартфоне установлена программа, которая считает расходы и сообщает, когда превышена планируемая к тратам сумма. Более детально: у вас на руках 1000 рублей. Сколько покупок вы сможете купить?

Глупый вопрос, не правда ли? Можно купить один товар за 1000, или десять по сто. Или накупить спичек, сколько их там будет неизвестно. То есть мы с вами никак не сможем определить, когда нужно сообщать пользователю, что сумма превышена и прекращать запрашивать данные.

Программа может выглядеть так. Если вы её запустите, то столкнётесь с абсурдным поведением:

# Сумма на руках money = 1000 # Для начала поставим максимально # 10 покупок for i in range(10): print() buy = int(input("Введите стоимость текущего товара: ")) # Вычитаем из общей суммы стоимость товара money = money - buy print("У вас осталось:", money, "денег.") if (money <= 0): print("Всё! Стоп! Деньги потрачены! ХОРОШ!")

Результат:

Введите стоимость текущего товара: 300 У вас осталось: 700 денег. Введите стоимость текущего товара: 400 У вас осталось: 300 денег. Введите стоимость текущего товара: 500 У вас осталось: -200 денег. Всё! Стоп! Деньги потрачены! ХОРОШ! Введите стоимость текущего товара: 600 У вас осталось: -800 денег. Всё! Стоп! Деньги потрачены! ХОРОШ! Введите стоимость текущего товара:

Что произошло? Мы потратили всю доступную сумму, но программа этого "не поняла" и продолжает спрашивать цену товара. Почему? Потому что вдруг мне в голову пришло указать в цикле 10 итераций (range(10)). Вернёмся к задаче позднее.

Пустая команда print(), стоящая в самом начале блока команд цикла, выводит на экран пустую строку. Для того, чтобы визуально разделить строки с вводом цены товара и остатком денег со следующим вводом.

Забота о пользователе - наша задача. Если уберёте указанный пустой print(), то получите на экране кашу из надписей, в которых трудно разобраться. Всё равно что книга без абзацев.

С помощью for решить проблему с вводом неопределённого множества значений нельзя, так как циклу нужно обязательно знать, сколько итераций произвести. В задаче с покупками методом математического расчёта мы никогда и никак не сможем узнать, какое количество покупок способен совершить человек с тысячью рублями в кармане...

Цикл for используем только тогда, когда точно знаем сколько раз нужно выполнить команды цикла для достижения поставленной цели.

Для решения этой задачи нужно использовать цикл while. Он ещё называется цикл с предусловием.


СТРАН­НЫЕ ВОПРОСЫ


Ответить на эти вопросы нельзя до тех пор, пока мы не совершим действие и не измерим затраченное (минуты, шаги, деньги). Но и в этом случае мы не можем быть уверены, что если повторится указанная в вопросе ситуация с другим человеком, то результат нашего измерения будет точным для него.

Попробуйте ответить конкретным числом:

Сравните с теми вопросами, на которые есть конкретные ответы:

Последний вопрос выдавил скупую слезу...

Но не время для эмоций! Проанализируйте вопросы: в первом случае у нас нет ничего конкретного, кроме совершаемого действия. И мы знаем, когда должны прекратить совершать это действие (отремонтировать двигатель, продуть деньги). Во втором случае все вопросы носят конкретный, выраженный в числах характер.

Как только увидите эту разницу - продолжайте заниматься дальше! Иначе - перечитайте заново.


НАЗНА­ЧЕНИЕ WHILE


Цикл while, ещё его называют "цикл, пока" или "цикл с предусловием", выполняет блок команд до тех пор, пока условие, указанное в заголовке цикла, истинно. Таким образом для использования while нам необходимо знать лишь условие, при котором цикл должен выполняться.

Предыдущая задача про покупки и оставшуюся сумму как раз для while. Мы будем совершать покупки, пока сумма денег больше нуля. То есть логическое выражение "сумма денег > 0" или, как в приведённом примере программы, (money > 0), мы будем выполнять цикл.

Цикл while (цикл, пока) используем в тех случаях, когда нам не известно количество повторений блока команд, но известно условие продолжения цикла.

Кстати, если выражаться в терминах цикла while, то условие продолжения для цикла for мы можем сформулировать также с помощью "пока":

# Для for i in range(10): Выполнять следующий блок команд, пока i < 10: Блок команд

Недостаток цикла while в том, что он не содержит автоматически создаваемой переменной - счётчика цикла с заданными range() значениями. Это не такая большая проблема, так как счётчик для while мы можем создать вручную.


СИНТАК­СИС WHILE


Цикл while записывается на языке Python следующим образом:

while (логическое выражение): Блок команд

Блок команд выполняется до тех пор, пока логическое выражение истинно.

Пример "вечного" цикла:

while (True): print("Разойдись, работает цикл while")

Когда надоест смотреть на надписи, нажмите Ctrl+C - принудительная остановка программы. Раскладка клавиатуры в момент нажатия должна быть на английском языке, иначе не прервётся. Если совсем ничего не получается - просто закройте Python Shell.

Программист всегда должен следить за тем, чтобы условие работы while в какой-то момент становилось ложью, иначе программа будет работать бесконечно.

While удобней читать по-русски как "пока", тогда условие будет более понятным. Например, предыдущую "вечную" программу я прочитал так:

Пока (Истина), выполнять: Выводить на экран("Разойдись, работает цикл while")

Возьмите себе это за полезную привычку - все конструкции языка мысленно перечитывать на русском языке, давая символизму программы понятные, родные названия.


ПОЛЕЗ­НАЯ ХИТ­РОСТЬ


Читайте программы, переводя значения операторов на русский язык. Сравните два кода:

a = 5 b = 10 while (b > a): a = a + 1 print(a)

И на русском языке:

Присвоить переменной a значение 5 Присвоить переменной b значение 10 Пока (значение переменной b больше значения переменной a), выполнять: a увеличиваем на единицу Вывести на экран значение переменной a

Что проще? Определите для себя. Не факт, что чтение "по-русски" поможет вам так же, как помогает мне.

Подумайте, каким будет результат работы программы?

Ответ

6 7 8 9 10



ПРОВЕ­РЯЕМ СКО­РОСТЬ АВТО­МОБИЛЯ


Итак, у нас есть программа, которая контролирует скорость автомобилей и при необходимости сообщает, что водитель нарушает скоростной режим. Доделаем её под новые условия.

Задача: в управлении ГИБДД решили ввести новую должность. Задача человека на этой должности - контролировать, ошибся ли инспектор при составлении протокола или нет. Наш контролёр берёт данные скорости автомобиля с административных протоколов и проверяет их в компьютерной программе. Компьютерная программа должна определить и сообщить, было ли нарушение или нет. Количество протоколов в день нам не известно, их может вообще не быть. Напишите такую программу, которая обрабатывает данные до тех пор, пока пользователь программы не введёт число 1000. Именно это число будет сигналом к завершению программы.

Текст программы:

speed = 0 while (speed != 1000): speed = int(input("Введите скорость автомобиля: ")) if (speed != 1000): if (speed > 60 and speed <= 200): print("Водитель нарушает! Штраф ему, штраф!") elif (speed > 200): print("Это не самолёт. Такой скорости не существует.") elif (speed == 0): print("Автомобиль стоит на месте.") elif (speed < 0): print("Отрицательной скорости не существует.") else: print("Водитель не нарушает.") print("Спасибо за использование нашей программы!")

Результат:

Введите скорость автомобиля: 40 Водитель не нарушает. Введите скорость автомобиля: 50 Водитель не нарушает. Введите скорость автомобиля: 65 Водитель нарушает! Штраф ему, штраф! Введите скорость автомобиля: 120 Водитель нарушает! Штраф ему, штраф! Введите скорость автомобиля: -10 Отрицательной скорости не существует. Введите скорость автомобиля: 200 Водитель нарушает! Штраф ему, штраф! Введите скорость автомобиля: 1000 Спасибо за использование нашей программы!

Переменная speed инициализируется в первой строке программы. Инициализация переменных обязательна. При использовании цикла while мы должны следить, чтобы условие в момент "входа в цикл" было истинным.

Например, если мы зададим переменной speed значение 1000 до входа в цикл, то while не сработает. Попробуйте:

speed = 1000



РАЗ­БОР ПРОГ­РАММЫ


speed = 0 while (speed != 1000):

Наиболее важная часть нашего алгоритма. Здесь мы задаём условие выполнения цикла. Звучит так:

Присвоить переменной speed значение 0 Пока (значение speed не равно 1000): будем выполнять блок команд цикла. По правилам Python блок команд записывается на расстоянии в 4 пробела от символа "w" в "while"

Следующая часть практически ничем не отличается от предыдущих версий, за исключением того, что к каждой строке добавлены четыре пробела для того, чтобы блок выполнялся в цикле while:

speed = int(input("Введите скорость автомобиля: ")) if (speed != 1000): if (speed > 60 and speed <= 200): print("Водитель нарушает! Штраф ему, штраф!") elif (speed > 200): print("Это не самолёт. Такой скорости не существует.") elif (speed == 0): print("Автомобиль стоит на месте.") elif (speed < 0): print("Отрицательной скорости не существует.") else: print("Водитель не нарушает.")

Весь код условий помещён в "над-if":

if (speed != 1000):

Зачем же?

Если убрать этот блок и ввести 1000, то программа прекратится. Но до прекращения Python выведет строку "Это не самолёт. Такой скорости не существует", потому что значение 1000 будет обрабатываться не как сигнал остановки программы, а как обычное значение скорости. Нужно избежать этого, поэтому ставим if: код будет обрабатываться при любых значениях переменной speed, не равных 1000.

Последняя строка:

print("Спасибо за использование нашей программы!")

Выполняется после окончательного завершения цикла. Команда записана с начала строки, поэтому не принадлежит блоку команд while.

Следующая глава - обобщение изученного. Освежим память.


© 2019-2021 Виктор Трофимов
[ Оглавление ] [ В начало страницы ]