Ruby Ruby Basics Conditionals A Better "check_speed" Method

Erin Claudio
Erin Claudio
4,644 Points

I think I found a bug

I received a positive grade for this code but I am not sure that is good code, please help?

def check_speed(speed)
  if speed < 45
    puts "too slow"
 elsif speed > 55
    puts "too fast"
 else speed == 45..60
    puts "speed OK"
end
program.rb
def check_speed(speed)
  if speed < 55
    puts "too slow"
  end
  if speed > 55
    puts "too fast"
  end
  if speed == 55
    puts "speed OK"
  end
end
Jay McGavren
Jay McGavren
Treehouse Teacher

So you're saying that you entered this code for the challenge:

def check_speed(speed)
  if speed < 45
    puts "too slow"
 elsif speed > 55
    puts "too fast"
 else speed == 45..60
    puts "speed OK"
end

...and it was accepted, and you feel it should not have been, is that right?

But when I enter the above code in the challenge, it is not accepted. I get the failure message:

There seems to be an error in your code: 8: syntax error, unexpected end-of-input, expecting keyword_end (SyntaxError)

And even if you add an end keyword on line 8, it then fails with the message:

We called check_speed with an argument of 60, but it didn't print "speed OK".

So I guess I'm not understanding the issue.

You are definitely going to want to remove the boolean clause from else speed == 45..60. That's technically legal Ruby, but there isn't supposed to be a condition following the else keyword, only if and elsif.

Erin Claudio
Erin Claudio
4,644 Points

Hello Jay, or should I say Professor McGraven, I posted the incorrect code to the previous post. Below please find the code that I entered which was accepted in this code challenge which I am not sure is valid Ruby. Thank you for your help.

def check_speed(speed)
  if speed < 45
    puts "too slow"
  elsif speed > 60
    puts "too fast"
  else speed = 45..60
    puts "speed OK"
  end
end
Jay McGavren
Jay McGavren
Treehouse Teacher

Erin Claudio "Jay" will do. :)

So here's what the code you posted in this latest comment looks like to Ruby:

def check_speed(speed)
  if speed < 45
    puts "too slow"
  elsif speed > 60
    puts "too fast"
  else
    speed = 45..60
    puts "speed OK"
  end
end

Let's say you made the call check_speed(55). 55 isn't less than 45, so the if clause wont' run. 55 also isn't greater than 60, so the elsif clause won't run. So the else clause runs instead.

The first statement in the else clause will discard the number 55 stored in speed, and assign the Range value 45..60 to speed instead. Now, I'm sure this is not at all what you meant to do, but that's what is written here, so that's what Ruby does. But the code works anyway, because it never accesses the speed variable again. It goes on to print "speed OK", which is what is requested in the challenge description, and is what our unit tests test for. That's why it passes.

There are two important lessons to learn here:

  • Never, ever put a condition following an else clause. else should always be on a line all by itself. It won't fail to compile, but it is very likely to introduce a bug. If you really want a condition, use elsif, not else.
  • The difference between == (equality comparison) and = (assignment) is very important! Again, it is very likely to introduce a bug if you make a mistake. Please review this video for details on the difference.

2 Answers

Steven Parker
Steven Parker
163,107 Points

The last video was about using "elsif" and "else" so you can handle more conditions with fewer tests. See if you can use those keywords here.

Hint: Once you've checked for "too high" and "too low", wouldn't everything else be "OK"?

Steven Parker
Steven Parker
163,107 Points

Oh, I see, I was looking at the color code and thinking you wanted hints to pass. Odd that it did not show what you actually entered.

Erin Claudio
Erin Claudio
4,644 Points

I do not think I posted the question well. Below is the code I posted to the challenge which I received passing grade I think this answer is not correct

def check_speed(speed)
  if speed < 45
    puts "too slow"
  elsif speed > 60
    puts "too fast"
  elsespeed == 45..60
    puts "speed OK"
  end
end

thank you for any help

Steven Parker
Steven Parker
163,107 Points

It does look like you have discovered a bug, even without formatting, that final comparison clearly does not belong (and a plain "else" does not take a condition).

You might want to submit a bug report to the staff, instructions can be found on the Support page. If you're the first (and they agree it's a bug) you should get the special "Exterminator" badge. :beetle:

Jay McGavren
Jay McGavren
Treehouse Teacher

This code does not pass the challenge for me either (which is as it should be):

def check_speed(speed)
  if speed < 45
    puts "too slow"
  elsif speed > 60
    puts "too fast"
  elsespeed == 45..60
    puts "speed OK"
  end
end

I get this error message:

We called check_speed with an argument of 45, but it didn't print "speed OK".

Again, although this code is not as intended, it's technically legal Ruby, so there's no syntax error for our challenge engine to report. To Ruby, the code looks more like this:

def check_speed(speed)
  if speed < 45
    puts "too slow"
  elsif speed > 60
    puts "too fast"
    elsespeed == 45..60
    puts "speed OK"
  end
end

If you tried calling check_speed(61) with the above code, you'd get the error undefined local variable or method 'elsespeed' for main:Object. But the tests we're running behind the scenes don't get that far; they fail when they try to call check_speed(45).

Again, the solution is to remove that conditional from the else clause, which shouldn't be there anyway.