awords = []
word = "x"
puts "Type as many words as you want, or press \"enter\" to quit."
while word != ""enter code here
#get word from user
word = gets.chomp
if word == ('')
puts 'you input nothing'
end
#add to array
awords.push word
end
#user exited loop test for array before printing
puts "Now sorting what you typed.. thanks."
puts awords.sort
Everything works fine, but I want this program to skip last two "puts" if users don't input anything. Is there anyway I could just stop program after puts 'you input nothing' if users decide not to input but press enter?
If you don't want to puts the last two lines, then you should check to make sure there are values within awords.
awords = []
word = 'x'
puts "Type as many words as you want, or press \"enter\" to quit."
until word.empty?
word = gets.chomp
if word.empty?
puts 'you input nothing'
end
awords << word
end
# Check to make sure awords has values in it
unless awords.empty?
puts "Now sorting what you typed.. thanks."
puts awords.sort
end
Now the easiest way to stop the program early if no input was ever given is to add a line after puts 'you input nothing' with a return.
puts 'you input nothing'
return if awords.empty?
You'll notice that I changed a lot of your == '' methods to .empty? because that is the ruby way of doing that type of check with strings.
awords = []
word = 'x'
puts "Type as many words as you want, or press \"enter\" to quit."
until word.empty?
word = gets.chomp
if word.empty?
puts 'you input nothing'
end
awords << word
end
# Check to make sure awords has values in it
unless awords.empty?
puts "Now sorting what you typed.. thanks."
puts awords.sort
end
thank you that was very clear
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}."
Instead of doing:
puts "what type of input?"
input = gets.chomp
if %W[Int INT i I Ints ints].include?(input)
puts "enter int"
i = gets.to_i
I want to use regex to interpret string user input. For example,
puts "are you entering in a string, an int or a float?"
case gets
when /\A(string|s)\z/i
puts "enter in a string"
gets.chomp
when /\A(int|i)\z/i
puts "enter an int"
gets.to_i
when /\A(float|f)\z/i
puts "enter a float"
gets.to_f
end
What is the syntax in order to get the same result but using if statements instead of case statement?
gets returns a string with a trailing carriage return. What you need is to match the ending against \Z, not \z.
puts "are you entering in a string, an int or a float?"
case gets
when /\As(tring)?\Z/i
puts "enter in a string"
gets.chomp
when /\Ai(nt)?\Z/i
puts "enter an int"
gets.to_i
when /\Af(loat)?\z/i
puts "enter a float"
gets.to_f
else puts "Didn’t work"
end
I also slightly updated regexps to clearly show the intent.
If you want to turn your case into an if, you have to store the expression intended for the gets into a variable:
response=gets.chomp
if /..../ =~ response
...
elsif /.../ =~ response
....
....
else
...
end
This is a problem where they have asked me to add an additional if statement to re-prompt the user for input if they don't enter anything.
I have tried to use the while loop, but still can't solve the problem
print "please enter a sentence with a letter s"
while user_input = gets.chomp.downcase!
case user_input
when user_input.include? "s"
user_input.gsub(/s/,"th")
print "Daffy Duck says #{user_input}"
break
else
print "please enter a sentence with a letter s"
end
I expect "please enter a sentence with a letter s" to loop until the user enters the letter "s"
My understanding is that the user enters sentences until one contains an "s" or an "S", at which time a certain action is taken and the program terminates.
Let's go through what you have.
print "Please enter a sentence with a letter s"
I think you want puts, which adds a newline character, rather than print, which does not.
while user_input = gets.chomp.downcase!
Suppose the user enters "Cat" (even though it's not a sentence), then presses the Enter key, then
str0 = gets
#=> "Cat\n"
str1 = str0.chomp
#=> "Cat"
user_input = str1.downcase!
#=> "cat"
str1
#=> "cat"
user_input
#=> "cat"
so we have
while "cat"
As "cat" is neither false nor nil (the only logical false objects), this is the same as
while true
so execution moves to the first statement within the while loop. Suppose instead the user entered "cat" and pressed the Enter key. Then
str0 = gets
#=> "cat\n"
str1 = str0.chomp
#=> "cat"
user_input = str1.downcase!
#=> nil
str1
#=> "cat"
user_input
#=> nil
so the program would not enter the while loop! How, you ask, can "cat".downcase return nil? Look at the doc for String#downcase!. It shows that nil is returned if there were no characters to downcase. Ruby has many methods that do the same: if the receiver is not altered nil is returned. (Don't get sidetracked with "why" at this point of your education.) For the present you are advised to avoid using bang methods (ending with an "!").
Similarly, if the user didn't enter anything and pressed enter,
str1 = "\n".chomp
#=> "" (an empty string)
user_input = str1.downcase
#=> nil
"".downcase! returns nil for the same reason that "cat".downcase! does.
I think what you what here is the following.
user_input = gets.chomp
while !user_input.match?(/s/i)
/s/i is a regular expression used to determine if the string contains an "s" or an "S". i in /i is a case-indifference modifier. (One could instead write while user_input !~ /s/i.)
The first statement within the while loop is
case user_input
When case has an argument (here user_input) the when statements contain arguments that are possible values of the case argument, for example
case user_input
when "call me silly!"
puts "You are silly"
when...
You are not doing that here, so you want case on a line by itself:
case
when user_input == ...
...
end
Here, however, there is no need for a case statement or "if/elsif/else/end" construct within the loop because we have already determined that user_input does not contain an "s". All we need in the loop is this:
while !user_input.match?(/s/i)
puts "Please enter a sentence with a letter s"
user_input = gets.chomp
end
After the loop is terminated user_input is a string that contains an "s". We therefore need only perform the following.
puts "Daffy Duck says #{user_input}"
#=> "Quack, quack, quackity-quack, sir"
Note that your statement
user_input.gsub(/s/, "s")
substitutes each "s" with an "s". :-) Nor is there a need for the break keyword.
Putting all this together, you could write:
puts "Please enter a sentence with a letter s"
user_input = gets.chomp
while !user_input.match?(/s/i)
puts "Please enter a sentence with a letter s"
user_input = gets.chomp
end
puts "Daffy Duck says #{user_input}"
You thought I was finished. Not so fast!
Firstly, many Ruby coders try to avoid negations such as while !user_input.match?(/s/i) (though it is purely a matter of taste). You could instead write that line
until user_input.match?(/s/i)
A more significant problem is the replication of code. You can improve upon that by using Kernel#loop and the keyword break instead of while or until.
loop do
puts "Please enter a sentence with a letter s"
user_input = gets.chomp
if user_input.match?(/s/i)
puts "Daffy Duck says #{user_input}"
break
end
end
If, however, we wrote
loop do
puts "Please enter a sentence with a letter s"
user_input = gets.chomp
break if user_input.match?(/s/i)
end
puts "Daffy Duck says #{user_input}"
The last line would raise the exception
NameError (undefined local variable or method `user_input' for main:Object)
because the variable user_input is only defined within the loop.
I generally use loop and break in preference to while or until.
Is your problem a program not working?
What do you want to do the following?
please enter a sentence with a letter s: a
please enter a sentence with a letter s: s
Daffy Duck says: s
in this case,
print "please enter a sentence with a letter s: "
while user_input = gets
user_input.chomp.downcase!
if user_input.include? "s"
user_input.gsub(/s/,"s")
print "Daffy Duck says: #{user_input}"
return
else
print "please enter a sentence with a letter s: "
end
end
The i after /s/ is case-insensitive search.
If the string has an s and we remove it, the
original will not match
puts "please enter a sentence with a letter s"
while user_input = gets
user_input = user_input.chomp
if user_input != user_input.gsub(/s/i,"")
puts "Daffy Duck says: #{user_input}"
break
else
puts "please enter a sentence with a letter s"
end
end
The match location will be a zero-based integer index if found
or nil if no match
puts "please enter another sentence with a letter s"
while user_input = gets
user_input = user_input.chomp
match_location = user_input =~ /s/i
if match_location.nil?
puts "please enter a sentence with a letter s"
else
puts "Daffy Duck says: #{user_input}"
break
end
end
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.
Getting stuck on chapter 8:
Type as many words as we want
One word per line, continuing until we just press Enter on an empty line
Repeats the words back to us in alphabetical order.
Use 'sort'
So, here's what I got to, but I'm having funny issues with not getting the first word to push into the array [among other things]
# alphabetting
puts 'Tell us some of your favorite things!'
# create an array
words = []
while gets.chomp != ''
words.push gets.chomp
words.sort
puts words
end
Did this and it works now... Do I have to have "thing" in there though? Seems naughty to assign within a 'while' loop.
puts 'Tell us some of your favorite things!'
words = []
puts words
while (thing = gets.chomp) != ''
words.push thing
end
puts words.sort
Your first gets call is not referred to by anything, and is thrown out. It is not just the first word, but every other word that is going to be thrown out. The output routine should also be outside of the loop. A fix is:
words = []
while word = gets.chomp and not word.empty?
words.push(word)
end
puts words.sort
Try this:
puts 'Tell us some of your favorite things!'
words = []
while line = STDIN.gets
line = line.chomp
break if line.empty?
words << line.chomp
end
words = words.sort
words.each {|word| puts word }