1

I have this code where I am entering input for sides of a triangle. Depending on the values, it will print it the triangle is equilateral, isoceles, or scalene. It's executing for number values, but how do I specify that the input should only be integers? For example, if I type in "w" , it should say invalid or error, but in this case, it executes. How do I solve this?

Basically, I am looking for a way to write that if a string were to be inputted, it should show up as an error (then I would write a print statement saying it is invalid). So could I put that into another if statement? (before the ones mentioned below)

Example Code:

puts "Enter the triangle length"
  x = gets.chomp

  puts "Enter the triangle width"
  y = gets.chomp


  puts "Enter the triangle height"
  z = gets.chomp


  if x == y and y == z
      puts "This triangle is equilateral"
      else if
       x==y or y == z or x==z
           puts "This triangle is isoceles"
        else if
          x!=y and y!=z and x!=z
             puts "this triangle is scalene"
         end
      end
  end
small5
  • 11
  • 1
  • 3
  • Where's the Java part? – shmosel Jun 28 '16 at 04:36
  • Are you sure you didn't mean `elsif` instead of `else if`? – Jordan Running Jun 28 '16 at 04:43
  • What is the difference between elseif and else if? – small5 Jun 28 '16 at 04:44
  • `else if` is two separate statements. You're putting an `if` expression inside the `else` block, i.e. `if … else (if … end) end`. Note the two `end`s. That's entirely different from `if … else … end` and behaves very differently. – Jordan Running Jun 28 '16 at 05:27
  • If you fix your newlines and indentation, the difference becomes very clear: https://gist.github.com/jrunning/df00de328d53a2a5b67db96616a8f870 In this case the behavior is actually the same, but that's only by accident. – Jordan Running Jun 28 '16 at 05:32

6 Answers6

2

If you are dealing with integers, you can check this with ruby.

Note, this is not as robust as regex, but it covers most cases.

if (input != '0') && (input.to_i.to_s != input.strip)
  # input is not a number
else
  # input is a number
end

strip is there if you want to accept input with leading or trailing whitespace, otherwise you can leave it off.

Petr Gazarov
  • 3,602
  • 2
  • 20
  • 37
  • So this if statement is basically saying that as long as the input is still a number and if a string can be converted to an integer, it should accept and execute? – small5 Jun 28 '16 at 04:53
  • I advise you to open `irb` and play with `to_i`, it might surprise you, especially when you call `to_i` on string. In short, calling `to_i` on string returns `0`. Does my if condition make sense now? – Petr Gazarov Jun 28 '16 at 04:56
  • I originally wrote under each variable (X = x.to_i etc) but however, I was noticing that even if I entered a letter, it somehow entered that if loop because it was being recognized as an integer. What would regex do? – small5 Jun 28 '16 at 04:59
1

While all the other answers are probably more or less robust, I would go with another one. Since you have a triangle sides lengths, they are to be greater than zero, right? Then one might use the side effect of String#to_i method: for everything that is not converting to integer it returns zero. Therefore:

x = gets.chomp.to_i
y = gets.chomp.to_i
z = gets.chomp.to_i

raise "Wrong input" unless x > 0 && y > 0 && z > 0

# ...
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
1

You can do something like this:

x = x.to_i

puts "Please enter an integer" if x == 0 

Why?

Because:

"ABC".to_i # returns 0

You may be better off calling strip instead of chomp

gets.strip.to_i

An example:

## ruby user_age.rb

# input variables
name = ""
years = 0
MONTHS_PER_YEAR = 12 # a constant

# output variable
months = 0

# processing
print "What is your name? "
name = gets.strip

print "How many years old are you? "
years = gets.strip.to_i

puts "please enter an integer" if years == 0

months = years * MONTHS_PER_YEAR

puts "#{name}, at #{years} years old, "\
"you are #{months} months old."
kgpdeveloper
  • 2,099
  • 4
  • 25
  • 34
0

There are several ways of doing it. If you allow for a leading sign,

x =~ /^[+-]?\d+$/

would be a possibility.

You will also have to think whether or not you allow surrounding or embedding spaces (for instance, a space between the sign and the first digit).

user1934428
  • 19,864
  • 7
  • 42
  • 87
0

I assume that any string value that, when converted to a float, equals an integer is to be accepted and the integer value is to be returned. Moreover, I assume integers can be entered with the "xen" (or "xEn") notation, where x is an integer or float and n is an integer.

def integer(str)
  x = Float(str) rescue nil
  return nil if x==nil || x%1 > 0
  x.to_i
end

integer("3")       #=> 3 
integer("-3")      #=> -3 
integer("3.0")     #=> 3 
integer("3.1")     #=> nil 
integer("9lives")  #=> nil 
integer("3e2")     #=> 300 
integer("-3.1e4")  #=> -31000 
integer("-30e-1")  #=> -3 
integer("3.0e-1")  #=> nil 
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
0

You could use Integer() to check if a string contains an integer:

Integer('1234')
#=> 1234

Integer('foo')
#=> ArgumentError: invalid value for Integer()

This could be combined with a retry:

begin
  number = Integer(gets) rescue retry
end
spickermann
  • 100,941
  • 9
  • 101
  • 131