Код близок, но я считаю, что ошибка происходит из-за чрезмерного усложнения того, как вы думаете о step
. Это значение просто должно быть правильным числом от go от 0 до 1 и наоборот для каждой комбинации, которую вы жестко запрограммировали. Ваша функция get_len
выполняет следующую операцию: (step + 1) * 5
, затем вы берете это значение и пытаетесь приблизиться к правильному размеру шага, заданному iteration
. Его можно уменьшить до len(combo) / iteration
, что даст вам правильное количество шагов при использовании операций +/-. Я думаю, это легче увидеть с помощью кода.
def gradient(iteration):
"""This function returns a list of HSL values
of all the colors in an order."""
ops = { '+': lambda c, step: min(1.0, c + step),
'-': lambda c, step: max(0.0, c - step)}
index = 0
operation = '+'
rgb, _list = [1.0, 0.0, 0.0], []
combo = ((2,1,0), (2,0,1), (0,2,1), (0,1,2), (1,0,2), (1,2,0))
step = len(combo) / iteration # The right calculation
for i in range(iteration):
if (rgb[combo[index][1]] == 1.0 and operation == '+') or \
(rgb[combo[index][1]] == 0.0 and operation == '-'):
operation = '-' if operation == '+' else '+'
index += 1
if len(combo) <= index: # Check isn't needed, but here for sanity
print('Break with index', index)
break
rgb[combo[index][1]] = ops[operation](rgb[combo[index][1]], step)
_list.append(rgb.copy()) # Make a copy to prevent mutation!
return _list
Чтобы проверить правильность, запустите следующее, и вы увидите, что оператор print
в break
не запускается, вы не получите an AssertionError
.
for i in range(1,100):
assert i == len(gradient(i))
Обратите внимание, что я внес два исправления в ваш исходный код: в операторе break
было неверное значение len(index) - 1
и добавлена копия rgb
в _list
, чтобы вы не получали одно и то же значение RGB снова и снова.
Думаю, это ответ на ваш вопрос, дайте мне знать иначе.