Home > Enterprise >  My Ruby calculator program acts like I didn't enter a valid operator
My Ruby calculator program acts like I didn't enter a valid operator

Time:08-16

I have started learning Ruby today and so far I am loving the easy to read syntax! However, I have made a calculator app to learn the language and am struggling to get it to work. Below is the code for the app.

def add(first_number, second_number)
    first_number   second_number
end

def subtract(first_number, second_number)
    first_number - second_number
end

def multiply(first_number, second_number)
    first_number * second_number
end

def divide(first_number, second_number)
    first_number / second_number
end

def mod(first_number, second_number)
    first_number % second_number
end

def main()
    puts "First number: "
    first_number = gets

    puts "Operator ( , -, *, /, %): "
    operator = gets

    puts "Second number: "
    second_number = gets

    if operator == " "
        result = add(first_number, second_number)
    elsif operator == "-"
        result = subtract(first_number, second_number)
    elsif operator == "*"
        result = multiply(first_number, second_number)
    elsif operator == "/"
        result = divide(first_number, second_number)
    elsif operator == "%"
        result = mod(first_number, second_number)
    else
        result = "Invalid operator. Please try again."
    end

    puts "Result: "   result
end

main()

It keeps going to the else and printing invalid operator and I am unsure why. Am I making a stupid mistake, or am I going about this program the wrong way? Thank you in advance and sorry for such a simple question, I have only started learning Ruby today :)

CodePudding user response:

The answer is quite simple: gets isn't doing what you think. It's preserving the trailing newline.

irb(main):003:0> gets
hello
=> "hello\n"

You need to get rid of the trailing newline.

irb(main):004:0> gets.chomp
hello
=> "hello"

You can see the impact of this on comparisons:

irb(main):013:0> gets.chomp == "hello"
hello
=> true
irb(main):014:0> gets == "hello"
hello
=> false

If you want to get rid of all leading or trailing whitespace, you may want to use #strip.

irb(main):015:0> gets.strip
       
=> " "

You'll also need to convert your inputs for operands to numbers.

first_number = gets.to_f

When converting this way, there is no need to chomp off the trailing newline, though you could: gets.chomp.to_f.

CodePudding user response:

This program is way longer and more complex then it needs to be. In Ruby operators are just implemented as methods so you can use Object#send to perform all of these simple mathematical operations:

# This is Ruby - not C/Java/Rust etc - there is no need for a "main" method.
puts "First number: "
first_number = gets.chomp.to_f

# Get the user input in a loop until the user provides a valid operator
operator = loop do
  puts "Operator ( , -, *, /, %): "
  operator = gets.chomp
  if [" ", "-", "*", "/", "%"].include?(operator)
    break operator 
  else
    puts "Invalid operator. Please try again."
  end 
end 

puts "Second number: "
second_number = gets.chomp.to_f
puts "Result: "   first_number.send(operator, second_number)

If you want to be able to take more advanced input and map it to methods in this way using a lookup table (a hash) as suggested by Tadman is a good idea.

  • Related