6.) Error! Error! The title isn't added, and I can't figure out why


#1

https://www.codecademy.com/en/courses/ruby-beginner-en-0i8v1/0/6?curriculum_id=5059f8619189a5000201fbcb#

Error: Oops, try again. It looks like The Lion King wasn't added to the movies hash with a rating of .

It's really rather strange...I don't know why I keep on failing this exercise. Is there a syntax error?

The step that I did when I run the program is:
1.) Choose add
2.) Enter, The Lion King as the added movie title.

And then it just fails. If I decided to go for the error route, where I didn't fill add to test the program, the exercise for some reason passes. :expressionless:

Can anybody please help? @mtf I see you quite frequently, and I hope you can help me with this. Thanks!

movies = Hash.new("No movies here")

movies[:The_Princess_Bride] = 9
movies[:Armageddon] = 8
movies[:The_Dark_Knight] = 8.7

puts "What do you want to do?"
puts "Please type one of the following according to your choice"
puts "add - Add a movie"
puts "update - Update a movie in the database"
puts "display - Display a movie of your choice"
puts "delete - Delete a movie in the database"

choice = gets.chomp.downcase

case choice
when "add"
    puts "What title do you want to give?"
    title = gets.chomp
    if movies[title.to_sym].nil?
        puts "What rating do you want to give the movie?"
        rating = gets.chomp
        movies[title.to_sym] = rating.to_i
        puts "The movie #{title} and its rating #{rating} is added to your hash!"
    else
        puts "The movie #{title} is already in the database with the rating of #{rating}" 
    end
    #DEBUG
    #print movies
when "update"
    puts "Updated!"
when "display"
    puts "Movies!"
when "delete"
    puts "Deleted"
else
    puts "Error!"
end

#2

We cannot use hash syntax outside of a hash.

movies["The Princess Bride"] = 4

Focus on this for a moment. What does it imply?

Answer: That we do not need to fabricate identifiers for hash names. We use what we are given, that way it can be searched for. That undersocores may be parsed as spaces is another layer of abstraction this is early, at this point. We do not need to fabricate identifiers. That's the main point. Use the data that is given, and wrap it in quotes.

It is still not a symbol, though, but it is a valid key name.

 > movies["The Princess Bride"] = 4
=> 4
 > movies[0].is_a?(Symbol)
=> false

We could convert it before we cache it.

 > s = "The Princess Bride"
 > movies[s.to_sym] = 4

Cosider the following:

 > movies["The Princess Bride"] = 4
=> 4
 > s = "The Princess Bride"
=> "The Princess Bride"
 > movies[s.to_sym] = 4
=> 4
 > movies
=> {:"The Princess Bride"=>4, "The Princess Bride"=>4}
 > movies["The Princess Bride"] = 3
=> 3
 > movies
=> {:"The Princess Bride"=>4, "The Princess Bride"=>3}

#3

Hmmm...so instead of putting a symbol straight into the hash as the key, we put a string instead? But wasn't it better for the memory if we put symbols as the key for the hash from the beginning?

movies = {
  Memento: 3,
  Primer: 4,
  Ishtar: 1
}

The example at the first exercise of this part of the lesson also showed that the hash is made with symbols. But I went and use the index operators instead of literals. Or was it not supposed to be that way if I used index operators?


#4

It is better if we put only one or the other in the hash, since it supports both indepently, as we have seen.

Where I get confused with this is the obfuscation of the the proper name to create a symbol. I'm not of that school of thought. I'd rather work with the proper names, no obfuscation. People will search for "Star Wars" not "star_wars".


#5

I saw your explanation in your edits, but I am still rather confused. Maybe it's because I am confusing between symbols and strings as keys, as well as problems I'm still having with familiarizing myself with the Hash syntax when I use operators or literals.

So I just tried to dumb things down a little bit more so I can really understand where am I going wrong.

But here is where it gets weird...

=begin
#Here is the Index Operators..refer as ..1)

movies = Hash.new("No movies here")

movies["The Princess Bride"] = 9
movies["Armageddon"] = 8
movies["The Dark Knight"] = 8.7
=end

=begin
#Here is the literal hash notation refer as ..2)

movies = {
    "The Princess Bride"=> 9,
    "Armageddon"=> 8,
    "The Dark Knight"=> 8.7
    }
=end

I print the movies hash using

puts movies

and both notations print out in the console

{"The Princess Bride"=>9, "Armageddon"=>8, "The Dark Knight"=>8.7}

Which is what is expected, because both are technically the same hash anyway. (notice there's no more underscores) All the keys are all in strings, and values are all integers, so everything is as simple as it should be. There's no symbols whatsoever.

But then I use this command below

puts "What title do you want to give?"
    title = gets.chomp
    if movies[title].nil? #here it checks the string, whether it's already available in the hash.
        puts "What rating do you want to give the movie?"
        rating = gets.chomp
        movies[title.to_sym] = rating.to_i
        puts "The movie #{title} as a symbol and its rating #{rating} is added to your hash!"
    else
        puts "The movie #{title} is already in the database with the rating of #{rating}" 
    end
    #DEBUG
    print movies

And this is where it REALLY stumps me, because it doesn't make any sense to me...

If I were to use the ...1) index operator, The Lion King will not be taken (the same error "Oops, try again. It looks like The Lion King wasn't added to the movies hash with a rating of ." from my first post pops up) and the rating will also not be prompted, and the code ends with

{"The Princess Bride"=>9, "Armageddon"=>8, "The Dark Knight"=>8.7}

If I were to use the ...2) literal notations however, The Lion King and the subsequent rating of 12, will be taken and the entire exercise is successful. The code ends with

{"The Princess Bride"=>9, "Armageddon"=>8, "The Dark Knight"=>8.7, :"The Lion King"=>12}

I notice there that the "The Lion King" becomes a symbol, which is according to what I had asked, so no problem there.

So, any idea on how to explain this?


#6

You used strings both times, there are no symbols as keys in your hashes because you used strings.
It's just a matter of deciding which one you are supposed/want to use and use that.


#7

One of your hashes has a default value, look at how your already-exists condition handles that.

Nothing to do with symbols, you just test something that is similar but not the same to what you should test.


#8

:sweat:

WELL D'OH!!! Oh dear God, how did I not see that???? Now it all makes sense why the program just doesn't work the way it's supposed to be for the exercise! Thanks @mtf, @ionatan !


#9

That may be rhetorical but just the same it's the most important question here.
You didn't observe what it did to reach the result it got. How could you have done that?


#10

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.