Reputation: 131
I am trying to implement this class and I am having trouble with the getPostFix method. I don't understand how to fix the error that I am getting.
This is the str method in the class just for reference.
# Returns the string representation of the Calc.
def __str__(self):
theCalc = ""
theCalc += 'Input is: ' + self.getInput() + '\n'
theCalc += 'Postfix input is: ' + self.getPostFix() + '\n'
theCalc += 'Value is: ' + str(self.evaluate()) + '\n'
return theCalc
This is where I am getting the error.
def getPostFix(self):
result = ""
# stack used to create postfix string
self.stack = MyStack()
input_string = self.getInput()
input_string_split = [x for x in re.split("(\d*\.?\d*)", input_string) if x != '']
numbers = re.findall('([0-9.]+)', input_string_split, re.DOTALL)
for i in input_string_split:
if i in numbers:
result += i
elif isOperator(i):
while True:
topItem = self.stack.getTop()
if self.stack.size == 0 or topItem == '(':
self.stack.push(i)
break
else:
precedence_i = getPrecedence(i)
precedence_topItem = getPrecedence(topItem)
if precedence_i > precedence_topItem:
self.stack.push(i)
break
else:
ipop = self.stack.pop()
result += ipop if ipop else ""
#result += self.stack.pop()
elif i == '(':
self.stack.push(i)
elif i == ')':
ipop = self.stack.pop()
while ipop != '(':
result += ipop if ipop else ""
ipop = self.stack.pop()
elif i == '=':
ipop = self.stack.pop()
result += ipop if ipop else ""
#result += self.stack.pop()
while not self.stack.size == 0:
ipop = self.stack.pop()
result += ipop if ipop else ""
return result
And here is the error. It says it's expecting a string, but isn't input_string_split a list of strings? I don't understand how to fix it.
Traceback (most recent call last):
File "xxx", line 9, in <module>
print(calc)
File "xxx", line 23, in __str__
theCalc += 'Postfix input is: ' + self.getPostFix() + '\n'
File "xxx", line 50, in getPostFix
numbers = re.findall('([0-9.]+)', input_string_split, re.DOTALL)
File "/usr/local/Cellar/[email protected]/3.9.2_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/re.py", line 241, in findall
return _compile(pattern, flags).findall(string)
TypeError: expected string or bytes-like object
I am updating to show my attempt at using @Xinthral's answer below. I added a helper function:
def isOperand(c):
number = re.search('([0-9.]+)', c)
if number != None:
return True
else:
return False
so now the if statement in the for loop is:
if isOperand(i):
result += (i + ' ')
But I get the output below which indicates to me that the rest of the for loop is not being executed. That is, it is not iterating through the list and finding operators or parentheses etc.
Input is: 3.2+.4*5.67/6.145=
Postfix input is: 3.2 .4 5.67 6.145
Value is: None
Input is: 11.897/3.4+9.2-0.4*6.9/12.6-16.7=
Postfix input is: 11.897 3.4 9.2 0.4 6.9 12.6 16.7
Value is: None
Input is: 234+34*65=
Postfix input is: 234 34 65
Value is: None
Upvotes: 0
Views: 949
Reputation: 437
The following should help, I think the logic is just out of order. Your for
loop is already going over the whole 'input_string_split', so check each line would be checked during the loop. Hopefully this helps, let me know.
Before:
input_string_split = [x for x in re.split("(\d*\.?\d*)", input_string) if x != '']
numbers = re.findall('([0-9.]+)', input_string_split, re.DOTALL)
for i in input_string_split:
if i in numbers:
result += i
After:
input_string_split = [x for x in re.split("(\d*\.?\d*)", input_string) if x != '']
numbers = list()
for i in input_string_split:
number = re.search('([0-9.]+)', i)
if number != None:
numbers.append(i)
result += i
Upvotes: 1