BuggyLemon
BuggyLemon

Reputation: 37

Isn't using eval() with a dictionary a better way in this case?

The two functions below perform an arithmetic operation on two integers and return an integer result.

I've heard a lot about eval() being really bad to use because it can cause many problems. But taking a look at the code I've written below, it seems that eval() spares many lines of code, right?

def dict_calculate(operation, num1, num2):
    operations = {'add': '+', 'subtract': '-', 'multiply': '*', 'divide': '//'}
    return eval(str(num1) + operations[operation] + str(num2))

def conditional_calculate(operation, num1, num2):
    if operation == 'add':
        return num1 + num2
    if operation == 'subtract':
        return num1 - num2
    if operation == 'multiply':
        return num1 * num2
    if operation == 'divide':
        return num1 // num2

if __name__ == "__main__":
    x = 10
    y = 5

    print(str(dict_calculate('add', x, y)) + ', ', end='')
    print(str(dict_calculate('subtract', x, y)) + ', ', end='')
    print(str(dict_calculate('multiply', x, y)) + ', ', end='')
    print(str(dict_calculate('divide', x, y)))

    print(str(conditional_calculate('add', x, y)) + ', ', end='')
    print(str(conditional_calculate('subtract', x, y)) + ', ', end='')
    print(str(conditional_calculate('multiply', x, y)) + ', ', end='')
    print(str(conditional_calculate('divide', x, y)))

Outputs are the same for both functions

15, 5, 50, 2
15, 5, 50, 2

Isn't eval best to use in this type of case? If not, is there a better way than eval() to achieve this same type of code-efficiency?

Thanks a lot.

Upvotes: 0

Views: 51

Answers (1)

Julien Spronck
Julien Spronck

Reputation: 15433

You can do this:

import operator
def dict_calculate(operation, num1, num2):
    operations = {'add': operator.add,
                  'subtract': operator.sub,
                  'multiply': operator.mul,
                  'divide': operator.floordiv}
    return operations[operation](num1, num2)

If you don't want to import another module, you can do this:

def dict_calculate(operation, num1, num2):
    operations = {'add': '__add__',
                  'subtract': '__sub__',
                  'multiply': '__mul__',
                  'divide': '__floordiv__'}
    return getattr(num1, operations[operation])(num2)

Upvotes: 5

Related Questions