Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to write a function that performs different calculations depending on a parameter?

I just would like to know what is the best approach to writing a function that performs different calculations depending on a parameter.

As an extremely simple example, let's say that I want a function that either multiply or divide two numbers depending on the value of the parameter that should only take two values, 'multiply' or 'divide'. What I would do is something like this:

def simple_operation(a, b, operation):
    if operation == 'divide':
        return a / b
    elif operation == 'multiply':
        return a * b


print(simple_operation(3, 9, 'multiply'))

In my particular case, I want to calculate the equilibrium constant of a reaction as a function of temperature and there are different ways to do that. For example, using van 't Hoff equation or calculating the formation properties at a specific temperature. Each way (both have pros and cons) would need a fair amount of lines so I don't know what's the best approach, I feel like there might be a better way than using if-statements with a lot of code for each case. I would like to know how experienced programmers approach this kind of situations.

like image 372
JaffXXI Avatar asked Mar 05 '23 01:03

JaffXXI


1 Answers

Use a dict:

def simple_operation(a, b, operation):
    operations = {
        'divide'  : lambda a, b: a / b,
        'multiply': lambda a, b: a * b,
    }
    return operations.get(operation)(a, b)

You can add a default function for unknown operations:

def simple_operation(a, b, operation):
        def err(*_):
            raise ValueError("Operation not accepted")
        operations = {
            'divide'  : lambda a, b: a / b,
            'multiply': lambda a, b: a * b,
        }
        return operations.get(operation, err)(a, b)

You can reference anything in the dict, it may be good to use plain funtions instead of lambdas or the operator module:

import operator
def simple_operation(a, b, operation):
        def err(*_):
            raise ValueError("Operation not accepted")
        operations = {
            'divide'  : operator.truediv,
            'multiply': operator.mul,
        }
        return operations.get(operation, err)(a, b)
like image 86
Netwave Avatar answered Apr 26 '23 09:04

Netwave