Best way to handle multiple checks ruby


Keywords:ruby 


Question: 

So I'm trying to write a converter for HSL to RGB (and eventually into hex) I'm following this colorspace conversion theory and I seem to be stuck on step 6

Now we need to do up to 3 tests to select the correct formula for each color channel. Let’s start with Red.

test 1 – If 6 x temporary_R is smaller then 1, Red = temporary_2 + (temporary_1 – temporary_2) x 6 x temporary_R In the case the first test is larger then 1 check the following

test 2 – If 2 x temporary_R is smaller then 1, Red = temporary_1 In the case the second test also is larger then 1 do the following

test 3 – If 3 x temporary_R is smaller then 2, Red = temporary_2 + (temporary_1 – temporary_2) x (0.666 – temporary_R) x 6 In the case the third test also is larger then 2 you do the following

Red = temporary_2

Ok lets do it for our Red value

6 x temporary_R = 6 x 0.869 = 5.214, so it’s larger then 1, we need to do test 2 2 x temporary_R = 2 x 0.869 = 1.738, it’s also larger then 1, we need to do test 3 3 x temporary_R = 3 x 0.869 = 2.607, it’s larger then 2, so we go for the last formula Red = temporary_2 = 0.0924 which rounded down is 0.09, which is a number we recognize from the RGB to HSL conversion

So far I've monkey patched a function to take my HSL colours

def toRGB(hue, sat, lum)
  temp_1 =
  case lum
   when lum < 0.0
     lum x (1.0 * sat)
   when lum > 0.0
     (lum + sat) - lum
  end
  temp_2 = (2 * lum) - temp_1.to_f
  h = (hue/360.0).round(4)
  temp_r = (h + 0.333).round(4)
  temp_r = temp_r + 1 if temp_r < 0
  temp_r = temp_r - 1 if temp_r > 1
  temp_g = h 
  temp_b = (h - 0.333).round(4)
  temp_b = temp_b + 1 if temp_b < 0
  temp_b = temp_b - 1 if temp_b > 1
  red = 
  #test 1
  #test 2
  #test 3
  "#{red}"
end

I was trying to use a case statement

red = 
  case temp_r
    when 6 * temp_r < 1
      temp_2 + (temp_1 - temp_2) * 6 * temp_r
    when 2 * temp_r < 1
      temp_1
    when 3 * temp_r < 2
      temp_2 + (temp_1 - temp_2) * (0.666 - temp_r * 6)
  end

but then I started re-reading the instructions and now I can't really see a way to do what I need in ruby. Maybe I'm over-thinking it.

If you want to see the rest of my code in context you can see it here


1 Answer: 

There are two things I noticed in your code snippet:

You are mixing two types of switch case statement in ruby.

case a
when 1..5
 "It's between 1 and 5"
when 6
 "It's 6"
end

case
when a > 1 && a < 5
 "It's between 1 and 5"
when a == 6
 "It's 6"
end

See a difference, in first case when you directly compare cases, you've to mention the variable name you're comparing with, while in second case you're comparing with true & false condition by explicitly putting a condition on your variable so you don't need to put it next to case.

The second thing is as per your condition statement, you'll need an else case in your case statement.

red = 
  case
    when 6 * temp_r < 1
      temp_2 + (temp_1 - temp_2) * 6 * temp_r
    when 2 * temp_r < 1
      temp_1
    when 3 * temp_r < 2
      temp_2 + (temp_1 - temp_2) * (0.666 - temp_r * 6)
    else
      temp_2
  end