修正了parser 矩阵运算还不完善
This commit is contained in:
parent
9eee646100
commit
e8404e1f9d
|
@ -53,15 +53,21 @@ def solve_equation(eq):
|
||||||
row.append(0)
|
row.append(0)
|
||||||
# 取出row中的最后一个元素,反转后加入常数项
|
# 取出row中的最后一个元素,反转后加入常数项
|
||||||
constant.append(-row.pop())
|
constant.append(-row.pop())
|
||||||
|
matrix.append(row)
|
||||||
matrix = np.mat(matrix, int)
|
matrix = np.mat(matrix, int)
|
||||||
print(matrix)
|
|
||||||
print(constant)
|
|
||||||
# 求解线性方程组
|
# 求解线性方程组
|
||||||
try:
|
try:
|
||||||
|
result = np.linalg.solve(matrix, constant).tolist()
|
||||||
|
except np.linalg.LinAlgError:
|
||||||
|
# 将常数项取负,插入到矩阵的最后一列
|
||||||
|
constant = [-x for x in constant]
|
||||||
|
matrix = np.insert(matrix, matrix.shape[1], constant, axis=1)
|
||||||
|
# 再次尝试求解
|
||||||
|
try:
|
||||||
|
constant = np.zeros(matrix.shape[0], int)
|
||||||
result = sp.linalg.solve(matrix, constant).tolist()
|
result = sp.linalg.solve(matrix, constant).tolist()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e.args[0])
|
print('无法配平' + str(e))
|
||||||
print('无解')
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 将结果写入化学方程式,最后一个生成物的系数需要计算得到
|
# 将结果写入化学方程式,最后一个生成物的系数需要计算得到
|
||||||
|
@ -70,6 +76,7 @@ def solve_equation(eq):
|
||||||
# 计算除最后一种生成物外的所有生成物包含last_atom的系数之和
|
# 计算除最后一种生成物外的所有生成物包含last_atom的系数之和
|
||||||
sum_ = 0
|
sum_ = 0
|
||||||
index = 0
|
index = 0
|
||||||
|
print(result)
|
||||||
for each in eq['left']:
|
for each in eq['left']:
|
||||||
for atom in each['atoms']:
|
for atom in each['atoms']:
|
||||||
if last_atom in atom:
|
if last_atom in atom:
|
||||||
|
|
5
main.py
5
main.py
|
@ -10,9 +10,12 @@ import equation_solver
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
while True:
|
while True:
|
||||||
eq = input('请输入化学方程式:')
|
eq = input('请输入化学方程式:')
|
||||||
|
if eq == 'exit':
|
||||||
|
break
|
||||||
try:
|
try:
|
||||||
eq = parser.parse_equation(eq)
|
eq = parser.parse_equation(eq)
|
||||||
equation_solver.solve_equation(eq)
|
eq = equation_solver.solve_equation(eq)
|
||||||
|
if eq is not None:
|
||||||
print('化学方程式:', parser.format_equation(eq))
|
print('化学方程式:', parser.format_equation(eq))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e.args[0])
|
print(e.args[0])
|
||||||
|
|
35
parser.py
35
parser.py
|
@ -49,21 +49,30 @@ def parse_atomic_clusters(atomic_clusters):
|
||||||
"""
|
"""
|
||||||
将原子团转化为字典
|
将原子团转化为字典
|
||||||
:param atomic_clusters: 经过parse_molecule处理后的原子团
|
:param atomic_clusters: 经过parse_molecule处理后的原子团
|
||||||
如(ClO)2->['(', 'Cl', 'O', ')2']
|
如(ClO)2->['(', 'Cl', 'O', ')', '2']
|
||||||
:return: 原子团的字典表示
|
:return: 原子团的字典表示
|
||||||
"""
|
"""
|
||||||
# 去除首括号
|
# 去除首括号
|
||||||
atomic_clusters = atomic_clusters[1:]
|
atomic_clusters = atomic_clusters[1:]
|
||||||
# 去除尾括号,解析尾括号后的数值作为原子团系数
|
# 去除尾括号,解析尾括号后的数值作为原子团系数
|
||||||
if atomic_clusters[-1][-1].isdigit():
|
if atomic_clusters[-1].isdigit():
|
||||||
coefficient = int(atomic_clusters[-1][-1])
|
coefficient = int(atomic_clusters[-1])
|
||||||
atomic_clusters = atomic_clusters[:-1]
|
atomic_clusters = atomic_clusters[:-2]
|
||||||
elif atomic_clusters[-1] == ')':
|
elif atomic_clusters[-1] == ')':
|
||||||
coefficient = 1
|
coefficient = 1
|
||||||
else:
|
else:
|
||||||
raise ValueError('无效的原子团系数')
|
raise ValueError('无效的原子团系数')
|
||||||
# 解析原子团
|
# 解析原子团
|
||||||
atoms = []
|
atoms = []
|
||||||
|
for i in range(len(atomic_clusters)):
|
||||||
|
if atomic_clusters[i].isdigit():
|
||||||
|
while atomic_clusters[i - 1] == '':
|
||||||
|
i -= 1
|
||||||
|
if i == 0:
|
||||||
|
raise ValueError('系数错误')
|
||||||
|
atomic_clusters[i - 1] += atomic_clusters[i]
|
||||||
|
atomic_clusters[i] = ''
|
||||||
|
atomic_clusters = [atom for atom in atomic_clusters if atom != '']
|
||||||
for atom in atomic_clusters:
|
for atom in atomic_clusters:
|
||||||
atoms.append(parse_atom(atom))
|
atoms.append(parse_atom(atom))
|
||||||
return {
|
return {
|
||||||
|
@ -86,27 +95,30 @@ def parse_molecule(molecule):
|
||||||
:param molecule: 化学式
|
:param molecule: 化学式
|
||||||
:return: 化学式的字典表示
|
:return: 化学式的字典表示
|
||||||
"""
|
"""
|
||||||
pretty_name = ''
|
|
||||||
if molecule[0].isdigit():
|
if molecule[0].isdigit():
|
||||||
coefficient = int(molecule[0])
|
coefficient = int(molecule[0])
|
||||||
pretty_name = molecule = molecule[1:]
|
pretty_name = molecule = molecule[1:]
|
||||||
else:
|
else:
|
||||||
coefficient = 1
|
coefficient = 1
|
||||||
pretty_name = molecule
|
pretty_name = molecule
|
||||||
# 以大写字母为分隔符,分割化学式
|
# 以大写字母和括号为分隔符,分割化学式
|
||||||
molecule = re.split(r'([A-Z][a-z]*)', molecule)
|
molecule = re.split('([A-Z][a-z]*|\(|\))', molecule)
|
||||||
molecule = [i for i in molecule if i != '']
|
molecule = [i for i in molecule if i != '']
|
||||||
# 将原子团提取出来单独处理
|
# 将原子团提取出来单独处理
|
||||||
atomic_clusters = []
|
atomic_clusters = []
|
||||||
for i in range(len(molecule)):
|
for i in range(len(molecule)):
|
||||||
if molecule[i] == '(':
|
if molecule[i] == '(':
|
||||||
j = i + 1
|
j = i + 1
|
||||||
while molecule[j][0] != ')':
|
# 当molecule内不包含右括号
|
||||||
|
while ')' not in molecule[j]:
|
||||||
j += 1
|
j += 1
|
||||||
if j == len(molecule):
|
if j == len(molecule):
|
||||||
raise ValueError('括号不匹配')
|
raise ValueError('括号不匹配')
|
||||||
for k in range(i, j + 1):
|
for k in range(i, j + 1):
|
||||||
atomic_clusters.append(molecule[k])
|
atomic_clusters.append(molecule[k])
|
||||||
|
if j + 1 < len(molecule) and molecule[j + 1].isdigit():
|
||||||
|
atomic_clusters.append(molecule[j + 1])
|
||||||
|
molecule[j + 1] = ''
|
||||||
for k in range(i, j + 1):
|
for k in range(i, j + 1):
|
||||||
molecule[k] = ''
|
molecule[k] = ''
|
||||||
# 如果出现单个数字,说明该数字是系数,将其追加到上一个原子/原子团(非空字符串)的后面
|
# 如果出现单个数字,说明该数字是系数,将其追加到上一个原子/原子团(非空字符串)的后面
|
||||||
|
@ -169,6 +181,7 @@ def format_molecule(molecule):
|
||||||
else:
|
else:
|
||||||
return molecule['pretty_name']
|
return molecule['pretty_name']
|
||||||
|
|
||||||
|
|
||||||
def format_equation(eq):
|
def format_equation(eq):
|
||||||
"""
|
"""
|
||||||
将化学方程式的字典表示转化为字符串,需要包含系数
|
将化学方程式的字典表示转化为字符串,需要包含系数
|
||||||
|
@ -180,3 +193,9 @@ def format_equation(eq):
|
||||||
left = [format_molecule(molecule) for molecule in left]
|
left = [format_molecule(molecule) for molecule in left]
|
||||||
right = [format_molecule(molecule) for molecule in right]
|
right = [format_molecule(molecule) for molecule in right]
|
||||||
return ' + '.join(left) + ' => ' + ' + '.join(right)
|
return ' + '.join(left) + ' => ' + ' + '.join(right)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
eq = input('测试parser:请输入分子式:')
|
||||||
|
parsed_eq = parse_molecule(eq)
|
||||||
|
print('解析结果:', parsed_eq)
|
||||||
|
|
Loading…
Reference in New Issue