【问题标题】:Simple program but so very stuck- Loops in Ruby简单的程序,但非常卡住——Ruby 中的循环
【发布时间】:2020-01-03 23:44:28
【问题描述】:

我必须编写一个要求用户输入数字的程序。 程序不断向用户询问一个数字,直到用户键入“停止” 此时应打印用户输入的数字总和。 我尝试了很多很多东西,但我的想法都没有奏效。 这就是我所拥有的——但我可以认为它是不正确的。我做错了什么?

我只用过while循环和数组

total_user_input = []
# As long as the user inputs a number, the program will keep putting Give me a number
# and then adding that number to the total_user_input array.
puts "Give me a number: "
while user_input = gets.chomp.to_i
  #add the input to the array total_user_input
  total_user_input.push(user_input.to_i)
  puts "Give me a number: "
  # If the user however types stop, then the loop is broken and we jump down to the
  # sum bit - where all of the numbers in the total_user_input array are added together
  # and printed. End of program!
  if user_input == "stop"
    break
  end
  sum = 0
  total_user_input.each { |num| 
    sum += num
  }
  puts sum
end

输出不是应有的。

【问题讨论】:

  • 这段代码中的缩进确实不一致,并且 cmets 被分解,所以它们的一部分看起来像代码。解决了这个问题,但请尽量保持您的示例尽可能干净。它有助于我们理解问题。
  • 提示:你会得到gets.chomp.to_i的输出是"stop"吗?
  • 关于 SO 的最佳做法是不要将第一个答案标记为立即接受,因为其他人可能会提供替代解决方案。
  • 进一步了解@lacostenycoder 的观点,请参阅this recent question 上的cmets。

标签: ruby loops iteration interactive


【解决方案1】:

由于其他人已经发现您的代码存在问题,让我建议您如何重新组织它。 Ruby 提供了许多执行循环的方法,但许多人发现主要依靠方法Kernel#loop 和关键字break 是可取的。 (随着时间的推移,loop 与枚举器一起使用时特别方便。)

def sum_numbers
  tot = 0
  loop do
    print 'Gimme a number: '
    s = gets.chomp
    break if s == 'Stop'
    tot += s.to_i
  end
  tot
end

关键字break 可以选择接受一个参数(尽管为什么我不能说文档中没有提到),在这种情况下,它(如果是文字)或其值(如果是变量或方法)由loop。这里一般会看到

    break tot if s == 'Stop'

没有最后一行,tot。由于循环返回tot,这是该方法执行的最后一次计算,该方法将返回tot的最终值。

你可以改写

return tot if user_input == 'Stop'

但我认为大多数编码人员认为最佳实践规定不应从循环内(或嵌套循环内)的方法返回,除非有充分的理由这样做。

一些小点:

  • 我使用了print 而不是puts,这样用户的输入将显示在提示符所在的同一行。
  • 我使用s(表示“字符串”)而不是user_input,因为它减少了拼写错误的机会(例如user_imput),加快了阅读速度,并且(可能是我的一个缺点)看起来更整洁。诚然,s 不是描述性的,但人们只需要记住它的含义即可连续三行代码。其他人可能不同意。
  • 你可以写,break if s.downcase == 'stop',如果你想让'stop''STOP''Stop'具有相同的效果。
  • '23O3'.to_i #=> 23(这是一个哦,不是零),所以在现实生活中,您需要确认是否输入了 'Stop' 或数字的字符串表示形式。

【讨论】:

    【解决方案2】:

    这就是我会这样做的方式,我宁愿在应该的时候使用loop do end 语法和break。还添加了更多文本,以便用户知道发生了什么。

    total_user_input = []
    puts 'Give me a number or "stop" to end: '
    loop do
      user_input = gets.chomp
      total_user_input << user_input.to_i
      puts "Give me a number: "
      break if user_input.downcase == "stop"
    end
    puts "Total entered: #{total_user_input.inject(&:+)}" unless total_user_input.empty?
    puts 'goodbye!'
    

    【讨论】:

      【解决方案3】:

      注意以下几点:

      1. get.chomp.to_i 会将每个输入转换为整数。 (“停止”或任何非整数字符串将为 0)
      2. 流程安排很乱。
      total_user_input = []
      
      puts "Give me a number: "
      while user_input = gets.chomp.strip
        total_user_input.push(user_input.to_i)
        sum = 0
        total_user_input.each { |num| 
          sum += num
        }
        puts sum
      
        if user_input == "stop"
          break
        end
      
      end
      

      希望你明白这一点。

      【讨论】:

      • 非常感谢。这非常有用。我能问一下你为什么使用“strip”吗?
      • 假设有人输入“stop”,它会在不使用strip的情况下破坏代码
      • @blitzblade 对。然而,任何接受用户输入的程序都应该有更彻底的“错误处理”。除了允许用户在“停止”命令中输入意外空格之外,您“修复” OP 问题的方式对改进 UI 几乎没有什么作用。
      猜你喜欢
      • 2015-08-13
      • 1970-01-01
      • 2021-05-29
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 2015-12-04
      相关资源
      最近更新 更多