Chemical equations balancer (Python)
From LiteratePrograms
This program is a code dump.
Code dumps are articles with little or no documentation or rearrangement of code. Please help to turn it into a literate program. Also make sure that the source of this code does consent to release it under the MIT or public domain license.
This program is under development.
Please help to debug it. When debugging
is complete, remove the {{develop}} tag.
#! /usr/bin/env python class Equ: def __init__(self): self.Eq = [[], []] self.Atoms = set() self.LS = 0 self.PS = 1 def addMolek(self, molek, side): self.Atoms = self.Atoms.union(molek.keys()) self.Eq[side].append([molek, 1]) return True def countAtom(self, atom): cl, cp = (None, None) for xat in self.Eq: count = 0 for mlk in xat: count += mlk[0].get(atom, 0) if cl == None: cl = count else: cp = count return (cl, cp) def multiRci(self, atom, nmbrs = (1, 1)): ls, ps = nmbrs print nmbrs # print ls, ps for xsd in xrange(len(self.Eq)): if xsd == self.LS: mtp = ls else: mtp = ps for xmolek in xrange(len(self.Eq[xsd])): if self.Eq[xsd][xmolek][0].get(atom, 0) != 0: for xother in self.Eq[xsd][xmolek][0].keys(): self.Eq[xsd][xmolek][0][xother] *= mtp self.Eq[xsd][xmolek][1] *= mtp return True def isEq(self): a = [] for at in self.Atoms: ls, ps = self.countAtom(at) print 'atom: ', at, ' left: ', ls, ' right: ', ps if ls != ps: a.append([at, (ls, ps)]) else: if len(a) == 0: return True else: print 'vracim: ', a, '\n\n' return a def mkEq(self): at = self.isEq() if at == True: return True else: for dsf in xrange(2): # hack, works only with 02 + H2 -> H20 reaction at = self.isEq() mn = ['',(float("infinity"), float("infinity"))] for at in at: if nsd(mn[1]) > nsd(at[1]): mn[1] = at[1] mn[0] = at[0] print mn print nsn(mn[1]), ' / ', (mn[1][0]), ' , ', nsn(mn[1]), ' / ', (mn[1][1]) self.multiRci(mn[0], (nsn(mn[1])/(mn[1][0]), nsn(mn[1])/(mn[1][1]))) def nsn((first, second)): return (first * second) / nsd((first, second)) def nsd((first, second)): if first == float("infinity") or second == float("infinity"): return float("infinity") if second == 0: return first return nsd((second, first%second)) rce = Equ() rce.addMolek(dict(H=2, O=0), rce.LS) rce.addMolek(dict(H=0, O=2), rce.LS) rce.addMolek(dict(H=2, O=1), rce.PS) print rce.Atoms rce.mkEq()
Download code |