HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

If Elif replacement for expandability

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
elifforexpandabilityreplacement

Problem

I am having the following problem. My code works, but it seems like it can improve a lot. I am fairly new to python and can't seem to get this block any better. The logic behind it goes like this.

I have a dictionary that acts like a tree, it looks like this:

SampleTree[10000000] = ['ACC','ARRAY']
SampleTree[10010000] = ['ACC_ABO','ABO']
SampleTree[10020000] = ['ACC_CHILDLOCK','OPTION']
SampleTree[10030000] = ['ACC_RECO','ARRAY']
SampleTree[10030100] = ['ACC_RECO_ACTIVATE']
SampleTree[10030200] = ['ACC_RECO_ACTIVATE']
SampleTree[10030201] = ['ACC_RECO_ACTIVATE']
SampleTree[10030202] = ['ACC_RECO_ACTIVATE']
SampleTree[10040000] = ['ACC_ADDUSER','OPTION']
SampleTree[10050000] = ['ACC_SETTINGS','ARRAY']


Where the dict key acts like a unique key, which I use to recognize in my program. I use a for loop to iterate over the full dict like this:

KEYLIST = SampleTree.keys()
KEYLIST.sort()

for KEY in KEYLIST :
    if (KEY % 1000000) == 0 :
        BACKS = 0
    elif (KEY % 1000000) == 10000 and (LAST % 1000000) == 0 :
        BACKS = 1
    elif (KEY % 10000) == 0 and (LAST % 1000000) == 10000 :
        BACKS = 2
    elif (KEY % 10000) == 100 and (LAST % 10000) == 0 :
        BACKS = 1
    elif (KEY % 10000) == 0 and (LAST % 10000) == 0 :
        BACKS = 2
    elif (KEY % 10000) == 0 and ((LAST % 10000) % 100) == 0 :
        BACKS = 3
    elif (KEY % 10000) == 0 and (LAST % 100) != 0 :
        BACKS = 4
    elif (KEY % 100) == 1 and ((LAST % 10000) % 100) == 0 :
        BACKS = 1
    elif (KEY % 100) == 0 and (LAST % 100) == 0 :
        BACKS = 2
    elif (KEY % 100) == 0 and (LAST % 100) != 0 :
        BACKS = 3
    elif (KEY % 100) != 0 and (LAST % 100) != 0 :
        BACKS = 2

    LAST=KEY


As you can see in the code, it uses a bunch of if elif tests to see in which branch the Key currently is. And accordingly it sets the BACKS variable how it should be. After this code there are a bunch of operation based on the KEY value and on the BACKS variable.

Solution

You've got tree paths encoded as integers such as: 10030201. Your code would much easier to write if instead they tuples like: (10, 03, 02, 01). If at all possible, you should change your dictionary to always use tuples. If not possible, have a function to convert the integers to tuples when you need them. If you do that, you'll find its fairly easy to devise a general implementation of your BACKS logic.

On the stylistic front: We typically use ALL_CAPS only for constants. We use lowercase_with_underscores for local variables which all of your stuff appears to be.

My solution:

def calculate_backs(source, destination):
    """
    Return how many "resets" are required to transform source into destination
    """

    def as_tuple(id_number):
        """
        Converts the id_number into a path sequence: 
        10010200 becomes (10, 1, 2)
        """
        pieces = []
        while id_number:
          pieces.append(id_number % 100)
          id_number /= 100
        pieces.reverse()

        # position 0 denotes a root node in the tree, so remove any trailing
        # zeros.
        while pieces[-1] == 0:
          pieces.pop()
        return tuple(pieces)

    def calculate(source, destination):
        if source and destination and source[0] == destination[0]:
            # If both source and destination agree for the first piece of the
            # path, drop that piece and determine the number of resets required
            # for the rest.
            return calculate(source[1:], destination[1:])
        else:
            # If the path disagrees on the first piece, we have to reset 
            # everything remaining in both paths.
            return len(source) + len(destination)

    return calculate(as_tuple(source), as_tuple(destination))

Code Snippets

def calculate_backs(source, destination):
    """
    Return how many "resets" are required to transform source into destination
    """

    def as_tuple(id_number):
        """
        Converts the id_number into a path sequence: 
        10010200 becomes (10, 1, 2)
        """
        pieces = []
        while id_number:
          pieces.append(id_number % 100)
          id_number /= 100
        pieces.reverse()

        # position 0 denotes a root node in the tree, so remove any trailing
        # zeros.
        while pieces[-1] == 0:
          pieces.pop()
        return tuple(pieces)

    def calculate(source, destination):
        if source and destination and source[0] == destination[0]:
            # If both source and destination agree for the first piece of the
            # path, drop that piece and determine the number of resets required
            # for the rest.
            return calculate(source[1:], destination[1:])
        else:
            # If the path disagrees on the first piece, we have to reset 
            # everything remaining in both paths.
            return len(source) + len(destination)

    return calculate(as_tuple(source), as_tuple(destination))

Context

StackExchange Code Review Q#63015, answer score: 3

Revisions (0)

No revisions yet.