我正在制作一个可以考虑子公式的化合物的摩尔质量计算器。
例如:
这是代码:
import re
atomic_mass = { "H": 1.00797,"He": 4.00260,"Li": 6.941,"Be": 9.01218,"B": 10.81,"C": 12.011,"N": 14.0067,"O": 15.9994,"F": 18.998403,"Ne": 20.179,"Na": 22.98977,"Mg": 24.305,"Al": 26.98154,"Si": 28.0855,"P": 30.97376,"S": 32.06,"Cl": 35.453,"K": 39.0983,"Ar": 39.948,"Ca": 40.08,"Sc": 44.9559,"Ti": 47.90,"V": 50.9415,"Cr": 51.996,"Mn": 54.9380,"Fe": 55.847,"Ni": 58.70,"Co": 58.9332,"Cu": 63.546,"Zn": 65.38,"Ga": 69.72,"Ge": 72.59,"As": 74.9216,"Se": 78.96,"Br": 79.904,"Kr": 83.80,"Rb": 85.4678,"Sr": 87.62,"Y": 88.9059,"Zr": 91.22,"Nb": 92.9064,"Mo": 95.94,"Tc": 98,"Ru": 101.07,"Rh": 102.9055,"Pd": 106.4,"Ag": 107.868,"Cd": 112.41,"In": 114.82,"Sn": 118.69,"Sb": 121.75,"I": 126.9045,"Te": 127.60,"Xe": 131.30,"Cs": 132.9054,"Ba": 137.33,"La": 138.9055,"Ce": 140.12,"Pr": 140.9077,"Nd": 144.24,"Pm": 145,"Sm": 150.4,"Eu": 151.96,"Gd": 157.25,"Tb": 158.9254,"Dy": 162.50,"Ho": 164.9304,"Er": 167.26,"Tm": 168.9342,"Yb": 173.04,"Lu": 174.967,"Hf": 178.49,"Ta": 180.9479,"W": 183.85,"Re": 186.207,"Os": 190.2,"Ir": 192.22,"Pt": 195.09,"Au": 196.9665,"Hg": 200.59,"Tl": 204.37,"Pb": 207.2,"Bi": 208.9804,"Po": 209,"At": 210,"Rn": 222,"Fr": 223,"Ra": 226.0254,"Ac": 227.0278,"Pa": 231.0359,"Th": 232.0381,"Np": 237.0482,"U": 238.029,"Pu": 242,"Am": 243,"Bk": 247,"Cm": 247,"No": 250,"Cf": 251,"Es": 252,"Hs": 255,"Mt": 256,"Fm": 257,"Md": 258,"Lr": 260,"Rf": 261,"Bh": 262,"Db": 262,"Sg": 263,"Uun": 269,"Uuu": 272,"Uub": 277 }
def separate_string_number(string):
previous_character = string[0]
groups = []
newword = string[0]
for x, i in enumerate(string[1:]):
if i.isalpha() and previous_character.isalpha():
newword += i
elif i.isnumeric() and previous_character.isnumeric():
newword += i
else:
groups.append(newword)
newword = i
previous_character = i
if x == len(string) - 2:
groups.append(newword)
newword = ''
return groups
def separate_glued_elements(list):
temp = []
for item in list:
if item.isalpha():
temp.append(re.findall('[A-Z][^A-Z]*', item))
else:
temp.append(item)
return [item for row in temp for item in row]
testformula = 'H20HeO(CO2)3'
print(separate_glued_elements(separate_string_number(testformula)))
到目前为止,我已经构建了一个系统,该系统基本上可以正确地将字符串输入拆分为元素数组并按顺序出现,
输入/输出示例:
流程: userIn ->separate_string_number ->separate_glued_elements ->尚未开始计算功能
用户输入 (<-): H20eO(CO2)3
separate_string_number (->): ['H', '20', 'HeO', '(', 'CO', '2', ')', '3']
seperate_glued_elements (->): ['H', '2', '0', 'He', 'O', '(', 'C', 'O', '2', ')', '3 ']
EX: H20HeO(CO2)3 的形式为 ['H', '2', '0', 'He', 'O', '(', 'C', 'O', '2', ')', '3'];
这是一个问题,它不是解析为 ['H', '20', 'He'...] 而是拆分为 ['H', '2', '0', 'He'.. .]
最重要的是,我一生都无法弄清楚一旦获得数据后如何实际使用它。
我通过更改粘合元素功能来修复它。在旧代码中,数字仍然是字符串,并且单独的字符串函数通过拆分所有字符串来工作,所以现在 20 不再是字符串
def seperate_glued_elements(chem_list):
temp1 = []
for item in chem_list:
if item.isnumeric():
temp1.append(int(item))
else:
temp1.append(item)
temp2 = []
for item in temp1:
if type(item) == str:
if item.isalpha():
temp3 = re.findall('[A-Z][^A-Z]*', item)
for subitem in temp3:
temp2.append(subitem)
else:
temp2.append(item)
else:
temp2.append(item)
return temp2
这是已完成的项目代码,供将来需要的任何人使用。 (我知道这不是很好,但它确实有效)
import re
atomic_mass = { "H": 1.00784,"He": 4.00260,"Li": 6.941,"Be": 9.01218,"B": 10.81,"C": 12.011,"N": 14.0067,"O": 15.9994,"F": 18.998403,"Ne": 20.179,"Na": 22.98977,"Mg": 24.305,"Al": 26.98154,"Si": 28.0855,"P": 30.97376,"S": 32.06,"Cl": 35.453,"K": 39.0983,"Ar": 39.948,"Ca": 40.08,"Sc": 44.9559,"Ti": 47.90,"V": 50.9415,"Cr": 51.996,"Mn": 54.9380,"Fe": 55.847,"Ni": 58.70,"Co": 58.9332,"Cu": 63.546,"Zn": 65.38,"Ga": 69.72,"Ge": 72.59,"As": 74.9216,"Se": 78.96,"Br": 79.904,"Kr": 83.80,"Rb": 85.4678,"Sr": 87.62,"Y": 88.9059,"Zr": 91.22,"Nb": 92.9064,"Mo": 95.94,"Tc": 98,"Ru": 101.07,"Rh": 102.9055,"Pd": 106.4,"Ag": 107.868,"Cd": 112.41,"In": 114.82,"Sn": 118.69,"Sb": 121.75,"I": 126.9045,"Te": 127.60,"Xe": 131.30,"Cs": 132.9054,"Ba": 137.33,"La": 138.9055,"Ce": 140.12,"Pr": 140.9077,"Nd": 144.24,"Pm": 145,"Sm": 150.4,"Eu": 151.96,"Gd": 157.25,"Tb": 158.9254,"Dy": 162.50,"Ho": 164.9304,"Er": 167.26,"Tm": 168.9342,"Yb": 173.04,"Lu": 174.967,"Hf": 178.49,"Ta": 180.9479,"W": 183.85,"Re": 186.207,"Os": 190.2,"Ir": 192.22,"Pt": 195.09,"Au": 196.9665,"Hg": 200.59,"Tl": 204.37,"Pb": 207.2,"Bi": 208.9804,"Po": 209,"At": 210,"Rn": 222,"Fr": 223,"Ra": 226.0254,"Ac": 227.0278,"Pa": 231.0359,"Th": 232.0381,"Np": 237.0482,"U": 238.029,"Pu": 242,"Am": 243,"Bk": 247,"Cm": 247,"No": 250,"Cf": 251,"Es": 252,"Hs": 255,"Mt": 256,"Fm": 257,"Md": 258,"Lr": 260,"Rf": 261,"Bh": 262,"Db": 262,"Sg": 263,"Uun": 269,"Uuu": 272,"Uub": 277 }
def seperate_string_number(string):
previous_character = string[0]
groups = []
newword = string[0]
for x, i in enumerate(string[1:]):
if i.isalpha() and previous_character.isalpha():
newword += i
elif i.isnumeric() and previous_character.isnumeric():
newword += i
else:
groups.append(newword)
newword = i
previous_character = i
if x == len(string) - 2:
groups.append(newword)
newword = ''
return groups
def seperate_glued_elements(chem_list):
temp1 = []
for item in chem_list:
if item.isnumeric():
temp1.append(int(item))
else:
temp1.append(item)
temp2 = []
for item in temp1:
if type(item) == str:
if item.isalpha():
temp3 = re.findall('[A-Z][^A-Z]*', item)
for subitem in temp3:
temp2.append(subitem)
else:
temp2.append(item)
else:
temp2.append(item)
return temp2
def get_subformullas(chem_list):
subformula_list = []
temp = []
switch = False
lastWasSub = False
for item in chem_list:
if type(item) == str:
if (item) == "(":
switch = True
if switch:
temp.append(item)
if type(item) == str:
if (item) == ")":
switch = False
lastWasSub = True
if type(item) == int:
if lastWasSub:
temp.append(item)
lastWasSub = False
subformula_list.append(temp)
temp = []
return subformula_list
def flatten(chem_list):
substring = ''
for item in chem_list:
substring += f'{item}'
return substring
def data_clean(chem_list):
multiplier = 1
temp = chem_list
if chem_list[0] == "(":
multiplier = chem_list[len(chem_list)-1]
chem_list.pop()
temp = [i for i in chem_list if i != '(' and i != ')']
return temp, multiplier
def calculate_part(chem_list, total_multiplier):
mass = 0
i = 0
while (i<len(chem_list)):
multiplier = 1
char = chem_list[i]
if (i+1<len(chem_list)):
if type(chem_list[i+1]) == int:
multiplier = chem_list[i+1]
i+=1
mass += atomic_mass[char]*multiplier
i+=1
return mass*total_multiplier
def main_calculation(chem_string):
testformula = chem_string
parsed_formula = seperate_glued_elements(seperate_string_number(testformula))
subformulas = get_subformullas(parsed_formula)
main_formula = chem_string
for subformula in subformulas:
main_formula = main_formula.replace(flatten(subformula),'')
main_formula = seperate_glued_elements(seperate_string_number(main_formula))
formulas = [data_clean(main_formula)]
for formula in subformulas:
formulas.append(data_clean(formula))
total_mass = 0
for formula in formulas:
total_mass += calculate_part(formula[0], formula[1])
return total_mass
def main():
formula = ""
while True:
formula = input("Input a valid chemical formula or type \"END\" to stop: ")
if formula == "END":
break
try:
print(f"\n{formula} has a mass of : ~{main_calculation(formula)}\n")
except:
print("Improper input!")
main()