0

这是我第一次在 stackoverflow 上发帖,所以我希望我在网站礼仪方面做的一切都是正确的。我正在上初级编程课程(Python),我目前的任务是在给定用户输入的情况下计算碳、氢和氧化合物的分子量。它可以是任何东西,从 C2 到 C8H19O2,等等。

我有我的代码,但我不断收到一个我不熟悉的错误。本质上,我想做的是让代码逐个字符地读取输入的复合字符,确定它是否是分子。然后,它读取前一个字符右侧的字符,以确定它是否是另一个复合词的数字。如果它是不同的化合物,则将先前的单一化合物添加到它的总分子的运行计数中。如果是数字,则读取右边的下一个字符,再次判断是数字还是字符。如果是数字,它将前一个字符数乘以 10,然后加上下一个,依此类推,直到到达下一个字符(C123H2 将是 10*1 + 2 后跟 10*12 + 3,然后它将在运行计数中增加 123 个碳)。一旦我们的流动计数完成,然后该数字乘以每个的分子量。我不断收到一个索引错误,说我的列表索引超出范围。任何帮助是极大的赞赏!

定义主():

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)
4

2 回答 2

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

顺便说一句: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

这不会使您的代码正确,但可以更容易地将其扩展到元素周期表的其余部分。:)

于 2013-05-24T05:33:52.130 回答
0

您有几个名为 的不同变量index,它们相互隐藏。

首先,您正在迭代 cformula:

for index, x in enumerate(cformula)

好的。soindex总是在 的合理范围内cformula。但在那之后你就做了

for index, y in enumerate(range(index + 1, 1000000000))

现在索引可以是 1000000000,然后:

if cformula[index + 1]

哎呀。cformula甚至不接近 1000000002 的大小,因为它需要对这个表达式进行合理的评估。我相信你真的不需要enumerate这里。

您所要做的就是访问cformulausing x- 主迭代中的当前元素。只要您只是阅读它(这是您真正需要的),就可以了。

从这个问题来看,您似乎不明白究竟是什么enumerate意思-您在实际上不需要任何特殊的地方使用它。

不要用同一个变量来表示不同的东西!

于 2013-05-24T03:47:44.003 回答