├── .nojekyll ├── content ├── examples │ ├── array │ ├── languages.csv │ ├── numpy_file.npy │ ├── ex_18_numpy_example.ipynb │ ├── ex_13_chain_map.ipynb │ ├── ex_07_set_comprehensions.ipynb │ ├── ex_19_numpy_example_timed.ipynb │ ├── ex_08_generators.ipynb │ ├── ex_11_ordered_dict.ipynb │ ├── ex_10_namedtuple.ipynb │ ├── ex_06_dict_comprehensions.ipynb │ ├── ex_14_deque.ipynb │ ├── ex_15_counter.ipynb │ ├── ex_12_default_dict.ipynb │ ├── ex_02_tuple.ipynb │ ├── ex_05_list_comprehensions.ipynb │ ├── ex_09_array.ipynb │ ├── ex_16_custom_classes.ipynb │ └── ex_03_dict.ipynb └── project │ ├── data │ ├── Survey-2024-May.csv │ ├── Survey-2024-Jul.csv │ ├── Survey-2024-Jan.csv │ ├── Survey-data.csv │ └── Survey-2024-Mar.csv │ ├── survey_analysis.ipynb │ └── sample_solutions │ ├── proj_3_collections.ipynb │ ├── proj_1_builtin.ipynb │ └── proj_2_comprehensions.ipynb ├── repl └── jupyter-lite.json ├── requirements.txt ├── README.md ├── .github └── workflows │ └── deploy.yml └── .gitignore /.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /content/examples/array: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ariannedee/python-data-structs/HEAD/content/examples/array -------------------------------------------------------------------------------- /content/examples/languages.csv: -------------------------------------------------------------------------------- 1 | Name,Percent used 2 | JavaScript,65.36 3 | HTML/CSS,55.08 4 | SQL,49.43 5 | Python,48.07 -------------------------------------------------------------------------------- /content/examples/numpy_file.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ariannedee/python-data-structs/HEAD/content/examples/numpy_file.npy -------------------------------------------------------------------------------- /repl/jupyter-lite.json: -------------------------------------------------------------------------------- 1 | { 2 | "jupyter-lite-schema-version": 0, 3 | "jupyter-config-data": { 4 | "disabledExtensions": [ 5 | "@jupyterlab/drawio-extension", 6 | "jupyterlab-kernel-spy", 7 | "jupyterlab-tour" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Core modules (mandatory) 2 | jupyterlite-core==0.1.2 3 | jupyterlab~=3.5.1 4 | 5 | # Python kernel (optional) 6 | jupyterlite-pyodide-kernel==0.1.2 7 | 8 | # Language support (optional) 9 | jupyterlab-language-pack-fr-FR 10 | jupyterlab-language-pack-zh-CN 11 | 12 | # JupyterLab: Fasta file renderer (optional) 13 | jupyterlab-fasta>=3,<4 14 | # JupyterLab: dark theme 15 | jupyterlab-night 16 | # JupyterLab: Miami nights theme (optional) 17 | jupyterlab_miami_nights 18 | 19 | numpy 20 | pandas -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Data Structures and Comprehensions 2 | 3 | This is the code for the **O'Reilly Live Training**, presented by **Arianne Dee**. 4 | 5 | ## Run the code in your browser 6 | 7 | ▶️ **https://ariannedee.github.io/python-data-structs/lab/index.html** 8 | 9 | ### Acknowledgments 10 | 11 | This site is run by [JupyterLite](https://jupyterlite.readthedocs.io/) 12 | 13 | JupyterLite is being tested against modern web browsers: 14 | 15 | - Firefox 90+ 16 | - Chromium 89+ 17 | 18 | If you have any questions, please send an email to **arianne.dee.studios** at gmail dot com. 19 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v3 17 | - name: Setup Python 18 | uses: actions/setup-python@v4 19 | with: 20 | python-version: '3.10' 21 | - name: Install the dependencies 22 | run: | 23 | python -m pip install -r requirements.txt 24 | - name: Build the JupyterLite site 25 | run: | 26 | cp README.md content 27 | jupyter lite build --contents content --output-dir dist 28 | - name: Upload artifact 29 | uses: actions/upload-pages-artifact@v1 30 | with: 31 | path: ./dist 32 | 33 | deploy: 34 | needs: build 35 | if: github.ref == 'refs/heads/main' 36 | permissions: 37 | pages: write 38 | id-token: write 39 | 40 | environment: 41 | name: github-pages 42 | url: ${{ steps.deployment.outputs.page_url }} 43 | 44 | runs-on: ubuntu-latest 45 | steps: 46 | - name: Deploy to GitHub Pages 47 | id: deployment 48 | uses: actions/deploy-pages@v1 49 | -------------------------------------------------------------------------------- /content/project/data/Survey-2024-May.csv: -------------------------------------------------------------------------------- 1 | "Timestamp","What programming languages do you have experience in?","How many years have you been programming?" 2 | "2024/05/14 5:22:21 am GMT-6","Python;SQL","1 - 5" 3 | "2024/05/17 10:13:04 am GMT-6","Python;C++","1 - 5" 4 | "2024/05/19 11:55:24 pm GMT-6","Python;SQL;C++;R;Matlab","1 - 5" 5 | "2024/05/21 9:57:33 am GMT-6","Python;Java","1 - 5" 6 | "2024/05/21 10:01:48 am GMT-6","Python;SQL;Perl","15 - 20" 7 | "2024/05/21 10:15:30 am GMT-6","Python","< 1" 8 | "2024/05/21 10:20:01 am GMT-6","Java","5 - 10" 9 | "2024/05/21 10:20:11 am GMT-6","SQL","< 1" 10 | "2024/05/21 10:20:47 am GMT-6","Python;Java;C;C++;Go;Cobol","> 20" 11 | "2024/05/21 10:21:19 am GMT-6","JavaScript","< 1" 12 | "2024/05/21 10:21:52 am GMT-6","Python","< 1" 13 | "2024/05/21 10:21:56 am GMT-6","Python;Java;SQL;C;R","1 - 5" 14 | "2024/05/21 10:22:01 am GMT-6","Python;Java;JavaScript;TypeScript;PHP;SQL;C;C++;C#;R;Go;Objective-C;Swift;Perl;Cobol;Assembly;Kotlin","10 - 15" 15 | "2024/05/21 10:22:01 am GMT-6","Python;Java;JavaScript;PHP;SQL;C;C++;Cobol","5 - 10" 16 | "2024/05/21 10:22:09 am GMT-6","Python;Java;JavaScript;TypeScript;SQL","10 - 15" 17 | "2024/05/21 10:22:42 am GMT-6","Python","1 - 5" 18 | "2024/05/21 10:23:00 am GMT-6","Python;SQL","< 1" 19 | "2024/05/21 10:31:44 am GMT-6","Python;SQL","< 1" 20 | "2024/05/21 11:22:40 am GMT-6","Python","< 1" -------------------------------------------------------------------------------- /content/project/data/Survey-2024-Jul.csv: -------------------------------------------------------------------------------- 1 | "Timestamp","What programming languages do you have experience in?","How many years have you been programming?" 2 | "2024/06/28 2:57:21 pm GMT-6","Python;Java;JavaScript;SQL;C;Ruby;R;Objective-C","15 - 20" 3 | "2024/06/30 8:29:25 pm GMT-6","Python;JavaScript;SQL;R;Visual Basic","1 - 5" 4 | "2024/07/02 9:47:15 am GMT-6","Python;JavaScript;C;C++;Matlab","1 - 5" 5 | "2024/07/02 10:05:35 am GMT-6","Python","1 - 5" 6 | "2024/07/02 10:05:37 am GMT-6","Java","1 - 5" 7 | "2024/07/02 10:05:41 am GMT-6","Python;SQL","15 - 20" 8 | "2024/07/02 10:05:54 am GMT-6","Python;Java;Go;Perl;Elixir","> 20" 9 | "2024/07/02 10:06:02 am GMT-6","Python;Matlab;Perl;Lisp;Assembly","> 20" 10 | "2024/07/02 10:06:10 am GMT-6","Python;JavaScript;PHP;SQL;Go","5 - 10" 11 | "2024/07/02 10:06:13 am GMT-6","Python;Java;JavaScript;TypeScript","10 - 15" 12 | "2024/07/02 10:06:19 am GMT-6","Python","1 - 5" 13 | "2024/07/02 10:07:04 am GMT-6","Python;C;C++;Matlab","1 - 5" 14 | "2024/07/02 10:08:00 am GMT-6","Python;Java;JavaScript;C;C++;Ruby;R;Go;Perl;Fortran;Lisp;Assembly;Lua;Haskell;Pascal","> 20" 15 | "2024/07/02 10:08:53 am GMT-6","Python;Java;C++;C#;Go;Perl;Fortran;Assembly;Scala","10 - 15" 16 | "2024/07/02 10:12:08 am GMT-6","Python;Java;SQL;C;C++;C#;Visual Basic;Fortran;Lisp;Pascal","> 20" 17 | "2024/07/02 10:12:40 am GMT-6","SQL;Cobol","15 - 20" 18 | "2024/07/02 10:22:28 am GMT-6","Python;SQL;R","< 1" 19 | "2024/07/02 10:22:44 am GMT-6","Python;Java;C;Lua","< 1" 20 | "2024/07/02 11:28:53 am GMT-6","SQL","10 - 15" 21 | "2024/07/02 11:29:10 am GMT-6","JavaScript","1 - 5" 22 | "2024/07/02 11:29:50 am GMT-6","Python;Java","1 - 5" 23 | "2024/07/02 11:31:47 am GMT-6","Python;Java;JavaScript;SQL;C","1 - 5" -------------------------------------------------------------------------------- /content/project/data/Survey-2024-Jan.csv: -------------------------------------------------------------------------------- 1 | "Timestamp","What programming languages do you have experience in?","How many years have you been programming?" 2 | "2024/01/30 8:40:43 am GMT-8","Python;SQL","1 - 5" 3 | "2024/01/30 8:45:28 am GMT-8","Python","5 - 10" 4 | "2024/01/30 9:02:42 am GMT-8","Python","1 - 5" 5 | "2024/01/30 9:02:59 am GMT-8","Java;JavaScript;SQL;C;C++;Visual Basic;Perl;Cobol;Fortran;Assembly;Pascal","> 20" 6 | "2024/01/30 9:03:28 am GMT-8","Python;Perl","> 20" 7 | "2024/01/30 9:03:35 am GMT-8","JavaScript;TypeScript;PHP;SQL;C++;Visual Basic;Perl","> 20" 8 | "2024/01/30 9:03:37 am GMT-8","Python;Java;C++;Perl","1 - 5" 9 | "2024/01/30 9:03:49 am GMT-8","Python;Java;JavaScript;TypeScript;PHP;SQL;Ruby;R;Objective-C;Swift;Perl;Kotlin;Dart","> 20" 10 | "2024/01/30 9:06:50 am GMT-8","Python;Java;JavaScript;SQL;C;C++;Matlab;Visual Basic;Cobol;Fortran;Assembly","> 20" 11 | "2024/01/30 9:10:51 am GMT-8","Java;JavaScript","15 - 20" 12 | "2024/01/30 9:14:33 am GMT-8","Python;Java;JavaScript;SQL;C;C++","15 - 20" 13 | "2024/01/30 9:26:37 am GMT-8","Python;SQL;C;R","1 - 5" 14 | "2024/01/30 9:26:50 am GMT-8","Java;C++","15 - 20" 15 | "2024/01/30 9:27:18 am GMT-8","SQL;R","1 - 5" 16 | "2024/01/30 9:27:28 am GMT-8","Python;Java","" 17 | "2024/01/30 9:27:44 am GMT-8","Ruby;Fortran;Lisp","5 - 10" 18 | "2024/01/30 9:28:46 am GMT-8","Python;Java;C#;Ruby;Visual Basic;Cobol;Pascal","> 20" 19 | "2024/01/30 9:30:13 am GMT-8","SQL","10 - 15" 20 | "2024/01/30 9:36:15 am GMT-8","Python;Java;JavaScript;C;Rust","10 - 15" 21 | "2024/01/30 10:45:33 am GMT-8","Python;JavaScript;Perl","1 - 5" 22 | "2024/01/30 10:45:55 am GMT-8","Java;SQL;C#","10 - 15" 23 | "2024/01/30 10:46:07 am GMT-8","Python;Java","1 - 5" 24 | "2024/01/30 10:46:24 am GMT-8","Python;JavaScript;SQL;C","1 - 5" 25 | "2024/01/30 10:48:04 am GMT-8","Python;SQL;C;C++","1 - 5" 26 | "2024/01/30 10:48:28 am GMT-8","Python;Java;JavaScript","1 - 5" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bundle.* 2 | lib/ 3 | node_modules/ 4 | .yarn-packages/ 5 | *.egg-info/ 6 | .ipynb_checkpoints 7 | *.tsbuildinfo 8 | 9 | # IDE settings 10 | .idea/ 11 | .vscode/ 12 | 13 | # Created by https://www.gitignore.io/api/python 14 | # Edit at https://www.gitignore.io/?templates=python 15 | 16 | ### Python ### 17 | # Byte-compiled / optimized / DLL files 18 | __pycache__/ 19 | *.py[cod] 20 | *$py.class 21 | 22 | # C extensions 23 | *.so 24 | 25 | # Distribution / packaging 26 | .Python 27 | build/ 28 | develop-eggs/ 29 | dist/ 30 | downloads/ 31 | eggs/ 32 | .eggs/ 33 | lib/ 34 | lib64/ 35 | parts/ 36 | sdist/ 37 | var/ 38 | wheels/ 39 | pip-wheel-metadata/ 40 | share/python-wheels/ 41 | .installed.cfg 42 | *.egg 43 | MANIFEST 44 | 45 | # PyInstaller 46 | # Usually these files are written by a python script from a template 47 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 48 | *.manifest 49 | *.spec 50 | 51 | # Installer logs 52 | pip-log.txt 53 | pip-delete-this-directory.txt 54 | 55 | # Unit test / coverage reports 56 | htmlcov/ 57 | .tox/ 58 | .nox/ 59 | .coverage 60 | .coverage.* 61 | .cache 62 | nosetests.xml 63 | coverage.xml 64 | *.cover 65 | .hypothesis/ 66 | .pytest_cache/ 67 | 68 | # Translations 69 | *.mo 70 | *.pot 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | target/ 80 | 81 | # pyenv 82 | .python-version 83 | 84 | # celery beat schedule file 85 | celerybeat-schedule 86 | 87 | # SageMath parsed files 88 | *.sage.py 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # Mr Developer 98 | .mr.developer.cfg 99 | .project 100 | .pydevproject 101 | 102 | # mkdocs documentation 103 | /site 104 | 105 | # mypy 106 | .mypy_cache/ 107 | .dmypy.json 108 | dmypy.json 109 | 110 | # Pyre type checker 111 | .pyre/ 112 | 113 | # OS X stuff 114 | *.DS_Store 115 | 116 | # End of https://www.gitignore.io/api/python 117 | 118 | # jupyterlite 119 | *.doit.db 120 | _output 121 | -------------------------------------------------------------------------------- /content/examples/ex_18_numpy_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "82cf0ca8-40e6-403e-9cb5-85ef7ac68b26", 6 | "metadata": {}, 7 | "source": [ 8 | "# Curving grades\n", 9 | "\n", 10 | "Example from https://realpython.com/numpy-tutorial/" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "id": "e15a2563-6a6d-4d37-8064-53ef3e338f83", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import numpy as np" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "id": "1060171b-ba8c-49f8-8795-9cef00585f2e", 26 | "metadata": {}, 27 | "source": [ 28 | "Define list of grades" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "id": "d4a1872f", 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "grades = np.array([72, 35, 64, 88, 51, 90, 74, 12])" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "id": "18353a75-ccc0-43a1-9ffb-52c88b7b63d4", 44 | "metadata": {}, 45 | "source": [ 46 | "Curve the grades so the average is 80" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 3, 52 | "id": "03017d26", 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "data": { 57 | "text/plain": [ 58 | "array([ 91.25, 54.25, 83.25, 100. , 70.25, 100. , 93.25, 31.25])" 59 | ] 60 | }, 61 | "execution_count": 3, 62 | "metadata": {}, 63 | "output_type": "execute_result" 64 | } 65 | ], 66 | "source": [ 67 | "CURVE_CENTER = 80\n", 68 | "\n", 69 | "def curve(grades):\n", 70 | " average = grades.mean() # 60.75\n", 71 | " change = CURVE_CENTER - average # 19.25\n", 72 | " new_grades = grades + change # [91.25, 54.25, 83.25, 107.25, 70.25, 109.25, 93.25, 31.25]\n", 73 | " return np.clip(new_grades, grades, 100) # [91.25, 54.25, 83.25, 100.0, 70.25, 100.0, 93.25, 31.25]\n", 74 | "\n", 75 | "curve(grades)" 76 | ] 77 | } 78 | ], 79 | "metadata": { 80 | "jupytext": { 81 | "cell_metadata_filter": "-all", 82 | "main_language": "python", 83 | "notebook_metadata_filter": "-all" 84 | }, 85 | "kernelspec": { 86 | "display_name": "Python 3 (ipykernel)", 87 | "language": "python", 88 | "name": "python3" 89 | }, 90 | "language_info": { 91 | "codemirror_mode": { 92 | "name": "ipython", 93 | "version": 3 94 | }, 95 | "file_extension": ".py", 96 | "mimetype": "text/x-python", 97 | "name": "python", 98 | "nbconvert_exporter": "python", 99 | "pygments_lexer": "ipython3", 100 | "version": "3.11.4" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 5 105 | } 106 | -------------------------------------------------------------------------------- /content/project/data/Survey-data.csv: -------------------------------------------------------------------------------- 1 | "Timestamp","What programming languages do you have experience in?","How many years have you been programming?" 2 | "2024/06/28 2:57:21 pm GMT-6","Python;Java;JavaScript;SQL;C;Ruby;R;Objective-C","15 - 20" 3 | "2024/06/30 8:29:25 pm GMT-6","Python;JavaScript;SQL;R;Visual Basic","1 - 5" 4 | "2024/07/02 9:47:15 am GMT-6","Python;JavaScript;C;C++;Matlab","1 - 5" 5 | "2024/07/02 10:05:35 am GMT-6","Python","1 - 5" 6 | "2024/07/02 10:05:37 am GMT-6","Java","1 - 5" 7 | "2024/07/02 10:05:41 am GMT-6","Python;SQL","15 - 20" 8 | "2024/07/02 10:05:54 am GMT-6","Python;Java;Go;Perl;Elixir","> 20" 9 | "2024/07/02 10:06:02 am GMT-6","Python;Matlab;Perl;Lisp;Assembly","> 20" 10 | "2024/07/02 10:06:10 am GMT-6","Python;JavaScript;PHP;SQL;Go","5 - 10" 11 | "2024/07/02 10:06:13 am GMT-6","Python;Java;JavaScript;TypeScript","10 - 15" 12 | "2024/07/02 10:06:19 am GMT-6","Python","1 - 5" 13 | "2024/07/02 10:07:04 am GMT-6","Python;C;C++;Matlab","1 - 5" 14 | "2024/07/02 10:08:00 am GMT-6","Python;Java;JavaScript;C;C++;Ruby;R;Go;Perl;Fortran;Lisp;Assembly;Lua;Haskell;Pascal","> 20" 15 | "2024/07/02 10:08:53 am GMT-6","Python;Java;C++;C#;Go;Perl;Fortran;Assembly;Scala","10 - 15" 16 | "2024/07/02 10:12:08 am GMT-6","Python;Java;SQL;C;C++;C#;Visual Basic;Fortran;Lisp;Pascal","> 20" 17 | "2024/07/02 10:12:40 am GMT-6","SQL;Cobol","15 - 20" 18 | "2024/07/02 10:22:28 am GMT-6","Python;SQL;R","< 1" 19 | "2024/07/02 10:22:44 am GMT-6","Python;Java;C;Lua","< 1" 20 | "2024/07/02 11:28:53 am GMT-6","SQL","10 - 15" 21 | "2024/07/02 11:29:10 am GMT-6","JavaScript","1 - 5" 22 | "2024/07/02 11:29:50 am GMT-6","Python;Java","1 - 5" 23 | "2024/07/02 11:31:47 am GMT-6","Python;Java;JavaScript;SQL;C","1 - 5" 24 | "2024/07/02 12:09:33 pm GMT-6","Python;Java;JavaScript;SQL;Go","> 20" 25 | "2024/11/06 9:51:24 am GMT-7","","< 1" 26 | "2024/11/06 9:51:29 am GMT-7","Python","< 1" 27 | "2024/11/06 9:59:42 am GMT-7","Python;JavaScript;Ruby;Go","10 - 15" 28 | "2024/11/06 10:02:12 am GMT-7","Python;C;C++;Matlab;Perl;Lisp","10 - 15" 29 | "2024/11/06 10:02:26 am GMT-7","Python","1 - 5" 30 | "2024/11/06 10:02:49 am GMT-7","Python;Java;SQL;C;Cobol","> 20" 31 | "2024/11/06 10:03:01 am GMT-7","Python;Java;TypeScript;C++;R;Perl;Haskell;Pascal","> 20" 32 | "2024/11/06 10:03:25 am GMT-7","Python;Java;JavaScript;SQL","> 20" 33 | "2024/11/06 10:03:44 am GMT-7","Python;Java;JavaScript;TypeScript;PHP;SQL","15 - 20" 34 | "2024/11/06 10:08:58 am GMT-7","Python;Java;SQL","< 1" 35 | "2024/11/06 10:22:57 am GMT-7","Python;Perl","10 - 15" 36 | "2024/11/06 12:25:27 pm GMT-7","SQL","10 - 15" 37 | "2024/11/06 2:04:15 pm GMT-7","Python;Java;JavaScript;PHP;SQL;C++;C#;Ruby;R;Visual Basic","15 - 20" 38 | "2025/02/14 10:18:39 pm GMT-7","Python;PHP;Visual Basic;Delphi;Pascal","10 - 15" 39 | "2025/03/11 4:31:30 am GMT-6","Python;Java;JavaScript;SQL;C;C++","> 20" 40 | "2025/03/11 1:02:59 pm GMT-6","Python;C;Perl","> 20" 41 | "2025/03/11 8:07:20 pm GMT-6","","< 1" 42 | "2025/03/12 8:27:19 am GMT-6","Python;Java;SQL;C;C++","1 - 5" 43 | "2025/03/12 9:05:00 am GMT-6","Python;Java;JavaScript;TypeScript;PHP;SQL;C;C++;C#;Visual Basic;Perl;Fortran;Pascal","> 20" 44 | "2025/03/12 9:20:45 am GMT-6","C;C#","1 - 5" 45 | "2025/03/12 9:50:46 am GMT-6","Python;JavaScript;SQL;C;C++;C#;Pascal","1 - 5" 46 | "2025/03/12 10:26:01 am GMT-6","Python;C;R;Visual Basic;Perl","1 - 5" 47 | "2025/06/05 9:34:29 am GMT-6","Python","1 - 5" 48 | "2025/06/08 8:32:52 am GMT-6","Python;PHP;SQL;C++;Perl","1 - 5" 49 | "2025/06/09 5:45:15 am GMT-6","Python","< 1" 50 | "2025/06/09 11:40:46 am GMT-6","SQL;C;C++","1 - 5" -------------------------------------------------------------------------------- /content/project/data/Survey-2024-Mar.csv: -------------------------------------------------------------------------------- 1 | "Timestamp","What programming languages do you have experience in?","How many years have you been programming?" 2 | "2024/01/30 9:40:43 am GMT-7","Python;SQL","1 - 5" 3 | "2024/01/30 9:45:28 am GMT-7","Python","5 - 10" 4 | "2024/01/30 10:02:42 am GMT-7","Python","1 - 5" 5 | "2024/01/30 10:02:59 am GMT-7","Java;JavaScript;SQL;C;C++;Visual Basic;Perl;Cobol;Fortran;Assembly;Pascal","> 20" 6 | "2024/01/30 10:03:28 am GMT-7","Python;Perl","> 20" 7 | "2024/01/30 10:03:35 am GMT-7","JavaScript;TypeScript;PHP;SQL;C++;Visual Basic;Perl","> 20" 8 | "2024/01/30 10:03:37 am GMT-7","Python;Java;C++;Perl","1 - 5" 9 | "2024/01/30 10:03:49 am GMT-7","Python;Java;JavaScript;TypeScript;PHP;SQL;Ruby;R;Objective-C;Swift;Perl;Kotlin;Dart","> 20" 10 | "2024/01/30 10:06:50 am GMT-7","Python;Java;JavaScript;SQL;C;C++;Matlab;Visual Basic;Cobol;Fortran;Assembly","> 20" 11 | "2024/01/30 10:10:51 am GMT-7","Java;JavaScript","15 - 20" 12 | "2024/01/30 10:14:33 am GMT-7","Python;Java;JavaScript;SQL;C;C++","15 - 20" 13 | "2024/01/30 10:26:37 am GMT-7","Python;SQL;C;R","1 - 5" 14 | "2024/01/30 10:26:50 am GMT-7","Java;C++","15 - 20" 15 | "2024/01/30 10:27:18 am GMT-7","SQL;R","1 - 5" 16 | "2024/01/30 10:27:28 am GMT-7","Python;Java","" 17 | "2024/01/30 10:27:44 am GMT-7","Ruby;Fortran;Lisp","5 - 10" 18 | "2024/01/30 10:28:46 am GMT-7","Python;Java;C#;Ruby;Visual Basic;Cobol;Pascal","> 20" 19 | "2024/01/30 10:30:13 am GMT-7","SQL","10 - 15" 20 | "2024/01/30 10:36:15 am GMT-7","Python;Java;JavaScript;C;Rust","10 - 15" 21 | "2024/01/30 11:45:33 am GMT-7","Python;JavaScript;Perl","1 - 5" 22 | "2024/01/30 11:45:55 am GMT-7","Java;SQL;C#","10 - 15" 23 | "2024/01/30 11:46:07 am GMT-7","Python;Java","1 - 5" 24 | "2024/01/30 11:46:24 am GMT-7","Python;JavaScript;SQL;C","1 - 5" 25 | "2024/01/30 11:48:04 am GMT-7","Python;SQL;C;C++","1 - 5" 26 | "2024/01/30 11:48:28 am GMT-7","Python;Java;JavaScript","1 - 5" 27 | "2024/01/30 12:10:37 pm GMT-7","Python;Java;JavaScript;TypeScript;SQL;C;C++","1 - 5" 28 | "2024/01/30 12:24:02 pm GMT-7","JavaScript;Matlab;Cobol;Fortran;Assembly;Pascal","> 20" 29 | "2024/02/29 8:17:01 pm GMT-7","Python;C","5 - 10" 30 | "2024/03/25 7:35:39 pm GMT-6","Python;JavaScript;C;Perl","15 - 20" 31 | "2024/03/25 8:23:58 pm GMT-6","Python","< 1" 32 | "2024/03/26 3:13:46 am GMT-6","Python;SQL","1 - 5" 33 | "2024/03/26 7:40:45 am GMT-6","Python;Java;JavaScript;SQL;C;C++;Perl;Kotlin;Pascal","> 20" 34 | "2024/03/26 8:37:35 am GMT-6","Python;C","< 1" 35 | "2024/03/26 9:27:38 am GMT-6","C++","10 - 15" 36 | "2024/03/26 10:03:59 am GMT-6","Python;PHP;SQL;Visual Basic","1 - 5" 37 | "2024/03/26 10:04:01 am GMT-6","Python;JavaScript;SQL;R","1 - 5" 38 | "2024/03/26 10:04:02 am GMT-6","Python;Java;JavaScript;TypeScript;SQL;C;R;Perl;Lisp;Haskell","> 20" 39 | "2024/03/26 10:04:10 am GMT-6","Java;SQL;C;C#;Assembly","> 20" 40 | "2024/03/26 10:04:23 am GMT-6","Python;SQL","1 - 5" 41 | "2024/03/26 10:04:32 am GMT-6","Python;SQL;C;C++;Perl","5 - 10" 42 | "2024/03/26 10:04:37 am GMT-6","Python;SQL;C;C++;C#;Visual Basic;Pascal","> 20" 43 | "2024/03/26 10:04:37 am GMT-6","Java","1 - 5" 44 | "2024/03/26 10:04:38 am GMT-6","Python;Java;JavaScript;SQL;C","15 - 20" 45 | "2024/03/26 10:04:48 am GMT-6","Python;JavaScript;SQL","1 - 5" 46 | "2024/03/26 10:04:52 am GMT-6","C;C++","> 20" 47 | "2024/03/26 10:04:55 am GMT-6","Java;SQL","> 20" 48 | "2024/03/26 10:05:05 am GMT-6","Java;Kotlin","10 - 15" 49 | "2024/03/26 10:05:26 am GMT-6","Python;SQL;C++;Perl;Cobol;Pascal","> 20" 50 | "2024/03/26 10:05:32 am GMT-6","Python;SQL;C;C++;C#;Matlab;Pascal","15 - 20" 51 | "2024/03/26 10:05:48 am GMT-6","Python;SQL;Visual Basic","> 20" 52 | "2024/03/26 10:11:25 am GMT-6","Python;C;C++;C#;Matlab;Perl","5 - 10" 53 | "2024/03/26 10:32:14 am GMT-6","Python;PHP;SQL;Visual Basic","1 - 5" 54 | "2024/03/26 10:34:02 am GMT-6","Python;Java;C;C++;Perl","5 - 10" 55 | "2024/03/26 10:35:29 am GMT-6","Java;SQL;C++","10 - 15" -------------------------------------------------------------------------------- /content/project/survey_analysis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "57cb35c4", 6 | "metadata": {}, 7 | "source": [ 8 | "# Survey analysis\n", 9 | "Analyse the results from the [languages survey](https://forms.gle/5b3mZRVcgAsoNG1FA)" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "id": "beb28a4b", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "all_langs = ['Python', 'Java', 'JavaScript', 'TypeScript', 'PHP', 'SQL', 'C', 'C++', 'C#',\n", 20 | " 'Ruby', 'R', 'Matlab', 'Go', 'Rust', 'Objective-C', 'Swift', 'Visual Basic',\n", 21 | " 'Perl', 'Cobol', 'Fortran', 'Lisp', 'Assembly', 'Kotlin', 'Dart', 'Scala',\n", 22 | " 'Lua', 'Delphi', 'Haskell', 'Julia', 'Clojure', 'Elixir', 'Pascal']" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "id": "bcc1c3f1", 28 | "metadata": {}, 29 | "source": [ 30 | "## Load data" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 1, 36 | "id": "44b83567", 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "import csv\n", 41 | "from pprint import pprint\n", 42 | "\n", 43 | "with open('data/Survey-2024-Jul.csv') as file:\n", 44 | " file.readline() # Ignore first line (header)\n", 45 | " reader = csv.DictReader(file, fieldnames=('timestamp', 'languages', 'years')) # list of dicts with keys passed into fieldnames\n", 46 | " for line in reader:\n", 47 | " print(line)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "id": "b7ecbf4b", 53 | "metadata": {}, 54 | "source": [ 55 | "## Find number of languages known\n", 56 | "Print `\"{# known by class} / {# in list} languages known by this class (as %)\"`.\n", 57 | "\n", 58 | "E.g. **12/21 languages known by this class (57%)**" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "id": "535c48b5", 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "id": "8854f96e", 72 | "metadata": {}, 73 | "source": [ 74 | "## List languages not known by anyone in the class" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "id": "88f7d084", 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "id": "4e6d082d", 88 | "metadata": {}, 89 | "source": [ 90 | "## Rank languages by most commonly known\n", 91 | "Print each language as `\"{position}: {language} ({percent_known}%)\"`, in order from most to least known\n", 92 | "\n", 93 | "e.g. **1: Python (93%)**" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "id": "b4f73f17", 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [] 103 | } 104 | ], 105 | "metadata": { 106 | "jupytext": { 107 | "cell_metadata_filter": "-all", 108 | "formats": "auto:light,ipynb", 109 | "main_language": "python", 110 | "notebook_metadata_filter": "-all" 111 | }, 112 | "kernelspec": { 113 | "display_name": "Python 3 (ipykernel)", 114 | "language": "python", 115 | "name": "python3" 116 | }, 117 | "language_info": { 118 | "codemirror_mode": { 119 | "name": "ipython", 120 | "version": 3 121 | }, 122 | "file_extension": ".py", 123 | "mimetype": "text/x-python", 124 | "name": "python", 125 | "nbconvert_exporter": "python", 126 | "pygments_lexer": "ipython3", 127 | "version": "3.11.4" 128 | } 129 | }, 130 | "nbformat": 4, 131 | "nbformat_minor": 5 132 | } 133 | -------------------------------------------------------------------------------- /content/examples/ex_13_chain_map.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "cd41e0da", 6 | "metadata": {}, 7 | "source": [ 8 | "# collections.ChainMap\n", 9 | "Search through multiple dictionaries at once." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "id": "96763fa4", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "from collections import ChainMap" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "id": "58904e3f", 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "dict1 = {\"one\": 1, \"two\": 2, \"three\": 33}\n", 30 | "dict2 = {\"three\": 3, \"four\": 4}" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 3, 36 | "id": "cf08775f", 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "data": { 41 | "text/plain": [ 42 | "ChainMap({'one': 1, 'two': 2, 'three': 33}, {'three': 3, 'four': 4})" 43 | ] 44 | }, 45 | "execution_count": 3, 46 | "metadata": {}, 47 | "output_type": "execute_result" 48 | } 49 | ], 50 | "source": [ 51 | "chain = ChainMap(dict1, dict2)\n", 52 | "chain" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "id": "49d3c3ba", 58 | "metadata": {}, 59 | "source": [ 60 | "## Key lookup\n", 61 | "Searches for keys in order." 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 4, 67 | "id": "b444d662", 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "data": { 72 | "text/plain": [ 73 | "33" 74 | ] 75 | }, 76 | "execution_count": 4, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "chain[\"three\"]" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 5, 88 | "id": "da9ba89c", 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "data": { 93 | "text/plain": [ 94 | "4" 95 | ] 96 | }, 97 | "execution_count": 5, 98 | "metadata": {}, 99 | "output_type": "execute_result" 100 | } 101 | ], 102 | "source": [ 103 | "chain.get(\"four\")" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 6, 109 | "id": "3a7af329", 110 | "metadata": {}, 111 | "outputs": [ 112 | { 113 | "data": { 114 | "text/plain": [ 115 | "'-'" 116 | ] 117 | }, 118 | "execution_count": 6, 119 | "metadata": {}, 120 | "output_type": "execute_result" 121 | } 122 | ], 123 | "source": [ 124 | "chain.get(\"five\", \"-\")" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "id": "cda35a48", 130 | "metadata": {}, 131 | "source": [ 132 | "## Updates\n", 133 | "Updating existing keys affects the first one found." 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 7, 139 | "id": "a70b17a8", 140 | "metadata": {}, 141 | "outputs": [ 142 | { 143 | "data": { 144 | "text/plain": [ 145 | "ChainMap({'one': 1, 'two': 2, 'three': -3}, {'three': 3, 'four': 4})" 146 | ] 147 | }, 148 | "execution_count": 7, 149 | "metadata": {}, 150 | "output_type": "execute_result" 151 | } 152 | ], 153 | "source": [ 154 | "chain[\"three\"] = -3\n", 155 | "chain" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 8, 161 | "id": "cdde2275", 162 | "metadata": {}, 163 | "outputs": [ 164 | { 165 | "data": { 166 | "text/plain": [ 167 | "ChainMap({'one': 1, 'two': 2}, {'three': 3, 'four': 4})" 168 | ] 169 | }, 170 | "execution_count": 8, 171 | "metadata": {}, 172 | "output_type": "execute_result" 173 | } 174 | ], 175 | "source": [ 176 | "del chain[\"three\"]\n", 177 | "chain" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "id": "f55464a0", 183 | "metadata": {}, 184 | "source": [ 185 | "Adding new items adds them to the first `dict`." 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": 9, 191 | "id": "d63be647", 192 | "metadata": {}, 193 | "outputs": [ 194 | { 195 | "data": { 196 | "text/plain": [ 197 | "ChainMap({'one': 1, 'two': 2, 'six': 6}, {'three': 3, 'four': 4})" 198 | ] 199 | }, 200 | "execution_count": 9, 201 | "metadata": {}, 202 | "output_type": "execute_result" 203 | } 204 | ], 205 | "source": [ 206 | "chain[\"six\"] = 6\n", 207 | "chain" 208 | ] 209 | } 210 | ], 211 | "metadata": { 212 | "jupytext": { 213 | "cell_metadata_filter": "-all", 214 | "formats": "auto:light,ipynb", 215 | "main_language": "python", 216 | "notebook_metadata_filter": "-all" 217 | }, 218 | "kernelspec": { 219 | "display_name": "Python 3 (ipykernel)", 220 | "language": "python", 221 | "name": "python3" 222 | }, 223 | "language_info": { 224 | "codemirror_mode": { 225 | "name": "ipython", 226 | "version": 3 227 | }, 228 | "file_extension": ".py", 229 | "mimetype": "text/x-python", 230 | "name": "python", 231 | "nbconvert_exporter": "python", 232 | "pygments_lexer": "ipython3", 233 | "version": "3.11.4" 234 | } 235 | }, 236 | "nbformat": 4, 237 | "nbformat_minor": 5 238 | } 239 | -------------------------------------------------------------------------------- /content/examples/ex_07_set_comprehensions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "440f5c8f", 6 | "metadata": {}, 7 | "source": [ 8 | "# Set Comprehensions\n", 9 | "Just like `dict` comprehensions, but without a value expression (just key).\n", 10 | "\n", 11 | "Or just like `list` comprehensions, but using curly braces `{}`.\n", 12 | "## Basic comprehensions" 13 | ] 14 | }, 15 | { 16 | "metadata": { 17 | "ExecuteTime": { 18 | "end_time": "2025-08-15T21:20:41.597827Z", 19 | "start_time": "2025-08-15T21:20:41.593589Z" 20 | } 21 | }, 22 | "cell_type": "code", 23 | "source": [ 24 | "num_list = [10, 2, 3, 3, 8]\n", 25 | "num_set = {num ** 2 for num in num_list}\n", 26 | "num_set" 27 | ], 28 | "id": "cc9194176c6d71a8", 29 | "outputs": [ 30 | { 31 | "data": { 32 | "text/plain": [ 33 | "{4, 9, 64, 100}" 34 | ] 35 | }, 36 | "execution_count": 5, 37 | "metadata": {}, 38 | "output_type": "execute_result" 39 | } 40 | ], 41 | "execution_count": 5 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "b782a490", 46 | "metadata": {}, 47 | "source": [ 48 | "## Nested comprehensions\n", 49 | "### Nested set\n", 50 | "Sets can only contain hashable items.\n", 51 | "\n", 52 | "Since sets are mutable, if you want to nest sets, you must make any inner set an immutable `frozenset`." 53 | ] 54 | }, 55 | { 56 | "metadata": { 57 | "ExecuteTime": { 58 | "end_time": "2025-08-15T21:20:41.614284Z", 59 | "start_time": "2025-08-15T21:20:41.611290Z" 60 | } 61 | }, 62 | "cell_type": "code", 63 | "source": [ 64 | "words = ['mom', 'dad', 'add', 'moo']\n", 65 | "num_set = {\n", 66 | " frozenset({char for char in word})\n", 67 | " for word in words\n", 68 | "}\n", 69 | "num_set" 70 | ], 71 | "id": "fcf2dc3f6b67289a", 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "{frozenset({'m', 'o'}), frozenset({'a', 'd'})}" 77 | ] 78 | }, 79 | "execution_count": 6, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | } 83 | ], 84 | "execution_count": 6 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "id": "9117d146", 89 | "metadata": {}, 90 | "source": [ 91 | "### Flattened set" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "id": "1d6802d8", 97 | "metadata": { 98 | "ExecuteTime": { 99 | "end_time": "2025-08-15T21:20:41.631279Z", 100 | "start_time": "2025-08-15T21:20:41.628180Z" 101 | } 102 | }, 103 | "source": [ 104 | "words = ['mom', 'dad', 'ham']\n", 105 | "chars = {char for word in words for char in word}\n", 106 | "chars" 107 | ], 108 | "outputs": [ 109 | { 110 | "data": { 111 | "text/plain": [ 112 | "{'a', 'd', 'h', 'm', 'o'}" 113 | ] 114 | }, 115 | "execution_count": 7, 116 | "metadata": {}, 117 | "output_type": "execute_result" 118 | } 119 | ], 120 | "execution_count": 7 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "id": "0f99d278", 125 | "metadata": {}, 126 | "source": [ 127 | "### As for-loop" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "id": "40c6d4c0", 133 | "metadata": { 134 | "ExecuteTime": { 135 | "end_time": "2025-08-15T21:20:41.640744Z", 136 | "start_time": "2025-08-15T21:20:41.638417Z" 137 | } 138 | }, 139 | "source": [ 140 | "chars = set()\n", 141 | "for word in words:\n", 142 | " for char in word:\n", 143 | " chars.add(char)\n", 144 | "chars" 145 | ], 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "{'a', 'd', 'h', 'm', 'o'}" 151 | ] 152 | }, 153 | "execution_count": 8, 154 | "metadata": {}, 155 | "output_type": "execute_result" 156 | } 157 | ], 158 | "execution_count": 8 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "id": "7c6c11c7", 163 | "metadata": {}, 164 | "source": [ 165 | "## Complex comprehension example" 166 | ] 167 | }, 168 | { 169 | "metadata": { 170 | "ExecuteTime": { 171 | "end_time": "2025-08-15T21:20:41.647823Z", 172 | "start_time": "2025-08-15T21:20:41.645512Z" 173 | } 174 | }, 175 | "cell_type": "code", 176 | "source": [ 177 | "words = ['Mom', 'Dad', 'Ham']\n", 178 | "consonants = {\n", 179 | " char.upper()\n", 180 | " for word in words\n", 181 | " for char in word.lower()\n", 182 | " if char not in 'aeiou'\n", 183 | "}\n", 184 | "consonants" 185 | ], 186 | "id": "ec398a6e3033dcc8", 187 | "outputs": [ 188 | { 189 | "data": { 190 | "text/plain": [ 191 | "{'D', 'H', 'M'}" 192 | ] 193 | }, 194 | "execution_count": 9, 195 | "metadata": {}, 196 | "output_type": "execute_result" 197 | } 198 | ], 199 | "execution_count": 9 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "id": "c2a04f7f", 204 | "metadata": {}, 205 | "source": [ 206 | "### As for-loop" 207 | ] 208 | }, 209 | { 210 | "metadata": { 211 | "ExecuteTime": { 212 | "end_time": "2025-08-15T21:20:41.658175Z", 213 | "start_time": "2025-08-15T21:20:41.655845Z" 214 | } 215 | }, 216 | "cell_type": "code", 217 | "source": [ 218 | "consonants = set()\n", 219 | "for word in words:\n", 220 | " for char in word.lower():\n", 221 | " if char not in 'aeiou':\n", 222 | " consonants.add(char.upper())\n", 223 | "consonants" 224 | ], 225 | "id": "d556e615cf0852ed", 226 | "outputs": [ 227 | { 228 | "data": { 229 | "text/plain": [ 230 | "{'D', 'H', 'M'}" 231 | ] 232 | }, 233 | "execution_count": 10, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | } 237 | ], 238 | "execution_count": 10 239 | } 240 | ], 241 | "metadata": { 242 | "jupytext": { 243 | "cell_metadata_filter": "-all", 244 | "formats": "auto:light,ipynb", 245 | "main_language": "python", 246 | "notebook_metadata_filter": "-all" 247 | }, 248 | "kernelspec": { 249 | "display_name": "Python 3 (ipykernel)", 250 | "language": "python", 251 | "name": "python3" 252 | }, 253 | "language_info": { 254 | "codemirror_mode": { 255 | "name": "ipython", 256 | "version": 3 257 | }, 258 | "file_extension": ".py", 259 | "mimetype": "text/x-python", 260 | "name": "python", 261 | "nbconvert_exporter": "python", 262 | "pygments_lexer": "ipython3", 263 | "version": "3.11.4" 264 | } 265 | }, 266 | "nbformat": 4, 267 | "nbformat_minor": 5 268 | } 269 | -------------------------------------------------------------------------------- /content/examples/ex_19_numpy_example_timed.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "88677cab-e5a3-4dd8-b852-ec1d8c37e9e4", 6 | "metadata": {}, 7 | "source": [ 8 | "# Compare grades curving\n", 9 | "Compare NumPy ndarrays and Python lists/loops" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 11, 15 | "id": "3868584e-8e61-403f-8856-a372e683c931", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import random\n", 20 | "import time\n", 21 | "import numpy as np" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "id": "ac35ed0b", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "CURVE_CENTER = 80" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "id": "86649951-4edb-4a3d-8263-2196bd315810", 37 | "metadata": {}, 38 | "source": [ 39 | "`timer()` is a decorator to log function execution times\n", 40 | "\n", 41 | "See Practical Decorators PyCon 2019 talk by Reuven M. Lerner to learn about decorators\n", 42 | "https://youtu.be/MjHpMCIvwsY?t=405" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 3, 48 | "id": "eb9d3c30", 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "def timer(func):\n", 53 | " def inner(*args, **kwargs):\n", 54 | " start = time.time()\n", 55 | " returned = func(*args, **kwargs)\n", 56 | " end = time.time()\n", 57 | " print(f'{func.__name__.upper():<20} {end - start:f}s')\n", 58 | " return returned\n", 59 | " return inner" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "id": "a76a233b-a63a-4321-a48c-3ec6a3cb804f", 65 | "metadata": {}, 66 | "source": [ 67 | "## Numpy functions\n", 68 | "Generate random grades" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 4, 74 | "id": "18aec345", 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "@timer\n", 79 | "def np_grades(num):\n", 80 | " rg = np.random.default_rng(0)\n", 81 | " grades = rg.integers(20, 100, num)\n", 82 | " return grades" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "id": "452d8ab1-1c4c-4f8e-b199-07ae5bd4f413", 88 | "metadata": {}, 89 | "source": [ 90 | "Curve grades" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 5, 96 | "id": "34ed2f83", 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [ 100 | "@timer\n", 101 | "def np_curve(grades):\n", 102 | " average = grades.mean()\n", 103 | " change = CURVE_CENTER - average\n", 104 | " new_grades = grades + change\n", 105 | " return np.clip(new_grades, grades, 100)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "id": "36ae2c40-6183-46ca-9f50-7f98c841c3c9", 111 | "metadata": {}, 112 | "source": [ 113 | "## Looping functions\n", 114 | "Generate random grades" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 6, 120 | "id": "ae160e5e", 121 | "metadata": {}, 122 | "outputs": [], 123 | "source": [ 124 | "@timer\n", 125 | "def loop_grades(num):\n", 126 | " grades = [random.randint(20, 100) for _ in range(num)]\n", 127 | " return grades" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "id": "3a0a2aaf-d41b-4020-9cbc-75f9c6197cb3", 133 | "metadata": {}, 134 | "source": [ 135 | "Curve grades" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 12, 141 | "id": "4f0f93c5", 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "@timer\n", 146 | "def loop_curve(grades):\n", 147 | " average = sum(grades) / len(grades)\n", 148 | " change = CURVE_CENTER - average\n", 149 | " new_grades = [max(min(grade + change, 100), grade) for grade in grades]\n", 150 | " return new_grades" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "id": "a07fa7db-27ef-4a75-9868-b2f1105075d6", 156 | "metadata": {}, 157 | "source": [ 158 | "## Time comparison of numpy vs loops\n", 159 | "Time how long it takes to curve 10 up to 10,000,000 grades" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 13, 165 | "id": "621568fd", 166 | "metadata": {}, 167 | "outputs": [ 168 | { 169 | "name": "stdout", 170 | "output_type": "stream", 171 | "text": [ 172 | "\n", 173 | "--- 100 GRADES ---\n", 174 | "NP_GRADES 0.001391s\n", 175 | "NP_CURVE 0.000297s\n", 176 | "LOOP_GRADES 0.000176s\n", 177 | "LOOP_CURVE 0.000049s\n", 178 | "\n", 179 | "--- 1,000 GRADES ---\n", 180 | "NP_GRADES 0.000141s\n", 181 | "NP_CURVE 0.000080s\n", 182 | "LOOP_GRADES 0.000648s\n", 183 | "LOOP_CURVE 0.000476s\n", 184 | "\n", 185 | "--- 10,000 GRADES ---\n", 186 | "NP_GRADES 0.000220s\n", 187 | "NP_CURVE 0.000557s\n", 188 | "LOOP_GRADES 0.005558s\n", 189 | "LOOP_CURVE 0.004576s\n", 190 | "\n", 191 | "--- 100,000 GRADES ---\n", 192 | "NP_GRADES 0.000693s\n", 193 | "NP_CURVE 0.000768s\n", 194 | "LOOP_GRADES 0.035679s\n", 195 | "LOOP_CURVE 0.017458s\n", 196 | "\n", 197 | "--- 1,000,000 GRADES ---\n", 198 | "NP_GRADES 0.003520s\n", 199 | "NP_CURVE 0.004345s\n", 200 | "LOOP_GRADES 0.224452s\n", 201 | "LOOP_CURVE 0.141708s\n", 202 | "\n", 203 | "--- 10,000,000 GRADES ---\n", 204 | "NP_GRADES 0.028744s\n", 205 | "NP_CURVE 0.058144s\n", 206 | "LOOP_GRADES 2.131262s\n", 207 | "LOOP_CURVE 1.384286s\n" 208 | ] 209 | } 210 | ], 211 | "source": [ 212 | "for num_zeroes in range(2, 8):\n", 213 | " num_grades = 10 ** num_zeroes\n", 214 | " print(f'\\n--- {num_grades:,} GRADES ---')\n", 215 | " \n", 216 | " np_curve(np_grades(num_grades)).tolist() # Curve N grades with NumPy\n", 217 | " loop_curve(loop_grades(num_grades)) # Curve N grades with loops" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": null, 223 | "id": "0a441aae-be08-406c-ba60-cc8242e6e2ee", 224 | "metadata": {}, 225 | "outputs": [], 226 | "source": [] 227 | } 228 | ], 229 | "metadata": { 230 | "jupytext": { 231 | "cell_metadata_filter": "-all", 232 | "main_language": "python", 233 | "notebook_metadata_filter": "-all" 234 | }, 235 | "kernelspec": { 236 | "display_name": "Python 3 (ipykernel)", 237 | "language": "python", 238 | "name": "python3" 239 | }, 240 | "language_info": { 241 | "codemirror_mode": { 242 | "name": "ipython", 243 | "version": 3 244 | }, 245 | "file_extension": ".py", 246 | "mimetype": "text/x-python", 247 | "name": "python", 248 | "nbconvert_exporter": "python", 249 | "pygments_lexer": "ipython3", 250 | "version": "3.11.4" 251 | } 252 | }, 253 | "nbformat": 4, 254 | "nbformat_minor": 5 255 | } 256 | -------------------------------------------------------------------------------- /content/examples/ex_08_generators.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "6856b48d", 6 | "metadata": {}, 7 | "source": [ 8 | "# Generator comprehensions\n", 9 | "If your main purpose is looping over a sequence and you don't need a list object, using a generator will save memory and can be a lot faster to run." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "id": "cc3fe503", 15 | "metadata": { 16 | "ExecuteTime": { 17 | "end_time": "2025-06-11T20:24:16.666367Z", 18 | "start_time": "2025-06-11T20:24:16.663801Z" 19 | } 20 | }, 21 | "source": [ 22 | "squares = (i ** 2 for i in range(10))\n", 23 | "print(squares)" 24 | ], 25 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | " at 0x104562f60>\n" 31 | ] 32 | } 33 | ], 34 | "execution_count": 78 35 | }, 36 | { 37 | "metadata": { 38 | "ExecuteTime": { 39 | "end_time": "2025-06-11T20:24:16.685973Z", 40 | "start_time": "2025-06-11T20:24:16.683275Z" 41 | } 42 | }, 43 | "cell_type": "code", 44 | "source": "next(squares)", 45 | "id": "5fcb217b80b40f79", 46 | "outputs": [ 47 | { 48 | "data": { 49 | "text/plain": [ 50 | "0" 51 | ] 52 | }, 53 | "execution_count": 79, 54 | "metadata": {}, 55 | "output_type": "execute_result" 56 | } 57 | ], 58 | "execution_count": 79 59 | }, 60 | { 61 | "cell_type": "code", 62 | "id": "9a5b63f1", 63 | "metadata": { 64 | "ExecuteTime": { 65 | "end_time": "2025-06-11T20:24:16.705138Z", 66 | "start_time": "2025-06-11T20:24:16.703252Z" 67 | } 68 | }, 69 | "source": [ 70 | "for num in squares:\n", 71 | " print(num)" 72 | ], 73 | "outputs": [ 74 | { 75 | "name": "stdout", 76 | "output_type": "stream", 77 | "text": [ 78 | "1\n", 79 | "4\n", 80 | "9\n", 81 | "16\n", 82 | "25\n", 83 | "36\n", 84 | "49\n", 85 | "64\n", 86 | "81\n" 87 | ] 88 | } 89 | ], 90 | "execution_count": 80 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "id": "7c6bacb0", 95 | "metadata": {}, 96 | "source": [ 97 | "Generators can only be looped over once" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "id": "0bea45b5", 103 | "metadata": { 104 | "ExecuteTime": { 105 | "end_time": "2025-06-11T20:24:16.720560Z", 106 | "start_time": "2025-06-11T20:24:16.719127Z" 107 | } 108 | }, 109 | "source": [ 110 | "for num in squares:\n", 111 | " print(num)" 112 | ], 113 | "outputs": [], 114 | "execution_count": 81 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "id": "39bc0e12", 119 | "metadata": {}, 120 | "source": [ 121 | "## Comparing speed" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "id": "3eedf5e2", 127 | "metadata": { 128 | "ExecuteTime": { 129 | "end_time": "2025-06-11T20:24:16.738572Z", 130 | "start_time": "2025-06-11T20:24:16.737142Z" 131 | } 132 | }, 133 | "source": [ 134 | "from time import time" 135 | ], 136 | "outputs": [], 137 | "execution_count": 82 138 | }, 139 | { 140 | "cell_type": "code", 141 | "id": "c704b3b5", 142 | "metadata": { 143 | "ExecuteTime": { 144 | "end_time": "2025-06-11T20:24:16.751974Z", 145 | "start_time": "2025-06-11T20:24:16.749780Z" 146 | } 147 | }, 148 | "source": [ 149 | "start = time()\n", 150 | "big_gen = (i for i in range(10**10))\n", 151 | "end = time()\n", 152 | "f'Took {round(end - start, 4)}s'" 153 | ], 154 | "outputs": [ 155 | { 156 | "data": { 157 | "text/plain": [ 158 | "'Took 0.0s'" 159 | ] 160 | }, 161 | "execution_count": 83, 162 | "metadata": {}, 163 | "output_type": "execute_result" 164 | } 165 | ], 166 | "execution_count": 83 167 | }, 168 | { 169 | "cell_type": "code", 170 | "id": "e4b4e5e7", 171 | "metadata": { 172 | "ExecuteTime": { 173 | "end_time": "2025-06-11T20:24:19.295394Z", 174 | "start_time": "2025-06-11T20:24:16.768598Z" 175 | } 176 | }, 177 | "source": [ 178 | "start = time()\n", 179 | "big_list = [i for i in range(10**8)] # Initializing can take a long time and use a lot of memory\n", 180 | "end = time()\n", 181 | "f'Took {round(end - start, 4)}s'" 182 | ], 183 | "outputs": [ 184 | { 185 | "data": { 186 | "text/plain": [ 187 | "'Took 2.524s'" 188 | ] 189 | }, 190 | "execution_count": 84, 191 | "metadata": {}, 192 | "output_type": "execute_result" 193 | } 194 | ], 195 | "execution_count": 84 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "id": "1d32ad19", 200 | "metadata": {}, 201 | "source": [ 202 | "They can be used in certain functions without creating a list.\n", 203 | "\n", 204 | "`any()`, `all()`, `min()`, `max()` and `sum()` can all accept generators." 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "id": "546033ae", 210 | "metadata": { 211 | "ExecuteTime": { 212 | "end_time": "2025-06-11T20:24:20.061223Z", 213 | "start_time": "2025-06-11T20:24:19.303764Z" 214 | } 215 | }, 216 | "source": [ 217 | "from random import random\n", 218 | "\n", 219 | "print(min((random() for i in range(10**7))))\n", 220 | "print(max((random() for i in range(10**7))))" 221 | ], 222 | "outputs": [ 223 | { 224 | "name": "stdout", 225 | "output_type": "stream", 226 | "text": [ 227 | "3.186830310752953e-08\n", 228 | "0.9999999929300746\n" 229 | ] 230 | } 231 | ], 232 | "execution_count": 85 233 | }, 234 | { 235 | "cell_type": "markdown", 236 | "id": "3b1c15fe", 237 | "metadata": {}, 238 | "source": [ 239 | "To create a tuple, cast a generator using the `tuple()`." 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "id": "6a96a5ac", 245 | "metadata": { 246 | "ExecuteTime": { 247 | "end_time": "2025-06-11T20:24:20.072782Z", 248 | "start_time": "2025-06-11T20:24:20.070232Z" 249 | } 250 | }, 251 | "source": [ 252 | "tuple(i for i in range(1, 30) if i % 3 == 0 or i % 5 == 0)" 253 | ], 254 | "outputs": [ 255 | { 256 | "data": { 257 | "text/plain": [ 258 | "(3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24, 25, 27)" 259 | ] 260 | }, 261 | "execution_count": 86, 262 | "metadata": {}, 263 | "output_type": "execute_result" 264 | } 265 | ], 266 | "execution_count": 86 267 | }, 268 | { 269 | "cell_type": "code", 270 | "id": "ebeed49e", 271 | "metadata": { 272 | "ExecuteTime": { 273 | "end_time": "2025-06-11T20:24:20.085054Z", 274 | "start_time": "2025-06-11T20:24:20.083643Z" 275 | } 276 | }, 277 | "source": [], 278 | "outputs": [], 279 | "execution_count": null 280 | } 281 | ], 282 | "metadata": { 283 | "jupytext": { 284 | "cell_metadata_filter": "-all", 285 | "formats": "auto:light,ipynb", 286 | "main_language": "python", 287 | "notebook_metadata_filter": "-all" 288 | }, 289 | "kernelspec": { 290 | "display_name": "Python 3 (ipykernel)", 291 | "language": "python", 292 | "name": "python3" 293 | }, 294 | "language_info": { 295 | "codemirror_mode": { 296 | "name": "ipython", 297 | "version": 3 298 | }, 299 | "file_extension": ".py", 300 | "mimetype": "text/x-python", 301 | "name": "python", 302 | "nbconvert_exporter": "python", 303 | "pygments_lexer": "ipython3", 304 | "version": "3.11.4" 305 | } 306 | }, 307 | "nbformat": 4, 308 | "nbformat_minor": 5 309 | } 310 | -------------------------------------------------------------------------------- /content/examples/ex_11_ordered_dict.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "69635744", 6 | "metadata": {}, 7 | "source": [ 8 | "# collections.OrderedDict" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "cc0e011f", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "from collections import OrderedDict" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "id": "6b1a42bc", 24 | "metadata": {}, 25 | "source": [ 26 | "## Create\n", 27 | "### Empty dict" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "id": "d3e75ad1", 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "data": { 38 | "text/plain": [ 39 | "OrderedDict()" 40 | ] 41 | }, 42 | "execution_count": 2, 43 | "metadata": {}, 44 | "output_type": "execute_result" 45 | } 46 | ], 47 | "source": [ 48 | "a = OrderedDict()\n", 49 | "a" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "id": "646cba33", 55 | "metadata": {}, 56 | "source": [ 57 | "### From a dict" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "id": "69606673", 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "data": { 68 | "text/plain": [ 69 | "OrderedDict([(1, 'a'), (2, 'b')])" 70 | ] 71 | }, 72 | "execution_count": 3, 73 | "metadata": {}, 74 | "output_type": "execute_result" 75 | } 76 | ], 77 | "source": [ 78 | "b = OrderedDict({1: 'a', 2: 'b'})\n", 79 | "b" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "id": "2f4df4a4", 85 | "metadata": {}, 86 | "source": [ 87 | "### From a sequence\n", 88 | "Each item in the sequence must be another sequence with length 2" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 4, 94 | "id": "f3ff07f5", 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "OrderedDict([('a', 'apple'), ('banana', 'b'), ('c', 'cherry')])" 101 | ] 102 | }, 103 | "execution_count": 4, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "c = OrderedDict([['a', 'apple'], {'b', 'banana'}, ('c', 'cherry')])\n", 110 | "c" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "id": "d78ef9f2", 116 | "metadata": {}, 117 | "source": [ 118 | "## Use like a dictionary\n", 119 | "`OrderedDict` has all the same methods as `dict`." 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 5, 125 | "id": "c0ce21e7", 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "OrderedDict([(1, 'a'), (2, 'b'), (0, 'z')])" 132 | ] 133 | }, 134 | "execution_count": 5, 135 | "metadata": {}, 136 | "output_type": "execute_result" 137 | } 138 | ], 139 | "source": [ 140 | "b[0] = 'z'\n", 141 | "b" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 6, 147 | "id": "b4cbac45", 148 | "metadata": {}, 149 | "outputs": [ 150 | { 151 | "name": "stdout", 152 | "output_type": "stream", 153 | "text": [ 154 | "z\n", 155 | "a\n", 156 | "b\n", 157 | "Not found\n" 158 | ] 159 | } 160 | ], 161 | "source": [ 162 | "for i in range(4):\n", 163 | " print(b.get(i, 'Not found'))" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "id": "e3b4d662", 169 | "metadata": {}, 170 | "source": [ 171 | "## Iteration order\n", 172 | "When iterating, it retains memory of insertion order" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": 7, 178 | "id": "6b6d9cd3", 179 | "metadata": {}, 180 | "outputs": [ 181 | { 182 | "name": "stdout", 183 | "output_type": "stream", 184 | "text": [ 185 | "1: a\n", 186 | "2: b\n", 187 | "0: z\n" 188 | ] 189 | } 190 | ], 191 | "source": [ 192 | "for key, value in b.items():\n", 193 | " print(f'{key}: {value}')" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "id": "d90cc992", 199 | "metadata": {}, 200 | "source": [ 201 | "## Pop item\n", 202 | "Additional method to remove the last key-value pair and return it." 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 8, 208 | "id": "d5b7e0e2", 209 | "metadata": {}, 210 | "outputs": [ 211 | { 212 | "data": { 213 | "text/plain": [ 214 | "(0, 'z')" 215 | ] 216 | }, 217 | "execution_count": 8, 218 | "metadata": {}, 219 | "output_type": "execute_result" 220 | } 221 | ], 222 | "source": [ 223 | "b.popitem()" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 9, 229 | "id": "19f7d533", 230 | "metadata": {}, 231 | "outputs": [ 232 | { 233 | "data": { 234 | "text/plain": [ 235 | "'b'" 236 | ] 237 | }, 238 | "execution_count": 9, 239 | "metadata": {}, 240 | "output_type": "execute_result" 241 | } 242 | ], 243 | "source": [ 244 | "b.pop(2)" 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "id": "ccf95467", 250 | "metadata": {}, 251 | "source": [ 252 | "## Reorder items\n", 253 | "`.move_to_end(key, last=True)` will move the item with `key` either to the end (`last=True`) or the front (`last=False`)." 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 10, 259 | "id": "5bbe12ca", 260 | "metadata": {}, 261 | "outputs": [ 262 | { 263 | "data": { 264 | "text/plain": [ 265 | "OrderedDict([(1, 'a')])" 266 | ] 267 | }, 268 | "execution_count": 10, 269 | "metadata": {}, 270 | "output_type": "execute_result" 271 | } 272 | ], 273 | "source": [ 274 | "b.move_to_end(1)\n", 275 | "b" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 11, 281 | "id": "95893dfb", 282 | "metadata": {}, 283 | "outputs": [ 284 | { 285 | "name": "stdout", 286 | "output_type": "stream", 287 | "text": [ 288 | "KeyError(0)\n" 289 | ] 290 | } 291 | ], 292 | "source": [ 293 | "try:\n", 294 | " b.move_to_end(0, last=False)\n", 295 | "except Exception as e:\n", 296 | " print(repr(e))" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 12, 302 | "id": "5aa712c2", 303 | "metadata": {}, 304 | "outputs": [ 305 | { 306 | "name": "stdout", 307 | "output_type": "stream", 308 | "text": [ 309 | "1: a\n" 310 | ] 311 | } 312 | ], 313 | "source": [ 314 | "for key, value in b.items():\n", 315 | " print(f'{key}: {value}')" 316 | ] 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "id": "effa03db", 321 | "metadata": {}, 322 | "source": [ 323 | "## When to use OrderedDict over dict\n", 324 | "`dict` is has been ordered since Python3.6.\n", 325 | "\n", 326 | "You should still use `OrderedDict` to:\n", 327 | "- Clearly state that the order is important\n", 328 | "- Use the `.move_to_end()` method\n", 329 | "- Test dictionary equality based on order\n", 330 | "- Maintain backwards compatibility with Python < 3.6" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "id": "444282ef", 337 | "metadata": {}, 338 | "outputs": [], 339 | "source": [] 340 | } 341 | ], 342 | "metadata": { 343 | "jupytext": { 344 | "cell_metadata_filter": "-all", 345 | "formats": "auto:light,ipynb", 346 | "main_language": "python", 347 | "notebook_metadata_filter": "-all" 348 | }, 349 | "kernelspec": { 350 | "display_name": "Python 3 (ipykernel)", 351 | "language": "python", 352 | "name": "python3" 353 | }, 354 | "language_info": { 355 | "codemirror_mode": { 356 | "name": "ipython", 357 | "version": 3 358 | }, 359 | "file_extension": ".py", 360 | "mimetype": "text/x-python", 361 | "name": "python", 362 | "nbconvert_exporter": "python", 363 | "pygments_lexer": "ipython3", 364 | "version": "3.11.4" 365 | } 366 | }, 367 | "nbformat": 4, 368 | "nbformat_minor": 5 369 | } 370 | -------------------------------------------------------------------------------- /content/project/sample_solutions/proj_3_collections.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "57cb35c4", 6 | "metadata": {}, 7 | "source": [ 8 | "# Survey analysis\n", 9 | "Analyse the results from the [languages survey](https://forms.gle/5b3mZRVcgAsoNG1FA)" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "id": "beb28a4b", 15 | "metadata": { 16 | "ExecuteTime": { 17 | "end_time": "2025-10-21T18:11:28.298617Z", 18 | "start_time": "2025-10-21T18:11:28.294166Z" 19 | } 20 | }, 21 | "source": [ 22 | "all_langs = ['Python', 'Java', 'JavaScript', 'TypeScript', 'PHP', 'SQL', 'C', 'C++', 'C#',\n", 23 | " 'Ruby', 'R', 'Matlab', 'Go', 'Rust', 'Objective-C', 'Swift', 'Visual Basic',\n", 24 | " 'Perl', 'Cobol', 'Fortran', 'Lisp', 'Assembly', 'Kotlin', 'Dart', 'Scala',\n", 25 | " 'Lua', 'Delphi', 'Haskell', 'Julia', 'Clojure', 'Elixir', 'Pascal']" 26 | ], 27 | "outputs": [], 28 | "execution_count": 1 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "id": "bcc1c3f1", 33 | "metadata": {}, 34 | "source": [ 35 | "## Load data" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "id": "44b83567", 41 | "metadata": { 42 | "ExecuteTime": { 43 | "end_time": "2025-10-21T20:10:32.375166Z", 44 | "start_time": "2025-10-21T20:10:32.371135Z" 45 | } 46 | }, 47 | "source": [ 48 | "import csv\n", 49 | "from collections import defaultdict\n", 50 | "from pprint import pprint\n", 51 | "\n", 52 | "lang_counts = defaultdict(int)\n", 53 | "num_responses = 0\n", 54 | "with open('../data/Survey-2024-Jan.csv') as file:\n", 55 | " file.readline() # Ignore first line (header)\n", 56 | " reader = csv.DictReader(file, fieldnames=('timestamp', 'languages', 'years')) # list of dicts with keys passed into fieldnames\n", 57 | " for response in reader:\n", 58 | " num_responses += 1\n", 59 | " for lang in response['languages'].split(';'):\n", 60 | " lang_counts[lang] += 1\n", 61 | "\n", 62 | "pprint(lang_counts)\n", 63 | "print(num_responses)\n" 64 | ], 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "defaultdict(,\n", 71 | " {'Assembly': 2,\n", 72 | " 'C': 7,\n", 73 | " 'C#': 2,\n", 74 | " 'C++': 7,\n", 75 | " 'Cobol': 3,\n", 76 | " 'Dart': 1,\n", 77 | " 'Fortran': 3,\n", 78 | " 'Java': 13,\n", 79 | " 'JavaScript': 10,\n", 80 | " 'Kotlin': 1,\n", 81 | " 'Lisp': 1,\n", 82 | " 'Matlab': 1,\n", 83 | " 'Objective-C': 1,\n", 84 | " 'PHP': 2,\n", 85 | " 'Pascal': 2,\n", 86 | " 'Perl': 6,\n", 87 | " 'Python': 17,\n", 88 | " 'R': 3,\n", 89 | " 'Ruby': 3,\n", 90 | " 'Rust': 1,\n", 91 | " 'SQL': 12,\n", 92 | " 'Swift': 1,\n", 93 | " 'TypeScript': 2,\n", 94 | " 'Visual Basic': 4})\n", 95 | "25\n" 96 | ] 97 | } 98 | ], 99 | "execution_count": 31 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "id": "b7ecbf4b", 104 | "metadata": {}, 105 | "source": [ 106 | "## Find number of languages known\n", 107 | "Print `\"{# known by class} / {# in list} languages known by this class\"`.\n", 108 | "\n", 109 | "E.g. **12/21 languages known by this class**" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "id": "535c48b5", 115 | "metadata": { 116 | "ExecuteTime": { 117 | "end_time": "2025-10-21T20:11:36.347991Z", 118 | "start_time": "2025-10-21T20:11:36.342435Z" 119 | } 120 | }, 121 | "source": [ 122 | "langs_known = set(lang_counts.keys())\n", 123 | "\n", 124 | "print(f\"{len(langs_known)} / {len(all_langs)} languages known by this class\")" 125 | ], 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "24 / 32 languages known by this class\n" 132 | ] 133 | } 134 | ], 135 | "execution_count": 32 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "id": "8854f96e", 140 | "metadata": {}, 141 | "source": [ 142 | "## List languages not known by anyone in the class" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "id": "88f7d084", 148 | "metadata": { 149 | "ExecuteTime": { 150 | "end_time": "2025-10-21T20:12:09.527552Z", 151 | "start_time": "2025-10-21T20:12:09.503913Z" 152 | } 153 | }, 154 | "source": [ 155 | "not_known = set(all_langs) - langs_known\n", 156 | "\n", 157 | "print(sorted(not_known))\n", 158 | "print(len(not_known))" 159 | ], 160 | "outputs": [ 161 | { 162 | "name": "stdout", 163 | "output_type": "stream", 164 | "text": [ 165 | "['Clojure', 'Delphi', 'Elixir', 'Go', 'Haskell', 'Julia', 'Lua', 'Scala']\n", 166 | "8\n" 167 | ] 168 | } 169 | ], 170 | "execution_count": 33 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "id": "4e6d082d", 175 | "metadata": {}, 176 | "source": [ 177 | "## Rank languages by most commonly known\n", 178 | "Print each language as `\"{position}: {language} ({percent_known}%)\"`, in order from most to least known\n", 179 | "\n", 180 | "e.g. **1: Python (93%)**" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "id": "b4f73f17", 186 | "metadata": { 187 | "ExecuteTime": { 188 | "end_time": "2025-10-21T20:13:08.070623Z", 189 | "start_time": "2025-10-21T20:13:08.056837Z" 190 | } 191 | }, 192 | "source": [ 193 | "from collections import Counter\n", 194 | "\n", 195 | "langs_counter = Counter(lang_counts)\n", 196 | "langs_counter" 197 | ], 198 | "outputs": [ 199 | { 200 | "data": { 201 | "text/plain": [ 202 | "Counter({'Python': 17,\n", 203 | " 'Java': 13,\n", 204 | " 'SQL': 12,\n", 205 | " 'JavaScript': 10,\n", 206 | " 'C': 7,\n", 207 | " 'C++': 7,\n", 208 | " 'Perl': 6,\n", 209 | " 'Visual Basic': 4,\n", 210 | " 'Cobol': 3,\n", 211 | " 'Fortran': 3,\n", 212 | " 'Ruby': 3,\n", 213 | " 'R': 3,\n", 214 | " 'Assembly': 2,\n", 215 | " 'Pascal': 2,\n", 216 | " 'TypeScript': 2,\n", 217 | " 'PHP': 2,\n", 218 | " 'C#': 2,\n", 219 | " 'Objective-C': 1,\n", 220 | " 'Swift': 1,\n", 221 | " 'Kotlin': 1,\n", 222 | " 'Dart': 1,\n", 223 | " 'Matlab': 1,\n", 224 | " 'Lisp': 1,\n", 225 | " 'Rust': 1})" 226 | ] 227 | }, 228 | "execution_count": 34, 229 | "metadata": {}, 230 | "output_type": "execute_result" 231 | } 232 | ], 233 | "execution_count": 34 234 | }, 235 | { 236 | "metadata": { 237 | "ExecuteTime": { 238 | "end_time": "2025-10-21T20:13:46.879737Z", 239 | "start_time": "2025-10-21T20:13:46.874456Z" 240 | } 241 | }, 242 | "cell_type": "code", 243 | "source": [ 244 | "for pos, (lang, count) in enumerate(langs_counter.most_common(), start=1):\n", 245 | " print(f\"{pos}: {lang} ({round(count / num_responses * 100)}%)\")" 246 | ], 247 | "id": "41d9a88cc48569e8", 248 | "outputs": [ 249 | { 250 | "name": "stdout", 251 | "output_type": "stream", 252 | "text": [ 253 | "1: Python (68%)\n", 254 | "2: Java (52%)\n", 255 | "3: SQL (48%)\n", 256 | "4: JavaScript (40%)\n", 257 | "5: C (28%)\n", 258 | "6: C++ (28%)\n", 259 | "7: Perl (24%)\n", 260 | "8: Visual Basic (16%)\n", 261 | "9: Cobol (12%)\n", 262 | "10: Fortran (12%)\n", 263 | "11: Ruby (12%)\n", 264 | "12: R (12%)\n", 265 | "13: Assembly (8%)\n", 266 | "14: Pascal (8%)\n", 267 | "15: TypeScript (8%)\n", 268 | "16: PHP (8%)\n", 269 | "17: C# (8%)\n", 270 | "18: Objective-C (4%)\n", 271 | "19: Swift (4%)\n", 272 | "20: Kotlin (4%)\n", 273 | "21: Dart (4%)\n", 274 | "22: Matlab (4%)\n", 275 | "23: Lisp (4%)\n", 276 | "24: Rust (4%)\n" 277 | ] 278 | } 279 | ], 280 | "execution_count": 35 281 | } 282 | ], 283 | "metadata": { 284 | "jupytext": { 285 | "cell_metadata_filter": "-all", 286 | "formats": "auto:light,ipynb", 287 | "main_language": "python", 288 | "notebook_metadata_filter": "-all" 289 | }, 290 | "kernelspec": { 291 | "display_name": "Python 3 (ipykernel)", 292 | "language": "python", 293 | "name": "python3" 294 | }, 295 | "language_info": { 296 | "codemirror_mode": { 297 | "name": "ipython", 298 | "version": 3 299 | }, 300 | "file_extension": ".py", 301 | "mimetype": "text/x-python", 302 | "name": "python", 303 | "nbconvert_exporter": "python", 304 | "pygments_lexer": "ipython3", 305 | "version": "3.11.4" 306 | } 307 | }, 308 | "nbformat": 4, 309 | "nbformat_minor": 5 310 | } 311 | -------------------------------------------------------------------------------- /content/examples/ex_10_namedtuple.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "b96222eb-c6d6-4a99-8345-71f324bfd283", 6 | "metadata": {}, 7 | "source": [ 8 | "# collections.namedtuple\n", 9 | "\n", 10 | "A lightweight class that acts like a tuple with a type name and attributes." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "id": "bd3a527a-9438-47e8-ac0e-19a252a5e02a", 16 | "metadata": { 17 | "ExecuteTime": { 18 | "end_time": "2025-10-21T19:14:46.673293Z", 19 | "start_time": "2025-10-21T19:14:46.671108Z" 20 | } 21 | }, 22 | "source": [ 23 | "from collections import namedtuple" 24 | ], 25 | "outputs": [], 26 | "execution_count": 1 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "id": "bfc59467-b978-4da6-a719-69dd13624fbb", 31 | "metadata": {}, 32 | "source": [ 33 | "Define a \"class\" with a name and attributes." 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "id": "81e30457-2fb8-4931-9155-7d4ef56e7c60", 39 | "metadata": { 40 | "ExecuteTime": { 41 | "end_time": "2025-10-21T19:16:22.436200Z", 42 | "start_time": "2025-10-21T19:16:22.430577Z" 43 | } 44 | }, 45 | "source": [ 46 | "Coords = namedtuple(\"Location\", \"name lat lon\")" 47 | ], 48 | "outputs": [], 49 | "execution_count": 3 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "id": "f85c368a-c984-414b-94d6-88a3ed512afd", 54 | "metadata": {}, 55 | "source": [ 56 | "Create an \"instance\" of the class." 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "id": "7725a970-2681-473b-a3a3-be6d871f0262", 62 | "metadata": { 63 | "ExecuteTime": { 64 | "end_time": "2025-10-21T19:16:23.241773Z", 65 | "start_time": "2025-10-21T19:16:23.235041Z" 66 | } 67 | }, 68 | "source": [ 69 | "c = Coords('London', 42.99, -81.243)\n", 70 | "c" 71 | ], 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "Location(name='London', lat=42.99, lon=-81.243)" 77 | ] 78 | }, 79 | "execution_count": 4, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | } 83 | ], 84 | "execution_count": 4 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "id": "3c9ece39-b54c-4fc0-9f2e-6abd9b6ecec2", 89 | "metadata": {}, 90 | "source": [ 91 | "You can interact with the instance as if it were a tuple." 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "id": "3f451a6d-e07f-46b0-803c-d018259fdc52", 97 | "metadata": { 98 | "ExecuteTime": { 99 | "end_time": "2025-10-21T19:16:45.310633Z", 100 | "start_time": "2025-10-21T19:16:45.307517Z" 101 | } 102 | }, 103 | "source": "c[0]", 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "'London'" 109 | ] 110 | }, 111 | "execution_count": 8, 112 | "metadata": {}, 113 | "output_type": "execute_result" 114 | } 115 | ], 116 | "execution_count": 8 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "id": "ce85f872-3615-4edf-9428-3478dd7c9931", 121 | "metadata": {}, 122 | "source": [ 123 | "You can also access the named attributes." 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "id": "783fb82b-3017-424d-bfa9-52ebc801888f", 129 | "metadata": { 130 | "ExecuteTime": { 131 | "end_time": "2025-10-21T19:16:50.644747Z", 132 | "start_time": "2025-10-21T19:16:50.641325Z" 133 | } 134 | }, 135 | "source": [ 136 | "c.name" 137 | ], 138 | "outputs": [ 139 | { 140 | "data": { 141 | "text/plain": [ 142 | "'London'" 143 | ] 144 | }, 145 | "execution_count": 9, 146 | "metadata": {}, 147 | "output_type": "execute_result" 148 | } 149 | ], 150 | "execution_count": 9 151 | }, 152 | { 153 | "cell_type": "code", 154 | "id": "a7d94b61-2579-4d1b-80a7-fff1aac4b85d", 155 | "metadata": { 156 | "ExecuteTime": { 157 | "end_time": "2025-10-21T19:16:51.656821Z", 158 | "start_time": "2025-10-21T19:16:51.653813Z" 159 | } 160 | }, 161 | "source": [ 162 | "c.lat" 163 | ], 164 | "outputs": [ 165 | { 166 | "data": { 167 | "text/plain": [ 168 | "42.99" 169 | ] 170 | }, 171 | "execution_count": 10, 172 | "metadata": {}, 173 | "output_type": "execute_result" 174 | } 175 | ], 176 | "execution_count": 10 177 | }, 178 | { 179 | "cell_type": "code", 180 | "id": "93396285-b89b-4395-91aa-2680656111b2", 181 | "metadata": { 182 | "ExecuteTime": { 183 | "end_time": "2025-10-21T19:17:06.463871Z", 184 | "start_time": "2025-10-21T19:17:06.461011Z" 185 | } 186 | }, 187 | "source": [ 188 | "type(c)" 189 | ], 190 | "outputs": [ 191 | { 192 | "data": { 193 | "text/plain": [ 194 | "__main__.Location" 195 | ] 196 | }, 197 | "execution_count": 11, 198 | "metadata": {}, 199 | "output_type": "execute_result" 200 | } 201 | ], 202 | "execution_count": 11 203 | }, 204 | { 205 | "cell_type": "code", 206 | "id": "d7375a53-0790-45c5-aa6f-31f2b15bd03c", 207 | "metadata": { 208 | "ExecuteTime": { 209 | "end_time": "2025-10-21T19:17:13.950180Z", 210 | "start_time": "2025-10-21T19:17:13.948312Z" 211 | } 212 | }, 213 | "source": [ 214 | "try:\n", 215 | " c[1] += 1\n", 216 | "except Exception as e:\n", 217 | " print(repr(e))" 218 | ], 219 | "outputs": [ 220 | { 221 | "name": "stdout", 222 | "output_type": "stream", 223 | "text": [ 224 | "TypeError(\"'Location' object does not support item assignment\")\n" 225 | ] 226 | } 227 | ], 228 | "execution_count": 12 229 | }, 230 | { 231 | "cell_type": "code", 232 | "id": "69446e6b-79f9-45d7-bd81-0e1d1907bb5e", 233 | "metadata": { 234 | "ExecuteTime": { 235 | "end_time": "2025-10-21T19:18:59.305646Z", 236 | "start_time": "2025-10-21T19:18:59.301300Z" 237 | } 238 | }, 239 | "source": [ 240 | "from typing import NamedTuple\n", 241 | "\n", 242 | "class Location(NamedTuple):\n", 243 | " name: str\n", 244 | " lat: float\n", 245 | " lon: float\n" 246 | ], 247 | "outputs": [], 248 | "execution_count": 13 249 | }, 250 | { 251 | "metadata": { 252 | "ExecuteTime": { 253 | "end_time": "2025-10-21T19:19:41.426885Z", 254 | "start_time": "2025-10-21T19:19:41.423648Z" 255 | } 256 | }, 257 | "cell_type": "code", 258 | "source": "l = Location('London2', 42.99, -81.243)", 259 | "id": "9b890e6c4742c11b", 260 | "outputs": [], 261 | "execution_count": 18 262 | }, 263 | { 264 | "metadata": { 265 | "ExecuteTime": { 266 | "end_time": "2025-10-21T19:19:08.710192Z", 267 | "start_time": "2025-10-21T19:19:08.707154Z" 268 | } 269 | }, 270 | "cell_type": "code", 271 | "source": "l.name", 272 | "id": "316623ccdcfd7613", 273 | "outputs": [ 274 | { 275 | "data": { 276 | "text/plain": [ 277 | "'London2'" 278 | ] 279 | }, 280 | "execution_count": 16, 281 | "metadata": {}, 282 | "output_type": "execute_result" 283 | } 284 | ], 285 | "execution_count": 16 286 | }, 287 | { 288 | "metadata": { 289 | "ExecuteTime": { 290 | "end_time": "2025-10-21T19:19:53.857140Z", 291 | "start_time": "2025-10-21T19:19:53.854077Z" 292 | } 293 | }, 294 | "cell_type": "code", 295 | "source": "type(l)", 296 | "id": "659c7aa315cdcaa9", 297 | "outputs": [ 298 | { 299 | "data": { 300 | "text/plain": [ 301 | "__main__.Location" 302 | ] 303 | }, 304 | "execution_count": 19, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "execution_count": 19 310 | }, 311 | { 312 | "metadata": { 313 | "ExecuteTime": { 314 | "end_time": "2025-10-21T19:20:05.834867Z", 315 | "start_time": "2025-10-21T19:20:05.832021Z" 316 | } 317 | }, 318 | "cell_type": "code", 319 | "source": "l[1]", 320 | "id": "b7b55ee2bfdc1cbe", 321 | "outputs": [ 322 | { 323 | "data": { 324 | "text/plain": [ 325 | "42.99" 326 | ] 327 | }, 328 | "execution_count": 20, 329 | "metadata": {}, 330 | "output_type": "execute_result" 331 | } 332 | ], 333 | "execution_count": 20 334 | }, 335 | { 336 | "metadata": { 337 | "ExecuteTime": { 338 | "end_time": "2025-10-21T19:20:20.385624Z", 339 | "start_time": "2025-10-21T19:20:20.380099Z" 340 | } 341 | }, 342 | "cell_type": "code", 343 | "source": [ 344 | "name, lat, lon = l\n", 345 | "lat" 346 | ], 347 | "id": "24d1bd08c160af46", 348 | "outputs": [ 349 | { 350 | "data": { 351 | "text/plain": [ 352 | "42.99" 353 | ] 354 | }, 355 | "execution_count": 21, 356 | "metadata": {}, 357 | "output_type": "execute_result" 358 | } 359 | ], 360 | "execution_count": 21 361 | }, 362 | { 363 | "metadata": {}, 364 | "cell_type": "code", 365 | "outputs": [], 366 | "execution_count": null, 367 | "source": "", 368 | "id": "3ca62e7ca2d75273" 369 | } 370 | ], 371 | "metadata": { 372 | "kernelspec": { 373 | "display_name": "Python 3 (ipykernel)", 374 | "language": "python", 375 | "name": "python3" 376 | }, 377 | "language_info": { 378 | "codemirror_mode": { 379 | "name": "ipython", 380 | "version": 3 381 | }, 382 | "file_extension": ".py", 383 | "mimetype": "text/x-python", 384 | "name": "python", 385 | "nbconvert_exporter": "python", 386 | "pygments_lexer": "ipython3", 387 | "version": "3.11.4" 388 | } 389 | }, 390 | "nbformat": 4, 391 | "nbformat_minor": 5 392 | } 393 | -------------------------------------------------------------------------------- /content/examples/ex_06_dict_comprehensions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d7084a4d", 6 | "metadata": {}, 7 | "source": [ 8 | "# Dict Comprehensions\n", 9 | "Just like list comprehensions, but use a different syntax to create dicts.\n", 10 | "## Basic comprehensions\n", 11 | "Format: `{key_exp: value_exp for member in iterable}`" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "id": "86cd588f", 18 | "metadata": {}, 19 | "outputs": [ 20 | { 21 | "data": { 22 | "text/plain": [ 23 | "{2: 4, 4: 16, 6: 64, 8: 256}" 24 | ] 25 | }, 26 | "execution_count": 1, 27 | "metadata": {}, 28 | "output_type": "execute_result" 29 | } 30 | ], 31 | "source": [ 32 | "powers_of_2 = {i: 2**i for i in range(2, 10, 2)}\n", 33 | "powers_of_2" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "4042c8e1", 39 | "metadata": {}, 40 | "source": [ 41 | "### As for-loop" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "id": "16341d9b", 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "data": { 52 | "text/plain": [ 53 | "{2: 4, 4: 16, 6: 64, 8: 256}" 54 | ] 55 | }, 56 | "execution_count": 2, 57 | "metadata": {}, 58 | "output_type": "execute_result" 59 | } 60 | ], 61 | "source": [ 62 | "powers_of_2 = {}\n", 63 | "for i in range(2, 10, 2):\n", 64 | " powers_of_2[i] = 2**i\n", 65 | "\n", 66 | "powers_of_2" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "id": "866853e3", 72 | "metadata": {}, 73 | "source": [ 74 | "## Using conditionals" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 3, 80 | "id": "f6f40261", 81 | "metadata": {}, 82 | "outputs": [ 83 | { 84 | "data": { 85 | "text/plain": [ 86 | "{'C': 3,\n", 87 | " 'T': 1,\n", 88 | " 'D': 2,\n", 89 | " 'E': 8,\n", 90 | " 'O': 1,\n", 91 | " 'F': 1,\n", 92 | " 'R': 3,\n", 93 | " 'A': 1,\n", 94 | " 'L': 1,\n", 95 | " 'S': 1,\n", 96 | " 'P': 9,\n", 97 | " 'K': 3,\n", 98 | " 'I': 3}" 99 | ] 100 | }, 101 | "execution_count": 3, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "phrase = \"peter piper picked a peck of pickled peppers\"\n", 108 | "letter_set = set(phrase)\n", 109 | "\n", 110 | "letter_counts = {char.upper(): phrase.count(char) for char in letter_set if char != ' '}\n", 111 | "letter_counts" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "id": "a4df46a1", 117 | "metadata": {}, 118 | "source": [ 119 | "### As for-loop" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 4, 125 | "id": "a3fd7f02", 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "{'i': 3,\n", 132 | " 'l': 1,\n", 133 | " 'f': 1,\n", 134 | " 'r': 3,\n", 135 | " 'a': 1,\n", 136 | " 'd': 2,\n", 137 | " 'o': 1,\n", 138 | " 's': 1,\n", 139 | " 't': 1,\n", 140 | " 'p': 9,\n", 141 | " 'k': 3,\n", 142 | " 'c': 3,\n", 143 | " 'e': 8}" 144 | ] 145 | }, 146 | "execution_count": 4, 147 | "metadata": {}, 148 | "output_type": "execute_result" 149 | } 150 | ], 151 | "source": [ 152 | "phrase = \"peter piper picked a peck of pickled peppers\"\n", 153 | "letter_set = set(phrase)\n", 154 | "\n", 155 | "letter_counts = {}\n", 156 | "for char in letter_set:\n", 157 | " if char != ' ':\n", 158 | " letter_counts[char] = phrase.count(char)\n", 159 | "\n", 160 | "letter_counts" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "id": "3cd6e8f8", 166 | "metadata": {}, 167 | "source": [ 168 | "## With ternary operator" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 5, 174 | "id": "c80a1684", 175 | "metadata": {}, 176 | "outputs": [ 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "{0: True,\n", 181 | " 1: False,\n", 182 | " 2: True,\n", 183 | " 3: False,\n", 184 | " 4: True,\n", 185 | " 5: False,\n", 186 | " 6: True,\n", 187 | " 7: False,\n", 188 | " 8: True,\n", 189 | " 9: False}" 190 | ] 191 | }, 192 | "execution_count": 5, 193 | "metadata": {}, 194 | "output_type": "execute_result" 195 | } 196 | ], 197 | "source": [ 198 | "is_even = {i: True if i % 2 == 0 else False for i in range(10)}\n", 199 | "is_even" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 6, 205 | "id": "64a4d677", 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "data": { 210 | "text/plain": [ 211 | "{0: True,\n", 212 | " 1: False,\n", 213 | " 2: True,\n", 214 | " 3: False,\n", 215 | " 4: True,\n", 216 | " 5: False,\n", 217 | " 6: True,\n", 218 | " 7: False,\n", 219 | " 8: True,\n", 220 | " 9: False}" 221 | ] 222 | }, 223 | "execution_count": 6, 224 | "metadata": {}, 225 | "output_type": "execute_result" 226 | } 227 | ], 228 | "source": [ 229 | "is_even = {}\n", 230 | "for i in range(10):\n", 231 | " if i % 2 == 0:\n", 232 | " is_even[i] = True\n", 233 | " else:\n", 234 | " is_even[i] = False\n", 235 | "is_even" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "id": "bd2e0da3", 241 | "metadata": {}, 242 | "source": [ 243 | "## Nested comprehensions\n", 244 | "### Dict wth list values" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 7, 250 | "id": "e323800b", 251 | "metadata": {}, 252 | "outputs": [ 253 | { 254 | "data": { 255 | "text/plain": [ 256 | "{0: [],\n", 257 | " 1: [0],\n", 258 | " 2: [0, 1],\n", 259 | " 3: [0, 1, 2],\n", 260 | " 4: [0, 1, 2, 3],\n", 261 | " 5: [0, 1, 2, 3, 4],\n", 262 | " 6: [0, 1, 2, 3, 4, 5],\n", 263 | " 7: [0, 1, 2, 3, 4, 5, 6],\n", 264 | " 8: [0, 1, 2, 3, 4, 5, 6, 7],\n", 265 | " 9: [0, 1, 2, 3, 4, 5, 6, 7, 8]}" 266 | ] 267 | }, 268 | "execution_count": 7, 269 | "metadata": {}, 270 | "output_type": "execute_result" 271 | } 272 | ], 273 | "source": [ 274 | "lesser_nums = {\n", 275 | " i: [j for j in range(i)] \n", 276 | " for i in range(10)\n", 277 | "}\n", 278 | "lesser_nums" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "id": "7bef5215", 284 | "metadata": {}, 285 | "source": [ 286 | "### As for-loop" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": 8, 292 | "id": "8344a681", 293 | "metadata": {}, 294 | "outputs": [ 295 | { 296 | "data": { 297 | "text/plain": [ 298 | "{0: [],\n", 299 | " 1: [0],\n", 300 | " 2: [0, 1],\n", 301 | " 3: [0, 1, 2],\n", 302 | " 4: [0, 1, 2, 3],\n", 303 | " 5: [0, 1, 2, 3, 4],\n", 304 | " 6: [0, 1, 2, 3, 4, 5],\n", 305 | " 7: [0, 1, 2, 3, 4, 5, 6],\n", 306 | " 8: [0, 1, 2, 3, 4, 5, 6, 7],\n", 307 | " 9: [0, 1, 2, 3, 4, 5, 6, 7, 8]}" 308 | ] 309 | }, 310 | "execution_count": 8, 311 | "metadata": {}, 312 | "output_type": "execute_result" 313 | } 314 | ], 315 | "source": [ 316 | "lesser_nums = {}\n", 317 | "for i in range(10):\n", 318 | " nums = []\n", 319 | " for j in range(i):\n", 320 | " nums.append(j)\n", 321 | " lesser_nums[i] = nums\n", 322 | "lesser_nums" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "id": "63466106", 328 | "metadata": {}, 329 | "source": [ 330 | "### Flat nesting" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": 9, 336 | "id": "fc88ba86", 337 | "metadata": {}, 338 | "outputs": [ 339 | { 340 | "data": { 341 | "text/plain": [ 342 | "{(0, 0): 0,\n", 343 | " (0, 1): 0,\n", 344 | " (0, 2): 0,\n", 345 | " (1, 0): 0,\n", 346 | " (1, 1): 1,\n", 347 | " (1, 2): 2,\n", 348 | " (2, 0): 0,\n", 349 | " (2, 1): 2,\n", 350 | " (2, 2): 4}" 351 | ] 352 | }, 353 | "execution_count": 9, 354 | "metadata": {}, 355 | "output_type": "execute_result" 356 | } 357 | ], 358 | "source": [ 359 | "products = {(x, y): x*y for x in range(3) for y in range(3)}\n", 360 | "products" 361 | ] 362 | }, 363 | { 364 | "cell_type": "markdown", 365 | "id": "74ad3722", 366 | "metadata": {}, 367 | "source": [ 368 | "### As for-loop" 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": 10, 374 | "id": "88182197", 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "data": { 379 | "text/plain": [ 380 | "{(0, 0): 0,\n", 381 | " (0, 1): 0,\n", 382 | " (0, 2): 0,\n", 383 | " (1, 0): 0,\n", 384 | " (1, 1): 1,\n", 385 | " (1, 2): 2,\n", 386 | " (2, 0): 0,\n", 387 | " (2, 1): 2,\n", 388 | " (2, 2): 4}" 389 | ] 390 | }, 391 | "execution_count": 10, 392 | "metadata": {}, 393 | "output_type": "execute_result" 394 | } 395 | ], 396 | "source": [ 397 | "products = {}\n", 398 | "for x in range(3):\n", 399 | " for y in range(3):\n", 400 | " products[(x, y)] = x * y\n", 401 | "products" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": null, 407 | "id": "e4665cd0", 408 | "metadata": {}, 409 | "outputs": [], 410 | "source": [] 411 | } 412 | ], 413 | "metadata": { 414 | "jupytext": { 415 | "cell_metadata_filter": "-all", 416 | "formats": "auto:light,ipynb", 417 | "main_language": "python", 418 | "notebook_metadata_filter": "-all" 419 | }, 420 | "kernelspec": { 421 | "display_name": "Python 3 (ipykernel)", 422 | "language": "python", 423 | "name": "python3" 424 | }, 425 | "language_info": { 426 | "codemirror_mode": { 427 | "name": "ipython", 428 | "version": 3 429 | }, 430 | "file_extension": ".py", 431 | "mimetype": "text/x-python", 432 | "name": "python", 433 | "nbconvert_exporter": "python", 434 | "pygments_lexer": "ipython3", 435 | "version": "3.11.4" 436 | } 437 | }, 438 | "nbformat": 4, 439 | "nbformat_minor": 5 440 | } 441 | -------------------------------------------------------------------------------- /content/project/sample_solutions/proj_1_builtin.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "57cb35c4", 6 | "metadata": {}, 7 | "source": [ 8 | "# Survey analysis\n", 9 | "Analyse the results from the [languages survey](https://forms.gle/5b3mZRVcgAsoNG1FA)" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "id": "beb28a4b", 15 | "metadata": { 16 | "ExecuteTime": { 17 | "end_time": "2025-10-21T18:11:28.298617Z", 18 | "start_time": "2025-10-21T18:11:28.294166Z" 19 | } 20 | }, 21 | "source": [ 22 | "all_langs = ['Python', 'Java', 'JavaScript', 'TypeScript', 'PHP', 'SQL', 'C', 'C++', 'C#',\n", 23 | " 'Ruby', 'R', 'Matlab', 'Go', 'Rust', 'Objective-C', 'Swift', 'Visual Basic',\n", 24 | " 'Perl', 'Cobol', 'Fortran', 'Lisp', 'Assembly', 'Kotlin', 'Dart', 'Scala',\n", 25 | " 'Lua', 'Delphi', 'Haskell', 'Julia', 'Clojure', 'Elixir', 'Pascal']" 26 | ], 27 | "outputs": [], 28 | "execution_count": 1 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "id": "bcc1c3f1", 33 | "metadata": {}, 34 | "source": [ 35 | "## Load data" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "id": "44b83567", 41 | "metadata": { 42 | "ExecuteTime": { 43 | "end_time": "2025-10-21T18:11:28.309222Z", 44 | "start_time": "2025-10-21T18:11:28.302711Z" 45 | } 46 | }, 47 | "source": [ 48 | "import csv\n", 49 | "from pprint import pprint\n", 50 | "\n", 51 | "lang_responses = []\n", 52 | "num_responses = 0\n", 53 | "with open('../data/Survey-2024-Jan.csv') as file:\n", 54 | " file.readline() # Ignore first line (header)\n", 55 | " reader = csv.DictReader(file, fieldnames=('timestamp', 'languages', 'years')) # list of dicts with keys passed into fieldnames\n", 56 | " for response in reader:\n", 57 | " langs = response['languages'].split(';')\n", 58 | " lang_responses += langs\n", 59 | " num_responses += 1\n", 60 | "\n", 61 | "print(len(lang_responses))\n", 62 | "print(num_responses)\n" 63 | ], 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "105\n", 70 | "25\n" 71 | ] 72 | } 73 | ], 74 | "execution_count": 2 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "id": "b7ecbf4b", 79 | "metadata": {}, 80 | "source": [ 81 | "## Find number of languages known\n", 82 | "Print `\"{# known by class} / {# in list} languages known by this class\"`.\n", 83 | "\n", 84 | "E.g. **12/21 languages known by this class**" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "id": "535c48b5", 90 | "metadata": { 91 | "ExecuteTime": { 92 | "end_time": "2025-10-21T18:11:28.317876Z", 93 | "start_time": "2025-10-21T18:11:28.315811Z" 94 | } 95 | }, 96 | "source": [ 97 | "langs_known = set(lang_responses)\n", 98 | "\n", 99 | "print(f\"{len(langs_known)} / {len(all_langs)} languages known by this class\")" 100 | ], 101 | "outputs": [ 102 | { 103 | "name": "stdout", 104 | "output_type": "stream", 105 | "text": [ 106 | "24 / 32 languages known by this class\n" 107 | ] 108 | } 109 | ], 110 | "execution_count": 3 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "id": "8854f96e", 115 | "metadata": {}, 116 | "source": [ 117 | "## List languages not known by anyone in the class" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "id": "88f7d084", 123 | "metadata": { 124 | "ExecuteTime": { 125 | "end_time": "2025-10-21T18:11:28.324325Z", 126 | "start_time": "2025-10-21T18:11:28.322226Z" 127 | } 128 | }, 129 | "source": [ 130 | "not_known = set(all_langs) - langs_known\n", 131 | "\n", 132 | "print(sorted(not_known))\n", 133 | "print(len(not_known))" 134 | ], 135 | "outputs": [ 136 | { 137 | "name": "stdout", 138 | "output_type": "stream", 139 | "text": [ 140 | "['Clojure', 'Delphi', 'Elixir', 'Go', 'Haskell', 'Julia', 'Lua', 'Scala']\n", 141 | "8\n" 142 | ] 143 | } 144 | ], 145 | "execution_count": 4 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "id": "4e6d082d", 150 | "metadata": {}, 151 | "source": [ 152 | "## Rank languages by most commonly known\n", 153 | "Print each language as `\"{position}: {language} ({percent_known}%)\"`, in order from most to least known\n", 154 | "\n", 155 | "e.g. **1: Python (93%)**" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "id": "b4f73f17", 161 | "metadata": { 162 | "ExecuteTime": { 163 | "end_time": "2025-10-21T18:11:28.333715Z", 164 | "start_time": "2025-10-21T18:11:28.329733Z" 165 | } 166 | }, 167 | "source": [ 168 | "lang_counts = {}\n", 169 | "\n", 170 | "for lang in sorted(all_langs):\n", 171 | " lang_counts[lang] = 0\n", 172 | "\n", 173 | "lang_counts" 174 | ], 175 | "outputs": [ 176 | { 177 | "data": { 178 | "text/plain": [ 179 | "{'Assembly': 0,\n", 180 | " 'C': 0,\n", 181 | " 'C#': 0,\n", 182 | " 'C++': 0,\n", 183 | " 'Clojure': 0,\n", 184 | " 'Cobol': 0,\n", 185 | " 'Dart': 0,\n", 186 | " 'Delphi': 0,\n", 187 | " 'Elixir': 0,\n", 188 | " 'Fortran': 0,\n", 189 | " 'Go': 0,\n", 190 | " 'Haskell': 0,\n", 191 | " 'Java': 0,\n", 192 | " 'JavaScript': 0,\n", 193 | " 'Julia': 0,\n", 194 | " 'Kotlin': 0,\n", 195 | " 'Lisp': 0,\n", 196 | " 'Lua': 0,\n", 197 | " 'Matlab': 0,\n", 198 | " 'Objective-C': 0,\n", 199 | " 'PHP': 0,\n", 200 | " 'Pascal': 0,\n", 201 | " 'Perl': 0,\n", 202 | " 'Python': 0,\n", 203 | " 'R': 0,\n", 204 | " 'Ruby': 0,\n", 205 | " 'Rust': 0,\n", 206 | " 'SQL': 0,\n", 207 | " 'Scala': 0,\n", 208 | " 'Swift': 0,\n", 209 | " 'TypeScript': 0,\n", 210 | " 'Visual Basic': 0}" 211 | ] 212 | }, 213 | "execution_count": 5, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "execution_count": 5 219 | }, 220 | { 221 | "metadata": { 222 | "ExecuteTime": { 223 | "end_time": "2025-10-21T18:11:28.342994Z", 224 | "start_time": "2025-10-21T18:11:28.339753Z" 225 | } 226 | }, 227 | "cell_type": "code", 228 | "source": [ 229 | "for lang in lang_responses:\n", 230 | " lang_counts[lang] += 1\n", 231 | "\n", 232 | "lang_counts" 233 | ], 234 | "id": "2e8e877a8c4e61ea", 235 | "outputs": [ 236 | { 237 | "data": { 238 | "text/plain": [ 239 | "{'Assembly': 2,\n", 240 | " 'C': 7,\n", 241 | " 'C#': 2,\n", 242 | " 'C++': 7,\n", 243 | " 'Clojure': 0,\n", 244 | " 'Cobol': 3,\n", 245 | " 'Dart': 1,\n", 246 | " 'Delphi': 0,\n", 247 | " 'Elixir': 0,\n", 248 | " 'Fortran': 3,\n", 249 | " 'Go': 0,\n", 250 | " 'Haskell': 0,\n", 251 | " 'Java': 13,\n", 252 | " 'JavaScript': 10,\n", 253 | " 'Julia': 0,\n", 254 | " 'Kotlin': 1,\n", 255 | " 'Lisp': 1,\n", 256 | " 'Lua': 0,\n", 257 | " 'Matlab': 1,\n", 258 | " 'Objective-C': 1,\n", 259 | " 'PHP': 2,\n", 260 | " 'Pascal': 2,\n", 261 | " 'Perl': 6,\n", 262 | " 'Python': 17,\n", 263 | " 'R': 3,\n", 264 | " 'Ruby': 3,\n", 265 | " 'Rust': 1,\n", 266 | " 'SQL': 12,\n", 267 | " 'Scala': 0,\n", 268 | " 'Swift': 1,\n", 269 | " 'TypeScript': 2,\n", 270 | " 'Visual Basic': 4}" 271 | ] 272 | }, 273 | "execution_count": 6, 274 | "metadata": {}, 275 | "output_type": "execute_result" 276 | } 277 | ], 278 | "execution_count": 6 279 | }, 280 | { 281 | "metadata": { 282 | "ExecuteTime": { 283 | "end_time": "2025-10-21T18:11:28.348919Z", 284 | "start_time": "2025-10-21T18:11:28.346373Z" 285 | } 286 | }, 287 | "cell_type": "code", 288 | "source": [ 289 | "lang_counts_list = list(lang_counts.items())\n", 290 | "lang_counts_list.sort(key=lambda l_c: -l_c[1])" 291 | ], 292 | "id": "ea5fa98a99766edd", 293 | "outputs": [], 294 | "execution_count": 7 295 | }, 296 | { 297 | "metadata": { 298 | "ExecuteTime": { 299 | "end_time": "2025-10-21T18:11:28.354914Z", 300 | "start_time": "2025-10-21T18:11:28.352803Z" 301 | } 302 | }, 303 | "cell_type": "code", 304 | "source": [ 305 | "for pos, (lang, count) in enumerate(lang_counts_list, start=1):\n", 306 | " print(f\"{pos}: {lang} ({round(count / num_responses * 100)}%)\")" 307 | ], 308 | "id": "41d9a88cc48569e8", 309 | "outputs": [ 310 | { 311 | "name": "stdout", 312 | "output_type": "stream", 313 | "text": [ 314 | "1: Python (68%)\n", 315 | "2: Java (52%)\n", 316 | "3: SQL (48%)\n", 317 | "4: JavaScript (40%)\n", 318 | "5: C (28%)\n", 319 | "6: C++ (28%)\n", 320 | "7: Perl (24%)\n", 321 | "8: Visual Basic (16%)\n", 322 | "9: Cobol (12%)\n", 323 | "10: Fortran (12%)\n", 324 | "11: R (12%)\n", 325 | "12: Ruby (12%)\n", 326 | "13: Assembly (8%)\n", 327 | "14: C# (8%)\n", 328 | "15: PHP (8%)\n", 329 | "16: Pascal (8%)\n", 330 | "17: TypeScript (8%)\n", 331 | "18: Dart (4%)\n", 332 | "19: Kotlin (4%)\n", 333 | "20: Lisp (4%)\n", 334 | "21: Matlab (4%)\n", 335 | "22: Objective-C (4%)\n", 336 | "23: Rust (4%)\n", 337 | "24: Swift (4%)\n", 338 | "25: Clojure (0%)\n", 339 | "26: Delphi (0%)\n", 340 | "27: Elixir (0%)\n", 341 | "28: Go (0%)\n", 342 | "29: Haskell (0%)\n", 343 | "30: Julia (0%)\n", 344 | "31: Lua (0%)\n", 345 | "32: Scala (0%)\n" 346 | ] 347 | } 348 | ], 349 | "execution_count": 8 350 | }, 351 | { 352 | "metadata": { 353 | "ExecuteTime": { 354 | "end_time": "2025-10-21T18:11:28.359329Z", 355 | "start_time": "2025-10-21T18:11:28.358154Z" 356 | } 357 | }, 358 | "cell_type": "code", 359 | "source": "", 360 | "id": "6fdc86a969c058eb", 361 | "outputs": [], 362 | "execution_count": null 363 | } 364 | ], 365 | "metadata": { 366 | "jupytext": { 367 | "cell_metadata_filter": "-all", 368 | "formats": "auto:light,ipynb", 369 | "main_language": "python", 370 | "notebook_metadata_filter": "-all" 371 | }, 372 | "kernelspec": { 373 | "display_name": "Python 3 (ipykernel)", 374 | "language": "python", 375 | "name": "python3" 376 | }, 377 | "language_info": { 378 | "codemirror_mode": { 379 | "name": "ipython", 380 | "version": 3 381 | }, 382 | "file_extension": ".py", 383 | "mimetype": "text/x-python", 384 | "name": "python", 385 | "nbconvert_exporter": "python", 386 | "pygments_lexer": "ipython3", 387 | "version": "3.11.4" 388 | } 389 | }, 390 | "nbformat": 4, 391 | "nbformat_minor": 5 392 | } 393 | -------------------------------------------------------------------------------- /content/project/sample_solutions/proj_2_comprehensions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "57cb35c4", 6 | "metadata": {}, 7 | "source": [ 8 | "# Survey analysis\n", 9 | "Analyse the results from the [languages survey](https://forms.gle/5b3mZRVcgAsoNG1FA)" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "id": "beb28a4b", 15 | "metadata": { 16 | "ExecuteTime": { 17 | "end_time": "2025-10-21T18:11:28.298617Z", 18 | "start_time": "2025-10-21T18:11:28.294166Z" 19 | } 20 | }, 21 | "source": [ 22 | "all_langs = ['Python', 'Java', 'JavaScript', 'TypeScript', 'PHP', 'SQL', 'C', 'C++', 'C#',\n", 23 | " 'Ruby', 'R', 'Matlab', 'Go', 'Rust', 'Objective-C', 'Swift', 'Visual Basic',\n", 24 | " 'Perl', 'Cobol', 'Fortran', 'Lisp', 'Assembly', 'Kotlin', 'Dart', 'Scala',\n", 25 | " 'Lua', 'Delphi', 'Haskell', 'Julia', 'Clojure', 'Elixir', 'Pascal']" 26 | ], 27 | "outputs": [], 28 | "execution_count": 1 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "id": "bcc1c3f1", 33 | "metadata": {}, 34 | "source": [ 35 | "## Load data" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "id": "44b83567", 41 | "metadata": { 42 | "ExecuteTime": { 43 | "end_time": "2025-10-21T18:58:10.337662Z", 44 | "start_time": "2025-10-21T18:58:10.332391Z" 45 | } 46 | }, 47 | "source": [ 48 | "import csv\n", 49 | "from pprint import pprint\n", 50 | "\n", 51 | "with open('../data/Survey-2024-Jan.csv') as file:\n", 52 | " file.readline() # Ignore first line (header)\n", 53 | " reader = csv.DictReader(file, fieldnames=('timestamp', 'languages', 'years')) # list of dicts with keys passed into fieldnames\n", 54 | " lang_responses = [\n", 55 | " response['languages'].split(';')\n", 56 | " for response in reader\n", 57 | " ]\n", 58 | "\n", 59 | "pprint(lang_responses)\n", 60 | "num_responses = len(lang_responses)\n", 61 | "print(num_responses)\n" 62 | ], 63 | "outputs": [ 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "[['Python', 'SQL'],\n", 69 | " ['Python'],\n", 70 | " ['Python'],\n", 71 | " ['Java',\n", 72 | " 'JavaScript',\n", 73 | " 'SQL',\n", 74 | " 'C',\n", 75 | " 'C++',\n", 76 | " 'Visual Basic',\n", 77 | " 'Perl',\n", 78 | " 'Cobol',\n", 79 | " 'Fortran',\n", 80 | " 'Assembly',\n", 81 | " 'Pascal'],\n", 82 | " ['Python', 'Perl'],\n", 83 | " ['JavaScript', 'TypeScript', 'PHP', 'SQL', 'C++', 'Visual Basic', 'Perl'],\n", 84 | " ['Python', 'Java', 'C++', 'Perl'],\n", 85 | " ['Python',\n", 86 | " 'Java',\n", 87 | " 'JavaScript',\n", 88 | " 'TypeScript',\n", 89 | " 'PHP',\n", 90 | " 'SQL',\n", 91 | " 'Ruby',\n", 92 | " 'R',\n", 93 | " 'Objective-C',\n", 94 | " 'Swift',\n", 95 | " 'Perl',\n", 96 | " 'Kotlin',\n", 97 | " 'Dart'],\n", 98 | " ['Python',\n", 99 | " 'Java',\n", 100 | " 'JavaScript',\n", 101 | " 'SQL',\n", 102 | " 'C',\n", 103 | " 'C++',\n", 104 | " 'Matlab',\n", 105 | " 'Visual Basic',\n", 106 | " 'Cobol',\n", 107 | " 'Fortran',\n", 108 | " 'Assembly'],\n", 109 | " ['Java', 'JavaScript'],\n", 110 | " ['Python', 'Java', 'JavaScript', 'SQL', 'C', 'C++'],\n", 111 | " ['Python', 'SQL', 'C', 'R'],\n", 112 | " ['Java', 'C++'],\n", 113 | " ['SQL', 'R'],\n", 114 | " ['Python', 'Java'],\n", 115 | " ['Ruby', 'Fortran', 'Lisp'],\n", 116 | " ['Python', 'Java', 'C#', 'Ruby', 'Visual Basic', 'Cobol', 'Pascal'],\n", 117 | " ['SQL'],\n", 118 | " ['Python', 'Java', 'JavaScript', 'C', 'Rust'],\n", 119 | " ['Python', 'JavaScript', 'Perl'],\n", 120 | " ['Java', 'SQL', 'C#'],\n", 121 | " ['Python', 'Java'],\n", 122 | " ['Python', 'JavaScript', 'SQL', 'C'],\n", 123 | " ['Python', 'SQL', 'C', 'C++'],\n", 124 | " ['Python', 'Java', 'JavaScript']]\n", 125 | "25\n" 126 | ] 127 | } 128 | ], 129 | "execution_count": 15 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "id": "b7ecbf4b", 134 | "metadata": {}, 135 | "source": [ 136 | "## Find number of languages known\n", 137 | "Print `\"{# known by class} / {# in list} languages known by this class\"`.\n", 138 | "\n", 139 | "E.g. **12/21 languages known by this class**" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "id": "535c48b5", 145 | "metadata": { 146 | "ExecuteTime": { 147 | "end_time": "2025-10-21T18:58:56.642770Z", 148 | "start_time": "2025-10-21T18:58:56.630082Z" 149 | } 150 | }, 151 | "source": [ 152 | "langs_known = {lang for langs in lang_responses for lang in langs}\n", 153 | "\n", 154 | "print(f\"{len(langs_known)} / {len(all_langs)} languages known by this class\")" 155 | ], 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "24 / 32 languages known by this class\n" 162 | ] 163 | } 164 | ], 165 | "execution_count": 16 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "id": "8854f96e", 170 | "metadata": {}, 171 | "source": [ 172 | "## List languages not known by anyone in the class" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "id": "88f7d084", 178 | "metadata": { 179 | "ExecuteTime": { 180 | "end_time": "2025-10-21T19:00:12.169472Z", 181 | "start_time": "2025-10-21T19:00:12.159735Z" 182 | } 183 | }, 184 | "source": [ 185 | "not_known = [lang for lang in all_langs if lang not in langs_known]\n", 186 | "\n", 187 | "print(sorted(not_known))\n", 188 | "print(len(not_known))" 189 | ], 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | "['Clojure', 'Delphi', 'Elixir', 'Go', 'Haskell', 'Julia', 'Lua', 'Scala']\n", 196 | "8\n" 197 | ] 198 | } 199 | ], 200 | "execution_count": 18 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "id": "4e6d082d", 205 | "metadata": {}, 206 | "source": [ 207 | "## Rank languages by most commonly known\n", 208 | "Print each language as `\"{position}: {language} ({percent_known}%)\"`, in order from most to least known\n", 209 | "\n", 210 | "e.g. **1: Python (93%)**" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "id": "b4f73f17", 216 | "metadata": { 217 | "ExecuteTime": { 218 | "end_time": "2025-10-21T19:05:00.780274Z", 219 | "start_time": "2025-10-21T19:05:00.773515Z" 220 | } 221 | }, 222 | "source": [ 223 | "langs_flat = [lang for langs in lang_responses for lang in langs]\n", 224 | "lang_counts = [(langs_flat.count(lang), lang) for lang in all_langs]\n", 225 | "lang_counts" 226 | ], 227 | "outputs": [ 228 | { 229 | "data": { 230 | "text/plain": [ 231 | "[(17, 'Python'),\n", 232 | " (13, 'Java'),\n", 233 | " (10, 'JavaScript'),\n", 234 | " (2, 'TypeScript'),\n", 235 | " (2, 'PHP'),\n", 236 | " (12, 'SQL'),\n", 237 | " (7, 'C'),\n", 238 | " (7, 'C++'),\n", 239 | " (2, 'C#'),\n", 240 | " (3, 'Ruby'),\n", 241 | " (3, 'R'),\n", 242 | " (1, 'Matlab'),\n", 243 | " (0, 'Go'),\n", 244 | " (1, 'Rust'),\n", 245 | " (1, 'Objective-C'),\n", 246 | " (1, 'Swift'),\n", 247 | " (4, 'Visual Basic'),\n", 248 | " (6, 'Perl'),\n", 249 | " (3, 'Cobol'),\n", 250 | " (3, 'Fortran'),\n", 251 | " (1, 'Lisp'),\n", 252 | " (2, 'Assembly'),\n", 253 | " (1, 'Kotlin'),\n", 254 | " (1, 'Dart'),\n", 255 | " (0, 'Scala'),\n", 256 | " (0, 'Lua'),\n", 257 | " (0, 'Delphi'),\n", 258 | " (0, 'Haskell'),\n", 259 | " (0, 'Julia'),\n", 260 | " (0, 'Clojure'),\n", 261 | " (0, 'Elixir'),\n", 262 | " (2, 'Pascal')]" 263 | ] 264 | }, 265 | "execution_count": 25, 266 | "metadata": {}, 267 | "output_type": "execute_result" 268 | } 269 | ], 270 | "execution_count": 25 271 | }, 272 | { 273 | "metadata": { 274 | "ExecuteTime": { 275 | "end_time": "2025-10-21T19:05:24.930646Z", 276 | "start_time": "2025-10-21T19:05:24.928676Z" 277 | } 278 | }, 279 | "cell_type": "code", 280 | "source": "lang_counts.sort(reverse=True)", 281 | "id": "ea5fa98a99766edd", 282 | "outputs": [], 283 | "execution_count": 28 284 | }, 285 | { 286 | "metadata": { 287 | "ExecuteTime": { 288 | "end_time": "2025-10-21T19:05:26.106681Z", 289 | "start_time": "2025-10-21T19:05:26.104376Z" 290 | } 291 | }, 292 | "cell_type": "code", 293 | "source": [ 294 | "for pos, (count, lang) in enumerate(lang_counts, start=1):\n", 295 | " print(f\"{pos}: {lang} ({round(count / num_responses * 100)}%)\")" 296 | ], 297 | "id": "41d9a88cc48569e8", 298 | "outputs": [ 299 | { 300 | "name": "stdout", 301 | "output_type": "stream", 302 | "text": [ 303 | "1: Python (68%)\n", 304 | "2: Java (52%)\n", 305 | "3: SQL (48%)\n", 306 | "4: JavaScript (40%)\n", 307 | "5: C++ (28%)\n", 308 | "6: C (28%)\n", 309 | "7: Perl (24%)\n", 310 | "8: Visual Basic (16%)\n", 311 | "9: Ruby (12%)\n", 312 | "10: R (12%)\n", 313 | "11: Fortran (12%)\n", 314 | "12: Cobol (12%)\n", 315 | "13: TypeScript (8%)\n", 316 | "14: Pascal (8%)\n", 317 | "15: PHP (8%)\n", 318 | "16: C# (8%)\n", 319 | "17: Assembly (8%)\n", 320 | "18: Swift (4%)\n", 321 | "19: Rust (4%)\n", 322 | "20: Objective-C (4%)\n", 323 | "21: Matlab (4%)\n", 324 | "22: Lisp (4%)\n", 325 | "23: Kotlin (4%)\n", 326 | "24: Dart (4%)\n", 327 | "25: Scala (0%)\n", 328 | "26: Lua (0%)\n", 329 | "27: Julia (0%)\n", 330 | "28: Haskell (0%)\n", 331 | "29: Go (0%)\n", 332 | "30: Elixir (0%)\n", 333 | "31: Delphi (0%)\n", 334 | "32: Clojure (0%)\n" 335 | ] 336 | } 337 | ], 338 | "execution_count": 29 339 | }, 340 | { 341 | "metadata": { 342 | "ExecuteTime": { 343 | "end_time": "2025-10-21T18:11:28.359329Z", 344 | "start_time": "2025-10-21T18:11:28.358154Z" 345 | } 346 | }, 347 | "cell_type": "code", 348 | "source": "", 349 | "id": "6fdc86a969c058eb", 350 | "outputs": [], 351 | "execution_count": null 352 | } 353 | ], 354 | "metadata": { 355 | "jupytext": { 356 | "cell_metadata_filter": "-all", 357 | "formats": "auto:light,ipynb", 358 | "main_language": "python", 359 | "notebook_metadata_filter": "-all" 360 | }, 361 | "kernelspec": { 362 | "display_name": "Python 3 (ipykernel)", 363 | "language": "python", 364 | "name": "python3" 365 | }, 366 | "language_info": { 367 | "codemirror_mode": { 368 | "name": "ipython", 369 | "version": 3 370 | }, 371 | "file_extension": ".py", 372 | "mimetype": "text/x-python", 373 | "name": "python", 374 | "nbconvert_exporter": "python", 375 | "pygments_lexer": "ipython3", 376 | "version": "3.11.4" 377 | } 378 | }, 379 | "nbformat": 4, 380 | "nbformat_minor": 5 381 | } 382 | -------------------------------------------------------------------------------- /content/examples/ex_14_deque.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "1a5ce425", 6 | "metadata": {}, 7 | "source": [ 8 | "# Deque\n", 9 | "A builtin linked list that can be used for stacks and queues." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "id": "fffc7c41", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "from collections import deque" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "id": "a66b2e5e", 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "data": { 30 | "text/plain": [ 31 | "deque([1, 2, 3])" 32 | ] 33 | }, 34 | "execution_count": 2, 35 | "metadata": {}, 36 | "output_type": "execute_result" 37 | } 38 | ], 39 | "source": [ 40 | "a = deque([1, 2, 3])\n", 41 | "a" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "id": "0202b10a", 47 | "metadata": {}, 48 | "source": [ 49 | "## Stack\n", 50 | "Last in, first out.\n", 51 | "### Using the tail as the top of the stack\n", 52 | "Use `.append()` and `.pop()` to add/remove from the end of the `list`/`deque`." 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "id": "451e7a56", 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "data": { 63 | "text/plain": [ 64 | "3" 65 | ] 66 | }, 67 | "execution_count": 3, 68 | "metadata": {}, 69 | "output_type": "execute_result" 70 | } 71 | ], 72 | "source": [ 73 | "last = a.pop()\n", 74 | "last" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 4, 80 | "id": "eaf35e08", 81 | "metadata": {}, 82 | "outputs": [ 83 | { 84 | "data": { 85 | "text/plain": [ 86 | "deque([1, 2, 4])" 87 | ] 88 | }, 89 | "execution_count": 4, 90 | "metadata": {}, 91 | "output_type": "execute_result" 92 | } 93 | ], 94 | "source": [ 95 | "a.append(4)\n", 96 | "a" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 5, 102 | "id": "2efc5f23", 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "name": "stdout", 107 | "output_type": "stream", 108 | "text": [ 109 | "4\n", 110 | "2\n", 111 | "1\n" 112 | ] 113 | } 114 | ], 115 | "source": [ 116 | "for _ in range(len(a)):\n", 117 | " print(a.pop())" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 6, 123 | "id": "5a79d624", 124 | "metadata": {}, 125 | "outputs": [ 126 | { 127 | "name": "stdout", 128 | "output_type": "stream", 129 | "text": [ 130 | "IndexError('pop from an empty deque')\n" 131 | ] 132 | } 133 | ], 134 | "source": [ 135 | "try:\n", 136 | " a.pop()\n", 137 | "except Exception as e:\n", 138 | " print(repr(e))" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "id": "655f5ce7", 144 | "metadata": {}, 145 | "source": [ 146 | "### Using the head as the top of the stack\n", 147 | "Use `.appendleft()` and `.popleft()` to add/remove from the front." 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 7, 153 | "id": "9339e086", 154 | "metadata": {}, 155 | "outputs": [ 156 | { 157 | "data": { 158 | "text/plain": [ 159 | "deque([1, 2, 3])" 160 | ] 161 | }, 162 | "execution_count": 7, 163 | "metadata": {}, 164 | "output_type": "execute_result" 165 | } 166 | ], 167 | "source": [ 168 | "b = deque([1, 2, 3])\n", 169 | "b" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 8, 175 | "id": "cb10e674", 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "data": { 180 | "text/plain": [ 181 | "1" 182 | ] 183 | }, 184 | "execution_count": 8, 185 | "metadata": {}, 186 | "output_type": "execute_result" 187 | } 188 | ], 189 | "source": [ 190 | "first = b.popleft()\n", 191 | "first" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 9, 197 | "id": "d66710b3", 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "data": { 202 | "text/plain": [ 203 | "deque([4, 2, 3])" 204 | ] 205 | }, 206 | "execution_count": 9, 207 | "metadata": {}, 208 | "output_type": "execute_result" 209 | } 210 | ], 211 | "source": [ 212 | "b.appendleft(4)\n", 213 | "b" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 10, 219 | "id": "4e7f4e4f", 220 | "metadata": {}, 221 | "outputs": [ 222 | { 223 | "name": "stdout", 224 | "output_type": "stream", 225 | "text": [ 226 | "4\n", 227 | "2\n", 228 | "3\n" 229 | ] 230 | } 231 | ], 232 | "source": [ 233 | "for _ in range(len(b)):\n", 234 | " print(b.popleft())" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": 11, 240 | "id": "63083de5", 241 | "metadata": {}, 242 | "outputs": [ 243 | { 244 | "name": "stdout", 245 | "output_type": "stream", 246 | "text": [ 247 | "IndexError('pop from an empty deque')\n" 248 | ] 249 | } 250 | ], 251 | "source": [ 252 | "try:\n", 253 | " a.popleft()\n", 254 | "except Exception as e:\n", 255 | " print(repr(e))" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "id": "a452351d", 261 | "metadata": {}, 262 | "source": [ 263 | "## Create a custom stack or queue \n", 264 | "They generally use **push** and **pop** as method names.\n", 265 | "### Stack\n", 266 | "Last in, first out" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 12, 272 | "id": "c89e3bf6", 273 | "metadata": {}, 274 | "outputs": [], 275 | "source": [ 276 | "class Stack(deque):\n", 277 | " def push(self, val):\n", 278 | " self.appendleft(val)\n", 279 | " \n", 280 | " def pop(self):\n", 281 | " return self.popleft()\n", 282 | " \n", 283 | " # If you want to remove methods, override it and use pass or raise an Exception" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 13, 289 | "id": "24b63572", 290 | "metadata": {}, 291 | "outputs": [ 292 | { 293 | "data": { 294 | "text/plain": [ 295 | "Stack([])" 296 | ] 297 | }, 298 | "execution_count": 13, 299 | "metadata": {}, 300 | "output_type": "execute_result" 301 | } 302 | ], 303 | "source": [ 304 | "my_stack = Stack()\n", 305 | "my_stack" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 14, 311 | "id": "e0504405", 312 | "metadata": {}, 313 | "outputs": [ 314 | { 315 | "data": { 316 | "text/plain": [ 317 | "Stack(['d', 'c', 'b', 'a'])" 318 | ] 319 | }, 320 | "execution_count": 14, 321 | "metadata": {}, 322 | "output_type": "execute_result" 323 | } 324 | ], 325 | "source": [ 326 | "for c in 'abcd':\n", 327 | " my_stack.push(c)\n", 328 | "my_stack" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": 15, 334 | "id": "ab138440", 335 | "metadata": {}, 336 | "outputs": [ 337 | { 338 | "data": { 339 | "text/plain": [ 340 | "'d'" 341 | ] 342 | }, 343 | "execution_count": 15, 344 | "metadata": {}, 345 | "output_type": "execute_result" 346 | } 347 | ], 348 | "source": [ 349 | "my_stack.pop()" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 16, 355 | "id": "6fac654a", 356 | "metadata": {}, 357 | "outputs": [ 358 | { 359 | "name": "stdout", 360 | "output_type": "stream", 361 | "text": [ 362 | "c\n", 363 | "b\n", 364 | "a\n" 365 | ] 366 | } 367 | ], 368 | "source": [ 369 | "for _ in range(len(my_stack)):\n", 370 | " print(my_stack.pop())" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "id": "7ad7ef8e", 376 | "metadata": {}, 377 | "source": [ 378 | "### Custom queue\n", 379 | "First in, first out" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": 17, 385 | "id": "0e432803", 386 | "metadata": {}, 387 | "outputs": [], 388 | "source": [ 389 | "class Queue(deque):\n", 390 | " def push(self, val):\n", 391 | " self.appendleft(val)\n", 392 | " \n", 393 | " # .pop() is already implemented\n", 394 | " \n", 395 | " # If you want to remove methods, override it and use pass or raise an Exception" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 18, 401 | "id": "1650b1b1", 402 | "metadata": {}, 403 | "outputs": [ 404 | { 405 | "data": { 406 | "text/plain": [ 407 | "Queue([])" 408 | ] 409 | }, 410 | "execution_count": 18, 411 | "metadata": {}, 412 | "output_type": "execute_result" 413 | } 414 | ], 415 | "source": [ 416 | "my_q = Queue()\n", 417 | "my_q" 418 | ] 419 | }, 420 | { 421 | "cell_type": "code", 422 | "execution_count": 19, 423 | "id": "cb225932", 424 | "metadata": {}, 425 | "outputs": [ 426 | { 427 | "data": { 428 | "text/plain": [ 429 | "Queue(['d', 'c', 'b', 'a'])" 430 | ] 431 | }, 432 | "execution_count": 19, 433 | "metadata": {}, 434 | "output_type": "execute_result" 435 | } 436 | ], 437 | "source": [ 438 | "for c in 'abcd':\n", 439 | " my_q.push(c)\n", 440 | "my_q" 441 | ] 442 | }, 443 | { 444 | "cell_type": "code", 445 | "execution_count": 20, 446 | "id": "ce457d2c", 447 | "metadata": {}, 448 | "outputs": [ 449 | { 450 | "data": { 451 | "text/plain": [ 452 | "'a'" 453 | ] 454 | }, 455 | "execution_count": 20, 456 | "metadata": {}, 457 | "output_type": "execute_result" 458 | } 459 | ], 460 | "source": [ 461 | "my_q.pop()" 462 | ] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "execution_count": 21, 467 | "id": "94b23981", 468 | "metadata": {}, 469 | "outputs": [ 470 | { 471 | "name": "stdout", 472 | "output_type": "stream", 473 | "text": [ 474 | "b\n", 475 | "c\n", 476 | "d\n" 477 | ] 478 | } 479 | ], 480 | "source": [ 481 | "for _ in range(len(my_q)):\n", 482 | " print(my_q.pop())" 483 | ] 484 | } 485 | ], 486 | "metadata": { 487 | "jupytext": { 488 | "cell_metadata_filter": "-all", 489 | "formats": "auto:light,ipynb", 490 | "main_language": "python", 491 | "notebook_metadata_filter": "-all" 492 | }, 493 | "kernelspec": { 494 | "display_name": "Python 3 (ipykernel)", 495 | "language": "python", 496 | "name": "python3" 497 | }, 498 | "language_info": { 499 | "codemirror_mode": { 500 | "name": "ipython", 501 | "version": 3 502 | }, 503 | "file_extension": ".py", 504 | "mimetype": "text/x-python", 505 | "name": "python", 506 | "nbconvert_exporter": "python", 507 | "pygments_lexer": "ipython3", 508 | "version": "3.11.4" 509 | } 510 | }, 511 | "nbformat": 4, 512 | "nbformat_minor": 5 513 | } 514 | -------------------------------------------------------------------------------- /content/examples/ex_15_counter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "46dad6c9", 6 | "metadata": {}, 7 | "source": [ 8 | "# collections.Counter\n", 9 | "Also called a multiset or bag, `Counter` keeps track of how many times an element is included in a set." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "id": "8686ecc2", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "from collections import Counter" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "id": "366d6f6d", 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "data": { 30 | "text/plain": [ 31 | "Counter({'silver': 4, 'copper': 3, 'gold': 1})" 32 | ] 33 | }, 34 | "execution_count": 2, 35 | "metadata": {}, 36 | "output_type": "execute_result" 37 | } 38 | ], 39 | "source": [ 40 | "coins = Counter()\n", 41 | "coins.update(['silver', 'silver', 'gold'])\n", 42 | "coins.update({'copper': 3, 'silver': 2})\n", 43 | "coins" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "id": "778e4e86", 49 | "metadata": {}, 50 | "source": [ 51 | "It's like a specialized `dict`, where the **key** is an element and the **value** is an integer of counts.\n", 52 | "## Creating counters \n", 53 | "### From a sequence\n", 54 | "If the sequence can contain duplicates, like `list` or `tuple`, it will keep track of item counts" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 3, 60 | "id": "7e1c9fc6", 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "data": { 65 | "text/plain": [ 66 | "Counter({1: 4, 3: 2, 2: 1, 4: 1})" 67 | ] 68 | }, 69 | "execution_count": 3, 70 | "metadata": {}, 71 | "output_type": "execute_result" 72 | } 73 | ], 74 | "source": [ 75 | "a = Counter([1, 1, 3, 2, 1, 3, 4, 1])\n", 76 | "a" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "id": "d3226a07", 82 | "metadata": {}, 83 | "source": [ 84 | "Sets remove duplicates when created, each count will be 1." 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 4, 90 | "id": "718b5a0d", 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "Counter({1: 1, 2: 1, 3: 1, 4: 1})" 97 | ] 98 | }, 99 | "execution_count": 4, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "b = Counter({1, 1, 3, 2, 1, 3, 4, 1})\n", 106 | "b" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "id": "83c0ebd6", 112 | "metadata": {}, 113 | "source": [ 114 | "### From a dictionary\n", 115 | "It will treat `{key: value}` as `{element: count}`" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 5, 121 | "id": "314ed85b", 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/plain": [ 127 | "Counter({'b': 5, 'a': 2, 'c': 1})" 128 | ] 129 | }, 130 | "execution_count": 5, 131 | "metadata": {}, 132 | "output_type": "execute_result" 133 | } 134 | ], 135 | "source": [ 136 | "c = Counter({'a': 2, 'b': 5, 'c': 1})\n", 137 | "c" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "id": "9e005640", 143 | "metadata": { 144 | "lines_to_next_cell": 2 145 | }, 146 | "source": [ 147 | "## Updating\n", 148 | "You can pass in a sequence or dict of counts." 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 6, 154 | "id": "bccfa417", 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "data": { 159 | "text/plain": [ 160 | "Counter()" 161 | ] 162 | }, 163 | "execution_count": 6, 164 | "metadata": {}, 165 | "output_type": "execute_result" 166 | } 167 | ], 168 | "source": [ 169 | "d = Counter()\n", 170 | "d" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "id": "090740cb", 176 | "metadata": {}, 177 | "source": [ 178 | "`.update()` to adds items (uses the `+` operator)" 179 | ] 180 | }, 181 | { 182 | "cell_type": "code", 183 | "execution_count": 7, 184 | "id": "4a9e8960", 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "data": { 189 | "text/plain": [ 190 | "Counter({'b': 3, 'a': 1})" 191 | ] 192 | }, 193 | "execution_count": 7, 194 | "metadata": {}, 195 | "output_type": "execute_result" 196 | } 197 | ], 198 | "source": [ 199 | "d.update('abbb')\n", 200 | "d" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 8, 206 | "id": "f14a4f33", 207 | "metadata": {}, 208 | "outputs": [ 209 | { 210 | "data": { 211 | "text/plain": [ 212 | "Counter({'b': 3, 'a': 2, 'c': 1})" 213 | ] 214 | }, 215 | "execution_count": 8, 216 | "metadata": {}, 217 | "output_type": "execute_result" 218 | } 219 | ], 220 | "source": [ 221 | "d.update({'c', 'c', 'a'}) # c is only counted once in a normal set\n", 222 | "d" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": 9, 228 | "id": "b0036a6b", 229 | "metadata": {}, 230 | "outputs": [ 231 | { 232 | "data": { 233 | "text/plain": [ 234 | "Counter({'b': 3, 'a': 2, 'd': 2, 'c': -2})" 235 | ] 236 | }, 237 | "execution_count": 9, 238 | "metadata": {}, 239 | "output_type": "execute_result" 240 | } 241 | ], 242 | "source": [ 243 | "d.update({'c':-3, 'd': 2})\n", 244 | "d" 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "id": "2f14184b", 250 | "metadata": {}, 251 | "source": [ 252 | "`.subtract()` removes items (uses the `-` operator)" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 10, 258 | "id": "4926d9dd", 259 | "metadata": {}, 260 | "outputs": [ 261 | { 262 | "data": { 263 | "text/plain": [ 264 | "Counter({'d': 2, 'a': 1, 'b': 0, 'c': -2})" 265 | ] 266 | }, 267 | "execution_count": 10, 268 | "metadata": {}, 269 | "output_type": "execute_result" 270 | } 271 | ], 272 | "source": [ 273 | "d.subtract('abbb')\n", 274 | "d" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 11, 280 | "id": "0c07d5ca", 281 | "metadata": {}, 282 | "outputs": [ 283 | { 284 | "data": { 285 | "text/plain": [ 286 | "Counter({'a': 4, 'd': 2, 'c': -2, 'b': -3})" 287 | ] 288 | }, 289 | "execution_count": 11, 290 | "metadata": {}, 291 | "output_type": "execute_result" 292 | } 293 | ], 294 | "source": [ 295 | "d.subtract({'a': -3, 'b': 3})\n", 296 | "d" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "id": "2c386ddf", 302 | "metadata": {}, 303 | "source": [ 304 | "## Counters are like dictionaries" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 12, 310 | "id": "79671997", 311 | "metadata": {}, 312 | "outputs": [ 313 | { 314 | "data": { 315 | "text/plain": [ 316 | "4" 317 | ] 318 | }, 319 | "execution_count": 12, 320 | "metadata": {}, 321 | "output_type": "execute_result" 322 | } 323 | ], 324 | "source": [ 325 | "d['a']" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": 13, 331 | "id": "0585d1ab", 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "2" 338 | ] 339 | }, 340 | "execution_count": 13, 341 | "metadata": {}, 342 | "output_type": "execute_result" 343 | } 344 | ], 345 | "source": [ 346 | "d.get('d', 0)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 14, 352 | "id": "7dcabdc4", 353 | "metadata": {}, 354 | "outputs": [ 355 | { 356 | "data": { 357 | "text/plain": [ 358 | "0" 359 | ] 360 | }, 361 | "execution_count": 14, 362 | "metadata": {}, 363 | "output_type": "execute_result" 364 | } 365 | ], 366 | "source": [ 367 | "d.get('e', 0)" 368 | ] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": 15, 373 | "id": "81778038", 374 | "metadata": {}, 375 | "outputs": [], 376 | "source": [ 377 | "d['c'] = 1" 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": 16, 383 | "id": "bff12e0f", 384 | "metadata": {}, 385 | "outputs": [ 386 | { 387 | "name": "stdout", 388 | "output_type": "stream", 389 | "text": [ 390 | "a: 4\n", 391 | "b: -3\n", 392 | "c: 1\n", 393 | "d: 2\n" 394 | ] 395 | } 396 | ], 397 | "source": [ 398 | "for key, value in d.items():\n", 399 | " print(f'{key}: {value}')" 400 | ] 401 | }, 402 | { 403 | "cell_type": "markdown", 404 | "id": "54cafde5", 405 | "metadata": {}, 406 | "source": [ 407 | "## Special Counter methods\n", 408 | "`.elements()` is an iterator of all the elements, repeating each value as many times as its count" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": 17, 414 | "id": "1dd42444", 415 | "metadata": {}, 416 | "outputs": [ 417 | { 418 | "name": "stdout", 419 | "output_type": "stream", 420 | "text": [ 421 | "a\n", 422 | "a\n", 423 | "a\n", 424 | "a\n", 425 | "c\n", 426 | "d\n", 427 | "d\n" 428 | ] 429 | } 430 | ], 431 | "source": [ 432 | "for element in d.elements(): # negative integer counts won't be included\n", 433 | " print(element)" 434 | ] 435 | }, 436 | { 437 | "cell_type": "markdown", 438 | "id": "ac21db92", 439 | "metadata": {}, 440 | "source": [ 441 | "`.elements()` expects all counts to be integers" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 18, 447 | "id": "eee6540a", 448 | "metadata": {}, 449 | "outputs": [ 450 | { 451 | "data": { 452 | "text/plain": [ 453 | "Counter({'a': 4, 'd': 2, 'c': 1.0, 'b': -3})" 454 | ] 455 | }, 456 | "execution_count": 18, 457 | "metadata": {}, 458 | "output_type": "execute_result" 459 | } 460 | ], 461 | "source": [ 462 | "d['c'] = 1.0\n", 463 | "d" 464 | ] 465 | }, 466 | { 467 | "cell_type": "code", 468 | "execution_count": 19, 469 | "id": "30150434", 470 | "metadata": {}, 471 | "outputs": [ 472 | { 473 | "name": "stdout", 474 | "output_type": "stream", 475 | "text": [ 476 | "a\n", 477 | "a\n", 478 | "a\n", 479 | "a\n", 480 | "TypeError(\"'float' object cannot be interpreted as an integer\")\n" 481 | ] 482 | } 483 | ], 484 | "source": [ 485 | "try:\n", 486 | " for value in d.elements():\n", 487 | " print(value)\n", 488 | "except Exception as ex:\n", 489 | " print(repr(ex))" 490 | ] 491 | }, 492 | { 493 | "cell_type": "markdown", 494 | "id": "7b52f5e8", 495 | "metadata": {}, 496 | "source": [ 497 | "`.most_common()` will return a list of the most common elements as `(element, count)`. If you pass an integer `n`, only that number are returned." 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": 20, 503 | "id": "2e9955c0", 504 | "metadata": {}, 505 | "outputs": [ 506 | { 507 | "data": { 508 | "text/plain": [ 509 | "[('a', 4), ('d', 2), ('c', 1.0), ('b', -3)]" 510 | ] 511 | }, 512 | "execution_count": 20, 513 | "metadata": {}, 514 | "output_type": "execute_result" 515 | } 516 | ], 517 | "source": [ 518 | "d.most_common()" 519 | ] 520 | }, 521 | { 522 | "cell_type": "code", 523 | "execution_count": 21, 524 | "id": "74c0faca", 525 | "metadata": {}, 526 | "outputs": [ 527 | { 528 | "data": { 529 | "text/plain": [ 530 | "[('a', 4), ('d', 2)]" 531 | ] 532 | }, 533 | "execution_count": 21, 534 | "metadata": {}, 535 | "output_type": "execute_result" 536 | } 537 | ], 538 | "source": [ 539 | "d.most_common(2)" 540 | ] 541 | } 542 | ], 543 | "metadata": { 544 | "jupytext": { 545 | "cell_metadata_filter": "-all", 546 | "formats": "auto:light,ipynb", 547 | "main_language": "python", 548 | "notebook_metadata_filter": "-all" 549 | }, 550 | "kernelspec": { 551 | "display_name": "Python 3 (ipykernel)", 552 | "language": "python", 553 | "name": "python3" 554 | }, 555 | "language_info": { 556 | "codemirror_mode": { 557 | "name": "ipython", 558 | "version": 3 559 | }, 560 | "file_extension": ".py", 561 | "mimetype": "text/x-python", 562 | "name": "python", 563 | "nbconvert_exporter": "python", 564 | "pygments_lexer": "ipython3", 565 | "version": "3.11.4" 566 | } 567 | }, 568 | "nbformat": 4, 569 | "nbformat_minor": 5 570 | } 571 | -------------------------------------------------------------------------------- /content/examples/ex_12_default_dict.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "c148a471", 6 | "metadata": {}, 7 | "source": [ 8 | "# collections.defaultdict\n", 9 | "A common pattern is to check if a key exists in a dictionary and initialize it if not.\n", 10 | "## Without defaultdict" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "id": "a990d3e6", 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "data": { 21 | "text/plain": [ 22 | "{'U': ['United States'],\n", 23 | " 'M': ['Mexico'],\n", 24 | " 'I': ['Iceland', 'India', 'Indonesia'],\n", 25 | " 'P': ['Philippines']}" 26 | ] 27 | }, 28 | "execution_count": 1, 29 | "metadata": {}, 30 | "output_type": "execute_result" 31 | } 32 | ], 33 | "source": [ 34 | "countries = [\"United States\", \"Mexico\", \"Iceland\", \"India\", \"Philippines\", \"Indonesia\"]\n", 35 | "\n", 36 | "letter_countries = {}\n", 37 | "for country in countries:\n", 38 | " first_letter = country[0]\n", 39 | " if first_letter not in letter_countries:\n", 40 | " letter_countries[first_letter] = []\n", 41 | " letter_countries[first_letter].append(country)\n", 42 | "\n", 43 | "letter_countries" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "id": "c39a1314", 49 | "metadata": {}, 50 | "source": [ 51 | "## With defaultdict" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 2, 57 | "id": "ce0187c4", 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "text/plain": [ 63 | "defaultdict(list,\n", 64 | " {'U': ['United States'],\n", 65 | " 'M': ['Mexico'],\n", 66 | " 'I': ['Iceland', 'India', 'Indonesia'],\n", 67 | " 'P': ['Philippines']})" 68 | ] 69 | }, 70 | "execution_count": 2, 71 | "metadata": {}, 72 | "output_type": "execute_result" 73 | } 74 | ], 75 | "source": [ 76 | "from collections import defaultdict\n", 77 | "\n", 78 | "letter_countries = defaultdict(list)\n", 79 | "for country in countries:\n", 80 | " letter_countries[country[0]].append(country)\n", 81 | "\n", 82 | "letter_countries" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "id": "abb978f9", 88 | "metadata": {}, 89 | "source": [ 90 | "## defaultdict\n", 91 | "Like regular dictionaries, but any missing keys have a default value if you try to access them.\n", 92 | "\n", 93 | "You can pass in any callable that doesn't have any required arguments.\n", 94 | "\n", 95 | "A callable can be:\n", 96 | "- a builtin function\n", 97 | "- a user-defined function\n", 98 | "- a lambda function\n", 99 | "- a class\n", 100 | "- a module function\n", 101 | "- an object's method" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 3, 107 | "id": "24878caf", 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "from collections import defaultdict" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "id": "61248aca", 117 | "metadata": {}, 118 | "source": [ 119 | "## Builtin functions\n", 120 | "The builtin types all have associated functions: `int`, `float`, `str`, `list`, `dict`, `tuple`, `set`.\n", 121 | "\n", 122 | "When you call them without arguments, they return an empty container or 0." 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 4, 128 | "id": "1f9b7a22", 129 | "metadata": {}, 130 | "outputs": [ 131 | { 132 | "data": { 133 | "text/plain": [ 134 | "defaultdict(int, {})" 135 | ] 136 | }, 137 | "execution_count": 4, 138 | "metadata": {}, 139 | "output_type": "execute_result" 140 | } 141 | ], 142 | "source": [ 143 | "word_counts = defaultdict(int)\n", 144 | "word_counts" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 5, 150 | "id": "bbabdaa1", 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "data": { 155 | "text/plain": [ 156 | "0" 157 | ] 158 | }, 159 | "execution_count": 5, 160 | "metadata": {}, 161 | "output_type": "execute_result" 162 | } 163 | ], 164 | "source": [ 165 | "word_counts['the']" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 6, 171 | "id": "51b1369b", 172 | "metadata": {}, 173 | "outputs": [ 174 | { 175 | "data": { 176 | "text/plain": [ 177 | "defaultdict(int, {'the': 0})" 178 | ] 179 | }, 180 | "execution_count": 6, 181 | "metadata": {}, 182 | "output_type": "execute_result" 183 | } 184 | ], 185 | "source": [ 186 | "word_counts" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 7, 192 | "id": "b1677830", 193 | "metadata": {}, 194 | "outputs": [ 195 | { 196 | "data": { 197 | "text/plain": [ 198 | "defaultdict(int,\n", 199 | " {'the': 3,\n", 200 | " 'quick': 1,\n", 201 | " 'brown': 2,\n", 202 | " 'fox': 1,\n", 203 | " 'jumps': 1,\n", 204 | " 'over': 1,\n", 205 | " 'lazy': 1,\n", 206 | " 'dog': 1,\n", 207 | " 'and': 1,\n", 208 | " 'cat': 1})" 209 | ] 210 | }, 211 | "execution_count": 7, 212 | "metadata": {}, 213 | "output_type": "execute_result" 214 | } 215 | ], 216 | "source": [ 217 | "phrase = \"the quick brown fox jumps over the lazy dog and the brown cat\"\n", 218 | "for word in phrase.split():\n", 219 | " word_counts[word] += 1\n", 220 | "word_counts" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "id": "50ad93c2", 226 | "metadata": {}, 227 | "source": [ 228 | "## Custom functions\n", 229 | "You can define the function to call. It shouldn't take any arguments." 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 8, 235 | "id": "5a1028a6", 236 | "metadata": {}, 237 | "outputs": [ 238 | { 239 | "name": "stdout", 240 | "output_type": "stream", 241 | "text": [ 242 | "1\n", 243 | "2\n", 244 | "3\n", 245 | "4\n" 246 | ] 247 | }, 248 | { 249 | "data": { 250 | "text/plain": [ 251 | "defaultdict(, {'a': 1, 'b': 2, 'c': 3, 'd': 4})" 252 | ] 253 | }, 254 | "execution_count": 8, 255 | "metadata": {}, 256 | "output_type": "execute_result" 257 | } 258 | ], 259 | "source": [ 260 | "count = 0\n", 261 | "\n", 262 | "def get_count():\n", 263 | " global count\n", 264 | " count += 1\n", 265 | " return count\n", 266 | "\n", 267 | "a = defaultdict(get_count) # No brackets after function\n", 268 | "for i in 'abcd':\n", 269 | " print(a[i])\n", 270 | " \n", 271 | "a" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "id": "dc892d9c", 277 | "metadata": {}, 278 | "source": [ 279 | "## Lambda functions\n", 280 | "For simple one-line functions that you won't need again, you can use lambda (anonymous) functions." 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 9, 286 | "id": "3ed6e1d2", 287 | "metadata": {}, 288 | "outputs": [ 289 | { 290 | "data": { 291 | "text/plain": [ 292 | "defaultdict(()>, {'A': [-2, 0], 'B': [1, 1]})" 293 | ] 294 | }, 295 | "execution_count": 9, 296 | "metadata": {}, 297 | "output_type": "execute_result" 298 | } 299 | ], 300 | "source": [ 301 | "b = defaultdict(lambda: [0, 0])\n", 302 | "\n", 303 | "sprites = {'A': ['L', 'D', 'L', 'U'], 'B': ['R', 'U']}\n", 304 | "\n", 305 | "for sprite, moves in sprites.items():\n", 306 | " for move in moves:\n", 307 | " if move == 'L':\n", 308 | " b[sprite][0] -= 1\n", 309 | " elif move == 'R':\n", 310 | " b[sprite][0] += 1\n", 311 | " elif move == 'D':\n", 312 | " b[sprite][1] -= 1\n", 313 | " elif move == 'U':\n", 314 | " b[sprite][1] += 1\n", 315 | " else:\n", 316 | " print(f\"Invalid move {move}\")\n", 317 | "b" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "id": "f3a0b62b", 323 | "metadata": {}, 324 | "source": [ 325 | "## Class" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": 10, 331 | "id": "f32ecfef", 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "defaultdict(__main__.Person,\n", 338 | " {0: Person(\"Aida\"),\n", 339 | " 1: Person(\"Jia\"),\n", 340 | " 2: Person(\"Lárus\"),\n", 341 | " 3: Person(\"Idrissa\")})" 342 | ] 343 | }, 344 | "execution_count": 10, 345 | "metadata": {}, 346 | "output_type": "execute_result" 347 | } 348 | ], 349 | "source": [ 350 | "class Person:\n", 351 | " def __init__(self, name=''):\n", 352 | " self.name = name\n", 353 | " \n", 354 | " def __repr__(self):\n", 355 | " return f'Person(\"{self.name}\")'\n", 356 | "\n", 357 | "c = defaultdict(Person)\n", 358 | "\n", 359 | "names = [\"Aida\", \"Jia\", \"Lárus\", \"Idrissa\"]\n", 360 | "for i, name in enumerate(names):\n", 361 | " c[i].name = name\n", 362 | "\n", 363 | "c" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "id": "1a39c655", 369 | "metadata": {}, 370 | "source": [ 371 | "## Module function" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 11, 377 | "id": "c0f7e126", 378 | "metadata": { 379 | "lines_to_next_cell": 2 380 | }, 381 | "outputs": [ 382 | { 383 | "name": "stdout", 384 | "output_type": "stream", 385 | "text": [ 386 | "1684356252.131718\n", 387 | "1684356253.1320431\n", 388 | "1684356254.1328871\n", 389 | "1684356255.13824\n" 390 | ] 391 | }, 392 | { 393 | "data": { 394 | "text/plain": [ 395 | "defaultdict(,\n", 396 | " {0: 1684356252.131718,\n", 397 | " 1: 1684356253.1320431,\n", 398 | " 2: 1684356254.1328871,\n", 399 | " 3: 1684356255.13824})" 400 | ] 401 | }, 402 | "execution_count": 11, 403 | "metadata": {}, 404 | "output_type": "execute_result" 405 | } 406 | ], 407 | "source": [ 408 | "from time import (\n", 409 | " time, # Gets current time in secs since the Epoch (00:00 Jan 1, 1970 UTC)\n", 410 | " sleep, # Wait n seconds\n", 411 | ")\n", 412 | "\n", 413 | "d = defaultdict(time)\n", 414 | "for i in range(4):\n", 415 | " print(d[i])\n", 416 | " sleep(1)\n", 417 | "d" 418 | ] 419 | }, 420 | { 421 | "cell_type": "markdown", 422 | "id": "bdd10c06", 423 | "metadata": {}, 424 | "source": [ 425 | "## Method\n", 426 | "I don't know a good reason to do this, but it can be done!" 427 | ] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "execution_count": 12, 432 | "id": "7b049187", 433 | "metadata": {}, 434 | "outputs": [ 435 | { 436 | "data": { 437 | "text/plain": [ 438 | "'c'" 439 | ] 440 | }, 441 | "execution_count": 12, 442 | "metadata": {}, 443 | "output_type": "execute_result" 444 | } 445 | ], 446 | "source": [ 447 | "chars = \"a b c\".split()\n", 448 | "e = defaultdict(chars.pop)\n", 449 | "e[0]" 450 | ] 451 | }, 452 | { 453 | "cell_type": "code", 454 | "execution_count": 13, 455 | "id": "6a781afe", 456 | "metadata": {}, 457 | "outputs": [ 458 | { 459 | "data": { 460 | "text/plain": [ 461 | "['a', 'b', 'd']" 462 | ] 463 | }, 464 | "execution_count": 13, 465 | "metadata": {}, 466 | "output_type": "execute_result" 467 | } 468 | ], 469 | "source": [ 470 | "chars.append('d')\n", 471 | "chars" 472 | ] 473 | }, 474 | { 475 | "cell_type": "code", 476 | "execution_count": 14, 477 | "id": "279dd29d", 478 | "metadata": {}, 479 | "outputs": [ 480 | { 481 | "name": "stdout", 482 | "output_type": "stream", 483 | "text": [ 484 | "c\n", 485 | "d\n", 486 | "b\n" 487 | ] 488 | }, 489 | { 490 | "data": { 491 | "text/plain": [ 492 | "defaultdict(, {0: 'c', 1: 'd', 2: 'b'})" 493 | ] 494 | }, 495 | "execution_count": 14, 496 | "metadata": {}, 497 | "output_type": "execute_result" 498 | } 499 | ], 500 | "source": [ 501 | "for i in range(3):\n", 502 | " print(e[i])\n", 503 | "e" 504 | ] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "execution_count": 15, 509 | "id": "1ff6bbd2", 510 | "metadata": {}, 511 | "outputs": [ 512 | { 513 | "data": { 514 | "text/plain": [ 515 | "['a']" 516 | ] 517 | }, 518 | "execution_count": 15, 519 | "metadata": {}, 520 | "output_type": "execute_result" 521 | } 522 | ], 523 | "source": [ 524 | "chars" 525 | ] 526 | } 527 | ], 528 | "metadata": { 529 | "jupytext": { 530 | "cell_metadata_filter": "-all", 531 | "formats": "auto:light,ipynb", 532 | "main_language": "python", 533 | "notebook_metadata_filter": "-all" 534 | }, 535 | "kernelspec": { 536 | "display_name": "Python 3 (ipykernel)", 537 | "language": "python", 538 | "name": "python3" 539 | }, 540 | "language_info": { 541 | "codemirror_mode": { 542 | "name": "ipython", 543 | "version": 3 544 | }, 545 | "file_extension": ".py", 546 | "mimetype": "text/x-python", 547 | "name": "python", 548 | "nbconvert_exporter": "python", 549 | "pygments_lexer": "ipython3", 550 | "version": "3.11.4" 551 | } 552 | }, 553 | "nbformat": 4, 554 | "nbformat_minor": 5 555 | } 556 | -------------------------------------------------------------------------------- /content/examples/ex_02_tuple.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "371d5bf4", 6 | "metadata": {}, 7 | "source": [ 8 | "# Tuples\n", 9 | "\n", 10 | "Immutable (non-modifiable) lists.\n", 11 | "\n", 12 | "## Creating tuples" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "id": "c27b4316", 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "data": { 23 | "text/plain": [ 24 | "(1, 2, 3)" 25 | ] 26 | }, 27 | "execution_count": 1, 28 | "metadata": {}, 29 | "output_type": "execute_result" 30 | } 31 | ], 32 | "source": [ 33 | "(1, 2, 3)" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "84cf1ca2", 39 | "metadata": {}, 40 | "source": [ 41 | "Be careful with single item tuples. \n", 42 | "\n", 43 | "They need a trailing comma or else it's just an expression." 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "id": "192e9860", 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "data": { 54 | "text/plain": [ 55 | "('Hello',)" 56 | ] 57 | }, 58 | "execution_count": 2, 59 | "metadata": {}, 60 | "output_type": "execute_result" 61 | } 62 | ], 63 | "source": [ 64 | "('Hello',)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 3, 70 | "id": "a34cd2a6", 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "'Goodbye'" 77 | ] 78 | }, 79 | "execution_count": 3, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | } 83 | ], 84 | "source": "('Goodbye') # (\"item\") doesn't create a tuple (it's just \"item\")" 85 | }, 86 | { 87 | "metadata": { 88 | "ExecuteTime": { 89 | "end_time": "2025-06-11T20:18:42.496607Z", 90 | "start_time": "2025-06-11T20:18:42.491235Z" 91 | } 92 | }, 93 | "cell_type": "code", 94 | "source": "type(()) # () creates empty tuples", 95 | "id": "669fa87cbde9c892", 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "tuple" 101 | ] 102 | }, 103 | "execution_count": 23, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "execution_count": 23 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "id": "142b8050-3470-4d1c-a2ff-755c37fbd15d", 113 | "metadata": {}, 114 | "source": [ 115 | "You can create a tuple from an existing collection/iterable, using `tuple()`." 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 4, 121 | "id": "6f48fabf", 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/plain": [ 127 | "('a', 'b', 'c')" 128 | ] 129 | }, 130 | "execution_count": 4, 131 | "metadata": {}, 132 | "output_type": "execute_result" 133 | } 134 | ], 135 | "source": [ 136 | "a = tuple('abc')\n", 137 | "a" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "id": "af668c86", 143 | "metadata": {}, 144 | "source": [ 145 | "## Cannot update tuples" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 5, 151 | "id": "db7aa756", 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "TypeError(\"'tuple' object does not support item assignment\")\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "try:\n", 164 | " a[0] = 'Howdy'\n", 165 | "except Exception as e:\n", 166 | " print(repr(e))" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "id": "18e74c28", 172 | "metadata": {}, 173 | "source": [ 174 | "## Slicing and indexing\n", 175 | "\n", 176 | "It's done just like lists!\n", 177 | "\n", 178 | "## Packing and unpacking\n", 179 | "\n", 180 | "**Packing** happens when you don't include the parentheses" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 6, 186 | "id": "9fade3cc", 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "data": { 191 | "text/plain": [ 192 | "(1.2, 3.4)" 193 | ] 194 | }, 195 | "execution_count": 6, 196 | "metadata": {}, 197 | "output_type": "execute_result" 198 | } 199 | ], 200 | "source": [ 201 | "coords = 1.2, 3.4\n", 202 | "coords" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 7, 208 | "id": "9affaa2b-d0ad-4716-81a5-236c11b5bced", 209 | "metadata": {}, 210 | "outputs": [ 211 | { 212 | "data": { 213 | "text/plain": [ 214 | "tuple" 215 | ] 216 | }, 217 | "execution_count": 7, 218 | "metadata": {}, 219 | "output_type": "execute_result" 220 | } 221 | ], 222 | "source": [ 223 | "type(coords)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "id": "e3753024", 229 | "metadata": {}, 230 | "source": [ 231 | "**Unpacking** happens when you expand a `tuple` into multiple variables" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 9, 237 | "id": "ed9f9d80", 238 | "metadata": {}, 239 | "outputs": [ 240 | { 241 | "name": "stdout", 242 | "output_type": "stream", 243 | "text": [ 244 | "1.2\n", 245 | "3.4\n" 246 | ] 247 | } 248 | ], 249 | "source": [ 250 | "lat, lon = coords\n", 251 | "print(lat)\n", 252 | "print(lon)" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 10, 258 | "id": "061b8d77", 259 | "metadata": {}, 260 | "outputs": [ 261 | { 262 | "data": { 263 | "text/plain": [ 264 | "[3.4, 5.6]" 265 | ] 266 | }, 267 | "execution_count": 10, 268 | "metadata": {}, 269 | "output_type": "execute_result" 270 | } 271 | ], 272 | "source": [ 273 | "a_tuple = 1.2, 3.4, 5.6, 7.8\n", 274 | "x, *y, z = a_tuple\n", 275 | "y" 276 | ] 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "id": "bdf85f3e", 281 | "metadata": {}, 282 | "source": [ 283 | "## When to use tuples" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "id": "439b863c", 289 | "metadata": {}, 290 | "source": [ 291 | "### Representing objects/heterogeneous data" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": 9, 297 | "id": "735e749b", 298 | "metadata": {}, 299 | "outputs": [], 300 | "source": [ 301 | "blue = 0, 0, 255\n", 302 | "colours = ['red', 'green', blue]" 303 | ] 304 | }, 305 | { 306 | "cell_type": "markdown", 307 | "id": "d60c7c01", 308 | "metadata": {}, 309 | "source": [ 310 | "### Swap variable names\n", 311 | "\n", 312 | "Use `tuple` packing and unpacking to do neat stuff.\n", 313 | "\n", 314 | "Without it, you'd need to introduce a temporary 3rd variable." 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 10, 320 | "id": "ab9d1af2", 321 | "metadata": {}, 322 | "outputs": [ 323 | { 324 | "name": "stdout", 325 | "output_type": "stream", 326 | "text": [ 327 | "-100\n", 328 | "100\n" 329 | ] 330 | } 331 | ], 332 | "source": [ 333 | "d = 100\n", 334 | "e = -100\n", 335 | "\n", 336 | "d, e = e, d\n", 337 | "print(d)\n", 338 | "print(e)" 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "id": "4cc6c781", 344 | "metadata": {}, 345 | "source": [ 346 | "### Represent constants/immutable values" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 11, 352 | "id": "745e4111", 353 | "metadata": {}, 354 | "outputs": [], 355 | "source": [ 356 | "paris = (33.66, -95.54)\n", 357 | "athens = (32.20, -95.85)" 358 | ] 359 | }, 360 | { 361 | "cell_type": "markdown", 362 | "id": "8e58eca4", 363 | "metadata": {}, 364 | "source": [ 365 | "### Use as dict keys" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": 12, 371 | "id": "e15411ba", 372 | "metadata": {}, 373 | "outputs": [ 374 | { 375 | "data": { 376 | "text/plain": [ 377 | "{(33.66, -95.54): 'Paris', (32.2, -95.85): 'Athens'}" 378 | ] 379 | }, 380 | "execution_count": 12, 381 | "metadata": {}, 382 | "output_type": "execute_result" 383 | } 384 | ], 385 | "source": [ 386 | "texas_cities = {\n", 387 | " paris: 'Paris',\n", 388 | " athens: 'Athens',\n", 389 | "}\n", 390 | "texas_cities" 391 | ] 392 | }, 393 | { 394 | "cell_type": "markdown", 395 | "id": "1a18e3f3", 396 | "metadata": {}, 397 | "source": [ 398 | "### Return multiple values from a function" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": 13, 404 | "id": "5dfaabc3", 405 | "metadata": {}, 406 | "outputs": [ 407 | { 408 | "name": "stdout", 409 | "output_type": "stream", 410 | "text": [ 411 | "11/2 is 5 remainder 1\n" 412 | ] 413 | } 414 | ], 415 | "source": [ 416 | "def div_mod(x, y):\n", 417 | " div = x // y\n", 418 | " mod = x % y\n", 419 | " return div, mod\n", 420 | "\n", 421 | "quotient, remainder = div_mod(11, 2)\n", 422 | "print(f'11/2 is {quotient} remainder {remainder}')" 423 | ] 424 | }, 425 | { 426 | "cell_type": "markdown", 427 | "id": "05845778", 428 | "metadata": {}, 429 | "source": [ 430 | "**Note**: the builtin `divmod()` exists because the CPU can determine them at the same time, so it saves computing time if you need both." 431 | ] 432 | }, 433 | { 434 | "cell_type": "markdown", 435 | "id": "a3bb6adc", 436 | "metadata": {}, 437 | "source": [ 438 | "### Access multiple items in a loop\n", 439 | "\n", 440 | "When you access multiple variables in `for` loops, you're actually unpacking a `tuple`." 441 | ] 442 | }, 443 | { 444 | "cell_type": "code", 445 | "execution_count": 14, 446 | "id": "cede3ca1", 447 | "metadata": {}, 448 | "outputs": [ 449 | { 450 | "name": "stdout", 451 | "output_type": "stream", 452 | "text": [ 453 | "0: a\n", 454 | "1: b\n", 455 | "2: c\n" 456 | ] 457 | } 458 | ], 459 | "source": [ 460 | "for i, val in enumerate('abc'):\n", 461 | " print(f'{i}: {val}')" 462 | ] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "execution_count": 15, 467 | "id": "0ef37567", 468 | "metadata": {}, 469 | "outputs": [ 470 | { 471 | "name": "stdout", 472 | "output_type": "stream", 473 | "text": [ 474 | "(0, 'a')\n", 475 | "(1, 'b')\n", 476 | "(2, 'c')\n" 477 | ] 478 | } 479 | ], 480 | "source": [ 481 | "for tup in enumerate('abc'):\n", 482 | " print(tup)" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "id": "1b306798", 488 | "metadata": {}, 489 | "source": [ 490 | "### The zip() function\n", 491 | "\n", 492 | "If you want to loop over items two or more sequences simultaneously, you can zip them and loop over the results." 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": 16, 498 | "id": "beb51111", 499 | "metadata": {}, 500 | "outputs": [ 501 | { 502 | "name": "stdout", 503 | "output_type": "stream", 504 | "text": [ 505 | "[(1, 'a'), (2, 'b'), (3, 'c')]\n", 506 | "a\n", 507 | "bb\n", 508 | "ccc\n" 509 | ] 510 | } 511 | ], 512 | "source": [ 513 | "nums = [1, 2, 3]\n", 514 | "letters = ['a', 'b', 'c']\n", 515 | "\n", 516 | "print(list(zip(nums, letters)))\n", 517 | "\n", 518 | "for num, letter in zip(nums, letters):\n", 519 | " print(num * letter)" 520 | ] 521 | }, 522 | { 523 | "cell_type": "markdown", 524 | "id": "7c944643", 525 | "metadata": {}, 526 | "source": [ 527 | "### Practical uses of zip()\n", 528 | "\n", 529 | "Copied from this [Real Python](https://realpython.com/python-zip-function/) article\n", 530 | "\n", 531 | "#### Calculating in pairs\n", 532 | "\n", 533 | "If you have a spreadsheet of `total_sales` and `costs` for multiple months, you can calculate the `profit` for each month and for the whole period." 534 | ] 535 | }, 536 | { 537 | "cell_type": "code", 538 | "execution_count": 17, 539 | "id": "0e487e44", 540 | "metadata": {}, 541 | "outputs": [ 542 | { 543 | "name": "stdout", 544 | "output_type": "stream", 545 | "text": [ 546 | "Profit: $5200.0\n", 547 | "Profit: $5100.0\n", 548 | "Profit: $4800.0\n", 549 | "Total profit: $15,100.0\n" 550 | ] 551 | } 552 | ], 553 | "source": [ 554 | "total_sales_q2 = [52000.00, 51000.00, 48000.00]\n", 555 | "costs_q2 = [46800.00, 45900.00, 43200.00]\n", 556 | "\n", 557 | "profit_q2 = 0\n", 558 | "for sales, costs in zip(total_sales_q2, costs_q2):\n", 559 | " profit = sales - costs\n", 560 | " print(f'Profit: ${profit}')\n", 561 | " profit_q2 += profit\n", 562 | "\n", 563 | "print(f'Total profit: ${profit_q2:,}')" 564 | ] 565 | }, 566 | { 567 | "cell_type": "markdown", 568 | "id": "e1665760", 569 | "metadata": {}, 570 | "source": [ 571 | "#### Building dictionaries" 572 | ] 573 | }, 574 | { 575 | "cell_type": "code", 576 | "execution_count": 18, 577 | "id": "2136d1d5", 578 | "metadata": { 579 | "lines_to_next_cell": 0 580 | }, 581 | "outputs": [ 582 | { 583 | "data": { 584 | "text/plain": [ 585 | "{'name': 'Jasmine', 'last_name': 'Doe', 'age': '45', 'job': 'Python Developer'}" 586 | ] 587 | }, 588 | "execution_count": 18, 589 | "metadata": {}, 590 | "output_type": "execute_result" 591 | } 592 | ], 593 | "source": [ 594 | "fields = ['name', 'last_name', 'age', 'job']\n", 595 | "values = ['Jasmine', 'Doe', '45', 'Python Developer']\n", 596 | "\n", 597 | "person = dict(zip(fields, values))\n", 598 | "person" 599 | ] 600 | }, 601 | { 602 | "cell_type": "code", 603 | "execution_count": null, 604 | "id": "c6be7a5a", 605 | "metadata": { 606 | "lines_to_next_cell": 2 607 | }, 608 | "outputs": [], 609 | "source": [] 610 | } 611 | ], 612 | "metadata": { 613 | "jupytext": { 614 | "cell_metadata_filter": "-all", 615 | "formats": "auto:light,ipynb", 616 | "main_language": "python", 617 | "notebook_metadata_filter": "-all" 618 | }, 619 | "kernelspec": { 620 | "display_name": "Python 3 (ipykernel)", 621 | "language": "python", 622 | "name": "python3" 623 | }, 624 | "language_info": { 625 | "codemirror_mode": { 626 | "name": "ipython", 627 | "version": 3 628 | }, 629 | "file_extension": ".py", 630 | "mimetype": "text/x-python", 631 | "name": "python", 632 | "nbconvert_exporter": "python", 633 | "pygments_lexer": "ipython3", 634 | "version": "3.11.4" 635 | } 636 | }, 637 | "nbformat": 4, 638 | "nbformat_minor": 5 639 | } 640 | -------------------------------------------------------------------------------- /content/examples/ex_05_list_comprehensions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "f965542d", 6 | "metadata": {}, 7 | "source": [ 8 | "# List Comprehensions\n", 9 | "General format:\n", 10 | "`new_list = [expression for member in iterable]`\n", 11 | "## Basic comprehensions" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "id": "6645930d", 18 | "metadata": {}, 19 | "outputs": [ 20 | { 21 | "data": { 22 | "text/plain": [ 23 | "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" 24 | ] 25 | }, 26 | "execution_count": 1, 27 | "metadata": {}, 28 | "output_type": "execute_result" 29 | } 30 | ], 31 | "source": [ 32 | "squares = [i ** 2 for i in range(10)]\n", 33 | "squares" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "48adce36", 39 | "metadata": {}, 40 | "source": [ 41 | "### As for-loop" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "id": "49295b69", 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "data": { 52 | "text/plain": [ 53 | "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" 54 | ] 55 | }, 56 | "execution_count": 2, 57 | "metadata": {}, 58 | "output_type": "execute_result" 59 | } 60 | ], 61 | "source": [ 62 | "squares = []\n", 63 | "for i in range(10):\n", 64 | " squares.append(i ** 2)\n", 65 | "\n", 66 | "squares" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "id": "bc661729", 72 | "metadata": {}, 73 | "source": [ 74 | "## Using conditionals\n", 75 | "Generalized:\n", 76 | "`new_list = [expression for member in iterable if condition]`" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 3, 82 | "id": "d6dbe602", 83 | "metadata": {}, 84 | "outputs": [ 85 | { 86 | "data": { 87 | "text/plain": [ 88 | "[1, 4, 16, 64, 256]" 89 | ] 90 | }, 91 | "execution_count": 3, 92 | "metadata": {}, 93 | "output_type": "execute_result" 94 | } 95 | ], 96 | "source": [ 97 | "evens = [2 ** i for i in range(10) if i % 2 == 0]\n", 98 | "evens" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "id": "765f5439", 104 | "metadata": {}, 105 | "source": [ 106 | "### As for-loop" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 4, 112 | "id": "2f85ee00", 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "text/plain": [ 118 | "[1, 4, 16, 64, 256]" 119 | ] 120 | }, 121 | "execution_count": 4, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "evens = []\n", 128 | "\n", 129 | "for i in range(10):\n", 130 | " if i % 2 == 0:\n", 131 | " evens.append(2 ** i)\n", 132 | "evens" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "id": "dbc31563", 138 | "metadata": {}, 139 | "source": [ 140 | "## With ternary operator" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 5, 146 | "id": "b6002c1c", 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "x = 'a' if True else 'b'\n", 151 | "\n", 152 | "if True:\n", 153 | " x = 'a'\n", 154 | "else:\n", 155 | " x = 'b'" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 6, 161 | "id": "5b7fe22d", 162 | "metadata": {}, 163 | "outputs": [ 164 | { 165 | "data": { 166 | "text/plain": [ 167 | "[True, False, True, False, True, False, True, False, True, False]" 168 | ] 169 | }, 170 | "execution_count": 6, 171 | "metadata": {}, 172 | "output_type": "execute_result" 173 | } 174 | ], 175 | "source": [ 176 | "is_even = [True if i % 2 == 0 else False for i in range(10)]\n", 177 | "is_even" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 7, 183 | "id": "ba83fd83", 184 | "metadata": {}, 185 | "outputs": [ 186 | { 187 | "data": { 188 | "text/plain": [ 189 | "[True, False, True, False, True, False, True, False, True, False]" 190 | ] 191 | }, 192 | "execution_count": 7, 193 | "metadata": {}, 194 | "output_type": "execute_result" 195 | } 196 | ], 197 | "source": [ 198 | "is_even = []\n", 199 | "for i in range(10):\n", 200 | " if i % 2 == 0:\n", 201 | " is_even.append(True)\n", 202 | " else:\n", 203 | " is_even.append(False)\n", 204 | "is_even" 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "id": "4a4e28e1", 210 | "metadata": {}, 211 | "source": [ 212 | "## Nested comprehensions\n", 213 | "### Nested lists" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 8, 219 | "id": "c1bd1ec2", 220 | "metadata": {}, 221 | "outputs": [ 222 | { 223 | "data": { 224 | "text/plain": [ 225 | "[[(0, 0), (0, 1), (0, 2)], [(1, 0), (1, 1), (1, 2)], [(2, 0), (2, 1), (2, 2)]]" 226 | ] 227 | }, 228 | "execution_count": 8, 229 | "metadata": {}, 230 | "output_type": "execute_result" 231 | } 232 | ], 233 | "source": [ 234 | "coords = [\n", 235 | " [(x, y) for y in range(3)]\n", 236 | " for x in range(3)\n", 237 | "]\n", 238 | "coords" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "id": "38e1ae94", 244 | "metadata": {}, 245 | "source": [ 246 | "### Looping over coords" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 9, 252 | "id": "2dd071ae", 253 | "metadata": {}, 254 | "outputs": [ 255 | { 256 | "name": "stdout", 257 | "output_type": "stream", 258 | "text": [ 259 | "[(0, 0), (0, 1), (0, 2)]\n", 260 | "[(1, 0), (1, 1), (1, 2)]\n", 261 | "[(2, 0), (2, 1), (2, 2)]\n" 262 | ] 263 | } 264 | ], 265 | "source": [ 266 | "for row in coords:\n", 267 | " print(row)" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "id": "fd65c801", 273 | "metadata": {}, 274 | "source": [ 275 | "### As for-loop" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 10, 281 | "id": "99115c5c", 282 | "metadata": {}, 283 | "outputs": [ 284 | { 285 | "data": { 286 | "text/plain": [ 287 | "[[(0, 0), (0, 1), (0, 2)], [(1, 0), (1, 1), (1, 2)], [(2, 0), (2, 1), (2, 2)]]" 288 | ] 289 | }, 290 | "execution_count": 10, 291 | "metadata": {}, 292 | "output_type": "execute_result" 293 | } 294 | ], 295 | "source": [ 296 | "coords = []\n", 297 | "for x in range(3):\n", 298 | " row = []\n", 299 | " for y in range(3):\n", 300 | " row.append((x, y))\n", 301 | " coords.append(row)\n", 302 | "coords" 303 | ] 304 | }, 305 | { 306 | "cell_type": "markdown", 307 | "id": "9f2a4f55", 308 | "metadata": {}, 309 | "source": [ 310 | "### Flattened list" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": 11, 316 | "id": "d78b2ec4", 317 | "metadata": {}, 318 | "outputs": [ 319 | { 320 | "data": { 321 | "text/plain": [ 322 | "[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]" 323 | ] 324 | }, 325 | "execution_count": 11, 326 | "metadata": {}, 327 | "output_type": "execute_result" 328 | } 329 | ], 330 | "source": [ 331 | "coords = [(x, y) for x in range(3) for y in range(3)]\n", 332 | "coords" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 12, 338 | "id": "90f8d9dc-0008-4bfd-a559-c458a2edb0d2", 339 | "metadata": {}, 340 | "outputs": [ 341 | { 342 | "data": { 343 | "text/plain": [ 344 | "[7, 2, 6, 1, 4, 5, -2, 8, 0]" 345 | ] 346 | }, 347 | "execution_count": 12, 348 | "metadata": {}, 349 | "output_type": "execute_result" 350 | } 351 | ], 352 | "source": [ 353 | "nums_list = [[7, 2], [6], [1, 4, 5], [-2, 8, 0]]\n", 354 | "nums = [n for li in nums_list for n in li]\n", 355 | "nums" 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "id": "f86e4c0f", 361 | "metadata": {}, 362 | "source": [ 363 | "### As for-loop" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": 13, 369 | "id": "9cb3f840", 370 | "metadata": {}, 371 | "outputs": [ 372 | { 373 | "data": { 374 | "text/plain": [ 375 | "[7, 2, 6, 1, 4, 5, -2, 8, 0]" 376 | ] 377 | }, 378 | "execution_count": 13, 379 | "metadata": {}, 380 | "output_type": "execute_result" 381 | } 382 | ], 383 | "source": [ 384 | "nums = []\n", 385 | "for li in nums_list:\n", 386 | " for n in li:\n", 387 | " nums.append(n)\n", 388 | "nums" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 14, 394 | "id": "537afa17", 395 | "metadata": {}, 396 | "outputs": [ 397 | { 398 | "data": { 399 | "text/plain": [ 400 | "[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]" 401 | ] 402 | }, 403 | "execution_count": 14, 404 | "metadata": {}, 405 | "output_type": "execute_result" 406 | } 407 | ], 408 | "source": [ 409 | "coords = []\n", 410 | "for x in range(3):\n", 411 | " for y in range(3):\n", 412 | " coords.append((x, y))\n", 413 | "coords" 414 | ] 415 | }, 416 | { 417 | "cell_type": "markdown", 418 | "id": "3aa84d52", 419 | "metadata": {}, 420 | "source": [ 421 | "## Complex comprehension example" 422 | ] 423 | }, 424 | { 425 | "cell_type": "code", 426 | "execution_count": 15, 427 | "id": "bf727a7f", 428 | "metadata": {}, 429 | "outputs": [], 430 | "source": [ 431 | "nums_list = [[7, 2], [6], [1, 4, 5], [-2, 8, 0]]" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 16, 437 | "id": "fc026a5b", 438 | "metadata": {}, 439 | "outputs": [ 440 | { 441 | "data": { 442 | "text/plain": [ 443 | "[4, 1, 16, 4, 0]" 444 | ] 445 | }, 446 | "execution_count": 16, 447 | "metadata": {}, 448 | "output_type": "execute_result" 449 | } 450 | ], 451 | "source": [ 452 | "small_nums_squared = [n ** 2\n", 453 | " for li in nums_list\n", 454 | " for n in li\n", 455 | " if n < 5]\n", 456 | "small_nums_squared" 457 | ] 458 | }, 459 | { 460 | "cell_type": "markdown", 461 | "id": "f0cea854", 462 | "metadata": {}, 463 | "source": [ 464 | "### As for-loop" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": 17, 470 | "id": "785f0f6b", 471 | "metadata": {}, 472 | "outputs": [ 473 | { 474 | "data": { 475 | "text/plain": [ 476 | "[2, 1, 4, -2, 0]" 477 | ] 478 | }, 479 | "execution_count": 17, 480 | "metadata": {}, 481 | "output_type": "execute_result" 482 | } 483 | ], 484 | "source": [ 485 | "small_nums = []\n", 486 | "for li in nums_list:\n", 487 | " for n in li:\n", 488 | " if n < 5:\n", 489 | " small_nums.append(n)\n", 490 | "small_nums" 491 | ] 492 | }, 493 | { 494 | "cell_type": "markdown", 495 | "id": "b03b448a", 496 | "metadata": {}, 497 | "source": [ 498 | "## Very complex example" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": 18, 504 | "id": "2eedf8cb", 505 | "metadata": {}, 506 | "outputs": [], 507 | "source": [ 508 | "nums_list = [[7, 2], [6], [1, 4, 5], [-2, 8, 0]]" 509 | ] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "execution_count": 19, 514 | "id": "de5f303a", 515 | "metadata": {}, 516 | "outputs": [ 517 | { 518 | "data": { 519 | "text/plain": [ 520 | "[7, -1, 5]" 521 | ] 522 | }, 523 | "execution_count": 19, 524 | "metadata": {}, 525 | "output_type": "execute_result" 526 | } 527 | ], 528 | "source": [ 529 | "a_list = [n if n > 3 else -n\n", 530 | " for li in nums_list\n", 531 | " if len(li) > 1\n", 532 | " for n in li\n", 533 | " if n % 2 == 1]\n", 534 | "a_list" 535 | ] 536 | }, 537 | { 538 | "cell_type": "markdown", 539 | "id": "28e08d20", 540 | "metadata": {}, 541 | "source": [ 542 | "### As for-loop" 543 | ] 544 | }, 545 | { 546 | "cell_type": "code", 547 | "execution_count": 20, 548 | "id": "5db47e00", 549 | "metadata": {}, 550 | "outputs": [ 551 | { 552 | "data": { 553 | "text/plain": [ 554 | "[7, -1, 5]" 555 | ] 556 | }, 557 | "execution_count": 20, 558 | "metadata": {}, 559 | "output_type": "execute_result" 560 | } 561 | ], 562 | "source": [ 563 | "a_list = []\n", 564 | "for li in nums_list:\n", 565 | " if len(li) > 1:\n", 566 | " for n in li:\n", 567 | " if n % 2 == 1:\n", 568 | " if n > 3:\n", 569 | " a_list.append(n)\n", 570 | " else:\n", 571 | " a_list.append(-n)\n", 572 | "a_list" 573 | ] 574 | }, 575 | { 576 | "cell_type": "markdown", 577 | "id": "28aa0da2", 578 | "metadata": {}, 579 | "source": [ 580 | "### Functionally, with map/filter/sum" 581 | ] 582 | }, 583 | { 584 | "cell_type": "code", 585 | "execution_count": 21, 586 | "id": "bb109db1", 587 | "metadata": {}, 588 | "outputs": [ 589 | { 590 | "data": { 591 | "text/plain": [ 592 | "[7, -1, 5]" 593 | ] 594 | }, 595 | "execution_count": 21, 596 | "metadata": {}, 597 | "output_type": "execute_result" 598 | } 599 | ], 600 | "source": [ 601 | "SMALL_NUM = 3\n", 602 | "multiple_nums = filter(lambda nums: len(nums) > 1, nums_list)\n", 603 | "flattened = sum(multiple_nums, [])\n", 604 | "odds = filter(lambda n: n % 2 == 1, flattened)\n", 605 | "small_becomes_negative = map(lambda n: -n if n < SMALL_NUM else n, odds)\n", 606 | "a_list = list(small_becomes_negative)\n", 607 | "a_list" 608 | ] 609 | }, 610 | { 611 | "cell_type": "code", 612 | "execution_count": null, 613 | "id": "3abfefc6", 614 | "metadata": {}, 615 | "outputs": [], 616 | "source": [] 617 | } 618 | ], 619 | "metadata": { 620 | "jupytext": { 621 | "cell_metadata_filter": "-all", 622 | "formats": "auto:light,ipynb", 623 | "main_language": "python", 624 | "notebook_metadata_filter": "-all" 625 | }, 626 | "kernelspec": { 627 | "display_name": "Python 3 (ipykernel)", 628 | "language": "python", 629 | "name": "python3" 630 | }, 631 | "language_info": { 632 | "codemirror_mode": { 633 | "name": "ipython", 634 | "version": 3 635 | }, 636 | "file_extension": ".py", 637 | "mimetype": "text/x-python", 638 | "name": "python", 639 | "nbconvert_exporter": "python", 640 | "pygments_lexer": "ipython3", 641 | "version": "3.11.4" 642 | } 643 | }, 644 | "nbformat": 4, 645 | "nbformat_minor": 5 646 | } 647 | -------------------------------------------------------------------------------- /content/examples/ex_09_array.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "c3a9c03a", 6 | "metadata": {}, 7 | "source": [ 8 | "# array.array\n", 9 | "[Documentation](https://docs.python.org/3/library/array.html)" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "id": "a8a19782", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import array" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "id": "a7006a70", 25 | "metadata": {}, 26 | "source": [ 27 | "Must declare the type of data it holds:\n", 28 | "- `'f'` - float\n", 29 | "- `'i'` - integer\n", 30 | "- `'u'` - Unicode character\n", 31 | "\n", 32 | "More types in [documentation](https://docs.python.org/3/library/array.html)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "id": "497aef61", 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "data": { 43 | "text/plain": [ 44 | "array('f', [1.0, 1.5, 2.0, 2.5])" 45 | ] 46 | }, 47 | "execution_count": 2, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "arr_f = array.array(\"f\", (1.0, 1.5, 2.0, 2.5))\n", 54 | "arr_f" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "id": "fb04a0c1", 60 | "metadata": {}, 61 | "source": [ 62 | "### Arrays have many similar list methods" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "id": "42baa2c8", 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "array('f', [1.0, 1.5, 2.0, 2.5, 3.0])" 75 | ] 76 | }, 77 | "execution_count": 3, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "arr_f.append(3.0)\n", 84 | "arr_f" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 4, 90 | "id": "ed6e2359", 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "array('f', [0.5, 1.0, 1.5, 2.0, 2.5, 3.0])" 97 | ] 98 | }, 99 | "execution_count": 4, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "arr_f.insert(0, 0.5)\n", 106 | "arr_f" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 5, 112 | "id": "16e596a2", 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "text/plain": [ 118 | "array('f', [3.0, 2.5, 2.0, 1.5, 1.0, 0.5])" 119 | ] 120 | }, 121 | "execution_count": 5, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "arr_f.reverse()\n", 128 | "arr_f" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "id": "7d1208b1", 134 | "metadata": {}, 135 | "source": [ 136 | "### And a few conversion methods" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 6, 142 | "id": "7e2e7d6f", 143 | "metadata": {}, 144 | "outputs": [ 145 | { 146 | "data": { 147 | "text/plain": [ 148 | "[3.0, 2.5, 2.0, 1.5, 1.0, 0.5]" 149 | ] 150 | }, 151 | "execution_count": 6, 152 | "metadata": {}, 153 | "output_type": "execute_result" 154 | } 155 | ], 156 | "source": [ 157 | "arr_f.tolist()" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 7, 163 | "id": "ea27c0c5", 164 | "metadata": {}, 165 | "outputs": [ 166 | { 167 | "data": { 168 | "text/plain": [ 169 | "b'\\x00\\x00@@\\x00\\x00 @\\x00\\x00\\x00@\\x00\\x00\\xc0?\\x00\\x00\\x80?\\x00\\x00\\x00?'" 170 | ] 171 | }, 172 | "execution_count": 7, 173 | "metadata": {}, 174 | "output_type": "execute_result" 175 | } 176 | ], 177 | "source": [ 178 | "arr_f.tobytes()" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "id": "3e89fa56", 184 | "metadata": {}, 185 | "source": [ 186 | "### Working with files" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "id": "5abc6e79", 192 | "metadata": {}, 193 | "source": [ 194 | "You can save arrays to a file as bytes, so use binary `'b'` mode. " 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 8, 200 | "id": "82cee028", 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "with open('array', 'wb') as file:\n", 205 | " arr_f.tofile(file)" 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 9, 211 | "id": "0761f889", 212 | "metadata": {}, 213 | "outputs": [ 214 | { 215 | "data": { 216 | "text/plain": [ 217 | "array('f', [-1.0, -1.5])" 218 | ] 219 | }, 220 | "execution_count": 9, 221 | "metadata": {}, 222 | "output_type": "execute_result" 223 | } 224 | ], 225 | "source": [ 226 | "arr_f2 = array.array(\"f\", (-1.0, -1.5))\n", 227 | "arr_f2" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "id": "ec2d55b0", 233 | "metadata": {}, 234 | "source": [ 235 | "`.fromfile(file, n)` appends `n` items from the file onto the existing array." 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 10, 241 | "id": "5a13241c", 242 | "metadata": {}, 243 | "outputs": [ 244 | { 245 | "data": { 246 | "text/plain": [ 247 | "array('f', [-1.0, -1.5, 3.0, 2.5, 2.0])" 248 | ] 249 | }, 250 | "execution_count": 10, 251 | "metadata": {}, 252 | "output_type": "execute_result" 253 | } 254 | ], 255 | "source": [ 256 | "with open('array', 'rb') as file:\n", 257 | " arr_f2.fromfile(file, 3)\n", 258 | "arr_f2" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "id": "7b7d0887", 264 | "metadata": {}, 265 | "source": [ 266 | "## Working with chars\n", 267 | "The `'u'` type stores Unicode characters and prints them like a string (instead of list)." 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": 11, 273 | "id": "f5ca2c03", 274 | "metadata": {}, 275 | "outputs": [ 276 | { 277 | "data": { 278 | "text/plain": [ 279 | "array('u', 'I 💚 🐍')" 280 | ] 281 | }, 282 | "execution_count": 11, 283 | "metadata": {}, 284 | "output_type": "execute_result" 285 | } 286 | ], 287 | "source": [ 288 | "arr_u = array.array('u', 'I 💚 🐍')\n", 289 | "arr_u" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 12, 295 | "id": "88f8e6e1", 296 | "metadata": {}, 297 | "outputs": [ 298 | { 299 | "data": { 300 | "text/plain": [ 301 | "array('u', 'I 💚 🐍!')" 302 | ] 303 | }, 304 | "execution_count": 12, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "source": [ 310 | "arr_u.append('!')\n", 311 | "arr_u" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": 13, 317 | "id": "ccdd9ddb", 318 | "metadata": {}, 319 | "outputs": [ 320 | { 321 | "name": "stdout", 322 | "output_type": "stream", 323 | "text": [ 324 | "\n", 325 | "I 💚 🐍!\n" 326 | ] 327 | } 328 | ], 329 | "source": [ 330 | "as_u = arr_u.tounicode() # Only works with 'u' type\n", 331 | "print(type(as_u))\n", 332 | "print(as_u)" 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "id": "cea7dd31", 338 | "metadata": {}, 339 | "source": [ 340 | "## Size specific integers\n", 341 | "In most other languages, integers have a minimum and maximum value.\n", 342 | "Python increases the memory for integers dynamically behind the scenes, so there is no minimum or maximum value.\n", 343 | "\n", 344 | "Since arrays assign a fixed amount of memory for each item, you must specify the number of bytes allocated for integers arrays and whether or not they can store negative numbers (signed vs unsigned).\n", 345 | "\n", 346 | "Type to byte list:\n", 347 | "- `'b'` and `'B'` (char): 1 byte\n", 348 | "- `'h'` and `'H'` (short): 2 bytes\n", 349 | "- `'i'` and `'I'` (int): 2 bytes\n", 350 | "- `'l'` and `'L'` (long): 4 bytes\n", 351 | "- `'q'` and `'Q'` (long long): 8 bytes\n", 352 | "- `'f'` (float): 8 bytes\n", 353 | "- `'d'` (double long float): 8 bytes\n", 354 | "\n", 355 | "### 'B': unsigned char\n", 356 | "This is an unintuitive name. It's basically 1 byte of data as an integer" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": 14, 362 | "id": "a0ce64bc", 363 | "metadata": {}, 364 | "outputs": [ 365 | { 366 | "data": { 367 | "text/plain": [ 368 | "array('B', [0, 255])" 369 | ] 370 | }, 371 | "execution_count": 14, 372 | "metadata": {}, 373 | "output_type": "execute_result" 374 | } 375 | ], 376 | "source": [ 377 | "smallest = 0\n", 378 | "largest = 2**8 - 1\n", 379 | "arr_B = array.array(\"B\", (smallest, largest))\n", 380 | "arr_B" 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": 15, 386 | "id": "8577e16e", 387 | "metadata": {}, 388 | "outputs": [ 389 | { 390 | "name": "stdout", 391 | "output_type": "stream", 392 | "text": [ 393 | "OverflowError('unsigned byte integer is greater than maximum')\n" 394 | ] 395 | } 396 | ], 397 | "source": [ 398 | "try:\n", 399 | " arr_B.append(largest + 1)\n", 400 | "except Exception as e:\n", 401 | " print(repr(e))" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 16, 407 | "id": "45d09d6c", 408 | "metadata": {}, 409 | "outputs": [ 410 | { 411 | "name": "stdout", 412 | "output_type": "stream", 413 | "text": [ 414 | "OverflowError('unsigned byte integer is less than minimum')\n" 415 | ] 416 | } 417 | ], 418 | "source": [ 419 | "try:\n", 420 | " arr_B.append(smallest - 1)\n", 421 | "except Exception as e:\n", 422 | " print(repr(e))" 423 | ] 424 | }, 425 | { 426 | "cell_type": "markdown", 427 | "id": "eab908b6", 428 | "metadata": {}, 429 | "source": [ 430 | "### 'b': signed char\n", 431 | "Like unsigned char but one bit is used to store the sign." 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 17, 437 | "id": "6a5cfd84", 438 | "metadata": {}, 439 | "outputs": [ 440 | { 441 | "data": { 442 | "text/plain": [ 443 | "array('b', [-128, 127])" 444 | ] 445 | }, 446 | "execution_count": 17, 447 | "metadata": {}, 448 | "output_type": "execute_result" 449 | } 450 | ], 451 | "source": [ 452 | "smallest = -(2**7)\n", 453 | "largest = 2**7 - 1\n", 454 | "arr_f2 = array.array(\"b\", (smallest, largest))\n", 455 | "arr_f2" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": 18, 461 | "id": "26da8ba7", 462 | "metadata": {}, 463 | "outputs": [ 464 | { 465 | "name": "stdout", 466 | "output_type": "stream", 467 | "text": [ 468 | "OverflowError('signed char is greater than maximum')\n" 469 | ] 470 | } 471 | ], 472 | "source": [ 473 | "try:\n", 474 | " arr_f2.append(largest + 1)\n", 475 | "except Exception as e:\n", 476 | " print(repr(e))" 477 | ] 478 | }, 479 | { 480 | "cell_type": "markdown", 481 | "id": "06d218eb", 482 | "metadata": {}, 483 | "source": [ 484 | "### 'I': unsigned int\n", 485 | "2 bytes" 486 | ] 487 | }, 488 | { 489 | "cell_type": "code", 490 | "execution_count": 19, 491 | "id": "3fd7c516", 492 | "metadata": {}, 493 | "outputs": [ 494 | { 495 | "data": { 496 | "text/plain": [ 497 | "array('I', [0, 4294967295])" 498 | ] 499 | }, 500 | "execution_count": 19, 501 | "metadata": {}, 502 | "output_type": "execute_result" 503 | } 504 | ], 505 | "source": [ 506 | "smallest = 0\n", 507 | "largest = 2**32 - 1\n", 508 | "arr_I = array.array(\"I\", (smallest, largest))\n", 509 | "arr_I" 510 | ] 511 | }, 512 | { 513 | "cell_type": "code", 514 | "execution_count": 20, 515 | "id": "42b7692e", 516 | "metadata": {}, 517 | "outputs": [ 518 | { 519 | "name": "stdout", 520 | "output_type": "stream", 521 | "text": [ 522 | "OverflowError('unsigned int is greater than maximum')\n" 523 | ] 524 | } 525 | ], 526 | "source": [ 527 | "try:\n", 528 | " arr_I.append(largest + 1)\n", 529 | "except Exception as e:\n", 530 | " print(repr(e))" 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "execution_count": 21, 536 | "id": "7a80f287", 537 | "metadata": {}, 538 | "outputs": [ 539 | { 540 | "name": "stdout", 541 | "output_type": "stream", 542 | "text": [ 543 | "OverflowError(\"can't convert negative value to unsigned int\")\n" 544 | ] 545 | } 546 | ], 547 | "source": [ 548 | "try:\n", 549 | " arr_I.append(smallest - 1)\n", 550 | "except Exception as e:\n", 551 | " print(repr(e))" 552 | ] 553 | }, 554 | { 555 | "cell_type": "markdown", 556 | "id": "19cd1f75", 557 | "metadata": {}, 558 | "source": [ 559 | "### 'i': signed integer\n", 560 | "2 bytes, with 1 bit to store the sign" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": 22, 566 | "id": "a7551ab4", 567 | "metadata": {}, 568 | "outputs": [ 569 | { 570 | "data": { 571 | "text/plain": [ 572 | "array('i', [-2147483648, 2147483647])" 573 | ] 574 | }, 575 | "execution_count": 22, 576 | "metadata": {}, 577 | "output_type": "execute_result" 578 | } 579 | ], 580 | "source": [ 581 | "smallest = -(2**31)\n", 582 | "largest = 2**31 - 1\n", 583 | "arr_i = array.array(\"i\", (smallest, largest))\n", 584 | "arr_i" 585 | ] 586 | }, 587 | { 588 | "cell_type": "code", 589 | "execution_count": 23, 590 | "id": "e191dbdd", 591 | "metadata": {}, 592 | "outputs": [ 593 | { 594 | "name": "stdout", 595 | "output_type": "stream", 596 | "text": [ 597 | "OverflowError('signed integer is greater than maximum')\n" 598 | ] 599 | } 600 | ], 601 | "source": [ 602 | "try:\n", 603 | " arr_i.append(largest + 1)\n", 604 | "except Exception as e:\n", 605 | " print(repr(e))" 606 | ] 607 | }, 608 | { 609 | "cell_type": "code", 610 | "execution_count": 24, 611 | "id": "749892ff", 612 | "metadata": {}, 613 | "outputs": [ 614 | { 615 | "name": "stdout", 616 | "output_type": "stream", 617 | "text": [ 618 | "OverflowError('signed integer is less than minimum')\n" 619 | ] 620 | } 621 | ], 622 | "source": [ 623 | "try:\n", 624 | " arr_i.append(smallest - 1)\n", 625 | "except Exception as e:\n", 626 | " print(repr(e))" 627 | ] 628 | } 629 | ], 630 | "metadata": { 631 | "jupytext": { 632 | "cell_metadata_filter": "-all", 633 | "formats": "auto:light,ipynb", 634 | "main_language": "python", 635 | "notebook_metadata_filter": "-all" 636 | }, 637 | "kernelspec": { 638 | "display_name": "Python 3 (ipykernel)", 639 | "language": "python", 640 | "name": "python3" 641 | }, 642 | "language_info": { 643 | "codemirror_mode": { 644 | "name": "ipython", 645 | "version": 3 646 | }, 647 | "file_extension": ".py", 648 | "mimetype": "text/x-python", 649 | "name": "python", 650 | "nbconvert_exporter": "python", 651 | "pygments_lexer": "ipython3", 652 | "version": "3.11.4" 653 | } 654 | }, 655 | "nbformat": 4, 656 | "nbformat_minor": 5 657 | } 658 | -------------------------------------------------------------------------------- /content/examples/ex_16_custom_classes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "58d5cbde", 6 | "metadata": {}, 7 | "source": [ 8 | "# Creating custom classes\n", 9 | "Any custom class should:\n", 10 | "- Override the default `.__init__()`, `.__str__()` and `.__repr__()` methods\n", 11 | "- Use PascalCase for its name unless you have a good reason not to\n", 12 | "- Use the appropriate dunder methods, like `.__len__()`, instead of a custom `.get_length()` or `.length` attribute" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "id": "58af9ed3", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "class MyClass:\n", 23 | " def __init__(self, data):\n", 24 | " self.data = data\n", 25 | " \n", 26 | " def __len__(self):\n", 27 | " if hasattr(self.data, '__len__'): # Does self.data.__len__() exist?\n", 28 | " return len(self.data)\n", 29 | " return 1\n", 30 | " \n", 31 | " def times_2(self):\n", 32 | " if hasattr(self.data, '__mul__'):\n", 33 | " return self.data * 2\n", 34 | " return self.data, self.data\n", 35 | " \n", 36 | " def __str__(self):\n", 37 | " return str(self.data)\n", 38 | " \n", 39 | " def __repr__(self):\n", 40 | " return f'MyClass({repr(self.data)})'" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 2, 46 | "id": "a4821eb2", 47 | "metadata": { 48 | "lines_to_end_of_cell_marker": 0, 49 | "lines_to_next_cell": 1 50 | }, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "[1, 2]\n", 57 | "[MyClass([1, 2])]\n", 58 | "2\n", 59 | "[1, 2, 1, 2]\n" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "data = [1, 2] # Try different data \n", 65 | "\n", 66 | "mc = MyClass(data) # Calls __init__\n", 67 | "print(mc) # Calls __str__\n", 68 | "print([mc]) # Calls __repr__\n", 69 | "print(len(mc)) # Calls __len__\n", 70 | "print(mc.times_2()) # Calls __mul__" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "id": "f9775a8f", 76 | "metadata": {}, 77 | "source": [ 78 | "### Example: Custom Linked List" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 3, 84 | "id": "eafaf9eb", 85 | "metadata": { 86 | "lines_to_end_of_cell_marker": 0, 87 | "lines_to_next_cell": 1 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "class LinkedList:\n", 92 | " def __init__(self, iterable=None):\n", 93 | " self.head = None\n", 94 | " if iterable:\n", 95 | " for i in iterable:\n", 96 | " self.append(i)\n", 97 | "\n", 98 | " def append(self, value):\n", 99 | " node = Node(value, self.head)\n", 100 | " self.head = node\n", 101 | "\n", 102 | " def pop(self):\n", 103 | " if self.head:\n", 104 | " node = self.head\n", 105 | " self.head = self.head.next\n", 106 | " return node.value\n", 107 | " return None\n", 108 | "\n", 109 | " def __iter__(self):\n", 110 | " node = self.head\n", 111 | " while node is not None:\n", 112 | " yield node\n", 113 | " node = node.next\n", 114 | " \n", 115 | " def __repr__(self):\n", 116 | " aslist = [val for val in self]\n", 117 | " return f\"LinkedList{repr(aslist)}\"\n", 118 | "\n", 119 | "\n", 120 | "class Node:\n", 121 | " def __init__(self, value, next_node):\n", 122 | " self.value = value\n", 123 | " self.next = next_node\n", 124 | " \n", 125 | " def __repr__(self):\n", 126 | " return repr(self.value)" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 4, 132 | "id": "140882a2", 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "text/plain": [ 138 | "LinkedList['c', 'b', 'a']" 139 | ] 140 | }, 141 | "execution_count": 4, 142 | "metadata": {}, 143 | "output_type": "execute_result" 144 | } 145 | ], 146 | "source": [ 147 | "ll = LinkedList('abc')\n", 148 | "ll" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 5, 154 | "id": "c7b4f822", 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "data": { 159 | "text/plain": [ 160 | "LinkedList['d', 'c', 'b', 'a']" 161 | ] 162 | }, 163 | "execution_count": 5, 164 | "metadata": {}, 165 | "output_type": "execute_result" 166 | } 167 | ], 168 | "source": [ 169 | "ll.append('d')\n", 170 | "ll" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 6, 176 | "id": "2378ba34", 177 | "metadata": {}, 178 | "outputs": [ 179 | { 180 | "data": { 181 | "text/plain": [ 182 | "'d'" 183 | ] 184 | }, 185 | "execution_count": 6, 186 | "metadata": {}, 187 | "output_type": "execute_result" 188 | } 189 | ], 190 | "source": [ 191 | "ll.pop()" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 7, 197 | "id": "e6c5a6e9", 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "data": { 202 | "text/plain": [ 203 | "LinkedList['c', 'b', 'a']" 204 | ] 205 | }, 206 | "execution_count": 7, 207 | "metadata": {}, 208 | "output_type": "execute_result" 209 | } 210 | ], 211 | "source": [ 212 | "ll" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 8, 218 | "id": "e790ca86", 219 | "metadata": {}, 220 | "outputs": [ 221 | { 222 | "name": "stdout", 223 | "output_type": "stream", 224 | "text": [ 225 | "'c'\n", 226 | "'b'\n", 227 | "'a'\n" 228 | ] 229 | } 230 | ], 231 | "source": [ 232 | "for val in ll:\n", 233 | " print(val)" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "id": "345b0c42", 239 | "metadata": {}, 240 | "source": [ 241 | "## Inheriting from a class\n", 242 | "Say we want to be able to subtract one string for another. The `-` operator currently throws `TypeError`." 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 9, 248 | "id": "85d4a007", 249 | "metadata": {}, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "TypeError(\"unsupported operand type(s) for -: 'str' and 'str'\")\n" 256 | ] 257 | } 258 | ], 259 | "source": [ 260 | "try:\n", 261 | " 'abc' - 'b'\n", 262 | "except Exception as e:\n", 263 | " print(repr(e))" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "id": "71d51d07", 269 | "metadata": {}, 270 | "source": [ 271 | "We can inherit from `str`, use `self` to access the string, and add/override any methods we want." 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 10, 277 | "id": "17fe527f", 278 | "metadata": {}, 279 | "outputs": [], 280 | "source": [ 281 | "class mystr(str):\n", 282 | " def __sub__(self, other):\n", 283 | " result_list = [char for char in self if char not in other]\n", 284 | " return ''.join(result_list)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "id": "a5831511", 290 | "metadata": {}, 291 | "source": [ 292 | "To use it, wrap your string in the new class (create an instance of it)." 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 11, 298 | "id": "1ff20a3d", 299 | "metadata": {}, 300 | "outputs": [ 301 | { 302 | "data": { 303 | "text/plain": [ 304 | "'abc'" 305 | ] 306 | }, 307 | "execution_count": 11, 308 | "metadata": {}, 309 | "output_type": "execute_result" 310 | } 311 | ], 312 | "source": [ 313 | "test = mystr('abc')\n", 314 | "test" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 12, 320 | "id": "a5a1936b", 321 | "metadata": {}, 322 | "outputs": [ 323 | { 324 | "data": { 325 | "text/plain": [ 326 | "'ac'" 327 | ] 328 | }, 329 | "execution_count": 12, 330 | "metadata": {}, 331 | "output_type": "execute_result" 332 | } 333 | ], 334 | "source": [ 335 | "test - 'b'" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 13, 341 | "id": "b6f67efb", 342 | "metadata": {}, 343 | "outputs": [ 344 | { 345 | "data": { 346 | "text/plain": [ 347 | "'ABC'" 348 | ] 349 | }, 350 | "execution_count": 13, 351 | "metadata": {}, 352 | "output_type": "execute_result" 353 | } 354 | ], 355 | "source": [ 356 | "test.upper()" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "id": "61cf51d6", 362 | "metadata": {}, 363 | "source": [ 364 | "## Inheriting from a collection class\n", 365 | "The `collections` module has `UserDict`, `UserList` and `UserString` to inherit from." 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": 14, 371 | "id": "834448e6", 372 | "metadata": { 373 | "lines_to_end_of_cell_marker": 0, 374 | "lines_to_next_cell": 1 375 | }, 376 | "outputs": [], 377 | "source": [ 378 | "from collections import UserList\n", 379 | "\n", 380 | "class MyList(UserList):\n", 381 | " def upper(self):\n", 382 | " new_data = []\n", 383 | " for val in self.data:\n", 384 | " if isinstance(val, str):\n", 385 | " new_data.append(val.upper())\n", 386 | " else:\n", 387 | " new_data.append(val)\n", 388 | " return MyList(new_data)" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 15, 394 | "id": "3b30f1fd", 395 | "metadata": {}, 396 | "outputs": [ 397 | { 398 | "data": { 399 | "text/plain": [ 400 | "MyList([1, 'a', 2, 'b'])" 401 | ] 402 | }, 403 | "execution_count": 15, 404 | "metadata": {}, 405 | "output_type": "execute_result" 406 | } 407 | ], 408 | "source": [ 409 | "l = MyList([1, 'a', 2, 'b'])\n", 410 | "l" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": 16, 416 | "id": "786221d8", 417 | "metadata": {}, 418 | "outputs": [ 419 | { 420 | "data": { 421 | "text/plain": [ 422 | "MyList([1, 'A', 2, 'B'])" 423 | ] 424 | }, 425 | "execution_count": 16, 426 | "metadata": {}, 427 | "output_type": "execute_result" 428 | } 429 | ], 430 | "source": [ 431 | "l.upper()" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 17, 437 | "id": "096ec1d5", 438 | "metadata": {}, 439 | "outputs": [ 440 | { 441 | "data": { 442 | "text/plain": [ 443 | "'a'" 444 | ] 445 | }, 446 | "execution_count": 17, 447 | "metadata": {}, 448 | "output_type": "execute_result" 449 | } 450 | ], 451 | "source": [ 452 | "l[1]" 453 | ] 454 | }, 455 | { 456 | "cell_type": "markdown", 457 | "id": "24d28910-e51d-4176-977b-bc0e7370c6c2", 458 | "metadata": {}, 459 | "source": [ 460 | "## Dataclasses\n", 461 | "\n", 462 | "You can use these for quick class creation that mostly stores data.\n", 463 | "\n", 464 | "Instead of defining instance attributes in `__init__()`, you define them on a class and provide the type." 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": 18, 470 | "id": "3a2b9eb3-7f72-4486-a4ad-d5dc5717bf9c", 471 | "metadata": {}, 472 | "outputs": [], 473 | "source": [ 474 | "from dataclasses import dataclass\n", 475 | "\n", 476 | "@dataclass\n", 477 | "class Location:\n", 478 | " name: str\n", 479 | " latitude: float\n", 480 | " longitude: float" 481 | ] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "execution_count": 19, 486 | "id": "d115e1ba-ed5b-465c-b39c-7870e4572067", 487 | "metadata": {}, 488 | "outputs": [ 489 | { 490 | "data": { 491 | "text/plain": [ 492 | "'London'" 493 | ] 494 | }, 495 | "execution_count": 19, 496 | "metadata": {}, 497 | "output_type": "execute_result" 498 | } 499 | ], 500 | "source": [ 501 | "london = Location('London', 42.99, -81.243)\n", 502 | "london.name" 503 | ] 504 | }, 505 | { 506 | "cell_type": "code", 507 | "execution_count": 20, 508 | "id": "34e56858-7b98-4d14-abe7-44c5cb674e24", 509 | "metadata": {}, 510 | "outputs": [ 511 | { 512 | "data": { 513 | "text/plain": [ 514 | "42.99" 515 | ] 516 | }, 517 | "execution_count": 20, 518 | "metadata": {}, 519 | "output_type": "execute_result" 520 | } 521 | ], 522 | "source": [ 523 | "london.latitude" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": 21, 529 | "id": "acb00994-e146-40e5-a8df-b65a0c086e9e", 530 | "metadata": {}, 531 | "outputs": [ 532 | { 533 | "data": { 534 | "text/plain": [ 535 | "-81.243" 536 | ] 537 | }, 538 | "execution_count": 21, 539 | "metadata": {}, 540 | "output_type": "execute_result" 541 | } 542 | ], 543 | "source": [ 544 | "london.longitude" 545 | ] 546 | }, 547 | { 548 | "cell_type": "markdown", 549 | "id": "2ce9a200-cf89-4721-8b4d-de9615e0c2a0", 550 | "metadata": {}, 551 | "source": [ 552 | "Dataclasses provide some default behaviour for `__str__()`, `__repr__()` and `__eq__()`." 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": 22, 558 | "id": "4a621ef9-16c1-456a-916d-52cda9c9b0a6", 559 | "metadata": {}, 560 | "outputs": [ 561 | { 562 | "data": { 563 | "text/plain": [ 564 | "Location(name='London', latitude=42.99, longitude=-81.243)" 565 | ] 566 | }, 567 | "execution_count": 22, 568 | "metadata": {}, 569 | "output_type": "execute_result" 570 | } 571 | ], 572 | "source": [ 573 | "london" 574 | ] 575 | }, 576 | { 577 | "cell_type": "code", 578 | "execution_count": 23, 579 | "id": "da8c93d1-2a74-437b-bbe0-31b0d3eabbbb", 580 | "metadata": {}, 581 | "outputs": [ 582 | { 583 | "name": "stdout", 584 | "output_type": "stream", 585 | "text": [ 586 | "Location(name='London', latitude=42.99, longitude=-81.243)\n" 587 | ] 588 | } 589 | ], 590 | "source": [ 591 | "print(london)" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": 24, 597 | "id": "41fec277-835e-44db-9226-87b5aada662c", 598 | "metadata": {}, 599 | "outputs": [ 600 | { 601 | "data": { 602 | "text/plain": [ 603 | "True" 604 | ] 605 | }, 606 | "execution_count": 24, 607 | "metadata": {}, 608 | "output_type": "execute_result" 609 | } 610 | ], 611 | "source": [ 612 | "london == Location('London', 42.99, -81.243)" 613 | ] 614 | } 615 | ], 616 | "metadata": { 617 | "jupytext": { 618 | "cell_metadata_filter": "-all", 619 | "formats": "auto:light,ipynb", 620 | "main_language": "python", 621 | "notebook_metadata_filter": "-all" 622 | }, 623 | "kernelspec": { 624 | "display_name": "Python 3 (ipykernel)", 625 | "language": "python", 626 | "name": "python3" 627 | }, 628 | "language_info": { 629 | "codemirror_mode": { 630 | "name": "ipython", 631 | "version": 3 632 | }, 633 | "file_extension": ".py", 634 | "mimetype": "text/x-python", 635 | "name": "python", 636 | "nbconvert_exporter": "python", 637 | "pygments_lexer": "ipython3", 638 | "version": "3.11.4" 639 | } 640 | }, 641 | "nbformat": 4, 642 | "nbformat_minor": 5 643 | } 644 | -------------------------------------------------------------------------------- /content/examples/ex_03_dict.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "83373c68", 6 | "metadata": {}, 7 | "source": [ 8 | "# Dicts\n", 9 | "Dictionaries are a type of key-value mapping object.\n", 10 | "\n", 11 | "Instead of accessing items by index (position), we get them through via keys.\n", 12 | "## Creating dicts" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "id": "789b6d27", 18 | "metadata": { 19 | "ExecuteTime": { 20 | "end_time": "2025-06-09T17:04:52.124164Z", 21 | "start_time": "2025-06-09T17:04:52.118076Z" 22 | } 23 | }, 24 | "source": [ 25 | "{'a': 1, 'b': 2}" 26 | ], 27 | "outputs": [ 28 | { 29 | "data": { 30 | "text/plain": [ 31 | "{'a': 1, 'b': 2}" 32 | ] 33 | }, 34 | "execution_count": 1, 35 | "metadata": {}, 36 | "output_type": "execute_result" 37 | } 38 | ], 39 | "execution_count": 1 40 | }, 41 | { 42 | "cell_type": "code", 43 | "id": "e14c35ef", 44 | "metadata": { 45 | "ExecuteTime": { 46 | "end_time": "2025-06-11T20:19:44.930618Z", 47 | "start_time": "2025-06-11T20:19:44.924529Z" 48 | } 49 | }, 50 | "source": "type({}) # {} creates empty dict", 51 | "outputs": [ 52 | { 53 | "data": { 54 | "text/plain": [ 55 | "dict" 56 | ] 57 | }, 58 | "execution_count": 34, 59 | "metadata": {}, 60 | "output_type": "execute_result" 61 | } 62 | ], 63 | "execution_count": 34 64 | }, 65 | { 66 | "cell_type": "code", 67 | "id": "f10231ac", 68 | "metadata": { 69 | "ExecuteTime": { 70 | "end_time": "2025-06-09T17:05:37.541983Z", 71 | "start_time": "2025-06-09T17:05:37.539386Z" 72 | } 73 | }, 74 | "source": [ 75 | "dict(((1, 2), [3, 4])) # Must be a sequence of 2-item lists/tuples" 76 | ], 77 | "outputs": [ 78 | { 79 | "data": { 80 | "text/plain": [ 81 | "{1: 2, 3: 4}" 82 | ] 83 | }, 84 | "execution_count": 4, 85 | "metadata": {}, 86 | "output_type": "execute_result" 87 | } 88 | ], 89 | "execution_count": 4 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "id": "f7decb34", 94 | "metadata": {}, 95 | "source": [ 96 | "You can also build dicts using **dict comprehensions**" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "id": "f780e799", 102 | "metadata": { 103 | "ExecuteTime": { 104 | "end_time": "2025-06-09T17:05:41.416406Z", 105 | "start_time": "2025-06-09T17:05:41.413441Z" 106 | } 107 | }, 108 | "source": [ 109 | "{i: 2 ** i for i in range(0, 10, 2)}" 110 | ], 111 | "outputs": [ 112 | { 113 | "data": { 114 | "text/plain": [ 115 | "{0: 1, 2: 4, 4: 16, 6: 64, 8: 256}" 116 | ] 117 | }, 118 | "execution_count": 5, 119 | "metadata": {}, 120 | "output_type": "execute_result" 121 | } 122 | ], 123 | "execution_count": 5 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "id": "f7252a01", 128 | "metadata": {}, 129 | "source": [ 130 | "We will look more at dict comprehensions in the second hour of the class." 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "id": "75688975", 136 | "metadata": {}, 137 | "source": [ 138 | "### Valid dict types\n", 139 | "`dict` **values** can be anything.\n", 140 | "\n", 141 | "`dict` **keys** must be __hashable__. Basically, if it's a builtin type, it can't be mutable (like `list`, `dict` or `set`). If it's a custom class, it must implement a special method for hashing and checking equality.\n", 142 | "\n", 143 | "Keys use `==` to determine key equality. So `1`, `1.0` and `True` all map to the same key." 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "id": "24c29589", 149 | "metadata": { 150 | "ExecuteTime": { 151 | "end_time": "2025-06-09T17:07:41.537119Z", 152 | "start_time": "2025-06-09T17:07:41.534428Z" 153 | } 154 | }, 155 | "source": "hash(1)", 156 | "outputs": [ 157 | { 158 | "data": { 159 | "text/plain": [ 160 | "1" 161 | ] 162 | }, 163 | "execution_count": 10, 164 | "metadata": {}, 165 | "output_type": "execute_result" 166 | } 167 | ], 168 | "execution_count": 10 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 6, 173 | "id": "e62ca448", 174 | "metadata": {}, 175 | "outputs": [ 176 | { 177 | "data": { 178 | "text/plain": [ 179 | "True" 180 | ] 181 | }, 182 | "execution_count": 6, 183 | "metadata": {}, 184 | "output_type": "execute_result" 185 | } 186 | ], 187 | "source": [ 188 | "1 == True" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 7, 194 | "id": "3246836b", 195 | "metadata": {}, 196 | "outputs": [ 197 | { 198 | "data": { 199 | "text/plain": [ 200 | "{1: 'float'}" 201 | ] 202 | }, 203 | "execution_count": 7, 204 | "metadata": {}, 205 | "output_type": "execute_result" 206 | } 207 | ], 208 | "source": [ 209 | "{\n", 210 | " 1: ['a', 2,],\n", 211 | " True: False,\n", 212 | " 1.0: 'float',\n", 213 | "}" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 8, 219 | "id": "8eee0cc5", 220 | "metadata": {}, 221 | "outputs": [ 222 | { 223 | "name": "stdout", 224 | "output_type": "stream", 225 | "text": [ 226 | "TypeError(\"unhashable type: 'list'\")\n" 227 | ] 228 | } 229 | ], 230 | "source": [ 231 | "try:\n", 232 | " {[1, 2]: 'list'}\n", 233 | "except Exception as e:\n", 234 | " print(repr(e))" 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "id": "f8ce4f2b", 240 | "metadata": {}, 241 | "source": [ 242 | "## Getting and updating contents" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "id": "d314f5a8", 248 | "metadata": { 249 | "ExecuteTime": { 250 | "end_time": "2025-06-09T17:09:34.517963Z", 251 | "start_time": "2025-06-09T17:09:34.515677Z" 252 | } 253 | }, 254 | "source": [ 255 | "d = {'a': 1, 'b': 2}" 256 | ], 257 | "outputs": [], 258 | "execution_count": 11 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "id": "0ec6e1a5", 263 | "metadata": {}, 264 | "source": [ 265 | "### Getting values\n", 266 | "We get items by key and not index (even if it's an int)" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "id": "5947a884", 272 | "metadata": { 273 | "ExecuteTime": { 274 | "end_time": "2025-06-09T17:09:37.048273Z", 275 | "start_time": "2025-06-09T17:09:37.044400Z" 276 | } 277 | }, 278 | "source": [ 279 | "d['a']" 280 | ], 281 | "outputs": [ 282 | { 283 | "data": { 284 | "text/plain": [ 285 | "1" 286 | ] 287 | }, 288 | "execution_count": 12, 289 | "metadata": {}, 290 | "output_type": "execute_result" 291 | } 292 | ], 293 | "execution_count": 12 294 | }, 295 | { 296 | "cell_type": "code", 297 | "id": "a62154d5", 298 | "metadata": { 299 | "ExecuteTime": { 300 | "end_time": "2025-06-09T17:09:56.824865Z", 301 | "start_time": "2025-06-09T17:09:56.822660Z" 302 | } 303 | }, 304 | "source": [ 305 | "try:\n", 306 | " print(d['c']) # Key doesn't exist\n", 307 | "except Exception as e:\n", 308 | " print(repr(e))" 309 | ], 310 | "outputs": [ 311 | { 312 | "name": "stdout", 313 | "output_type": "stream", 314 | "text": [ 315 | "KeyError('c')\n" 316 | ] 317 | } 318 | ], 319 | "execution_count": 13 320 | }, 321 | { 322 | "cell_type": "code", 323 | "id": "1259a415", 324 | "metadata": { 325 | "ExecuteTime": { 326 | "end_time": "2025-06-09T17:10:04.415469Z", 327 | "start_time": "2025-06-09T17:10:04.410694Z" 328 | } 329 | }, 330 | "source": [ 331 | "d.get('a')" 332 | ], 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "1" 338 | ] 339 | }, 340 | "execution_count": 14, 341 | "metadata": {}, 342 | "output_type": "execute_result" 343 | } 344 | ], 345 | "execution_count": 14 346 | }, 347 | { 348 | "cell_type": "code", 349 | "id": "a9022e8a", 350 | "metadata": { 351 | "ExecuteTime": { 352 | "end_time": "2025-06-09T17:10:09.940874Z", 353 | "start_time": "2025-06-09T17:10:09.938824Z" 354 | } 355 | }, 356 | "source": [ 357 | "print(d.get('c')) # Key doesn't exist" 358 | ], 359 | "outputs": [ 360 | { 361 | "name": "stdout", 362 | "output_type": "stream", 363 | "text": [ 364 | "None\n" 365 | ] 366 | } 367 | ], 368 | "execution_count": 15 369 | }, 370 | { 371 | "cell_type": "code", 372 | "id": "f0c5b218", 373 | "metadata": { 374 | "ExecuteTime": { 375 | "end_time": "2025-06-09T17:10:18.113406Z", 376 | "start_time": "2025-06-09T17:10:18.109970Z" 377 | } 378 | }, 379 | "source": [ 380 | "d.get('c', 'Not found') # Can provide default value" 381 | ], 382 | "outputs": [ 383 | { 384 | "data": { 385 | "text/plain": [ 386 | "'Not found'" 387 | ] 388 | }, 389 | "execution_count": 16, 390 | "metadata": {}, 391 | "output_type": "execute_result" 392 | } 393 | ], 394 | "execution_count": 16 395 | }, 396 | { 397 | "cell_type": "markdown", 398 | "id": "7c6249a1", 399 | "metadata": {}, 400 | "source": [ 401 | "### Updating values" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "id": "7150340a", 407 | "metadata": { 408 | "ExecuteTime": { 409 | "end_time": "2025-06-09T17:10:28.168567Z", 410 | "start_time": "2025-06-09T17:10:28.165637Z" 411 | } 412 | }, 413 | "source": [ 414 | "d['a'] = 'new' # update existing item\n", 415 | "d" 416 | ], 417 | "outputs": [ 418 | { 419 | "data": { 420 | "text/plain": [ 421 | "{'a': 'new', 'b': 2}" 422 | ] 423 | }, 424 | "execution_count": 17, 425 | "metadata": {}, 426 | "output_type": "execute_result" 427 | } 428 | ], 429 | "execution_count": 17 430 | }, 431 | { 432 | "cell_type": "code", 433 | "id": "02928b64", 434 | "metadata": { 435 | "ExecuteTime": { 436 | "end_time": "2025-06-09T17:10:34.674594Z", 437 | "start_time": "2025-06-09T17:10:34.670277Z" 438 | } 439 | }, 440 | "source": [ 441 | "d['c'] = 3 # add item a new item\n", 442 | "d" 443 | ], 444 | "outputs": [ 445 | { 446 | "data": { 447 | "text/plain": [ 448 | "{'a': 'new', 'b': 2, 'c': 3}" 449 | ] 450 | }, 451 | "execution_count": 18, 452 | "metadata": {}, 453 | "output_type": "execute_result" 454 | } 455 | ], 456 | "execution_count": 18 457 | }, 458 | { 459 | "cell_type": "code", 460 | "id": "3252aca0", 461 | "metadata": { 462 | "ExecuteTime": { 463 | "end_time": "2025-06-09T17:10:43.599Z", 464 | "start_time": "2025-06-09T17:10:43.595436Z" 465 | } 466 | }, 467 | "source": [ 468 | "del d['b'] # deleting by key\n", 469 | "d" 470 | ], 471 | "outputs": [ 472 | { 473 | "data": { 474 | "text/plain": [ 475 | "{'a': 'new', 'c': 3}" 476 | ] 477 | }, 478 | "execution_count": 19, 479 | "metadata": {}, 480 | "output_type": "execute_result" 481 | } 482 | ], 483 | "execution_count": 19 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "id": "357e1918", 488 | "metadata": {}, 489 | "source": [ 490 | "## Checking containment\n", 491 | "Checks keys, not values" 492 | ] 493 | }, 494 | { 495 | "cell_type": "code", 496 | "id": "5a5e6601", 497 | "metadata": { 498 | "ExecuteTime": { 499 | "end_time": "2025-06-09T17:10:51.233092Z", 500 | "start_time": "2025-06-09T17:10:51.230194Z" 501 | } 502 | }, 503 | "source": [ 504 | "'a' in d" 505 | ], 506 | "outputs": [ 507 | { 508 | "data": { 509 | "text/plain": [ 510 | "True" 511 | ] 512 | }, 513 | "execution_count": 20, 514 | "metadata": {}, 515 | "output_type": "execute_result" 516 | } 517 | ], 518 | "execution_count": 20 519 | }, 520 | { 521 | "cell_type": "code", 522 | "id": "f3fa375b", 523 | "metadata": { 524 | "ExecuteTime": { 525 | "end_time": "2025-06-09T17:11:19.759815Z", 526 | "start_time": "2025-06-09T17:11:19.756225Z" 527 | } 528 | }, 529 | "source": "3 in d.values()", 530 | "outputs": [ 531 | { 532 | "data": { 533 | "text/plain": [ 534 | "True" 535 | ] 536 | }, 537 | "execution_count": 23, 538 | "metadata": {}, 539 | "output_type": "execute_result" 540 | } 541 | ], 542 | "execution_count": 23 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "id": "6dbce2f9", 547 | "metadata": {}, 548 | "source": [ 549 | "## Looping\n", 550 | "Basic loop is over keys" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "id": "6b99824f", 556 | "metadata": { 557 | "ExecuteTime": { 558 | "end_time": "2025-06-09T17:11:29.284165Z", 559 | "start_time": "2025-06-09T17:11:29.280487Z" 560 | } 561 | }, 562 | "source": [ 563 | "for key in d:\n", 564 | " print(key)" 565 | ], 566 | "outputs": [ 567 | { 568 | "name": "stdout", 569 | "output_type": "stream", 570 | "text": [ 571 | "a\n", 572 | "c\n" 573 | ] 574 | } 575 | ], 576 | "execution_count": 24 577 | }, 578 | { 579 | "cell_type": "markdown", 580 | "id": "0223cb5f", 581 | "metadata": {}, 582 | "source": [ 583 | "It's recommended to use `.keys()`, `.values()` or `.items()` to be explicit about what you're looping over." 584 | ] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "id": "8a12e8bb", 589 | "metadata": { 590 | "ExecuteTime": { 591 | "end_time": "2025-06-09T17:12:06.025839Z", 592 | "start_time": "2025-06-09T17:12:06.023768Z" 593 | } 594 | }, 595 | "source": [ 596 | "for key, value in d.items():\n", 597 | " print(f\"{key}: {value}\")" 598 | ], 599 | "outputs": [ 600 | { 601 | "name": "stdout", 602 | "output_type": "stream", 603 | "text": [ 604 | "a: new\n", 605 | "c: 3\n" 606 | ] 607 | } 608 | ], 609 | "execution_count": 25 610 | }, 611 | { 612 | "cell_type": "markdown", 613 | "id": "3a375857-61e5-488a-8a67-8908ad72809f", 614 | "metadata": {}, 615 | "source": [ 616 | "## Sorting lists of dicts" 617 | ] 618 | }, 619 | { 620 | "cell_type": "code", 621 | "id": "f83d9909", 622 | "metadata": { 623 | "ExecuteTime": { 624 | "end_time": "2025-06-09T17:12:47.924006Z", 625 | "start_time": "2025-06-09T17:12:47.920558Z" 626 | } 627 | }, 628 | "source": [ 629 | "u1 = {1: 'a'}\n", 630 | "u2 = {1: 'b'}\n", 631 | "u3 = {1: 'c'}\n", 632 | "\n", 633 | "users = [u3, u1, u2]\n", 634 | "users" 635 | ], 636 | "outputs": [ 637 | { 638 | "data": { 639 | "text/plain": [ 640 | "[{1: 'c'}, {1: 'a'}, {1: 'b'}]" 641 | ] 642 | }, 643 | "execution_count": 26, 644 | "metadata": {}, 645 | "output_type": "execute_result" 646 | } 647 | ], 648 | "execution_count": 26 649 | }, 650 | { 651 | "cell_type": "markdown", 652 | "id": "9935a105-c7ee-4985-9ff7-73e244d04992", 653 | "metadata": {}, 654 | "source": [ 655 | "Create a sort function that takes 1 argument and returns a value to sort by.\n", 656 | "Pass the function into the `.sort()` `key` argument (without calling it)." 657 | ] 658 | }, 659 | { 660 | "cell_type": "code", 661 | "id": "5b02afd6", 662 | "metadata": { 663 | "ExecuteTime": { 664 | "end_time": "2025-06-09T17:15:34.343663Z", 665 | "start_time": "2025-06-09T17:15:34.340579Z" 666 | } 667 | }, 668 | "source": [ 669 | "def sort_by(u):\n", 670 | " return u[1]\n", 671 | "\n", 672 | "users.sort(key=sort_by)\n", 673 | "users" 674 | ], 675 | "outputs": [ 676 | { 677 | "data": { 678 | "text/plain": [ 679 | "[{1: 'a'}, {1: 'b'}, {1: 'c'}]" 680 | ] 681 | }, 682 | "execution_count": 32, 683 | "metadata": {}, 684 | "output_type": "execute_result" 685 | } 686 | ], 687 | "execution_count": 32 688 | }, 689 | { 690 | "cell_type": "markdown", 691 | "id": "f8748211-b6fb-4b6b-b15d-d6176067c68a", 692 | "metadata": {}, 693 | "source": [ 694 | "Or create an anonymous (lambda) function." 695 | ] 696 | }, 697 | { 698 | "cell_type": "code", 699 | "id": "68c101ad", 700 | "metadata": { 701 | "ExecuteTime": { 702 | "end_time": "2025-06-09T17:15:36.720737Z", 703 | "start_time": "2025-06-09T17:15:36.716857Z" 704 | } 705 | }, 706 | "source": [ 707 | "users.sort(key=lambda u: u[1])\n", 708 | "users" 709 | ], 710 | "outputs": [ 711 | { 712 | "data": { 713 | "text/plain": [ 714 | "[{1: 'a'}, {1: 'b'}, {1: 'c'}]" 715 | ] 716 | }, 717 | "execution_count": 33, 718 | "metadata": {}, 719 | "output_type": "execute_result" 720 | } 721 | ], 722 | "execution_count": 33 723 | } 724 | ], 725 | "metadata": { 726 | "jupytext": { 727 | "cell_metadata_filter": "-all", 728 | "formats": "auto:light,ipynb", 729 | "main_language": "python", 730 | "notebook_metadata_filter": "-all" 731 | }, 732 | "kernelspec": { 733 | "display_name": "Python 3 (ipykernel)", 734 | "language": "python", 735 | "name": "python3" 736 | }, 737 | "language_info": { 738 | "codemirror_mode": { 739 | "name": "ipython", 740 | "version": 3 741 | }, 742 | "file_extension": ".py", 743 | "mimetype": "text/x-python", 744 | "name": "python", 745 | "nbconvert_exporter": "python", 746 | "pygments_lexer": "ipython3", 747 | "version": "3.11.4" 748 | } 749 | }, 750 | "nbformat": 4, 751 | "nbformat_minor": 5 752 | } 753 | --------------------------------------------------------------------------------