raise ElementDoesNotExist stack.exceptions.ElementDoesNotExist - python

I have a problem with my RPN calculator:
def calculate_onp(onp):
from stack.stack import Stack
OPERATORS = ['+', '-', '*', '/']
s = Stack()
lista = onp.split(" ")
index = None
for i in range(1, len(onp)):
index = i - 1
if lista[index] in OPERATORS:
if lista[index] == OPERATORS[0]:
num1 = s.pop()
num2 = s.pop()
wyn = int(num1) + int(num2)
s.push(wyn)
elif lista[index] == OPERATORS[1]:
num1 = s.pop()
num2 = s.pop()
wyn = int(num1) - int(num2)
s.push(wyn)
elif lista[index] == OPERATORS[2]:
num1 = s.pop()
num2 = s.pop()
wyn = int(num1) * int(num2)
s.push(wyn)
elif lista[index] == OPERATORS[3]:
num1 = s.pop()
num2 = s.pop()
wyn = int(num1) / int(num2)
s.push(wyn)
else:
return 'ERROR'
else:
s.push(lista[index])
return int(s.pop())
I added a stack implementation to this:
from stack.exceptions import ElementDoesNotExist
class Stack(object):
def __init__(self):
self.stack = []
def __len__(self):
return len(self.stack)
def push(self, s):
return self.stack.append(s)
def pop(self):
if len(self.stack) == 0:
raise ElementDoesNotExist
else:
return self.stack.pop()
def show_list(self):
print(self.stack)
And exceptions:
for stack:
class ElementDoesNotExist(Exception):
pass
for rpn:
class OnpException(Exception):
pass
class OnpMissingOperationArgument(OnpException):
pass
class OnpMissingNumericArgument(OnpException):
pass
After running this:
File "/home/maciek/PycharmProjects/Calc/stack/stack.py", line 16, in pop
raise ElementDoesNotExist
stack.exceptions.ElementDoesNotExist
What's wrong?

your pop function has called to a function named len(self.stack). But It doesn't exists. so try on Changing the name def __len__(self): to def len(self):

Related

how to invoke a function in a Python app which has multiple files

I have two or three files in Python for s-expression. But I am not able to invoke the function to calulate the result of s-expression as I am not sure which function to invoke.
I have four files here:
1st file: calc.py
import sys
from parse import *
from expr import *
from calculator import *
def main():
if len(sys.argv)<2:
print('No Input!')
return
expr_list = ParseInput(sys.argv[1]).parse_to_list()
expression = Expression(expr_list)
if not expression.check_validation():
print('Not Valid Input!')
return
calculator = Calculator()
print(calculator.calculate(expression))
if __name__ == '__main__':
main()
2nd file: expr.py
class Expression(object):
def __init__(self, expr_list=None):
self.__expression = expr_list
def get_subexprs(self, expr_list):
res = []
i = 2
while i < len(expr_list)-1:
l = self.count_subexpr_length(expr_list, i)
res.append(expr_list[i:i+l])
i += l
return res
def count_subexpr_length(self, expr_list, i):
j = i+1
if expr_list[i] == '(':
count = 1
while count!= 0 and j<len(expr_list):
if expr_list[j] == ')':
count -= 1
if expr_list[j] == '(':
count += 1
j += 1
return j-i
def check_validation(self):
return self.is_valid(self.__expression)
def is_valid(self, expr_list):
if not expr_list:
return False
if len(expr_list)==1:
return self.is_integer(expr_list)
return self.is_func(expr_list)
def is_func(self, expr_list):
if len(expr_list) < 4:
return False
if expr_list[0] != '(' or expr_list[-1] != ')':
return False
if expr_list[1] not in ['add', 'multiply']:
return False
count = 0
for char in expr_list:
if char == '(':
count += 1
if char == ')':
count -=1
if count <0 :
return False
if count != 0 :
return False
for subexpr in self.get_subexprs(expr_list):
if not self.is_valid(subexpr):
return False
return True
def is_integer(self, expr_list):
return expr_list[0].isdigit()
def get_length(self):
return len(self.__expression)
def get_int(self):
if len(self.__expression) == 1:
return int(self.__expression[0])
def get_operator(self):
if len(self.__expression) > 1 :
return self.__expression[1]
def get_exprlist(self):
return self.__expression
3rd file: parse.py
class ParseInput(object):
def __init__(self, input_string=''):
self.input_string = input_string
def parse_to_list(self):
if self.input_string == '':
print('No Valid Input!')
return None
newString = ''
for char in self.input_string:
if char == '(':
newString += char + ' '
elif char == ')':
newString += ' ' + char
else:
newString += char
return newString.split()
4th file:calculator.py
from expr import *
class Calculator(object):
def __init__(self):
pass
def calculate(self, expression):
return self.calc_expression(expression)
def calc_expression(self, expression):
if not expression:
print('Sorry, you need to load expression!')
return
if expression.get_length() == 1:
return expression.get_int()
operator = expression.get_operator()
if operator == 'add':
return self.calc_add(expression)
if operator == 'multiply':
return self.calc_mul(expression)
def calc_add(self, expression):
base = 0
for subexpr in expression.get_subexprs(expression.get_exprlist()):
base += self.calc_expression(Expression(subexpr))
return base
def calc_mul(self, expression):
base = 1
for subexpr in expression.get_subexprs(expression.get_exprlist()):
base *= self.calc_expression(Expression(subexpr))
return base
The requirement says:
calc.py
Main file to run this calculator engine. Runs the engine in command line, with one valid argument as input.
Example:
$ python calc.py "123"
$ python calc.py "(add 12 12)"
However, I don't see any input expression taking input from the user in calc.py. Also I did the following in Python shell and it gives me the following error.
>>> import calc
>>> calc.py "(add 12 12)"
File "<stdin>", line 1
calc.py "(add 12 12)"
^^^^^^^^^^^^^
SyntaxError: invalid syntax
I want to know which function to invoke and how to invoke that in Python shell?
Update:
When I tried it in the command prompt, it gives me the following error:

AttributeError: 'Fraction' object has no attribute 'denom'

The below code is part of a fraction calculator, I want my code to go to my gcd function from my init so that I can pass the result as a gcd of the fraction to simplify it, I don't know if the below way is correct to do so.
class Fraction:
def __init__(self, num, denom) -> None:
self.num = self.denom = self.gcd()
if self.denom < 0:
self.denom = abs(self.denom)
self.num = -1*self.num
elif self.denom == 0:
raise ZeroDivisionError("cansnot divide by zero")
def gcd(self):
while self.denom != 0:
self.num,self.denom = self.denom,self.num%self.denom
return abs(self.num)
def get_fraction() -> Fraction:
while True:
num: str = input("Enter the numerator")
denom: str = input("Enter the denominator")
try:
a = int(num)
b = int(denom)
return Fraction(a, b)
except ValueError:
print("Enter valid numerator and denominator")
def compute(f1: Fraction, operator: str, f2: Fraction) -> None:
okay = True
if operator == '+':
result = f1.__add__(f2)
elif operator == '-':
result = f1.__sub__(f2)
elif operator == '*':
result = f1.__mul__(f2)
elif operator == '/':
result = f1.__truediv__(f2)
else:
print(operator, " is an unrecognized operator")
okay = False
if okay == True:
print(f"{f1} {operator} {f2} = {result}")
def main() -> None:
"""Main menu"""
print("Welcome to the Fraction Calculator! ")
while True:
print('Press Q to quit or any other key to start')
z = input("Start or Quit?")
if z == 'Q' or z == 'q':
exit()
else:
f1: Fraction = get_fraction()
operator: str = input("Operation (+, -, *, / , = , < , > , <= ,>= , != ): ")
f2: Fraction = get_fraction()
try:
compute(f1, operator, f2)
except ZeroDivisionError as e:
print(e)
if __name__ == '__main__':
main()
When I execute this I get the below error:
while self.denom != 0:
AttributeError: 'Fraction' object has no attribute 'denom'
I am not sure why this message is thrown.

global variable in python that doesn't make change in sub function

So why result doesn't change? result is global but it will return zero even when print(result) in def add() print correct answer.
number = int(input("enter your first num: "))
operation = input("enter your operation: ")
second_number = int(input("enter your second num: "))
def cal(num1,op,num2):
result = 0
def add():
result = num1+num2
print(result)
def multiply():
result = num1 * num2
def devide():
if not num2==0:
result = num1 / num2
else:
result = 'num2 can\'t be zero'
def default():
print("Incorrect option")
switch = {
'+':add,
'*':multiply,
'/':devide
}
switch.get(op,default)()
return result
print(cal(number,operation,second_number))
The global result was outside the scope.
number = int(input("enter your first num: "))
operation = input("enter your operation: ")
second_number = int(input("enter your second num: "))
def cal(num1, op, num2):
def add():
result = num1+num2
return result
def multiply():
result = num1 * num2
return result
def devide():
if not num2 == 0:
result = num1 / num2
return result
else:
result = 'num2 can\'t be zero'
return result
def default():
print("Incorrect option")
switch = {
'+': add,
'*': multiply,
'/': divide
}
return switch.get(op, default)()
print(cal(number, operation, second_number))
Python program that uses global
def method():
# Change "value" to mean the global variable.
# ... The assignment will be local without "global."
global value
value = 100
value = 0
method()
# The value has been changed to 100.
print(value)
100`
Python program that uses nonlocal
def method():
def method2():
# In nested method, reference nonlocal variable.
nonlocal value
value = 100
# Set local.
value = 10
method2()
# Local variable reflects nonlocal change.
print(value)
# Call method.
method()
100
The result variables in the operation functions are in a different scope to the cal function. Have those functions return a value and then return that from cal and you will get the desired behaviour.
def cal(num1,op,num2):
def add():
return num1+num2
def multiply():
return num1 * num2
def devide():
if not num2==0:
result = num1 / num2
else:
result = 'num2 can\'t be zero'
return result
def default():
print("Incorrect option")
switch = {
'+':add,
'*':multiply,
'/':devide
}
return switch.get(op,default)()

Evaluating infix expressions using stacks

So I am currently learning about postfix, prefix, and infix expressions; and one of the challenge questions was about evaluating infix expressions using stacks. I think I understand the concept of it. However, I am really puzzled as to why my operators are not pushing onto my stack. I believe the problem is within line 31. However, I am not sure as to why. Could someone help me find and fix the problem?
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items) - 1]
def size(self):
return len(self.items)
def infix(equation):
prec_dictionary = {"(": 0, ")": 0, "^": 4, "*": 3, "/": 3, "+": 2, "-": 2, "<": 1, ">": 1}
operator_stack = Stack()
operand_stack = Stack()
allowed_operators = "+-/*^<>"
a_list = equation.split()
for i in a_list:
if i in allowed_operators:
if operator_stack.is_empty():
operator_stack.push(i)
else:
if prec_dictionary[i] > prec_dictionary[operator_stack.peek()]:
operator_stack.push(i)
if i == "(":
operator_stack.push(i)
elif i == ")":
while operator_stack.peek() != "(":
value1 = int(operand_stack.pop())
operator = operator_stack.pop()
value2 = int(operand_stack.pop())
value = compute(value1, value2, operator)
operand_stack.push(value)
operator_stack.pop()
else:
operand_stack.push(i)
return operand_stack.pop()
def compute(number1, number2, operator):
if operator == "+":
return number1 + number2
elif operator == "-":
return number1 - number2
elif operator == "*":
return number1 * number2
elif operator == "/":
return number1 / number2
elif operator == "^":
return number1 ** number2
elif operator == "<":
return min(number1, number2)
else:
return max(number1, number2)
print(infix('2 ^ ( 1 + 3 ^ 2 )'))

Infix to Postfix Converter Python 2.7

I am trying to create a infix to postfix converter in python for a homework assignment, I found multiple ones online that seem simple enough but none of them meet the requirements I need. I have to use the following classes:
class Token(object):
UNKNOWN = 0 # unknown
INT = 4 # integer
MINUS = 5 # minus operator
PLUS = 6 # plus operator
MUL = 7 # multiply operator
DIV = 8 # divide operator
FIRST_OP = 5 # first operator code
def getPrecedence(self):
if self is '(':
return 0
elif self is '+'or '-':
return 1
elif self is '*' or '/':
return 2
else:
return 3
def _init_(self, value):
if type(value) == int:
self._type = Token.INT
else:
self._type = self._makeType(value)
self._value = value
def isOperator(self):
return self._type >= Token.FIRST_OP
def _str_(self):
return str(self._value)
def getType(self):
return self._type
def getValue(self):
return self._value
def _makeType(self, ch):
if ch == '*': return Token.MUL
elif ch == '/': return Token.DIV
elif ch == '+': return Token.PLUS
elif ch == '-': return Token.MINUS
else: return Token.UNKNOWN;
I had to add the getPrecedence(): method, which returns an Integer that represents the precedence level of an operator. I also had to use the following class:
from token import Token
class Scanner(object):
EOE = ';' # end-of-expression
TAB = '\t' # tab
def __init__(self, sourceStr):
self._sourceStr = sourceStr
self._getFirstToken()
def hasNext(self):
return self._currentToken != None
def next(self):
if not self.hasNext():
raise Exception, "There are no more tokens"
temp = self._currentToken
self._getNextToken()
return temp
def _getFirstToken(self):
self._index = 0
self._currentChar = self._sourceStr[0]
self._getNextToken()
def _getNextToken(self):
self._skipWhiteSpace()
if self._currentChar.isdigit():
self._currentToken = Token(self._getInteger())
elif self._currentChar == Scanner.EOE:
self._currentToken = None
else:
self._currentToken = Token(self._currentChar)
self._nextChar()
def _nextChar(self):
if self._index >= len(self._sourceStr) - 1:
self._currentChar = Scanner.EOE
else:
self._index += 1
self._currentChar = self._sourceStr[self._index]
def _skipWhiteSpace(self):
while self._currentChar in (' ', Scanner.TAB):
self._nextChar()
def _getInteger(self):
num = 0
while True:
num = num * 10 + int(self._currentChar)
self._nextChar()
if not self._currentChar.isdigit():
break
return num
I have to write a program that converts a infix expression to a postfix expression. This program should use the Token and Scanner classes (which I have included above). The program should consist of a main function that preforms the inputs and outputs, and a class named IFToPFConverter. The main function receives a input string an creates a scanner with it. The scanner is then passed as a argument to the constructor of the converter object. The converter objects convert method is then run to convert the infix expression. This method returns a list of tokens that represent the postfix string. The main function then displays this string. Here is what I have so far:
from arrayStack import ArrayStack
from token import Token
from scanner import Scanner
class IFToPFConverter(object):
def convert(self):
opStack = Stack()
postFixList = []
while self._scanner.hasNext():
currentToken = self._scanner.next()
if currentToken in '0123456789'
postFixList.append(currentToken)
elif currentToken == '(':
opStack.push(currentToken)
elif currentToken == '*':
opStack.push(currentToken)
elif currentToken == '/':
opStack.push(currentToken)
elif currentToken == '+':
opStack.push(currentToken)
elif currentToken == '-':
opStack.push(currentToken)
elif currentToken == ')':
opStack.push(currentToken)
while not opStack.isEmpty():
def main():
sourceStr = raw_input("Please enter an expression:")
scanner = Scanner(sourceStr)
conversion = IFToConverter.convert(scanner)
return conversion
main()
I don't know where to go from here, I don't even know if what I am trying to do at in my IFToPFConverter class will work. I have seen much simpler infix to postfix converters.

Categories