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
5
  • Where's the Java part? Commented Jun 28, 2016 at 4:36
  • Are you sure you didn't mean elsif instead of else if? Commented Jun 28, 2016 at 4:43
  • What is the difference between elseif and else if? Commented Jun 28, 2016 at 4: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 ends. That's entirely different from if … else … end and behaves very differently. Commented Jun 28, 2016 at 5:27
  • If you fix your newlines and indentation, the difference becomes very clear: gist.github.com/jrunning/df00de328d53a2a5b67db96616a8f870 In this case the behavior is actually the same, but that's only by accident. Commented Jun 28, 2016 at 5:32

6 Answers 6

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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?
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?
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?
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

# ...

2 Comments

I tried the raise command and its working for me. However, would I be able to put in a print statement? I.E puts "Invalid input" (without an error coming from the compiler?)
Of course, just change raise to puts or whatever.
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."

Comments

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).

Comments

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 

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.