Python for AI/ML Engineering
Revision Notes
Python — JSON
■ Beginner Friendly ■■ File I/O ■ Real-World Ready ■ AI/ML Foundation
■ Quick Function Reference
Function Direction Works With Memory Trick
[Link]() Dict → JSON string Memory / Variables "dumps it out" as text
[Link]() JSON string → Dict Memory / Variables "loads it in" as data
[Link]() Dict → JSON file Files on disk No "s" → file
[Link]() JSON file → Dict Files on disk No "s" → file
Python JSON Revision Notes · Page 1
1 · What is JSON?
JSON stands for JavaScript Object Notation. Despite the name, it is used everywhere — especially in
Python and AI/ML projects. Think of JSON as a neat label system that both humans and computers can
read easily.
JSON Structure
JSON stores data as key–value pairs inside curly braces, exactly like a Python dictionary:
■ [Link]
1 {
2 "name": "Ali",
3 "age": 25,
4 "city": "Karachi",
5 "active": true
6 }
Python ↔ JSON Type Mapping
Python Type JSON Type Example
dict object {} {"name": "Ali"}
list array [] ["Python", "ML"]
str string "Hello"
int / float number 25 / 3.14
True / False true / false true / false
None null null
■ Note In Python, booleans are True / False (capital). JSON uses true / false (lowercase). Python handles this
automatically.
Python JSON Revision Notes · Page 2
2 · Core JSON Functions
2.1 [Link]() — Dictionary → JSON String
■ dumps_example.py
1 import json
2
3 person = {
4 "name": "Ali",
5 "age": 25,
6 "is_student": True
7 }
8
9 json_string = [Link](person)
10 print(json_string)
11 print(type(json_string))
12
13 # Output: {"name": "Ali", "age": 25, "is_student": true}
14 # Output:
2.2 [Link]() — JSON String → Dictionary
■ loads_example.py
1 import json
2
3 json_string = '{"name": "Ali", "age": 25}'
4
5 person = [Link](json_string)
6 print(person["name"])
7 # Output: Ali
2.3 Formatting Options — indent & sort_keys
■ [Link]
1 import json
2
3 book = {"title": "Atomic Habits", "year": 2018}
4
5 # Pretty print with 4-space indentation
6 print([Link](book, indent=4)
7
8 # Sort keys alphabetically
9 print([Link](book, indent=4, sort_keys=True)
Python JSON Revision Notes · Page 3
■ Note indent=4 makes JSON human-readable. It does NOT change the data, only its appearance.
sort_keys=True sorts keys A→Z for consistent output.
Python JSON Revision Notes · Page 4
2.4 [Link]() — Dictionary → JSON File
■ dump_to_file.py
1 import json
2
3 student = {"name": "Ali", "age": 22}
4
5 with open("[Link]", "w") as file:
6 [Link](student, file, indent=4)
7
8 # Creates [Link] with nicely formatted content
2.5 [Link]() — JSON File → Dictionary
■ load_from_file.py
1 import json
2
3 with open("[Link]", "r") as file:
4 data = [Link](file)
5
6 print(data["name"]) # Ali
7 print(type(data) #
Python JSON Revision Notes · Page 5
3 · Nested JSON
Real-world JSON is rarely flat. It contains dictionaries inside dictionaries and lists of dictionaries — just
like folders inside folders.
■ nested_json.py
1 import json
2
3 employee = {
4 "name": "Sara",
5 "address": { # nested dict
6 "city": "Lahore",
7 "zip": "54000"
8 },
9 "skills": ["Python", "SQL"], # list
10 "experience": [ # list of dicts
11 {"company": "TechCorp", "years": 2},
12 {"company": "AI Labs", "years": 3}
13 ]
14 }
15
16 # Accessing nested data
17 print(employee["address"]["city"]) # Lahore
18 print(employee["skills"][1]) # SQL
19 print(employee["experience"][1]["company"]) # AI Labs
■ Note Read nested access left to right: data["experience"][1]["company"] means → go into 'experience' list →
grab item at index 1 → get its 'company' key.
Python JSON Revision Notes · Page 6
4 · Modifying JSON Data
The pattern is always: Load → Modify → Save
■ modify_json.py
1 import json
2
3 # Step 1: LOAD
4 with open("[Link]", "r") as file:
5 data = [Link](file)
6
7 # Step 2: MODIFY
8 data["year"] = 2024 # update existing value
9 data["is_public"] = True # add new key
10 data["location"]["state"] = "CA" # update nested value
11 data["tags"].append("new_tag") # add to list
12
13 # Step 3: SAVE
14 with open("[Link]", "w") as file:
15 [Link](data, file, indent=4)
■ Remember Once JSON is loaded into Python, it is just a normal dictionary. All standard dict operations work:
update values, add keys, delete keys, append to lists.
Python JSON Revision Notes · Page 7
5 · Error Handling
Always wrap JSON operations in try/except. Files can be missing, empty, or corrupted.
■ error_handling.py
1 import json
2
3 def load_data(filename):
4 try:
5 with open(filename, "r") as file:
6 return [Link](file)
7
8 except FileNotFoundError:
9 print("File not found!")
10 return [] # return safe default
11
12 except [Link]:
13 print("Invalid JSON format!")
14 return []
Common JSON Errors
Error Cause Fix
FileNotFoundError File path is wrong or file doesn't exist yet Use try/except, return []
[Link] File is empty, corrupted, or not valid JSON Use try/except, return []
KeyError Accessing a key that doesn't exist in the dict Use .get("key", default)
TypeError Trying to serialize an unsupported Python type Convert to str/int/list first
■ Note return [] inside except is the 'safe default' pattern — your program gets an empty list instead of crashing,
so all downstream code still works.
Python JSON Revision Notes · Page 8
6 · Mini Project — Contact Book
A complete command-line contact book demonstrating all JSON concepts:
■ contact_book.py [Part 1 — load / save / add]
1 import json
2
3 FILENAME = "[Link]"
4
6 def load_contacts():
7 try:
8 with open(FILENAME, "r") as f:
9 return [Link](f)
10 except (FileNotFoundError, [Link]):
11 return []
12
13
14 def save_contacts(contacts):
15 with open(FILENAME, "w") as f:
16 [Link](contacts, f, indent=4)
17
18
19 def add_contact():
20 contacts = load_contacts()
21 name = input("Name: ")
22 phone = input("Phone: ")
23 email = input("Email: ")
24 [Link]({"name": name, "phone": phone, "email": email})
25 save_contacts(contacts)
26 print("Contact added!")
■ contact_book.py [Part 2 — view / search / delete / main loop]
Python JSON Revision Notes · Page 9
1 def view_contacts():
2 contacts = load_contacts()
3 if not contacts:
4 print("No contacts found."); return
5 for c in contacts:
6 print(f"Name: {c['name']} | Phone: {c['phone']} | Email: {c['email']}")
7
9 def search_contact():
10 query = input("Search name: ").lower()
11 contacts = load_contacts()
12 found = False
13 for c in contacts:
14 if c["name"].lower() == query:
15 print(f"Found: {c['name']} — {c['phone']}")
16 found = True
17 if not found: print("Not found.")
18
19
20 def delete_contact():
21 name = input("Delete name: ").lower()
22 contacts = load_contacts()
23 updated = [c for c in contacts if c["name"].lower() != name]
24 if len(updated) == len(contacts):
25 print("Not found.")
26 else:
27 save_contacts(updated)
28 print("Deleted.")
29
30
31 # ■■■ Main Loop ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
32 while True:
33 print("\n=== Contact Book ===")
34 choice = input("1-Add 2-View 3-Search 4-Delete 5-Exit: ")
35 if choice == "1": add_contact()
36 elif choice == "2": view_contacts()
37 elif choice == "3": search_contact()
38 elif choice == "4": delete_contact()
39 elif choice == "5": break
40 else: print("Invalid choice.")
Python JSON Revision Notes · Page 10
7 · ■ Mistakes I Made
■ Mistake Mistake 1 — Storing numbers as strings
Wrote: "population": "30 million"
Problem: You cannot do arithmetic on a string. Always store numbers as int or float.
Fix: "population": 30_000_000
■ Mistake Mistake 2 — JSON keys without double quotes
Wrote: [{name: "Ali"}]
Problem: Valid JSON requires ALL keys to be in double quotes.
Fix: [{"name": "Ali"}]
■ Mistake Mistake 3 — Using a variable after a failed try/except
Wrote: try: contacts = [Link](f) except: print(err) → [Link](...)
Problem: If except runs, contacts was never defined → NameError crash.
Fix: Add return or exit() inside the except block, OR use the safe-default pattern: return []
■ Mistake Mistake 4 — Menu and input() placed OUTSIDE the while loop
Problem: The menu printed once and the same choice ran forever in an infinite loop.
Fix: Move both print(menu) and choice = input() INSIDE the while loop so the user is asked on every
iteration.
■ Mistake Mistake 5 — Case-insensitive search only on one side
Wrote: if contact["name"].lower() == name_searched
Problem: If user types "ALI", comparing "ali" == "ALI" returns False.
Fix: if contact["name"].lower() == name_searched.lower()
■ Mistake Mistake 6 — Double quotes inside a double-quoted f-string
Wrote: f"{contact["name"]}"
Problem: Python cannot parse quotes-inside-same-quotes (SyntaxError in Python < 3.12).
Fix: f"{contact['name']}" (use single quotes inside the f-string)
■ Mistake Mistake 7 — Mixing two responsibilities into one function
Named the function load_contacts() but put add-contact logic inside it.
Problem: One function should do ONE job. Mixing makes code hard to reuse and debug.
Fix: Separate into load_contacts() (only loads & returns data) and add_contact() (only handles adding).
Python JSON Revision Notes · Page 11
8 · ■ Things to Remember
■ Remember The "s" in dumps / loads = String. No "s" in dump / load = File.
■ Remember Once JSON is loaded into Python it is just a normal dictionary — use it exactly like one.
■ Remember Always use try/except around file operations. Files can be missing, empty, or corrupted.
■ Remember The safe-default pattern: except ...: return [] keeps your program running even when
data doesn't exist yet.
■ Remember Every key and every string value in JSON must use double quotes. Single quotes are valid
Python but invalid JSON.
■ Remember JSON booleans are lowercase: true / false / null. Python handles the conversion
automatically.
■ Remember Always apply .lower() to both sides of a string comparison for case-insensitive matching.
■ Remember Take menu input as a string (plain input()), not int(input()) — this prevents crashes when
users type unexpected characters.
■ Remember The Load → Modify → Save pattern is the standard way to update any JSON file.
■ Remember Use single quotes INSIDE f-strings that use double quotes: f"{d['key']}"
■ You are now ready for real-world Python JSON work!
Next topics will build on JSON — APIs, config files, AI/ML data pipelines.
Python JSON Revision Notes · Page 12