patternpythonMinor
If Elif replacement for expandability
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:
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:
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.
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=KEYAs 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:
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:
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.