
# Dictionaries are associative arrays:
#
#   associates a value with a key
#

# Define an empty dictionary

empty_dict = {} 		# Pythonic
empty_dict2 = dict() 		# less Pythonic

# Initialize a (non-empty) dictionary):

grades = { "Joel" : 80, "Tim" : 95 } 		# dictionary literal
#          ^^^^^   ^^^
#          key    value

# You can look up the value for a key using square brackets:

joels_grade = grades["Joel"] 			# equals 80

# You’ll get a KeyError if you ask for a key that’s not in the dictionary:

try:
    kates_grade = grades["Kate"]
except KeyError:
    print("no grade for Kate!")

# Dictionaries have a get method that returns a default value 
# (instead of raising an exception) when you look up a key that’s 
# not in the dictionary:

joels_grade = grades.get("Joel", 0) 		# equals 80
kates_grade = grades.get("Kate", 0) 		# equals 0
no_ones_grade = grades.get("No One") 		# default default is None

# You assign key-value pairs using the same square brackets:

grades["Tim"] = 99 			# Replaces the old value
grades["Kate"] = 100 			# ** Adds a third entry *** !!!
num_students = len(grades) 		# Now equals 3




# #####################################################################
# We will frequently use dictionaries as a simple way to represent 
# structured data:
# #####################################################################
tweet = {
    "user" : "joelgrus",
    "text" : "Data Science is Awesome",
    "retweet_count" : 100,
    "hashtags" : ["#data", "#science", "#datascience", "#awesome", "#yolo"]
}

# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Besides looking for specific keys we can look at all of them:
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%o

tweet_keys = tweet.keys() 		# list of keys
tweet_values = tweet.values() 		# list of values
tweet_items = tweet.items() 		# list of (key, value) tuples

print("\n", tweet_keys)			# It's list of strings
print("\n", tweet_values)		# It's list of "things" stored
print("\n", tweet_items)		# It's list of tuples 

# #########################################################
# Test for keys
# #########################################################

"user" in tweet.keys()			# True, but uses a slow list in-test
"user" in tweet				# more Pythonic, use faster dict in-test

print("\ntweet:\n", tweet)
if 'user' in tweet:
    print(tweet['user'])
else:
    print("No user field in tweet")


# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Important fact:
#
#    Dictionary keys must be immutable; in particular, 
#
#           you cannot use lists as keys !!!
#
# If you need a multipart key, you should use a tuple or 
# find a way to turn the key into a string
#
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


