CodeWars: RGB To Hexadecimal
Table of Contents
Description
Given three arguments r
, g
, and b
which are integers from 0 to 255 representing RGB values, convert them to a six digit (zero-padded) hexadecimal string. Invalid (out of range) values need to be rounded to nearest value.
The Code
Imports
# pypi
from expects import equal, expect
Submission
HEX_DIGITS = "0123456789ABCDEF"
RGB_TO_HEX = dict(zip(range(len(HEX_DIGITS)), HEX_DIGITS))
HEX = 16
def rgb(r: int, g: int, b: int) -> str:
"""Convert RGB to Hexadecimal
If the values are out of bounds they will be set to the nearest limit
e.g. -1 becomes 0 and 2919 becomes 255
Non-integers will raise an error
Args:
r: red channel (0-255)
g: green channel (0-255)
b: blue channel (0-255)
Returns:
6-digit hexadecimal equivalent of r, g, b
"""
colors = (max(min(color, 255), 0) for color in (r, g, b))
converted = ((RGB_TO_HEX[color//HEX], RGB_TO_HEX[color % HEX])
for color in colors)
return "".join((y for x in converted for y in x))
expect(rgb(0,0,0)).to(equal("000000"))
expect(rgb(1,2,3)).to(equal("010203"))
expect(rgb(255,255,255)).to(equal("FFFFFF"))
expect(rgb(254,253,252)).to(equal("FEFDFC"))
expect(rgb(-20,275,125)).to(equal("00FF7D"))
Alternatives
A surprising number of people used the string formatting - {:02X}
to convert the numbers to hexadecimal. I think that's sort of the problem with these earlier puzzles - there's a big question of how much of python's built in functionality you should use. I guess since I use string formatting a lot that might make sense as a shortcut in this case.
def rgb_2(r: int, g: int, b: int) -> str:
"""Convert RGB to Hexadecimal
If the values are out of bounds they will be set to the nearest limit
e.g. -1 becomes 0 and 2919 becomes 255
Non-integers will raise an error
Args:
r: red channel (0-255)
g: green channel (0-255)
b: blue channel (0-255)
Returns:
6-digit hexadecimal equivalent of r, g, b
"""
return "".join((f"{max(min(color, 255), 0):02X}" for color in (r, g, b)))
expect(rgb_2(0,0,0)).to(equal("000000"))
expect(rgb_2(1,2,3)).to(equal("010203"))
expect(rgb_2(255,255,255)).to(equal("FFFFFF"))
expect(rgb_2(254,253,252)).to(equal("FEFDFC"))
expect(rgb_2(-20,275,125)).to(equal("00FF7D"))
Not quite so readable, but short.