Codecademy - a night at movies 4/10: Prompting: Redux - ruby

I can't find the error, it keeps telling me: Oops, try again. It looks like you didn't add to the movies hash!
Thank you.
movies = { 'himym' => 5,
'oitnb' => 4 }
puts "Which one do you like better?"
choice = gets.chomp
case choice
when "add"
puts "What is your favorite movie?"
title = gets.chomp
puts "What would you rate it?"
rating = gets.chomp
movies = {}
movies[title] = rating
puts "#{title} with rating #{rating} has been added!"
when "update"
puts "Updated!"
when "display"
puts "Movies!"
when "delete"
puts "Deleted!"
else
puts "Error!"
end

I tested your code - I got stuck in the same part. Instructions at CodeAcademy are not always clear. Your code, according to what CA is asking is right, you just need to write "add" as an answer for "Which one do you like better?" when testing code at CA's virtual machine. So:
choice = "add"
That way you will be running your case/when filter. Got it?

Related

I'm currently learning Ruby from Codecademy and I'm not sure if this works, according to the website it's right but I don't see how?

so the assignment is I'm making a case statement and adding movies paired with their rating in a hash. The "add" case is supposed to add a prompted movie with its paired rating to a hash. It's also supposed to check if the movie already exists in the hash and prompts the user if it does. There's an "update" case which allows the user to update a movie within the hash and also checks if the user inputs a movie that isn't in the hash. Now the update case works fine, it lets the user know if the movies doesn't exist however, I don't think the else part of the add case is working properly? I can add "Wall-E" with a rating of 10 and it doesn't prompt me saying it's already there.
movies = {
"Wall-E" => 10
}
puts "Please choose to add, update, display or delete movies"
choice = gets.chomp
case choice
when "add"
puts "Please name a movie you wish to add"
title = gets.chomp
puts "Please give a rating for this movie"
rating = gets.chomp
if movies[title.to_sym].nil? == true
movies[title.to_sym] = rating.to_i
puts "#{title} was added with a rating of #{rating}"
else
puts "The movie you entered has already been added"
end
when "update"
puts "Please name a movie you wish to update"
title = gets.chomp
if movies[title].nil? == true
puts "Hey bud, that one doesn't exist but you can add it if you want"
else
puts "Please give a rating for this movie"
rating = gets.chomp
movies[title.to_sym] = rating.to_i
end

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

Not able to iterate properly over hash in my continuous input program (Ruby)

I am trying to see if I can create a list of user input requests with a hash in this program I am trying to create. Whats the best way to go about this?
print "would you like to begin a changeover? (y/n) "
input = gets.chomp
tracking = {
"start time" => input.Time.now,
"Type?" => input,
"shift?" => input,
"standard hrs?" => input,
"actual hrs?" => input,
"end time" => input = gets.chomp.Time.now
}
tracking.each do |key, value|
puts "great please answer the following: #{tracking}"
end
thanks in advance!
You have to remember that the evaluation is sequential, going from top to bottom (unless you are defining functions/methods). In your code:
You ask the user about a changeover
You get user input (say, y) into the variable input
You make a hash, with six values; four of them will contain y, two of them will contain current time
You iterate over the hash, printing its values (and asking the user nothing).
Or at least it would if gets.chomp.Time.now was not an error.
So, taking care about the timing:
print "would you like to begin a changeover? (y/n) "
unless gets.chomp.tolower == 'n'
puts "great please answer the following:"
tracking = {
"start time" => Time.now
}
[
"Type?",
"shift?",
"standard hrs?",
"actual hrs?"
].each do |question|
print question
tracking[question] = gets.chomp
}
tracking["end_time"] = Time.now
end
Thanks Alot! This set me on the right track. However, was not time stamping the beginning and end of the questionnaire the way I wanted. After playing with the code a bit on my own however, I was able to make it work.
print "would you like to begin a changeover? (y/n) "
unless gets.chomp. == "n"
puts Time.now
puts "great please answer the following: "
end
questionnaire = ["Type", "Shift?", "Standard hrs?", "Actual hrs?"]
.each do |question|
puts question
questionnaire = gets.chomp
end
puts "Please type 'done' when change over complete"
input = gets.chomp
puts Time.now

Hashes and case statements

I have to update and add a movie title and its associated rating to an existing hash. This is the code that i have so far:
movies = {
Titanic:4,
Bestman: 3,
Agora: 2
}
puts "What would you like to do?"
choice = gets.chomp
case movies
when "add"
puts "What movie do you want to add?"
title = gets.chomp
puts "What's the rating of the movie?"
rating = gets.chomp
movies[title] = rating
puts "#{title} has been added with a rating of #{rating}."
when "update"
puts "Updated!"
when "display"
puts "Movies!"
when "delete"
puts "Deleted!"
else
puts "Error!"
end
When I run the code, I get this error "it looks like you didn't add to the movies hash"
I know the error lies somewhere between these lines:
case movies
when "add"
puts "What movie do you want to add?"
title = gets.chomp
puts "What's the rating of the movie?"
rating = gets.chomp
movies[title] = rating
puts "#{title} has been added with a rating of #{rating}."
I have been trying to figure it out but thus far have failed to figure out what I am doing wrong.
Is there an alternative way to add to my movies hash? And what is wrong with my puts code for letting the user know that his/her movie title and rating has been added?
Thank you
EDIT
As pointed out by Some Guy, changing the case statement from
case movies
to
case choice
resolved the issue.
What I need to learn/figure out is why the 2nd works but the 1st does not.
Change
case movies
to
case choice # because this is where your choice of what to do is being stored
If it's still not clear, it may help to think of a case statement as a series of if/elsif (there are differences, but for this scenario it works), so:
case movies
when "add" # do stuff
is akin to:
if movies == "add"
# do stuff
end
Hoping that makes it clearer.

Unexpected boolean result using .nil? on a hash

I am working through exercises on codecademy and I came across a solution that I do not completely understand involving .nil? Here is my code :
movies = { GIS: 10.0, Phantasm: 1.5, Bourne: 4.0}
puts "Whats your movie brah?"
title = gets.chomp
puts "What's your rating brah?"
rating = gets.chomp
movies[title.to_sym] = rating.to_i
puts "Your info was saved brah!"
case movies
when 'add'
puts "What movie do you want to add son?"
title = gets.chomp
if movies[title.to_sym].nil?
puts "What's your new rating brah?"
rating = gets.chomp
movies[title.to_sym] = rating.to_i
puts "#{title} has been added with a rating of #{rating}."
else
puts "That movie already exists! Its rating is #{movies[title.to_sym]}."
end
when "update"
if movies[title.to_sym].nil?
when "display"
puts "Movies!"
when "delete"
puts "Deleted!"
else puts "Error!"
end
I am only referring to the add method. the rest of the script is a work in progress. I don't like not understanding things though and this has me in a bit of a quandry.
My question is does Ruby know not to add a title that already exists because two symbols cannot have the same name? I am curious how it determines when the hash has no value. Can anyone clarify this for me? I would really appreciate it!
The answer is a bit more complicated than that.
From the RubyDoc: "Two objects refer to the same hash key when their hash value is identical and the two objects are eql? to each other."
An object's hash value is a calculated numerical result based on the data the object contains. And the eql? method tests if two objects are equal, and this is usually aliased to == in ruby (i.e my_string1 == my_string2 is the same as my_string1.eql? my_string2).
When you say movies[title.to_sym], Ruby is saying "In the movies hash, are there any pairs currently stored where the key.eql? title.to_sym and key.hash == title.to_sym.hash? If so, return that value of the pairing, and if not return nil.
The reason Ruby doesn't add the title if it already exists is because of your if movies[title.to_sym].nil? line, which in English translates to "only do what follows if no pairing for the key title.to_sym exists."
If you had title = "GIS", and you were to just say movies[title.to_sym] = 1, Ruby would gladly over write the 10.0 you currently have stored there so that movies[:GIS] returned 1.

Resources