'Simplifying code - perform mathematical operations based on operator
Here is the code for a calculator in 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()
About 30 minutes ago I found my old Python folder and took a look at all my basic scripts from 8+ months ago. I found my calculator mini-script and thought it would be fun to recreate it in as few lines as possible (I'm just now learning lambda). Here's what I have:
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')
I know this is a personal question based off of my specific situation, but I would appreciate any help making it shorter. Is there a way to make it more Pythonic? Am I using lambda correctly? Is there a way to handle errors in my shortened version? Any help would be appreciated. I'm very new to this. Thanks!
Solution 1:[1]
In order to simplify the code, I will suggest to:
- Create a function to perform operation taking the help of dictionary.
Note: I shared the alternative with lambda
function based on requirement mentioned by user. Personally I would use operator
, as it is much cleaner.
Using `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`
Using `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()`
Sample run:
>>> perform_operation('/')(3, 5)
0.6
PS: Looking at the defination you would have got the idea why using operator
is more pythonic than lambda
Update your
else
block to make a call to it as: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
Simplify your
if
condition with:if operation not in ["+", "-", "*", "/", "^"]: # invalid operation
Solution 2:[2]
I understand this is a for fun self-challenge (and I'm impressed by how well you compressed it), but I might as well give some general advice for lambda and pythonicity like you asked. Only use them when you're doing inline code.
PEP-8 suggests the only benefit of using lambda is that they can be embedded inside a larger expression. For example:
result = sorted(some_weird_iterable, key=lambda x: abs(x[0] - x[-1]))
When you want to assign a identifier to a method, always use def
because it gives you valuable information in stack traces and understanding. In fact, if it's anything beyond the most trivial case, I'd suggest avoiding lambdas entirely to make it clearer what you are doing.
def as_the_bird_flies_distance(x):
return abs(x[0] - x[-1])
result = sorted(some_weird_iterable, key=as_the_bird_flies_distance)
The concept of making something more "Pythonic" is not to shorten it. But to make it easier to read, maintain and expand.
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!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |