Это довольно классика. Читать в базе легче, чем писать в одной.
def bintodec(var):
assert set(var) <= set("01") # Just check that we only have 0s and 1s
assert isinstance(var, str) # Checks that var is a string
result = 0
for character in var: # character will be each character of var, from left to rigth
digitvalue = ord(character) - ord("0")
result *= 2
result += digitvalue
return result
Хорошо, как это работает?
Ну, это читает значение слева направо. digitvalue
будет содержать 1
или 0
. Для каждой цифры, которую мы читаем, если это 0
, нет ничего, чтобы добавить результат (поэтому result += digitvalue
добавляет действительно 0
), но мы все равно должны принять во внимание, что в конце есть еще один 0
числа.
Теперь в базе 10 добавление нуля в конец делает число в 10 раз больше. То же самое в базе 2. Добавление нуля в конце делает число в два раза больше. Вот почему мы умножаем это на 2.
Наконец, если digitvalue
равно 1
вместо 0
, нам нужно добавить 1
к числу и result += digitvalue
сделает это.
Примечание. Просто для ясности приведенные ниже два цикла for эквивалентны.
for character in var:
pass # pass does nothing
for i in range(len(var)):
character = var[i]
pass
@ JayF:.
Есть ли способ перекомпоновки без использования assert?
Полагаю, вы хотите сделать перепроверку, если ввод неправильный. Для этого вам нужно использовать цикл:
while True:
var = input()
if set(var) <= set("01"):
print(bintodec(var))
break # Remove this `break` statement if you want to reprompt forever
else:
# print("The input must consist of only 0s and 1s.")
pass # `pass` does nothing.
Если вы оставите утверждения в функции bintodec
, это можно сделать более питоническим способом, используя обработку исключений:
while True:
var = input()
try:
print(bintodec(var))
break
except AssertionError:
print("The input must consist of only 0s and 1s.")