Evaluating a mathematical expression in a string

前端 未结 11 1494
名媛妹妹
名媛妹妹 2020-11-21 05:01
stringExp = \"2^4\"
intVal = int(stringExp)      # Expected value: 16

This returns the following error:

Traceback (most recent call         


        
11条回答
  •  半阙折子戏
    2020-11-21 05:25

    Here's my solution to the problem without using eval. Works with Python2 and Python3. It doesn't work with negative numbers.

    $ python -m pytest test.py
    

    test.py

    from solution import Solutions
    
    class SolutionsTestCase(unittest.TestCase):
        def setUp(self):
            self.solutions = Solutions()
    
        def test_evaluate(self):
            expressions = [
                '2+3=5',
                '6+4/2*2=10',
                '3+2.45/8=3.30625',
                '3**3*3/3+3=30',
                '2^4=6'
            ]
            results = [x.split('=')[1] for x in expressions]
            for e in range(len(expressions)):
                if '.' in results[e]:
                    results[e] = float(results[e])
                else:
                    results[e] = int(results[e])
                self.assertEqual(
                    results[e],
                    self.solutions.evaluate(expressions[e])
                )
    

    solution.py

    class Solutions(object):
        def evaluate(self, exp):
            def format(res):
                if '.' in res:
                    try:
                        res = float(res)
                    except ValueError:
                        pass
                else:
                    try:
                        res = int(res)
                    except ValueError:
                        pass
                return res
            def splitter(item, op):
                mul = item.split(op)
                if len(mul) == 2:
                    for x in ['^', '*', '/', '+', '-']:
                        if x in mul[0]:
                            mul = [mul[0].split(x)[1], mul[1]]
                        if x in mul[1]:
                            mul = [mul[0], mul[1].split(x)[0]]
                elif len(mul) > 2:
                    pass
                else:
                    pass
                for x in range(len(mul)):
                    mul[x] = format(mul[x])
                return mul
            exp = exp.replace(' ', '')
            if '=' in exp:
                res = exp.split('=')[1]
                res = format(res)
                exp = exp.replace('=%s' % res, '')
            while '^' in exp:
                if '^' in exp:
                    itm = splitter(exp, '^')
                    res = itm[0] ^ itm[1]
                    exp = exp.replace('%s^%s' % (str(itm[0]), str(itm[1])), str(res))
            while '**' in exp:
                if '**' in exp:
                    itm = splitter(exp, '**')
                    res = itm[0] ** itm[1]
                    exp = exp.replace('%s**%s' % (str(itm[0]), str(itm[1])), str(res))
            while '/' in exp:
                if '/' in exp:
                    itm = splitter(exp, '/')
                    res = itm[0] / itm[1]
                    exp = exp.replace('%s/%s' % (str(itm[0]), str(itm[1])), str(res))
            while '*' in exp:
                if '*' in exp:
                    itm = splitter(exp, '*')
                    res = itm[0] * itm[1]
                    exp = exp.replace('%s*%s' % (str(itm[0]), str(itm[1])), str(res))
            while '+' in exp:
                if '+' in exp:
                    itm = splitter(exp, '+')
                    res = itm[0] + itm[1]
                    exp = exp.replace('%s+%s' % (str(itm[0]), str(itm[1])), str(res))
            while '-' in exp:
                if '-' in exp:
                    itm = splitter(exp, '-')
                    res = itm[0] - itm[1]
                    exp = exp.replace('%s-%s' % (str(itm[0]), str(itm[1])), str(res))
    
            return format(exp)
    

提交回复
热议问题