Ruby trouble with breaking loop - ruby

All right, I have the programming aptitude of a goldfish, so I could use some help. I have the following code (please excuse my terrible sense of humor):
puts 'Do you have a middle name?'
answer=gets.chomp.downcase
while true
if answer != ('yes' || 'no')
puts 'Yes or no answers only, dumbass.'
puts 'So I\'ll ask again. Do you have a middle name?'
answer=gets.chomp.downcase
elsif answer == ('yes' || 'no')
if answer == 'yes'
puts 'Cool. What is it?'
middlename=gets.chomp
puts middlename +'? That\'s dumb.'
break
if answer == 'no'
puts 'I guess you aren\'t cool enough.'
break
end
end
end
end
puts 'Well, smell ya later.'
It works mostly fine, but I have one problem: choosing the no option. I cannot figure out how to get that to work. It will loop fine, and choosing the yes option works.
Basically, my question is: how do I create a loop with two break options?

For something like this you should use a case/when which is a Ruby switch statement because having all of those if/end blocks will get confusing fast.
Also please read this guide: https://github.com/bbatsov/ruby-style-guide
It will teach you how to properly format your ruby code.
puts 'Do you have a middle name?'
answer=gets.chomp.downcase
case answer
when 'yes'
puts 'Cool. What is it?'
middlename=gets.chomp
puts middlename +'? That\'s dumb.'
when 'no'
puts 'I guess you aren\'t cool enough.'
else
puts 'Yes or no answers only, dumbass.'
puts 'So I\'ll ask again. Do you have a middle name?'
answer=gets.chomp.downcase
end
puts 'Well, smell ya later.'
And if you always want it to loop when they don't answer yes or no. You can do that by wrapping the code block in a loop as follows:
puts 'Do you have a middle name?'
answer=gets.chomp.downcase
loop do
case answer
when 'yes'
puts 'Cool. What is it?'
middlename=gets.chomp
puts middlename +'? That\'s dumb.'
break
when 'no'
puts 'I guess you aren\'t cool enough.'
break
else
puts 'Yes or no answers only, dumbass.'
puts 'So I\'ll ask again. Do you have a middle name?'
answer=gets.chomp.downcase
end
end
puts 'Well, smell ya later.'
See this answer: How to write a switch statement in Ruby

if answer != ('yes' || 'no') isn't doing what you think it is. Since 'yes' is non-nil, which is true, the logical OR is short-circuited and the value of the parenthetic expression is always 'yes'. Try if answer != 'yes' && answer != 'no' instead.

Related

Ruby Endless Loop

I am new to Ruby. I have written the code below, its working about 90% except the else statement. The else statement triggers endless loop. I just want it to ask user to try again. Here is my code
puts "Do you want to print something? (Y / N)"
user = gets.chomp.downcase
answer = true
while answer
if user == "y"
puts "Something"
answer = false
elsif user == "n"
puts " "
answer = false
else
puts "Invalid input! Please enter Y or N"
end
end
Somewhat shorter (note user has gone, the answer is now referred to as answer).
answer = ""
until (answer == "y") or (answer == "n")
puts 'Do you want to print something? (Y/N)'
answer = gets.chomp.downcase
end
Once you exit the else, answer is still true. If you want to re-prompt, you can move your puts and user statement into the loop.
Something like this should work.
while true # (alternately) loop do
puts 'Do you want to print something? (Y/N)'
case gets.chomp.downcase
when 'y'
puts 'foo'
break
when 'n'
puts 'bar'
break
else
puts 'Invalid input! Please enter Y or N'
end
end
You can use break to exit out of your loop instead of setting up another variable. Also, this looks like a good use-case for a case statement to have some explicit cases listed.

Enter with no input as a valid boolean

I'm writing some very simple code, asking for confirmation on a text input, and
what I want to do is that if the users simply presses "Enter", make it count as a "yes". For example:
define method
puts "enter some text"
#text= gets.chomp
puts "you entered '#{#text}', is it correct?"
correct = gets.chomp
if correct == 'y' || ''
other_method
else
method
end
end
But when I run it on Ruby, I get the "Warning, literal string in condition", and whatever you enter, calls the "other_method". The solution I found is the following:
define method
puts "enter some text"
#text= gets.chomp
puts "you entered '#{#text}', is it correct?"
correct = gets.chomp
if correct == 'y'
other_method
elsif correct == ''
other_method
else
method
end
end
But it's pretty annoying, I'd rather understand why the first one doesn't work, and how can I make it work using the | |
Thank you!
What the error is saying is that you are supplying a string (literal) inside of a conditional statement by itself. When you do if correct == "y" || "" you're actually telling it if correct == "y" OR "" and just supplying the string by itself is not a condition.
To fix this you'd simply supply the condition after the operator as well as before it. Ruby does not assume you want the same thing to happen after the ||.
Like this:
define method
puts "enter some text"
#text= gets.chomp
puts "you entered '#{#text}', is it correct?"
correct = gets.chomp
if correct == 'y' || correct == ''
other_method
else
method
end
end
Hope this helps. Happy coding
The solution here is to use Ruby's very versatile case statement to set up a number of "cases" you want to test:
puts "you entered '#{#text}', is it correct?"
case (gets.chomp)
when 'y', 'yes', ''
method_a
else
method_b
end
This can be extended to use regular expressions for even more versatility:
case (gets.chomp)
when /\A\s*y(?:es)?\s*\z/i
method_a
else
method_b
end
Where now anything like "y" or "yes" or "Yes " will work.
When you have bunch of if statements all testing the same variable, consider using a case statement to simplify your logic.
Here is another option using Regex (Docs):
puts "enter some text"
#text= gets.chomp
puts "you entered '#{#text}', is it correct?"
correct = gets.chomp
if /^y?$/ =~ correct # This will match 'y' and empty string both
other_method
else
method
end

Ruby - if else statement

I have been working on the configuration an else statement.
Here is the code:
puts "Do you like PC?"
case (gets.chomp)
when 'yes'
puts "I do too"
when 'no'
puts "Mac is better"
end
Now I am trying to configure it to (1) use else, and (2) to use elsif. How do I better write this to use "else", and how do I write it to use elsif. Here is what I wrote for the else version
puts "Do you like PC?"
case (gets.chomp)
if 'yes'
puts "I do too"
else
puts "Mac is better"
end
You should re-write as:
puts "Do you like PC?"
answer = gets.chomp
if answer == 'yes'
puts "I do too"
elsif answer == 'maybe'
puts "you're confused"
else
puts "Mac is better"
end
The keyword case is preserved for case statements.

How to wrap a loop around an if statement [duplicate]

This question already has answers here:
Is there a "do ... while" loop in Ruby?
(10 answers)
Closed 8 years ago.
I'm coding a program that asks whether or not the user wants to give his name. If the user responds 'yes', the question is asked; on 'no' the program quits. If the users enter anything else, they are reminded to say either 'yes' or 'no'.
My code so far:
puts "Would you like to give us your name? (type yes or no)"
answer = gets.chomp
if answer == "yes"
print "What's your name?"
name = gets.chomp
puts "Nice to meet you, #{name}"
elsif answer == "no"
puts "Oh, ok. Good bye"
else
puts "You need to answer yes or no"
end
I need start over, if the user does not enter 'yes' or 'no' for the initial question.
You can solve that problem with a while loop, that breaks only when the correct input is made.
puts "Would you like to give us your name? (type yes or no)"
while answer = gets.chomp
case answer
when "yes"
print "What's your name?"
name = gets.chomp
puts "Nice to meet you, #{name}"
break
when "no"
puts "Oh, ok. Good bye"
break
else
puts "You need to answer yes or no"
end
end
answer = ""
while (answer != "yes" && answer != "no") do
puts "Would you like to give us your name? (type yes or no)"
answer = gets.chomp
end
if answer == "yes"
print "What's your name?"
name = gets.chomp
puts "Nice to meet you, #{name}"
elsif answer == "no"
puts "Oh, ok. Good bye"
else
puts "You need to answer yes or no"
end
This would be better accomplished creating a Method
Something like this will work for you:
def getname
# ask the user if we should continue
puts "Would you like to give us your name? (type yes or no)"
answer = gets.chomp
if answer == "yes"
# the user said yes. get the name
print "What's your name?"
name = gets.chomp
elsif answer == "no"
# the user said no. get out of here
puts "Oh, ok. Good bye"
else
# the user didnt answer correctly
puts "You need to answer yest or no"
# so we call this very function again
getname
end
end
# call the above method that we created
getname
What we did here was wrap your code in a method declaration. In that very method declaration we call that very method if the user doesnt supply the expected input.
Hope this helps.

ruby program basic design explanation

I want to rewrite the following code with the code below, but I am stuck.
def ask question
good_answer = false
while (not good_answer)
puts question
reply = gets.chomp.downcase
if (reply == 'yes' or reply =='no')
good_answer = true
if reply == 'yes'
answer = true
else
answer = false
end
else
puts 'Please answer "yes" or "no"'
end
end
answer
end
Replacement code:
def ask question
puts question
reply = gets.chomp
if (reply == 'yes' or reply == 'no')
puts reply.capitalize
else
puts 'Please enter "yes" or "no"'
#jump the code to like 2 ( but how?)- use while reply != empty & comment the below lines
puts question
reply = gets.chomp
end
end
I want to jump to the main part of program is there any goto, jump or can I call method inside that method?
I want to jump to the main part of program is there any goto, jump or can I call method inside that method?
Yes, it is called a loop, i.e., what you are using in your original code. Why in the world would you want to replace a loop with a goto? Makes no sense.
It can however be simplified. I don't like the checking against 'yes' or 'no', but I also don't have time to restructure your program.
def ask question
while true
puts(question)
reply = gets.chomp.downcase
if reply == 'yes' || reply == 'no'
return reply == 'yes'
else
puts('Please answer "yes" or "no"')
end
end
end
Even if there was a goto statement you shouldn't be using it. Not only is it bad form, but it causes all kinds of headaches for maintainers since your program ends up being hard to follow.
A better approach is to define proper structures for your questions and valid answers, then iterate over those simply, collecting the results into a structure you can use later:
# Auto-flush output buffer
STDOUT.sync = true
questions = [
[ 'Is this a good question?', 'yes', 'no' ],
[ 'Is the sky blue?', 'yes', 'no' ],
[ 'Do hamsters fly?', 'no', 'yes' ]
]
answers_given = [ ]
questions.each do |question, *answers|
print question + ' '
while (true)
answer = gets
answer.chomp!
if (answers.include?(answer))
puts "Thanks!"
answers_given << (answer == answers.first)
break
end
puts "You must answer one of #{answers.join(', ')}!"
print question + ' '
end
end
questions.each_with_index do |(question, *answers), i|
puts "#{question} #{answers_given[i]}"
end
You can try something liek this:
def ask_question
puts('Please answer "yes" or "no"') until (reply = gets.chomp.downcase) =~ /^(yes|no)$/
return reply == 'yes'
end
def ask question
puts question
reply = gets.chomp.downcase
if (reply == 'yes' or reply == 'no')
puts reply.capitalize
else
puts 'Please enter "yes" or "no"'
ask question # this does the looping of loop
end
end
Thanks, and sorry I didn't copy it well from my clipboard last time.

Resources