这是你的第一门编程语言吗?如果是这样,让我向您介绍变量初始化的概念。
当计算机运行代码时,它正在处理内存和 CPU 之间的字节。您可能已经知道这一点,但您可能没有意识到,在您的代码中,您要求计算机对z
尚不存在的变量执行操作。
记住别的东西。Python 不需要初始化一个变量来分配它。那么,为什么需要z
在程序运行之前进行初始化呢?答案很简单:您首先引用的z
是操作。尽管 Python 可以自动(无需初始化)动态分配变量(通常与其他编程语言不同),但它仍然需要所述变量存在,然后才能使用它完成数学运算。
简单的解决方案是z = 0
在之前的任何时候添加if bd == 'a':
(因为如果你把它放在之后,每次它进入if
语句时,它都会用 覆盖z
,0
破坏它的逻辑。
快乐编码!
编辑:除了这个问题,你将面临的错误问题:
File "C:/Users/<USERNAME>/Desktop/Task 1.py", line 15, in <module> answer += 1*z**i TypeError: Can't convert 'int' object to str implicitly
来自行:
if answer [ i ] == '1':
你看,当你输入 时'1'
,你说这1
是一个字符串,因为你用引号括起来,就像你写的一样:
if answer [i] == "1":
相反,你需要的是这条线
if answer [i] == 1:
因为这告诉它分配号码 1
。那么,在操作中
answer += 1*z**i
您将告诉它乘以三个数字而不是两个数字和字符串“1”。
在 C 等其他语言中,您必须声明变量,以便计算机知道变量类型。您必须编写string variable_name = "string text"
才能告诉计算机该变量是一个字符串。在 Python 中,类型转换是自动发生的。Python 看到variable = "string text"
并且知道因为你使用""
了 ,所以它是一个字符串类型的变量。不幸的是,这意味着您错误地制作1
了一个字符串。
理解?
编辑 2:正在发生的事情
好的,所以你一直遇到错误。当我运行你的代码时,我一直遇到不同的错误。由于复杂的语法和隐式更改的类型,我决定更简单的方法是重写代码并向您解释它的工作原理和原因。所以,这是新的代码:
bd = raw_input("""
Would you like to convert a number into:
a) Binary to Decimal
b) Decimal to Binary
""").lower()
## ORIGINAL CODE
##
##if bd == 'a':
## answer = input("""
##Please enter a Binary number. Up to, and including, 8 digits of 1 and/or 0
##""")
##
## print answer
## for i in range(8):
## z += 2
## if answer[i] == '1':
## answer += 1*z**i
##NEW CODE
if bd == 'a':
number_original = raw_input("Please enter a Binary number (a string of 1's and 0's)")
j = 0
number_converted = 0
for i in reversed(number):
if i == '1':
number_converted += 2**j
j+=1
print number_converted
从上到下,我将回顾我写的内容(我会跳过你的代码),我会解释它的作用以及它是如何做到的。希望这将帮助您进行十进制->二进制转换,因为我假设您仍然需要这样做。
因此,我们首先对您的开场问题进行一些更改。以前有bd=input("")
,现在有bd=raw_input("").lower()
。
bd 仍然是a
or b
。但是,至少在我这方面,该声明中有一些不稳定的类型处理。所以,我利用raw_input()
which 将你的答案变成一个字符串,不管它是什么。例如,如果您回答101010011
,它将存储变量"101010011"
而不是数字101010011
(尽管无论如何这都是错误的-它会是base 10
,所以实际上是101,010,011
)...我还添加.lower()
了从whAtevErYouWritE
到回答whateveryouwrite
。这是数据清理的一个例子,并且是至关重要的在一个好的程序中,因为人们可能很愚蠢并期望计算机知道他们的意思。计算机当然不知道你的意思,所以你必须非常小心,知道用户会犯什么错误,并提前计划(奖励:这是一个关于这个主题的漫画,你现在肯定会得到)。
因此,进入程序的核心。我们首先测试答案的条件a
:
if bd == 'a':
现在,如果您输入A
,这仍然可以工作,因为.lower()
. 如果您b
输入 , if 将不起作用(您还没有输入您的十进制->二进制代码!),并且永远记住,总有一天,有人会输入C
,只是为了欺骗您,所以包括一个elif
forb
和 an else
for any别的。
在此之后,我们遇到了它只是我的代码的第一个迹象。
number_original = raw_input("Please enter a bin...
我将其命名为 number_original ,因为在代码中,清晰和简洁始终是最佳实践。请记住,变量名this_is_the_variable_i_use_to_calculate_my_circumference
比x
它清楚地解释它是什么更好,并帮助其他人理解你的工作。在这种情况下,更高级的编码人员喜欢模棱两可,但很多时候它只是在炫耀。
我raw_input()
再次使用,因为我实际上希望将我的号码存储为字符串。还记得我说过那101010011
会是101,010,011
电脑吗?这将很难检查,因为计算机将假定一个基数为 10的数字。因此,我只是将它存储为字符串"101010011"
,并避免了整个问题。还有一个额外的好处是字符串具有操作方法,使其更易于使用,比您尝试引入的逻辑更容易range(8)
。很快就能看到那个操纵器。
接下来,我们声明我们的变量:
j = 0 #This 'j' accomplishes the same work done by your 'z' variable.
number_converted = 0 #this will be correctly converted by the end, as we add to it.
正如我在这篇文章的原始版本中所提到的,这些是被初始化的,因为当你第一次在循环中对它们进行操作时,你会对它们进行数学运算,并且它们需要以数字的形式存在,然后你才能这样做。即使它们从 0 开始。
所以现在我们来看最有趣的部分,for
循环。根据您的原始工作,您可以了解for
循环的工作原理,但我会详细介绍它们,以便在您需要查看全局时尽可能地帮助您。
在for
循环中,您需要迭代一系列数字。在您的原始代码中,您生成了[0,1,2,3,4,5,6,7]
要迭代的范围。我认为您这样做是为了跟踪您所在的二进制数中的哪个位置,我也在这样做,但是以不同的方式,我慢慢设计的一种方式是为了帮助您做到最好我可以的十进制到二进制系统。
首先,记住它number
现在是一个字符串,所以 `"101010011"。接下来,意识到字符串具有可以像这样访问的索引。
demo_string = "super mario brothers"
print demo_string[0]
print demo_string[1]
print demo_string[2]
print demo_string[3]
print demo_string[4:10]
print demo_string[:10] #if you leave out the first number, it starts at the beginning
print demo_string[10:] #if you leave out the last number, it ends at the end.
上面的代码会给你以下结果:
s
u
p
e
r mari
super mari
o brothers
特别注意索引从0 开始,这就是demo_string[1]
isu
和 not的原因s
。
知道了这一点,您可能会开始意识到为什么我们将其保留number_original
为字符串:现在我们可以使用它的索引并对其进行迭代,而不是使用range()
! 这就是为什么我们可以输入for i in reverse(number_original)
; 因为这使它从reverse(number_original)[0]
to循环reverse(number_original)[i]
,尽可能i
地去。**注意:***我们将reverse()
很快讨论我们为什么使用*。
是时候学习数字/计算机科学和数学了!
您是否已经学会了以 2 的幂的形式表示每个二进制数字?我知道您了解二进制数转换的基本概念。好吧,这是您可能知道也可能不知道的另一个很酷的技巧:
... # # # # # # <--The binary number, eg "101010"
...32 16 8 4 2 1 <--What each digit stands for in decimal form
... 5 4 3 2 1 0 <--The power of two that it stands for (2^5=32, 2^4=16...)
您将意识到的另一件事是,通常(并非总是如此,但通常,二进制数是从右到左读取的。这很快就会派上用场)。
所以我们在for
循环中。我们现在知道我们可以遍历一个字符串。但是二进制数字是从右到左读取的。所以,二进制数10 = 2
,不是10 = 1
。这就是为什么我们写道:
for i in reversed(string):
因为现在,for
循环将向后迭代!它将为我们从右到左读取字符串。
我们也知道2^x = (digit value in decimal)
。
所以我们在for
循环的每次迭代中要做的是:
- 检查是否
i == '1'
Note,这次我们希望它是一个字符串。
- 如果
i == '1'
,例如,我们突出显示的数字是,'1'
那么...
- 获取
number_converted
并添加number_converted + 2^j
- 然后累积一次到
j
,所以下次旅行时它会更高。
为了直观地说明这一点,我将对 number 做两个循环101010011
。
循环 4
j = 4
number_converted = 3(仍在转换中)
被反转(number_original)[3] == '1'?( 1 1 0 0 1 0 1 0 1, 所以没有)
然后将 1 添加到 j (j = 5)
循环 5
j = 5
number_converted = 3 (仍在转换
中) 反转(number_original)[4] == '1' ? (1 1 0 0 1 0 1 0 1,所以是的!)
然后取 number_converted (3) 并将 2^j (2^5 = 16) 添加到它 (number_converted = 25) 然后将 1 添加到 j (j = 6)
循环 6
j = 6
number_converted = 35(仍在转换中)
这将一直持续到结束!
所以你有它。二进制转十进制,在 python 中。
如果您对此有任何疑问,请提出。我记得我刚开始时对这些东西感到困惑!
再次,快乐编码。