我想浓缩一些看起来像这样的湿代码:
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)
每次重复这段代码时,唯一改变的是背景画布(在这种情况下为wheel['slip']
),以及if ifif else中的数字。
我首先想到的就是制作一些可以像这样使用的东西:
if_replacer(wheel['slip'], slips[i], 3000, 3700, 4100, 4500)
def if_replacer(canvas, value, *args):
# idunno
我的问题是,如何以编程方式生成if elif else?我知道我可以像这样硬编码:
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)
但我很感兴趣,如果有简洁的Pythonic方法来实现这一点。
编辑:很多优秀的答案,但是我只能将其中一个标记为已被接受(尽管所有有效的解决方案都被赞成)。我接受了我在我的代码中实现的答案,但是对于遇到这个问题的其他人来说,看看其他解决方案,他们都非常出色。并且,感谢所有写过答案的人。
答案 0 :(得分:2)
这是一个可能的解决方案。
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)
请注意,least_bound_index
也可以称为index_between
,因为您可以想象数字行上的[a,b,c,d],它会告诉您这些选择的价值在哪里:
a b c d
^ ^ ^ ^ ^
0 1 2 3 4
答案 1 :(得分:2)
如果错误地省略了'setBackgroundOpacity',或者如果第一种情况中也包含它并不重要,那么这是您可能正在寻找的解决方案:
while ( (scanf ("%d", &number) ) == 0) {
printf("Entered value is not integer");
}
编辑:看到有关setBackgroundOpacity函数的评论
Edit2:修正了拼写错误并为10 ** 10
添加了替代解决方案color_map = [ (3000, 0, 0, 0),
(3700, .2, .4, .2),
(4100, 0, 1, 0),
(4500, 0, 0, 1),
(10**10, 1, 0, 0) ]
for i, (c, r, g, b) in enumerate(color_map):
if value < c:
ac.setBackgroundColor(wheel['slip'], r, g, b)
if i > 0:
ac.setBackgroundOpacity(wheel['slip'], 1)
break
答案 2 :(得分:1)
c = [[0,0,0],[.2,.4,.2],[0,1,0],[0,0,1]]
threshold = [3000,3700,4100,4500]
if slips[i] >= 4500:
ac.setBackgroundColor(wheel['slip'],1,0,0)
else:
for x in range(4):
if slips[i] < threshold[x]:
ac.setBackgroundColor(wheel['slip'],c[x][0],c[x][1],c[x][2])
break
if slips[i] >= 3000:
ac.setBackgroundOpacity(wheel['slip'], 1)
这是另一种选择,但我个人更喜欢@ mpurg的答案。
答案 3 :(得分:1)
我接受它(未经测试的实际ac...
次调用):
from functools import partial
mapping = [
(3000, (0, 0, 0), None),
(3700, (.2, .4, .2), 1),
(4100, (0, 1, 0), 1),
(4500, (0, 0, 1), 1),
(float('inf'), (1, 0, 0), 1)
]
def if_replacer(canvas, value, mapping):
set_color = partial(ac.setBackgroundColor, canvas)
set_opacity = partial(ac.setBackgroundOpacity, canvas)
for limit, vals, opacity in lookup:
if value < limit:
set_color(*vals)
if opacity is not None:
set_opacity(opacity)
break
然后,如果由于某种原因你必须选择新的范围,那么你可以做类似的事情:
from bisect import insort_left
insort_left(mapping, (4300, (1, 1, 1), 0))
将mapping
更新为:
[(3000, (0, 0, 0), None),
(3700, (0.2, 0.4, 0.2), 1),
(4100, (0, 1, 0), 1),
(4300, (1, 1, 1), 0),
(4500, (0, 0, 1), 1),
(inf, (1, 0, 0), 1)]
答案 4 :(得分:0)
def problem1_5(age):
"""Prints according to ages"""
if age(1<7):
print("Have a glass of milk")
elif age(7<21):
print("Have a cake")
elif age>21:
print("Have a martini")
else:
print(end='')