I am trying to validate proper date input in my ruby script.
When I run the script it just asks for the date twice no matter if it is correct or not.
Could someone please tell me where I went wrong?
def get_date(prompt="What is the date of the last scan (YYYYMMDD)")
new_regex = /\A[0-9]{4}[0-1][0-9][0-3][0-9]\z/
print prompt
gets.chomp
if prompt != new_regex
puts "Please enter the date in the correct format"
print prompt
gets.chomp
end
end
Your code, as it is, is trying to compare the likeness of the prompt to the regex pattern.
/\A[0-9]{4}[0-1][0-9][0-3][0-9]\z/ === /\A[0-9]{4}[0-1][0-9][0-3][0-9]\z/ is true.
Your input is also not being captured, and thus not compared to the regex.
def get_date(prompt="What is the date of the last scan")
new_regex = /\A[0-9]{4}[0-1][0-9][0-3][0-9]\z/
print prompt + " (YYYYMMDD)"
input = gets.chomp
unless (input =~ new_regex) == 0
puts "Please enter the date in the correct format"
get_date(prompt)
end
input
end
input =~ new_regex will be nil (false) if there's no match.
(ps Rubyists like two spaces)
Related
I want in brief to run a program to check if the user input is empty to let him reinsert the needed data and in case there is "s" in the string to be substituted with another letter
print "Please enter a string: "
user_input = gets.chomp.downcase!
if user_input.empty?
print "Please enter a vaild string... "
user_input = gets.chomp.downcase!
elsif
user_input.include? "s"
user_input.gsub!(/s/, "th")
else
puts "There are no 's's in your string. #{user_input}"
end
puts "Your new thtring is #{user_input}."
The problem is with this line
user_input = gets.chomp.downcase!
according to the docs
Downcases the contents of str, returning nil if no changes were made.
So if the user inputs a string with only lowercase letters, nil is returned.
Your function works if a user enters FOO, then it works fine.
You're better off using downcase instead of downcase!. downcase always return the string itself.
As I understand you need get valid user input (with s)
Now you are only using if and this does not guarantee that user input will be valid
You can refactor to something like this
puts "Please enter a string with s:"
thtring = ""
loop do
user_input = gets.chomp
next puts "Please enter some string..." if user_input.empty?
thtring = user_input.downcase
next puts "There are no 's's in your string" unless thtring.include?("s")
break thtring.gsub!(/s/, "th")
end
puts "Your new thtring is #{thtring}."
I'm trying to loop this question until the user's input is a string value:
Question: What is your name?
I don't want the user to just press enter and leave the name blank.
I don't want the user's input to be numeric/numbers.
Please see my code below:
name1 = gets.chomp.to_s
loop do
print "Please enter your name "
name1 = gets.chomp.to_s
if name1.empty?
puts "No input."
else name1.to_i
puts "Illegal character ':'"
end
end
With this code, I can't proceed to the next question even if I input a string value. Please help.
Your code has several issues:
Your input and output is out of order. You gather input before prompting and that input (from your first line) is never used:
name1 = gets.chomp.to_s # <- Ruby is waiting for input
loop do
print "Please enter your name " # <- user is prompted to enter name
name1 = gets.chomp.to_s # <- previous input is overwritten
# ...
end
The first line should probably be deleted.
gets might return nil, but chomp always returns a string. Calling to_s afterwards is therefore superfluous.
Your if-else construct is actually:
if name1.empty?
puts "No input."
else
name1.to_i
puts "Illegal character ':'"
end
So whenever the input is not empty?, you convert it to an integer (discarding the result) and print an error message. You probably want an elsif instead (/.../ is a regexp and \d matches a digit):
if name1.empty?
puts 'No input.'
elsif name1.match? /\d/
puts 'Digits not allowed.'
end
You could also use a case expression:
case name1
when ''
puts 'No input.'
when /\d/
puts 'Digits not allowed.'
end
You never break out of your loop. The code keeps looping even if no error was found. This can be fixed by adding a break statement in an else branch (to either if or case):
# ...
else
break
end
gets.chomp will always return a string, and as such there is no need to call to_s on the method.
If you don't want the user to be able to input any integers, you could use the following for a clean solution:
name.count("0-9") > 0
If this returns true, then you know that the user's input contains at least one number.
I want to check if a field was filled in. I have an imcompleted code:
print "What is your name?"
user_input = gets.chomp.upcase
if user_input = ??
print "Nice to meet you user_input!"
else
puts "Please enter your name."
end
How do I complete the code to do that?
Under the premise that you would like to:
Print out a message: "What is your name?"
Have the user enter their name and store it in the user_input variable(with gets.chomp)
Output either "Nice to meet you << user name >>" or "Please enter your name" depending on whether the input matches certain criteria
...we have a few changes to make.
The first being the condition of checking to make sure the input isn't blank and the second being seeing if the input matches a certain value.
First, let's check to see if the input is empty before continuing. We can use String#empty to make sure the string has at least one character (including whitespace):
print "What is your name?"
user_input = gets.chomp.upcase
# Check to make sure the input isn't empty
if !user_input.empty?
print "Nice to meet you user_input!"
else
puts "Please enter your name."
end
Then, we can check to see if the input matches certain criteria. Unfortunately, your question doesn't specify what these criteria are, so as other users are suggesting you can use regex to see if it matches a particular pattern, or just use a hard coded string to compare:
print "What is your name?"
user_input = gets.chomp.upcase
# After making sure the input is empty, check to make sure it matches the string "Bob"
if !user_input.empty? && user.input == "Bob"
print "Nice to meet you user_input!"
else
puts "Please enter your name."
end
Lastly, there is one bug in the code. The output once a user's input has been validated will always be "Nice to meet you user_input", even when the user_input variable is another value. This is because we aren't using String Interpolation properly:
print "What is your name?"
user_input = gets.chomp.upcase
if !user_input.empty? && user.input == "Bob"
# When using string interpolation, surround the variable you'd like to print with #{}
print "Nice to meet you #{user_input}!"
else
puts "Please enter your name."
end
As other users have stated, you should consider fine tuning the requirements of your problem a bit more. You can add a lot of detail and experimentation to this simple example!
There's a lot of context missing from the question, but there are a couple of things that may be helpful to you.
Basic check if it's nil or empty:
if user_input.nil? || user_input.empty?
# Ask the user to try again
end
Check if it matches a pattern you specify using a Regex (see https://ruby-doc.org/core-2.1.1/Regexp.html). For example:
if user_input =~ /^[[:upper:]][[:lower:]]+/
# One uppercase character, followed by at least one lowercase
end
The second option has far more possibilities, but again it depends on your needs.
if user_input.blank?
puts "please enter your name"
else
puts "Nice to met you"
end
I need to check whether my variable is an Integer or a String.
The code below will just break the loop, without warning me for an illegal character. Can anyone help me to find the mistake?
x = 0
while x == 0
name = gets.chomp.capitalize
if name.empty?
puts "No input. Try again"
elsif name.is_a? Integer
puts "Illegal character: Integer "
else
x = 1
end
end
Because gets returns a string you need to find out if the string represents a number (and only a number).
First, translate your string to an integer with to_i. Please note that to_i returns 0 for strings that do not include numbers. In a second step check if translating this integer back into a string matches the original string
string.to_i.to_s == string
Note that this is just a simple example, it wouldn't work for example with the string 00.
Another way might be checking if the string only contains numbers. That could be done by using a regexp:
string.match(/\A\d+\z/)
You can do something like this:
loop do
puts "Enter name"
name = gets.chomp
if name.empty?
puts "No input, try again"
elsif name.scan(/\d+/).any?
puts "Illegal character: Integer"
else
raise StopIteration
end
end
case-expression
Or use a case-expression to tidy things up.
loop do
puts "Enter name"
case gets.chomp
when ''
puts "No input, try again"
when /\d/
puts "Illegal character: Integer"
else
raise StopIteration
end
end
See String#scan, Array#any? and StopIteration for further details
how do I loop if a condition is not met?
print "Please enter first number "
first_number = gets.chomp
if first_number =~ /[a-zA-Z]/
puts "not a number"
end
As per the code posted above, if you enter a letter, you'll get the statement of it not being a number.
How do I repeat it, if a user enters a letter?
As of now, it goes to the next one which is this:
print "Please enter second number "
second_number = gets.chomp
if second_number =~ /[a-zA-Z]/
puts "not a number"
end
I don't want it to it to go to the next one, until the user has entered a number in the first one.
You can use while and until as a modifier to a block. This will run the block first and then check a conditional and run the block again until it passes, which is the behavior you want.
begin
puts 'Please enter first number'
first_number = gets.chomp
end until first_number =~ /\d+/
I suggest you consider doing it like this:
num = nil # initialize to anything
loop do
puts 'Enter a number'
num = gets.chomp.strip
case num
when /^\d+$/
break
when /^[a-z]+$/i
print "You entered one or more letters and no digits."
else
print "You made some other illegal entry."
end
puts " Try again"
end
puts "You enterered the number #{num}"
Some notes:
num must be initialized (to anything) before the loop in order for it to be visible after the loop's end statement.
the case statement, since it uses === for evaluating when expressions, allows you to enter a regex for each case.
^ and $ in the regexes are anchors, so that, for example, "34b" =~ /^\d+$/ => nil (what I assume you want), rather than "34b" =~ /\d+/ => 0.
the i in /[a-z]+$/i allows matching letters to be uppercase or lowercase.
the user may enter one or more digits, or one or more letters, but there are many other possibilities as well ("3$,a"), so I added another "catch-all" possibility in the case statement.