2017-05-05 347 views
-2

所以我想创建一个程序来计算分子量只需三个分子C = 12.0110,H = 1.0079和O = 15.9994。用户将输入一个像H2O这样的公式,程序应该输出“18.01528”的计算权重。 我只是难住如何创建一个方法来乘以一个数字的字母,以及如何计算它是否输入公式是两个字符长或更长。 到目前为止,我有一本字典:python计算分子量

elements = { 
'C' : 12.0110, 
'H' : 1.0079, 
'O' : 15.9994 
} 

输出应该是这样的:

Enter a chemical formula, or just the enter key to quit: C2H5OH 
The molecular weight is 46.0688 

的Python 3.6.1 谢谢!

+2

像[上CodeGolf这一挑战(https://codegolf.stackexchange.com/questions/118715/build-a-mass-spectrometer/118725#118725)你意思是 ? –

+1

@PaulR我认为这与你发布的内容相反。 :D – rbaleksandar

+0

@rbaleksandar是的,它恰恰相反! – jfra3191

回答

-1

你只需要解析字符串(H2O或其他),并检查一个元素后面是数字(或数字),另一个元素或什么都没有(字符串的末尾)。

你还需要考虑一个情况,你可以有多个相邻的数字(H22O;是的,我知道这样的元素是不可能的,但它只是一个例子)。

分子的所有部分将被存储在列表中,每个原子(或多个相同的)被分开存储。这将允许您在列表中运行一个简单的总和以获得最终结果。

对于每一个字符做(这将是一个简单的循环如for char in user_input: ...):

  • 检查它是否是字母 - 如果是这样,随着原子量更换(或任何它被称为)和存储它在一个列表中:

    f = [] 
    f = [1]  # let's say H has a mass of 1 :D 
    f = [1, 2] # let's say O has a mass of 2 :D 
    

    您必须在您提供的表格中找到该元素。就我个人而言,我会用字典来更快,更方便地访问。元素的字母表示将是关键,它的质量就是价值。如果你需要处理的是由多个字符(例如:Pb)元素(如你转换级联字符为整数没有最后一部分)可以适应用于处理数字下一步:

    e_tmp = '' 
    e_tmp = e_tmp + 'P' # P 
    e_tmp = e_tmp + 'b' # Pb 
    
    # elements below is a dictionary. You should do an extra step to check if the key is present 
    a_mass = elements.get(e_tmp) 
    f.append(a_mass) 
    
  • 检查如果它是数字字符 - 将其存储在临时变量中(作为字符串,不要将其转换为数字!)。继续串联数字字符,直到到达用户的输入端或其他英文字母:

    tmp = '' 
    tmp = tmp + '2' 
    ... 
    

    现在你已经只有数字字符的字符串,你可以将其转换为整数:

    tmpInt = int(tmp) # tmpInt = 2 
    

    现在,将您插入的元素列表中的最后一个单元格与该数字相乘。您可以跟踪该小区的指数与变量,使接入更加容易:

    f = [] 
    f = [1] 
    tmp = '' 
    tmp = tmp + '2' 
    tmpInt = int(tmp) 
    f[last] = f[last]*tmpInt 
    
  • 你已经达到了用户输入的字符串结束之后,你可以总结的所有元素:

    molecular_weight = sum(map(int, f)) 
    

编辑:Here是一个非常广泛的例子,如何使用字典存储元素周期表虽然作为刚刚使用dict内部数据管理的自定义类。

-1

使用正则表达式来解析字符串,很容易想出一个解决方案,可以处理两个字母元素,如Pb和多位数字如C10H3。请注意,这仍然不会处理化合物。

compounds = { 
'C' : 12.0110, 
'H' : 1.0079, 
'O' : 15.9994, 
'Pb': 81.4 # Added to show Aa elements working, not actual weight of Pb! 
} 

pattern = re.compile(r'([A-Z][a-z]?)(\d+)?') 

z = 'Pb4O5' 

total = 0.0 
for element, n_str in re.findall(pattern, z): 
    if n_str: 
     n = int(n_str) 
    else: 
     # If there's no number for current element, n_str = '' 
     n = 1 
    total += compounds[element] * n 

print(total) 
3

我识别两个主要功能:

  1. 验证/解析公式例如,H2O成化学符号和它发生的次数。例如,H20[('H', 2), ('O', 1)]

    您需要注意首字母为大写的化学符号,后面带小写字母,数字不得超过一位。这可能有点棘手,并可能分成几个阶段。

  2. 从解析的公式中总结权重。即,对于[('H', 2), ('O', 1)]做这样的事情

    parsed_formula = parse(formula) # [('H', 2), ('O', 1)] 
    return sum([weight[symbol] * number] for symbol, number in parsed_formula])