┏╾╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╼┳╾╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╼┓
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ╭╴┆╶╮ ┆
┣╾╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╼╋╾╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╼┫
┆ ╰╴┆╶╯ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┆ ┆ ┆
┗╾╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╼┻╾╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╼┛
This slide if for centering and scaling your terminal appropriately when using
lookatme
. This entire presentation is built to fit this exact scaling. Please ensure that the entire box above is visible without line wrapping. And that this block quote isn’t visible.
The Python source distribution has long maintained the philosophy of “batteries included” – having a rich and versatile standard library which is immediately available, without making the user download separate packages. This gives the Python language a head start in many projects.
HERE: https://docs.python.org/3/library/index.html
string
, re
, …pathlib
, os.path
,
tempfile
, …csv
, json
, html
,
xml
, (toml
), …threading
, multiprocessing
,
concurrent.futures
, …asyncio
, select
,
selectors
, …urllib
, http
,
socketserver
, …optparse
, argparse
, …tkinter
.When? | What? |
---|---|
13:15 - 14:30 | Intro & Acquisition |
14:30 - 14:45 | break |
14:45 - 16:00 | Exploration (& CLI?) |
Let’s use SWAPI, the starwars API!
https://swapi.dev
download_json
(see previous)download_json
(see previous)def download_chain(chain_link, get_result, start):
"""Download all links in a given chain.
:param chain_link: function to determin the next link in
a chain
:type chain_link: Callable[[Any], str]
:param chain_link: function to extract a list of relevant
data from each link
:type chain_link: Callable[[Any], list[T]]
:param start: first link in the chain
:type start: str
:return: list of all results in a chain
:rtype: list[T]
"""
concurrent.futures
(docs)** ⚠ This is – a lot – more difficult! **
╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴
GIL: The Global Interpreter Lock
Only one thread per process can use the python interpreter at a time!
Threads in python are good at doing literally nothing, i.e. blocking I/O.
╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴
╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴
Mutable default arguments do not “reset” after a call.
Most common fix:
╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴
▄▄▄▄▄▄▄ ▄▄ ▄ ▄▄▄▄▄ ▄▄▄▄▄▄▄
█ ▄▄▄ █ ▄ ▄▄█▄ ▀█ ▄ █ ▄▄▄ █
█ ███ █ ██▄█ █ █▀▀▀█ █ ███ █
█▄▄▄▄▄█ ▄▀▄ █▀▄ ▄▀█▀█ █▄▄▄▄▄█
▄▄▄▄ ▄ ▄▀ ▀ ▄▄▀▀███▀▄ ▄▄▄ ▄
▄▄█▄█▀▄▀▄▀ ▄▀ █ ▄▀█ ███ ▄▄▀
█▄█▀▄▄▀ ▄ █▀██▄█▄▀▄▀▀▀▀▀▄▄ ▀
█▀▄▀██▄ ▀▄█▀▄ █ █▀ ██▄▀█▄ ███
█▀▄██ ▄ ▀ ▄▄▀ ▀▀▀ ▄ █▄▀▀█▄ █
▄▀▀▄▀ ▄▀██▄▄█ ▀█▄ ▀ ▀▀ █ ▀█▀
▄▀█▀▀▄▄▄▄▄▄█ █▄▀█▄███▄▄▄▄█
▄▄▄▄▄▄▄ ▀██▄█▄▄ ▀▄█ ▄ ██▀█▀
█ ▄▄▄ █ ▀▄ ▄▀██▄▄▀ █▄▄▄█▀▄█▄
█ ███ █ █ ▄█▀▄ ▀▀ ▀▀█ ▄▀▀▄ █
█▄▄▄▄▄█ █ ▀ █▄█ ▀██ ▀ █ █
max
(docs)def longest_vehicle(data):
"""Get longest vehicle per class.
:param data: Starwars dataset
:return: Vehicles counts per class.
:rtype: Vehicle
"""
⚠ Types are just to emphasize the exercise!
╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴
List-Comprehensions create an entirely new list, i.e. they materialize all results immediately.
This can and will lead to problems in big data sets!
Consider the use of Generator(-Comprehension)s for big data sets!
They produce values one after another, considerably shrinking the memory footprint.
╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴✄╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴
collections
(docs)def vehicles_by_class(data):
"""Get all vehicles grouped by their classes.
:param data: Starwars dataset
:return: Grouped vehicles
:rtype: dict[VehicleClass, list[Vehicle]]
"""
⚠ Types are just to emphasize the exercise!
collections
(docs)def longest_vehicle_per_class(data):
"""Get biggest vehicle per class.
:param data: Starwars dataset
:return: Vehicles counts per class.
:rtype: dict[VehicleClass, Vehicle]
"""
⚠ Types are just to emphasize the exercise!
collections
(docs)def vehicles_per_class(data):
"""Count vehicles by their class.
:param data: Starwars dataset
:return: Vehicles counts per class.
:rtype: dict[VehicleClass, int]
"""
⚠ Types are just to emphasize the exercise!
Episode ⟨𝘌𝘗𝘐𝘚𝘖𝘋𝘌#⟩: ⟨𝘛𝘐𝘛𝘓𝘌⟩
def vehicles_by_film(data):
"""Get all characters by film.
:param data: Starwars dataset
:return: Vehicles grouped by films.
:rtype: dict[str, list[Vehicle]]
"""
⚠ Types are just to emphasize the exercise!
vehicles_by_film
(see previous)collections
(docs)def by_film(data, film_field, data_field):
"""Group things by film.
:param data: Starwars dataset
:param film_field: Name of "relation" field on a film.
:type film_field: str
:param data_field: Name of "data" field in dataset.
:type data_field: str
:return: Things grouped by films.
:rtype: dict[str, list[Thing]]
"""
⚠ Types are just to emphasize the exercise!
def by_film(data, film_field, data_field=None):
data_field = data_field or film_field
res = defaultdict(list)
for film_id, film in data["films"].items():
episode = (int(film_id) + 2) % 6 + 1
key = f"Episode {episode}: {film['title']}"
for vehicle_id in film[film_field]:
res[key].append(data[data_field][vehicle_id])
return res
def uniqueness_per_film(data, film_field, data_field):
"""Get the uniqueness a things in a film by films.
:param data: Starwars dataset
:param film_field: Name of "relation" field on a film.
:type film_field: str
:param data_field: Name of "data" field in dataset.
:type data_field: str
:return: Uniqueness or things by films.
:rtype: dict[str, list[Thing]]
"""
⚠ Types are just to emphasize the exercise!
def uniquest_film(data):
inidivdual_uniquenesses = [
uniqueness_per_film(data, "vehicles"),
uniqueness_per_film(data, "starships"),
uniqueness_per_film(data, "planets"),
uniqueness_per_film(data, "species"),
uniqueness_per_film(data, "characters", "people"),
]
res = inidivdual_uniquenesses[0]
for uniquenesses in inidivdual_uniquenesses[1:]:
for key, value in uniquenesses.items():
res[key] += value
return max(
res.keys(),
key=res.__getitem__
)