Ruby While loop not working correctly - ruby

I have been trying to make a while loop in ruby that responds to user input.
What is supposed to happen is that when a user inputs the word "Omega" correctly it ends the loop and displays a message, if the word "hint" is entered a message is displayed and the loop repeats, and anything else will have a "try again" message displayed. What is happening is that regardless of what is entered, the loop just asks the original question.
Can anyone find what is wrong with my code, thank you
#GateOneLocked = true
GateOnePassword = String.new('Omega')
GateOneHint= String.new('hint')
#Omega is supposed to be the correct password
while (#GateOneLocked == true) do
puts 'What is the password?'
passwordEntered = gets.to_s
if (#passwordEntered == #GateOnePassword)
#GateOneLocked == false
else if (#passwordEntered != #GateOneHint)
puts "This is a hint: the password is 'Omega'"
puts " "
puts " "
else
puts "wrong password, try again"
puts " "
puts " "
end
end
end
puts 'You entered the correct password!'

instead #GateOneLocked == false should be #GateOneLocked = false
addiotional remarks:
in ruby variable names follow different conventions than C#/Java, instead of
GateOneLocked devs write gate_one_locked
no need to write String.new, variable = "your_string" is enough (GateOnePassword = 'Omega')
while(#GateOneLocked) is enough - no need to check whether it's == true

I made several fixes to your code. I changed the else if to elsif and added # to the variable references that were missing it so that your code is consistent. (I'd actually ditch them all unless you're using this code in a class.) I changed your #GateOneLocked == false to use the assignment operator instead of the comparison operator. Most importantly, perhaps, I added a chomp call that will remove the \n (new line character) from your user's input. Also, I changed the comparison in the elsif to == so that your user can request a hint, which is what I think you intended.
#GateOneLocked = true
#GateOnePassword = String.new('Omega')
#GateOneHint= String.new('hint')
#Omega is supposed to be the correct password
while (#GateOneLocked == true) do
puts 'What is the password?'
#passwordEntered = gets.chomp.to_s
if (#passwordEntered == #GateOnePassword)
puts "abc"
#GateOneLocked = false
elsif (#passwordEntered == #GateOneHint)
puts "This is a hint: the password is 'Omega'"
puts " "
puts " "
else
puts "wrong password, try again"
puts " "
puts " "
end
end
puts 'You entered the correct password!'

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

Conversion to integer isn't executing?

i have this code :
#require_relative '../lib/hackex/net/typhoeus'
require_relative '../lib/hackex'
require 'rubygems'
require 'faker'
print "how many farms do you want : "
choice = gets.chomp
choice.to_i
check = choice.is_a?(Integer)
puts check
if choice > 250
puts "Error! you cannot make more than 250 farms at once"
elsif choice < 250
puts "Error! you have to make at least one farm..."
elsif choice.is_a?(Integer) == false
puts "Error, something went wrong !"
else
puts "making #{choice} acounts ! ! !"
cnt = 1
while choice>cnt
gen = Faker::Name.first_name + Faker::Name.last_name
path=("created1.txt")
email = gen+'#gmail.com'
password = Faker::Internet.password(8)
username = gen.to_s+'/>'
puts HackEx::Request.Do(http,HackEx::Request.CreateUser(username, email, password, facebook_id = nil))
cnt +=1
open(path, 'a') { |f|
f << "#{email};"
f << "#{password}"
f << "\n"
}
puts "Account created!"
puts "#{choice - cnt} accounts remaining!"
end
end
i am trying to determing if the choice is an integer... i did the .to_i on choice, but it returns false, meaning its not an integer, its a string, why isnt it switching ?
ps : i do not get any errors, and the rest of the code works fine, except for the if part
choice.to_i returns an integer, but does not change choice. If you want choice to be changed to the integral value of the old choice, you need to reassign it explicitly:
choice = choice.to_i
Quoting the doc of String::to_i, emphasis is mine
to_i(base=10) → integer
Returns the result of interpreting leading characters in str as an
integer base base (between 2 and 36).
So you have to assign the return to something, or itself:
choice = choice.to_i

Two Parts, If I read in a file that's formatted like an array, can it be treated as such? And another about searching strings

I have two questions with this sample of code i'm about to drop in. The first deals with
person = gets.chomp
puts "Good choice! Here are #{person}'s tags!"
person = "#{person}.txt"
file = File.open(person)
while line = file.gets do
puts line
end
If the file that's opened is formatted exactly like an array (in this case its actually an array ruby has previously written to a txt file lets say, ["Funny", "Clever", "Tall", "Playboy"] ) Is there an easy way just make that an array again? Nothing I tried seemed to work.
The second deals with this
puts "Which tag would you like to vote on?"
tag = gets.chomp
if File.open(person).grep(/tag/) == true
puts "Found it!"
else
puts "Sorry Nope"
end
#f = File.new("#{person}")
#text = f.read
#if text =~ /tag/ then
#puts "Alright, I found that!"
#else
#puts "Can't find that sorry."
#exit
#end
This section just doesn't seem to be working. It never finds the string, also the commented out attempt didn't work either. I wasn't sure if the grep line actually returned a true or false value, but the commented out part avoids that and still doesn't return the string. I tried formatting the input with "" around it and every possible configuration ruby might be looking for but it always passes to the negative result.
and for the sake of completeness here is all the code.
puts "This is where you get to vote on a Tag!"
puts "Whose Tags would you like to alter?"
Dir.glob('*.txt').each do|f|
puts f[0..-5]
end
puts ".........."
person = gets.chomp
puts "Good choice! Here are #{person}'s tags!"
person = "#{person}.txt"
file = File.open(person)
while line = file.gets do
puts line
end
puts "Which tag would you like to vote on?"
tag = gets.chomp
if File.open(person).grep(tag) == true
puts "Found it!"
else
puts "Sorry Nope"
end
#f = File.new("#{person}")
#text = f.read
#if text =~ /tag/ then
#puts "Alright, I found that!"
#else
#puts "Can't find that sorry."
#exit
#end
Part 1 - Parse a string into an array
Use JSON.parse:
require 'json'
JSON.parse('["Funny", "Clever", "Tall", "Playboy"]')
# => ["Funny", "Clever", "Tall", "Playboy"]
Part 2 - Find a string in a file
As bjhaid recommended, use File.read and include?:
File.read(person).include?(tag)
This returns either true or false.
change:
if File.open(person).grep(tag) == true
puts "Found it!"
else
puts "Sorry Nope"
end
to
if File.read(person).include?(tag)
puts "Found it!"
else
puts "Sorry Nope"
end
File#open returns an IO object so you can't call grep on it like you would have done on an array, so I would suggest File.read which returns a String object that you can now call include? on

how to re-ask a user for input if none was given the first time?

My current code is this:
print "Feed me input."
def get_input
input_value=gets.chomp
if !input_value
print "you didn't type anything"
else
input_value.downcase!
if input_value.include? "s"
input_value.gsub!(/s/,"th")
else
print "You entered a string but it had no 's' letters."
end
end
return input_value
end
get_input()
if !get_input
get_input
else
puts "#{get_input}"
end
I'm not sure why it isn't working. When I run it I get prompted for input then when I press enter after entering none I get the "You entered a string but it had no 's' letters", not the "you didn't type anything" that I wanted.
Every object except false and nil is treated as false if they are used as predicates. Even empty string is treated as true:
s = ""
puts true if s # => true
Use String#empty? to check if it is empty string.
As you said When I run it I get prompted for input then when I press enter after entering none - It means what happened acctually is
input_value="\n".chomp #( you gets methods take only `\n` as input)
"\n".chomp # => ""
so your input_value variable holds and empty string object. Now in Ruby every object has true value, except nil and false. Said that "" is also true,but you did !input_value,which means you are making it false explicitly. That's the reason in the below if-else block, else part has been executed and you didn't see the expected output "you didn't type anything".
if !input_value
print "you didn't type anything"
else
input_value.downcase!
if input_value.include? "s"
#.. rest code.
So I would suggest you in such a context replace the line if !input_value to if input_value.empty?, Which will make your code to behave as you are expecting. I didn't take your logic as a whole,but tries to show you how to code to meet your needs:
print "Feed me input."
def get_input
input_value=gets.chomp
if input_value.empty?
puts "you didn't type anything"
false
else
puts "found value"
input_value.downcase!
end
end
until input = get_input
# code
end
puts input
output
kirti#kirti-Aspire-5733Z:~/Ruby$ ruby test.rb
Feed me input.
you didn't type anything
you didn't type anything
you didn't type anything
HH
found value
hh
kirti#kirti-Aspire-5733Z:~/Ruby$

Resources