如何分隔计算器的运算符和负数?

How can I separate operators and negative numbers for a calculator?

我正在尝试自己制作 "calculator" 虽然我遇到了问题。 当我将运算符和数字分开时,负数不起作用。 因为'-'符号算作运算符。现在我的问题是如何区分运算符和包括负数在内的数字?

我不希望负数适用于我当前的代码,尽管我正在努力使它们起作用。
关于我该怎么做的任何想法?

这是计算器的完整代码。

import re

def calc(equation):

    equationList = re.findall('[+-/*]|\d+', equation)
    operators = [i for i in equationList if not i.isdigit()]
    numbers = [i for i in equationList if i.isdigit()]
    operators.insert(0,'+')
    answer = 0

    for i, operator in enumerate(operators):
        number = numbers[i]
        if operator == '+': answer += int(number)
        if operator == '-': answer -= int(number)
        if operator == '*': answer *= int(number)
        if operator == '/': answer /= int(number)

    print(f'Equation: {"".join(equationList)}\nAnswer: {answer}')


while True:
    calc(input('>>> '))

当我尝试 运行 一个带负数的方程时,我得到一个错误:

>>> -5*10

Traceback (most recent call last):                                                                                                                                                 
  File "main.py", line 22, in <module>                                                                                                                                             
    calc(input('>>> '))                                                                                                                                                            
  File "main.py", line 12, in calc                                                                                                                                                 
    number = numbers[i]                                                                                                                                                            
IndexError: list index out of range

所以,我有很多信息要给你,但它们非常相关。我还彻底 更改了您的代码:

简单地将运算符和数字分开是行不通的,除非您需要诸如每个负数周围都有 parentheses/spaces 之类的东西。但这不仅使您无法在计算器中输入常规的、未格式化的方程式,而且还要求您将负数视为特殊数。他们是,但这不是必需的。这是因为您基本上可以忽略它们是否定的。我建议的代码更改将使您也可以更轻松地处理任何运算符。

任何一个负数都可以分解成一个运算:-x 等同于0 - x。问题是:什么时候加零?有两种情况:当第一个输入是负号时,以及当另一个运算符后面有负号时。 您需要做的就是添加一些代码来处理这些情况。让我们看一些例子:

>>> -2+5
3
>>> 5+-2
3
>>> (1/9)^(-1/2)
3
>>> (2+(-1))*5-2
43

你的方法中负数的问题来自于这样一个事实:当你将运算符与数字分开时你不知道接下来会发生什么: 一个运算符或一个数字(这是所有上述示例的问题)。


一个解决方案是跟踪所有号码的位置!这样做可以让你确切地知道每个数字之间有多少个运算符,你可以通过它找出哪些数字是负数(或者你应该在什么地方加零)。

我已经为此重写了你的代码,它有很大的不同,但主要思想仍然存在。请看下面的代码:

import re

# Takes care of applying the operation on the left number given the right number
def applyOperation(operator, left, right):
    answer = left
    if operator == '(':
        return NotImplemented
    elif operator == ')':
        return NotImplemented
    elif operator == '^':
        return NotImplemented
    elif operator == '*': answer *= int(right)
    elif operator == '/': answer /= int(right)
    elif operator == '+': answer += int(right)
    elif operator == '-': answer -= int(right)
    else:
        print("Error. Only '*', '/', '+',and '-' are allowed at the moment.")
        # You could also allow a period, exponents (^), modulo, exponential, etc.
        exit(1)
    return answer

def calc(equation):
    """
    Magical calculator (It handles negative numbers)

    DISCLAIMER: 
     -This version does not allow parentheses or float inputs (but does allow float outputs)
     -It also does not follow the order of operations
    """
    numIndices = [m.span() for m in re.finditer("\d+", equation)]
    prevNumber = 0
    prevEnd = ''

    for numIndex in numIndices:
        number = float(equation[numIndex[0]:numIndex[1]])

        # If at the start, just add the number
        if numIndex[0] == 0:
            prevNumber = number
            prevEnd = numIndex[1]
            continue

        # Starting at the second spot of the equation is special
        if numIndex[0] == 1:
            # Remember this for order of operations (if implemented)
            if equation[0] == "(":
                # I think handling these would be best done recursively
                # Or you could split on all parentheses and compute each in turn
                # Or ...
                return NotImplemented
            # It's a negative number
            elif equation[0] == "-":
                prevNumber -= number
                prevEnd = numIndex[1]
                continue
            else:
                print("Error. Only numbers, '-' and '(' are allowed at the " 
                      +"beginning of the equation.")
                # You could allow a period as well.
                exit(1)

        # If reached here, then should have passed the first number
        # Extract relevant operators and remove any spaces
        operators = equation[prevEnd:numIndex[0]]
        operators = "".join(operators.split())
        if len(operators) == 1:
            prevNumber = applyOperation(operators[0], prevNumber, number)

        elif len(operators) == 2:
            if (operators[1] == '-'):
                prevNumber = applyOperation(operators[0], prevNumber, -number)
            else:
                print("Error. Currently, the second operator must always be a '-'.")
                exit(1)

        # If it reaches here, then parentheses are probably involved 
        # or syntax is probably incorrect
        else:
            print("Error. Only two operators are currently allowed between numbers." 
                  + " The second one always being a '-'.")
            # You could allow all sorts of nesting with parentheses if you want.
            exit(1)
        prevEnd = numIndex[1]

    # Do not display the decimal places if they are all 0
    prevNumber = int(prevNumber) if prevNumber-int(prevNumber) == 0 else prevNumber
    print("Equation:", equation,"\nAnswer:",prevNumber)


while True:
    calc(input('>>> '))

计算器可不是闹着玩的! xD

P.S。它还接受只有字母的等式。