2017-02-10 20 views
0

Совершенно новый для кодирования и пытается выяснить, как оценивать, является ли пользовательский ввод плавающей точкой или целым числом больше 0, и если не продолжать предлагать им ответ, пока они не дадут мне ответ, соответствующий этим критериям.Как создать цикл на основе ввода пользователем float/integer vs string в Ruby?

я смог придумать следующее, что помогает мне отделить действительные ответы (число> 0) от недействительных ответов (строка или число < = 0):

input = "How much money do you have?" 
print input 
money_1 = gets.chomp.to_f 
    if money_1 > 0 
    puts "You have $#{money_1}." 
    else 
    puts "Please enter a valid amount" 
    print input 
end 

Что я могу 't выяснить, как превратить это в цикл, так что пользователь должен продолжать вводить ответ, пока не будет введено число, большее 0.

Любые советы? Похоже, это должен быть очевидный ответ, но я не нашел ничего, что работает через пару часов, чтобы копаться и пытаться.

Я также хотел бы знать, есть ли более простой способ, чем мой обходной путь, чтобы оценить, является ли пользовательский ввод плавающим или целочисленным по отношению к строке, а затем продолжать запрашивать их для ответа, пока они не дадут мне поплавок или целое число. Проблема заключается в том, что мне нужно преобразовать их вход в float, чтобы иметь возможность использовать его в уравнении позже в коде, поэтому я придумал это обходное решение, потому что я решил, что любая строка будет преобразована в 0, и я действительно только ищу номера больше 0, но если есть лучший способ, я бы с удовольствием узнал об этом!

Спасибо!

+0

Если вы нашли какой-либо ответ полезным, обязательно примите ответ, нажав соответствующий «серый тик», чтобы он стал зеленым. –

ответ

2

Kernel#loop использования, что-то вроде этого:

input = "How much money do you have?" 
puts input 
money_1 = gets.to_f 

loop do 
    if money_1 > 0 
    puts "You have $#{"%.2f" % money_1}" 
    break 
    else 
    puts "Please enter a valid amount", 
     input 
    end 
    money_1 = gets.to_f 
end 

Если вам не нужна переменная money_1 снова или вне цикла, следующий будет достаточно:

loop do 
    puts "How much money do you have?" 
    money_1 = gets.to_f 
    if money_1 > 0 
    puts "You have $#{"%.2f" % money_1}" 
    break 
    else 
    puts "Please enter a valid amount" 
    end 
end 
+1

Есть немного проблемы с этим, как написано; после цикла, 'money_1' выходит за рамки и не может быть использован. – philomory

+0

'break puts' кажется довольно странным для меня. Разве не было бы яснее иметь два утверждения: «ставит», затем «ломает»? –

+0

@CarySwoveland re первый комментарий: «странно», да, я думаю, вы, возможно, были правы, я не думаю, что когда-либо видел, как это делалось в любом месте, поэтому не уверен, почему я это сделал. Второе замечание: круто, я проверю ответ, который вы только что отправили, не зная, что вы могли бы сделать это, как это tbh. –

1

Есть пара различных способов решения этой проблемы. Более общий подход заключается в использовании loop, until, или while. Я вообще предпочитаю loop, но while немного проще в данном конкретном случае:

input = "How much money do you have?" 
print input 
keep_going = true 
while keep_going 
    money_1 = gets.chomp.to_f 
    if money_1 > 0 
    puts "You have $#{money_1}." 
    keep_going = false 
    else 
    puts "Please enter a valid amount" 
    end 
end 

Вы также спросили о других способах распознают поплавки; с String#to_f, строка типа «Hello» приводит к нулю, то же, что и «0»; Однако, метод Float() сгенерирует исключение, если прошел несоответствующую строку:

"hello".to_f #=> 0.0 
Float("Hello") #=> ArgumentError: invalid value for Float(): "hello" 

Теперь, было бы неплохо, если бы был вариант этого метода, который возвращается false или nil для недопустимого ввода, вместо того, приподнимая исключение, но даже, как сейчас она обеспечивает альтернативный способ написания кода:

puts "How much money do you have?" 

begin 
    money_1 = Float(gets) # \n at the end is ignored by Float() 
rescue ArgumentError 
    puts "Please enter a valid amount." 
    retry 
end 

puts "You have $#{money_1}." 

Если бы гипотетический Float?() метод, который возвращается ложь, а не поднимать исключение, вы могли бы написать это:

puts "How much money do you have?" 
until money_1 = Float?(gets) 
    puts "Please enter a valid amount." 
end 
puts "You have $#{money_1}." 

Это было бы намного приятнее, потому что сбор и спасение исключений для обработки довольно нормальных ситуаций, таких как неправильный ввод данных, - довольно плохая форма.

+0

OP 'money_1 = gets.chomp.to_f; если money_1> 0 ... 'выполняет две цели. Один из них заключается в том, чтобы обрабатывать нулевые или нечисловые значения (например, «cat») как недопустимые (как «cat» .to_f # => 0.0'). Вторая цель - игнорировать отрицательные поплавки. Ваш метод имеет дело с первым (лучше, чем 'to_f', так как это будет nix' "9lives" ', который' to_f' с радостью преобразует в '9.0', а также примет' 1.0e8 # => 100000000.0', так как я думаю, что это должно), но не со вторым. Конечно, это небольшая проблема. –

1

вы можете также использовать время цикла, как так:

while (input = gets.chomp.to_f) <= 0 
    puts "enter a valid input" 
end 
puts "you have $#{input}" 

Это использует встроенный назначение переменной. Переменная input переопределяется в каждом цикле, используя новый вызов gets. К концу цикла вы знаете, что у вас есть положительное значение.

2

Если вы положили тест завершения цикла в конце, вам не нужны избыточные утверждения, предшествующие циклу.

begin 
    puts "How much money do you have?" 
    money_1 = Float(gets) rescue 0 
    puts money_1 > 0 ? "You have $#{"%.2f" % money_1}" : "Please enter a valid amount" 
end until money_1 > 0 

Я также уменьшил if puts ... else puts... end к одной линии.

+0

Ницца. просто опечатка 'money1' –

+0

@ sagarpandya82, спасибо за улов и комплимент. Подумайте об этом, интересно, что означает '1' в' money_1'. Думаю, я бы использовал что-то вроде 'amount'. –

+2

Интересно, что [Мац не любит эту идиому и желает, чтобы он никогда не включал ее в язык] (http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745). Он даже заявил, что может удалить его в будущем, хотя лично я думаю, что это вряд ли произойдет. – philomory