# functions.py import numpy as np def calculate_average(arr): return np.mean(arr) def calculate_standard_deviation(arr): return np.std(arr)
In the main program, we need to select desired algorithm to process calculation for array input.
Hard-coded implementation
Below is kind of 'level-one' implementation for the main program. Needless to say, we are forced to modify the program as soon as any new function will be implemented in functions module and we would like to use that new function in the main program.
import functions try: arr = [1, 2, 3, 4, 5] selection = 1 if(selection == 1): result = functions.calculate_average(arr) elif(selection == 2): result = functions.calculate_standard_deviation(arr) else: raise Exception('Selected function is not implemented.') print(result) except Exception as e: print(e)
Flexible implementation
Fortunately, there are ways to get out of such hard-coded scheme for selecting algorithm and this post is only presenting one such possibility. First, let us implement the following json configuration file. In this file, we are configuring the name of the function what we would like to use in our main program.
{
"function_name": "calculate_standard_deviation"
}
In our new main program, we create configurations from the previous file and read function name from it. Then, by using hasattr function we check, if functions module is containing configured function. After this, we use getattr function to get reference to configured function. Finally, we will use the function and print calculation result.
import json import functions try: arr = [1, 2, 3, 4, 5] # create configurations path = '//temp/configurations.json' configurations = json.load(open(path, 'r')) function_name = configurations['function_name'] if(hasattr(functions, function_name)): function = getattr(functions, function_name) result = function(arr) else: raise Exception('Calculation cannot be processed due to incorrect function configuration.') print(result) except Exception as e: print(e)
Assume there would be a new function implementation in functions module and we would like to use that new function in our main program. In this flexible implementation, there would be no need to touch the main program here. Required change (run-time information of what function will be used) has now been isolated to configurations file.
From purely technical point of view, presented scheme is far from being 'traditional' Strategy pattern implementation starting from the fact, that there is no class hierarchy. However, code is receiving run-time instructions (from configurations file) for selecting a specific algorithm (from all functions available). At least for me, this is the essence of Strategy design pattern.
Finally, thanks for reading this blog.
-Mike