Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sympy
- import re
- """
- Also btw this wont work with things like Si(SO4)2
- However if it is given a chemical compound like Na2SO4
- It will return a dict of element counts like {"Na":2, "S":1, "O":4}
- """
- def solver(eqtn):
- ELEMENT_CLAUSE = re.compile("([A-Z][a-z]?)([0-9]*)")
- def reformatter(equation):
- eqtin = equation.replace(' ', '|').replace("+", " + ")
- return eqtin
- def understand(compound):
- assert "(" not in compound, "This parser doesn't support subclauses"
- return {el: (int(num) if num else 1) for el, num in ELEMENT_CLAUSE.findall(compound)}
- #Here is the shitfuck starting
- lhs = eqtn.split(" = ")[0]
- lhs_strings = lhs.split(" + ")
- lhs_compounds = [understand(compound) for compound in lhs_strings]
- rhs = eqtn.split(" = ")[1]
- rhs_strings = rhs.split(" + ")
- rhs_compounds = [understand(compound) for compound in rhs_strings]
- # Get canonical list of elements
- els = sorted(set().union(*lhs_compounds, *rhs_compounds))
- els_index = dict(zip(els, range(len(els))))
- # Build matrix to solve
- w = len(lhs_compounds) + len(rhs_compounds)
- h = len(els)
- A = [[0] * w for _ in range(h)]
- # load with element coefficients
- for col, compound in enumerate(lhs_compounds):
- for el, num in compound.items():
- row = els_index[el]
- A[row][col] = num
- for col, compound in enumerate(rhs_compounds, len(lhs_compounds)):
- for el, num in compound.items():
- row = els_index[el]
- A[row][col] = -num # invert coefficients for RHS
- # Solve using Sympy for absolute-precision math
- A = sympy.Matrix(A)
- # find first basis vector == primary solution
- coeffs = A.nullspace()[0]
- # find the least common denominator, multiply through to convert to integer solution
- coeffs *= sympy.lcm([term.q for term in coeffs])
- # Display result
- lhs = reformatter("+".join(["{} {}".format(coeffs[i], s) for i, s in enumerate(lhs_strings)]))
- rhs = reformatter("+".join(["{} {}".format(coeffs[i], s) for i, s in enumerate(rhs_strings, len(lhs_strings))]))
- return "{} = {}".format(lhs, rhs)
- formula = input("Input your chemical reaction: ")
- print(solver(formula))
Add Comment
Please, Sign In to add comment