A bit of context
I wrote a utility function (as shown below) having a string argument which returns a big message block, depending upon the value of argument.
I thought I wrote some great piece of code,....until I asked my friend to review.
# Code written inside a utility file
def do_something_important(a : str) {
if a == 'APPLE':
# A very large dictionary
message_1 = {....}
return message_1
elif a == 'ORANGE':
# Another very large dictionary
message_2 = {....}
return message_2
}
----
# Calling the above function in a separate file
get_message(a='APPLE')
Here’s how our conversation went ahead -
FRIEND: Why don’t you use python enum here?
ME: Say what? But why enum?
Enum is a class in python for creating enumerations, which are a set of symbolic names (members) bound to unique, constant values.
FRIEND: Well, think of it like this. In future, if some other engineer decides to change the string from APPLE to APPLE_PIE,
they will have to change in multiple places, where ever this function is called
or even worse, if they might only change it in the function call, but forgets to update the string in the main function get_message, then your service is doomed to fail.
# Calling with updated string
get_message(a='APPLE_PIE')
ME: That is a very unlikely case. Very rare chance of happening.
FRIEND: Even if something is very unlikely to happen, it can and will happen. Especially true in software engineering world 😈.
Remember the Murphy’s Law -
“Anything that can go wrong will go wrong”
ME: ** Remembering old days of horror… **
FRIEND: Now, let’s see how things turn out when we use enum in your current code.
utility.py
import enum
# Declare an enum class
class FruitType(enum.Enum):
APPLE = 'APPLE'
ORANGE = 'ORANGE'
common.py
from personal_project.service import utils as project_utils
# A dictionary to store messages acc. to enum member
CUSTOM_MESSAGES = {
project_utils.FruitType.APPLE.value: {....},
project_utils.FruitType.ORANGE.value: {....}
}
service.py
from personal_project.ui import CUSTOM_MESSAGES
from personal_project.service import utils as project_utils
# Fetch one of the custom message
get_apple_message = CUSTOM_MESSAGES[project_utils.FruitType.APPLE.value]
Let’s analyse -
Now, if someone wants to change the string value of a fruit type, they will have to go to the enum class FruitType, and just update the value there (only at a single place).
Also, this refactored code is much more clean and structured.
ME: ** Buys coffee for my friend **
THE END