【问题标题】:How to loop and ask for user input如何循环并询问用户输入
【发布时间】:2017-05-15 18:09:42
【问题描述】:

我需要循环方面的帮助。

我正在尝试获取用户的输入并确定酒店计划假期的成本。

我在循环输入时遇到问题,因此如果用户没有选择任何击键(“A”、“a”、“B”、“b”、“C”,用户可以选择另一家酒店并结束程序"、"c"、"D" 或 "d"),然后计算酒店的总成本。

到目前为止,我想出了这个:

puts choice = gets.chomp.downcase
puts "For how many nights?"
num=gets.chomp.to_i
puts "Okay...any other hotels?"  
puts choice = gets.chomp.downcase

#Hotel Prices  

#Hotel A
if (choice== "a" or choice=="A") 
cost_2= (num/3)*500 + (num%3)*200
end

#Hotel B
if (choice=="b" or choice=="B")
cost_3= num*250
end

#Hotel C
if (choice=="c" or choice=="C")
cost_4 = (num/3)*700 + (num%3)*300
end

#Hotel D
 if (choice== "d" or choice=="D")
  cost_5= num*500
   end

Hotel Program

【问题讨论】:

  • 看看Kernel#loop
  • "How To s The Smart Way" 对你来说是个好读物。
  • 不要使用指向图像的链接来获取对问题很重要的信息。相反,将其复制/粘贴到问题中并适当地格式化。链接腐烂然后断开,如果链接中的信息是必不可少的,那么您的问题对其他人来说将变得毫无价值。请记住,您的问题是帮助其他人解决相同问题的文章。
  • 正如@sagarpandya82 所建议的,正常的方式是loop do; ..; break if <some condition)>;...; end。您可以使用(例如)while true;..;endwhile 1;...; end,但首选 loop。在某些情况下,您可能更喜欢while(<some condition>);..;enduntil(<some condition);..;endloop 的一个优点是,当循环包含一个尝试枚举超出其末尾的枚举器,导致枚举器引发StopInteration 异常时,loop 通过跳出循环来处理异常。见Kernel#loop

标签: ruby loops if-statement while-loop


【解决方案1】:

将您的代码包装在一个while循环中,

continue = true
while continue
  ...
  if choice == "done"
    continue = false
  end
end

显然,最终情况可以是任何事情,而不仅仅是“完成”。

为了完整起见,这个问题的一个优雅的解决方案是这样的:

loop do
  puts choice = gets.chomp.downcase
  puts "For how many nights?"
  num=gets.chomp.to_i
  puts "Okay...any other hotels?"  
  puts choice = gets.chomp.downcase

  selections = {
     a: (num/3)*500 + (num%3)*200,
     b: num*250,
     c: (num/3)*700 + (num%3)*300,
     d: (num*500)
  }

  if selections[choice.to_sym]
    cost += selections[choice.to_sym]
  else
    break
  end
end

【讨论】:

  • IMO 它对break 更简洁,而不是让这些布尔变量四处浮动。
  • 这是一个很好的改进,但是代码仍然需要一些重构。有重复的代码,这种方法对我们如何提问以及如何计算成本了解太多。方法本身应该只关心他需要什么,并信任其他对象来完成他们的工作。那些关于成本的部分可以从这里提取到类中,并且它们中的每一个都可以作为依赖注入。只是一个想法。代码将更加稳定,并且只依赖于这些类的公共方法(可以实现相同的接口),这将使代码更加稳定
  • 不要使用while,使用loop。这是 Ruby 的惯用语。
【解决方案2】:

您的代码有几个可能的改进,但我会尽可能简单直接地回答这个问题。

使用一个loop 和一个if ... else if ... else ... end 块代码,而不是几个单独的if 语句:

loop do
  if (choice== "a" or choice=="A") 
    cost_2= (num/3)*500 + (num%3)*200
  #Hotel B
  elsif (choice=="b" or choice=="B")
    cost_3= num*250
  #Hotel C
  elsif (choice=="c" or choice=="C")
    cost_4 = (num/3)*700 + (num%3)*300
  #Hotel D
  elsif (choice== "d" or choice=="D")
    cost_5= num*500
  else
    puts "Final cost is: [...]"
    break
  end
end

您还可以考虑通过说"Type 'done' when you have finished" 之类的内容来实现更明确的退出 - 并“忽略”任何其他不是 a/b/c/d/done 的输入。换句话说,类似于:

# ...
elsif (choice== "d" or choice=="D")
  cost_5= num*500
elsif choice == 'done'
  puts "Final cost is: [...]"
  break
else
  puts 'Unknown option'
end
# ...

【讨论】:

  • @theTinMan 完成。
【解决方案3】:

这是未经测试的,但这是我使用的基本思想:

loop do

  cost = nil
  loop do

    puts 'Which hotel? (A, B, C, D)'
    hotel = gets.chomp.downcase

    puts 'For how many nights?'
    days = gets.to_i

    cost = if hotel == 'a' 
             (days / 3) * 500 + (days % 3) * 200
           elsif hotel == 'b'
             days * 250
           elsif hotel == 'c'
             (days / 3) * 700 + (days % 3) * 300
           elsif hotel == 'd'
             days * 500
           else
             puts 'Unknown hotel.'
           end

    break if cost

  end

  puts cost

  puts 'Okay...any other hotels? (y/n)'  

  break unless gets.downcase.start_with?('y')    
end

而不是链式if/elsif/else/end 我会使用case 声明:

cost = case hotel
       when 'a' 
         (days / 3) * 500 + (days % 3) * 200
       when 'b'
         days * 250
       when 'c'
         (days / 3) * 700 + (days % 3) * 300
       when 'd'
         days * 500
       else
         puts 'Unknown hotel.'
       end

【讨论】:

    猜你喜欢
    • 2011-10-19
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多