Занятие № 3. Решение задач с использованием цикла с предусловием

Цель: изучить применение цикла с предусловием while; рассмотреть типовые задачи.

Теория

Цикл с предусловием

Для многократного повторения инструкций используются циклы. Тело цикла с предусловием выполняется до тех пор, пока условие цикла истинно.

В Python цикл с предусловием реализуется инструкцией while:

while <логическое выражение>:
    <инструкция 1>
    <инструкция 2>
    ...
    <инструкция N>
graph TD
    A([Начало]) --> B(( ))
    B --> C{Лог.<br> выражение<br>истино?}
    C -->|Да| E[Инструкции в<br>теле цикла]
    E --> B
    C -->|Нет| H([Конец])
Рисунок 1

Цикл выполняется так:

  1. Вычисление значения логического выражения. Результат True или False.
  2. Если значение False - завершить инструкцию while и перейти к следующей по-порядку инструкции.
  3. Если значение True - выполнить все инструкции в теле цикла и перейти к шагу 1.

Рисунок 1 содержит диаграмму с ходом работы цикла while.

Если на первом шаге цикла значение логического выражения равно False, то цикл x не выполнится ни разу.

В этом примере найдём сумму вводимых чисел. Цикл будет работать до тех пор, пока пользователь вводит числа не равные 0.

theSum = 0 # переменная-аккумулятор
x = -1 # очередное слагаемое
while x != 0:
    x = int(input("Следующее число (0 для остановки): "))
    theSum = theSum + x

print(theSum) # вывод ответа

      
theSum = 0 # переменная-аккумулятор
x = -1 # очередное слагаемое
while x != 0:
    x = int(input("Следующее число (0 для остановки): "))
    theSum = theSum + x

print(theSum) # вывод ответа

Условие цикла находится в x ? строке программы.

Ещё один пример использования цикла while - валидация вводимых значений. В следующем коде, ввод возраста (переменная age) будет продолжаться до тех пор, пока не введут число x больше нуля:

age = int(input("Введите ваш возраст: "))
while age <= 0:
    print("Возраст должен быть больше 0")
    age = int(input("Введите ваш возраст: "))

print(age)

      
age = int(input("Введите ваш возраст: "))
while age <= 0:
    print("Возраст должен быть больше 0")
    age = int(input("Введите ваш возраст: "))

print(age)
Бесконечный цикл

Если логическое выражение цикла всегда имеет значениеTrue, то такой цикл while может работать бесконечно.

В следующей программе цикл while будет выполняться бесконечно. Как лучше всего объяснить причину зацикливания?

n = 10
answer = 1
while n > 0:
  answer = answer + n
  n = n + 1
print(answer)

Выполнение тела цикла зависит только от значения переменной n. Пока она имеет положительное значение, цикл будет выполняться.

Значение переменной answer не используется в условии цикла, а значит не влияет на его остановку.

В логическом выражении можно использовать литералы (буквальные значения).

Условие цикла n > 0 должно принять значение False, чтобы он остановился.

Инструкция break

С помощью инструкции break можно прервать выполнение цикла и перейти к инструкциям расположенным после него.

while True:
    print("Эта строка появится на экране")
    break
    print("А эта строка?")

print("Цикл while завершил работу")

      
while True:
    print("Эта строка появится на экране")
    break
    print("А эта строка?")

print("Цикл while завершил работу")
Рисунок 2: Работа инструкции break

Инструкция, записанная в x строке не выполнится, так как инструкция break в третьей строке прервёт выполнение цикла.

Инструкция continue

Инструкция continue прерывает выполнение текущей итерации цикла. Интерпретатор вернётся к проверке условия цикла.

В следующем примере на экран выведутся только чётные числа от 1 до 9. Каждый раз, когда значение переменной x делится на 2 без остатка, будем пропускать итерацию цикла с помощью continue:

x = 0
while x < 10:
    x = x + 1
    if x % 2 == 0:
        continue
    print(x)
    
print("Конец программы")

      
x = 0
while x < 10:
    x = x + 1
    if x % 2 == 0:
        continue
    print(x)
    
print("Конец программы")
Рисунок 3: Работа инструкции continue

Объединим break и continue в одной программе.

while True:
    name = input("Имя пользователя: ")
    if name != 'admin':
        continue
    password = input('Привет, admin. Введите пароль:')
    if password == 'swordfish':
        break

print("Доступ разрешён!")

      
while True:
    name = input("Имя пользователя: ")
    if name != 'admin':
        continue
    password = input('Привет, admin. Введите пароль:')
    if password == 'swordfish':
        break

print("Доступ разрешён!")

Цикл while будет выполняться бесконечно, так как условие цикла всегда равно True. В теле цикла просим ввести имя пользователя - переменная name. Если имя не равно строке “ x admin”, то пропускаем итерацию цикла с помощью continue и возвращаемся к началу тела цикла. Когда введено правильное имя, просим ввести пароль - переменная password. Когда будет введен пароль “ x swordfish” будет выполнена инструкция break и цикл while прервётся.

Примеры

Пример № 1 (ex01.py)

Напишите программу рассчитывающую среднее арифметическое группы оценок. Количество оценок не известно заранее. Оценка не может быть отрицательным числом.

print("Среднее арифметическое")

#сумма чисел изначально равна 0
sum = 0
#переменная count будет хранить количество оценок
count = 0

#вводим первую оценку
x = int(input("Введите оценку> "))

#цикл while будет выполняться пока введённая оценка
#будет положительным числом
while x >= 0:
    #прибавляем введённую оценку к общей сумме
    sum = sum + x
    #увеличиваем счётчик оценок на 1
    count = count + 1
    #запрашиваем ввод следующей оценки
    x = int(input("Введите оценку> "))

#выводим среднюю оценку
print("Средняя оценка: ", sum / count)

      
print("Среднее арифметическое")

#сумма чисел изначально равна 0
sum = 0
#переменная count будет хранить количество оценок
count = 0

#вводим первую оценку
x = int(input("Введите оценку> "))

#цикл while будет выполняться пока введённая оценка
#будет положительным числом
while x >= 0:
    #прибавляем введённую оценку к общей сумме
    sum = sum + x
    #увеличиваем счётчик оценок на 1
    count = count + 1
    #запрашиваем ввод следующей оценки
    x = int(input("Введите оценку> "))

#выводим среднюю оценку
print("Средняя оценка: ", sum / count)

Пример № 2 (ex02.py)

Напишите игру «Угадай число». Компьютер загадывает число от 1 до 10 и предлагает его отгадать. Компьютер сообщает пользователю больше или меньше число введённое пользователем относительно загаданного числа. Для получения случайного числа используется модуль random.

#импортируем модуль для получения случайного числа
import random
#генерируем случайное число от 1 до 10
num = random.randrange(1,11)
#предлагаем ввести ответ
guess = int(input(">"))
#инициализируем счётчик количества попыток угадать число
guesses = 1
#цикл повторяется пока число не угадано
while num != guess:
    if num > guess:
        print("Задуманное число больше введённого")
    elif num < guess:
        print("Задуманное число меньше введённого")
    guess = int(input(">"))
    guesses = guesses + 1
#выводим результаты игры
print("Задуманное число:", num)
print("Количество попыток:", guesses)

      
#импортируем модуль для получения случайного числа
import random
#генерируем случайное число от 1 до 10
num = random.randrange(1,11)
#предлагаем ввести ответ
guess = int(input(">"))
#инициализируем счётчик количества попыток угадать число
guesses = 1
#цикл повторяется пока число не угадано
while num != guess:
    if num > guess:
        print("Задуманное число больше введённого")
    elif num < guess:
        print("Задуманное число меньше введённого")
    guess = int(input(">"))
    guesses = guesses + 1
#выводим результаты игры
print("Задуманное число:", num)
print("Количество попыток:", guesses)

Задания для самостоятельной работы

Задание № 1 (sam01.py)

Вычислите сумму всех нечётных чисел от 1 до 20. Для выполнения вычислений используйте цикл while.

Задание № 2 (sam02.py)

Вычислите сумму чётных чисел от одного до n, где n – число, введённое с клавиатуры. Для выполнения вычислений используйте цикл while.

Задание № 3 (sam03.py)

Найти все трёхзначные числа, которые делятся на 11 без остатка. Для решения задачи используйте цикл while.

Для определения делимости числа используйте оператор % - получение остатка от деления:

# 10 не делится на 3 без остатка, 3 не является делителем 10
10 % 3 
>>> 1
# 10 делится на 5 без остатка, 5 является делителем 10
10 % 5
>>> 0

Задание № 4 (sam04.py)

Числа 1, 1, 2, 3, 5, 8 … являются частью последовательности Фибоначчи. Каждое число в последовательности, после первых двух является суммой двух предыдущих чисел последовательности. Напишите программу, которая вычисляет и выводит на экран n-ое число последовательности. Число n вводиться с клавиатуры.

Задание № 5 (sam05.py)

Для нахождения наибольшего общего делителя (НОД) двух чисел можно использовать алгоритм Евклида. Пусть m и n - исходные числа. Многократно выполним следующую операцию:

n, m = m, n % m

до тех пор, пока m не будет равно 0. После этого значение НОД будет храниться в переменной n.

Напишите программу нахождения НОД двух чисел, используя приведённый выше алгоритм.