带加减法的递归计算器

Recursive calculator with adding and substracting

我制作了带有 3 个独立参数的嵌套函数 - 每个函数都有一个:(arg1)(operation)(arg2)

def simple_functional_calc(arg1: int):
    def inner_functional_calc(operation: str):
        import operator
        ops = {
            '+': operator.add,
            '-': operator.sub
        }

        def inner_inner_functional_calc(arg2: int):
            return ops[operation](arg1, arg2)
        return inner_inner_functional_calc
    return inner_functional_calc

还有其他想法(不导入):

def calculator(arg1: int):
    def inner_calc(operation: str):
        def add(arg2: int):
            return arg1 + arg2

        def sub(arg2: int):
            return arg1 - arg2

        if operation == '+':
            return add
        elif operation == '-':
            return sub
    return inner_calc

在此示例中 print(calculator(1)('+')(7)) 结果为 8。问题是使函数可以接受任意数量的参数,并且当最后一个参数为“=”时结果为 return。示例:print(calculator(2)('+')('5')('-')(3)('-')(1)('=')) 结果为 3。有什么提示吗? (如果可能的话,我宁愿不使用任何导入和全局变量!)

您可以编写计算器来获取任何输入 t,以及默认的 lambda 累加器 r -

def calculator(t, r = lambda a: a):
  if isinstance(t, int):
    return lambda next: \
      calculator(next, lambda _: r(t))
  elif t == "+":
    return lambda next: \
      calculator(next, lambda a: r(0) + a)
  elif t == "-":
    return lambda next: \
      calculator(next, lambda a: r(0) - a)
  # else any other operation:
    # ...
  elif t == "=":
    return r(0)
print(calculator(2)('+')(5)('-')(3)('-')(1)('='))
2 + 5 - 3 - 1 =
7 - 3 - 1 =
4 - 1 =
3

即使在“覆盖”操作时,它也能可靠地工作 -

calculator(5)("+")("-")(3)("=")       # 2
calculator(5)("+")("-")("+")(3)("=")  # 8

然而,当提供多个数字而没有将它们组合起来的操作时,就不是那么多了-

calculator(5)(4)(3)("=")  # 5

这是一个玩具程序,看起来像是一项玩具作业,但如果您认为袖珍计算器算术可以是一种有趣的方式来实现您的第一语言,我认为还有很多东西需要学习。有关详细信息,请参阅

为了阐明我的意思,请考虑 calc -

的这个大大简化的版本
def calc(t, r = ()):
  if t == "=":
    return r
  else:
    return lambda next: \
      calc(next, (*r, t))
print(calc(2)('+')(5)('-')(3)('-')(1)('='))
print(calc(5)("+")("-")(3)("="))
print(calc(5)("+")("-")("+")(3)("="))
print(calc(5)(4)(3)("="))
(2, '+', 5, '-', 3, '-', 1)
(5, '+', '-', 3)
(5, '+', '-', '+', 3)
(5, 4, 3)

calc 不是试图计算超复杂函数中的所有内容,而是形成一个结果 表达式 r。在最后一步,我们可以使用您预期的操作顺序标记化和解析计算所需结果,而不是将表达式作为输出返回 -

def calc(t, r = ()):
  if t == "=":
    return eval(parse(tokenize(r))) # <--
  else:
    return lambda next: \
      calc(next, (*r, t))

def tokenize(t):
  # ...

def parse(t):
  # ...

def eval(t):
  # ...

这使您能够恰当地处理像

这样的表达式
calc(5)(3)("+")(1)(0)(7)("*")(2)("=")

可能标记为 -

53 + 107 * 2 =

并以从左到右的操作顺序进行评估 -

53 + 107 * 2 =
160 * 2 =
320

或使用 PEMDAS 进行评估,例如 -

53 + 107 * 2 =
53 + 214 =
267

实施 tokenizeparseeval 留作 reader 的练习。如果您有任何问题,我很乐意提供帮助。