DEV Community

Cover image for HyperCubed !! Easy State Management simplifying 2^n conditions
Arka Bhowmik
Arka Bhowmik

Posted on • Edited on

HyperCubed !! Easy State Management simplifying 2^n conditions

Do you have backend code looking like this ? or something similar?

if condition1:
    if condition1.1:
        do this
        if condition1.1.1:
            do that
        if condition1.1.2:
            do this
            if condition 1.1.2.1:
                do that
    else if condtion2:
        do that
    else:
        do that
Enter fullscreen mode Exit fullscreen mode

This arises when you have unplanned state management arising from unstructured conditions. Having too many nested conditions will affect readability and mantainability of your code. So lets simplify this. Lets have no branching at all .

NOTE:

The approach followed below assumes that the states we are working with are somewhat related to one another.
Also, this approach is only useful for cases where the nested branching level is >=3
The approach focuses on identifying the core components of a condition and minimize redundant checks and transitions

The simplicity of Bit Logic:

We formulate each condition as a state. Let's try with an example where you have 8 different outcomes of your problem which means that there are 8 different output states. Let's number them from State0, State1, State2 to State7.
So the binary representation of every state, based on its index will be from [000 to 111]. For our simple example these states are the human states of mind:
[HAPPY ,IRRITATED ,BUSY ,ANGRY, LONELY, BAD, SAD ,EVIL]
Based on our mood, we will perform some action. But do we need 8 branching conditions for this ? Also, what happens if our mental state changes to a different mood, we write new code for that ? NEVER AGAIN !!!!

Finding a relation between the states by Filtering CORE conditions/states:

Our motive is simple, we need to plan our states in such a way that every bit corresponding to the state's index, has some information associated with it. For this we map all states in a visualization space and see the interdependencies the states have between eachother. The interdependencies will be such that if one state leads to another state by changing a core condition/state, we can say that they are separated by one bit or 1 hamming distance.
Lets clear this up by looking at the diagram of the hypercube with 3 dimensions where we have mapped these states in an open space, with arrows denoting state transitions/ dependencies.

( number of dimension in hypercube = number of bits = number of CORE conditional elements in your state)

Now imagine
Alt Text

For simplicity of understanding, we work with the human emotional state, where one mood can be altered by another mood state . Lets assign the bits at each of the 3 positions from MSB to LSB to denote the states :

IRRITATED = 1 LSB set for irritated (001)
BUSY = 2 MiddleSB set for busy. (010)
LONELY = 4 MSB set for lonely. (100)

these are our core conditional elements in our state transition diagram whose occurence can alter any state. This basically means that between all possible states. All different combinations of these 3 core states, will give us all the different states we have defined below:

HAPPY = 0          # 000 NO BAD FLAGS SET [ INITIAL STATE]
IRRITATED = 1      # 001 [CORE STATE LSB]
BUSY = 2           # 010 [CORE STATE mid-bit]
ANGRY = 3          # 011 BUSY   | IRRITATED
LONELY = 4         # 100 [CORE STATE MSB]
BAD = 5            # 101 LONELY | IRRITATED
SAD = 6            # 110 LONELY | BUSY
EVIL = 7           # 111 SAD    | IRRITATED
Enter fullscreen mode Exit fullscreen mode

And we have a planned dependency between all our states !. We can now map what we intend to do when we are in that state, by mapping a function to that state. Check out the code snippet below. Each index [i] in the to_do list defines what the person wants to do when he in the [i]th state . If your states are not of 2^n , consider having a hashmap with :
{STATE_NAME: corr_function_name}

# DEMO HYPERCUBE STYLE PROGRAM DESIGN
class Moods:

    # seggregating basic states which can alter mood state logically
    #IRRITATED = 1      LSB  set for irritated
    #BUSY = 2           MiddleSB set for busy
    #LONELY = 4         MSB set for lonely

    HAPPY = 0          # 000 NO BAD FLAGS SET
    IRRITATED = 1      # 001
    BUSY = 2           # 010
    ANGRY = 3          # 011 BUSY   | IRRITATED
    LONELY = 4         # 100
    BAD = 5            # 101 LONELY | IRRITATED
    SAD = 6            # 110 LONELY | BUSY
    EVIL = 7           # 111 SAD  | IRRITATED

    # a list or a dict mapped corresponding to  above states. can be a list of function-pointers,
    # responses, emails and what not , based on your functional requirements!
    things_to_do = ["I'll go on a trip", "I need to break a vase or something" ,
     "I'll post an article on dev.to", "I'll eat an entire chocolate cake ",
      "I'll go to sleep", "I'll jump on my best friend",
       "I'll cry in a corner", "I kill some people in GTA V"]

    def __init__(self):
        self.mood = Moods.HAPPY

    def get_action(self):
        # performs a function based on current state. (customize this as required)
        return self.things_to_do[self.mood]

    def alter_state(self, added_mood):
        # alters current state based on external state or intervention
        # you can XOR it for neutralizing current state too, if you want instead
        self.mood = self.mood | added_mood

Enter fullscreen mode Exit fullscreen mode

Since we know our state dependencies, lets run our code now and try to change our state to another state without having to touch another branching condtion.
Lets make Timm'ys mood BAD.

timmy = Moods()
print timmy.get_action()
timmy.alter_state(Moods.BAD)
print timmy.get_action()
Enter fullscreen mode Exit fullscreen mode

output:

I'll go on a trip
I'll jump on my best friend
Enter fullscreen mode Exit fullscreen mode

Looks like Timmy responded to his mood swings ! That too without getting our hands dirty.

Some possible use-cases:

  • API for Sending emails to people based on -> Their ROLE + ACTION_TYPE + SENDER
  • API responses
  • State based games

Some related articles for better coding approaches in API programming:

Avoiding Boilerplates

Also I came across this amazing video by Computerphile ! which helped me coin a Terminology for this programming style of mine:

The Perfect Code - Computerphile

SOLID design pattern principles in OOPS

FUNCTIONAL DESIGN PATTERNS

Top comments (0)