在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 

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

考虑以下代码:

 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 }" 

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

为了避免输入错误,我建议你做一些事情:

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

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

除非response为空,否则将起作用。 你可以弄清楚如何处理它。


确定运算符后,获得答案的另一种方法是answer = gets.to_i.send(operator, gets.to_i)

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

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

可能成为:

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

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

 def get_int_values(n) n.times.map { gets.chomp.to_i } end 

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

现在,要做到这一点,需要使用不同的文本来提醒用户预期会有多个值,但这可以通过让用户说出他们想要输入的数量,然后提示每个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 }" 

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 

你的作业是在声明的错误一面。 你应该有answer = n1 * n2 ,它与answer == n1 * n2 (这是检查相等性,使用== )。 表达式总是在右边,而结果分配的变量在左边 – 这几乎是通用的,但不一定是来自代数的直观。

另外:使用变量名之前的@将其区分为类的实例变量或成员。 根据您在此处显示的内容,您不需要包含这些内容,只需使用通常范围的变量即可。 有关该部分的更多信息,请查看此问题 。

“@”sigil用于表示类实例变量,您没有类,所以不要使用它。

 @n1 + @n2 == @answer 

是一个布尔表达式,用于评估@ n1 + @ n2是否等于@answer。

它将评估为真或假….但你没有使用答案。

你想要的是……

 answer = n1 + n2 

我强烈建议您始终使用-w选项运行Ruby。 它会为你节省很多心痛。

请缩进“结束”以匹配您的“def”(或“if”)。

你在整个地方重复n1 = gets.chomp.to_i,做一次并将答案作为参数传递……

 response = gets.chomp n1 = gets.chomp.to_i n2 = gets.chomp.to_i if response == "add" then addition_function( n1, n2) elsif... 

其他人未提及的一些建议:

  • 缩短你的方法(不是“函数”)名称并使用动词(例如, add而不是addition_method )。

  • 除了使用局部变量而不是实例变量(由他人提及)之外,尽可能消除它们。 例如,您可以简化

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

  def add puts "Which numbers would you like to add?" puts "The sum is... #{gets.to_i + gets.to_i}" end 
  • 注意我使用了缩进两个空格的Ruby约定。

  • 你不需要在这里选择chomp (尽管没有任何伤害),因为"123followed by \n or any other non-digits".to_i => 123

  • 一个case语句最后会运行良好(让我们循环直到用户选择退出):

  loop do puts "Would you like to [add], [multiply], [subtract] or [quit]?" case gets.chomp when "add" add when "subtract" subtract when "multiply" multiply when "quit" break end 

要不就

  def quit() break end loop do puts "Would you like to [add], [multiply], [subtract] or [quit]?" send(gets.chomp) end 
  • 在这里我们确实需要chomp 。 您可以将loop do替换为while true do或使用其他等效构造。

class级计算器

def Calc

  puts"==well come to mobiloitte calculator==" puts "enter the first operand:" @op1 = gets.chomp return if @op1=="q" @o1=@op1.to_i puts "entre the second operand:" @op2 = gets.chomp return if @op2=="q" @o2=@op2.to_i 

强文本 “输入你选择的任何一个运算符(add,sub,mul,div,mod)”operator = gets.chomp

 case operator when 'add' then @s=@o1+@o2 ; puts "\n #@o1 + #@o2 =#@s" when 'sub' then @t=@o1-@o2 ; puts "\n #@o1 - #@o2 =#@t" when 'mul' then @l=@o1*@o2 ; puts "\n #@o1 * #@o2 =#@l" when 'div' then @r=@o1/@o2 ; puts "\n #@o1 \ #@o2 =#@r" when 'md' then @d=@o1%@o2 ; puts "\n #@o1 % #@o2 =#@d" else puts"invalide input" 

end end end obj = Calculator.new $ f = obj.Calc

您正在使用@n1 + @n2 == @answer尝试设置答案。 你想要做的是@answer = @n1 + @n2

=是赋值, ==是比较运算符。

此外,您需要@n1 = gets.chomp.to_i 。 这会将您的输入转换为字符串中的整数。 也可以用@n2做到这一点。

您也不需要在每个变量之前使用@ 。 这应该仅在您处理类似的时候使用,而您似乎并没有这样做。

 print "enter number 1 : " n1 = gets.chomp.to_f print "enter number 2 : " n2 = gets.chomp.to_f print "enter operator: " op = gets.chomp if op == '+' puts "#{n1} + #{n2} = #{n1 + n2}" elsif op == '-' puts "#{n1} - #{n2} = #{n1 - n2}" elsif op == '*' puts "#{n1} * #{n2} = #{n1 * n2}" elsif op == '/' puts "#{n1} / #{n2} = #{n1 / n2}" end 
 puts "Would you like to 0 ---- [exit], 1 ---- [add], 2 ---- [subtract], 3 ---- [multiply], 4 ---- [divide]" response = gets.chomp case response.downcase when '1' def addition_function puts "Which numbers would you like to add?" n1 = gets.to_i n2 = gets.to_i answer = n1 + n2 puts "The sum is... #{n1} + #{n2} = #{answer}" end addition_function() #Subtract when '2' def subtraction_function puts "Which numbers would you like to subtact?" n1 = gets.to_i n2 = gets.to_i answer = n1 - n2 puts "The subtraction is... #{n1} - #{n2} = #{answer}" end subtraction_function() #Multiply when '3' def multiplication_function puts "Which numbers would you like to multiply?" n1 = gets.to_i n2 = gets.to_i answer = n1 * n2 puts "The multiplication is... #{n1} * #{n2} = #{answer}" end multiplication_function() #Division when '4' def division_function puts "Which numbers would you like to divide?" n1 = gets.to_i n2 = gets.to_i answer = n1 / n2 puts "The division is... #{n1} / #{n2} = #{answer}" end division_function() else '0' puts "Exit! Thank You for using us!" end 
 #ruby script to do the calculator puts " enter the number1" in1=gets.to_i puts " enter the number2" in2=gets.to_i puts "enter the operator" op=gets.chomp case op when '+' plus=in1+in2 puts "#{in1+in2}" #puts "#{plus}" when '-' min=in1-in2 puts "#{min}" when '*' mul= in1*in2 puts "#{mul}" when '/' div=in1/in2 puts "#{div}" else puts "invalid operator" end