2017-05-15 11 views
0

Ich brauche Hilfe mit Schleifen.Wie zu loopen und nach Benutzereingabe zu fragen

Ich versuche, die Eingabe vom Benutzer zu erfassen und die Kosten eines Hotels für die Planung eines Urlaubs zu bestimmen.

Ich habe ein Problem beim Durchlaufen der Eingabe, so dass der Benutzer ein anderes Hotel auswählen und das Programm beenden kann, wenn der Benutzer keine der Tastenanschläge auswählt ("A", "a", "B", "b", " C "," c "," D "oder" d ") und berechnen dann die Gesamtkosten für Hotels.

kam ich mit diesem so weit nach oben:

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

+3

Werfen Sie einen Blick auf ['Kernel # loop'] (http://ruby-doc.org/core-2.4.1/Kernel.html#method-i-loop). –

+0

"[Wie man Fragen auf intelligente Weise stellt] (http://catb.org/esr/faqs/smart-questions.html)" wäre eine gute Lektüre für Sie. –

+0

Verwenden Sie keinen Link zu einem Bild für Informationen, die für die Frage wichtig sind. Kopieren Sie das stattdessen in die Frage und formatieren Sie es entsprechend. Links verrotten dann, und wenn die Information in der Verbindung wesentlich ist, wird Ihre Frage für andere wertlos. Denken Sie daran, Ihre Frage ist ein Artikel, der anderen hilft, das gleiche Problem zu lösen. –

Antwort

2

Es gibt mehrere mögliche Verbesserungen, um Ihren Code, aber ich werde diese Antwort so einfach und direkt halten, wie ich kann.

Verwenden Sie ein loop und ein einzelner if ... else if ... else ... end Blockcode, anstatt mehrere separate if Aussagen:

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 

Man könnte auch sagen, so etwas wie "Type 'done' when you have finished" einen klareren Ausgang betrachten Umsetzung - und ‚ignorieren‘ jede andere Eingabe ist das nicht a/b/c/d/done. Mit anderen Worten, etwas entlang der Linien von:

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

Fügen Sie das nicht als Kommentar hinzu, bearbeiten Sie Ihre Antwort. –

+0

@theTinMan Fertig. –

2

Wickeln Sie Ihren Code in einer while-Schleife,

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

Offensichtlich ist das Ende Fall kann alles sein, nicht nur "fertig".

Aus Gründen der Fertigstellung, eine elegante Lösung für dieses Problem wäre, wie etwas sein:

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 
+1

IMO es ist sauberer zu "brechen", anstatt solche booleschen Variablen herumschweben zu lassen. –

+0

Dies ist eine gute Verbesserung, aber der Code muss noch überarbeitet werden. Es gibt doppelten Code und diese Methode weiß zu viel darüber, wie wir Fragen stellen und wie die Kosten berechnet werden. Die Methode selbst sollte sich nur darum kümmern, was sie braucht, und darauf vertrauen, dass andere Objekte ihren Teil dazu beitragen. Jene Teile über Kosten könnten hier heraus in Klassen extrahiert werden und jeder von ihnen könnte als Abhängigkeit injiziert werden. Nur eine Idee. Der Code wird viel stabiler sein und wird nur von den öffentlichen Methoden dieser Klassen abhängen (die dieselbe Schnittstelle implementieren könnten), die den Code stabiler machen würden. –

+0

Verwenden Sie 'while' nicht, verwenden Sie' loop'. Es ist idiomatisch für Ruby. –

-1

Dies ist nicht getestet, aber es ist die Grundidee für das, was ich verwenden würde:

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 

Statt if/elsif/else/end gekettet würde ich eine case Anweisung:

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