Angle Identifier

H

Hd Pwnz0r

puts "Enter degree of angle:"
measure = gets.chomp.to_i
if measure == "180".to_i then puts "That's a straight angle."
if measure == 181..359.to_i then puts "That's an obtuse angle."
if measure == 91..179.to_i then puts "That's an obtuse angle."
if measure == "90".to_i then puts "That's a right angle."
if measure < 90.to_i then puts "That's an acute angle."
if measure == "360".to_i then puts "That's a circle..."
else puts "That's an invalid measurement."
end
end
end
end
end
end

This seems like it should work, but sometimes it doesn't. Help?
 
B

Brian Candler

Hd said:
puts "Enter degree of angle:"
measure = gets.chomp.to_i
if measure == "180".to_i then puts "That's a straight angle."
if measure == 181..359.to_i then puts "That's an obtuse angle."

That won't work; consider the case when measure is 190, does 190 ==
181..359 ?

The way to find out is by testing your code interactively in irb.

irb(main):001:0> measure = 190
=> 190
irb(main):002:0> measure == 181..359
ArgumentError: bad value for range
from (irb):2
irb(main):003:0> measure == (181..359)
=> false

The first error is because the line was parsed as (measure == 181)..359,
that is (false..359), which is not a valid range.

After adding the right parentheses, you can see that the Fixnum object
190 is not *equal* to the Range object 181..359. You need a different
test to see if 190 is *within* the proscribed range.

Here are a few options to consider:

if measure == 180
..
elsif (181..359).include?(measure)
..
elsif 91 <= measure && measure <= 179
..
end

Or more simply, reorder your tests:

if measure < 90
..
elsif measure == 90
..
elsif measure < 180
..
elsif measure == 180
..
elsif measure < 360
..
end

That also has the advantage of working with floating point values like
180.5 which wouldn't be accepted by your original test for 181..359.

If you want to work with Ranges, there is a neat solution using the case
statement:

case measure
when 180
..
when 181..359
..
when 91..179
..
end

This expands to:

if 180 === measure
..
elsif 181..359 === measure
..
elsif 91..179 === measure
..
end

Helpfully, the '===' operator on an integer checks for equality, but the
'===' operator on a range checks for inclusion.

irb(main):005:0> (181..359).include? 190
=> true
irb(main):006:0> (181..359) === 190
=> true


There is also the three dot form of range: x...y means "from x up to but
not including y".

case measure
when 180
..
when 180...360
..
when 90
..
when 90...180
..
when 0...90
..
end


irb(main):007:0> (180...360).include? 359
=> true
irb(main):008:0> (180...360).include? 359.999
=> true
irb(main):009:0> (180...360).include? 360
=> false
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,372
Latest member
LucretiaFo

Latest Threads

Top