这是我第一次在stackoverflow中发帖,所以我希望我在网站礼仪方面做得很好。我是一个初级编程类(Python),我目前的任务是根据用户输入计算碳,氢和氧的化合物的分子量。它可以是从C2到C8H19O2的任何东西,依此类推。
我有我的代码,我不断收到我不熟悉的错误。基本上我要做的是让代码通过字符读取输入复合字符,确定它是否是分子。然后,它读取前一个字符右侧的字符,以确定它是否是另一个化合物的数量。如果它是一种不同的化合物,则将之前的单一化合物添加到其总计的任何分子的运行记录中。如果它是一个数字,那么它将读取右边的下一个字符,再次确定它是一个数字还是一个字符。如果它是一个数字,它将前一个字符数乘以10,然后加上下一个,依此类推,直到它到达下一个字符(C123H2将是10 * 1 + 2,然后是10 * 12 + 3,然后它会在运行的计数中添加123个碳。一旦我们的流动结果完成,那么该数字乘以其中一个的分子量。我一直得到索引错误,说我的列表索引超出范围。非常感谢任何帮助!
def main():
C1 = 0
H1 = 0
O1 = 0
num = 0
chemicalFormula = (input("Enter the chemical formula, or enter key to quit: "))
while True:
cformula = list(chemicalFormula)
for index, x in enumerate(cformula):
if x == 'C':
if cformula[index + 1] == 'H' or cformula[index + 1] == 'O':
C1 += 1
else:
for index, y in enumerate(range(index + 1, 1000000000)):
if cformula[index + 1] != 'H' or cformula[index + 1] != 'O':
num = int(y)
num = num*10 + int(cformula[index + 1])
else:
C1 += num
break
elif x == 'H':
if cformula[index + 1] == 'C' or cformula[index + 1] == 'O':
H1 += 1
else:
for y in range(index + 1, 1000000000):
if cformula[index + 1] != 'C' or cformula[index + 1] != 'O':
num = int(y)
num = num*10 + cformula[index + 1]
else:
H1 += num
break
elif x == 'O':
if cformula[index + 1] == 'C' or cformula[index + 1] == 'H':
O1 += 1
else:
for y in range(index + 1, 1000000000):
if cformula[index + 1] != 'C' or cformula[index + 1] != 'H':
num = int(y)
num = num*10 + cformula[index + 1]
else:
O1 += num
break
else:
break
weightC = 15.994*C1
weightH = 1.0079*H1
weightO = 12.011*O1
sumWeight = weightC + weightH + weightO
print("The molecular weight is ", sumWeight)
答案 0 :(得分:0)
您有几个名为index
的不同变量,它们相互隐藏。
首先,你正在迭代cformula:
for index, x in enumerate(cformula)
行。所以index
总是在cformula
的合理范围内。但就在那之后你做了
for index, y in enumerate(range(index + 1, 1000000000))
现在索引可以是1000000000,然后是:
if cformula[index + 1]
糟糕。 cformula
甚至不接近大小为1000000002,因为它需要对此表达式进行合理评估。我相信你在这里并不需要enumerate
。
您所要做的就是使用cformula
访问x
- 主迭代中的当前元素。只要你只是阅读它(这是你真正需要的),它就没事了。
从这个问题来看,你似乎并不明白enumerate
到底意味着什么 - 你正在使用它而你实际上并不需要任何特别的东西。
不要使用相同的变量来表示不同的东西!
答案 1 :(得分:0)
首先,对于初学者来说,这种方法看起来相当不错,竖起大拇指!现在,为了从标题中回答你的问题,错误来自于访问不存在的序列的元素,例如,四个元素序列的第五个元素。在你的情况下,我想这是由cformula[index + 1]
触发的,其中索引可能已经是最后一个元素的索引。请注意,知道哪个输入触发了此错误也很有趣,我的猜测是“CO”或“C2H5OH”,因为两者都有一个复合字母,后面没有数字。
现在,如何绕过它?一个非常简单的方法是简单地接受字符串的其余部分(可以为空)并处理其内容。
count = ''
for d in cformula[index + 1:]:
if d.isdigit():
count += d
else:
break
此代码将cformula[index]
之后的所有数字存储到下一个非数字。如果没有数字,则存储空字符串。请注意,这甚至不关心您正在查看哪个原子(C,H,O),因此对于可以移动到单独函数的代码来说,它是一个很好的示例。然后,在调用该函数后,检查数字字符串:
if count == '':
# number of atoms is implicitly 1
atoms = 1
else:
# number of atoms is explicitly given
atoms = int(count)
# TODO: discard len(count) elements from the input string
BTW:有dict
类型可用于存储每个元素的原子数。同样,您可以使用它来存储每种原子类型的权重:
atom_weight = {'C': 15.994,
'H': 1.0079,
'O': 12.011,}
weight = atom_weight['C'] * C1 + atom_weight['H'] * H1 + atom_weight['O'] * O1
这不会使您的代码正确,但可以更容易地将其扩展到周期表的其余部分。 :)