Section #8: Nested Dictionaries


Written by Kevin Wang, Kavel Rao, and Ngoc Nguyen


In this section, you'll learn how to work with JSON structures and handle nested dictionaries. The dataset used in this problem contains three layers of nesting, similar to the Infinite Story assignment, which will help you practice navigating through complex data structures.

Network

In this problem, you'll analyze a social network dataset stored in a JSON file.

Your Data

You are working with a dictionary loaded from a JSON file that contains information about people and their friends. Each person has a list of their friends, and for each friend, we store how many years they've been friends. Each person's data is in social network structured something like this


data = {
    "network": {
        "Kavel": {
            "friends": [
                {
                "name": "Clinton",
                "years_friends": 6
                },
                {
                "name": "Diego",
                "years_friends": 2
                }
            ]
        },
        "Clinton": {
            "friends": [
                {
                "name": "Kavel",
                "years_friends": 6
                },
                {
                "name": "Anita",
                "years_friends": 4
                }
            ]
        }
    }
}
                   
    
            

Your actual dataset is much larger - go check it out in the file named data.json!

Tracing Warmups

1. For each expression below, use the small sample data dictionary above to determine the value type (int, str, dictionary, etc)

data["network"]
data["network"]["Kavel"]
data["network"]["Kavel"]["friends"]
data["network"]["Kavel"]["friends"][0]
data["network"]["Kavel"]["friends"][0]["name"]

2. Write a piece of code to update the number of years Clinton has been friends with Anita to 7 years.

Task 1: Find Missing Friends

Given a larger dictionary loaded from a JSON file containing a social network, your first task is to find and print the names of the friends who are mentioned but are missing from the network. Our code should avoid printing out names twice.

                
                def find_missing_friends(data_dict):


                
            
For example, using the small JSON dataset above,

The program should print the names of these "missing" friends, which in this case would be

Diego
Anita

Run the provided doctest to make sure your code is working.

Task 2: Calculate Total Friendship Years

Given the same data dictionary loaded from a JSON file and a person's name, we want to write a function to calculate the total number of years a given person has been friends with their friends.

            
            def calculate_total_years(data_dict, name):


            
        

Using the small example friend network from above, asking for Clinton's total years of friendship will print

            Clinton has a total of 10 years of friendship.
            

When we ask for name that is not in the network like "Langston", the program should print

            Langston is not in the network.
            

Task 3: Make friends! 🫂

If only it were that easy...right? :-) This problem is deceptively challenging, so don't worry if it takes a bit of time to work things out! Your task is to write a function that adds a friendship to the data dictionary. You're given two people, person1 and person2, along with the number of years they've been friends, num_years.

def add_friendship(data_dict, person1, person2, num_years)

You'll put person2 as a friend in person1's friends list, as well as person1 as a friend in person2's friends list.

For example, if we called the following function:

add_friendship(data, "Ngoc", "Yasmine", 4)

we would return the following dictionary:

            
            {
    "network": {
        "Kavel": {
            "friends": [
                {
                "name": "Clinton",
                "years_friends": 6
                },
                {
                "name": "Diego",
                "years_friends": 2
                }
            ]
        },
        "Clinton": {
            "friends": [
                {
                "name": "Kavel",
                "years_friends": 6
                },
                {
                "name": "Anita",
                "years_friends": 4
                }
            ]
        },
        "Ngoc": {
            "friends": [
                {
                    "name": "Yasmine",
                    "years_friends": 4
                }
            ]
        },
        "Yasmine": {
            "friends": [
                {
                    "name": "Ngoc",
                    "years_friends": 4
                }
            ]
        }
    }
}
                
                        

If you find an existing friendship, update it with the new num_years you passed into your function call.

Some pointers: Decompose when things get hairy, and you might want to use a map or two. What specific task are you doing more than once? When would we use a map in the wild? Have fun with this problem! 🌟 You rock!!