ch15: draft examples

This commit is contained in:
Luciano Ramalho
2021-05-20 22:58:05 -03:00
parent 5312d4f824
commit 1689eec623
19 changed files with 501 additions and 36 deletions

View File

@@ -0,0 +1,32 @@
# tag::BOOKDICT[]
from typing import TypedDict, List
import json
class BookDict(TypedDict):
isbn: str
title: str
authors: List[str]
pagecount: int
# end::BOOKDICT[]
# tag::TOXML[]
AUTHOR_EL = '<AUTHOR>{}</AUTHOR>'
def to_xml(book: BookDict) -> str: # <1>
elements: List[str] = [] # <2>
for key, value in book.items():
if isinstance(value, list): # <3>
elements.extend(
AUTHOR_EL.format(n) for n in value) # <4>
else:
tag = key.upper()
elements.append(f'<{tag}>{value}</{tag}>')
xml = '\n\t'.join(elements)
return f'<BOOK>\n\t{xml}\n</BOOK>'
# end::TOXML[]
# tag::FROMJSON[]
def from_json(data: str) -> BookDict:
whatever: BookDict = json.loads(data) # <1>
return whatever # <2>
# end::FROMJSON[]

View File

@@ -0,0 +1,32 @@
# tag::BOOKDICT[]
from typing import TypedDict, List
import json
class BookDict(TypedDict):
isbn: str
title: str
authors: List[str]
pagecount: int
# end::BOOKDICT[]
# tag::TOXML[]
AUTHOR_EL = '<AUTHOR>{}</AUTHOR>'
def to_xml(book: BookDict) -> str: # <1>
elements: List[str] = [] # <2>
for key, value in book.items():
if isinstance(value, list): # <3>
elements.extend(AUTHOR_EL.format(n)
for n in value)
else:
tag = key.upper()
elements.append(f'<{tag}>{value}</{tag}>')
xml = '\n\t'.join(elements)
return f'<BOOK>\n\t{xml}\n</BOOK>'
# end::TOXML[]
# tag::FROMJSON[]
def from_json(data: str) -> BookDict:
whatever = json.loads(data) # <1>
return whatever # <2>
# end::FROMJSON[]

View File

@@ -0,0 +1,20 @@
from books import BookDict
from typing import TYPE_CHECKING
def demo() -> None: # <1>
book = BookDict( # <2>
isbn='0134757599',
title='Refactoring, 2e',
authors=['Martin Fowler', 'Kent Beck'],
pagecount=478
)
authors = book['authors'] # <3>
if TYPE_CHECKING: # <4>
reveal_type(authors) # <5>
authors = 'Bob' # <6>
book['weight'] = 4.2
del book['title']
if __name__ == '__main__':
demo()

View File

@@ -0,0 +1,23 @@
from books import to_xml, from_json
from typing import TYPE_CHECKING
def demo() -> None:
NOT_BOOK_JSON = """
{"title": "Andromeda Strain",
"flavor": "pistachio",
"authors": true}
"""
not_book = from_json(NOT_BOOK_JSON) # <1>
if TYPE_CHECKING: # <2>
reveal_type(not_book)
reveal_type(not_book['authors'])
print(not_book) # <3>
print(not_book['flavor']) # <4>
xml = to_xml(not_book) # <5>
print(xml) # <6>
if __name__ == '__main__':
demo()

View File

@@ -0,0 +1,112 @@
import json
from typing import cast
from books import BookDict, to_xml, from_json
XML_SAMPLE = """
<BOOK>
\t<ISBN>0134757599</ISBN>
\t<TITLE>Refactoring, 2e</TITLE>
\t<AUTHOR>Martin Fowler</AUTHOR>
\t<AUTHOR>Kent Beck</AUTHOR>
\t<PAGECOUNT>478</PAGECOUNT>
</BOOK>
""".strip()
# using plain dicts
def test_1() -> None:
xml = to_xml({
'isbn': '0134757599',
'title': 'Refactoring, 2e',
'authors': ['Martin Fowler', 'Kent Beck'],
'pagecount': 478,
})
assert xml == XML_SAMPLE
def test_2() -> None:
xml = to_xml(dict(
isbn='0134757599',
title='Refactoring, 2e',
authors=['Martin Fowler', 'Kent Beck'],
pagecount=478))
assert xml == XML_SAMPLE
def test_5() -> None:
book_data: BookDict = dict(
isbn='0134757599',
title='Refactoring, 2e',
authors=['Martin Fowler', 'Kent Beck'],
pagecount=478
)
xml = to_xml(book_data)
assert xml == XML_SAMPLE
def test_6() -> None:
book_data = dict(
isbn='0134757599',
title='Refactoring, 2e',
authors=['Martin Fowler', 'Kent Beck'],
pagecount=478
)
xml = to_xml(cast(BookDict, book_data)) # cast needed
assert xml == XML_SAMPLE
def test_4() -> None:
xml = to_xml(BookDict(
isbn='0134757599',
title='Refactoring, 2e',
authors=['Martin Fowler', 'Kent Beck'],
pagecount=478))
assert xml == XML_SAMPLE
def test_7() -> None:
book_data = BookDict(
isbn='0134757599',
title='Refactoring, 2e',
authors=['Martin Fowler', 'Kent Beck'],
pagecount=478
)
xml = to_xml(book_data)
assert xml == XML_SAMPLE
def test_8() -> None:
book_data: BookDict = {
'isbn': '0134757599',
'title': 'Refactoring, 2e',
'authors': ['Martin Fowler', 'Kent Beck'],
'pagecount': 478,
}
xml = to_xml(book_data)
assert xml == XML_SAMPLE
BOOK_JSON = """
{"isbn": "0134757599",
"title": "Refactoring, 2e",
"authors": ["Martin Fowler", "Kent Beck"],
"pagecount": 478}
"""
def test_load_book_0() -> None:
book_data: BookDict = json.loads(BOOK_JSON) # typed var
xml = to_xml(book_data)
assert xml == XML_SAMPLE
def test_load_book() -> None:
book_data = from_json(BOOK_JSON)
xml = to_xml(book_data)
assert xml == XML_SAMPLE
NOT_BOOK_JSON = """
{"isbn": 3.141592653589793
"title": [1, 2, 3],
"authors": ["Martin Fowler", "Kent Beck"],
"flavor": "strawberry"}
"""
def test_load_not_book() -> None:
book_data: BookDict = json.loads(BOOK_JSON) # typed var
xml = to_xml(book_data)
assert xml == XML_SAMPLE

View File

@@ -0,0 +1,20 @@
from books import BookDict, to_xml
XML_SAMPLE = """
<BOOK>
\t<ISBN>0134757599</ISBN>
\t<TITLE>Refactoring, 2e</TITLE>
\t<AUTHOR>Martin Fowler</AUTHOR>
\t<AUTHOR>Kent Beck</AUTHOR>
\t<PAGECOUNT>478</PAGECOUNT>
</BOOK>
""".strip()
def test_3() -> None:
xml = to_xml(BookDict(dict([ # Expected keyword arguments, {...}, or dict(...) in TypedDict constructor
('isbn', '0134757599'),
('title', 'Refactoring, 2e'),
('authors', ['Martin Fowler', 'Kent Beck']),
('pagecount', 478),
])))
assert xml == XML_SAMPLE