简体   繁体   English

python 中存在数学解析错误的计算器

[英]Calculator with mathematical parsing error in python

Code:代码:

import re
num=['0','1','2','3','4','5','6','7','8','9']
opr=['+','-','%','/','*','^']
length=0
#tokens,operators,numbers=[],[],[]
def greater_precedence(op1,op2):
    precedence={'+':0,'-':1,'*':2,'/':3}
    return precedence[op1]>precedence[op2]
def peek(stack):
    return stack[-1] if stack else None
def solve(operator,number):
    print('OP1: ',operator,' ','NP1: ',number)
    v=0
    operator.reverse()
    for i,j in enumerate(operator):
        if j=='+':
            num1=number.pop()
            num2=number.pop()
            v=num1+num2
            operator.remove(j)
        if j=='-':
            num1=number.pop()
            num2=number.pop()
            v=num2-num1
            operator.remove(j)
        if j=='*':
            num1=number.pop()
            num2=number.pop()
            v=num1*num2
            operator.remove(j)
        if j=='/':
            num1=number.pop()
            num2=number.pop()
            v=num2/num1
            operator.remove(j)
    operator.reverse()
    number.append(v)
def bracket_op(operator,number,holder):
    #print('Operation: ',exp)
    #print('Operation 1: ',exp_1)
    print('Operators: ',operator,' ','Numbers: ',number)
    v=0
    lth=len(number)
    top=peek(operator)
    operator.reverse()
    print('Length: ',lth)
    print('OP2: ',operator)
    for i,j in enumerate(operator):
        if j=='+' and top=='+':
            num1=number.pop()
            num2=number.pop()
            v=num2+num1
            operator.remove(j)
    #for i,j in enumerate(operator):
        if j=='-' and top=='-':
            num1=number.pop()
            print('S: ',number)
            num2=number.pop()
            v=num1-num2
            operator.remove(j)
    #for i,j in enumerate(operator):
        if j=='*'and top =='*':
            num1=number.pop()
            print('M: ',number)
            num2=number.pop()
            v=num1*num2
            operator.remove(j)
    #for i,j in enumerate(operator):
        if j=='/'and top =='/':
            num1=number.pop()
            print('D: ',number)
            num2=number.pop()
            v=num2/num1
            operator.remove(j)
    operator.reverse()
    
    
    #print('Operators 1: ',operators,' ','Numbers 1: ',numbers)
    print('holder: ',holder)
    number.insert(holder,v)
    print(number)
        

def evaluate(exp):
    tokens=re.findall('[-]|[(,),+,*,^,%,/]|\d+',exp)
    print('Tokens: ',tokens)
    bracket=False
    holder,value=0,0
    operator,number,brackets=[],[],[]
    for token in tokens:
        if token=='(':
            holder=tokens.index(token)
            operator.append(token)
        elif token==')':
            holder=operator.index('(')
            top=peek(operator)
            while top is not None and top is not '(':
                bracket_op(operator,number,holder)
                top=peek(operator)
            operator.pop()
        else:
            if token in num:
                number.append(float(token))
            else:
                top=peek(operator)
                while top is not None and top is not '(' and greater_precedence(top,token):
                    solve(operator,number)
                    top=peek(operator)
                operator.append(token)
    while peek(operator) is not None:
         solve(operator,number)
            
            
    print('Operators: ',operator,'','Numbers: ',number)
    return number
        

        
def main():
    exp=input("Enter: ")
    print("Answer: {0}".format(evaluate(exp)))
if __name__=='__main__':
    main()

Output: Output:

Correct Output:正确的 Output:

Enter: (2+2)*(2+2)
Tokens:  ['(', '2', '+', '2', ')', '*', '(', '2', '+', '2', ')']
Operators:  ['(', '+']   Numbers:  [2.0, 2.0]
Length:  2
OP2:  ['+', '(']
holder:  0
[4.0]
Operators:  ['*', '(', '+']   Numbers:  [4.0, 2.0, 2.0]
Length:  3
OP2:  ['+', '(', '*']
holder:  1
[4.0, 4.0]
OP1:  ['*']   NP1:  [4.0, 4.0]
Operators:  []  Numbers:  [16.0]
Answer: [16.0]

Error Output:错误 Output:

Enter: (2+2)+(2+2)
Tokens:  ['(', '2', '+', '2', ')', '+', '(', '2', '+', '2', ')']
Operators:  ['(', '+']   Numbers:  [2.0, 2.0]
Length:  2
OP2:  ['+', '(']
holder:  0
[4.0]
Operators:  ['+', '(', '+']   Numbers:  [4.0, 2.0, 2.0]
Length:  3
OP2:  ['+', '(', '+']
Traceback (most recent call last):
File "F:\TYBScIT\Sem V\Advanced_Calculator_3.py", line 123, in <module>
   main()
File "F:\TYBScIT\Sem V\Advanced_Calculator_3.py", line 121, in main
   print("Answer: {0}".format(evaluate(exp)))
File "F:\TYBScIT\Sem V\Advanced_Calculator_3.py", line 98, in evaluate
   bracket_op(operator,number,holder)
File "F:\TYBScIT\Sem V\Advanced_Calculator_3.py", line 51, in bracket_op
   num2=number.pop()
IndexError: pop from empty list

Don't know why I get this Error It works fine with correct output and wrong when I replace '*' with '+' .不知道为什么我会收到此错误 它适用于正确的 output 并且当我将'*'替换为'+'时错误。 It works fine without any brackets ie '(' and ')' .它可以在没有任何括号的情况下正常工作,即'('')' Its main aim is to follow BODMAS rule ie其主要目的是遵循 BODMAS 规则,即

(B: Brackets,O:Exponential,D:Division,M:Multiplication,A:Addition,S:Subtraction) . (B: Brackets,O:Exponential,D:Division,M:Multiplication,A:Addition,S:Subtraction) I have worked far till only with Brackets,Addition,*,-,/ .我一直工作到只使用Brackets,Addition,*,-,/ Does not work with all other maths work related to +,-,/,* with some extend supporting ( ) (2+2)+(2+2)不适用于与 +,-,/,* 相关的所有其他数学工作,某些扩展支持 ( ) (2+2)+(2+2)

Correct Back-end Code for BODMAS rule which works correctly by me.正确的 BODMAS 规则后端代码,我可以正常工作。 In Python 3.8.3 Shell.在 Python 3.8.3 Shell 中。 For Calculating mathematical string using parsing method用于使用解析方法计算数学字符串

#Note: #笔记:

It works only for 0-9 numbers.It does not work for any float numbers.它仅适用于 0-9 数字。它不适用于任何浮点数。 While float number work is still under work虽然浮点数工作仍在进行中

#Code #代码

import re
num=['0','1','2','3','4','5','6','7','8','9','.']
opr=['+','-','%','/','*','^']
length=0
def greater_precedence(op1,op2):
precedence={'+':0,'-':1,'*':2,'/':3,'^':4}
return precedence[op1]>precedence[op2]
def peek(stack):
    return stack[-1] if stack else None
def solve(operator,number):
    v=0
    operator.reverse()
    for i,j in enumerate(operator):
        if j=='+':
            num1=number.pop()
            num2=number.pop()
            v=num1+num2
            operator.remove(j)
        if j=='-':
            num1=number.pop()
            num2=number.pop()
            v=float(num2-num1)
            operator.remove(j)
        if j=='*':
            num1=number.pop()
            num2=number.pop()
            v=num1*num2
            operator.remove(j)
        if j=='/':
            num1=number.pop()
            num2=number.pop()
            v=num2/num1
            operator.remove(j)
        if j=='^':
            num1=number.pop()
            num2=number.pop()
            v=num2**num1
            operator.remove(j)
operator.reverse()
number.append(v)
def bracket_op(operator,number):
    v=0
    lth=len(number)
    top=peek(operator)
    operator.reverse()
    number.reverse()
    for i,j in enumerate(operator):
        if j=='+' and top=='+':
            number[0]=number[0]+number[0+1]
            number.remove(number[0+1])
            operator.remove(j)
            top=' '
        if j=='-' and top=='-':
            number[0]=number[0+1]-number[0]
            number.remove(number[0+1])
            operator.remove(j)
            top=' '
        if j=='*'and top =='*':
            number[0]=float(number[0]*number[0+1])
            number.remove(number[0+1])
            operator.remove(j)
            top=' '
        if j=='/'and top =='/':
            number[0]=number[0+1]/number[0]
            number.remove(number[0+1])
            operator.remove(j)
            top=' '
        if j=='^' and top=='^':
            number[0]=number[0+1]**number[0]
            number.remove(number[0+1])
            operator.remove(j)
            top=' '
    operator.reverse()
    number.reverse() 


def evaluate(exp):
    tokens=re.findall('[-]|[(,),+,*,^,%,/]|\d+',exp)
    bracket=False
    holder,value=0,0
    operator,number,brackets=[],[],[]
    for token in tokens:
    if token=='(':
        operator.append(token)
    elif token==')':
        top=peek(operator)
        while top != None and top != '(':
            bracket_op(operator,number)
            top=peek(operator)
        operator.pop()
    else:
        if token in num:
            number.append(float(token))
        else:
            top=peek(operator)
            while top != None and top != '(' and greater_precedence(top,token):
                solve(operator,number)
                top=peek(operator)
            operator.append(token)
while peek(operator) is not None:
     solve(operator,number)
value=number.pop()
return value
        

        
def main():
    exp=input("Enter: ")
    print("Answer: {0}".format(evaluate(exp)))
if __name__=='__main__':
    main()

#Note: #笔记:

Square root wont work as it need UI平方根无法工作,因为它需要 UI

If any error are occured while executing this code plzz comment down below如果执行此代码时发生任何错误,请在下方评论

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM