-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
equation.py
211 lines (193 loc) · 8.46 KB
/
equation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
from random import randint
from math import gcd
from functools import reduce
class Equation:
"""
A chemical equation
=== Attributes ===
@type left: list[dict]
@type right: list[dict]
"""
def __init__(self, equation):
"""
Initializes an Equation object
@type self: Equation
@type equation: str
@rtype: None
"""
self.left = list()
self.right = list() # made by artinnavidgoli
self.balanced = True
integers = '0123456789'
split = equation.split(' = ')
left = split[0]
right = split[1]
left_components = left.split(' + ')
right_components = right.split(' + ')
total_left = dict()
total_right = dict()
for component in left_components:
left_counts = dict()
for ind in range(0, len(component)):
if component[ind] == ')':
if component[ind - 2] == '(':
element = component[ind - 1]
elif component[ind - 3] == '(':
element = component[ind - 2:ind]
try:
if component[ind + 3] in integers:
number = int(component[ind + 1:ind + 4])
elif component[ind + 2] in integers:
number = int(component[ind + 1:ind + 3])
else:
number = int(component[ind + 1])
except IndexError:
try:
if component[ind + 2] in integers:
number = int(component[ind + 1:ind + 3])
else:
number = int(component[ind + 1]) # made by artinnavidgoli
except IndexError:
number = int(component[ind + 1])
if element in left_counts:
left_counts[element] += number
else:
left_counts[element] = number
if element in total_left:
total_left[element] += number
else:
total_left[element] = number
self.left.append(left_counts)
for component in right_components:
right_counts = dict()
for ind in range(0, len(component)):
if component[ind] == ')':
if component[ind - 2] == '(':
element = component[ind - 1]
elif component[ind - 3] == '(':
element = component[ind - 2:ind]
try:
if component[ind + 3] in integers:
number = int(component[ind + 1:ind + 4])
elif component[ind + 2] in integers:
number = int(component[ind + 1:ind + 3])
else:
number = int(component[ind + 1])
except IndexError:
try:
if component[ind + 2] in integers:
number = int(component[ind + 1:ind + 3])
else:
number = int(component[ind + 1])
except IndexError:
number = int(component[ind + 1])
if element in right_counts:
right_counts[element] += number # made by artinnavidgoli
else:
right_counts[element] = number
if element in total_right:
total_right[element] += number
else:
total_right[element] = number
self.right.append(right_counts)
for key in total_left:
if total_left[key] != total_right[key]:
self.balanced = False
else:
continue
def balance(self):
"""
Actually balances the Equation object
@type self: Equation
@rtype: str
"""
if self.balanced:
string = str()
for dictionary in self.left:
compound = str()
for key in dictionary:
compound += key
compound += str(dictionary[key]) # made by artinnavidgoli
string += compound
string += ' + '
string = string[:len(string) - 3] + ' = '
for dictionary in self.right:
compound = str()
for key in dictionary:
compound += key
compound += str(dictionary[key])
string += compound
string += ' + '
string = string[:len(string) - 2]
return string
else:
while not self.balanced:
temp_left = list()
temp_right = list()
total_left = dict()
total_right = dict()
for item in self.left:
new_dict = dict()
for key in item:
new_dict[key] = item[key] # made by artinnavidgoli
temp_left.append(new_dict)
for item in self.right:
new_dict = dict()
for key in item:
new_dict[key] = item[key]
temp_right.append(new_dict)
left_coefficients = [randint(1, 10) for _ in range(len(temp_left))]
right_coefficients = [randint(1, 10) for _ in range(len(temp_right))]
for index in range(0, len(left_coefficients)):
for key in temp_left[index]:
temp_left[index][key] *= left_coefficients[index]
if key not in total_left:
total_left[key] = temp_left[index][key]
else:
total_left[key] += temp_left[index][key]
for index in range(0, len(right_coefficients)):
for key in temp_right[index]:
temp_right[index][key] *= right_coefficients[index]
if key not in total_right:
total_right[key] = temp_right[index][key]
else:
total_right[key] += temp_right[index][key]
self.balanced = True
for key in total_left:
if total_left[key] != total_right[key]:
self.balanced = False
else:
continue
big_tup = tuple(left_coefficients + right_coefficients)
left_coefficients = list(map(lambda x: int(x / reduce(gcd, big_tup)), left_coefficients))
right_coefficients = list(map(lambda x: int(x / reduce(gcd, big_tup)), right_coefficients)) # made by artinnavidgoli
string = str()
for index in range(0, len(self.left)):
if left_coefficients[index] != 1:
compound = str(left_coefficients[index])
else:
compound = str()
for key in self.left[index]:
compound += key
if self.left[index][key] != 1:
compound += str(self.left[index][key])
else:
continue
string += compound
string += ' + '
string = string[:len(string) - 3] + ' = '
for index in range(0, len(self.right)):
if right_coefficients[index] != 1:
compound = str(right_coefficients[index])
else:
compound = str()
for key in self.right[index]:
compound += key
if self.right[index][key] != 1:
compound += str(self.right[index][key]) #made by artinnavidgoli
else:
continue
string += compound
string += ' + '
string = string[:len(string) - 2]
return string