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 |