условные операторы, принимающие в качестве входных данных только целое число - PullRequest
2 голосов
/ 25 октября 2019

Я написал код, в котором он задает вопросы нескольким лицам, а ответы каждого из них помещаются в хэш. Это в цикле и выглядит примерно так:

arr:[]
     (1..n).each do |i|

 hash=Hash.new()

 puts "Please input a value for day # #{i}" 
 hash["day1"]=gets.chomp.to_f

 puts "Please input a value for day # #{i}" 
 hash["day2"]=gets.chomp.to_f

 arr << hash
 end 

Поэтому, чтобы избежать неправильного ввода (т. Е. Вводить строку вместо целого числа / числа), мне нужно поместить условный оператор. Я очень запутался в том, как бы я это сделал, хотя, так как я назначаю входные данные пользователей в хеш-код, я беру их вклады. Возможно ли это сделать или я должен полностью выбрать другой маршрут?

спасибо

Ответы [ 2 ]

0 голосов
/ 27 октября 2019

Возможно, вы можете рассмотреть этот общий подход для проверки пользовательского ввода, обратите внимание, что этот пример require 'date'.

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


Сначала определите массив вопросов, содержащий текст вопроса, метод проверки и способ преобразования входных данных, например:
questions = [
              {text: "Enter an integer:", validate: :must_be_an_integer, convert: :my_to_i},
              {text: "Enter a float:", validate: :must_be_a_float, convert: :my_to_f},
              {text: "Enter a data as d-m-yyyy", validate: :must_be_a_formatted_date, convert: :to_formatted_date}
             ]


Затем определите некоторые методы, которые будут вызываться клавишей :validate, для проверки ввода пользователя:
def must_be_an_integer(num)
  Integer(num).class == Integer rescue false
end

def must_be_a_float(num)
  Float(num).class == Float && num.include?('.') rescue false
end

def must_be_a_formatted_date(date_str)
  date = Date.strptime(date_str, "%d-%m-%Y") rescue false
  return false unless date
  date.year <= 9999 && date.year >= 1000
end


Определите также методы, требуемые клавишей :convert (необходимо передатьаргумент, поэтому my_to_i и my_to_f):
def my_to_i(num)
  num.to_i
end

def my_to_f(num)
  num.to_f
end

def to_formatted_date(date_str)
  DateTime.strptime(date_str, "%d-%m-%y")
end


Наконец, итерации по вопросам:
res = questions.map do |question|
  answer = nil
  3.times do
    puts question[:text]
    u_input = gets.chomp
    if send question[:validate], u_input
      answer = send question[:convert], u_input
      break
    end
  end
  if answer.nil?
    puts "C'mon man! Check your keyboard!" # after three input errors!!
    break
  end
  { question: question[:text], answer: answer }
end


Пример результата:
#=> [
     {:question=>"Enter an integer:", :answer=>1},
     {:question=>"Enter a float:", :answer=>1.1},
     {:question=>"Enter a data as d-m-Y", :answer=>#<DateTime: 2020-10-27T00:00:00+00:00 ((2459150j,0s,0n),+0s,2299161j)>}
    ]
0 голосов
/ 25 октября 2019

Вы можете получить значения дня, как показано ниже. Когда вводится символ, отличный от числа, он снова запрашивает значение этого дня.

puts 'Enter number of days'
days_hash = {}
number_of_days = gets.chomp.to_i
day = 1

while day <= number_of_days
  puts "Please enter a value for day # #{day}" 
  input = gets.chomp
  if input !~ /\D/
    days_hash["day#{day}"] = input.to_i
    day += 1
  else
    puts "Please enter only number"
    next
  end
end

p days_hash
#=> { "day1" => 2, "day2" => 4, "day3" => 8 }
days_hash['day2']
#=> 4
...