Pythonic的方式来计算计算器的函数 - Python

Jac*_*cob -1 python if-statement while-loop

我正在创建一个文本计算器,它不能完全按常规工作.它的工作原理如下:

  • 操作输入:用户输入计算器将处理的操作(+用于加法,-用于减法,*用于乘法或/用于除法)
  • 操作数输入:用户在计算的每个操作数中输入,按操作数之间的Return键.一旦用户输入了所有他想要的操作数,击中Return三次就会启动计算.

计算:

当用户输入两个以上的操作数时,而不是:

operand1 plus/minus/times/divided by operand2,

它确实:

operand1 plus/minus/times/divided by operand2 plus/minus/times/divided by operand3,

等等所有输入的操作数.

这个代码只是循环输入操作数列表operandList,并使用所选择的操作operation(并且result是计算的结果):

def Calculate():
    global operation, operandList, result
    operateCount = 0
    result = 0
    while operateCount < len(operandList):
        if operation == '+':
            result += operandList[operateCount]
        elif operation == '-':
            result -= operandList[operateCount]
        elif operation == '*':
            result *= operandList[operateCount]
        elif operation == '/':
            result /= operandList[operateCount]        
        operateCount += 1

    if operation == '+':
        resultName = 'Sum'    
    elif operation == '-':
        resultName = 'Difference'
    elif operation == '*':
        resultName = 'Product'
    elif operation == '/':
        resultName = 'Quotient'

    if result.is_integer():
        print(int(result), '=', resultName)
    else:
        print(result, '=', resultName)
    print()
Run Code Online (Sandbox Code Playgroud)

这是非常低效的,因为它检查操作两次,并且一次在while循环内,这甚至更糟.

显然,如果我为每个操作编写其中一个while循环块,并使用if语句开始每个操作,以检查更糟糕的操作.

如果我这样做,你会发现每个代码块之间的唯一区别是操作登录result +,-,*,/= operandList[operateCount].

我怎么能够:

  • 切出检查操作的冗余代码并执行相应的循环,和
  • 减少/更改显示result?时检查操作的冗余代码?

任何帮助是极大的赞赏.如有必要,请询问规格.如果您投票,请评论您这样做的原因,以便我可以进行更改.

Ale*_*lli 8

关键的想法是,建立一个dict:

import operator

ops = {
    '+': (operator.add, 'Sum', 0),
    '-': (operator.sub, 'Difference', 0),
    '*': (operator.mul, 'Product', 1),
    '/': (operator.truediv, 'Quotient', 1),
}
Run Code Online (Sandbox Code Playgroud)

我正在将每个操作符号与三个项目相关联:要使用的函数,要使用的名称,以及(您似乎忽略了!)"中性"起点.在开始总是0为你做使得产品和商可笑-乘法和除法的一切,也不要紧,如果它开始于0,它停留0永远,你知道的- - !)

现在事情变得更简单......:

def Calculate():
    global result
    op, resultName, result = ops[operation]
    for item in operandList:
        result = op(result, item)
    if result == int(result):
        print(int(result), '=', resultName)
    else:
        print(result, '=', resultName)
    print()
Run Code Online (Sandbox Code Playgroud)

知道为什么你如此过分喜欢global并且在没有必要的情况下搞乱索引. is_number显然只是一种方法float而且你正在初始化result为一个int,所以它可能会使代码崩溃 - 我用一个明智的检查代替了它.

不需要global你只使用的名字而不需要分配 - 当然最后输掉global result而且return result最后输掉它是有道理的; 但是我已经离开了,以防万一有任何理智的理由让它全球化(我想不出任何).

但其核心思想是:在Python中,用于调度的目的,认为dict首要的!

补充:OP在评论中提出了一些特殊问题,例如"导入语句的功能究竟是什么?" - 答案显然是"使另一个模块可用"(在这种情况下,operator来自Python标准库的模块,以使其功能执行加法,乘法等).另外"什么是'中性起点'" - 显然,答案是" result开始添加,乘法等之前的初始值" .

在OP的原始代码中,result无条件地初始化为零.如果从零开始并将其乘以任何数字(s),则它保持为零 - 它不是一系列乘法的"中性"起点,它更像是一个"固定"点,一个是"黑洞".感.所以,我根据操作使用了不同的初始值.