Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def d(s):
- raw_input("----DEBUG----{0}".format(s))
- # Class Molecule:
- # elements: a dictionary of elements and their subscripts
- # count: the coefficient on the molecule
- class Molecule:
- class Atomic: # Represents a {Element}_{Subscript} structure (no coefficient)
- def __init__(self, el, sub):
- self.element = el
- self.subscript = sub
- def getElement(self):
- return self.element
- def getSubscript(self):
- return self.subscript
- def __init__(self):
- self.elements = dict()
- self.count = 1
- def __str__(self):
- ret = "{"+str(self.count)+"}"
- for el in self.elements:
- ret += "[{0}_{1}]".format(el,self.elements[el])
- return ret
- def getElementTotals(self):
- ret = dict()
- for el in self.elements.keys():
- ret[el] = self.elements[el] * self.count
- return ret
- def add(self, atomic):
- self.add(atomic.getElement(), atomic.getSubscript())
- def add(self, element, subscript):
- # if the molecule already contains this element, just increase the subscript
- if element in self.elements:
- self.elements[element] += subscript
- else: # otherwise, add the element and its subscript
- self.elements[element] = subscript
- def fold(self, mol):
- for el in mol.elements.keys():
- self.add(el, mol.elements[el] * mol.count)
- def getWord(s,i): # Returns a [isElem, token, lastIndex] list from a string s starting at index i
- if i >= len(s) or i < 0:
- return Nothing
- ret = s[i]
- isElem = ret.isalpha()
- i += 1
- while i < len(s):
- #d(str((isDigit, s[i], i, ret)))
- if not isElem:
- if s[i].isdigit():
- ret += s[i]
- else:
- return [isElem,ret,i]
- else:
- if s[i].isupper() or s[i].isdigit():
- return [isElem,ret,i]
- else:
- ret += s[i]
- i = i + 1
- return [isElem,ret,i]
- def tokenize(s):
- l = list()
- i = 0
- while i < len(s):
- newi = getWord(s, i)
- i = newi[2]
- l.append(newi)
- return l
- def standardize(tokens): # inserts implicit subscripts and puts them into ints
- if tokens[0][0]:
- tokens.insert(0,[False,1,0])
- i = 0
- while i < len(tokens):
- if tokens[i][0]: # if this is an element
- if i+1 == len(tokens):
- tokens.append([False,1,tokens[i][2]])
- elif tokens[i+1][0]: # if the next is also an element (ie not a subscript)
- tokens.insert(i+1,[False,1,tokens[i][2]])
- else: # if this was a subscript
- tokens[i][1] = int(tokens[i][1])
- i = i + 1
- return tokens
- def molecularize(tokens):
- mol = Molecule()
- mol.count = tokens[0][1]
- for i in range(1,len(tokens),2):
- mol.add(tokens[i][1], tokens[i+1][1])
- return mol
- def pl(l):
- for n in l:
- print n
- def getmol(s): # returns a Molecule from a string
- tok = tokenize(s)
- standardize(tok)
- mol = molecularize(tok)
- return mol
- def fission(s): # splits a string 'A=B' up into molecular components [[A1,A2,...],[B1,B2,...]
- lnr = s.split('=')
- if len(lnr) != 2:
- print 'error'
- return Nothing
- left = lnr[0].split('+')
- right = lnr[1].split('+')
- lmols = list()
- for m in left:
- lmols.append(getmol(m))
- rmols = list()
- for m in right:
- rmols.append(getmol(m))
- return [lmols,rmols]
- def fusion(lnr): # takes the output of fission and folds them for balancing
- if len(lnr) != 2:
- print 'error'
- return Nothing
- for side in lnr:
- for i in range(1,len(side)):
- side[0].fold(side[i])
- return [lnr[0][0], lnr[1][0]]
- def balance(s):
- print "fission"
- fis = fission(s)
- for side in fis:
- pl(side)
- print "fusion"
- fus = fusion(fis)
- pl(fus)
- l = fus[0].getElementTotals()
- r = fus[1].getElementTotals()
- return l == r
- print balance("H2O+H2O=2H2O")
- # to do the function multiple times, map(balance, input.split())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement