7
\$\begingroup\$

I've made this Function gradient() that returns a list of rbg of all the colors in an order.

Issues:-

  • What should be the condition for while loop to stop the loop. Though b == 0 in the last elif block works fine.

  • How can I reduce the code of the function keeping the functionality the same. Like if there is any better approach to doing this.

  • Also, How can I calculate the length of the rbg_list just with the value of gap parameter without running the function. Let's say the length of the rbg_list will be 1529 if gap=1 so I can iterate it with range(1529).


gradient() function:-

def gradient(gap=1):
    r, g, b = 255, 0, 0

    if gap<=0: 
        return (r, g, b)

    rbg_list = []
    while True:
        if  r == 255 and g >= 0 and g < 255 and b == 0:           # 1
            g += gap
            if g > 255:
                g = 255

        elif r <= 255 and g == 255 and r > 0 and b == 0:          # 2
            r -= gap
            if r < 0:
                r = 0
        
        elif r == 0 and g == 255 and b < 255 and b >= 0:          # 3
            b += gap
            if b > 255:
                b = 255
        
        elif r == 0 and g <= 255 and g > 0 and b == 255:          # 4
            g -= gap
            if g < 0:
                g = 0
        
        elif r >= 0 and g == 0 and r < 255 and b == 255:          # 5
            r += gap
            if r > 255:
                r = 255
        
        elif r == 255 and g == 0 and b > 0 and b <= 255:          # 6
            b -= gap
            if b < 0:
                b = 0
                
            if b == 0: break
        
        # print(r, g, b)
        rbg_list.append((r, g, b))
    return rbg_list

print(gradient(5))

Note:- I want the function to be compatible with both Python 2 and Python 3

\$\endgroup\$
3
  • \$\begingroup\$ Is this in python 2 or python 3? \$\endgroup\$
    – Linny
    Commented Jun 16, 2020 at 18:32
  • \$\begingroup\$ @Linny: I want it to run on both Python versions. \$\endgroup\$
    – Saad
    Commented Jun 16, 2020 at 18:33
  • \$\begingroup\$ Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers. \$\endgroup\$
    – Mast
    Commented Jun 17, 2020 at 9:28

1 Answer 1

6
\$\begingroup\$

I rarely do python nowadays, but cleanup of the conditions would be:

def add(c, gap):
    return min(255, c + gap)
   
def sub(c, gap):
    return max(0, c - gap)

def gradient(gap=1):
    r, g, b = 255, 0, 0

    if gap<=0: 
        return (r, g, b)

    rbg_list = []
    while True:
        if  r == 255 and g < 255 and b == 0:         # 1
            g = add(g, gap)

        elif r > 0 and g == 255 and b == 0:          # 2
            r = sub(r, gap)
        
        elif r == 0 and g == 255 and b < 255:        # 3
            b = add(b, gap)
        
        elif r == 0 and g > 0 and b == 255:          # 4
            g = sub(g, gap)
        
        elif r < 255 and g == 0 and b == 255:        # 5
            r = add(r, gap)
        
        elif r == 255 and g == 0 and b > 0:          # 6
            b = sub(b, gap)
                
            if b == 0: break
        
        # print(r, g, b)
        rbg_list.append((r, g, b))
    return rbg_list
    

Now let me understand what happens. Let us on paper name the 3 states for a color component x (r, g or b):

    a = x == 0
    b = 0 < x < 255
    c = x == 255 
    
    a :   == 0
    bc :  > 0
    c :   == 255
    ab :  < 255
    
    start: c a a
    
    c   ab  a    .+.  -->>  c c a
    bc  c   a    -..  -->>  a c a
    a   c   ab   ..+  -->>  a c c
    a   bc  c    .-.  -->>  a a c
    ab  a   c    +..  -->>  c a c
    c   a   bc   ..-  -->>  c a a
    

A very limited kind of gradient, restricted to one color component. This could be written as 6 loops:

        while g < 255:         # 1
            g += gap
            rbg_list.append((r, g, b))

        g = 255
        rbg_list.append((r, g, b))
            
        while r > 0:           # 2
            r -= gap
            
        r = 0
        rbg_list.append((r, g, b))

        ...

However you have just increasing from 0 by gap, and decreasing from 255 by gap. These would give two component value arrays which can then be used with the two other components 0 or 255. That should be exploitable in Python.

You might also calculate how many gap steps are needed for 255, times 6, and have a function that gives for the ith step the (r, g, b). That would be the simplest.

I admit I might be mistaken in what gradient calculation you want to achieve.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you for a good explanation, I really like how you simplify the function with add and sub functions. I've figured a calculation to find the total iterations according to the value given to gap by this len([c for c in range(0, 255, gap)])*6-1, this gives me the accurate value and also I've tested it by comparing to the length of the list with different gap values, but I'm not sure if this is how it should be calculated. \$\endgroup\$
    – Saad
    Commented Jun 16, 2020 at 21:00
  • \$\begingroup\$ You forget to return the values of functions add and sub. \$\endgroup\$
    – Saad
    Commented Jun 16, 2020 at 21:21
  • 2
    \$\begingroup\$ Thanks, @StephenRauch corrected that. If you write out the loop, add/siub are not needed too, only for the <= 0, >= 255 value one, which then becomes an assignment = 0, resp. = 255. The total number of iterations could also be done with approx. (255/gap) * 6 with careful rounding. Maybe faster then range. \$\endgroup\$
    – Joop Eggen
    Commented Jun 17, 2020 at 6:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.