1

Right now, I have code that converts R, G, and B color values to hexadecimal.

However, if the user enters invalid numbers (e.g. -20) it will return a completely random number.

My code is:

def rgb(r, g, b):
    if r < 0:
        r = 0
    elif r > 255:
        r = 255
    if g < 0:
        g = 0
    elif g > 255:
        g = 255
    if b < 0:
        b = 0
    elif b > 255:
        b = 255
    return '%02x%02x%02x'.upper() % (r,g,b)

However, I don't want to have to put all the if/elif statements, because they take up too much space. Is it possible to do something like r.range(0,255) to change an invalid number to the closest one? For example, -20 would be changed to 0, and 300 would be 255.

Any help would be appreciated.

Vangelis
  • 108
  • 1
  • 11
  • possible duplicate of [How to limit a number to be within a specified range? (Python)](http://stackoverflow.com/questions/5996881/how-to-limit-a-number-to-be-within-a-specified-range-python) – Paul Feb 06 '15 at 02:19

3 Answers3

3

I think the idiom most people use looks like this for some value:

maxValue = 255
minValue = 0

min(maxValue, max(minValue, value))
Mark
  • 90,562
  • 7
  • 108
  • 148
2

If you want to be fancy about it, this works nicely:

r, g, b = (min(255, max(0, c)) for c in (r, g, b))

Example:

In [1]: r, g, b = -1, 145, 289

In [2]: r, g, b = (min(255, max(0, c)) for c in (r, g, b))

In [3]: r, g, b
Out[3]: (0, 145, 255)
fletom
  • 1,998
  • 13
  • 17
  • Your first code example has max an min reversed. `[max(255, min(0, c)) for c in (-10, 300, 150)]` returns `[255, 255, 255]` – Mark Feb 06 '15 at 02:25
2

If your values are always packed as a "list-like" structure (e.g., tuple, list, numpy array), then consider using Numpy's clip function. Then, in the following example, you can avoid unpacking the values into the variables r, g, and b.

#!/usr/bin/env python


import numpy as np


def clip(r, g, b, min_val=0, max_val=255):
    return tuple(np.clip((r, g, b), min_val, max_val))


def main():
    x = clip(-20, 1, 256)
    print(x)

    x = clip(0, 300, -1)
    print(x)

    x = clip(1, 100, 255)
    print(x)

    y = (-20, 1, 256)
    y = clip(*y)  # Unpack y into r, g, b, if you like
    print(y)


if __name__ == '__main__':
    main()

Output:

(0, 1, 255)
(0, 255, 0)
(1, 100, 255)
(0, 1, 255)
lightalchemist
  • 10,031
  • 4
  • 47
  • 55