Python Arena
Step 2 of 3

Reading JSON files

JSON (JavaScript Object Notation) is the most common format for data that programs pass to each other: web services send their answers in it, and many apps save their settings in it. To a Python programmer it looks familiar, because it's written almost exactly like lists and dictionaries:

The file games.json
[
    {
        "name": "Chess",
        "players": 2,
        "tags": ["strategy", "classic"]
    },
    {
        "name": "Uno",
        "players": 4,
        "tags": ["cards", "family"]
    }
]

The standard library's json module turns JSON text into Python data. json.loads(text) (load from a string) takes the text and gives the list or dictionary it describes:

import json

with open("games.json") as file:
    text = file.read()

games = json.loads(text)
print(games)
Output
[{'name': 'Chess', 'players': 2, 'tags': ['strategy', 'classic']}, {'name': 'Uno', 'players': 4, 'tags': ['cards', 'family']}]

What comes out is an ordinary list of dictionaries, so everything you know about lists and dictionaries works on it. A JSON file can also be one dictionary, with lists and dictionaries nested inside it as deep as needed. Numbers become integers or floats, ready for calculating:

The file team.json
{
    "team": "Owls",
    "players": [
        {"name": "Ada", "goals": 3},
        {"name": "Ben", "goals": 5}
    ]
}
import json

with open("team.json") as file:
    team = json.loads(file.read())

print("Team:", team["team"])
total = 0
for player in team["players"]:
    print(f"{player['name']} scored {player['goals']}")
    total += player["goals"]
print("Goals in all:", total)
Output
Team: Owls
Ada scored 3
Ben scored 5
Goals in all: 8

(Inside the f-string the keys are in single quotes, so they stand out from the f-string's own double quotes. Python 3.12 and later accept double quotes there too, but older versions don't, so you'll see single quotes in most code.) The module also has json.load(file), without the s, which reads the open file directly.

JSON is not quite Python

A few things are written differently in JSON. Strings always have double quotes. True and false are true and false in small letters, and the missing value is null. The module translates them:

In the Python interpreter
>>> import json
>>> json.loads('{"done": true, "score": 9.5, "note": null}')
{'done': True, 'score': 9.5, 'note': None}

JSON's rules are strict, and text that breaks them stops the program with a JSONDecodeError that says where the problem is. Single quotes are the usual culprit:

import json

data = json.loads("{'name': 'Ada'}")
Python stops with
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    data = json.loads("{'name': 'Ada'}")
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Your task

Challenge 1 of 3

What does this program print? Type each line it prints.

Challenge 2

The file books.json has a list of books, each with a title and a number of pages:

[
    {"title": "Python Pocket Guide", "pages": 210},
    {"title": "Data in Practice", "pages": 345}
]

Write a function total_pages(filename) that reads such a file with the json module and returns the total number of pages of all the books. For the file above it returns 555.

Challenge 3

A JSON file has a list of recipes, each with a name, a list of ingredients and the minutes it takes:

[
    {"name": "Pancakes", "ingredients": ["flour", "milk", "eggs", "butter", "salt"], "minutes": 20},
    {"name": "Tomato soup", "ingredients": ["tomatoes", "onion", "garlic", "stock", "cream", "basil"], "minutes": 35}
]

Write a program that asks for the name of the file, reads it with the json module and prints one line for each recipe, as in the example:

File: recipes.json
Pancakes: 5 ingredients, 20 minutes
Tomato soup: 6 ingredients, 35 minutes