Skip to content

Commit 3dd60c1

Browse files
authored
Merge pull request #4 from gjbex/development
Various additions
2 parents c3bf5a1 + dbd2983 commit 3dd60c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+4896
-158
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,6 @@ venv.bak/
108108
*.swp
109109
*.bak
110110
~$python_software_engineering.pptx
111+
112+
# direnv configuration file
113+
.envrc

environment.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ name: python_software_engineering
22
channels:
33
- defaults
44
dependencies:
5-
- flake8
5+
- pyparsing
66
- jupyterlab
7-
- matplotlib
7+
- flake8
8+
- pytest
9+
- python=3.9
810
- mypy
911
- pylint
10-
- pyparsing
11-
- pytest
12-
- python=3.7.10
12+
- matplotlib
13+
prefix: /home/gjb/miniconda3/envs/python_software_engineering

python_software_engineering.pptx

205 KB
Binary file not shown.

python_software_engineering_linux64_conda_specs.txt

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ https://repo.anaconda.com/pkgs/main/linux-64/intel-openmp-2021.2.0-h06a4308_610.
99
https://repo.anaconda.com/pkgs/main/linux-64/ld_impl_linux-64-2.33.1-h53a641e_7.conda
1010
https://repo.anaconda.com/pkgs/main/linux-64/libstdcxx-ng-9.1.0-hdf63c60_0.conda
1111
https://repo.anaconda.com/pkgs/main/linux-64/pandoc-2.12-h06a4308_0.conda
12+
https://repo.anaconda.com/pkgs/main/noarch/tzdata-2020f-h52ac0ba_0.conda
1213
https://repo.anaconda.com/pkgs/main/linux-64/libgcc-ng-9.1.0-hdf63c60_0.conda
1314
https://repo.anaconda.com/pkgs/main/linux-64/mkl-2021.2.0-h06a4308_296.conda
1415
https://repo.anaconda.com/pkgs/main/linux-64/expat-2.3.0-h2531618_2.conda
@@ -39,110 +40,110 @@ https://repo.anaconda.com/pkgs/main/linux-64/sqlite-3.35.4-hdfb4753_0.conda
3940
https://repo.anaconda.com/pkgs/main/linux-64/fontconfig-2.13.1-h6c09931_0.conda
4041
https://repo.anaconda.com/pkgs/main/linux-64/gst-plugins-base-1.14.0-h8213a91_2.conda
4142
https://repo.anaconda.com/pkgs/main/linux-64/lcms2-2.12-h3be6417_0.conda
42-
https://repo.anaconda.com/pkgs/main/linux-64/python-3.7.10-hdb3f193_0.conda
43-
https://repo.anaconda.com/pkgs/main/linux-64/async_generator-1.10-py37h28b3542_0.conda
43+
https://repo.anaconda.com/pkgs/main/linux-64/python-3.9.5-hdb3f193_3.conda
44+
https://repo.anaconda.com/pkgs/main/noarch/async_generator-1.10-pyhd3eb1b0_0.tar.bz2
4445
https://repo.anaconda.com/pkgs/main/noarch/attrs-20.3.0-pyhd3eb1b0_0.conda
4546
https://repo.anaconda.com/pkgs/main/noarch/backcall-0.2.0-pyhd3eb1b0_0.tar.bz2
46-
https://repo.anaconda.com/pkgs/main/linux-64/certifi-2020.12.5-py37h06a4308_0.conda
47-
https://repo.anaconda.com/pkgs/main/linux-64/chardet-4.0.0-py37h06a4308_1003.conda
47+
https://repo.anaconda.com/pkgs/main/linux-64/certifi-2020.12.5-py39h06a4308_0.conda
48+
https://repo.anaconda.com/pkgs/main/linux-64/chardet-4.0.0-py39h06a4308_1003.conda
4849
https://repo.anaconda.com/pkgs/main/noarch/decorator-5.0.6-pyhd3eb1b0_0.conda
4950
https://repo.anaconda.com/pkgs/main/noarch/defusedxml-0.7.1-pyhd3eb1b0_0.conda
50-
https://repo.anaconda.com/pkgs/main/linux-64/entrypoints-0.3-py37_0.conda
51+
https://repo.anaconda.com/pkgs/main/linux-64/entrypoints-0.3-py39h06a4308_0.conda
5152
https://repo.anaconda.com/pkgs/main/noarch/idna-2.10-pyhd3eb1b0_0.tar.bz2
5253
https://repo.anaconda.com/pkgs/main/noarch/iniconfig-1.1.1-pyhd3eb1b0_0.tar.bz2
5354
https://repo.anaconda.com/pkgs/main/noarch/ipython_genutils-0.2.0-pyhd3eb1b0_1.conda
5455
https://repo.anaconda.com/pkgs/main/noarch/json5-0.9.5-py_0.conda
55-
https://repo.anaconda.com/pkgs/main/linux-64/kiwisolver-1.3.1-py37h2531618_0.conda
56-
https://repo.anaconda.com/pkgs/main/linux-64/lazy-object-proxy-1.6.0-py37h27cfd23_0.conda
57-
https://repo.anaconda.com/pkgs/main/linux-64/markupsafe-1.1.1-py37h14c3975_1.conda
58-
https://repo.anaconda.com/pkgs/main/linux-64/mccabe-0.6.1-py37_1.conda
59-
https://repo.anaconda.com/pkgs/main/linux-64/mistune-0.8.4-py37h14c3975_1001.conda
56+
https://repo.anaconda.com/pkgs/main/linux-64/kiwisolver-1.3.1-py39h2531618_0.conda
57+
https://repo.anaconda.com/pkgs/main/linux-64/lazy-object-proxy-1.6.0-py39h27cfd23_0.conda
58+
https://repo.anaconda.com/pkgs/main/linux-64/markupsafe-2.0.1-py39h27cfd23_0.conda
59+
https://repo.anaconda.com/pkgs/main/linux-64/mccabe-0.6.1-py39h06a4308_1.conda
60+
https://repo.anaconda.com/pkgs/main/linux-64/mistune-0.8.4-py39h27cfd23_1000.conda
6061
https://repo.anaconda.com/pkgs/main/noarch/more-itertools-8.7.0-pyhd3eb1b0_0.conda
61-
https://repo.anaconda.com/pkgs/main/linux-64/mypy_extensions-0.4.3-py37_0.conda
62+
https://repo.anaconda.com/pkgs/main/linux-64/mypy_extensions-0.4.1-py39h06a4308_0.conda
6263
https://repo.anaconda.com/pkgs/main/noarch/nest-asyncio-1.5.1-pyhd3eb1b0_0.conda
63-
https://repo.anaconda.com/pkgs/main/linux-64/olefile-0.46-py37_0.conda
64-
https://repo.anaconda.com/pkgs/main/linux-64/pandocfilters-1.4.3-py37h06a4308_1.conda
64+
https://repo.anaconda.com/pkgs/main/noarch/olefile-0.46-py_0.conda
65+
https://repo.anaconda.com/pkgs/main/linux-64/pandocfilters-1.4.3-py39h06a4308_1.conda
6566
https://repo.anaconda.com/pkgs/main/noarch/parso-0.7.0-py_0.conda
6667
https://repo.anaconda.com/pkgs/main/noarch/pickleshare-0.7.5-pyhd3eb1b0_1003.conda
68+
https://repo.anaconda.com/pkgs/main/linux-64/pluggy-0.13.1-py39h06a4308_0.conda
6769
https://repo.anaconda.com/pkgs/main/noarch/prometheus_client-0.10.1-pyhd3eb1b0_0.conda
68-
https://repo.anaconda.com/pkgs/main/linux-64/psutil-5.8.0-py37h27cfd23_1.conda
70+
https://repo.anaconda.com/pkgs/main/linux-64/psutil-5.8.0-py39h27cfd23_1.conda
6971
https://repo.anaconda.com/pkgs/main/noarch/ptyprocess-0.7.0-pyhd3eb1b0_2.conda
7072
https://repo.anaconda.com/pkgs/main/noarch/py-1.10.0-pyhd3eb1b0_0.conda
7173
https://repo.anaconda.com/pkgs/main/noarch/pycodestyle-2.6.0-pyhd3eb1b0_0.tar.bz2
7274
https://repo.anaconda.com/pkgs/main/noarch/pycparser-2.20-py_2.conda
7375
https://repo.anaconda.com/pkgs/main/noarch/pyflakes-2.2.0-pyhd3eb1b0_0.tar.bz2
7476
https://repo.anaconda.com/pkgs/main/noarch/pyparsing-2.4.7-pyhd3eb1b0_0.tar.bz2
75-
https://repo.anaconda.com/pkgs/main/linux-64/pyrsistent-0.17.3-py37h7b6447c_0.conda
76-
https://repo.anaconda.com/pkgs/main/linux-64/pysocks-1.7.1-py37_1.conda
77+
https://repo.anaconda.com/pkgs/main/linux-64/pyrsistent-0.17.3-py39h27cfd23_0.conda
78+
https://repo.anaconda.com/pkgs/main/linux-64/pysocks-1.7.1-py39h06a4308_0.conda
7779
https://repo.anaconda.com/pkgs/main/noarch/pytz-2021.1-pyhd3eb1b0_0.conda
78-
https://repo.anaconda.com/pkgs/main/linux-64/pyzmq-20.0.0-py37h2531618_1.conda
80+
https://repo.anaconda.com/pkgs/main/linux-64/pyzmq-20.0.0-py39h2531618_1.conda
7981
https://repo.anaconda.com/pkgs/main/linux-64/qt-5.9.7-h5867ecd_1.conda
8082
https://repo.anaconda.com/pkgs/main/noarch/send2trash-1.5.0-pyhd3eb1b0_1.conda
81-
https://repo.anaconda.com/pkgs/main/linux-64/sip-4.19.8-py37hf484d3e_0.conda
82-
https://repo.anaconda.com/pkgs/main/linux-64/six-1.15.0-py37h06a4308_0.conda
83-
https://repo.anaconda.com/pkgs/main/linux-64/sniffio-1.2.0-py37h06a4308_1.conda
83+
https://repo.anaconda.com/pkgs/main/linux-64/sip-4.19.13-py39h2531618_0.conda
84+
https://repo.anaconda.com/pkgs/main/linux-64/six-1.15.0-py39h06a4308_0.conda
85+
https://repo.anaconda.com/pkgs/main/linux-64/sniffio-1.2.0-py39h06a4308_1.conda
8486
https://repo.anaconda.com/pkgs/main/noarch/testpath-0.4.4-pyhd3eb1b0_0.tar.bz2
8587
https://repo.anaconda.com/pkgs/main/noarch/toml-0.10.2-pyhd3eb1b0_0.conda
86-
https://repo.anaconda.com/pkgs/main/linux-64/tornado-6.1-py37h27cfd23_0.conda
87-
https://repo.anaconda.com/pkgs/main/linux-64/typed-ast-1.4.2-py37h27cfd23_1.conda
88+
https://repo.anaconda.com/pkgs/main/linux-64/tornado-6.1-py39h27cfd23_0.conda
89+
https://repo.anaconda.com/pkgs/main/linux-64/typed-ast-1.4.2-py39h27cfd23_1.conda
8890
https://repo.anaconda.com/pkgs/main/noarch/typing_extensions-3.7.4.3-pyha847dfd_0.tar.bz2
8991
https://repo.anaconda.com/pkgs/main/noarch/wcwidth-0.2.5-py_0.conda
90-
https://repo.anaconda.com/pkgs/main/linux-64/webencodings-0.5.1-py37_1.conda
92+
https://repo.anaconda.com/pkgs/main/linux-64/webencodings-0.5.1-py39h06a4308_1.conda
9193
https://repo.anaconda.com/pkgs/main/noarch/wheel-0.36.2-pyhd3eb1b0_0.conda
92-
https://repo.anaconda.com/pkgs/main/linux-64/wrapt-1.12.1-py37h7b6447c_1.conda
94+
https://repo.anaconda.com/pkgs/main/linux-64/wrapt-1.12.1-py39he8ac12f_1.conda
9395
https://repo.anaconda.com/pkgs/main/noarch/zipp-3.4.1-pyhd3eb1b0_0.conda
94-
https://repo.anaconda.com/pkgs/main/linux-64/anyio-2.2.0-py37h06a4308_1.conda
96+
https://repo.anaconda.com/pkgs/main/linux-64/anyio-2.2.0-py39h06a4308_1.conda
9597
https://repo.anaconda.com/pkgs/main/noarch/babel-2.9.0-pyhd3eb1b0_0.conda
96-
https://repo.anaconda.com/pkgs/main/linux-64/cffi-1.14.5-py37h261ae71_0.conda
97-
https://repo.anaconda.com/pkgs/main/linux-64/cycler-0.10.0-py37_0.conda
98-
https://repo.anaconda.com/pkgs/main/linux-64/importlib-metadata-3.10.0-py37h06a4308_0.conda
99-
https://repo.anaconda.com/pkgs/main/linux-64/jedi-0.17.2-py37h06a4308_1.conda
100-
https://repo.anaconda.com/pkgs/main/linux-64/mkl-service-2.3.0-py37h27cfd23_1.conda
101-
https://repo.anaconda.com/pkgs/main/noarch/mypy-0.812-pyhd3eb1b0_0.conda
98+
https://repo.anaconda.com/pkgs/main/linux-64/cffi-1.14.5-py39h261ae71_0.conda
99+
https://repo.anaconda.com/pkgs/main/linux-64/cycler-0.10.0-py39h06a4308_0.conda
100+
https://repo.anaconda.com/pkgs/main/linux-64/importlib-metadata-3.10.0-py39h06a4308_0.conda
101+
https://repo.anaconda.com/pkgs/main/linux-64/jedi-0.17.2-py39h06a4308_1.conda
102+
https://repo.anaconda.com/pkgs/main/linux-64/mkl-service-2.3.0-py39h27cfd23_1.conda
103+
https://repo.anaconda.com/pkgs/main/noarch/mypy-0.750-py_0.conda
102104
https://repo.anaconda.com/pkgs/main/noarch/packaging-20.9-pyhd3eb1b0_0.conda
103105
https://repo.anaconda.com/pkgs/main/noarch/pexpect-4.8.0-pyhd3eb1b0_3.conda
104-
https://repo.anaconda.com/pkgs/main/linux-64/pillow-8.2.0-py37he98fc37_0.conda
106+
https://repo.anaconda.com/pkgs/main/linux-64/pillow-8.2.0-py39he98fc37_0.conda
105107
https://repo.anaconda.com/pkgs/main/noarch/prompt-toolkit-3.0.17-pyh06a4308_0.conda
106-
https://repo.anaconda.com/pkgs/main/linux-64/pyqt-5.9.2-py37h05f1152_2.conda
108+
https://repo.anaconda.com/pkgs/main/linux-64/pyqt-5.9.2-py39h2531618_6.conda
107109
https://repo.anaconda.com/pkgs/main/noarch/python-dateutil-2.8.1-pyhd3eb1b0_0.tar.bz2
108-
https://repo.anaconda.com/pkgs/main/linux-64/setuptools-52.0.0-py37h06a4308_0.conda
109-
https://repo.anaconda.com/pkgs/main/linux-64/terminado-0.9.4-py37h06a4308_0.conda
110+
https://repo.anaconda.com/pkgs/main/linux-64/setuptools-52.0.0-py39h06a4308_0.conda
111+
https://repo.anaconda.com/pkgs/main/linux-64/terminado-0.9.4-py39h06a4308_0.conda
110112
https://repo.anaconda.com/pkgs/main/noarch/traitlets-5.0.5-pyhd3eb1b0_0.tar.bz2
111-
https://repo.anaconda.com/pkgs/main/linux-64/argon2-cffi-20.1.0-py37h27cfd23_1.conda
112-
https://repo.anaconda.com/pkgs/main/linux-64/astroid-2.5-py37h06a4308_1.conda
113+
https://repo.anaconda.com/pkgs/main/linux-64/argon2-cffi-20.1.0-py39h27cfd23_1.conda
114+
https://repo.anaconda.com/pkgs/main/linux-64/astroid-2.5-py39h06a4308_1.conda
113115
https://repo.anaconda.com/pkgs/main/noarch/bleach-3.3.0-pyhd3eb1b0_0.conda
114-
https://repo.anaconda.com/pkgs/main/linux-64/brotlipy-0.7.0-py37h27cfd23_1003.conda
115-
https://repo.anaconda.com/pkgs/main/linux-64/cryptography-3.4.7-py37hd23ed53_0.conda
116+
https://repo.anaconda.com/pkgs/main/linux-64/brotlipy-0.7.0-py39h27cfd23_1003.conda
117+
https://repo.anaconda.com/pkgs/main/linux-64/cryptography-3.4.7-py39hd23ed53_0.conda
116118
https://repo.anaconda.com/pkgs/main/noarch/flake8-3.9.0-pyhd3eb1b0_0.conda
117119
https://repo.anaconda.com/pkgs/main/noarch/importlib_metadata-3.10.0-hd3eb1b0_0.conda
118120
https://repo.anaconda.com/pkgs/main/noarch/isort-5.8.0-pyhd3eb1b0_0.conda
119121
https://repo.anaconda.com/pkgs/main/noarch/jinja2-2.11.3-pyhd3eb1b0_0.conda
120122
https://repo.anaconda.com/pkgs/main/noarch/jupyter-packaging-0.7.12-pyhd3eb1b0_0.conda
121-
https://repo.anaconda.com/pkgs/main/linux-64/jupyter_core-4.7.1-py37h06a4308_0.conda
122-
https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.20.1-py37h7d8b39e_0.conda
123-
https://repo.anaconda.com/pkgs/main/linux-64/pip-21.0.1-py37h06a4308_0.conda
123+
https://repo.anaconda.com/pkgs/main/linux-64/jupyter_core-4.7.1-py39h06a4308_0.conda
124+
https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.20.2-py39hfae3a4d_0.conda
125+
https://repo.anaconda.com/pkgs/main/linux-64/pip-21.1.1-py39h06a4308_0.conda
124126
https://repo.anaconda.com/pkgs/main/noarch/pygments-2.8.1-pyhd3eb1b0_0.conda
125-
https://repo.anaconda.com/pkgs/main/linux-64/ipython-7.22.0-py37hb070fc8_0.conda
127+
https://repo.anaconda.com/pkgs/main/linux-64/pytest-6.2.3-py39h06a4308_2.conda
128+
https://repo.anaconda.com/pkgs/main/linux-64/ipython-7.22.0-py39hb070fc8_0.conda
126129
https://repo.anaconda.com/pkgs/main/noarch/jsonschema-3.2.0-py_2.conda
127130
https://repo.anaconda.com/pkgs/main/noarch/jupyter_client-6.1.12-pyhd3eb1b0_0.conda
128131
https://repo.anaconda.com/pkgs/main/noarch/jupyterlab_pygments-0.1.2-py_0.conda
129-
https://repo.anaconda.com/pkgs/main/linux-64/pluggy-0.13.1-py37h06a4308_0.conda
130-
https://repo.anaconda.com/pkgs/main/linux-64/pylint-2.7.4-py37h06a4308_1.conda
132+
https://repo.anaconda.com/pkgs/main/linux-64/pylint-2.7.4-py39h06a4308_1.conda
131133
https://repo.anaconda.com/pkgs/main/noarch/pyopenssl-20.0.1-pyhd3eb1b0_1.conda
132-
https://repo.anaconda.com/pkgs/main/linux-64/ipykernel-5.3.4-py37h5ca1d4c_0.conda
134+
https://repo.anaconda.com/pkgs/main/linux-64/ipykernel-5.3.4-py39hb070fc8_0.conda
133135
https://repo.anaconda.com/pkgs/main/noarch/nbformat-5.1.3-pyhd3eb1b0_0.conda
134-
https://repo.anaconda.com/pkgs/main/linux-64/pytest-6.2.3-py37h06a4308_2.conda
135136
https://repo.anaconda.com/pkgs/main/noarch/urllib3-1.26.4-pyhd3eb1b0_0.conda
136137
https://repo.anaconda.com/pkgs/main/noarch/nbclient-0.5.3-pyhd3eb1b0_0.conda
137138
https://repo.anaconda.com/pkgs/main/noarch/requests-2.25.1-pyhd3eb1b0_0.conda
138-
https://repo.anaconda.com/pkgs/main/linux-64/nbconvert-6.0.7-py37_0.conda
139-
https://repo.anaconda.com/pkgs/main/linux-64/jupyter_server-1.4.1-py37h06a4308_0.conda
140-
https://repo.anaconda.com/pkgs/main/linux-64/notebook-6.3.0-py37h06a4308_0.conda
139+
https://repo.anaconda.com/pkgs/main/linux-64/nbconvert-6.0.7-py39h06a4308_0.conda
140+
https://repo.anaconda.com/pkgs/main/linux-64/jupyter_server-1.4.1-py39h06a4308_0.conda
141+
https://repo.anaconda.com/pkgs/main/linux-64/notebook-6.4.0-py39h06a4308_0.conda
141142
https://repo.anaconda.com/pkgs/main/noarch/jupyterlab_server-2.4.0-pyhd3eb1b0_0.conda
142143
https://repo.anaconda.com/pkgs/main/noarch/nbclassic-0.2.6-pyhd3eb1b0_0.conda
143144
https://repo.anaconda.com/pkgs/main/noarch/jupyterlab-3.0.14-pyhd3eb1b0_1.conda
144-
https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-3.3.4-py37h06a4308_0.conda
145-
https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-base-3.3.4-py37h62a2d02_0.conda
146-
https://repo.anaconda.com/pkgs/main/linux-64/mkl_fft-1.3.0-py37h42c9631_2.conda
147-
https://repo.anaconda.com/pkgs/main/linux-64/mkl_random-1.2.1-py37ha9443f7_2.conda
148-
https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.20.1-py37h93e21f0_0.conda
145+
https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-3.3.4-py39h06a4308_0.conda
146+
https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-base-3.3.4-py39h62a2d02_0.conda
147+
https://repo.anaconda.com/pkgs/main/linux-64/mkl_fft-1.3.0-py39h42c9631_2.conda
148+
https://repo.anaconda.com/pkgs/main/linux-64/mkl_random-1.2.1-py39ha9443f7_2.conda
149+
https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.20.2-py39h2d18471_0.conda

source-code/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ was used to develop it.
66

77
## What is it?
88

9-
1. `code-testing`: illustrations of using assertions and unit tests.
109
1. `context-manager`: illustrates how to write your own context managers.
1110
1. `coroutines`: illustrates how to write coroutines in Python.
1211
1. `decorators`: illustrates how to write decorators in Python.
@@ -24,5 +23,7 @@ was used to develop it.
2423
1. `pyparsing`: illustration of unit testing on real world code.
2524
1. `typing`: illustrates how to use type annotation in Python, and
2625
demonstrates `mypy`.
27-
1. `unit-testing`: illustrates writing unit tests with `unittest` and
26+
1. `testing`: illustrates writing unit tests with `unittest` and
2827
`pytest`.
28+
1. `oo_vs_functional.ipynb`: comparing object-oriented approach to
29+
functional approach, including coroutines.

source-code/decorators/decorator.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
class NegArgError(Exception):
77
def __init__(self, name, n):
8-
super(NegArgError, self).__init__()
8+
super().__init__()
99
self.message = 'argument {0} for {1} negative'.format(n, name)
1010

1111

1212
class TooLargeArgError(Exception):
1313
def __init__(self, name, n):
14-
super(TooLargeArgError, self).__init__()
14+
super().__init__()
1515
self.message = 'argument {0} for {1} too large'.format(n, name)
1616

1717

@@ -46,8 +46,8 @@ def fact(n):
4646
import sys
4747
for n in [3, 7, 22, -1]:
4848
try:
49-
print('{0}! = {1}'.format(n, fact(n)))
49+
print(f'{n}! = {fact(n)}')
5050
except Exception as error:
51-
sys.stderr.write('### error: {0}\n'.format(error))
52-
print('function name: {0}'.format(fact.__name__))
53-
print('function docs: {0}'.format(fact.__doc__))
51+
print(f'### error: {error.message}', file=sys.stderr)
52+
print(f'function name: {fact.__name__}')
53+
print(f'function docs: {fact.__doc__}')

source-code/decorators/memoize.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
22

3-
from functools import lru_cache
3+
from functools import cache, lru_cache
44

55

66
def memoize(f):
@@ -30,24 +30,32 @@ def fib_lru_cache(n):
3030
return fib_lru_cache(n - 1) + fib_lru_cache(n - 2)
3131

3232

33+
@cache
34+
def fib_cache(n):
35+
if n < 2:
36+
return 1
37+
else:
38+
return fib_cache(n - 1) + fib_cache(n - 2)
39+
40+
3341
def fib(n):
3442
if n < 2:
3543
return 1
3644
else:
3745
return fib(n - 1) + fib(n - 2)
3846

3947

40-
def execute(func, n_max):
48+
def execute(func, n_max, verbose=False):
4149
values = []
4250
start = datetime.now()
4351
for n in range(n_max):
4452
values.append(func(n))
4553
delta = datetime.now() - start
46-
for n in range(n_max):
47-
print('{0}({1}) = {2}'.format(func.__name__, n, values[n]))
48-
delta_time = float(delta.seconds) + 1.0e-6*float(delta.microseconds)
49-
print('{0}: {1:.6f} s'.format(func.__name__, delta_time))
50-
return delta_time
54+
if verbose:
55+
for n in range(n_max):
56+
print('{0}({1}) = {2}'.format(func.__name__, n, values[n]))
57+
return float(delta.seconds) + 1.0e-6*float(delta.microseconds)
58+
5159

5260
if __name__ == '__main__':
5361
from argparse import ArgumentParser
@@ -56,10 +64,9 @@ def execute(func, n_max):
5664
arg_parser = ArgumentParser(description='compare memoized versus '
5765
'non-memooized')
5866
arg_parser.add_argument('n_max', type=int, help='maximum n value')
67+
arg_parser.add_argument('--verbose', action='store_true',
68+
help='display computed values')
5969
options = arg_parser.parse_args()
60-
delta_fib = execute(fib, options.n_max)
61-
delta_fib_memoized = execute(fib_memoized, options.n_max)
62-
delta_fib_lru_cache = execute(fib_lru_cache, options.n_max)
63-
print('non-memoized:\t\t{0:.6f} s'.format(delta_fib))
64-
print('memoized:\t\t{0:.6f} s'.format(delta_fib_memoized))
65-
print('lru_cache:\t\t{0:.6f} s'.format(delta_fib_lru_cache))
70+
for fib_impl in (fib, fib_memoized, fib_cache, fib_lru_cache):
71+
delta_time = execute(fib_impl, options.n_max, options.verbose)
72+
print(f'{fib_impl.__name__:20s}: {delta_time:.6f} s')

0 commit comments

Comments
 (0)