'Is this an efficient calculator in Python?

Is this an efficient calculator in Python?

def calculator():

    print("\nBasic Calculator.\n")

    num_1 = input("Enter your first number: ")
    operation = input("Enter your operation: ")
    num_2 = input("Enter your second number: ")

    if operation == ("+"):
        sum = float(num_1) + float(num_2)
        print ("The answer is:",(sum))

    elif operation == ("-"):
        sum = float(num_1) - float(num_2)
        print ("The answer is:",(sum))

    elif operation == ("*"):
        sum = float(num_1) * float(num_2)
        print ("The answer is:",(sum))

    elif operation == ("/") and num_2 == ("0"):
        print ("\nYou cannot divide by zero.")

    elif operation == ("/"):
        sum = float(num_1) / float(num_2)
        print ("The answer is:",(sum))

    else:
        print("Invalid Operation.")

    restart = input("\nDo you want to enter another equation? Yes or No?").lower()

    if restart == ("yes"):
        calculator()

    else:
        print ("\nEnding Program.")
        quit()

calculator()



Solution 1:[1]

You can use eval()

a = 1
b = 2
operation = '/'
print(eval(f'{a} {operation} {b}'))
0.5

Handle shenanigans by users:

a = 1
b = 0
operation = '/'
try:
    print(eval(f'{a} {operation} {b}'))
except Exception as exp:
    print(exp)

Solution 2:[2]

Here is another basic example:

operations = {
    '+': lambda x, y: x + y,
    '-': lambda x, y: x - y,
    '*': lambda x, y: x * y,
    '/': lambda x, y: x / y,
}

try:
    x, sign, y = input("Enter expression separated by whitespace(ex: 2 + 3): ").split()
    if sign == '0':
        break
    else:
        print(operations[sign](int(x), int(y)))
except (ValueError, KeyError, ZeroDivisionError):
    print("Something went wrong, check your input")

Solution 3:[3]

It's decent, but reviews of working code belong on CodeReview.SE, not here.

  • Call the result variable result instead of sum, that obviously only is meaningful for addition.
  • As per AlexanderLekontsev's answer, you don't need a huge big if...else ladder that always computes result and prints the output. A dispatch dictionary to (binary or unary) lambda function is better. You could have all the functions be binary, and default arg2=None, that way you can handle unary functions.
  • You're assuming the user types in valid floats in response to num_1, num_2. But what if they press return? or type pi or e? or 'help' or :-D etc. You should catch the exception ValueError: could not convert string to floatand display the user's invalid input back to them, "expected a number"(/"operator").
    • You only need num_2 if operation is a binary not a unary operation, but future stuff like sqrt, log, log10, trigonometrics (sin, cos, tan), hyperbolics and their inverses (arc-fns) are all unary operations. Just something to keep in mind for the future. Don't hardwire your parser to one expected input sequence.
    • Inputting numbers could get more complicated in future. What if you wanted to support both hexadecimal 7e8 and float/general/exponential notation 7e8? You might need multiple try...except clauses. You might add a HEX mode in future. But then you'll need to generalize from num1 to say arg1, and if arg1 == HEX then enable(/toggle) hex mode, and recurse/loop.
  • Suggest printing print("Invalid Operation: must be +,-,*,/,..."), this actually tells the user which operations are legal. So: % isn't, neither is ^, neither is log, cos, sqrt etc.
  • So if you implement the above, you can support things like e^x
  • Supporting parentheses would require recursion.

Solution 4:[4]

Try this:

def calculate(num1, num2, operator):
    operator = operator.strip()
    if operator.strip() in ['+', '-', '*', '/']:
        if operator == '/' and eval(num2) == 0:
            return None
    try:
        result = eval(f'float({num1.strip()}) {operator} float({num2.strip()})')
    except:
        return ""
    return result

num1 = '3'
num2 = '5'
operator =  '+'

result = calculate(num1, num2, operator)

if result == '':
    print('Wrong expression !')
elif result == None:
    print('Dive bye zero !')
else:
    print(f'The answe is {result} !')

Solution 5:[5]

Your code is alright but we can improvise by using eval()

print(" Basic Calculator ")
i = ""
while i != 'exit':
    i = input(" Enter the expression to evaluate or type 'exit' to exit : ")
    print(eval(i))

Solution 6:[6]

Here is a very clean and short calculator script:

num1 = float(input("Enter a number: "))
op = (input("Enter an operation: "))
num2 = float(input("Enter another number: "))
if op == "*":   
    print(num1 * num2)
elif op == "/":
    print(num1 / num2)
elif op == "+":
    print(num1 + num2)
elif op == "-":
    print(num1 - num2)
elif op == "^":
    print(num1 ** num2)
else:
    print("error, you did not enter a supported operation")

Also if you were wondering ** means ^ or to the power of.

Solution 7:[7]

Try this: this calculator will take several inputs, and you can choose to clear the values or to delete it before computing the result.

values_collector = [] #empty list for all values
multi = 1
total = 0
index = 0

print('''For addition press the +,
         For Subtraction press the -
         For division press the /
         For Multiplication press the *''')

entries = int(input('Enter the number of the values you want to compute: '))
signs = input('Enter the sign: ')


while index < entries:
    my_input = int(input('Enter your values: '))
    values_collector.append(my_input)
    index +=1
    
to_remove = input('Do you want to remove any values, enter Y for yes and N for no ').upper()

if to_remove == 'Y':
    values_re=[]
    x = 0
    no_to_remove = int(input('How many variables do you want to remove: '))
    while x < no_to_remove:
        my_removed = int(input('Enter your values: '))
        values_re.append(my_removed)
        x +=1
        
    for y in values_re:
        values_collector.remove(y) 
        

my_clear = input("Do you want to clear all the values press Y for yes and N for No  ").upper()

if my_clear == 'Y':
    values_collector.clear()
    print('There is no values to compute because its cleared')

elif my_clear == 'N':
    if signs == '+':
        for x in range(len(values_collector)):
            total +=values_collector[x] 

    elif signs == '-':
        for x in range(len(values_collector)):
            total -=values_collector[x] 

    elif signs == '*':
        for x in range(len(values_collector)):
            multi *=values_collector[x] 
            total = multi

    elif signs == '/':
        for x in range(len(values_collector)):
            multi /=values_collector[x] 
            total = multi


    print('The computation of all the values {} is {}'.format(values_collector, total))
    
    
    enter code here

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 Alexander Lekontsev
Solution 3
Solution 4 Jason Yang
Solution 5 Anup Thomas
Solution 6
Solution 7 BrokenBenchmark