Skip to content

Add metaclasses #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ For information on the training, see the website
1. [Contributing](CONTRIBUTING.md): information on how to contribute to this
repository.
1. docs: directory containing the website for this repository.

## Contributors

* Geert Jan Bex ([[email protected]](mailto:[email protected])),
Hasselt University/University of Leuven
* Mustafa Dikmen, University of Leuven
* correcting typos and pointing out various mistakes
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dependencies:
- jupyterlab
- flake8
- pytest
- python=3.9
- python=3.10
- mypy
- pylint
- matplotlib
Expand Down
Binary file modified python_software_engineering.pptx
Binary file not shown.
3 changes: 3 additions & 0 deletions source-code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ was used to develop it.
`pytest`.
1. `oo_vs_functional.ipynb`: comparing object-oriented approach to
functional approach, including coroutines.
1. `metaclasses`: illustration of the use of metaclasses in Python.
1. `data-structures`: illustration of Python and standard library data
structures.
11 changes: 11 additions & 0 deletions source-code/data-structures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Data structures

Python as well as its standard library have many data structures that help you
write elegant and efficient code. Here you will soe examples.


## What is it?

1. `defaultdict.ipynb`: Jupyter notebook that illustrates the use of
`collections.defaultdict` with a default factory for a Python `list` and
a `dataclasss`.
231 changes: 231 additions & 0 deletions source-code/data-structures/defaultdict.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "2462a390-11a0-4d96-be42-a215460ee554",
"metadata": {},
"source": [
"# Requirements"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "4012d44e-1e7f-488d-bb19-d40466a0b800",
"metadata": {},
"outputs": [],
"source": [
"from collections import defaultdict\n",
"from dataclasses import dataclass"
]
},
{
"cell_type": "markdown",
"id": "62c1100f-d14c-4773-a87d-9b7935d55dcd",
"metadata": {},
"source": [
"# defaultdict"
]
},
{
"cell_type": "markdown",
"id": "771384fa-293a-4f00-94f9-0c5d28f19ed5",
"metadata": {},
"source": [
"The `defaultdict` class is quite convenient since you don't have to test whether a key is already in a dictionary. If it is not, a factory is used to create an initial entry."
]
},
{
"cell_type": "markdown",
"id": "f3951a33-b671-4603-8349-61c1641ae405",
"metadata": {},
"source": [
"## Simple example"
]
},
{
"cell_type": "markdown",
"id": "a2630300-45fd-4d51-8a05-a05bad9ee9d6",
"metadata": {},
"source": [
"Consider a dictionary that has lists as values. If a key is not in the dictionary, it should be initialized with an empty list. The factory function for an empty list is the `list` function."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "67799112-3eb0-4410-b260-5c4646adffa6",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"multiples = defaultdict(list)"
]
},
{
"cell_type": "markdown",
"id": "556ecf15-3003-49f8-aa9b-e9f3998f2855",
"metadata": {},
"source": [
"Now we can add data to the dictionary, for each integer between 0 and 20, we check whether the number is divisible by 2, 3, 4, or 5, and append it to the list that is the value for the divisor (which is the key)."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "34147d51-a265-46b8-9e22-10b81460c006",
"metadata": {},
"outputs": [],
"source": [
"for number in range(20):\n",
" for divisor in range(2, 6):\n",
" if number % divisor == 0:\n",
" multiples[divisor].append(number)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "d533abb9-7fcc-4ddf-895b-a13a71af138a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"defaultdict(list,\n",
" {2: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18],\n",
" 3: [0, 3, 6, 9, 12, 15, 18],\n",
" 4: [0, 4, 8, 12, 16],\n",
" 5: [0, 5, 10, 15]})"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"multiples"
]
},
{
"cell_type": "markdown",
"id": "4fb29e3d-4264-4030-b933-b101c115d923",
"metadata": {},
"source": [
"## Arbitrary classes"
]
},
{
"cell_type": "markdown",
"id": "667ee4ca-6b2f-4ec0-823e-beef80dbbe93",
"metadata": {},
"source": [
"`defaultdict` also supports arbitrary objects as default values. Consider the following dataclass that represents a person."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "0d049fe8-5b12-4c35-a730-1ddb47db55e8",
"metadata": {},
"outputs": [],
"source": [
"@dataclass\n",
"class Person:\n",
" first_name: str = None\n",
" last_name: str = None\n",
" age: int = None"
]
},
{
"cell_type": "markdown",
"id": "928778d2-6fd8-4662-bb31-857e3a87f2c5",
"metadata": {},
"source": [
"The constructor is the default factory in this case."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "1eec5ce6-3d7e-4e64-abd1-86f5f92e1446",
"metadata": {},
"outputs": [],
"source": [
"people = defaultdict(Person)"
]
},
{
"cell_type": "markdown",
"id": "aa0d20b2-ef70-487f-8637-cc6060355c1f",
"metadata": {},
"source": [
"When a new person turns up, a default `Person` is constructed with `None` for each attribute, and one of the attributes, `first_name` is assigned to below."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6732bd91-c726-4603-b4c4-7c70fc5eae7d",
"metadata": {},
"outputs": [],
"source": [
"people['gjb'].first_name = 'Geert Jan'"
]
},
{
"cell_type": "markdown",
"id": "63b5c683-0a51-45e1-9d65-c9527e75136d",
"metadata": {},
"source": [
"The dictionary indeed contains a single entry, a `Person` with `first_name` initialized, and `liast_name` and `age` attributes still set to `None`."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c510d857-6796-48c4-a181-9ce58828cc2f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"defaultdict(__main__.Person,\n",
" {'gjb': Person(first_name='Geert Jan', last_name=None, age=None)})"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"people"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.5"
},
"toc-autonumbering": true
},
"nbformat": 4,
"nbformat_minor": 5
}
2 changes: 2 additions & 0 deletions source-code/design-patters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ Code to illustrate some design patterns in Python.
can be used to change the behaviour of objects.
1. `factory_design_pattern.ipynb`: notebook illustrating how a factory class
can be used to conveniently construct many objects with the same properties.
* `finite-state-parser`: illustration of object-oriented data
representation and the state pattern.
2 changes: 2 additions & 0 deletions source-code/functional-programming/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ Some examples of a functional programming style in Python.
## What is it?
1. `functional_programming_style.ipynb`: notebook explaining a functional
programming style in Python with examples.
1. `sieve_of_eratosthenes.ipynb`: a lazy implementation of the sieve of
Eratosthenes using generators.
Loading