I have a function that looks something like this:
function_name(step, ... , typ):
if typ == 'some type of calc method':
if step == 1:
do_me_at_step_1(...)
elif step == 2:
do_me_at_step_2(...)
elif ...
elif typ == 'another calc method':
if step == 1:
do_me_at_step_1(...)
elif ...
Hopefully the general structure is clear here. What are the differences between the different typ
s and how they are handled? There is one instance of typ
which changes one variable in a very different way from all the others. All instances of typ
vary in the number of separate step instructions, ranging from an if step == 1: ... else:
to if step == 1 ... elif step == 5 ... else
. The last elif
and the else
statements are different, basically.
How can I better structure this function, because it currently looks horrific?
My thought was to pull out all the initial steps…but I have to have a way to associate each typ
with the step which becomes "key". So I thought somewhere along the lines of:
function_name(step, ... , typ):
orders = {typ1:key_step, typ2:key_step, ...}
while key_step['typ1'] != step:
if step == 1:
...
step +=1
But I noticed two problems: one, this doesn't really fully take advantage of the while loop. It would require me to add if statements up until the max step out of all the typ
s that is not "key" in there, which doesn't seem to me to really take advantage of the information in orders
.
The other problem is once you are out of the while loop. I suppose you could do something like
if typ == 'something':
do_the_key_step_function_for_this_typ(...)
but this really isn't doing anything new to clean up this function. How can I change the structure of this code so it is cleaner and shorter? There's an underlying structure, so I feel like there should be a better way to do this.
Feel free to ask me if you need any specifics about this function, but hopefully there are enough details provided here. Thanks!
Best Answer
Your initial function executes one specific step for one specific type, both of them being provided as argument. In the second case you iterate over steps trying to find the right one.
Alternative 1: double dictionary
Based on your alternative, I propose you to consider a dictionary of dictionaries, using two indexes instead of just one. Exemple:
So in this case, your function_name() just finds the function to invoke using a dictionary of dictionaries, and then invokes them.
Alternative 2: object oriented code ?
You could also consider using an object oriented approach:
So in fact, you'd create different classes, each corresponding to a different type. And then you'd invoke for an instantiation of one specific class the method corresponding to the step.
In fact, the implementation would be very close to the the state pattern