Creating a function that takes an equation given as a string and computes it [duplicate]

懵懂的女人 提交于 2019-12-23 02:20:44

问题


As part of an assignment, I am creating a function that takes in a string, which is an equation. here is an example of one: 48+6x6/3=6x8-9x2. The compute function takes one side of the equal sign and evaluates it. I am not too concerned with splitting the equation. I believe I can just slice it with s[:s.find("=")].

My main problem is the compute function itself. I will post where I am with it so far. The commented out part was stuff I was trying to deal with double digits but I cannot figure out a logical way to do that. I would like some help thinking about this.

I was told not to use eval because doing eval on an equation "2+3*5-11/2*88+153" would not be easy due to operator precedence--or lack thereof. My program should not obey the normal operator precedence rules. Instead it is supposed to evaluate purely from left to right.

 def compute(s):
    result = 0
    a = 1
    for a in range(len(s)):

    #while s[a].isdigit():
        #result = (result * 10) + int(s[a])
        #a += 1

    if s[a] == '/':

        result = result / int(s[a + 1])

    elif s[a] == '+':

        result = result + int(s[a + 1])

    elif s[a] == 'x' or s[a] == '*' or s[a] == 'X':

        result = result * int(s[a + 1])
    elif s[a] == '-':
        result = result - int(s[a + 1])
    else:
        result += int(s[a])
    a += 1
    return result

 print(compute("48+6x6/3") == 108) 

EDIT this works for single digits. Maybe we can get this to work with multiple digits

 def compute(s):
    result = int(s[0])
    op = 0
    a = 1
    while a < len(s):
        if s[a] == '/':
        result /= int(s[a + 1])
    elif s[a] == '+':
        result += int(s[a + 1])
    elif s[a] == '*':
        result *= int(s[a + 1])
    elif s[a] == '-':
        result -= int(s[a + 1])
    a += 1
    return int(result)

回答1:


using eval can be very dangerous if you accept strings to evaluate from untrusted input. for example Suppose the string being evaluated is "os.system('rm -rf /')" ? It will really start deleting all the files on your computer.

So you can parse it with python's internal compiler :

import compiler
eq="48+6*6/3"
ast= compiler.parse( eq )

>>> compiler.parse( eq )
Module(None, Stmt([Discard(Add((Const(48), Div((Mul((Const(6), Const(6))), Const(3))))))]))
>>>

Also you can use sympy that is a Python library for symbolic mathematics. It aims to become a full-featured computer algebra system (CAS) while keeping the code as simple as possible in order to be comprehensible and easily extensible. SymPy is written entirely in Python and does not require any external libraries.




回答2:


You can use Polish notation. http://en.wikipedia.org/wiki/Polish_notation This is a stack based algorithm for parsing and evaluating data. It is quite simple and widely used.



来源:https://stackoverflow.com/questions/26130075/creating-a-function-that-takes-an-equation-given-as-a-string-and-computes-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!