I have a homework to make a calculator(infix-to postfix) and I need to do it asap. I get always an error when I run this code(Enter a postfix expression (or nothing to quit): +54 Traceback (most recent call last): File "C:\Python32\infix to postfix", line 69, in <module> main() File "C:\Python32\infix to postfix", line 62, in main print(" => {}".format(postfix_eval(expr))) File "C:\Python32\infix to postfix", line 42, in postfix_eval stack = Stack() NameError: global name 'Stack' is not defined – How do i fix this error?

By the way I am a new programmer,the question could be simple for experts.I will be very pleased, if you could just give the answer as soon as possible.

class Op:

    def __init__(self, num_in, num_out, fn):


    """
    A postfix operator

    num_in:     int
    num_out:    int
    fn:         accept num_in positional arguments,
                perform operation,
                return list containing num_out values
    """
    assert num_in  >= 0, "Operator cannot have negative number of arguments"
    self.num_in = num_in
    assert num_out >= 0, "Operator cannot return negative number of results"
    self.num_out = num_out
    self.fn = fn

def __call__(self, stack):
    """
    Run operator against stack (in-place)
    """
    args = stack.pop_n(self.num_in)         # pop num_in arguments
    res = self.fn(*args)                    # pass to function, get results
    stack.push_n(self.num_out, res)         # push num_out values back



ops = {


'*':  Op(2, 1, lambda a,b: [a*b]),          # multiplication
'/':  Op(2, 1, lambda a,b: [a//b]),         # integer division
'+':  Op(2, 1, lambda a,b: [a+b]),          # addition
'-':  Op(2, 1, lambda a,b: [a-b]),          # subtraction
'/%': Op(2, 2, lambda a,b: [a//b, a%b])     # divmod (example of 2-output op)


}




def postfix_eval(tokens):

"""
Evaluate a series of tokens as a postfix expression;
return the resulting stack
"""
if isinstance(tokens, str):
    # if tokens is a string, treat it as a space-separated list of tokens
    tokens = tokens.split()

stack = Stack()
for token in tokens:
    try:
        # Convert to int and push on stack
        stack.append(int(token))
    except ValueError:
        try:
            # Not an int - must be an operator
            # Get the appropriate operator and run it against the stack
            op = ops[token]
            op(stack)         # runs Op.__call__(op, stack)
        except KeyError:
            # Not a valid operator either
            raise ValueError("unknown operator {}".format(token))
return stack


def main():
    while True:
        expr = input('\nEnter a postfix expression (or nothing to quit): ').strip()
        if expr:
            try:
                print("  => {}".format(postfix_eval(expr)))
            except ValueError as error:
                print("Your expression caused an error: {}".format(error))
        else:
            break

if __name__=="__main__":
    main()

Recommended Answers

All 3 Replies

NameError: global name 'Stack' is not defined – How do i fix this error?

Do you have a class named Stack somewhere in another file? If not, you'll need to define one. Either way, you would also need to import the class into the module you are writing, something like:

from stack import Stack

You would need this in your code before your first use of the Stack class.

If you don't already have a Stack class, the easiest way to implement one is to use a list as the underlying data structure.

I changed these expressions.I just got an error now that I noticed below the paragraphes.I have 5 options,only option 2 didN't work.Could you help me to fix option 2?Apart from that,
no other problem about these expressions.

        def push_stack(stackArr,ele):
            stackArr.append(ele)

        def pop_stack(stackArr):
            return stackArr.pop()

        def isOperand(who):
            if(not(isOperator(who)) and (who != "(") and (who != ")")):
                return 1
            return 0

        def isOperator(who):
            if(who == "+" or who == "-" or who == "*" or who == "/" or who == "^"):
                return 1
            return 0

        def topStack(stackArr):
            return(stackArr[len(stackArr)-1])

        def isEmpty(stackArr):
            if(len(stackArr) == 0):
                return 1
            return 0

        def prcd(who):
            if(who == "^"):
                return 5
            if((who == "*") or (who == "/")):
                return 4
            if((who == "+") or (who == "-")):
                return 3
            if(who == "("):
                return 2
            if(who == ")"):
                return 1

        def ip(infixStr,postfixStr = [],retType = 0):
            postfixStr = []
            stackArr = []
            postfixPtr = 0
            tempStr = infixStr
            infixStr = []
            infixStr = strToTokens(tempStr)
            for x in infixStr:
                if(isOperand(x)):
                    postfixStr.append(x)
                    postfixPtr = postfixPtr+1
                if(isOperator(x)):
                    if(x != "^"):
                        while((not(isEmpty(stackArr))) and (prcd(x) <= prcd(topStack(stackArr)))):
                            postfixStr.append(topStack(stackArr))
                            pop_stack(stackArr)
                            postfixPtr = postfixPtr+1
                    else:
                        while((not(isEmpty(stackArr))) and (prcd(x) < prcd(topStack(stackArr)))):
                            postfixStr.append(topStack(stackArr))
                            pop_stack(stackArr)
                            postfixPtr = postfixPtr+1
                    push_stack(stackArr,x)
                if(x == "("):
                        push_stack(stackArr,x)                
                if(x == ")"):
                    while(topStack(stackArr) != "("):
                        postfixStr.append(pop_stack(stackArr))
                        postfixPtr = postfixPtr+1
                    pop_stack(stackArr)

            while(not(isEmpty(stackArr))):
                if(topStack(stackArr) == "("):
                    pop_stack(stackArr)
                else:
                    postfixStr.append(pop_stack(stackArr))

            returnVal = ''
            for x in postfixStr:
                returnVal += x

            if(retType == 0):
                return(returnVal)
            else:
                return(postfixStr)

        def pi(postfixStr):
            stackArr = []
            tempStr = postfixStr
            postfixStr = []
            postfixStr = tempStr
            for x in postfixStr:
                if(isOperand(x)):
                    push_stack(stackArr,x)
                else:
                    temp = topStack(stackArr)
                pop_stack(stackArr)
                pushVal = '(' + topStack(stackArr) + x + temp + ')'
                pop_stack(stackArr)
                push_stack(stackArr,pushVal)
                return(topStack(stackArr))

        def strToTokens(str):
            strArr = []
            strArr = str
            tempStr = ''    
            tokens = []
            tokens_index = 0
            count = 0
            for x in strArr:
                count = count+1
                if(isOperand(x)):
                    tempStr += x
                if(isOperator(x) or x == ")" or x == "("):
                    if(tempStr != ""):
                        tokens.append(tempStr)
                        tokens_index = tokens_index+1
                    tempStr = ''
                    tokens.append(x)
                    tokens_index = tokens_index+1 
                if(count == len(strArr)):
                    if(tempStr != ''):
                        tokens.append(tempStr)
            return(tokens)

        def PostfixSubEval(num1,num2,sym):
            num1,num2 = float(num1),float(num2)
            if(sym == "+"):
                returnVal = num1 + num2
            if(sym == "-"):
                returnVal = num1 - num2
            if(sym == "*"):
                returnVal = num1 * num2
            if(sym == "/"):
                returnVal = num1 / num2
            if(sym == "^"):
                returnVal = pow(num1,num2)
            return returnVal

        def PostfixEval(postfixStr):
            temp = postfixStr
            postfixStr = []
            postfixStr = temp
            stackArr = []
            for x in postfixStr:
                if(isOperand(x)):
                    push_stack(stackArr,x)
                else:
                    temp = topStack(stackArr)
                    pop_stack(stackArr)
                    pushVal = PostfixSubEval(topStack(stackArr),temp,x)
                    pop_stack(stackArr)
                    push_stack(stackArr,pushVal)
            return(topStack(stackArr))

        def InfixEval(infixStr):
            return PostfixEval(ip(infixStr,[],1))

        def menu():
            def again():
                flag = input('Continue (y/n)?')
                if flag not in ('y','n'):
                    again()
                if(flag == 'y'):
                    menu()
                if(flag == 'n'):
                    exit

            print ('\n############################')
            print ('# Infix-Postfix Calculator #')
            print ('############################')    
            print ('\n(1) Infix to Postfix')
            print ('(2) Postfix to Infix')
            print ('(3) Evaluate Infix')
            print ('(4) Evaluate Postfix')
            print ('(5) Exit')
            opt = input("Enter option (1/2/3/4/5): ")
            if opt in ('1','2','3','4','5'):
                if(opt == '1'):
                    what = input('\nEnter Infix String: ')
                    print ('Postfix String: ', ip(what))
                if(opt == '2'):
                    what = input('\nEnter Postfix String: ')
                    print ('Infix String: ', pi(what))
                if(opt == '3'):
                    what = input('\nEnter Infix String: ')
                    print ('Infix Value: ', InfixEval(what))
                if(opt == '4'):
                    what = input('\nEnter Infix String: ')
                    print ('Postfix Value: ', PostfixEval(what))
                if(opt == '5'):
                    exit
                if(opt != '5'):
                    again()
            else:
                menu()

        menu()






Traceback (most recent call last):


  File "C:\Users\user\Downloads\ip2.py", line 194, in <module>
    menu()
  File "C:\Users\user\Downloads\ip2.py", line 180, in menu
    print ('Infix String: ', pi(what))
  File "C:\Users\user\Downloads\ip2.py", line 94, in pi
    pushVal = '(' + topStack(stackArr) + x + temp + ')'
  File "C:\Users\user\Downloads\ip2.py", line 18, in topStack
    return(stackArr[len(stackArr)-1])
IndexError: list index out of range
Member Avatar for iamthwee

Your precedence function needs to take in two characters

TakesPrecedence(char OperatorA, char OperatorB)
{
   if (OperatorA == '(')
      return false;
   else if (OperatorB == '(')
      return false;
   else if (OperatorB == ')')
      return true;
   else if ((OperatorA == '^') && (OperatorB == '^'))
      return false;
   else if (OperatorA == '^')
      return true;
   else if (OperatorB == '^')
      return false;
   else if ((OperatorA == '*') || (OperatorA == '/'))
      return true;
   else if ((OperatorB == '*') || (OperatorB == '/'))
      return false;
   else
      return true;   
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.