I trying to make loop through if statement if user input is invalid it keep telling to enter number only or break if true
I tried this is my code
class String
def numeric?
Float(self) != nil rescue false
end
end
cond = false
puts "Enter number "
line = gets.chomp.strip
while cond == false
if (line.numeric? )
puts "Ok nice "
cond = true
else
puts "Please enter number only "
end
end
but it keep looping if the condition is false just printing "Please enter number only "
i will be very happy for any suggestion
Thank you
The problem is that after telling the user to just enter a number you don't read another number, you just loop back around.
The easiest way to fix this is to move the prompt and input into the while loop, a bit like this:
class String
def numeric?
Float(self) != nil rescue false
end
end
cond = false
while cond == false
puts "Enter number "
line = gets.chomp.strip
if (line.numeric? )
puts "Ok nice "
cond = true
else
puts "Please enter number only "
end
end
try this:
while cond == false
if (line.numeric? )
puts "Ok nice "
cond = true
else
puts "Please enter number only "
line = gets.chomp.strip
end
end
Right after overriding String method, try this:
while true
print "Enter number "
line = gets.chomp.strip
if line.numeric?
puts "Ok nice"
break
else
puts "Please enter number only"
end
end
Related
I created a calculator in ruby. I am wondering how to put this in a loop so I don't have to run it constantly. I am new to programming so please understand I am I just trying to learn. I would appreciate any help provided.
puts "Hello, My name is Calvin The Calculator and I am a calculator that can do basic functions such as Adding, Subtracting, Multiplying and Dividing"
puts "Press a and enter to enable my services"
enable = gets.chomp
if enable == "a"
puts "Choose which operation you want to do. + for adding, - for subtraction, * for multiplication and / for division"
else
"Puts Im Waiting..."
end
which_operation = gets.chomp
if which_operation == "+"
puts "What is the first number you want to add"
adding_first_number = gets.chomp.to_i
puts "What is the second number you want to add to #{adding_first_number}"
adding_second_number = gets.chomp.to_i
puts "#{adding_first_number} + #{adding_second_number} is #{adding_first_number + adding_second_number}"
else
end
if which_operation == "-"
puts "What is the first number you want to subtract"
subtracting_first_number = gets.chomp.to_i
puts "What is the number you want to subtract from #{subtracting_first_number}"
subtracting_second_number = gets.chomp.to_i
puts "#{subtracting_first_number} - #{subtracting_second_number} is #{subtracting_first_number - subtracting_second_number}"
else
end
if which_operation == "*"
puts "What is the first number you want to multiple"
multiplying_first_number = gets.chomp.to_i
puts "What is the number you want to multiple #{multiplying_first_number} by"
multiplying_second_number = gets.chomp.to_i
puts "#{multiplying_first_number} * by #{multiplying_second_number} is #{multiplying_first_number * multiplying_second_number}"
else
end
if which_operation == "/"
puts "What is the first number to your divison question?"
dividing_first_number = gets.chomp.to_i
puts "What is the divisor?"
dividing_second_number = gets.chomp.to_i
puts "#{dividing_first_number} divided by #{dividing_second_number} is #{dividing_first_number / dividing_second_number}"
else
end
For example:
until (which_operation = gets.chomp).empty?
if which_operation == "+"
...
end
if which_operation == "-"
...
end
if which_operation == "*"
...
end
if which_operation == "/"
...
end
end
This loop will work until you press Enter without entering any text before it.
P.S.: Better use case operator instead of multiple if.
P.P.S.: All your code, after loop addition and without case operator, will be:
puts "Hello, My name is Calvin The Calculator and I am a calculator that can do basic functions such as Adding, Subtracting, Multiplying and Dividing"
puts "Press a and enter to enable my services"
until gets.chomp == "a"
puts "I'm Waiting..."
end
puts "Choose which operation you want to do. + for adding, - for subtraction, * for multiplication and / for division"
until (which_operation = gets.chomp).empty?
if which_operation == "+"
puts "What is the first number you want to add"
adding_first_number = gets.chomp.to_i
puts "What is the second number you want to add to #{adding_first_number}"
adding_second_number = gets.chomp.to_i
puts "#{adding_first_number} + #{adding_second_number} is #{adding_first_number + adding_second_number}"
elsif which_operation == "-"
puts "What is the first number you want to subtract"
subtracting_first_number = gets.chomp.to_i
puts "What is the number you want to subtract from #{subtracting_first_number}"
subtracting_second_number = gets.chomp.to_i
puts "#{subtracting_first_number} - #{subtracting_second_number} is #{subtracting_first_number - subtracting_second_number}"
elsif which_operation == "*"
puts "What is the first number you want to multiple"
multiplying_first_number = gets.chomp.to_i
puts "What is the number you want to multiple #{multiplying_first_number} by"
multiplying_second_number = gets.chomp.to_i
puts "#{multiplying_first_number} * by #{multiplying_second_number} is #{multiplying_first_number * multiplying_second_number}"
elsif which_operation == "/"
puts "What is the first number to your divison question?"
dividing_first_number = gets.chomp.to_i
puts "What is the divisor?"
dividing_second_number = gets.chomp.to_i
puts "#{dividing_first_number} divided by #{dividing_second_number} is #{dividing_first_number / dividing_second_number}"
end
puts "\nLet's try again: "
end
I am new to Ruby and working with this hangman style word guessing game. I have 2 main issues. Here is what I am working with now:
class Word_game
def initialize(word)
#word = word.downcase
#display_word = "_ " * word.length
end
def guess_the_word(word_guess)
word_guess.downcase
#word.split("").each_with_index do |word_letter, index|
if word_guess == word_letter
#display_word[index] = word_guess
p #display_word
puts "You're getting somewhere! Keep trying!"
end
end
if !#word.include? (word_guess)
puts "Nope, guess again..."
end
def win?
if #word == #display_word
puts "Congratulations you won!!! You are the word master!!!"
true
else
false
end
end
def lose?
if #attempts == 0
puts "You lose!!"
true
end
end
puts "Welcome to the Word Guessing Game! Let's see if YOU have what it TAKES!!!"
puts "This is a 2 player game. "
puts "Player 1... please enter a word for Player 2 to guess!"
puts ">>"
game_word = gets.chomp
game = Word_game.new(game_word)
attempts = 0
guessed_letters = []
until #attempts == game_word.length
puts "Ok Player 2, Guess a letter! GO!!!"
letter_guess = gets.chomp
if guessed_letters.include? letter_guess
puts "You already guessed that letter! Enter a new one."
letter_guess = gets.chomp
end
guessed_letters << letter_guess
game.guess_the_word(letter_guess)
if game.win?
attempts += 1
else game.lose?
end
end
end
First, the word progress should look like this if the word is hello:
h _ e _ _ o
Instead of this, the spaces are not in the right places and looks like this (an actual outcome of running my code):
.
Ok Player 2, Guess a letter! GO!!!
h
"h _ _ _ _ "
You're getting somewhere! Keep trying!
Ok Player 2, Guess a letter! GO!!!
o
"h _ o _ _ "
You're getting somewhere! Keep trying!
Ok Player 2, Guess a letter! GO!!!
e
"he_ o _ _ "
You're getting somewhere! Keep trying!
Ok Player 2, Guess a letter! GO!!!
l
"hel o _ _ "
You're getting somewhere! Keep trying!
"hello _ _ "
When the user guesses the word, it does not put my "congrats" statement and end the game.
I am also stuck on my 'lose' method. I am not sure how to fix the method so that the game ends when the user runs out of attempts and prints the "lose" statement.
Thanks for your help!
I think you're making the output too complicated. I would track the word and the guesses in an array. Instead of a display_word variable, I'd make it a method, possibly "to_s"
By the way, Ruby convention is to use CamelCase class names.
class WordGame
def initialize(word)
#word = word.downcase.chars
#guesses = ["_"] * #word.size
end
def to_s
#guesses.join " "
end
This should fix your spacing problem. This will also simplify guesses.
Also, the checking to see if you've already used the letter should probably be handled by the WordGame class.
For your first problem, your #display_word starts as follows:
[0] = '_' # For h
[1] = ' '
[2] = '_' # For e
[3] = ' '
...
When you guess 'e', for instance, you do:
#display_word[index] = word_guess
Where index equals 1, the second character in "hello", so as you can see it doesn't write to the 'e' index in #display_word.
For your second problem, there are a number of ways to fix it. For instance, I would do something like using #attempts_remaining starting from a value of 10 or so, then using the existing code:
if !#word.include? (word_guess)
#attempts_remaining -= 1 # Count failure to guess
puts "Nope, guess again..."
end
Then:
def win?
# If you've guessed all the letters, there's no '_' left in the display word
if !#display_word.include? ('_')
puts "Congratulations you won!!! You are the word master!!!"
true
else
false
end
end
def lose?
if #attempts_remaining == 0
puts "You lose!!"
true
end
end
Finally, tweak the until loop termination condition:
until game.win? or game.lose?
The existing calls to win? and lose? can be deleted.
(WORD MISSING GAME)
puts " "
puts "Total Round"
puts " "
puts "=> [Round-One ,Round-two,Round -three Round-four]"
puts " "
puts "=> [TOTAL 5 Tries]"
puts " "
one=""
two=""
three=""
four=""
puts " "
puts " --ROUND One press-- => (1)"
one=gets.to_i
puts '==================='
puts "Question:=> ( K ? N G )"
puts ""
c=5
5.times do
string1 = 'i'
stringone ="I"
puts "Answer:=> Try NO:#{c}"
string2 = gets.chomp
if (string1==string2)
puts "Good Work correct spaling"
break
elsif (stringone == string2 )
puts "Good Work correct spaling"
break
else
puts "-Worng spaling-"
end
c -=1
end
puts " Round Over "
if c<1
puts " Tries Over Game End "
exit
end
puts '==================='
puts "--ROUND Two press-- => (2)"
two=gets.to_i
puts '==================='
puts "Question:=> (P L ? Y )"
5.times do
string1 = 'a'
stringone = "A"
puts "Answer:=> Try NO:#{c}"
string2 = gets.chomp
if (string1==string2)
puts "Good Work correct spaling"
break
elsif (stringone==string2)
puts "Good Work correct spaling"
break
else
puts "-Worng spaling-"
end
c -=1
if c<1
puts " Tries Over Game End "
exit
end
end
puts " Round Over "
puts '==================='
puts "--ROUND Three press-- => (3)"
three=gets.to_i
puts '==================='
puts "Question:=> ( S P ? T )"
5.times do
string1 = 'o'
stringone= 'O'
puts "Answer:=> Try NO:#{c}*"
string2 = gets.chomp
if (string1==string2)
puts "_Good Work correct spaling_"
break
elsif (stringone == string2)
puts "_Good Work correct spaling_"
break
else
puts "-Worng spaling-"
end
c -=1
if c<1
puts " *Tries Over Game End* "
exit
end
end
puts " *Round Over* "
puts '==================='
puts "--ROUND Four press-- => (4)"
four=gets.to_i
puts '==================='
puts "Question:=> ( G ? M E )"
5.times do
string1 = 'a'
stringone = "A"
puts "Answer:=> Try NO:#{c}*"
string2 = gets.chomp
if (string1==string2)
puts "_Good Work correct spaling_"
break
elsif (stringone == string2)
puts "_Good Work correct spaling_"
break
else
puts "-Worng spaling-"
end
c -=1
if c<1
puts " *Tries Over Game End* "
exit
end
end
puts "**Yahoo Congragualtion complete All Round**"
Hey the code I created only repeats 2 times.
After I type the second time "y" for the "continue_question"-method the code only stops.
def greeting
puts "Hello! Please type your name: "
name = gets.chomp.capitalize
puts "It is nice to meet you #{name}. I am a simple calculator application."
puts "I can add, subtract, multiply, and divide."
end
greeting
def calculator
puts "First number: "
#n1 = gets.chomp.to_i
puts "Secons number: "
#n2 = gets.chomp.to_i
def calculation
puts "Type 1 to add, 2 to subtract, 3 to multiply, or 4 to divide two numbers: "
operation_selection = gets.chomp.to_i
if operation_selection == 1
#result = #n1 + #n2
elsif operation_selection == 2
#result = #n1 - #n2
elsif operation_selection == 3
#result = #n1 * #n2
elsif operation_selection == 4
#result = #n1 / #n2
else
puts "Something went wrong!"
calculation
end
end
calculation
puts "Your Result is #{#result}"
end
calculator
def continue_question
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator
elsif continue == "n"
puts "Bye!"
else
puts "What?"
continue_question
end
end
continue_question
Your code does not repeat 2 times, it repeats once.
The reason is because in your continue_question method, you do not tell it to repeat again:
def continue_question
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator # <-- This causes it it repeat ONCE!
elsif continue == "n"
puts "Bye!"
else
puts "What?"
continue_question
end
end
A quick fix is to re-call the continue_question method below that line, to recursively repeat itself:
def continue_question
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator
continue_question # <-- Add this to repeat indefinitely
elsif continue == "n"
puts "Bye!"
else
puts "What?"
continue_question
end
end
The problem is that continue_question only executes once, at the end of your code, but you need to loop until user exits (i.e types n).
So simply add a loop inside continue_question, for example:
def continue_question
continue = "y"
until continue == "n" do
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator
elsif continue == "n"
puts "Bye!"
else
puts "What?"
end
end
end
Hey the code I created only repeats 2 times.
I think you misunderstand the following:
if continue == "y"
calculator
elsif continue == "n"
puts "Bye!"
When you call the above function calculator, you are still executing the continue_question function. So when the calculator finishes executing, continue_question will finish as well and the program will stop. For the wanted result you can try using a loop.
I have to create a program where I have to ask the user for their first and last name on a single line. If the user puts only their first OR last name, it will be rejected through the exception. I keep getting an error at the end (below).
class MyNewException < Exception
attr_accessor :first, :last
def initialize (first, last)
#first = first
#last = last
end
end
print "Enter your first and last name:"
begin
first, last = gets.chomp.split
print "Hello," + first + " " + last + "!"
if last.size == 0
raise MyNewException, "Sorry, I didn't catch that! Try again:"
end
rescue MyNewException
puts "Sorry, I didn't catch that. Try again:"
retry
end
Keep getting an error:
testing.rb:15:in `+': no implicit conversion of nil into String (TypeError)
The raise() docs are faulty. You can do this:
puts "Enter your first and last name:"
name = gets.chomp
class MyNewException < Exception
def initialize(str)
super(str) #pass the value for the message property to the parent class
end
end
begin
raise MyNewException, "Sorry, I didn't quite catch that! Try again:"
rescue MyNewException => e
puts e.message
end
--output:--
Enter your first and last name:
Sarah Kim
Sorry, I didn't quite catch that! Try again:
Or:
puts "Enter your first and last name:"
name = gets.chomp
class MyNewException < Exception
attr_accessor :first, :last
def initialize(user_name, exception_message)
#first, #last = user_name.split
super exception_message
end
end
begin
raise MyNewException.new(name, "I didn't quite catch that! Try again:")
rescue MyNewException => e
puts e.message
puts e.first
puts e.last
end
--output:--
Enter your first and last name:
Sarah Kim
I didn't quite catch that! Try again:
Sarah
Kim
Here's how to write an infinite loop to get user input:
class Person
attr_accessor :first, :last
def initialize(first, last)
#first = first.capitalize
#last = last.capitalize
end
end
while true
puts "Enter your first and last name:"
first, last = gets.chomp.split
#Show what you got:
p first
p last
if first and last
#If no names were entered, both first and last will be nil.
#If one name was entered, first will evaluate to true and last will be nil.
#If two names were entered, first and last will evaluate to true.
#If two or more names were entered, first and last will evaluate to true.
user = Person.new first, last
break #jump to the line immediately after the infinite loop
end
puts "Sorry, you must enter both a first and a last name. Try again"
end
puts "Thanks #{user.first} #{user.last}!"
Create a loop that do your trial and error.
as for my answer I choose while loop
i = 0
while i < 1 do
if condition == true
# display your greetings then increment loop to end
i += 1
else
# display error message
end
end
So your code would be like this
class MyNewException < Exception
attr_accessor :first, :last, :valid
def initialize(first, last)
#first = first
#last = last
#valid = true
if first.empty? || last.empty? then
#valid = false
end
end
end
i = 0
while i < 1 do
print "Enter your first name: "
firstname = gets.chomp
print "Enter your last name: "
lastname = gets.chomp
name = MyNewException.new(firstname, lastname)
if name.valid then
puts "Greetings " << name.first << " " << name.last
i += 1
else
puts "I didn't quite catch that! Try again:"
end
end
I have the following code:
def say(msg)
puts "=> #{msg}"
end
def do_math(num1, num2, operation)
case operation
when '+'
num1.to_i + num2.to_i
when '-'
num1.to_i - num2.to_i
when '*'
num1.to_i * num2.to_i
when '/'
num1.to_f / num2.to_f
end
end
say "Welcome to my calculator!"
run_calculator = 'yes'
while run_calculator == 'yes'
say "What's the first number?"
num1 = gets.chomp
say "What's the second number?"
num2 = gets.chomp
say "What would you like to do?"
say "Enter '+' for Addition, '-' for Subtraction, '*' for Multiplication, or '/' for Division"
operation = gets.chomp
if num2.to_f == 0 && operation == '/'
say "You cannot devide by 0, please enter another value!"
num2 = gets.chomp
else
result = do_math(num1, num2, operation)
end
say "#{num1} #{operation} #{num2} = #{result}"
say "Would you like to do another calculation? Yes / No?"
run_calculator = gets.chomp
if run_calculator.downcase == 'no'
say "Thanks for using my calculator!"
elsif run_calculator.downcase == 'yes'
run_calculator = 'yes'
else
until run_calculator.downcase == 'yes' || run_calculator.downcase == 'no'
say "Please enter yes or no!"
run_calculator = gets.chomp
end
end
end
I need it to take the num1 and num2 variables that the user inputs and validate that they are numbers and return a message if they aren't.
I would like to use a Regex, but I don't know if I should create a method for this or just wrap it in a loop.
The Integer method will raise an exception when the given string is not a valid number, whereas to_i will fail silently (which I think is not desired behavior):
begin
num = Integer gets.chomp
rescue ArgumentError
say "Invalid number!"
end
If you want a regex solution, this will also work (although I recommend the method above):
num = gets.chomp
unless num =~ /^\d+$/
say "Invalid number!"
end
You would often see each section written something like this:
ERR_MSG = "You must enter a non-negative integer"
def enter_non_negative_integer(instruction, error_msg)
loop do
puts instruction
str = gets.strip
return str.to_i if str =~ /^\d+$/
puts error_msg
end
end
x1 = enter_non_negative_integer("What's the first number?", ERR_MSG)
x2 = enter_non_negative_integer("What's the second number?", ERR_MSG)
Here's possible dialog:
What's the first number?
: cat
You must enter a non-negative integer
What's the first number?
: 4cat
You must enter a non-negative integer
What's the first number?
: 22
#=> 22
What's the second number?
: 51
#=> 51
x1 #=> 22
x2 #=> 51