在Ruby中编写基本计算器

Rog*_*Wav 0 ruby

这是我第一次涉足计算机编程.我选择学习Ruby,我很享受它.但是,我有点困惑的是为什么答案在这段代码中输出不正确.

def addition_function
    puts "Which numbers would you like to add?"
    @n1 = gets.chomp
    @n2 = gets.chomp
    @n1 + @n2 == @answer
    puts "The sum is... #{@answer}"
end

def subtraction_function
    puts "Which numbers would you like to subtract?"
    @n1 = gets.chomp.to_i
    @n2 = gets.chomp.to_i
    @n1 - @n2 == @answer
    puts "The answer is... #{@answer}"
end

def multiplication_function
puts "Which numbers would you like to multiply?"
    @n1 = gets.chomp
    @n2 = gets.chomp
    @n1 * @n2 == @answer
    puts "The answer is... #{@answer}"
end

puts "Would you like to [add], [multiply], or [subtract]?"
response = gets.chomp
if response == "add" then
    addition_function
end
if response == "subtract" then
    subtraction_function
end
if response == "multiply" then
    multiplication_function
end
Run Code Online (Sandbox Code Playgroud)

我知道这可能是可怕的代码......但是有人可以帮助引导我朝着正确的方向前进吗?

the*_*Man 6

考虑以下代码:

def get_int_values
  [gets, gets].map{ |s| s.chomp.to_i }
end

puts "Would you like to [add], [multiply], or [subtract]?"
response = gets.chomp

case response.downcase
when 'add'
  puts "Which numbers would you like to add?"
  operator = :+

when 'subtract'
  puts "Which numbers would you like to subtract?"
  operator = :-

when 'multiply'
  puts "Which numbers would you like to multiply?"
  operator = :*

end

answer = get_int_values.inject(operator)
puts "The answer is... #{ answer }"
Run Code Online (Sandbox Code Playgroud)

我们的想法是遵循"干"原则:"干"意味着"不要重复自己",绝大多数时候,这是一件非常好的事情.

为了避免输入错误,我建议做以下事情:

puts "Would you like to [a]dd, [m]ultiply, or [s]ubtract?"
response = gets.chomp

case response[0].downcase
Run Code Online (Sandbox Code Playgroud)

然后更改when子句以匹配所需操作的第一个字母.

这将是有效的,除非response是空的.你可以弄清楚如何处理它.


一旦确定了操作员,另一种获得答案的方法是 answer = gets.to_i.send(operator, gets.to_i)

这是真的,但这就是我按照我的方式重构代码的原因:如果由于某种原因,需要对两个以上的值进行操作,那么只需要改变一件事:

[gets, gets].map{ |s| s.chomp.to_i }
Run Code Online (Sandbox Code Playgroud)

可能成为:

[gets, gets, gets].map{ |s| s.chomp.to_i }
Run Code Online (Sandbox Code Playgroud)

或者,更好的是,可以转换为:

def get_int_values(n)
  n.times.map { gets.chomp.to_i }
end
Run Code Online (Sandbox Code Playgroud)

除了找出需要多少值之外,别无其他任何改变.

现在,要做到这一点,需要使用不同的文本来提醒用户预期会有多个值,但这可以通过让用户说出他们想要输入的数量,然后提示每个值来轻松完成gets:

def get_int_values(n)
  n.times.map.with_index { |n|
    print "Enter value ##{ 1 + n }: "
    gets.chomp.to_i 
  }
end

puts "Would you like to [add], [multiply], or [subtract]?"
response = gets.chomp

puts "How many values?"
num_of_values = gets.to_i

case response.downcase
when 'add'
  puts "Which numbers would you like to add?"
  operator = :+

when 'subtract'
  puts "Which numbers would you like to subtract?"
  operator = :-

when 'multiply'
  puts "Which numbers would you like to multiply?"
  operator = :*

end

answer = get_int_values(num_of_values).inject(operator)
puts "The answer is... #{ answer }"
Run Code Online (Sandbox Code Playgroud)

inject 可以轻松扩展,因为它不预先假定有关正在操作的值的数量的知识.


我认为n.times.map.with_index中的with_index是您忘记删除的工件.

这是故意的,但我更喜欢这个:

def get_int_values(n)
  1.upto(n).map { |n|
    print "Enter value ##{ n }: "
    gets.chomp.to_i
  }
end
Run Code Online (Sandbox Code Playgroud)