Как избежать этого цикла while?

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

Приведенный ниже код проверяет, содержит ли пользовательский ввод только 1 и 0 и не превышает ли он максимум 8 бит. Когда я запускаю его и ввожу недопустимый номер, он работает и зацикливается нормально, но когда я ввожу действительный номер, он продолжает возвращаться к команде ввода и просит меня ввести что-то вместо выхода из цикла и перехода к следующему. . Пожалуйста помоги!

max_8bits = 1
only_bin = 1
while max_8bits > 0 or only_bin > 0:

    b2d_num = input("Enter a binary number:")

    for i in range(len(b2d_num)):
        if b2d_num[i] == "0" or b2d_num[i] == "1":
            if i == len(b2d_num):
                only_bin -= 1
        else:
            print("Only enter a binary number! (0's and 1's)")
            break

    if len(b2d_num) > 8:
        print("Only enter up to 8 bits!")
    elif len(b2d_num) <= 8:
        max_8bits -= 1
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
0
93
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Похоже, что у вас есть код b2d_num = input("Enter a binary number:") внутри вашего цикла while, который заставит этот код запускаться каждый раз при выполнении цикла while.

Исправить это довольно просто: поместите этот фрагмент кода чуть выше цикла while, чтобы он был выполнен только один раз.

Условие i == len(b2d_num) никогда не является True, потому что последняя итерация цикла выполняется с i == len(b2d_num) - 1.

Например.

>>> for i in range(10):
       pass

>>> print(i)
9

Спасибо! Я забыл об этом, вроде у меня тоже была еще одна ошибка, но я справился :)

tysh444 26.10.2018 22:08
Ответ принят как подходящий

Основная проблема в том, что вы никогда не устанавливаете флаги для выхода из цикла. Вы никогда не дойдете до того, чтобы индекс 8 был в цикле от 0 до 7. Когда break выходит из цикла for, вы неправильно управляете значениями. Предложения:

  1. Используйте логические значения, а не целые числа: это логика в вашей голове.
  2. Упростите проверку значений: используйте встроенные функции Python.

Код:

too_long = True
not_bin = True

while too_long or not_bin:

    b2d_num = input("Enter a binary number:")

    # Check input length
    too_long = len(b2d_num) > 8
    if too_long:
        print("Only enter up to 8 bits!")
        continue

    # Check input content
    not_bin = False

    for i, bit in enumerate(b2d_num):
        not_bin = not_bin or bit not in "01"

    if not_bin:
        print("Only enter a binary number! (0's and 1's)")

В конечном итоге я использовал логические значения, но я не сталкивался и не понимаю некоторых встроенных функций, поэтому я хотел бы избежать путаницы. Если бы я использовал новый фрагмент кода, мне также пришлось бы объяснять его своему учителю, так что это своего рода недостаток.

tysh444 27.10.2018 00:12

Единственная новая встроенная функция, которую я вижу здесь, - это enumerate; все остальное - стандартные языковые функции.

Prune 27.10.2018 02:17

Условие if i == len(b2d_num): никогда не будет выполнено, потому что оператор range() не включает значение остановки, поэтому последним значением i будет len(b2d_num) - 1.


Язык Python должен быть легко читаемым, и вы можете улучшить свой код, используя bool вместо int. Это могло быть улучшением:

max_8bits = False
only_bin = False

while not (max_8bits and only_bin):
    b2d_num = input("Enter a binary number:")
    max_8bits = True
    only_bin = True

    # test first condition
    if len(b2d_num) > 8:
        max_8bits = False
        print("Only enter up to 8 bits!")

    # test second condition, but only if first condition is met
    if max_8bits:
        for char in b2d_num:
            if char not in ("0", "1"):
                only_bin = False
                print("Only enter a binary number! (0's and 1's)")
                break

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

>>> import timeit

>>> timeit.timeit('for elem in elem_list: _ = elem', 'elem_list = list(range(1000))', number=100000)
0.9983139920514077
>>> timeit.timeit('for i in range(len(elem_list)): _ = elem_list[i]', 'elem_list = list(range(1000))', number=100000)
3.1029140750179067

>>> timeit.timeit('for elem in elem_list: _ = elem', 'elem_list = list(range(10))', number=100000)
0.014086865936405957
>>> timeit.timeit('for i in range(len(elem_list)): _ = elem_list[i]', 'elem_list = list(range(10))', number=100000)
0.06772643199656159

Как видите, использование позиционного доступа к элементам списка приводит к тому, что цикл занимает примерно в 3 раза больше времени (это может варьироваться, но это сильный индикатор). Использование for elem in elem_list более читабельно и быстрее.

Да, в конце концов, я их поменял, но спасибо! Однако, боюсь, я не использовал лупы for в формате: for char in b2d_num:, поэтому не решаюсь использовать их.

tysh444 27.10.2018 00:07

@ tysh444 Я добавил сравнение скорости к своему ответу о циклах for.

Ralf 27.10.2018 12:35

Другие вопросы по теме