8.3. JSON File

  • json.load(file) -> dict

  • json.dump(data, file) -> None

  • file extension .json

8.3.1. SetUp

>>> import json

8.3.2. Write Data to JSON File

  • json.dump(data, file) -> None

  • file extension .json

def dump(obj: Any,
         fp: IO[str],
         *,
         skipkeys: bool = ...,
         ensure_ascii: bool = ...,
         check_circular: bool = ...,
         allow_nan: bool = ...,
         cls: Type[JSONEncoder] | None = ...,
         indent: None | int | str = ...,
         separators: tuple[str, str] | None = ...,
         default: (Any) -> Any | None = ...,
         sort_keys: bool = ...,
         **kwds: Any) -> None

SetUp:

>>> FILE = r'/tmp/myfile.json'
>>>
>>> DATA = {
...     'firstname': 'Mark',
...     'lastname': 'Watney',
... }

Usage:

>>> with open(FILE, mode='w') as file:
...     json.dump(DATA, file)

Result:

>>> print(open(FILE).read())
{"firstname": "Mark", "lastname": "Watney"}

8.3.3. Read Data From JSON File

  • json.load(file) -> dict

  • file extension .json

def load(fp: SupportsRead[str | bytes],
         *,
         cls: Type[JSONDecoder] | None = ...,
         object_hook: (dict) -> Any | None = ...,
         parse_float: (str) -> Any | None = ...,
         parse_int: (str) -> Any | None = ...,
         parse_constant: (str) -> Any | None = ...,
         object_pairs_hook: (list[tuple[Any, Any]]) -> Any | None = ...,
         **kwds: Any) -> Any

SetUp:

>>> FILE = r'/tmp/myfile.json'
>>> DATA = """{
...     "firstname": "Mark",
...     "lastname": "Watney"
... }"""
>>>
>>> _ = open(FILE, mode='w').write(DATA)

Usage:

>>> with open(FILE) as file:
...     result = json.load(file)
>>>
>>> print(result)
{'firstname': 'Mark', 'lastname': 'Watney'}

8.3.4. Assignments

Code 8.28. Solution
"""
* Assignment: JSON File Dump
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min

English:
    1. Dump `result` to file `FILE` in JSON format
    2. Run doctests - all must succeed

Polish:
    1. Zrzuć `result` do pliku `FILE` w formacie JSON
    2. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from os import remove
    >>> result = open(FILE).read()
    >>> remove(FILE)
    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'
    >>> assert type(result) is str, \
    'Variable `result` has invalid type, should be str'
    >>> assert len(result) > 0, \
    'Variable `result` should not be empty'

    >>> print(result)  # doctest: +NORMALIZE_WHITESPACE
    [["Sepal length", "Sepal width", "Petal length", "Petal width", "Species"],
     [5.8, 2.7, 5.1, 1.9, "virginica"],
     [5.1, 3.5, 1.4, 0.2, "setosa"],
     [5.7, 2.8, 4.1, 1.3, "versicolor"],
     [6.3, 2.9, 5.6, 1.8, "virginica"],
     [6.4, 3.2, 4.5, 1.5, "versicolor"],
     [4.7, 3.2, 1.3, 0.2, "setosa"],
     [7.0, 3.2, 4.7, 1.4, "versicolor"],
     [7.6, 3.0, 6.6, 2.1, "virginica"],
     [4.9, 3.0, 1.4, 0.2, "setosa"]]
"""

import json

FILE = '_temporary.json'

DATA = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, 'virginica'),
    (5.1, 3.5, 1.4, 0.2, 'setosa'),
    (5.7, 2.8, 4.1, 1.3, 'versicolor'),
    (6.3, 2.9, 5.6, 1.8, 'virginica'),
    (6.4, 3.2, 4.5, 1.5, 'versicolor'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
]

# Dump `result` to file `FILE` in JSON format

Code 8.29. Solution
"""
* Assignment: JSON File Dump
* Complexity: easy
* Lines of code: 4 lines
* Time: 5 min

English:
    1. Extract from input a header and rows
    2. Create `result: list[dict]`:
        a. key - name from the header
        b. value - measurement or species
    3. Dump `result` to file `FILE` in JSON format
    4. Run doctests - all must succeed

Polish:
    1. Z danych wydziel nagłówek i wiersze
    2. Wygeneruj `result: list[dict]`:
        a. klucz - nazwa z nagłówka
        b. wartość - wyniki pomiarów lub gatunek
    3. Zrzuć `result` do pliku `FILE` w formacie JSON
    4. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from os import remove
    >>> result = open(FILE).read()
    >>> remove(FILE)
    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'
    >>> assert type(result) is str, \
    'Variable `result` has invalid type, should be str'
    >>> assert len(result) > 0, \
    'Variable `result` should not be empty'

    >>> print(result)  # doctest: +NORMALIZE_WHITESPACE
    [{"Sepal length": 5.8, "Sepal width": 2.7, "Petal length": 5.1, "Petal width": 1.9, "Species": "virginica"},
     {"Sepal length": 5.1, "Sepal width": 3.5, "Petal length": 1.4, "Petal width": 0.2, "Species": "setosa"},
     {"Sepal length": 5.7, "Sepal width": 2.8, "Petal length": 4.1, "Petal width": 1.3, "Species": "versicolor"},
     {"Sepal length": 6.3, "Sepal width": 2.9, "Petal length": 5.6, "Petal width": 1.8, "Species": "virginica"},
     {"Sepal length": 6.4, "Sepal width": 3.2, "Petal length": 4.5, "Petal width": 1.5, "Species": "versicolor"},
     {"Sepal length": 4.7, "Sepal width": 3.2, "Petal length": 1.3, "Petal width": 0.2, "Species": "setosa"},
     {"Sepal length": 7.0, "Sepal width": 3.2, "Petal length": 4.7, "Petal width": 1.4, "Species": "versicolor"},
     {"Sepal length": 7.6, "Sepal width": 3.0, "Petal length": 6.6, "Petal width": 2.1, "Species": "virginica"},
     {"Sepal length": 4.9, "Sepal width": 3.0, "Petal length": 1.4, "Petal width": 0.2, "Species": "setosa"}]
"""

import json

FILE = '_temporary.json'

DATA = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, 'virginica'),
    (5.1, 3.5, 1.4, 0.2, 'setosa'),
    (5.7, 2.8, 4.1, 1.3, 'versicolor'),
    (6.3, 2.9, 5.6, 1.8, 'virginica'),
    (6.4, 3.2, 4.5, 1.5, 'versicolor'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
]

# Extract from input a header and rows
# Create `result: list[dict]`:
#  a. key - name from the header
#  b. value - measurement or species
# Dump `result` to file `FILE` in JSON format
data = ...


Code 8.30. Solution
"""
* Assignment: JSON File Load
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min

English:
    1. Read JSON data from `FILE`
    2. Run doctests - all must succeed

Polish:
    1. Odczytaj dane JSON z pliku `FILE`
    2. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from os import remove
    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'
    >>> assert type(result) is list, \
    'Variable `result` has invalid type, should be list'
    >>> assert len(result) > 0, \
    'Variable `result` should not be empty'
    >>> assert all(type(row) is dict for row in result), \
    'Variable `result` should be a list[dict]'

    >>> result  # doctest: +NORMALIZE_WHITESPACE
    [{'Sepal length': 5.8, 'Sepal width': 2.7, 'Petal length': 5.1, 'Petal width': 1.9, 'Species': 'virginica'},
     {'Sepal length': 5.1, 'Sepal width': 3.5, 'Petal length': 1.4, 'Petal width': 0.2, 'Species': 'setosa'},
     {'Sepal length': 5.7, 'Sepal width': 2.8, 'Petal length': 4.1, 'Petal width': 1.3, 'Species': 'versicolor'},
     {'Sepal length': 6.3, 'Sepal width': 2.9, 'Petal length': 5.6, 'Petal width': 1.8, 'Species': 'virginica'},
     {'Sepal length': 6.4, 'Sepal width': 3.2, 'Petal length': 4.5, 'Petal width': 1.5, 'Species': 'versicolor'},
     {'Sepal length': 4.7, 'Sepal width': 3.2, 'Petal length': 1.3, 'Petal width': 0.2, 'Species': 'setosa'},
     {'Sepal length': 7.0, 'Sepal width': 3.2, 'Petal length': 4.7, 'Petal width': 1.4, 'Species': 'versicolor'},
     {'Sepal length': 7.6, 'Sepal width': 3.0, 'Petal length': 6.6, 'Petal width': 2.1, 'Species': 'virginica'},
     {'Sepal length': 4.9, 'Sepal width': 3.0, 'Petal length': 1.4, 'Petal width': 0.2, 'Species': 'setosa'}]

     >>> remove(FILE)
"""

import json


FILE = r'_temporary.json'

DATA = """[{"Sepal length": 5.8, "Sepal width": 2.7, "Petal length": 5.1, "Petal width": 1.9, "Species": "virginica"},
{"Sepal length": 5.1, "Sepal width": 3.5, "Petal length": 1.4, "Petal width": 0.2, "Species": "setosa"},
{"Sepal length": 5.7, "Sepal width": 2.8, "Petal length": 4.1, "Petal width": 1.3, "Species": "versicolor"},
{"Sepal length": 6.3, "Sepal width": 2.9, "Petal length": 5.6, "Petal width": 1.8, "Species": "virginica"},
{"Sepal length": 6.4, "Sepal width": 3.2, "Petal length": 4.5, "Petal width": 1.5, "Species": "versicolor"},
{"Sepal length": 4.7, "Sepal width": 3.2, "Petal length": 1.3, "Petal width": 0.2, "Species": "setosa"},
{"Sepal length": 7.0, "Sepal width": 3.2, "Petal length": 4.7, "Petal width": 1.4, "Species": "versicolor"},
{"Sepal length": 7.6, "Sepal width": 3.0, "Petal length": 6.6, "Petal width": 2.1, "Species": "virginica"},
{"Sepal length": 4.9, "Sepal width": 3.0, "Petal length": 1.4, "Petal width": 0.2, "Species": "setosa"}]"""

with open(FILE, mode='w') as file:
    file.write(DATA)

# Read JSON data from `FILE`
# type: list[tuple]
result = ...

Code 8.31. Solution
"""
* Assignment: JSON File Load
* Complexity: easy
* Lines of code: 2 lines
* Time: 5 min

English:
    1. Read data from `FILE`
    2. Convert data to `result: list[tuple]`
    3. Do not add header as a first line
    4. Run doctests - all must succeed

Polish:
    1. Odczytaj dane z pliku `FILE`
    2. Przekonwertuj dane do `result: list[tuple]`
    3. Nie dodawaj nagłówka jako pierwsza linia
    4. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from os import remove
    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'
    >>> assert type(result) is list, \
    'Variable `result` has invalid type, should be list'
    >>> assert len(result) > 0, \
    'Variable `result` should not be empty'
    >>> assert all(type(row) is tuple for row in result), \
    'Variable `result` should be a list[tuple]'

    >>> result  # doctest: +NORMALIZE_WHITESPACE
    [(5.8, 2.7, 5.1, 1.9, 'virginica'),
     (5.1, 3.5, 1.4, 0.2, 'setosa'),
     (5.7, 2.8, 4.1, 1.3, 'versicolor'),
     (6.3, 2.9, 5.6, 1.8, 'virginica'),
     (6.4, 3.2, 4.5, 1.5, 'versicolor'),
     (4.7, 3.2, 1.3, 0.2, 'setosa'),
     (7.0, 3.2, 4.7, 1.4, 'versicolor'),
     (7.6, 3.0, 6.6, 2.1, 'virginica'),
     (4.9, 3.0, 1.4, 0.2, 'setosa')]

     >>> remove(FILE)
"""

import json


FILE = r'_temporary.json'

DATA = """[{"Sepal length": 5.8, "Sepal width": 2.7, "Petal length": 5.1, "Petal width": 1.9, "Species": "virginica"},
{"Sepal length": 5.1, "Sepal width": 3.5, "Petal length": 1.4, "Petal width": 0.2, "Species": "setosa"},
{"Sepal length": 5.7, "Sepal width": 2.8, "Petal length": 4.1, "Petal width": 1.3, "Species": "versicolor"},
{"Sepal length": 6.3, "Sepal width": 2.9, "Petal length": 5.6, "Petal width": 1.8, "Species": "virginica"},
{"Sepal length": 6.4, "Sepal width": 3.2, "Petal length": 4.5, "Petal width": 1.5, "Species": "versicolor"},
{"Sepal length": 4.7, "Sepal width": 3.2, "Petal length": 1.3, "Petal width": 0.2, "Species": "setosa"},
{"Sepal length": 7.0, "Sepal width": 3.2, "Petal length": 4.7, "Petal width": 1.4, "Species": "versicolor"},
{"Sepal length": 7.6, "Sepal width": 3.0, "Petal length": 6.6, "Petal width": 2.1, "Species": "virginica"},
{"Sepal length": 4.9, "Sepal width": 3.0, "Petal length": 1.4, "Petal width": 0.2, "Species": "setosa"}]"""

with open(FILE, mode='w') as file:
    file.write(DATA)

# type: list[tuple]
result = ...