Reputation: 203
I'm creating a new calculator in Ruby. However, I keep experiencing this problem: The "if" statement is not executed even though I typed "add" if I want to add numbers together. Same with the "elsif" statements. The "else" statement will be always executed.
Pardon my messy code. I’m getting started in Ruby
class CalculatorFunctions
def addNumbers(num1, num2)
@n1 = num1
@n2 = num2
@sum = @n1 + @n2
puts @sum
end
def subtractNumbers(num1, num2)
@n1 = num1
@n2 = num2
@difference = @n1 - @n2
puts @difference
end
def multiplyNumbers(num1, num2)
@n1 = num1
@n2 = num2
@product = @n1 * @n2
puts @product
end
def divideNumbers(num1, num2)
@n1 = num1
@n2 = num2
@quotient = @n1 / @n2
puts @quotient
end
end
calcFunctions = CalculatorFunctions.new
puts "Select a method:\nType 'add' for Addition\nType 'subtract' for Subtraction\nType 'multiply' for Multiplication\nType 'divide' for Division"
method = gets
puts "Enter the first number:"
num1 = gets.to_i
puts "Enter the second number:"
num2 = gets.to_i
if method == "add" or method == "Add"
calcFunctions.addNumbers(num1, num2)
elsif method == "subtract" or method == "Subtract"
calcFunctions.subtractNumbers(num1, num2)
elsif method == "multiply" or method == "Multiply"
calcFunctions.multiplyNumbers(num1, num2)
elsif method == "divide" or method == "Divide"
calcFunctions.divideNumbers(num1, num2)
else
puts "Invalid method"
end
Upvotes: 0
Views: 1571
Reputation: 9
simple calculator using switch statement in ruby
puts "Entre first number"
num1 = gets.chomp().to_f
puts "Entre operator"
op = gets.chomp()
puts "Entre second number"
num2 = gets.chomp().to_f
case op
when "+"
puts(num1 + num2)
when "-"
puts(num1 - num2)
when "*"
puts(num1 * num2)
when "/"
puts(num1/num2)
end
Upvotes: 0
Reputation: 110675
This is not an answer but an extended comment that cannot be easily expressed in one or more conventional comments. Accordingly, no upvotes please (downvotes OK).
Firstly, there is not reason to put your methods in a class because you will not be creating instances of the class. You could put the methods in a module, which you could then Module#include in classes as needed. As an example, look at Ruby's built-in Math module. They are all module methods, so they are invoked with the module name. For example,
Math.sqrt(25)
Next, notice that the four basic arithmetic methods are similar in that they all have two arguments and one operator. We therefore can simplify the code by writing a single method that applies to all.
module Calc
def self.compute(op, arg1, arg2)
arg1.public_send(op, arg2)
end
end
See #public_send.
Let's try it.
Calc.compute(:+, 2, 3) #=> 5
Calc.compute(:-, 2, 3) #=> -1
Calc.compute(:*, 2, 3) #=> 6
Calc.compute(:/, 7, 2) #=> 3
Calc.compute(:/, 7.0, 2) #=> 3.5
Note that we can alternatively pass the operator as a string rather than a symbol.
Calc.compute('+', 2, 3) #=> 5
Because we want separate methods for each operator we can write the module Calc
as follows.
module Calc
def self.add(arg1, arg2)
compute(:+, arg1, arg2)
end
def self.subtract(arg1, arg2)
compute(:-, arg1, arg2)
end
def self.multiply(arg1, arg2)
compute(:*, arg1, arg2)
end
def self.divide(arg1, arg2)
raise ZeroDivisionError if arg2.zero?
compute(:/, arg1, arg2)
end
private
def self.compute(op, arg1, arg2)
arg1.public_send(op, arg2)
end
end
Calc.add(2, 3) #=> 5
Calc.subtract(2, 3) #=> -1
Calc.multiply(2, 3) #=> 6
Calc.divide(7, 2) #=> 3
Calc.divide(7.0, 2) #=> 3.5
Calc.divide(7.0, 0) #=> ZeroDivisionError
Curiously, had I not raised a divide-by-zero exception in Calc::divide
when the second argument is zero, the following would result.
Calc.divide(7.0, 0) #=> Infinity
You can obtain the arguments as follows.
print "Enter the method, 'add', 'subtract', 'multiply' or 'divide': "
method = gets.strip.downcase
puts
print "Enter the first number: "
num1 = gets.to_i
puts
print "Enter the second number: "
num2 = gets.to_i
Then, if, say, method = 'add'
, num1 = 2
and num2 = 5
.
Calc.public_send(method, num1, num2) #=> 7
Notice that I've not created any instance variables. Also, Ruby has a convention to use Snake case for naming variables and methods. You don't have to follow that, but 99%+ of Rubyists do.
Upvotes: 1
Reputation: 84343
When you call method = gets
, you also capture the newline when the user presses RETURN. You need to strip the newline from your input with String#chomp or String#strip.
method = gets.chomp
Alternatively, you could swap out the equality checks in your if-statements for String#start_with?. That would solve the problem too, but is a less idiomatic approach to what you're trying to do.
Upvotes: 1