# ----------------------------------------------
# Examples: Working with Dictionaries
# ----------------------------------------------

# A dictionary in Python is a collection of key-value pairs.
# Keys and values are separated by a colon ':', and key-value pairs are separated by commas.

# Creating an empty dictionary
my_dict = {}

# Initializing a dictionary with key-value pairs
# Note: You don't need to create an empty dictionary first.
my_dict = {
    'a': 1,
    'b': 17,
    'c': -1,
    'd': 4
}
print(my_dict)
print(my_dict['a'])
# print(my_dict['e'])  # Uncomment to see: KeyError: 'e'

# Safely get the value for key 'c', returns None if key is not found
print(my_dict.get('c'))

# Writing to a dictionary
my_dict['e'] = 5
print(my_dict)  # Dictionary updated with a new key-value pair

# Extending a dictionary with another dictionary
more_data = {'t': [0, 2, 4], 'k': "cheese"}
my_dict.update(more_data)  # Updates/extends `my_dict` with `more_data`
print(my_dict)

# Clearing all entries in the dictionary
my_dict.clear()
print(my_dict)  # Dictionary is now empty

# Creating a dictionary using `dict()` from a list of tuples
students_list = [('Victoria', 286734), ('Jeremy', 234809), ('Katie', 256789)]
students = dict(students_list)

print(students)
print(list(students.keys()))     # List of all keys
print(list(students.values()))   # List of all values
print(list(students.items()))    # List of key-value pairs as tuples

# Looping through keys and values using the `items()` function
for name, sciper in students.items():
    print(f"Sciper number of {name} is {sciper}")

# Removing an entry with `pop()` (returns the value of the removed key)
# print(students.pop("Lena"))  # Uncomment to see: KeyError: 'Lena'
print(students.pop("Victoria"))
print(students)

# Removing and returning the last inserted key-value pair using `popitem()`
print(students.popitem())
print(students)

# Resetting the dictionary for further examples
students = dict(students_list)
# Current state: {'Victoria': 286734, 'Jeremy': 234809, 'Katie': 256789}

# Deleting a key-value pair with `del`
del students['Katie']
print(students)

# Clearing all entries in the dictionary
my_dict.clear()
print(my_dict)  # Dictionary is now empty

# ----------------------------------------------
# Using `fromkeys()` to create a new dictionary
# ----------------------------------------------

new_dict = dict.fromkeys(range(4), [])
print("New dictionary with empty lists as values:")
print(new_dict)

# ----------------------------------------------------------
# Given an input list of words, group words by their length.
# ----------------------------------------------------------

# Input list of words
words = ["cat", "dog", "elephant", "mouse", "rat", "lion"]

# Initialize an empty dictionary
length_groups = {}

# Group words by their length
for word in words:
    length = len(word)
    if length not in length_groups:
        length_groups[length] = []
    length_groups[length].append(word)

# Print the grouped words
print("Words grouped by length:", length_groups)

# ----------------------------------------------------------
# Count how many times each word appears in a given string.
# ----------------------------------------------------------

# Input string
text = "apple banana apple orange banana apple"

# Initialize an empty dictionary
word_count = {}

# Process the string
for word in text.split():
    if word in word_count:
        word_count[word] += 1
    else:
        word_count[word] = 1

# Print the word frequency dictionary
print("Word frequencies:", word_count)


# ----------------------------------------------------------
# Sorting a dictionary
# ----------------------------------------------------------

# A dictionary of items with their prices
fruits = {
    "date": 2.80,
    "banana": 1.20,
    "apple": 2.50,
    "elderberry": 1.50,
    "cherry": 3.00
}

print("Original dictionary:")
print(fruits)

# Sorting the dictionary by keys in ascending order (alphabetically)
sorted_by_keys = dict(sorted(fruits.items()))
print("Dictionary sorted by keys:")
print(sorted_by_keys)

# Try sorted() below; you will see that it returns only the list of keys and not the entire dictionary
print(sorted(fruits))
