如何分隔计算器的运算符和负数?
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。它还接受只有字母的等式。
我正在尝试自己制作 "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。它还接受只有字母的等式。