-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReflektion.py
More file actions
executable file
·285 lines (250 loc) · 8.73 KB
/
Reflektion.py
File metadata and controls
executable file
·285 lines (250 loc) · 8.73 KB
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#Applicant Name: Leo Zhao
#University: University of Waterloo
#Purpose: Simulate 4 users buying stocks at the same time. We can retrieve the top trades at anytime.
#Utilizing global variable that is necesary in multiple functions to reduce passing of parameters
global concurrentUsers
global commands
global commandsCounter
global userCount
global maxEntry
global tradeLog
global nodesCount
global topCounter
maxEntry = 0
userCount = 0
nodesCount = 0
commandsCounter = 0
topCounter = 0
concurrentUsers = {}
commandList = {}
#Initializing the tree from the previous day record.
#Could be combined with the insertAVL() but since we know the previous record has been sorted we might as well take advantage
class TreeNode:
def MinimumBST(self, value, parent = None, leftChild = None, rightChild = None, startIndex = None, endIndex = None, trades = None, childType = None):
global nodesCount
self.value = value
self.leftChild = leftChild
self.rightChild = rightChild
self.parent = parent
self.childNodes = 0
self.childType = childType
#Creating a BST from a sorted array
if (startIndex is not None):
if(startIndex>endIndex):
return
currentIndex = int((startIndex+endIndex)/2)
self.value = int (trades[currentIndex].replace("\n",""))
self.updateChildNodes()
nodesCount += 1
if(self.value <= int (trades[(currentIndex+1+endIndex)/2].replace("\n",""))):
childR = TreeNode()
self.rightChild = childR.MinimumBST (0, self, None, None, currentIndex+1, endIndex, trades, -1)
if(self.value > int (trades[(currentIndex-1+startIndex)/2].replace("\n",""))):
childL = TreeNode()
self.leftChild = childL.MinimumBST (0, self, None, None, startIndex, currentIndex-1, trades, 1)
return self
return self
#Recursively update the childNodes counter
#A right child node counts as -1 and a left child node counts as +1. A node with childNodes counter between -1 and 1 is balanced
def updateChildNodes(self):
if(self.parent is not None):
if (self.childType == 1):
self.parent.childNodes += 1
elif (self.childType == -1):
self.parent.childNodes -= 1
self.parent.updateChildNodes()
def hasLeftchild (self):
return self.leftChild
def hasrightChild (self):
return self.rightChild
def isLeftChild(self):
if(self.parent.leftChild is not None):
if (self.parent is not None and self.parent.leftChild.value == self.value):
return True
else:
return False
def isRightChild(self):
if(self.parent.rightChild is not None):
if (self.parent is not None and self.parent.rightChild.value == self.value):
return True
else:
return False
def isRoot (self):
if (self.parent is None):
return True
else:
return False
#Imports the previous day data from file
def ImportHistory (inputFile):
global tradeLog
with open(inputFile) as f:
trades = []
trades = f.readlines()
Tree = TreeNode ()
tradeLog = Tree.MinimumBST(0, None, None, None, 0, len(trades)-1, trades)
#Import current day data from file
def ImportCurrent (inputFile):
global userCount
global maxEntry
global concurrentUsers
with open(inputFile) as f:
concurrentUsers[userCount] = []
concurrentUsers[userCount] = f.readlines()
if (maxEntry < len(concurrentUsers[userCount])):
maxEntry = len(concurrentUsers[userCount])
userCount += 1
#Import commands from file
def ImportCommands(inputFile):
global commandList
with open(inputFile) as f:
commandList = f.readlines()
#Execute the commands read from the command file
def ReadCommands():
global commandList
global commandsCounter
global topCounter
stringBuffer = ""
if(commandsCounter<len(commandList)):
stringBuffer = commandList[commandsCounter].replace("\n","").replace("\r","").split()
if (len(stringBuffer)==0):
commandsCounter += 1
elif(len(stringBuffer)>0):
if (stringBuffer[0] != "end"):
if (int(stringBuffer[1]) <= nodesCount and int(stringBuffer[2]) <= int(stringBuffer[1])):
topCounter = int(stringBuffer[2])
retrieveTop (tradeLog)
commandsCounter += 1
#Success exit condition
elif (stringBuffer[0] == "end"):
print "Thank you for the consideration. The program has ended. Please check file 'file_3.txt' for output."
outputFile.close()
exit()
#Read the imported current day data from multiple file
#Every line from the current day data files are considered as a time frame
def LoadCurrent ():
global userCount
global maxEntry
global concurrentUsers
global tradeLog
global nodesCount
stringBuffer = ""
#interate through the time frames
for x in range (0, maxEntry):
#interate through the number of users
for y in range (0, userCount):
if (len(concurrentUsers[y]) > x):
stringBuffer = concurrentUsers[y][x].replace("\r","")
stringBuffer = concurrentUsers[y][x].replace("\n","")
if(stringBuffer != "" and stringBuffer != "\r"):
nodesCount += 1
insertAVL (int (stringBuffer), tradeLog)
#Check if the command can be executed every time frame
ReadCommands()
#Insert node via AVL method
def insertAVL(newTrade, node):
if (newTrade < int(node.value)):
if (node.hasLeftchild() is not None):
insertAVL(newTrade, node.leftChild)
else:
newNode = TreeNode ()
node.leftChild = newNode.MinimumBST(newTrade, node)
balanceTree (node.leftChild)
else:
if (node.hasrightChild() is not None):
insertAVL(newTrade, node.rightChild)
else:
newNode = TreeNode ()
node.rightChild = newNode.MinimumBST(newTrade, node)
balanceTree (node.rightChild)
#Check if the tree is balanced. If not balance
#A right child node counts as -1 and a left child node counts as +1. A node with childNodes counter between -1 and 1 is balanced
def balanceTree (node):
if (node.childNodes > 1 or node.childNodes < -1):
rebalanceTree(node)
return
if (node.parent is not None):
if (node.isLeftChild()):
node.parent.childNodes += 1
elif (node.isRightChild()):
node.parent.childNodes -= 1
if (node.parent.childNodes != 0):
balanceTree(node.parent)
#Rebalancing the tree
def rebalanceTree(node):
if (node.childNodes < 0):
if (node.rightChild.childNodes > 0):
rotateRight(node.rightChild)
rotateLeft(node)
else:
rotateLeft(node)
elif (node.childNodes > 0):
if (node.leftChild.childNodes < 0):
rotateLeft(node.leftChild)
rotateRight(node)
else:
rotateRight(node)
#Single and double rotation to the left combined into one method
def rotateLeft(rotationPoint):
global tradeLog
newRoot = rotationPoint.rightChild
rotationPoint.rightChild = newRoot.leftChild
if (newRoot.leftChild is not None):
newRoot.leftChild.parent = rotationPoint
newRoot.parent = rotationPoint.parent
if (rotationPoint.isRoot()):
tradeLog = newRoot
else:
if (rotationPoint.isLeftChild()):
rotationPoint.parent.leftChild = newRoot
else:
rotationPoint.parent.rightChild = newRoot
newRoot.leftChild = rotationPoint
rotationPoint.parent = newRoot
rotationPoint.childNodes = rotationPoint.childNodes + 1 - min(newRoot.childNodes, 0)
newRoot.childNodes = newRoot.childNodes + 1 + max(rotationPoint.childNodes, 0)
#Single and double rotation to the right combined into one method
def rotateRight(rotationPoint):
global tradeLog
newRoot = rotationPoint.leftChild
rotationPoint.leftChild = newRoot.rightChild
if (newRoot.rightChild is not None):
newRoot.rightChild.parent = rotationPoint
newRoot.parent = rotationPoint.parent
if (rotationPoint.isRoot()):
tradeLog = newRoot
else:
if (rotationPoint.isRightChild()):
rotationPoint.parent.rightChild = newRoot
else:
rotationPoint.parent.leftChild = newRoot
newRoot.rightChild = rotationPoint
rotationPoint.parent = newRoot
rotationPoint.childNodes = rotationPoint.childNodes - 1 - max(newRoot.childNodes, 0)
newRoot.childNodes = newRoot.childNodes - 1 + min(rotationPoint.childNodes, 0)
#Print to outputfile
def printer(printNode):
outputFile.write (str(printNode)+" ")
#Traverse through the tree in reverse of in order traversal
def retrieveTop(node, printNode = printer):
global topCounter
if (node is not None):
retrieveTop(node.rightChild, printNode)
if (topCounter > 0):
printNode(node.value)
topCounter -= 1
if (topCounter == 0):
topCounter -= 1
outputFile.write ("\n")
retrieveTop(node.leftChild, printNode)
#Loading files
outputFile = open ("file_3.txt", "w")
ImportHistory ("file_1.txt")
ImportCurrent ("file_4.txt")
ImportCurrent ("file_5.txt")
ImportCurrent ("file_6.txt")
ImportCurrent ("file_7.txt")
ImportCommands ("file_2.txt")
LoadCurrent()
#Erroneous exit
print "An Error has occured. please makes sure the top requests could be fulfilled."
outputFile.close()