12.3. Serialization Load
loads(str) -> object
load(file) -> object
12.3.1. Sequence
>>> DATA = 'Alice,Apricot,30'
>>>
>>> def loads(data, fieldseparator=','):
... return tuple(data.split(fieldseparator))
>>>
>>>
>>> loads(DATA)
('Alice', 'Apricot', '30')
12.3.2. Mapping
>>> DATA = 'firstname,lastname,age;Alice,Apricot,30'
>>>
>>> def loads(data, fieldseparator=',', recordseparator=';'):
... records = data.split(recordseparator)
... header, row = [row.split(fieldseparator) for row in records]
... return dict(zip(header,row))
>>>
>>>
>>> loads(DATA)
{'firstname': 'Alice', 'lastname': 'Apricot', 'age': '30'}
12.3.3. List of Sequence
>>> DATA = 'firstname,lastname,age;Alice,Apricot,30;Bob,Banana,31;Carol,Corn,32;Dave,Durian,33;Eve,Elderberry,34;Mallory,Melon,15'
>>>
>>> def loads(data, fieldseparator=',', recordseparator=';'):
... rows = data.split(recordseparator)
... return [tuple(row.split(fieldseparator)) for row in rows]
>>>
>>>
>>> loads(DATA)
[('firstname', 'lastname', 'age'),
('Alice', 'Apricot', '30'),
('Bob', 'Banana', '31'),
('Carol', 'Corn', '32'),
('Dave', 'Durian', '33'),
('Eve', 'Elderberry', '34'),
('Mallory', 'Melon', '15')]
12.3.4. List of Mappings
>>> DATA = 'age,firstname,lastname;30,Alice,Apricot;31,Bob,Banana;32,Carol,Corn;33,Dave,Durian;34,Eve,Elderberry;15,Mallory,Melon'
>>>
>>> def loads(data, fieldseparator=',', recordseparator=';'):
... records = data.split(recordseparator)
... header, *rows = [row.split(fieldseparator) for row in records]
... return [dict(zip(header,row)) for row in rows]
>>>
>>>
>>> loads(DATA)
[{'age': '30', 'firstname': 'Alice', 'lastname': 'Apricot'},
{'age': '31', 'firstname': 'Bob', 'lastname': 'Banana'},
{'age': '32', 'firstname': 'Carol', 'lastname': 'Corn'},
{'age': '33', 'firstname': 'Dave', 'lastname': 'Durian'},
{'age': '34', 'firstname': 'Eve', 'lastname': 'Elderberry'},
{'age': '15', 'firstname': 'Mallory', 'lastname': 'Melon'}]
12.3.5. List of Objects
>>> DATA = 'age,firstname,lastname;30,Alice,Apricot;31,Bob,Banana;32,Carol,Corn;33,Dave,Durian;34,Eve,Elderberry;15,Mallory,Melon'
>>>
>>> class User:
... def __init__(self, firstname, lastname, age):
... self.firstname = firstname
... self.lastname = lastname
... self.age = age
...
... def __repr__(self):
... clsname = self.__class__.__name__
... firstname = self.firstname
... lastname = self.lastname
... age = self.age
... return f'{clsname}({firstname=}, {lastname=}, {age=})'
>>>
>>>
>>> def loads(data, fieldseparator=',', recordseparator=';'):
... records = data.split(recordseparator)
... header, *rows = [row.split(fieldseparator) for row in records]
... return [User(**dict(zip(header,row))) for row in rows]
>>>
>>>
>>> loads(DATA)
[User(firstname='Alice', lastname='Apricot', age='30'),
User(firstname='Bob', lastname='Banana', age='31'),
User(firstname='Carol', lastname='Corn', age='32'),
User(firstname='Dave', lastname='Durian', age='33'),
User(firstname='Eve', lastname='Elderberry', age='34'),
User(firstname='Mallory', lastname='Melon', age='15')]
12.3.6. From File
SetUp:
>>> with open('/tmp/myfile.txt', mode='wt') as file:
... file.write('Alice,Apricot,25\n')
17
Solution:
>>> with open('/tmp/myfile.txt', mode='rt') as file:
... content = file.read()
>>>
>>> firstname, lastname, age = content.strip().split(',')
>>> result = [firstname, lastname, int(age)]
>>> result
['Alice', 'Apricot', 25]
12.3.7. Use Case - 1
SetUp:
>>> from pprint import pprint
>>>
>>> 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.6,3.1,1.5,0.2,setosa"""
Usage:
>>> def loads(data):
... header, *lines = data.splitlines()
... header = tuple(header.split(','))
... rows = []
... for line in lines:
... *values, species = line.strip().split(',')
... values = [float(x) for x in values]
... row = tuple(values) + (species,)
... rows.append(row)
... return [header] + rows
>>>
>>> result = loads(DATA)
>>>
>>> pprint(result)
[('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.6, 3.1, 1.5, 0.2, 'setosa')]
12.3.8. Use Case - 2
>>> from pprint import pprint
>>>
>>> class User:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
...
... def __repr__(self):
... firstname = self.firstname
... lastname = self.lastname
... return f'User({firstname=}, {lastname=})'
>>>
>>>
>>> DATA = 'Alice,Apricot\n'
Usage:
>>> def loads(data):
... values = data.strip().split(',')
... result = User(*values)
... return result
>>>
>>>
>>> result = loads(DATA)
>>> pprint(result)
User(firstname='Alice', lastname='Apricot')
12.3.9. Use Case - 3
SetUp:
>>> from pprint import pprint
>>>
>>> class User:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
...
... def __repr__(self):
... firstname = self.firstname
... lastname = self.lastname
... return f'User({firstname=}, {lastname=})'
>>>
>>>
>>> DATA = 'Alice,Apricot\nBob,Banana\nCarol,Corn\n'
Usage:
>>> def loads(data):
... records = data.splitlines()
... result = []
... for record in records:
... values = record.strip().split(',')
... user = User(*values)
... result.append(user)
... return result
>>>
>>>
>>> result = loads(DATA)
>>>
>>> pprint(result)
[User(firstname='Alice', lastname='Apricot'),
User(firstname='Bob', lastname='Banana'),
User(firstname='Carol', lastname='Corn')]
12.3.10. Use Case - 4
>>> from pprint import pprint
>>>
>>> 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.6,3.1,1.5,0.2,setosa"""
>>>
>>> with open('/tmp/myfile.csv', mode='wt') as file:
... file.write(DATA)
285
Solution:
>>> def load(filename):
... with open(filename, mode='rt') as file:
... data = file.read()
... header, *lines = data.strip().splitlines()
... header = tuple(header.split(','))
... rows = []
... for line in lines:
... *values, species = line.split(',')
... values = map(float, values)
... row = tuple(values) + (species,)
... rows.append(row)
... return [header] + rows
Result:
>>> result = load('/tmp/myfile.csv')
>>> pprint(result)
[('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.6, 3.1, 1.5, 0.2, 'setosa')]
12.3.11. Assignments
# %% About
# - Name: Serialization Loads Sequence
# - Difficulty: easy
# - Lines: 3
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `loads()`, which deserialize Sequence:
# - Argument: `data: str`
# - Returns: `tuple`
# 2. Define `result: tuple` with result of `dumps()` function for `DATA`
# 3. Non-functional requirements:
# - Do not use `import` and any module
# - Do not convert numbers to `int` or `float`, leave them as `str`
# - Quoting: none
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcję `loads()`, która deserializuje Sequence:
# - Argument: `data: str`
# - Zwraca: `tuple`
# 2. Zdefiniuj `result: tuple` z wynikiem funkcji `dumps()` dla `DATA`
# 3. Wymagania niefunkcjonalne:
# - Nie używaj `import` ani żadnych modułów
# - Nie konwertuj liczb do `int` lub `float`, pozostaw je jako `str`
# - Quoting: żadne
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> result
# ('Alice', 'Apricot', '30')
# %% Hints
# - `tuple()`
# - `str.split()`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 12), \
'Python 3.12+ required'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is tuple, \
'Variable `result` has invalid type, should be tuple'
>>> from pprint import pprint
>>> pprint(result, sort_dicts=False, width=79)
('Alice', 'Apricot', '30')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
type data = tuple[str,...]
loads: Callable[[str,...], data]
result: data
# %% Data
DATA = 'Alice,Apricot,30'
# %% Result
result = ...
# %% About
# - Name: Serialization Loads Mapping
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `loads()`, which deserialize Mapping:
# - Argument: `data: str`
# - Returns: `dict[str,str]`
# 2. Define `result: dict` with result of `dumps()` function for `DATA`
# 3. Non-functional requirements:
# - Do not use `import` and any module
# - Do not convert numbers to `int` or `float`, leave them as `str`
# - Quoting: none
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcję `loads()`, która deserializuje Mapping:
# - Argument: `data: str`
# - Zwraca: `dict[str,str]`
# 2. Zdefiniuj `result: dict` z wynikiem funkcji `dumps()` dla `DATA`
# 3. Wymagania niefunkcjonalne:
# - Nie używaj `import` ani żadnych modułów
# - Nie konwertuj liczb do `int` lub `float`, pozostaw je jako `str`
# - Quoting: żadne
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> result
# {'firstname': 'Alice', 'lastname': 'Apricot', 'age': '30'}
# %% Hints
# - `str.split()`
# - `[x for x in data]`
# - `dict()`
# - `zip()`
# - `first, second = 1, 2`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 12), \
'Python 3.12+ required'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is dict, \
'Variable `result` has invalid type, should be dict'
>>> from pprint import pprint
>>> pprint(result, sort_dicts=False, width=79)
{'firstname': 'Alice', 'lastname': 'Apricot', 'age': '30'}
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
type data = dict[str,str]
loads: Callable[[str,...], data]
result: data
# %% Data
DATA = 'firstname,lastname,age;Alice,Apricot,30'
# %% Result
result = ...
# %% About
# - Name: Serialization Loads ListSequence
# - Difficulty: easy
# - Lines: 4
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `loads()`, which deserialize list[Sequence]:
# - Argument: `data: str`
# - Returns: `list[tuple]`
# 2. Define `result: list[tuple]` with result of `dumps()` function for `DATA`
# 3. Non-functional requirements:
# - Do not use `import` and any module
# - Do not convert numbers to `int` or `float`, leave them as `str`
# - Quoting: none
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcję `loads()`, która deserializuje list[Sequence]:
# - Argument: `data: str`
# - Zwraca: `list[tuple]`
# 2. Zdefiniuj `result: list[tuple]` z wynikiem funkcji `dumps()` dla `DATA`
# 3. Wymagania niefunkcjonalne:
# - Nie używaj `import` ani żadnych modułów
# - Nie konwertuj liczb do `int` lub `float`, pozostaw je jako `str`
# - Quoting: żadne
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> result
# [('firstname', 'lastname', 'age'),
# ('Alice', 'Apricot', '30'),
# ('Bob', 'Banana', '31'),
# ('Carol', 'Corn', '32'),
# ('Dave', 'Durian', '33'),
# ('Eve', 'Elderberry', '34'),
# ('Mallory', 'Melon', '15')]
# %% Hints
# - `tuple()`
# - `str.split()`
# - `[x for x in data]`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 12), \
'Python 3.12+ required'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert all(type(x) is tuple for x in result), \
'All rows in `result` should be tuple'
>>> from pprint import pprint
>>> pprint(result, sort_dicts=False, width=79)
[('firstname', 'lastname', 'age'),
('Alice', 'Apricot', '30'),
('Bob', 'Banana', '31'),
('Carol', 'Corn', '32'),
('Dave', 'Durian', '33'),
('Eve', 'Elderberry', '34'),
('Mallory', 'Melon', '15')]
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
type data = list[tuple[str,...]]
loads: Callable[[str,...], data]
result: data
# %% Data
DATA = 'firstname,lastname,age;Alice,Apricot,30;Bob,Banana,31;Carol,Corn,32;Dave,Durian,33;Eve,Elderberry,34;Mallory,Melon,15'
# %% Result
result = ...
# %% About
# - Name: Serialization Loads ListMapping
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `loads()`, which deserialize list[Mapping]:
# - Argument: `data: str`
# - Returns: `list[dict]`
# 2. Define `result: list[dict]` with result of `dumps()` function for `DATA`
# 3. Non-functional requirements:
# - Do not use `import` and any module
# - Do not convert numbers to `int` or `float`, leave them as `str`
# - Quoting: none
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcję `loads()`, która deserializuje list[Mapping]:
# - Argument: `data: str`
# - Zwraca: `list[dict]`
# 2. Zdefiniuj `result: list[dict]` z wynikiem funkcji `dumps()` dla `DATA`
# 3. Wymagania niefunkcjonalne:
# - Nie używaj `import` ani żadnych modułów
# - Nie konwertuj liczb do `int` lub `float`, pozostaw je jako `str`
# - Quoting: żadne
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> result
# [{'age': '30', 'firstname': 'Alice', 'lastname': 'Apricot'},
# {'age': '31', 'firstname': 'Bob', 'lastname': 'Banana'},
# {'age': '32', 'firstname': 'Carol', 'lastname': 'Corn'},
# {'age': '33', 'firstname': 'Dave', 'lastname': 'Durian'},
# {'age': '34', 'firstname': 'Eve', 'lastname': 'Elderberry'},
# {'age': '15', 'firstname': 'Mallory', 'lastname': 'Melon'}]
# %% Hints
# - `str.split()`
# - `[x for x in data]`
# - `dict()`
# - `zip()`
# - `first, *others = 1, 2, 3, 4, 5`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 12), \
'Python 3.12+ required'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert all(type(x) is dict for x in result), \
'All rows in `result` should be dict'
>>> from pprint import pprint
>>> pprint(result, sort_dicts=False, width=79)
[{'age': '30', 'firstname': 'Alice', 'lastname': 'Apricot'},
{'age': '31', 'firstname': 'Bob', 'lastname': 'Banana'},
{'age': '32', 'firstname': 'Carol', 'lastname': 'Corn'},
{'age': '33', 'firstname': 'Dave', 'lastname': 'Durian'},
{'age': '34', 'firstname': 'Eve', 'lastname': 'Elderberry'},
{'age': '15', 'firstname': 'Mallory', 'lastname': 'Melon'}]
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
type data = list[dict[str,str]]
loads: Callable[[str,...], data]
result: data
# %% Data
DATA = 'age,firstname,lastname;30,Alice,Apricot;31,Bob,Banana;32,Carol,Corn;33,Dave,Durian;34,Eve,Elderberry;15,Mallory,Melon'
# %% Result
result = ...
# %% About
# - Name: Serialization Loads ListObject
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `loads()`, which deserialize list[object]:
# - Argument: `data: str`
# - Returns: `list[object]`
# 2. Define `result: list[object]` with result of `dumps()` function for `DATA`
# 3. Non-functional requirements:
# - Do not use `import` and any module
# - Do not convert numbers to `int` or `float`, leave them as `str`
# - Quoting: none
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcję `loads()`, która deserializuje list[object]:
# - Argument: `data: str`
# - Zwraca: `list[object]`
# 2. Zdefiniuj `result: list[object]` z wynikiem funkcji `dumps()` dla `DATA`
# 3. Wymagania niefunkcjonalne:
# - Nie używaj `import` ani żadnych modułów
# - Nie konwertuj liczb do `int` lub `float`, pozostaw je jako `str`
# - Quoting: żadne
# - Delimiter: `,`
# - Lineseparator: `;`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> result
# [User(firstname='Alice', lastname='Apricot', age='30'),
# User(firstname='Bob', lastname='Banana', age='31'),
# User(firstname='Carol', lastname='Corn', age='32'),
# User(firstname='Dave', lastname='Durian', age='33'),
# User(firstname='Eve', lastname='Elderberry', age='34'),
# User(firstname='Mallory', lastname='Melon', age='15')]
# %% Hints
# - `[x for x in data]`
# - `tuple()`
# - `str.split()`
# - `dict()`
# - `zip()`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 12), \
'Python 3.12+ required'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert all(type(x) is User for x in result), \
'All rows in `result` should be User'
>>> from pprint import pprint
>>> pprint(result, sort_dicts=False, width=79)
[User(firstname='Alice', lastname='Apricot', age='30'),
User(firstname='Bob', lastname='Banana', age='31'),
User(firstname='Carol', lastname='Corn', age='32'),
User(firstname='Dave', lastname='Durian', age='33'),
User(firstname='Eve', lastname='Elderberry', age='34'),
User(firstname='Mallory', lastname='Melon', age='15')]
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
type data = list[object]
loads: Callable[[str,...], data]
result: data
# %% Data
DATA = 'age,firstname,lastname;30,Alice,Apricot;31,Bob,Banana;32,Carol,Corn;33,Dave,Durian;34,Eve,Elderberry;15,Mallory,Melon'
class User:
def __init__(self, firstname, lastname, age):
self.firstname = firstname
self.lastname = lastname
self.age = age
def __repr__(self):
clsname = self.__class__.__name__
firstname = self.firstname
lastname = self.lastname
age = self.age
return f'{clsname}({firstname=}, {lastname=}, {age=})'
# %% Result
result = ...
# %% About
# - Name: Serialization Loads ListObject
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `load()`, which deserialize list[object] from file:
# - Argument: `file: str`
# - Returns: `data: list[dict]`
# 2. Define `result: data: list[dict]` with result of `dumps()` function for `DATA`
# 3. Non-functional requirements:
# - Do not use `import` and any module
# - Do not convert numbers to `int` or `float`, leave them as `str`
# - Quoting: none
# - Delimiter: `,`
# - Lineseparator: `;`
# - File ends with an empty line
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcję `load()`, która deserializuje list[object] z pliku:
# - Argument: `data: str`
# - Zwraca: `list[object]`
# 2. Zdefiniuj `result: list[object]` z wynikiem funkcji `dumps()` dla `DATA`
# 3. Wymagania niefunkcjonalne:
# - Nie używaj `import` ani żadnych modułów
# - Nie konwertuj liczb do `int` lub `float`, pozostaw je jako `str`
# - Quoting: żadne
# - Delimiter: `,`
# - Lineseparator: `;`
# - Plik kończy się pustą linią
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> result
# [{'age': '30', 'firstname': 'Alice', 'lastname': 'Apricot'},
# {'age': '31', 'firstname': 'Bob', 'lastname': 'Banana'},
# {'age': '32', 'firstname': 'Carol', 'lastname': 'Corn'},
# {'age': '33', 'firstname': 'Dave', 'lastname': 'Durian'},
# {'age': '34', 'firstname': 'Eve', 'lastname': 'Elderberry'},
# {'age': '15', 'firstname': 'Mallory', 'lastname': 'Melon'}]
# %% Hints
# - `[x for x in data]`
# - `tuple()`
# - `str.split()`
# - `dict()`
# - `zip()`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 12), \
'Python 3.12+ required'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert all(type(x) is dict for x in result), \
'All rows in `result` should be dict'
>>> from pprint import pprint
>>> pprint(result, sort_dicts=False, width=79)
[{'age': '30', 'firstname': 'Alice', 'lastname': 'Apricot'},
{'age': '31', 'firstname': 'Bob', 'lastname': 'Banana'},
{'age': '32', 'firstname': 'Carol', 'lastname': 'Corn'},
{'age': '33', 'firstname': 'Dave', 'lastname': 'Durian'},
{'age': '34', 'firstname': 'Eve', 'lastname': 'Elderberry'},
{'age': '15', 'firstname': 'Mallory', 'lastname': 'Melon'}]
>>> from os import remove
>>> remove(FILE)
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
type data = list[object]
loads: Callable[[str,...], data]
result: data
# %% Data
DATA = 'age,firstname,lastname;30,Alice,Apricot;31,Bob,Banana;32,Carol,Corn;33,Dave,Durian;34,Eve,Elderberry;15,Mallory,Melon'
FILE = '_temporary.dat'
with open(FILE, mode='wt', encoding='utf-8') as file:
file.write(DATA)
# %% Result
result = ...