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.