View difference between Paste ID: RfFiHBHy and wa1S6aCp
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.add(el, mol.elements[el])
39+
40
		else: # otherwise, add the element and its subscript
41
			self.elements[element] = subscript
42
	
43
	def fold(self, mol):
44
		for el in mol.elements.keys():
45
			self.add(el, mol.elements[el] * mol.count)
46
47
def getWord(s,i): # Returns a [isElem, token, lastIndex] list from a string s starting at index i
48
	if i >= len(s) or i < 0:
49
		return Nothing
50
	
51
	ret = s[i]
52
	isElem = ret.isalpha()
53
	i += 1
54
	while i < len(s):
55
		#d(str((isDigit, s[i], i, ret)))
56
		if not isElem:
57
			if s[i].isdigit():
58
				ret += s[i]
59
			else:
60
				return [isElem,ret,i]
61
		else:
62
			if s[i].isupper() or s[i].isdigit():
63
				return [isElem,ret,i]
64
			else:
65
				ret += s[i]
66
		i = i + 1
67
	return [isElem,ret,i]
68
69
def tokenize(s):
70
	l = list()
71
	i = 0
72
	while i < len(s):
73
		newi = getWord(s, i)
74
		i = newi[2]
75
		l.append(newi)
76
	return l
77
78
def standardize(tokens): # inserts implicit subscripts and puts them into ints
79
	if tokens[0][0]:
80
		tokens.insert(0,[False,1,0])
81
	i = 0
82
	while i < len(tokens):
83
		if tokens[i][0]: # if this is an element
84
			if i+1 == len(tokens):
85
				tokens.append([False,1,tokens[i][2]])
86
			elif tokens[i+1][0]: # if the next is also an element (ie not a subscript)
87
				tokens.insert(i+1,[False,1,tokens[i][2]])
88
		else: # if this was a subscript
89
			tokens[i][1] = int(tokens[i][1])
90
		i = i + 1
91
	
92
	return tokens
93
94
def molecularize(tokens):
95
	mol = Molecule()
96
	mol.count = tokens[0][1]
97
	for i in range(1,len(tokens),2):
98
		mol.add(tokens[i][1], tokens[i+1][1])
99
	return mol
100
101
def pl(l):
102
	for n in l:
103
		print n
104
105
def getmol(s): # returns a Molecule from a string
106-
	return [left,right]
106+
	tok = tokenize(s)
107
	standardize(tok)
108
	mol = molecularize(tok)
109-
# NaOH = "NaOH"
109+
110-
# Na2O3H = "Na2O3HC"
110+
111-
# 
111+
112-
# t_NaOH = tokenize(NaOH)
112+
113-
# standardize(t_NaOH)
113+
114-
# m_NaOH = molecularize(t_NaOH)
114+
115-
# 
115+
116-
# print "Molecule: {}".format(m_NaOH)
116+
117-
# 
117+
118-
# 
118+
119-
# t_Na2O3H = tokenize(Na2O3H)
119+
	lmols = list()
120-
# standardize(t_Na2O3H)
120+
	for m in left:
121-
# m_Na2O3H = molecularize(t_Na2O3H)
121+
		lmols.append(getmol(m))
122-
# 
122+
123-
# print "Molecule: {}".format(m_Na2O3H)
123+
	rmols = list()
124-
# 
124+
	for m in right:
125-
# m_NaOH.fold(m_Na2O3H)
125+
		rmols.append(getmol(m))
126-
# 
126+
127-
# print "Molecule: {}".format(m_NaOH)
127+
	return [lmols,rmols]
128
129-
print fission("H2O+NaOH=C6H12O6")
129+
def fusion(lnr): # takes the output of fission and folds them for balancing
130
	if len(lnr) != 2:
131-
# to do the function multiple times, map(balance, sequence_of_split_tokens)
131+
132
		return Nothing
133
	
134
	for side in lnr:
135
		for i in range(1,len(side)):
136
			side[0].fold(side[i])
137
	
138
	return [lnr[0][0], lnr[1][0]]
139
	
140
def balance(s):
141
	print "fission"
142
	fis = fission(s)
143
	for side in fis:
144
		pl(side)
145
	print "fusion"
146
	fus = fusion(fis)
147
	pl(fus)
148
	
149
	l = fus[0].getElementTotals()
150
	r = fus[1].getElementTotals()
151
	
152
	return l == r
153
154
print balance("H2O+H2O=2H2O")
155
# to do the function multiple times, map(balance, input.split())