SHOW:
|
|
- or go back to the newest paste.
| 1 | def d(s): | |
| 2 | raw_input("----DEBUG----{0}".format(s))
| |
| 3 | ||
| 4 | # Class Molecule: | |
| 5 | # elements: a dictionary of elements and their subscripts | |
| 6 | # count: the coefficient on the molecule | |
| 7 | class Molecule: | |
| 8 | class Atomic: # Represents a {Element}_{Subscript} structure (no coefficient)
| |
| 9 | def __init__(self, el, sub): | |
| 10 | self.element = el | |
| 11 | self.subscript = sub | |
| 12 | def getElement(self): | |
| 13 | return self.element | |
| 14 | def getSubscript(self): | |
| 15 | return self.subscript | |
| 16 | ||
| 17 | def __init__(self): | |
| 18 | self.elements = dict() | |
| 19 | self.count = 1 | |
| 20 | ||
| 21 | def __str__(self): | |
| 22 | ret = "{"+str(self.count)+"}"
| |
| 23 | for el in self.elements: | |
| 24 | ret += "[{0}_{1}]".format(el,self.elements[el])
| |
| 25 | return ret | |
| 26 | ||
| 27 | def getElementTotals(self): | |
| 28 | ret = dict() | |
| 29 | for el in self.elements.keys(): | |
| 30 | ret[el] = self.elements[el] * self.count | |
| 31 | return ret | |
| 32 | ||
| 33 | def add(self, atomic): | |
| 34 | self.add(atomic.getElement(), atomic.getSubscript()) | |
| 35 | ||
| 36 | def add(self, element, subscript): | |
| 37 | # if the molecule already contains this element, just increase the subscript | |
| 38 | if element in self.elements: | |
| 39 | self.elements[element] += subscript | |
| 40 | else: # otherwise, add the element and its subscript | |
| 41 | self.elements[element] = subscript | |
| 42 | ||
| 43 | def fold(self, mol): | |
| 44 | self.elements = self.getElementTotals() | |
| 45 | self.count = 1 | |
| 46 | for el in mol.elements.keys(): | |
| 47 | self.add(el, mol.elements[el] * mol.count) | |
| 48 | ||
| 49 | def getWord(s,i): # Returns a [isElem, token, lastIndex] list from a string s starting at index i | |
| 50 | if i >= len(s) or i < 0: | |
| 51 | return Nothing | |
| 52 | ||
| 53 | ret = s[i] | |
| 54 | isElem = ret.isalpha() | |
| 55 | i += 1 | |
| 56 | while i < len(s): | |
| 57 | #d(str((isDigit, s[i], i, ret))) | |
| 58 | if not isElem: | |
| 59 | if s[i].isdigit(): | |
| 60 | ret += s[i] | |
| 61 | else: | |
| 62 | return [isElem,ret,i] | |
| 63 | else: | |
| 64 | if s[i].isupper() or s[i].isdigit(): | |
| 65 | return [isElem,ret,i] | |
| 66 | else: | |
| 67 | ret += s[i] | |
| 68 | i = i + 1 | |
| 69 | return [isElem,ret,i] | |
| 70 | ||
| 71 | def tokenize(s): | |
| 72 | l = list() | |
| 73 | i = 0 | |
| 74 | while i < len(s): | |
| 75 | newi = getWord(s, i) | |
| 76 | i = newi[2] | |
| 77 | l.append(newi) | |
| 78 | return l | |
| 79 | ||
| 80 | def standardize(tokens): # inserts implicit subscripts and puts them into ints | |
| 81 | if tokens[0][0]: | |
| 82 | tokens.insert(0,[False,1,0]) | |
| 83 | i = 0 | |
| 84 | while i < len(tokens): | |
| 85 | if tokens[i][0]: # if this is an element | |
| 86 | if i+1 == len(tokens): | |
| 87 | tokens.append([False,1,tokens[i][2]]) | |
| 88 | elif tokens[i+1][0]: # if the next is also an element (ie not a subscript) | |
| 89 | tokens.insert(i+1,[False,1,tokens[i][2]]) | |
| 90 | else: # if this was a subscript | |
| 91 | tokens[i][1] = int(tokens[i][1]) | |
| 92 | i = i + 1 | |
| 93 | ||
| 94 | return tokens | |
| 95 | ||
| 96 | def molecularize(tokens): | |
| 97 | mol = Molecule() | |
| 98 | mol.count = tokens[0][1] | |
| 99 | for i in range(1,len(tokens),2): | |
| 100 | mol.add(tokens[i][1], tokens[i+1][1]) | |
| 101 | return mol | |
| 102 | ||
| 103 | - | print n |
| 103 | + | |
| 104 | for n in l: | |
| 105 | d(n) | |
| 106 | ||
| 107 | def getmol(s): # returns a Molecule from a string | |
| 108 | tok = tokenize(s) | |
| 109 | standardize(tok) | |
| 110 | mol = molecularize(tok) | |
| 111 | return mol | |
| 112 | ||
| 113 | def fission(s): # splits a string 'A=B' up into molecular components [[A1,A2,...],[B1,B2,...] | |
| 114 | lnr = s.split('=')
| |
| 115 | if len(lnr) != 2: | |
| 116 | print 'error' | |
| 117 | return Nothing | |
| 118 | left = lnr[0].split('+')
| |
| 119 | right = lnr[1].split('+')
| |
| 120 | ||
| 121 | lmols = list() | |
| 122 | for m in left: | |
| 123 | lmols.append(getmol(m)) | |
| 124 | ||
| 125 | rmols = list() | |
| 126 | for m in right: | |
| 127 | rmols.append(getmol(m)) | |
| 128 | ||
| 129 | return [lmols,rmols] | |
| 130 | ||
| 131 | def fusion(lnr): # takes the output of fission and folds them for balancing | |
| 132 | if len(lnr) != 2: | |
| 133 | print 'error' | |
| 134 | return Nothing | |
| 135 | ||
| 136 | for side in lnr: | |
| 137 | for i in range(1,len(side)): | |
| 138 | side[0].fold(side[i]) | |
| 139 | ||
| 140 | return [lnr[0][0], lnr[1][0]] | |
| 141 | - | print "fission" |
| 141 | + | |
| 142 | - | fis = fission(s) |
| 142 | + | |
| 143 | - | for side in fis: |
| 143 | + | # split up the string into lists of left and right molecules |
| 144 | - | pl(side) |
| 144 | + | # add the sides together element-wise, taking coefficients into consideration |
| 145 | - | print "fusion" |
| 145 | + | f = fusion(fission(s)) |
| 146 | - | fus = fusion(fis) |
| 146 | + | |
| 147 | - | pl(fus) |
| 147 | + | # get element totals |
| 148 | l = f[0].getElementTotals() | |
| 149 | - | l = fus[0].getElementTotals() |
| 149 | + | r = f[1].getElementTotals() |
| 150 | - | r = fus[1].getElementTotals() |
| 150 | + | |
| 151 | if l == r: | |
| 152 | - | return l == r |
| 152 | + | print "{} balances".format(s)
|
| 153 | else: | |
| 154 | - | print balance("H2O+H2O=2H2O")
|
| 154 | + | print "{} does not balance".format(s)
|
| 155 | - | # to do the function multiple times, map(balance, input.split()) |
| 155 | + | |
| 156 | def Problem3(s): | |
| 157 | map(balance, s.split()) | |
| 158 | ||
| 159 | Problem3("6H2O+6CO2=6O2+C6H12O6 2Na+2H2O=2NaOH+H2 C6H12O6=3C2H2+3O") |