Ruby - Unexpected keyword_when, expecting keyword_end - ruby

I get this message twice when inputting two blocks in a case statement. Having trouble locating the problem.
choice = gets.chomp.downcase!
case = choice
when "update"
puts "Enter the title of the movie to be updated."
title = gets.chomp.to_sym
if movies[title] == nil
puts "This movie is not in the system."
else
puts "Input the new rating."
rating = gets.chomp.to_i
movies[title] = rating
retry if (rating < 0 || rating > 5)
puts "This rating is invalid! Try again."
end
end
when "display"
movies.each do |title, rating|
puts "#{title}: #{rating} / 5 stars"
end
end
The code block extends further down to further instances of "when" but I decided to truncate it for simplicity's sake. I can submit the full code if necessary. The errors are specifically as follows:
(ruby):57: syntax error, unexpected keyword_when, expecting keyword_end
when "update"
^
(ruby):72: syntax error, unexpected keyword_when, expecting $end
when "display"
^

The error you are seeing is because your syntax is wrong. Be very careful when indenting your code, it will make it easier to find these kind of bugs:
choice = gets.chomp.downcase!
case choice
when "update"
puts "Enter the title of the movie to be updated."
title = gets.chomp.to_sym
if movies[title] == nil
puts "This movie is not in the system."
else
puts "Input the new rating."
rating = gets.chomp.to_i
movies[title] = rating
# retry if (rating < 0 || rating > 5)
puts "This rating is invalid! Try again."
end
when "display"
movies.each do |title, rating|
puts "#{title}: #{rating} / 5 stars"
end
end
There was an extra end before when "display". I guess it was meant to close the if (rating < 0 || rating > 5), but since it was preceded by a statement, making it a one line if statement.
Even when it is fixed, the retry is misused. As it is not apparent what exactly you were trying to do, I commented it out - I suggest you read to relevant documentation regrading the proper retry syntax, and re-write your code accordingly.

I guess this line case = choice should be just case choice
choice = gets.chomp.downcase!
case choice
when "update"
puts "Enter the title of the movie to be updated."
title = gets.chomp.to_sym
if movies[title] == nil
puts "This movie is not in the system."
else
puts "Input the new rating."
rating = gets.chomp.to_i
movies[title] = rating
if (rating < 0 || rating > 5)
puts "This rating is invalid! Try again."
end
when "display"
movies.each do |title, rating|
puts "#{title}: #{rating} / 5 stars"
end
end

Related

Handling Ruby Case Statement

I tried to rewrite the "if/else statement" in the following piece of code by replacing it with a "case" statement, and I am deadly stuck with it for a few hours - what am I missing?
puts "Welcome to 'Guess My Number!'"
print "What is your name?"
input = gets
name = input.chomp
puts "Welcome, #{name.upcase!}!"
puts "I've got a random number between 1 and 100!"
puts "Can you guess it?"
target = rand(100) + 1
num_guesses = 0
guessed_it = false
until num_guesses == 10 || guessed_it
remaining_guesses = 10 - num_guesses
puts "You've got #{remaining_guesses.to_s} guesses left!"
print "Make a guess, put down a number: "
guess = gets.chomp.to_i
num_guesses = num_guesses + 1
end
puts case verification
when guess < target
then "Ooops. Your guess was LOW."
when guess > target
then "Ooops. Your guess was HIGH."
when guess < -1
then puts "Oooops. You have entered a number lower that 1!"
when guess > 100
then puts "Oooops. You have entered a number higher than 100!"
when guess =~ /^([w])/
then puts "Ooops. Looks like you have entered a non numeric
value!"
when guess == String
then puts "Oooops! Looks like you have entered a non numeric
value"
when guess == target
then puts "Good job, #{name}!"
puts "You guessed my number in #{num_guesses} guesses!"
guessed_it = true
end
unless guessed_it
puts "Sorry, you didn't get my number. My number was #{target}."
end
The "case statement" was used to replace and enhance the logic of the following if else statement:
if guess < target
puts "Ooops. Your guess was LOW."
elsif guess > target
puts "Ooops. Your guess was HIGH."
elsif guess == target
puts "Good job, #{name}!"
puts "You guessed my number in #{num_guesses} guesses!"
guessed_it = true
end
Your problem is that you're using the form of case with the optional condition, but you're using when clauses as if you were using the condition-less case.
puts case
when guess < target
"Ooops. Your guess was LOW."
should work.
Further explanation:
using case without a condition, the earliest when branch with a truthy expression is executed. This is what you want here.
But you were using case with verification. In this case, all branches are compared to verification, and the first branch where verification === branch condition is true is executed.
Since in your example I'm guessing verification is always nil, and all your branches' conditions are always true or false, no branch will ever get executed.
You can use a case statement like so:
class String
def green;"\e[32m#{self}\e[0m";end
def yellow;"\e[33m#{self}\e[0m";end
def cyan;"\e[36m#{self}\e[0m";end
def bg_blue;"\e[44m#{self}\e[0m";end
def bold;"\e[1m#{self}\e[22m";end
def underline;"\e[4m#{self}\e[24m";end
def border(num);"\n#{'-' * num}\n#{self}\n#{'-' * num}\n";end
end
puts;puts "Welcome to 'Guess My Number!'".bold.bg_blue;puts
print 'What is your name? '.green
name = gets.chomp
puts "\nWelcome, #{name.upcase!}!\n".cyan.underline
puts "I've got a random number between 1 and 100!\nCan you guess it?".border(44)
target = rand(100) + 1
num_guesses = 0
guessed_it = false
until num_guesses == 10 || guessed_it
remaining_guesses = 10 - num_guesses
puts "\nYou've got #{remaining_guesses} guesses left!\n"
puts;print 'Make a guess, put down a number: '
guess = gets.chomp
case guess.to_i
when (1...target)
puts 'Ooops. Your guess was LOW'.yellow.border(26)
when (target + 1..100)
puts 'Ooops. Your guess was HIGH'.yellow.border(26)
when target
puts; puts; puts
puts "Good job, #{name}!".bold.green
puts 'You guessed my number in ' + "#{num_guesses} guesses!".cyan
puts; puts; puts
guessed_it = true
else
puts "Oooops. You didn't enter a number from 1 to 100".yellow.border(47); puts
end
num_guesses += 1
end
unless guessed_it
puts;puts;puts "Sorry, you didn't get my number. My number was #{target}.".yellow;puts
end
Thanks a lot to everybody! With your invaluable help I managed to regain patience in my soul and satisfaction from this small task :) My mistake is that I violated the rules of common sense by trying to run several pieces of code in a wrong sequence. I moved the case statement inside the until loop and now all I have to do is correct the mistakes in particular when/then statements. It works :)
until num_guesses == 10 || guessed_it
remaining_guesses = 10 - num_guesses
puts "You've got #{remaining_guesses.to_s} guesses left!"
print "Make a guess, put down a number: "
guess = gets.chomp.to_i
num_guesses = num_guesses + 1
puts case
when guess < target
then "Ooops. Your guess was LOW."
when guess > target
then "Ooops. Your guess was HIGH."
when guess < -1
then puts "Oooops. You have entered a number lower that 1!"
when guess > 100
then puts "Oooops. You have entered a number higher than 100!"
when guess =~ /^([w])/
then puts "Ooops. Looks like you have entered a non numeric value!"
when guess == String
then puts "Oooops! Looks like you have entered a non numeric value"
when guess == target
then puts "Good job, #{name}!"
puts "You guessed my number in #{num_guesses} guesses!"
guessed_it = true
end
end
unless guessed_it
puts "Sorry, you didn't get my number. My number was #{target}."
end

Head First Ruby - #{10 — num_guesses} error

Here is book code. And he is not work...
# Get My Number Game
# Written by: you!
puts "Welcome to 'Get My Number!'"
# Получение имени игрока и вывод приветствия.
print "What's your name? "
input = gets
name = input.chomp
puts "Welcome, #{name}!"
# Сохранение случайного числа.
puts "I've got a random number between 1 and 100."
puts "Can you guess it?"
target = rand(100) + 1
# Отслеживание количества попыток.
num_guesses = 0
# Признак продолжения игры.
guessed_it = false
until num_guesses == 10 || guessed_it
puts "You've got #{10 — num_guesses} guesses left."
print "Make a guess: "
guess = gets.to_i
num_guesses += 1
# Сравнение введенного числа с загаданным
# и вывод соответствующего сообщения.
if guess < target
puts "Oops. Your guess was LOW."
elsif guess > target
puts "Oops. Your guess was HIGH."
elsif guess == target
puts "Good job, #{name}!"
puts "You guessed my number in #{num_guesses} guesses!"
guessed_it = true
end
end
# Если попыток не осталось, сообщить загаданное число.
unless guessed_it
puts "Sorry. You didn't get my number. (It was #{target}.)"
end
The error:
test.rb:18: syntax error, unexpected tIDENTIFIER, expecting t│ => String
STRING_DEND │2.4.0 :016 > name * 3
puts "You've got #{10 — num_guesses} guesses left."
I'm not sure what that character is between the 10 and the num_guesses but it's probably a hyphen.
#{10 — num_guesses}
it's not a minus sign, which would look like this...
#{10 - num_guesses}
What sort of editor did you use to enter your code?
Anyway, change the hyphen to a minus sign and that will fix your problem.

how to save changes made in my .rb program in the terminal?

I'm really new to this but I’ve written a small program that will CRUD a movie to a list the only problem is it is not saving the changes made. how can I make this happen?
error = "movie not found"
movies = {
Mazerunner: 1
}
error = "movie not found"
puts "welcome to CrudMovies"
puts "enter a command"
puts "type add to add a movie to the list"
choice = gets.chomp.downcase
case choice
when "add"
puts "what movie would you like to add"
title = gets.chomp
if movies[title.to_sym].nil?
puts "what would you like the rating of #{rating} (1-4)to be?"
rating = gets.chomp
movies[title.to_sym] = rating.to_i
puts "#{title} was added with a rating of #{rating}"
else
puts "that movie already exists"
end
when "update"
puts "what movie would you like to update? (case sensitive)"
title = gets.chomp
if movies[title.to_sym].nil?
puts "#{error}"
else
puts "what is the movie rating would you like to update?"
movies[title.to symb] = rating.to_i
puts "#{title}'s rating has been updated to #{rating}"
end
when "display"
movies.each do |x, y|
puts "#{x} Rating:#{y}"
end
when "destroy"
puts "what movie would you like to erase?"
title = gets.chomp
if movies[title.to_sym].nil?
puts "#{error}"
else
movies.delete(title.to_sym)
puts "the movie no longer exists"
end
else
puts "command not recognized"
end
I'm going to assume that by "Save" you mean stored in the movies hash. The answer to that is that is it is in fact being stored. Only your script exits after you perform an operation, so you never get to see the updated movies.
To see the desired result you're going to want to wrap the majority of this in an infinite loop to prevent the script from naturally exiting.
Consider the following as an example:
store = []
while true
puts "Enter something:"
choice = gets.chomp
store.push choice
puts "Your choices so far are: #{store.inspect}"
end

Program won't output what it's supposed to

I am following tutorial and I can't figure out what I am doing wrong. It's outputting everything up to if down
puts "we are going down the cave" I can't get it to output the else statement or anything afterwards. I am just learning and the answer is probably really simple.
puts("Would you like to go up or down?")
user_input = gets()
down = "cave"
up = "mountain"
if down
puts "we are going down the cave"
else up
puts "we are going up the mountain"
puts("Pick a number between 1 and 100")
LOCATION = "cave"
NUMBER = gets()
if NUMBER == 100
puts "You've achieved enlightment in the #{LOCATION}! Spread joy around the world!"
elsif NUMBER >= 50 > 100
puts "There are #{NUMBER} goblins in the #{LOCATION}. WE MUST FIGHT!"
elsif NUMBER > 20 > 50
puts "There is still hope that we will make it to the #{LOCATION}. before the #{NUMBER} Snufflebums get us!"
else NUMBER <= 20
puts "We have conquered the Goon Squad of the #{LOCATION}.. It only took us #{NUMBER} years!!!"
end
end
down is "cave" and is always 'truthy' so if down is always, always true. You want to be testing the user_input, not the variable down
What I think you want is...
user_input = gets.chomp
# you need the chomp to remove the return character
down = "cave"
up = "mountain"
if user_input == down
puts "we are going down the cave"
elsif user_input == up
puts "we are going up the mountain"
end
# you need the end statement, otherwise everything that follows is part of the "else"
And remove the last end

Code never enter any of the if statements

begin
selected_option = gets.chomp
if selected_option == 1
puts "Welcome to the Welcome Screen!"
elsif selected_option == 2
puts "This is the options menu."
elsif selected_option == 3
puts "Logging out. Goodbye!"
else
puts "Please select a valid option."
end
end while not selected_option == 3
I enter in 1 or 2 or 3 and I always get the "Please enter a valid option" message. I'm guessing that's because the chomp method retrieves the input as a string.
Any way around this sans using quotes around the options?
gets.chomp.to_i
Will convert it to an integer.
You may also want to use a switch instead:
begin
selected_option = gets.chomp.to_i
case selected_option
when 1
puts "Welcome to the Welcome Screen!"
when 2
puts "This is the options menu."
when 3
puts "Logging out. Goodbye!"
else
puts "Please select a valid option."
end
end while not selected_option == 3

Resources