Day 6 of 80

Dictionaries & JSON

Phase 1: Python Foundation

What You'll Build Today

Welcome to Day 6. Today is a pivotal day. Up until now, we have been storing data in lists. Lists are great for keeping items in a specific order, like a to-do list or a queue of songs. But lists are terrible at relationships.

Today, we are going to build a Digital Contact Book. By the end of this session, you will build an application that can store a person's name, email, phone number, and even their location, all organized so you can find exactly what you need instantly without searching through the whole pile.

Here is what you will learn and, more importantly, why:

* Dictionaries (Key-Value Pairs): You will learn to label your data. Instead of remembering that the email is at "index 1," you will just ask for the "email."

* Nested Dictionaries: Real data is rarely flat. You will learn to store data inside other data, which is exactly how complex information is structured in the real world.

* The .get() Method: You will learn how to write safe code that doesn't crash when information is missing.

* JSON (JavaScript Object Notation): This is the universal language of the internet. When you eventually ask an AI model a question, the answer comes back in this format. If you can't navigate it, you can't use the AI's response.

Let's get started.

The Problem

Imagine you are trying to store contact information for three people using what we have learned so far (variables and lists).

You might try creating a list for names and a separate list for emails.

# The "List" approach

names = ["Alice", "Bob", "Charlie"]

emails = ["alice@tech.com", "bob@design.com", "charlie@sales.com"]

phone_numbers = ["555-0100", "555-0101", "555-0102"]

# I want to find Bob's email. # First, I have to find where Bob is in the names list. # I happen to know he is second, so that is index 1.

bobs_index = 1

print(f"Name: {names[bobs_index]}")

print(f"Email: {emails[bobs_index]}")

print(f"Phone: {phone_numbers[bobs_index]}")

This works, technically. But think about the problems here:

  • Synchronization Risk: If you delete "Alice" from the names list but forget to delete her from emails and phone_numbers, everything shifts. Suddenly, "Bob" (now at index 0) has Alice's email. Your data is corrupted.
  • The "Mystery Data" Problem: What if we tried to put it all in one list?
  •     # A list of lists?
    

    contacts = [

    ["Alice", "alice@tech.com", "555-0100"],

    ["Bob", "bob@design.com", "555-0101"]

    ]

    # To get Bob's phone number:

    print(contacts[1][2])

    Look at contacts[1][2]. What does 2 mean? Is it the phone number? The zip code? The age? You have to memorize the structure. If you hand this code to a colleague, they will have no idea what index 2 represents.

    There has to be a way to label data so we can say: "Give me Bob's email," rather than "Give me the item at index 1."

    Let's Build It

    The solution is the Dictionary.

    In Python, a dictionary is a collection of Key-Value pairs. Think of a real physical dictionary. You don't read it page by page to find a definition. You look up a specific word (the Key) to find its definition (the Value).

    Step 1: Creating a Simple Dictionary

    We use curly braces {} for dictionaries. Keys and values are separated by a colon :.

    # Creating a dictionary for a single person
    # Key : Value
    

    person = {

    "name": "Alice",

    "email": "alice@tech.com",

    "role": "Developer"

    }

    print(person)

    print(type(person))

    Output:
    {'name': 'Alice', 'email': 'alice@tech.com', 'role': 'Developer'}
    
    

    Step 2: Accessing Data (The Unsafe vs. Safe Way)

    To get data out, we use the key name.

    person = {
    

    "name": "Alice",

    "email": "alice@tech.com",

    "role": "Developer"

    }

    # 1. The Bracket Method (Direct Access)

    print(person["name"])

    print(person["email"])

    # 2. The Pain of Brackets # Uncommenting the line below causes a crash because "phone" doesn't exist yet # print(person["phone"]) # KeyError: 'phone'

    If you try to access a key that doesn't exist using brackets [], Python throws an error and stops your program. This is dangerous when working with AI or web data, because sometimes data is missing.

    The Solution: .get()
    # 3. The .get() Method (Safe Access)
    

    print(person.get("email"))

    # If the key doesn't exist, .get() returns None instead of crashing

    print(person.get("phone"))

    # You can even provide a default value if the key is missing

    print(person.get("phone", "No phone number found"))

    Output:
    Alice
    

    alice@tech.com

    alice@tech.com

    None

    No phone number found

    Step 3: Adding and Modifying Data

    Dictionaries are mutable (changeable). You can add new keys or update existing ones just by assigning them.

    person = {
    

    "name": "Alice",

    "role": "Developer"

    }

    print(f"Original: {person}")

    # Adding a new key-value pair

    person["email"] = "alice@new-job.com"

    # Updating an existing key

    person["role"] = "Senior Developer"

    print(f"Updated: {person}")

    Output:
    Original: {'name': 'Alice', 'role': 'Developer'}
    

    Updated: {'name': 'Alice', 'role': 'Senior Developer', 'email': 'alice@new-job.com'}

    Step 4: The Contact Book (Nested Dictionaries)

    Now, let's solve the original problem. We want to store multiple people. We can use a dictionary where the Key is the person's name, and the Value is another dictionary containing their details.

    This is called Nesting.

    contacts = {
    

    "Alice": {

    "phone": "555-0100",

    "email": "alice@tech.com"

    },

    "Bob": {

    "phone": "555-0101",

    "email": "bob@design.com"

    }

    }

    # Accessing nested data # Logic: Go into 'contacts', find 'Alice', then find 'phone'

    alice_phone = contacts["Alice"]["phone"]

    print(f"Alice's phone is: {alice_phone}")

    Output:
    Alice's phone is: 555-0100
    

    Step 5: Iterating Through Dictionaries

    Sometimes you want to list everyone in your book. You can loop through keys, values, or both.

    contacts = {
    

    "Alice": {"email": "alice@tech.com"},

    "Bob": {"email": "bob@design.com"},

    "Charlie": {"email": "charlie@sales.com"}

    }

    print("--- Contact List ---")

    # .items() gives us both the key (name) and value (info_dict)

    for name, info in contacts.items():

    email = info["email"]

    print(f"Name: {name} | Email: {email}")

    Output:
    --- Contact List ---
    

    Name: Alice | Email: alice@tech.com

    Name: Bob | Email: bob@design.com

    Name: Charlie | Email: charlie@sales.com

    Step 6: Introduction to JSON

    This is the bridge to AI. JSON (JavaScript Object Notation) looks almost exactly like a Python dictionary. It is the standard format for sending data across the web.

    When you use Python to talk to OpenAI or Google Gemini, you send JSON, and they send JSON back.

    Python has a built-in tool to handle this.

    import json
    
    # A Python Dictionary
    

    my_data = {

    "name": "Alice",

    "is_student": False,

    "skills": ["Python", "AI", "Data"]

    }

    # 1. dumps (Dump to String): Convert Dictionary -> JSON String # We use this when SENDING data to an AI

    json_string = json.dumps(my_data)

    print(f"Type: {type(json_string)}")

    print(f"Data: {json_string}")

    # 2. loads (Load from String): Convert JSON String -> Dictionary # We use this when RECEIVING data from an AI

    incoming_data = '{"id": 101, "status": "success"}'

    parsed_data = json.loads(incoming_data)

    print(f"Type: {type(parsed_data)}")

    print(f"Status is: {parsed_data['status']}")

    Output:
    Type: 
    

    Data: {"name": "Alice", "is_student": false, "skills": ["Python", "AI", "Data"]}

    Type:

    Status is: success

    Note: In JSON, False becomes false (lowercase). Python handles this conversion for you automatically.

    Now You Try

    You have the source code for the Contact Book above. Now, extend it.

  • Add Locations: Update the contacts dictionary so that every person also has a "city" key.
  • The Search Function: Write a script that asks the user (using input()) for a name.
  • * If the name exists in contacts, print their email and city.

    * If the name does not exist, print "User not found" (Hint: Use the in keyword or .get()).

  • The Pretty Printer: Iterate through the dictionary and print the data in this sentence format:
  • "Alice lives in New York and can be reached at alice@email.com"*

    Challenge Project: The API Parser

    When you work with AI, you will often receive a large, complex "response object" that contains the answer you want, buried inside metadata.

    Your challenge is to extract specific data from a mock API response representing a social media post.

    Requirements:
  • Copy the api_response variable provided below into your code.
  • Extract and print the username of the author.
  • Extract and print the number of likes.
  • Extract and print the second hashtag in the list.
  • Bonus: Check if the user is verified. If true, print "Verified Account". If false, print "Unverified".
  • The Data (Copy this):
    api_response = {
    

    "status": 200,

    "data": {

    "post_id": "8823-1123",

    "content": "Just learned about Python dictionaries! #coding #python #learning",

    "metrics": {

    "likes": 42,

    "shares": 12,

    "views": 1500

    },

    "author": {

    "username": "coder_jane",

    "display_name": "Jane Doe",

    "is_verified": True,

    "profile": {

    "age": 28,

    "location": "San Francisco"

    }

    }

    }

    }

    Expected Output:
    Author: coder_jane
    

    Likes: 42

    Hashtag: #python

    Verified Account

    Hints:

    * This is a dictionary inside a dictionary inside a dictionary.

    * To get the username, you need to go: api_response -> data -> author -> username.

    * The hashtags are inside the string "content". You might need to manipulate that string or just manually locate the second one if you haven't learned string splitting yet (though string splitting content.split() is the best way!).

    What You Learned

    Today you moved from simple lists to structured data.

    * Dictionaries: You can now label data with keys (name, email) instead of relying on numbered indexes.

    * Nesting: You learned that values can be other dictionaries, allowing you to model complex real-world objects.

    * Safety: You learned to use .get() to prevent your code from crashing when data is missing.

    * JSON: You learned that JSON is just a text representation of a dictionary, used for web communication.

    Why This Matters:

    In Phase 2, you will build a chatbot. The conversation history of that chatbot will be a list of dictionaries:

    [{"role": "user", "content": "Hello"}, {"role": "ai", "content": "Hi there!"}]

    Understanding today's lesson is the only way you will be able to build that history.

    Tomorrow: We tackle Functions. You have been writing a lot of code that runs top-to-bottom. Tomorrow, we will learn how to package that code into reusable blocks so you don't have to repeat yourself.