-3

I recently wrote a program that calculates the hex value when given rgb values. I was just wondering if my code is terrible (i did my best to write it from scratch without much help). I'm still a beginner and trying to learn.

Any help would be greatly appreciated (guidance about how i could do things better etc.).

Thank you

# sets the HEX letters for numbers above 9
hex_table = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8, '9':9,
            'a':10, 'b':11, 'c':12, 'd':13, 'e':14, 'f':15}
# creates variable for the keys in dictionary
key_list = list(hex_table.keys())
# creates variable for values in dictionary
val_list = list(hex_table.values())



def test(r= int(input('red value: ')),g= int(input('green value: ')), b= int(input('blue value: '))):
    # finds the index of the value
    red_value = r // 16
    green_value = g // 16
    blue_value = b // 16
    
    # Calcuate the remainder
    red_float = float(r) / 16
    red_remainder = red_float % 1

    green_float = float(g) / 16
    green_remainder = green_float % 1

    blue_float = float(b) / 16
    blue_remainder = blue_float % 1

    # adds '#' in front of the result
    print('#',end='')

    #find the first two values in HEX code
    if r >= 10:
        print(key_list[val_list.index(red_value)],end='')
        second_letter = (int(red_remainder * 16))
        print(key_list[val_list.index(second_letter)],end='')
    elif r <10:
        print(red_value,end='')
        print(int(red_remainder * 16),end='')
    
    #find the next two values
    if g >= 10:
        print(key_list[val_list.index(green_value)],end='')
        second_letter = (int(green_remainder * 16))
        print(key_list[val_list.index(second_letter)],end='')
    elif g <10:
        print(green_value,end='')
        print(int(green_remainder * 16),end='')

    #find the last two values
    if b >= 10:
        print(key_list[val_list.index(blue_value)],end='')
        second_letter = (int(blue_remainder * 16))
        print(key_list[val_list.index(second_letter)],end='')
    elif b <10:
        print(blue_value,end='')
        print(int(blue_remainder * 16),end='')

test()
total_due
  • 7
  • 3
  • 4
    More suitable in https://codereview.stackexchange.com/ . Also https://stackoverflow.com/questions/3380726/converting-a-rgb-color-tuple-to-a-six-digit-code-in-python – Equinox Nov 17 '20 at 11:40
  • Does this answer your question? [RGB to hex and hex to RGB](https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb) – Jasar Orion Nov 17 '20 at 13:06

3 Answers3

0

You could reduce the amount of code by a lot by reducing the amount of times you repeat yourself, you are calculating the values for the digits for all three colours in the same function, therefore repeating yourself 3 times.

I've wrote my answer using JavaScript but I will explain what I am doing.

function getDigit(val) {
    var alphabet = ["a", "b", "c", "d", "e", "f"]
    if (val >= 10 && val < 16)
        val = alphabet[val - 10];

    return val.toString();
}

function helper(val) {
    var first = Math.floor(val / 16)
    var second = val % 16;
    
    return getDigit(first) + getDigit(second)
}

function rgbToHex(red, green, blue) {
    return helper(red) + helper(green) + helper(blue);
}

I have created two functions to help calculate the digits for each of the RGB values. The helper() function calculates two numbers for the first and second digits. Lets use 24 and 172 as an example.

To find the first digit, you can divide the value by 16, and Floor the answer so it rounds down to a single digit.

24 / 16 = 1.5, Floor(1.5) = 1;

Therefore are first digit is 1.

And for the second digit we take the remainder of the value divided by 16.

24 % 16 = 8

So the full value for would be 18

Lets see 172 now.

172 / 16 = 10.75, Floor(10.75) = 10;

This will not work because the value should be "a" rather than "10", this is where the getDigit() function comes in, this function will take the value and check if it is between 10 and 15. We then take 10 from the value to find which letter we should use from the 'alphabet' array.

So for 10, we get 10 - 10 = 0; which means we will use the value at index 0 which gives us "a"

We can do the same for the second digit

172 % 16 = 12; Now the getDigit() function is called again.

12 - 10 = 2; so we take the item from index 2 in the array, which is "c"

so for 172 the value will be ac

AaronReed17
  • 26
  • 1
  • 4
  • thank you so much for your help! much appreciated. I went over my code and made it more compact, hopefully it's in the right direction : ) – total_due Nov 18 '20 at 01:26
  • hi, glad I could help. Also I realised that you can just convert the numbers the user enters in to a base 16 number which would make the program even smaller. With JavaScript I believe it was `172.toString(16) = ac` – AaronReed17 Nov 18 '20 at 08:55
  • Cheers, thank you for that. I'm a super beginner, i understand there are way simpler ways to work it out. I guess the point is in doing it from scratch by myself without looking for the answers. I feel in this way i can probably learn better than if i were to just look at answer without trying myself first : ) – total_due Nov 18 '20 at 10:42
  • Definitely! Your question is what made me think about this problem myself, its always more fun when you achieve the result you wanted through your own methods no matter how good or bad they may be. Keep it up! – AaronReed17 Nov 18 '20 at 10:52
  • I appreciate the words of encouragement! : ) it's slow progress but I'm getting there, i think... – total_due Nov 19 '20 at 11:42
0

Here's my slightly amended code:

hex_table = {'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,
'A':10, 'B':11, 'C':12, 'D':13, 'E':14, 'F':15}
key_list = list(hex_table.keys())
val_list = list(hex_table.values())


def rgb(num_val):
    num = num_val // 16
    
    num_float = float(num_val) / 16
    num_remainder = num_float % 1
    
    if num_val >= 10:
        print(key_list[val_list.index(num)], end='')
        second_letter = (int(num_remainder * 16))
        print(key_list[val_list.index(second_letter)],end='')
    elif num_val <10:
        print(num_val)
        print(int(num_remainder * 16))

def rgb_hex(r,g,b):
    print('#',end='')
    return (f'{rgb(r)} {rgb(g)} {rgb(b)}')


rgb_hex(220,20,60)
total_due
  • 7
  • 3
-3

This is an old question but for information, I developed a package with some utilities related to colors and colormaps and contains the rgb2hex function you were looking to convert triplet into hexa value (which can be found in many other packages, e.g. matplotlib). It's on pypi

pip install colormap

and then

>>> from colormap import rgb2hex
>>> rgb2hex(0, 128, 64)
'##008040'

Validity of the inputs is checked (values must be between 0 and 255).

Jasar Orion
  • 626
  • 7
  • 26