I would like to condense some wet code that looks like this:
if slips[i] < 3000:
ac.setBackgroundColor(wheel['slip'], 0, 0, 0)
# setBackgroundOpacity deliberately omitted here
elif slips[i] < 3700:
ac.setBackgroundColor(wheel['slip'], .2, .4, .2)
ac.setBackgroundOpacity(wheel['slip'], 1)
elif slips[i] < 4100:
ac.setBackgroundColor(wheel['slip'], 0, 1, 0)
ac.setBackgroundOpacity(wheel['slip'], 1)
elif slips[i] < 4500:
ac.setBackgroundColor(wheel['slip'], 0, 0, 1)
ac.setBackgroundOpacity(wheel['slip'], 1)
else:
ac.setBackgroundColor(wheel['slip'], 1, 0, 0)
ac.setBackgroundOpacity(wheel['slip'], 1)
Each time this snippet of code is repeated, the only things that change are the background canvas (wheel['slip']
in this case), and the numbers in the if elif else's.
My first thought to dry this up was to make something that could be used like this:
if_replacer(wheel['slip'], slips[i], 3000, 3700, 4100, 4500)
def if_replacer(canvas, value, *args):
# idunno
My question is, how would I programmatically generate the if elif else's? I know I could hard-code it like so:
def if_replacer(canvas, value, c1, c2, c3, c4):
if value < c1:
ac.setBackgroundColor(canvas, 0, 0, 0)
return
elif value < c2:
ac.setBackgroundColor(canvas, .2, .4, .2)
elif value < c3:
ac.setBackgroundColor(canvas, 0, 1, 0)
elif value < c4:
ac.setBackgroundColor(canvas, 0, 0, 1)
else:
ac.setBackgroundColor(canvas, 1, 0, 0)
ac.setBackgroundOpacity(canvas, 1)
But I'm interested if there is a succinct and Pythonic method to accomplish this.
edit: A lot of excellent answers, but alas I can only mark one of them as accepted (though all valid solutions were upvoted). I accepted the answer that I implemented in my code, but for anyone else who stumbles across this question, do take a look at the other solutions, they're all excellent. And, thanks to everyone who wrote an answer.
Here's one possible solution.
def least_bound_index(value, bounds):
"""return the least index such that value < bounds[i], or else len(bounds)"""
for i, b in enumerate(bounds):
if value < b:
return i
return i+1
bounds = [3000, 3700, 4100, 4500]
bgcolors = [(0, 0, 0), (.2, .4, .2), (0, 1, 0), (0, 0, 1), (1, 0, 0)]
i = least_bound_index(slips[i], bounds)
ac.setBackgroundColor(wheel['slip'], *bgcolors[i])
if i > 0:
ac.setBackgroundOpacity(wheel['slip'], 1)
Note that least_bound_index
could also be called index_between
because you could imagine [a, b, c, d] on a number line, and it would tell you where the value lands out of these choices:
a b c d
^ ^ ^ ^ ^
0 1 2 3 4