python - 如何区分计算器的运算符和负数?
问题描述
尽管遇到问题,但我正在尝试制作自己的“计算器”。当我将运算符和数字分开时,负数不起作用。因为'-'符号被算作一个操作符。现在我的问题是如何区分两个运算符和包括负数的数字?
我不希望负数适用于我当前的代码,尽管我正在努力让它们工作。
关于我该怎么做的任何想法?
这是计算器的完整代码。
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
解决方案
所以,我有很多信息给你,但它们非常相关。我还彻底改变了你的代码:
除非您需要诸如在每个负数周围有括号/空格之类的东西,否则轻松地将运算符和数字分开是行不通的。但这不仅会使您无法在计算器中输入常规的、未格式化的方程式,而且还要求您将负数视为特殊数。它们是什么,但这不是必需的。这是因为您基本上可以忽略它们是否定的。我建议的代码更改将更容易让您处理任何运算符。
任何负数都可以分解为一个运算:-x 与 0 - x 相同。问题是:什么时候应该加零?有两种情况:当第一个输入是负号时,以及当另一个运算符后面有一个负号时。您需要做的就是添加一些代码来处理这些条件。让我们看一些例子:
>>> -2+5
3
>>> 5+-2
3
>>> (1/9)^(-1/2)
3
>>> (2+(-1))*5-2
43
您的方法中的否定问题来自这样一个事实,即当您将运算符与 numbers 分开时,您不知道接下来应该发生什么:运算符或数字(这是上述所有示例的问题)。
一种解决方案是跟踪所有号码的位置!这样做可以让您确切地知道每个数字之间有多少个运算符,并且您可以通过它找出哪些数字是负数(或者您应该在哪里添加零)。
我已经为此重写了您的代码,它非常不同,但主要思想仍然存在。请看下面的代码:
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
PS它也接受只有字母的方程。
推荐阅读
- html - DIV 元素变得不可见
- android - common.apiexception.c:不在主线程上
- mysql - 如果日期以 varchar 类型格式存储为事件调度程序的 (mm-dd-yyyy),如何获取昨天的日期
- ios - 使用 reduce 从对象数组中填充 [String : [CGFloat]] 字典
- npm - npm 错误!缺少脚本:启动反应项目
- python-3.x - 将 8.9 GB 数据集从 Google Drive 加载到 Google Colab?
- android - 从输入流中获取并在android中显示图像
- angular - Angular:无法读取未定义的属性“_id”
- javascript - 扩展类方法不公开
- c - 仅使用奇数除数计算素数较慢