Занятие № 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)

Выведите на экран значения функции \(f(x) = x^2+\frac{x}{2}\). Начальное и конечное значение x, а также шаг его изменения вводится с клавиатуры.

Начало
Начало
Ввод
xn, xk, h
Ввод xn, xk, h
Да
Да
Нет
Нет
x <= xk
x <= xk
y = x ** 2 + x / 2
y = x ** 2 + x / 2
Вывод
x, y
Вывод x, y
Конец
Конец
x = xn
x = xn
x = x + h
x = x + h
Text is not SVG - cannot display
Рисунок 4
# запрашиваем ввод необходимых данных
xn = float(input("Введите начальное значение x "))
xk = float(input("Введите конечное значение x "))
h = float(input("Введите шаг изменения x "))

x = xn # начальное значение x
while x <= xk:
    y = x ** 2 + x / 2 # вычисляем y
    print(f"{x:.2f} {y:.2f}")
    x = x + h

Пример работы программы:

Введите начальное значение x <{1}> ++enter++
Введите конечное значение x <{2}> ++enter++
Введите шаг изменения x <{0.2}> ++enter++
1.00 1.50
1.20 2.04
1.40 2.66
1.60 3.36
1.80 4.14
2.00 5.00

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

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

Начало
Начало
Вывод
Среднее арифметическое
Вывод Среднее арифметическое
summ = 0
summ = 0
count = 0
count = 0
Ввод
x
Ввод x
Да
Да
Нет
Нет
x > 0
x > 0
summ = summ + x
summ = summ + x
count = count + 1
count = count + 1
Ввод
x
Ввод x
Вывод
summ / count
Вывод summ / count
1
1
1
1
Конец
Конец
Text is not SVG - cannot display
Рисунок 5
print("Среднее арифметическое")

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

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

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

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

Пример работы программы:

Введите оценку> <{6}> ++enter++
Введите оценку> <{7}> ++enter++
Введите оценку> <{8}> ++enter++
Введите оценку> <{9}> ++enter++
Введите оценку> <{0}> ++enter++
Средняя оценка: 7.5

Исправьте условие цикла так, чтобы расчёты продолжались только если оценка больше 0 и меньше или равна 10.

Пример № 3 (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)

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

Решите следующие задачи самостоятельно.

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

Составьте программу, которая принимает на вход целое число - рейтинг товара. Значение должно находится в отрезке от 0 до 5. Ввод значения должен повторяться, пока не будет получено корректное число.

Пример работы программы:

Введите рейтинг товара: <{7}> ++enter++
Повторный ввод: <{-3}> ++enter++
Повторный ввод: <{4}> ++enter++
Ваша оценка товара: 4

В левой колонке есть лишние блоки.

rate = int(input("Введите рейтинг товара: "))
while rate > 5 or rate < 0:
    rate = int(input("Повторный ввод: "))
print(f"Ваша оценка товара: {rate}")
print(f"Ваша оценка товара: {rate}")
while not rate == 0 and not rate == 5:
while rate >= 0 and rate <= 5:
rate = int(input("Повторный ввод: "))
print("Ваша оценка товара: {rate}")
while rate > 5 or rate < 0:
rate = int(input("Введите рейтинг товара: "))

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

Напишите программу, которая переводит значение энергии из килокалории в Джоули: 1 ккал = 4186.8 Дж. Предусмотрите защиту от ввода отрицательных значений энергии.

Пример работы программы:

Энергия (ккал): <{-100}> ++enter++
Энергия (ккал): <{250}> ++enter++
250 ккал = 1046700.0 Дж

Алгоритм решения задачи можно составить из следующих инструкций:

ввод значения энергии E
пока E меньше нуля повторять
    повторный ввод значения энергии E
вывод на экран значения E * 4186.8
повторный ввод значения энергии E
ввод значения энергии E
пока E меньше нуля повторять
вывод на экран значения E * 4186.8

Теперь запишите полученный алгоритм с помощью инструкций Python, чтобы решить задачу.

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

Напишите программу для отслеживания суммарного количества пройденных за день шагов. Пользователь вводит количество пройденных шагов. Ввод повторяется пока не будет введено отрицательное значение. Все введенные значения суммируются (кроме отрицательного). Если суммарное количество шагов превышает 10000, выведите сообщение “Дневная норма выполнена. Пройдено шагов: <сумма>”. Иначе выведите “Норма не выполнена. Осталось <10000 - сумма> шагов”.

Примеры работы программы:

Ввод: <{5000}> ++enter++
Следующее значение: <{3500}> ++enter++
Следующее значение: <{-1}> ++enter++
Норма не выполнена. Осталось 1500 шагов
Ввод: <{7500}> ++enter++
Следующее значение: <{4700}> ++enter++
Следующее значение: <{-1}> ++enter++
Дневная норма выполнена. Пройдено шагов: 12200

Алгоритм решения задачи можно составить из следующих инструкций:

ввод значения N
S = 0
пока N > 0 повторять
    увеличить S на N
    повторный ввод N
если S больше или равно 10000, то
    вывод "Дневная норма выполнена"
иначе
    вывод "Норма не выполнена"
повторный ввод N
вывод "Норма не выполнена"
иначе
увеличить S на N
если S больше или равно 10000, то
вывод "Дневная норма выполнена"
ввод значения N S = 0
пока N > 0 повторять

Теперь запишите полученный алгоритм с помощью инструкций Python, чтобы решить задачу.

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

Реализуйте алгоритм Евклида для нахождения наибольшего общего делителя двух целых чисел. Посчитайте наименьшее общее кратное этих чисел. Реализуйте алгоритм по приведённой блок-схеме:

Начало
Начало
Ввод
x, y
Ввод x, y
Нет
Нет
a != b
a != b
Да
Да
Нет
Нет
a > b
a > b
a = a - b
a = a - b
b = b - a
b = b - a
Вывод
a
Вывод a
Конец
Конец
Да
Да
1
1
1
1
a = x
b = y
a = x…
nok = x * y / a
nok = x * y / a
Вывод
nok
Вывод nok
Text is not SVG - cannot display
Рисунок 6

Примеры работы программы:

x: <{24}> ++enter++
y: <{18}> ++enter++
НОД: 6
НОК: 72
x: <{13}> ++enter++
y: <{7}> ++enter++
НОД: 1
НОК: 91

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

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