简化代码 - 基于运算符执行数学运算

时间:2016-10-26 06:19:16

标签: python python-3.x lambda error-handling operators

以下是Python中计算器的代码:

import time
#Returns the sum of num1 and num2
def add(num1, num2):
    return num1 + num2

#Returns the difference of num1 and num2
def subtract(num1, num2):
    return num1 - num2

#Returns the quotient of num1 and num2
def divide(num1, num2):
    return num1 / num2

#Returns the product of num1 and num2
def multiply(num1, num2):
    return num1 * num2

#Returns the exponentiation of num1 and num2
def power(num1, num2):
    return num1 ** num2

import time

def main ():
    operation = input("What do you want to do? (+, -, *, /, ^): ")
    if(operation != "+" and operation != "-" and operation != "*" and operation != "/" and operation != "^"):
        #invalid operation
        print("You must enter a valid operation")
        time.sleep(3)
    else:
        var1 = int(input("Enter num1: ")) #variable one is identified
        var2 = int(input("Enter num2: ")) #variable two is identified
        if(operation == "+"):
            print (add(var1, var2))
        elif(operation == "-"): 
            print (subtract(var1, var2))
        elif(operation == "/"): 
            print (divide(var1, var2))
        elif(operation == "*"):
            print (multiply(var1, var2))
        else:
            print (power(var1, var2))
main()
input("Press enter to exit")
exit()

大约30分钟前,我找到了我的旧Python文件夹,并查看了8个多月前的所有基本脚本。我找到了我的计算器迷你脚本,并认为尽可能少地重新创建它会很有趣(我现在正在学习lambda)。这就是我所拥有的:

main = lambda operation,var1,var2: var1+var2 if operation=='+' else var1-var2 if operation=='-' else var1*var2 if operation=='*' else var1/var2 if operation=='/' else 'None'
print(main(input('What operation would you like to perform? [+,-,*,/]: '),int(input('Enter num1: ')),int(input('Enter num2: '))))
input('Press enter to exit')

我知道这是一个基于我的具体情况的个人问题,但我希望任何帮助缩短它的时间。有没有办法让它更像Pythonic?我正确使用lambda吗?有没有办法处理缩短版本中的错误?任何帮助,将不胜感激。我对此非常陌生。谢谢!

2 个答案:

答案 0 :(得分:0)

为了简化代码,我建议:

  1. 创建一个函数,借助字典来执行操作。

    注意:我根据用户提到的要求,使用lambda函数来替换替代方案。我个人会使用operator

    使用operator

    import operator
    
    def perform_operation(my_operator):
        return {
            '+': operator.add,
            '-': operator.sub,
            '*': operator.mul,
            '/': operator.truediv,  # "operator.div" in python 2
            '^': operator.pow,
       }.get(my_operator, '^')  # using `^` as defualt value since in your 
                                # "else" block you are calculating the `pow` 
    

    使用lambda

    def perform_operation(my_operator):
        return {
            '+': lambda x, y: x + y,
            '-': lambda x, y: x - y,
            '*': lambda x, y: x * y,
            '/': lambda x, y: x / float(y), 
            '^': lambda x, y: x ** y,
       }.get(my_operator, '^')  # using `^` as defualt value since in your 
                                # "else" block you are calculating the `pow()`
    

    示例运行:

    >>> perform_operation('/')(3, 5)
    0.6
    

    PS:看看定义,你会明白为什么使用operatorlambda

    更多pythonic
  2. 更新您的else区块以对其进行调用

    var1 = int(input("Enter num1: ")) 
    var2 = int(input("Enter num2: ")) 
    perform_operation(operation)(var1, var2)  # Making call to function created above
    # THE END - nothing more in else block
    
  3. 使用以下内容简化if条件

    if operation not in ["+", "-", "*", "/", "^"]:
        # invalid operation
    

答案 1 :(得分:0)

我知道这是一个有趣的自我挑战(我对你的压缩效果给我留下了深刻的印象),但我不妨提出一些关于lambda和pythonicity的一般建议。只有在使用内联代码时才能使用它们。

PEP-8表明使用lambda的唯一好处是它们可以嵌入到更大的表达式中。例如:

result = sorted(some_weird_iterable, key=lambda x: abs(x[0] - x[-1]))

如果要为方法分配标识符,请始终使用def,因为它为堆栈跟踪和理解提供了有价值的信息。事实上,如果它超出了最微不足道的情况,我建议完全避免使用lambdas来使它更清楚你正在做什么。

def as_the_bird_flies_distance(x):
    return abs(x[0] - x[-1])

result = sorted(some_weird_iterable, key=as_the_bird_flies_distance)

制作更多“Pythonic”的概念并不是为了缩短它。但是为了便于阅读,维护和扩展。

Python 2.7.11 (default, Jan 22 2016, 08:29:18) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!