Сейчас я учусь в 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
Похоже, что у вас есть код 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
Основная проблема в том, что вы никогда не устанавливаете флаги для выхода из цикла. Вы никогда не дойдете до того, чтобы индекс 8
был в цикле от 0 до 7.
Когда break
выходит из цикла for
, вы неправильно управляете значениями. Предложения:
Код:
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)")
В конечном итоге я использовал логические значения, но я не сталкивался и не понимаю некоторых встроенных функций, поэтому я хотел бы избежать путаницы. Если бы я использовал новый фрагмент кода, мне также пришлось бы объяснять его своему учителю, так что это своего рода недостаток.
Единственная новая встроенная функция, которую я вижу здесь, - это enumerate
; все остальное - стандартные языковые функции.
Условие 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 Я добавил сравнение скорости к своему ответу о циклах for.
Спасибо! Я забыл об этом, вроде у меня тоже была еще одна ошибка, но я справился :)