Справка по бесконечному циклу в Python

#python #loops #while-loop #infinite

Вопрос:

Может кто-нибудь помочь мне понять, почему этот цикл бесконечен? Класс, в котором я нахожусь, автоматически вводит переменные для меня в соответствии с этими последними 2 строками. Он проходит тест с номерами 2 и 4. Однако есть еще один вход, который я не могу видеть, который заставляет это работать как бесконечный цикл. Я не могу понять, где в этом коде есть пробел, который позволил бы бесконечный цикл. Есть какие-нибудь предложения?

 def shampoo_instructions(user_cycles):
    N = 1
    while N <= user_cycles:
        if N < 1:
            print('Too few')
        elif N > 4:
            print('Too many')
        else:
            print(N,': Lather and rinse.')
            N = N   1
    print('Done.')
                
user_cycles = int(input())
shampoo_instructions(user_cycles)
 

Комментарии:

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

2. Добро пожаловать в SO. Пожалуйста, исправьте свой отступ.

3. Я добавил с обновленным отступом. Извините. @ewong

4. Я добавил с обновленным отступом. Извините. @Сэмвайз

5. По вашим собственным словам, что должно быть правдой, N = N 1 чтобы это произошло? По вашим собственным словам, если этого не произойдет, то почему результат должен N <= user_cycles измениться? Если этого не произойдет, то почему цикл закончится?

Ответ №1:

N = N 1 Выйдите из цикла, иначе он никогда не дойдет до добавления.

Или лучше использовать N = 1 :

 def shampoo_instructions(user_cycles):
    N = 1
    while N <= user_cycles:
        if N < 1:
            print('Too few')
        elif N > 4:
            print('Too many')
        else:
            print(N,': Lather and rinse.')
        N = N   1
    print('Done.')
                
user_cycles = int(input())
shampoo_instructions(user_cycles)
 

Ответ №2:

Во-первых: привыкайте тестировать свой код. Поскольку у вас есть условные обозначения, включающие числа 1 и 4, вы должны проверить числа, которые меньше 1 и больше 4, чтобы увидеть, что происходит за этими краями. Конечно же, если ввести 5 в качестве входных данных, получится бесконечный цикл:

 0
Done.
1
1 : Lather and rinse.
Done.
4
1 : Lather and rinse.
2 : Lather and rinse.
3 : Lather and rinse.
4 : Lather and rinse.
Done.
5
1 : Lather and rinse.
2 : Lather and rinse.
3 : Lather and rinse.
4 : Lather and rinse.
Too many
Too many
Too many
Too many
Too many
Too many
 

Почему это происходит? user_cycles == 5 таким образом, цикл не остановится до N == 6 тех пор (или до любого значения, превышающего 5.

Что произойдет, когда N == 5 ? Мы печатаем «Слишком много», а затем продолжаем цикл без увеличения N снова. Следовательно, цикл всегда будет застревать при N = 5.

Обратите внимание, что тестирование с этими значениями также показывает, что мы никогда не выполняем Too few условие-это мертвый код! Невозможно когда-либо достичь этого состояния, потому N что оно всегда начинается с 1 и никогда не уменьшается.

Способ исправления бесконечного цикла зависит от желаемого поведения. Вы можете break запустить цикл, как только N превысит 4:

         elif N > 4:
            print('Too many')
            break
 

Другим вариантом было бы убедиться, что N всегда увеличивается, либо увеличивая его внутри этого условного блока, либо увеличивая его вне всего if...elif...else оператора, а не внутри else (который будет выполняться только для значений от 1 до 4).

Комментарии:

1. Большое вам спасибо за подробное объяснение! Это сформулировано именно так, как мне было нужно, для удобства понимания. Мы очень ценим вашу помощь! Это помогло мне увидеть, что я также не установил ограничений для переменной user_cycles, в которой генерируются входные данные. Еще раз спасибо вам!