1

I'm trying to achieve function without using:

if op == '+':

    return a+b

if op == '-':

    return a+b

if op == '*':

    return a+b

if op == '/':

    return a+b
def calculator():
    """op will be a sign that used between a and b, a op b ==?"""

    a = int(input('a: '))
    b = int(input('b: '))
    op = (input('op: '))
    basic = ['+','-','*','/']
    if op not in basic:
        return 'this is a base calculator, use + - * / only'
    else:
        return a op b
ggorlen
  • 44,755
  • 7
  • 76
  • 106
harris
  • 21
  • 1
  • Possible duplicate of [Turn string into operator](https://stackoverflow.com/questions/1740726/turn-string-into-operator) – ggorlen Sep 19 '19 at 17:39

1 Answers1

2

You could do this with eval(f"{a}{op}{b}"), but it's a security risk.

A better approach might be use operator, which are function wrappers on the primitive operations (but we still need a dict to convert the symbol to a name):

import operator

ops = {
    "+": operator.add,
    "-": operator.sub,
    "*": operator.mul,
    "/": operator.truediv,
}
a = 7
b = 6
op = "*"
print(ops[op](a, b)) # => 42

You could wrap this in a try/except block to catch unsupported operations (and division by zero):

import operator

def calculate(op, a, b):
    try:
        return {
            "+": operator.add,
            "-": operator.sub,
            "*": operator.mul,
            "/": operator.truediv,
        }[op](a, b) 
    except KeyError: pass

if __name__ == "__main__":
    a = int(input('a: '))
    b = int(input('b: '))
    op = input('op: ')
    result = calculate(op, a, b)

    if result is None:
        print('this is a base calculator, use + - * / only')
    else:
        print(result)

It's a good idea to move user interaction outside of the function to enforce single responsibility and avoid side effects.

Todo: improve error handling if user fails to enter an int and add a loop for multiple prompts.

ggorlen
  • 44,755
  • 7
  • 76
  • 106