I am a beginner in Python, I want to know if this code can be improved. Is it possible to make it work without the if/else?
number1=int(input('Enter first number: '))
number2=int(input('Enter Second number: '))
operation=input("Enter operation\n[+,-,*,/]")
if operation == '+':
sum=number1+number2
elif operation == '-':
sum =number1-number2
elif operation == '*':
sum =number1*number2
else:
sum =number1//number2
print(sum)
2 Answers 2
If you don't want any if
statements then you can do the same with the operator
library and a dictionary. This is by using the dict.get
method that allows you to have a default value (operator.floordiv
) if the value isn't in the dictionary. After getting a valid function from the dictionary, you then just have to call the function.
import operator
operators = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul
}
number1 = int(input('Enter first number: '))
number2 = int(input('Enter Second number: '))
operation = input("Enter operation\n[+,-,*,/]")
print(operators.get(operation, operator.floordiv)(number1, number2))
I would however not assume division if the user enters random data. And so I'd add an if
and else
. In this case I'd check that the operator is in the operators
dictionary, and perform the operation if it is. If it isn't, then I'd tell the user that they entered an invalid operator:
operators = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.floordiv
}
if operation in operators:
print(operators[operation](number1, number2))
else:
print('Invalid operator')
You can also make the operator list in the input
automatically created from the dictionary too. To create the string '+,-,*,/'
you can use ','.join(['+', '-', '*', '/'])
, to get the array you can then use operators.keys()
. Finally you'd have to insert it into the rest of the string, and so I'd use str.format
.
operation = input("Enter operation\n[{}]".format(','.join(operators.keys())))
And so tying this all together you could use:
import operator
operators = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.floordiv
}
number1 = int(input('Enter first number: '))
number2 = int(input('Enter Second number: '))
operation = input("Enter operation\n[{}]".format(','.join(operators.keys())))
if operation in operators:
print(operators[operation](number1, number2))
else:
print('Invalid operator')
-
\$\begingroup\$ Adding to the conciseness, and in the spirit of teaching Python, there's also a chance here to use the ternary operator and Python's dynamic typing to change the last four lines to a single line:
print(operators[operation](number1, number2) if operator in operations else "Invalid Operator")
This is basically equivalent to writingprint(operation in operators ? operators[operation](number1, number2) : 'Invalid Operator')
in a different language, but only works in a dynamically typed language like Python \$\endgroup\$Joe– Joe2018年06月22日 13:21:58 +00:00Commented Jun 22, 2018 at 13:21 -
\$\begingroup\$ @QuantumHoneybees Honestly, I find it hard to read. And so I personally wouldn't recommend it here. \$\endgroup\$2018年06月22日 13:42:17 +00:00Commented Jun 22, 2018 at 13:42
-
\$\begingroup\$ The main goal was to introduce the ternary operator in Python, and so I do agree. Also, following the "zen of python"
readability counts
and your code is more readable, but I sometimes prefer a one-liner print statement for conciseness because too many if statements can make the code be unreadable \$\endgroup\$Joe– Joe2018年06月22日 20:33:16 +00:00Commented Jun 22, 2018 at 20:33
sum
you use sum
as a variable name, shadowing the builtin, which is generally a bad idea
function
Divide the program into functions with their own goal. Here you have following part
- get the 2 numbers
- get the operation
- do the calculation
- present the result
Get the numbers
you ask for an input, which you get returned as a str
. You convert this to a number with int
. If the input is not an integer value, this will crash the program, so you'll need some sort of input validation.
For the input validation, I will borrow a bit from this answer to another question
def ask_number(message='please enter a number', number_types=None):
if number_types is None:
number_types = (int, float, complex)
while True:
number = input(message)
for converter in number_types:
try:
return converter(number)
except ValueError:
pass
else:
print('Please enter a valid number')
In this way, you can specify which types are valid, and in which order they should be tried. You can even use custom types if you want.
This will keep asking until you have a valid number, and can be stopped with ctrl+c
, which will raise a KeyboardInteruptError
Get the operation
To make it easy for ourselves, we define the default options for operators
DEFAULT_OPERATIONS = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'//': operator.floordiv,
'/': operator.truediv,
'**': operator.pow,
'^': operator.pow,
}
This way we can call the function without arguments most of the times
def ask_operator(operators=None):
if operators is None:
operators = DEFAULT_OPERATIONS
message = f'Please select an operator from [{','.join(map(str, operators)))}]'
while True:
operator = input(message)
if operator in operators:
return operator
else:
print('Please enter a valid operator')
putting it together
def main():
operators = DEFAULT_OPERATIONS
number1 = ask_number('Please enter the first number:')
number2 = ask_number('Please enter the second number:')
operator_str = ask_operator(operators)
operator = operators[operator_str]
result = operator(number1, number2)
print(f'{number1} {operator_str} {number2} = {result}')
which you can put behing a if __name__ == '__main__'
-guard
if __name__ == '__main__':
main()
Explore related questions
See similar questions with these tags.
sum
as a variable name since it shadows a builtin. \$\endgroup\$//
), I don't have a non-if/else solution for that. At least without resorting toeval
, which should be avoided. \$\endgroup\$sum =number1//number2
, sure this totally represent a sum. \$\endgroup\$