diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml new file mode 100644 index 0000000..63470c7 --- /dev/null +++ b/.github/workflows/cleanup.yml @@ -0,0 +1,12 @@ +name: Cleanup Deleted Branch + +on: + delete + +permissions: + contents: write + +jobs: + cleanup: + uses: DurhamARC-Training/PythonCourse-jupyterlite/.github/workflows/cleanup-branch-deployment.yml@main + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 92a88c7..f8c2afe 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,67 +1,13 @@ -name: Deploy Jupyter Notebooks to GitHub Pages +name: Deploy JupyterLite on: push: - branches: [ main ] + branches: ['**'] # Deploy all branches -env: - TEMPLATE_REPO: 'DurhamARC-Training/PythonCourse-jupyterlite' -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Checkout template repository - uses: actions/checkout@v4 - with: - repository: ${{ env.TEMPLATE_REPO }} - - - name: Checkout main repository into content directory - uses: actions/checkout@v4 - with: - path: content - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Install template dependencies - run: | - python -m pip install -r requirements.txt - - - name: Install content dependencies - run: | - if [ -f content/requirements.txt ]; then - echo "Found content/requirements.txt, installing dependencies..." - python -m pip install -r content/requirements.txt - else - echo "No content/requirements.txt found, skipping content dependencies" - fi - - - name: Build the JupyterLite site - run: | - cp README.md content - jupyter lite build --contents content --output-dir dist - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ./dist +permissions: + contents: write +jobs: deploy: - needs: build - if: github.ref == 'refs/heads/main' - permissions: - pages: write - id-token: write - - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - - runs-on: ubuntu-latest - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 + uses: DurhamARC-Training/PythonCourse-jupyterlite/.github/workflows/deploy-jupyterlite.yml@main + secrets: inherit \ No newline at end of file diff --git a/Intermediate.ipynb b/Intermediate.ipynb index 32e64a0..2216356 100644 --- a/Intermediate.ipynb +++ b/Intermediate.ipynb @@ -4,11 +4,11 @@ "cell_type": "markdown", "id": "872c6494", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "ARC course \"Coding with Python\" (Intermediate level)\n", @@ -20,10 +20,10 @@ "cell_type": "markdown", "id": "2cd478b7", "metadata": { - "editable": false, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "Welcome to our ARC course \"Coding with Python\" (Intermediate level).\n", @@ -47,11 +47,11 @@ "cell_type": "markdown", "id": "4d58fde4", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# The Python Environment\n", @@ -72,11 +72,11 @@ "cell_type": "markdown", "id": "e673e2cd", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# Table of Contents" @@ -86,11 +86,11 @@ "cell_type": "markdown", "id": "85069fdb", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ " - [0. Introduction](#0.-Introduction)\n", @@ -100,26 +100,28 @@ "- [Part I](#Part-I)\n", " - [1. Recap](#1.-Recap)\n", " - [2. Data structures](#2.-Data-structures)\n", - " - [3. Conditional expression](#3.-Conditional-expressions)\n", + " - [3. Conditional expressions](#3.-Conditional-expressions)\n", " - [4. Comprehensions](#4.-Comprehensions)\n", - " - [5. Exceptions](#5-exceptions)\n", "\n", "- [Part II](#Part-II)\n", - " - [5. Brief introduction to Object-Oriented Programming](#6-brief-introduction-to-object-oriented-programming)\n", - " - [6. Introduction to modules](#7-introduction-to-modules)\n", - " - [7. Advanced string manipulation](#8-advanced-string-manipulation)\n", - " - [8. (Optional) Working with modules: Examples and creating your own](#9-optional-working-with-modules-examples-and-creating-your-own)\n" + " - [5. Exceptions](#5.-Exceptions)\n", + " - [6. Introduction to modules](#6.-Introduction-to-modules)\n", + " - [7. Advanced string manipulation](#7.-Advanced-string-manipulation)\n", + "\n", + "- [Optional topics](#Optional-Topics)\n", + " - [8. Working with modules: Examples and creating your own](#8.-(Optional)-Working-with-modules:-Examples-and-creating-your-own)\n", + " - [9. Brief introduction to Object-Oriented Programming](#9.-(Optional)-Brief-introduction-to-Object-Oriented-Programming)\n" ] }, { "cell_type": "markdown", "id": "153ed362", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# 0. Introduction" @@ -129,11 +131,11 @@ "cell_type": "markdown", "id": "6ba842c0", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Course objectives" @@ -143,11 +145,11 @@ "cell_type": "markdown", "id": "b1d20fc9", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "By the end of this course, you should know:\n", @@ -164,11 +166,11 @@ "cell_type": "markdown", "id": "cdfa9441", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Useful resources" @@ -178,10 +180,10 @@ "cell_type": "markdown", "id": "3eadf8e2", "metadata": { - "editable": false, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "There are plenty of resources to learn Python in the Internet from. These can be recommended by this tutorial for further learning:\n", @@ -196,11 +198,11 @@ "cell_type": "markdown", "id": "26d2d446", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# **Part I**" @@ -210,24 +212,24 @@ "cell_type": "markdown", "id": "4e49802b", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "# **1.** Recap" + "# 1. Recap" ] }, { "cell_type": "markdown", "id": "f99bdeea", "metadata": { - "editable": false, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "This section is a brief recap of materials covered in the Beginner Python course:\n", @@ -245,11 +247,11 @@ "cell_type": "markdown", "id": "b721c83a", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Data Types, variables, operators" @@ -268,11 +270,11 @@ } } }, - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Variables\n", @@ -286,7 +288,6 @@ "execution_count": null, "id": "decd8f2c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -302,7 +303,6 @@ "execution_count": null, "id": "1489fa3d", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -318,7 +318,6 @@ "execution_count": null, "id": "fb6110d3", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -333,7 +332,6 @@ "execution_count": null, "id": "ac31e498", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -347,11 +345,11 @@ "cell_type": "markdown", "id": "e1bd297e", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -365,7 +363,6 @@ "execution_count": null, "id": "94b6e716", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -381,7 +378,6 @@ "execution_count": null, "id": "d11dd969", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -396,11 +392,11 @@ "cell_type": "markdown", "id": "2a63c2dd", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Data types" @@ -410,11 +406,11 @@ "cell_type": "markdown", "id": "7ab44bf2", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "As with any programming language, Python can deal with many different data types. Among the basic ones are `str` strings, `int` integers, `float` floating-point numbers and `bool` booleans.\n", @@ -428,11 +424,11 @@ "cell_type": "markdown", "id": "c33c20f5", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "#### Numerical" @@ -442,11 +438,11 @@ "cell_type": "markdown", "id": "7a797eab", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "##### Floating-point representation:\n", @@ -462,7 +458,6 @@ "execution_count": null, "id": "c13d9a15", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -478,7 +473,6 @@ "execution_count": null, "id": "26b8760c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -492,10 +486,10 @@ "cell_type": "markdown", "id": "b9324c88", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "_NOTE_: Scientific notation is supported!" @@ -506,7 +500,6 @@ "execution_count": null, "id": "3253e3d0", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -523,10 +516,10 @@ "cell_type": "markdown", "id": "397f9f86", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "editable": false }, "source": [ "##### Integer representation:\n", @@ -539,7 +532,6 @@ "execution_count": null, "id": "3342a922", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -555,7 +547,6 @@ "execution_count": null, "id": "36e671e1", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -569,10 +560,10 @@ "cell_type": "markdown", "id": "b68a5bbf", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "editable": false }, "source": [ "**Numerical Operators** \n", @@ -593,7 +584,6 @@ "execution_count": null, "id": "af62e441", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -608,7 +598,6 @@ "execution_count": null, "id": "7e7ef933", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -623,7 +612,6 @@ "execution_count": null, "id": "28810d42", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -638,7 +626,6 @@ "execution_count": null, "id": "8b66a0a4", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -653,7 +640,6 @@ "execution_count": null, "id": "6984dbe1", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -668,7 +654,6 @@ "execution_count": null, "id": "74e37711", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -680,150 +665,145 @@ }, { "cell_type": "markdown", - "id": "9ca15865", + "id": "a5e3ab30", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "tags": [], + "editable": false }, "source": [ - "#### Boolean" + "#### String" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "d7b7abb8", + "cell_type": "markdown", + "id": "ba570bf4", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" - } + "slide_type": "fragment" + }, + "editable": false }, - "outputs": [], "source": [ - "b1 = False\n", - "b2 = True\n", - "print(b1)" + "A string is a series of characters enclosed in quotes, either single or double, used to represent text." ] }, { "cell_type": "code", "execution_count": null, - "id": "9296bb88", + "id": "ea3df5a1", "metadata": { - "editable": true, "slideshow": { "slide_type": "" - } + }, + "tags": [] }, "outputs": [], "source": [ - "type(True) # boolean" + "s = 'Hello, World!'\n", + "s = \"Hello, World!\"\n", + "print(s)" ] }, { - "cell_type": "markdown", - "id": "eae67d96", + "cell_type": "code", + "execution_count": null, + "id": "e3c09d2d", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "**Logical Operators** \n", - "We can also determine conditions based on Boolean logic: `and`, `or`, `not`" + "type(s) # string" ] }, { "cell_type": "markdown", - "id": "b38b2739", + "id": "50a4347d", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "**AND:**" + "**String Concatenation** \n", + "\n", + "We can combine strings together." ] }, { "cell_type": "code", "execution_count": null, - "id": "db33e773", + "id": "d9fadfdc", "metadata": { - "editable": true, "slideshow": { "slide_type": "" - }, - "tags": [] + } }, "outputs": [], "source": [ - "a = True\n", - "b = False\n", - "\n", - "a and b" + "# String concatenation\n", + "hello_world = \"Hello,\" + \" World!\"\n", + "print(hello_world)" ] }, { "cell_type": "markdown", - "id": "8b00b658", + "id": "d20cb9b3", "metadata": { - "editable": false, "slideshow": { - "slide_type": "fragment" + "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "---\n", - "**OR:**" + "## Comments" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "725d0173", + "cell_type": "markdown", + "id": "7ac031a7", "metadata": { - "editable": true, "slideshow": { "slide_type": "" - } + }, + "tags": [], + "editable": false }, - "outputs": [], "source": [ - "a = True\n", - "b = False\n", - "\n", - "a or b" + "Used to write notes or comments about code, as well as description of what the code is doing, or the variables used." ] }, { - "cell_type": "markdown", - "id": "6a10fe2f", + "cell_type": "code", + "execution_count": null, + "id": "41b7cdfe", "metadata": { - "editable": false, "slideshow": { - "slide_type": "fragment" - } + "slide_type": "" + }, + "tags": [] }, + "outputs": [], "source": [ - "---\n", - "**NOT:**" + "# A single-line comment!\n", + "welcome_message = \"Welcome, User!\"\n", + "print(welcome_message) # Print welcome message" ] }, { "cell_type": "code", "execution_count": null, - "id": "27378611", + "id": "9c50f102", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -831,62 +811,63 @@ }, "outputs": [], "source": [ - "a = True\n", - "\n", - "not a" + "'''\n", + "A multi-line comment!\n", + "'''\n", + "print(\"something\")" ] }, { - "cell_type": "markdown", - "id": "a5e3ab30", + "cell_type": "code", + "execution_count": null, + "id": "3f72dedf", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "#### String" + "\"\"\"\n", + "Another multi-line comment!\n", + "\"\"\"\n", + "print(\"something else\")" ] }, { "cell_type": "markdown", - "id": "ba570bf4", + "id": "8ee98ee9", "metadata": { - "editable": false, "slideshow": { - "slide_type": "fragment" - } + "slide_type": "slide" + }, + "tags": [], + "editable": false }, "source": [ - "A string is a series of characters enclosed in quotes, either single or double, used to represent text." + "## User Input" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "ea3df5a1", + "cell_type": "markdown", + "id": "6b2e3c6e", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, - "outputs": [], "source": [ - "s = 'Hello, World!'\n", - "s = \"Hello, World!\"\n", - "print(s)" + "You can use `input()` to read user input: " ] }, { "cell_type": "code", "execution_count": null, - "id": "e3c09d2d", + "id": "a1178a62", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -894,181 +875,20 @@ }, "outputs": [], "source": [ - "type(s) # string" - ] - }, - { - "cell_type": "markdown", - "id": "50a4347d", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "**String Concatenation** \n", - "\n", - "We can combine strings together." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d9fadfdc", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - } - }, - "outputs": [], - "source": [ - "# String concatenation\n", - "hello_world = \"Hello,\" + \" World!\"\n", - "print(hello_world)" - ] - }, - { - "cell_type": "markdown", - "id": "d20cb9b3", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Comments" - ] - }, - { - "cell_type": "markdown", - "id": "7ac031a7", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "Used to write notes or comments about code, as well as description of what the code is doing, or the variables used." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "41b7cdfe", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# A single-line comment!\n", - "welcome_message = \"Welcome, User!\"\n", - "print(welcome_message) # Print welcome message" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9c50f102", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "'''\n", - "A multi-line comment!\n", - "'''\n", - "print(\"something\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3f72dedf", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "\"\"\"\n", - "Another multi-line comment!\n", - "\"\"\"\n", - "print(\"something else\")" - ] - }, - { - "cell_type": "markdown", - "id": "8ee98ee9", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## User Input" - ] - }, - { - "cell_type": "markdown", - "id": "6b2e3c6e", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "You can use `input()` to read user input: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1178a62", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "inputted_variable = float(input())\n", - "print(inputted_variable) # Print what we just input!\n", - "type(inputted_variable)" + "inputted_variable = float(input())\n", + "print(inputted_variable) # Print what we just input!\n", + "type(inputted_variable)" ] }, { "cell_type": "markdown", "id": "52819c95", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Reading and Writing Files" @@ -1078,11 +898,11 @@ "cell_type": "markdown", "id": "a0966820", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Opening a File**\n", @@ -1103,7 +923,6 @@ "execution_count": null, "id": "38966db9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1121,11 +940,11 @@ "cell_type": "markdown", "id": "aadba414", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Reading from a File**\n", @@ -1141,7 +960,6 @@ "execution_count": null, "id": "7f0a6056", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1158,7 +976,6 @@ "execution_count": null, "id": "ec567746", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1174,11 +991,11 @@ "cell_type": "markdown", "id": "1f1185e6", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Writing to a File**" @@ -1188,11 +1005,11 @@ "cell_type": "markdown", "id": "179f132a", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "One way we can write to files is using the `write()` function." @@ -1202,11 +1019,11 @@ "cell_type": "markdown", "id": "e998f8fe", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Using the `with` keyword:" @@ -1217,7 +1034,6 @@ "execution_count": null, "id": "911d44b3", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1234,11 +1050,11 @@ "cell_type": "markdown", "id": "b61a8691", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Lists" @@ -1248,11 +1064,11 @@ "cell_type": "markdown", "id": "9c82edee", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Python can work not only with basic data types mentioned before, but also with compound ones. Compound data types in Python are a powerful tool for organizing and storing data. Among the most commonly used is _lists_ which we learned about in the beginner's course.\n", @@ -1266,11 +1082,11 @@ "cell_type": "markdown", "id": "8bb91a15", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "An ordered list of items, accessed by a numerical index (starting at `0`). Elements within a list can be removed, modified, or accessed by their index, and a list can have values added to it.\n", @@ -1283,7 +1099,6 @@ "execution_count": null, "id": "fdc8600e", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1299,11 +1114,11 @@ "cell_type": "markdown", "id": "efc747a1", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**List Access** \n", @@ -1315,7 +1130,6 @@ "execution_count": null, "id": "2b2c4dee", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1330,7 +1144,6 @@ "execution_count": null, "id": "3f87d56b", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1345,7 +1158,6 @@ "execution_count": null, "id": "b686d58d", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1361,7 +1173,6 @@ "execution_count": null, "id": "1f916c68", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1375,11 +1186,11 @@ "cell_type": "markdown", "id": "b8369a1a", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Slicing** \n", @@ -1391,7 +1202,6 @@ "execution_count": null, "id": "e0fac9bf", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1407,7 +1217,6 @@ "execution_count": null, "id": "586edf14", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1422,7 +1231,6 @@ "execution_count": null, "id": "9f0dea38", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1437,7 +1245,6 @@ "execution_count": null, "id": "bab8e8a0", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1451,11 +1258,11 @@ "cell_type": "markdown", "id": "fe6ffaf2", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Empty List** \n", @@ -1467,7 +1274,6 @@ "execution_count": null, "id": "0edf3fa6", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1482,70 +1288,277 @@ "cell_type": "markdown", "id": "f87cfa0f", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "## Repetitions and Conditions" + "## Repetitions and Conditions\n", + "\n", + "First, let's recap boolean logic. Boolean logic uses just two values: True, and False." ] }, { "cell_type": "markdown", - "id": "9303b3ff", + "id": "9ca15865", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "editable": false }, "source": [ - "**Conditions** \n", - "In order to control program flow, and whether or not code is executed, we can do conditions based on variable values." + "#### Boolean" ] }, { "cell_type": "code", "execution_count": null, - "id": "a0af6ea1", + "id": "d7b7abb8", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } }, "outputs": [], "source": [ - "x = 5\n", - "\n", - "if x > 2:\n", - " print(\"x =\", x, \"is GREATER THAN 2\")\n", - "\n", - "if x == 3:\n", - " print(\"x =\", x, \"is EQUAL TO 3\")\n", - "\n", - "if x >= 3:\n", - " print(\"x =\", x, \"is GREATER THAN or EQUAL TO 3\")\n", - "\n", - "if x != 0:\n", - " print(\"x =\", x, \"IS NOT 0\")\n", - "\n", - "if x < 4:\n", - " print(\"x =\", x, \"is LESS THAN 4\")" + "b1 = False\n", + "b2 = True\n", + "print(b1)" ] }, { - "cell_type": "markdown", - "id": "3246bbe1", + "cell_type": "code", + "execution_count": null, + "id": "9296bb88", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" - }, + "slide_type": "" + } + }, + "outputs": [], + "source": [ + "type(True) # boolean" + ] + }, + { + "cell_type": "markdown", + "id": "eae67d96", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, + "source": [ + "**Logical Operators** \n", + "We can determine conditions based on Boolean logic: using `and`, `or`, `not` to *evaluate* boolean expressions:" + ] + }, + { + "cell_type": "markdown", + "id": "b38b2739", + "metadata": { + "slideshow": { + "slide_type": "fragment" + }, + "tags": [], + "editable": false + }, + "source": [ + "**AND:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "db33e773", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "a = True\n", + "b = False\n", + "\n", + "a and b" + ] + }, + { + "cell_type": "markdown", + "id": "5c8055b9-5863-486e-a741-de11eee3faa9", + "metadata": { + "editable": false + }, + "source": [ + "We can display the results of the `AND` operation using a \"truth table\":\n", + "| *and* | True | False |\n", + "| --------- | ----- | ----- |\n", + "| __True__ | True | False |\n", + "| __False__ | False | False |" + ] + }, + { + "cell_type": "markdown", + "id": "8b00b658", + "metadata": { + "slideshow": { + "slide_type": "fragment" + }, + "tags": [], + "editable": false + }, + "source": [ + "---\n", + "**OR:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "725d0173", + "metadata": { + "slideshow": { + "slide_type": "" + } + }, + "outputs": [], + "source": [ + "a = True\n", + "b = False\n", + "\n", + "a or b" + ] + }, + { + "cell_type": "markdown", + "id": "4a4f35dc-5107-4589-984a-75f7a929958c", + "metadata": { + "editable": false + }, + "source": [ + "| *or* | True | False |\n", + "| --------- | ----- | ----- |\n", + "| __True__ | True | True |\n", + "| __False__ | True | False |\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "6a10fe2f", + "metadata": { + "slideshow": { + "slide_type": "fragment" + }, + "editable": false + }, + "source": [ + "---\n", + "**NOT:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27378611", + "metadata": { + "slideshow": { + "slide_type": "" + }, "tags": [] }, + "outputs": [], + "source": [ + "a = True\n", + "\n", + "not a" + ] + }, + { + "cell_type": "markdown", + "id": "bf19d081-ce51-4b07-bc67-94c4569b9ca9", + "metadata": { + "editable": false + }, + "source": [ + "| *not* | True | False |\n", + "| ----- | ----- | ----- |\n", + "| | False | True |" + ] + }, + { + "cell_type": "markdown", + "id": "9303b3ff", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "editable": false + }, + "source": [ + "**Conditions** \n", + "In order to control program flow, and whether or not code is executed, we can do conditions based on variable values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7fd769b8-28d3-416a-823f-21f7ffcceef7", + "metadata": {}, + "outputs": [], + "source": [ + "if a:\n", + " print(\"a is True!\")\n", + "else:\n", + " print(\"a is False.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0af6ea1", + "metadata": { + "slideshow": { + "slide_type": "" + } + }, + "outputs": [], + "source": [ + "x = 5\n", + "\n", + "if x > 2:\n", + " print(\"x =\", x, \"is GREATER THAN 2\")\n", + "\n", + "if x == 3:\n", + " print(\"x =\", x, \"is EQUAL TO 3\")\n", + "\n", + "if x >= 3:\n", + " print(\"x =\", x, \"is GREATER THAN or EQUAL TO 3\")\n", + "\n", + "if x != 0:\n", + " print(\"x =\", x, \"IS NOT 0\")\n", + "\n", + "if x < 4:\n", + " print(\"x =\", x, \"is LESS THAN 4\")" + ] + }, + { + "cell_type": "markdown", + "id": "3246bbe1", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, "source": [ "**Else/Elif** \n", "\n", @@ -1557,7 +1570,6 @@ "execution_count": null, "id": "8cab77e6", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1579,11 +1591,11 @@ "cell_type": "markdown", "id": "8c87d3f8", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Repetitions** \n", @@ -1594,11 +1606,11 @@ "cell_type": "markdown", "id": "095edef4", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "For Each Loop: \n", @@ -1610,7 +1622,6 @@ "execution_count": null, "id": "c7dc2e03", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1628,10 +1639,10 @@ "cell_type": "markdown", "id": "76e99a09", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "The above describes `for each animal in animal_list`." @@ -1641,11 +1652,11 @@ "cell_type": "markdown", "id": "e5b05a2c", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -1657,7 +1668,6 @@ "execution_count": null, "id": "b14f546d", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1674,7 +1684,6 @@ "execution_count": null, "id": "713884f6", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1690,7 +1699,6 @@ "execution_count": null, "id": "b3078796", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1705,11 +1713,11 @@ "cell_type": "markdown", "id": "99b52e73", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "While Loop \n", @@ -1723,7 +1731,6 @@ "execution_count": null, "id": "136268d9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1741,10 +1748,10 @@ "cell_type": "markdown", "id": "89cd06cc", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "_NOTE_: The `break` keyword can be used to stop execution of a loop. \n", @@ -1755,10 +1762,10 @@ "cell_type": "markdown", "id": "b6c7b631", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "editable": false }, "source": [ "## Functions" @@ -1768,11 +1775,11 @@ "cell_type": "markdown", "id": "ad3766a1", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "A function is a reusable block of code used to perform a specific task.\n", @@ -1786,11 +1793,11 @@ "cell_type": "markdown", "id": "b83eb9fd", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Parameters/Arguments** \n", @@ -1801,11 +1808,11 @@ "cell_type": "markdown", "id": "25dddacf", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "**Returns** \n", @@ -1816,11 +1823,11 @@ "cell_type": "markdown", "id": "aa2983d4", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Here is a very basic example of a function:" @@ -1831,7 +1838,6 @@ "execution_count": null, "id": "d4ca99fa", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1851,11 +1857,11 @@ "cell_type": "markdown", "id": "429c78c2", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Note that we are able to save the result of `sum_numbers`, to a variable which we have aptly named `calculated_value`, which can be reused later." @@ -1865,11 +1871,11 @@ "cell_type": "markdown", "id": "f64d31aa", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -1881,7 +1887,6 @@ "execution_count": null, "id": "643f4038", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1904,10 +1909,10 @@ "cell_type": "markdown", "id": "b07b62ef", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "Without specifying the `name` argument, the `generate_greeting` will use the default value specified within the function definition." @@ -1917,11 +1922,11 @@ "cell_type": "markdown", "id": "7e95592e", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# 2. Data structures\n", @@ -1934,11 +1939,11 @@ "cell_type": "markdown", "id": "aae1eed3", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## List methods\n", @@ -1950,7 +1955,6 @@ "execution_count": null, "id": "cb25df04", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -1966,10 +1970,10 @@ "cell_type": "markdown", "id": "50327676", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "We can access the number of elements with `len`" @@ -1980,7 +1984,6 @@ "execution_count": null, "id": "250138ea", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -1995,11 +1998,11 @@ "cell_type": "markdown", "id": "5bda75d6", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Adding and removing values\n", @@ -2011,7 +2014,6 @@ "execution_count": null, "id": "e1027891", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2027,7 +2029,6 @@ "execution_count": null, "id": "48a12e4a", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2042,10 +2043,10 @@ "cell_type": "markdown", "id": "7e4b1b25", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "removing a specific element" @@ -2056,7 +2057,6 @@ "execution_count": null, "id": "3a23bbd1", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2071,11 +2071,11 @@ "cell_type": "markdown", "id": "290722a8", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Iterating over lists\n", @@ -2087,7 +2087,6 @@ "execution_count": null, "id": "54db3f5f", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2102,10 +2101,10 @@ "cell_type": "markdown", "id": "81d1f392", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "we can iterate over the list starting from the back using `reversed`" @@ -2116,7 +2115,6 @@ "execution_count": null, "id": "230fdc57", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2132,10 +2130,10 @@ "cell_type": "markdown", "id": "f6fce9a1", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "and `sorted`, sorts the values" @@ -2146,7 +2144,6 @@ "execution_count": null, "id": "100c9390", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2162,10 +2159,10 @@ "cell_type": "markdown", "id": "b26074d7", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "If you want a reversed new list you need to convert the iterator into a list" @@ -2176,7 +2173,6 @@ "execution_count": null, "id": "5279a6b8", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2192,7 +2188,6 @@ "execution_count": null, "id": "ad34c0bf", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2208,11 +2203,11 @@ "cell_type": "markdown", "id": "e00e5f84", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Checking if an item is in a list\n", @@ -2225,7 +2220,6 @@ "execution_count": null, "id": "0e61b0ef", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2240,11 +2234,11 @@ "cell_type": "markdown", "id": "8be77c84", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Emptying a list" @@ -2255,7 +2249,6 @@ "execution_count": null, "id": "867aa292", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2270,11 +2263,11 @@ "cell_type": "markdown", "id": "04d87890", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## _Tuples_\n", @@ -2286,7 +2279,6 @@ "execution_count": null, "id": "3afd38d5", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2302,7 +2294,6 @@ "execution_count": null, "id": "4bf75e76", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2320,7 +2311,6 @@ "execution_count": null, "id": "4775ecb7", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "fragment" @@ -2344,7 +2334,6 @@ "execution_count": null, "id": "8f3c40be", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2360,11 +2349,11 @@ "cell_type": "markdown", "id": "812d5a14", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "The dictionary method `items` returns a list of tuples (see an exercise after _dictionaries_)." @@ -2374,11 +2363,11 @@ "cell_type": "markdown", "id": "66b0bb86", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## _Sets_\n", @@ -2390,7 +2379,6 @@ "execution_count": null, "id": "a9622e5a", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2407,7 +2395,6 @@ "execution_count": null, "id": "95e68a89", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2424,7 +2411,6 @@ "execution_count": null, "id": "d84ee17a", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2440,11 +2426,11 @@ "cell_type": "markdown", "id": "4131293a", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "There are a few operators that work with sets as well as some useful methods:\n", @@ -2469,11 +2455,11 @@ "cell_type": "markdown", "id": "03763f24", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### _Example 1_\n", @@ -2485,7 +2471,6 @@ "execution_count": null, "id": "18bac89c", "metadata": { - "editable": true, "remove_code": "after:# Generate new list with unique values", "slideshow": { "slide_type": "" @@ -2503,10 +2488,10 @@ "cell_type": "markdown", "id": "d0501b3f", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "### _Example 2_\n", @@ -2519,7 +2504,6 @@ "execution_count": null, "id": "a924df94", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -2539,11 +2523,11 @@ "cell_type": "markdown", "id": "245d1725", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## _Dictionaries_\n", @@ -2554,11 +2538,11 @@ "cell_type": "markdown", "id": "8b83afd4", "metadata": { - "editable": false, "slideshow": { "slide_type": null }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "- _Dictionaries_ are like labelled drawers:\n", @@ -2576,7 +2560,6 @@ "execution_count": null, "id": "200a2eba", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -2593,7 +2576,6 @@ "execution_count": null, "id": "553707eb", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2609,7 +2591,6 @@ "execution_count": null, "id": "eb9476c1", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2626,7 +2607,6 @@ "execution_count": null, "id": "112e1c7b", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2643,7 +2623,6 @@ "execution_count": null, "id": "9affafb3", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2659,11 +2638,11 @@ "cell_type": "markdown", "id": "de3b6a25-6150-4fb7-8cab-e97872f8974e", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Accessing values from dictionaries" @@ -2684,7 +2663,6 @@ "execution_count": null, "id": "a71f9c99-e59e-4470-aa19-fde963cbb276", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2711,7 +2689,6 @@ "execution_count": null, "id": "3a6e30f1-c169-4ecb-9d59-f0e7cef1fb56", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2727,11 +2704,11 @@ "cell_type": "markdown", "id": "968a105e-1cc1-45e7-aa30-d19ce18943fe", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Looping over a dictionary" @@ -2752,7 +2729,6 @@ "execution_count": null, "id": "6081d62b-efd5-4b51-ba91-7307e53c9a36", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2769,7 +2745,6 @@ "execution_count": null, "id": "b65b03ae-768e-4bee-8502-b0ea4d633e5c", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2786,7 +2761,6 @@ "execution_count": null, "id": "2ff80eea-453f-44ac-8ddf-5f084008127b", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2802,11 +2776,11 @@ "cell_type": "markdown", "id": "f73a79d3", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Notes on _lists_, _strings_, _tuples_, _sets_, and _dictionaries_" @@ -2816,11 +2790,11 @@ "cell_type": "markdown", "id": "624091b9", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "* **_Lists_** and **_dictionaries_** are _mutable_, which means their contents can be changed.\n", @@ -2832,11 +2806,11 @@ "cell_type": "markdown", "id": "7271e95a", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Similarities of _lists_ and _strings_:\n", @@ -2850,7 +2824,6 @@ "execution_count": null, "id": "502cadb7", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2869,7 +2842,6 @@ "execution_count": null, "id": "3f76fba0", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2887,11 +2859,11 @@ "cell_type": "markdown", "id": "b35c5868", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -2904,7 +2876,6 @@ "execution_count": null, "id": "662c5a6c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -2927,11 +2898,11 @@ "cell_type": "markdown", "id": "70429b28", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## _Lists_ and _strings_ behave differently when we try to make copies." @@ -2942,7 +2913,6 @@ "execution_count": null, "id": "ceb379c2", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -2961,7 +2931,6 @@ "execution_count": null, "id": "d7738594", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -2979,11 +2948,11 @@ "cell_type": "markdown", "id": "36c080f0", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Everything in Python is an object. This includes numbers, strings, and lists and any other data structure. When we\n", @@ -2997,7 +2966,6 @@ "execution_count": null, "id": "e4dfb2cb", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3015,11 +2983,11 @@ "cell_type": "markdown", "id": "b424a761", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Have a Play!" @@ -3029,10 +2997,10 @@ "cell_type": "markdown", "id": "38cc0279", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "editable": false }, "source": [ "### _Exercise 1 (dictionaries)_" @@ -3042,11 +3010,11 @@ "cell_type": "markdown", "id": "3f494a2e", "metadata": { - "editable": false, "lines_to_next_cell": 2, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "1) Create a dictionary of the days in the months of the year.\n", @@ -3058,7 +3026,6 @@ "execution_count": null, "id": "3ae9acd3", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3079,11 +3046,11 @@ "cell_type": "markdown", "id": "1178f7dc", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### _Exercise 2 (dictionaries)_" @@ -3093,11 +3060,11 @@ "cell_type": "markdown", "id": "31e0b17b", "metadata": { - "editable": false, "jp-MarkdownHeadingCollapsed": true, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "1. Create a dictionary of several countries and capitals. Think about what's going to be a key and a value.\n", @@ -3111,7 +3078,6 @@ "execution_count": null, "id": "d3e579d3", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3132,11 +3098,11 @@ "cell_type": "markdown", "id": "07d53abe", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### _Exercise 3 (tuples)_" @@ -3146,10 +3112,10 @@ "cell_type": "markdown", "id": "6e83da5f", "metadata": { - "editable": false, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "Try `items()` method on the dictionary you've created before. Print that out. What kind of data structure does it return?" @@ -3160,7 +3126,6 @@ "execution_count": null, "id": "fb62cca7", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3181,11 +3146,11 @@ "cell_type": "markdown", "id": "f2ad81c8", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### _Exercise 4 (lists)_" @@ -3195,10 +3160,10 @@ "cell_type": "markdown", "id": "7c84ec76", "metadata": { - "editable": false, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "Given this list: " @@ -3209,7 +3174,6 @@ "execution_count": null, "id": "f964f97b", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3224,10 +3188,10 @@ "cell_type": "markdown", "id": "01378c1c", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "Complete these tasks:" @@ -3238,7 +3202,6 @@ "execution_count": null, "id": "9ad284dd", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3262,11 +3225,11 @@ "cell_type": "markdown", "id": "5bc9a961", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# 3. Conditional expressions\n", @@ -3278,7 +3241,6 @@ "execution_count": null, "id": "56986833", "metadata": { - "editable": true, "remove_code": "after:# shorten by ternary expression", "slideshow": { "slide_type": "fragment" @@ -3302,11 +3264,11 @@ "cell_type": "markdown", "id": "21217bab", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -3318,7 +3280,6 @@ "execution_count": null, "id": "81768bf7", "metadata": { - "editable": true, "remove_code": "# catch None with or", "slideshow": { "slide_type": "" @@ -3338,11 +3299,11 @@ "cell_type": "markdown", "id": "63274497", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -3354,7 +3315,6 @@ "execution_count": null, "id": "40fb97c5", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3374,7 +3334,6 @@ "execution_count": null, "id": "23e5335e", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3389,11 +3348,11 @@ "cell_type": "markdown", "id": "a6f9d70c-8116-4e65-b719-e3eb2afa7338", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Have a play!" @@ -3403,10 +3362,10 @@ "cell_type": "markdown", "id": "6dd1230b", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "editable": false }, "source": [ "#### Conditional Expression\n", @@ -3418,7 +3377,6 @@ "execution_count": null, "id": "30eb5d01", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3437,11 +3395,11 @@ "cell_type": "markdown", "id": "f77b3d5e", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# 4. Comprehensions" @@ -3451,10 +3409,10 @@ "cell_type": "markdown", "id": "0002904e", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" - } + }, + "editable": false }, "source": [ "### `list` comprehensions\n", @@ -3466,7 +3424,6 @@ "execution_count": null, "id": "d2d4f618", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -3483,10 +3440,10 @@ "cell_type": "markdown", "id": "2b2a108f", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" - } + }, + "editable": false }, "source": [ "You can simplify it using list comprehensions:" @@ -3497,7 +3454,6 @@ "execution_count": null, "id": "8e6b943b", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3513,10 +3469,10 @@ "cell_type": "markdown", "id": "fba1d4bd", "metadata": { - "editable": false, "slideshow": { "slide_type": "" - } + }, + "editable": false }, "source": [ "We can create a list for only a subset with a condition:" @@ -3527,7 +3483,6 @@ "execution_count": null, "id": "7fa7800c", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3554,7 +3509,6 @@ "execution_count": null, "id": "ef3ac491-86bf-4e69-9c32-1e320773202d", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3570,11 +3524,11 @@ "cell_type": "markdown", "id": "23631ac8", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### `dict` comprehensions" @@ -3585,7 +3539,6 @@ "execution_count": null, "id": "b19190dc", "metadata": { - "editable": true, "remove_code": "after:# print a dictionaries of lengths for the names", "slideshow": { "slide_type": "" @@ -3603,11 +3556,11 @@ "cell_type": "markdown", "id": "2d4e0235", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### `set` comprehensions" @@ -3618,7 +3571,6 @@ "execution_count": null, "id": "27175fde", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3634,11 +3586,11 @@ "cell_type": "markdown", "id": "f8beaad4", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Have a play!\n", @@ -3654,7 +3606,6 @@ "execution_count": null, "id": "72ee6d83", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3672,11 +3623,11 @@ "cell_type": "markdown", "id": "2092afdb", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "#### Dictionary Comprehension\n", @@ -3688,7 +3639,6 @@ "execution_count": null, "id": "9dc013da", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "after:# your solution", "slideshow": { @@ -3702,15 +3652,25 @@ "# your solution\n" ] }, + { + "cell_type": "markdown", + "id": "13a0e98b", + "metadata": { + "editable": false + }, + "source": [ + "# **Part II**" + ] + }, { "cell_type": "markdown", "id": "6e54d68e", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "# 5. Exceptions\n", @@ -3732,11 +3692,11 @@ "cell_type": "markdown", "id": "e4ffd520", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Exceptions often are used for known edge cases \n" @@ -3764,11 +3724,11 @@ "cell_type": "markdown", "id": "d26956f3", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Reraising Meaningful exceptions" @@ -3779,7 +3739,6 @@ "execution_count": null, "id": "6a7114a0", "metadata": { - "editable": true, "remove_code": "after:# Modify function to list the index and content of the entry that caused the error", "slideshow": { "slide_type": "" @@ -3809,11 +3768,11 @@ "cell_type": "markdown", "id": "44d08a7e", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Raising exceptions for invalid values" @@ -3844,11 +3803,11 @@ "cell_type": "markdown", "id": "6011ded7", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## The `finally` block will always be executed, either after code execution or after the failure\n", @@ -3870,7 +3829,6 @@ "execution_count": null, "id": "6401f075", "metadata": { - "editable": true, "remove_code": "after:# Modify function to always include the timing", "slideshow": { "slide_type": "" @@ -3908,11 +3866,11 @@ "cell_type": "markdown", "id": "bbc81d0f", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Best Practice:\n", @@ -3931,11 +3889,11 @@ "cell_type": "markdown", "id": "67e040dc", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Have a play:" @@ -3945,11 +3903,11 @@ "cell_type": "markdown", "id": "ff630616", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "\n", @@ -3986,74 +3944,69 @@ }, { "cell_type": "markdown", - "id": "930a9ea5", + "id": "ecad0562", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "# **Part II**" + "# 6. Introduction to modules\n", + "A _module_ is a single file (or collection of files) that is intended to be imported and used in other Python programs. It can include functions, classes, variables, and runnable code." ] }, { "cell_type": "markdown", - "id": "9e01e73d", + "id": "dc4b7323-f4f7-4b51-b6da-f651abf5029e", "metadata": { "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, "source": [ - "# 6. Brief introduction to Object-Oriented Programming" + "Modules let us:\n", + "- Use code that others have already written and tested\n", + "- Load in only the functionality we need\n", + "- Know exactly where a piece of functionality comes from" ] }, { "cell_type": "markdown", - "id": "3627c2ef", + "id": "9e1c43a8", "metadata": { - "editable": false, "slideshow": { - "slide_type": "" + "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "* Python is an object oriented programming language. Object-Oriented Programming (OOP) is a programming paradigm based on the concept of \"objects\" which can contain:\n", - " - Data (attributes)\n", - " - Code (methods)" + "## Importing _modules_" ] }, { "cell_type": "markdown", - "id": "8393fae9", + "id": "db90a278", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "\n", - "## 1. Classes and Objects\n", - " - Class: A blueprint for creating objects (Think a cookiecutter)\n", - " - Object: An instance of a class (The created cookies)\n", - "\n", - "\n", - "A simple example:" + "There are several ways of importing _modules_:" ] }, { "cell_type": "code", "execution_count": null, - "id": "5005c5bc", + "id": "0f8ee4bb", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4061,42 +4014,34 @@ }, "outputs": [], "source": [ - "# Simple example\n", - "class CourseParticipant:\n", - " def __init__(self, name, email):\n", - " self.name = name\n", - " self.email = email\n", - "\n", - " def welcome(self):\n", - " print(f\"Welcome {self.name}! We're glad to have you.\")\n", + "# import the whole module\n", + "import math\n", "\n", - "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", - "participant1.welcome()" + "# module's function name is in the module's namespace\n", + "print(math.sqrt(16.0))" ] }, { - "cell_type": "markdown", - "id": "b2a91e2a", + "cell_type": "code", + "execution_count": null, + "id": "338eca3f", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "## 2. Encapsulation\n", - " - Bundling data and methods that work on that data within one unit\n", - " - Restricting access to certain details\n", - " - Is also often used to keep track of states." + "# import several modules at once\n", + "import pathlib, sys, time" ] }, { "cell_type": "code", "execution_count": null, - "id": "74cd0847", + "id": "2f29773e", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4104,49 +4049,35 @@ }, "outputs": [], "source": [ - "class CourseParticipant:\n", - " def __init__(self, name, email):\n", - " self.name = name\n", - " self.email = email\n", - " self.registered_attendance = False\n", - "\n", - " def welcome(self):\n", - " print(f\"Welcome {self.name}! We're glad to have you.\")\n", - "\n", - " def register_attendance(self):\n", - " self.registered_attendance = True\n", - " print(f\"{self.name} has been registered for attendance.\")\n", - "\n", - "# use the class\n", - "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", - "participant1.welcome()\n", - "participant1.register_attendance()\n" + "# use 'as' keyword to change the name of the module\n", + "import math as m\n", + "print(m.sqrt(36.0))" ] }, { - "cell_type": "markdown", - "id": "df442469", + "cell_type": "code", + "execution_count": null, + "id": "77b96e95", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "## 3. Inheritance\n", - " - Creating new classes that extend the functionality of existing classes\n", - " - We _inherit_ the properties of the base class `CourseParticipant`\n", - " - `super()` lets us invoke the function of the same name from the base class\n", - " - Carefully decide between inheritance and composition (see soon)" + "# import only a selected function from a module\n", + "from math import sqrt\n", + "\n", + "# the function's name is in the global namespace\n", + "print(sqrt(49))" ] }, { "cell_type": "code", "execution_count": null, - "id": "8e94ff6d", + "id": "ce4f29f0", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4154,22 +4085,14 @@ }, "outputs": [], "source": [ - "class ExternalParticipant(CourseParticipant):\n", - " def __init__(self, name, email, company):\n", - " super().__init__(name, email)\n", - " self.company = company\n", - "\n", - " def contact_company(self):\n", - " print(f\"Contacting {self.company} regarding course participation.\")\n", - "\n", - "external_participant1 = ExternalParticipant(\"Bob\", \"bob@example.com\", \"Cooperative Inc.\")\n", - "external_participant1.welcome()\n", - "external_participant1.contact_company()\n" + "# change the name of the function in the module\n", + "from math import sqrt as square_root\n", + "print(square_root(25))" ] }, { "cell_type": "markdown", - "id": "2cf3958b", + "id": "04bec6e4-8e4d-4899-a3c3-c9abd332f275", "metadata": { "editable": false, "slideshow": { @@ -4178,19 +4101,15 @@ "tags": [] }, "source": [ - "## 4. Polymorphism\n", - "- Definition: Call the same method name on different object types and get type-specific behavior.\n", - "- Key idea: Write code to an interface, not a concrete class.\n", - "- Why it matters:\n", - " - Decouples caller from concrete types (extensible)\n", - " - Removes conditionals/type-checks (cleaner)\n", - " - Eases testing and substitution (mocks/fakes)" + "## Why Namespaces Matter\n", + "\n", + "The word `log` means two very different things:" ] }, { "cell_type": "code", "execution_count": null, - "id": "a414bc89", + "id": "4de72e4c-2795-4b4d-8542-10729a74f44a", "metadata": { "editable": true, "slideshow": { @@ -4200,50 +4119,47 @@ }, "outputs": [], "source": [ - "class DurhamUniversityParticipant(CourseParticipant):\n", - " def register_attendance(self):\n", - " super().register_attendance()\n", - " print(f\" Also registered attendance with the internal additional system for {self.name}\")\n", - " \n", + "import logging\n", "\n", - "participants = [\n", - " ExternalParticipant(\"Alice\", \"alice@example.com\", \"Acme Corp\"),\n", - " DurhamUniversityParticipant(\"Bob\", \"bob@durham.ac.uk\"),\n", - " CourseParticipant(\"Charlie\", \"charlie@example.com\")\n", - "]\n", + "math.log(100, 10) # A logarithm: 2.0\n", "\n", - "for participant in participants:\n", - " participant.register_attendance()" + "logging.log(20, \"Hello\") # A logbook entry: records a message" ] }, { "cell_type": "markdown", - "id": "fdb800a8", + "id": "36f46ead-b9a1-481f-8798-edbfc58b5504", "metadata": { "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, "source": [ - "## 5. Composition\n", - "\n", - "- Definition: Build classes by combining other objects (a class has collaborators).\n", - "- Why choose it:\n", - " - Favors flexibility and reuse over tight inheritance ties\n", - " - Swap components easily\n", - "\n", - "- If your `__init__` functions have alternative optional parameters, this is often a sign you should use composition\n", - "- Especially favour composition if there are several options for different behaviours that can be combined interchangeably (_has-a_ vs interitance: _is-a_)\n" + "Without namespaces, Python, and your reader, couldn't tell them apart." + ] + }, + { + "cell_type": "markdown", + "id": "fbf736e6-8dfb-4a00-86fb-5e71de650e9f", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "----\n", + "This is why importing a whole module into namespace is usually a bad idea:" ] }, { "cell_type": "code", "execution_count": null, - "id": "2cea837b", + "id": "44c18b00", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4251,185 +4167,124 @@ }, "outputs": [], "source": [ - "class Messenger:\n", - " def send_message(self, message):\n", - " pass\n", - "\n", - "class EmailMessenger(Messenger):\n", - "\n", - " def __init__(self, email):\n", - " self.email = email\n", - "\n", - " def send_message(self, message):\n", - " print(f\"Sending email to {self.email}: {message}\")\n", - "\n", - "class TeamsMessenger(Messenger):\n", - "\n", - " def __init__(self, user_id):\n", - " self.user_id = user_id\n", - "\n", - " def send_message(self, message):\n", - " print(f\"Sending Teams message to {self.user_id}: {message}\")\n", - "\n", - "\n", - "class Participant:\n", - " def __init__(self, name, messenger):\n", - " self.name = name\n", - " self.messenger = messenger\n", - "\n", - " def welcome(self):\n", - " self.messenger.send_message(f\"Welcome {self.name}!\")\n", - "\n", - "# Use the Participant class\n", - "participants = [\n", - " Participant(\"Alice\", EmailMessenger(\"alice@example.com\")),\n", - " Participant(\"Bob\", TeamsMessenger(\"bob123\"))\n", - "]\n", - "\n", - "for participant in participants:\n", - " participant.welcome()\n" + "# import all functions, variables, and classes from a module - better to avoid this\n", + "from math import *\n", + "print(sqrt(4.0))" ] }, { "cell_type": "markdown", - "id": "129df112", + "id": "d1cc0855", "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], "editable": false }, "source": [ - "---" + "## Getting help\n", + "To get help on a module at the Python shell, import it the whole (the very first way), then you can..." ] }, { - "cell_type": "markdown", - "id": "d9c8cd20", + "cell_type": "code", + "execution_count": null, + "id": "558e0d9e", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" - }, - "tags": [] + "slide_type": "" + } }, + "outputs": [], "source": [ - "## Have a play!" + "# get a list of the functions and variables in the module\n", + "dir(math)" ] }, { - "cell_type": "markdown", - "id": "28e31e47", + "cell_type": "code", + "execution_count": null, + "id": "01d2c703", "metadata": { - "editable": false, "slideshow": { "slide_type": "" + } + }, + "outputs": [], + "source": [ + "# get a long description\n", + "help(math)" + ] + }, + { + "cell_type": "markdown", + "id": "8e33b8e3", + "metadata": { + "slideshow": { + "slide_type": "fragment" }, - "tags": [] + "editable": false }, "source": [ - "### Plant Sensor API Exercise\n", - "You've been given a virtual sensor API module which you can import with (`import sensor_api`) that can monitor plants. \n", - "The API provides three functions:\n", - "\n", - "- `connect(sensor_id)`: Connects to a sensor (returns True/False)\n", - "- `disconnect(sensor_id)`: Disconnects from a sensor (returns True/False) \n", - "- `send_message(message)`: Sends a command and receives a reading (returns float or None)\n", - "\n", - "#### Message Format\n", - "Messages must be formatted as: `\"SENSOR_ID:COMMAND\"`\n", - "\n", - "Available commands:\n", - "- `SOIL_HUMIDITY`: Get soil humidity (0-100%)\n", - "- `AIR_HUMIDITY`: Get air humidity (0-100%)\n", - "- `TEMPERATURE`: Get temperature in Celsius\n", - "\n", - "#### Before\n", - "This is how working with the API would currently look:\n", - "\n", - "```python\n", - "import sensor_api\n", - "\n", - "sensor_id = \"GREENHOUSE_01\"\n", - "sensor_api.connect(sensor_id)\n", - "\n", - "soil_humidity = float(sensor_api.send_message(f\"{id}:SOIL_HUMIDITY\"))\n", - "air_humidity = float(sensor_api.send_message(f\"{id}:AIR_HUMIDITY\"))\n", - "temperature = float(sensor_api.send_message(f\"{id}:TEMPERATURE\"))\n", - "\n", - "print(f\"\\n=== Plant Sensor {sensor_id} Readings ===\")\n", - "print(f\"Soil Humidity: {soil_humidity}%\")\n", - "print(f\"Air Humidity: {air_humidity}%\")\n", - "print(f\"Temperature: {temperature}\u00b0C\")\n", - "print(\"=\" * 35)\n", - "sensor_api.disconnect(id)\n", - "```\n", - "\n", - "#### Your Task\n", - "Create a `PlantSensor` class that:\n", - "\n", - "1. Stores the sensor ID when created\n", - "2. Automatically connects when initialized\n", - "3. Provides easy-to-use methods for each measurement type\n", - "4. Properly disconnects when done\n", - "5. Displays all readings in a nice format\n", - "\n", - "\n", - "\n", - "#### Desired result\n", - "```python\n", - "# This is how your class should work:\n", - "sensor = PlantSensor(\"PLANT_01\")\n", - "soil = sensor.get_soil_humidity()\n", - "air = sensor.get_air_humidity()\n", - "temp = sensor.get_temperature()\n", - "sensor.display_readings()\n", - "sensor.disconnect()\n", - "```" + "---" ] }, { "cell_type": "markdown", - "id": "9cb57fee", + "id": "2d186e61-b776-483a-a6b9-0890af512e80", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "### Implementation" + "# 7. Advanced string manipulation" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "fb0d76f6", + "cell_type": "markdown", + "id": "e34aedb6", "metadata": { - "editable": true, - "remove_code": "all", + "editable": false, "slideshow": { - "slide_type": "" + "slide_type": "slide" }, "tags": [] }, - "outputs": [], "source": [ - "\n" + "## String Methods - Working with String Objects" ] }, { "cell_type": "markdown", - "id": "1624a7a4", + "id": "ffef8f84", "metadata": { - "editable": false + "editable": false, + "slideshow": { + "slide_type": "" + } }, "source": [ - "You can use this to try to use your class. You can comment out functionality, if you have not implemented it yet" + "In Python, strings are objects, and objects have **methods** - functions that belong to and operate on that object.\n", + "\n", + "**Syntax**: `string_object.method_name(arguments)`\n", + "\n", + "Key characteristics:\n", + "- Methods are called using _dot notation_: `variable.method()`\n", + "- String methods return a **new string** (strings are immutable)\n", + "- The original string is never modified\n", + "- You must assign the result if you want to keep it\n", + "\n", + "**Example:**" ] }, { "cell_type": "code", "execution_count": null, - "id": "49d66487", + "id": "d5bd4280", "metadata": { "editable": true, "slideshow": { @@ -4439,65 +4294,47 @@ }, "outputs": [], "source": [ - "my_plant = PlantSensor(\"GREENHOUSE_01\")\n", - "\n", - "# Take readings\n", - "my_plant.get_soil_humidity()\n", - "my_plant.get_air_humidity()\n", - "my_plant.get_temperature()\n", - "\n", - "# Display results\n", - "my_plant.display_readings()\n", - "\n", - "# Clean up\n", - "my_plant.disconnect()" + "text = \"hello world\"\n", + "result = text.upper() # Creates new string\n", + "print(text) # Still \"hello world\" \n", + "print(result) # \"HELLO WORLD\"" ] }, { "cell_type": "markdown", - "id": "ecad0562", + "id": "c9016a2e-dee1-4030-a1a0-8e519a84be6f", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "# 7. Introduction to modules\n", - "A _module_ is a single file (or collection of files) that is intended to be imported and used in other Python programs. It can include functions, classes, variables, and runnable code." + "Common categories of string methods we'll explore:\n", + "- **Finding/searching**: `find()`, `index()`\n", + "- **Checking**: `startswith()`, `endswith()`\n", + "- **Transforming**: `replace()`, `upper()`, `lower()`, `capitalize()`, `strip()`\n", + "- **Splitting/joining**: `split()`, `join()`" ] }, { "cell_type": "markdown", - "id": "9e1c43a8", + "id": "00e14678-81a2-4509-815a-53f9f2fdb332", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] - }, - "source": [ - "## Importing _modules_" - ] - }, - { - "cell_type": "markdown", - "id": "eed64626", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "" - } + "tags": [], + "editable": false }, "source": [ - "Python comes with hundreds of _modules_ doing all sorts of things. Also, many 3rd-party modules are available to download from the Internet." + "## Finding/searching string methods" ] }, { "cell_type": "markdown", - "id": "db90a278", + "id": "a4fa9b5b", "metadata": { "editable": false, "slideshow": { @@ -4505,15 +4342,16 @@ } }, "source": [ - "There are several ways of importing _modules_:" + "These methods help you locate substrings within a string, returning their position or checking for their presence:\n", + "* `index()`\n", + "* `find()`" ] }, { "cell_type": "code", "execution_count": null, - "id": "0f8ee4bb", + "id": "0eab0a2d-eea9-4c33-b700-56eb293ef28b", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4521,19 +4359,16 @@ }, "outputs": [], "source": [ - "# import the whole module\n", - "import math\n", - "\n", - "# module's function name is in the module's namespace\n", - "print(math.sqrt(16.0))" + "line = \"the quick brown fox jumped over a lazy dog\"\n", + "print(line.find('fox'))\n", + "print(line.index('fox'))" ] }, { "cell_type": "code", "execution_count": null, - "id": "338eca3f", + "id": "134c6eba-8897-4ee8-a6e5-f3740a0a4d21", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4541,54 +4376,44 @@ }, "outputs": [], "source": [ - "# import several modules at once\n", - "import pathlib, sys, time" + "print(line.find('wombat'))" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "2f29773e", + "cell_type": "markdown", + "id": "40d4c38b-9a07-4e49-a9b3-003dd13f129d", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" + "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, - "outputs": [], "source": [ - "# use 'as' keyword to change the name of the module\n", - "import math as m\n", - "print(m.sqrt(36.0))" + "## Checking string methods" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "77b96e95", + "cell_type": "markdown", + "id": "7b5ac28b-5cfb-4c43-bf54-093c240cbe2b", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, - "outputs": [], "source": [ - "# import only a selected function from a module\n", - "from math import sqrt\n", - "\n", - "# the function's name is in the global namespace\n", - "print(sqrt(49))" + "These methods return boolean values (`True` or `False`) to verify if a string matches certain patterns or criteria:\n", + "* `startswith(substring)`\n", + "* `endswith(substring)`" ] }, { "cell_type": "code", "execution_count": null, - "id": "ce4f29f0", + "id": "77d4d329-9e07-4100-a84e-bd8e55287b5d", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4596,17 +4421,18 @@ }, "outputs": [], "source": [ - "# change the name of the function in the module\n", - "from math import sqrt as square_root\n", - "print(square_root(25))" + "line = \"the quick brown fox jumped over a lazy dog\"\n", + "\n", + "print(line.startswith('the')) # True\n", + "print(line.endswith('dog')) # True - makes sense!\n", + "print(line.endswith('fox')) # False - now it's clear why" ] }, { "cell_type": "code", "execution_count": null, - "id": "44c18b00", + "id": "7e401e7c-4cc2-4de7-8e11-45654b9592b9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4614,381 +4440,154 @@ }, "outputs": [], "source": [ - "# import all functions, variables, and classes from a module into the global namespace\n", - "# - better to avoid this as some names from the module can interfere with your own variable names in the global namespace\n", - "from math import *\n", - "print(int(sqrt(4.0)))" + "# Case sensitivity matters\n", + "print(line.startswith('The')) # False - capital T\n", + "print(line.startswith('the')) # True - lowercase t" ] }, { "cell_type": "markdown", - "id": "d1cc0855", + "id": "e040bf97-a6bd-493e-b047-2041b5a99131", "metadata": { - "editable": false, "slideshow": { - "slide_type": "fragment" + "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "---\n", - "To get help on a module at the Python shell, import it the whole (the very first way), then you can..." + "The canonical way to search a string (if not interested in the index):" ] }, { "cell_type": "code", "execution_count": null, - "id": "558e0d9e", + "id": "47c2d357", "metadata": { - "editable": true, "slideshow": { "slide_type": "" - } + }, + "tags": [] }, "outputs": [], "source": [ - "# get a list of the functions and variables in the module\n", - "dir(math)" + "if \"fox\" in line:\n", + " print(\"A fox has been seen\")" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "01d2c703", + "cell_type": "markdown", + "id": "fe3ce02d-08bd-4c52-a935-d27b843dde39", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" - } + "slide_type": "slide" + }, + "tags": [], + "editable": false }, - "outputs": [], "source": [ - "# get a long description\n", - "help(math)" + "## Transforming string methods" ] }, { "cell_type": "markdown", - "id": "8e33b8e3", + "id": "80b12b8b", "metadata": { "editable": false, "slideshow": { - "slide_type": "fragment" + "slide_type": "" } }, "source": [ - "---" + "These methods create modified versions of strings by replacing content, changing case, or removing unwanted characters. _**Remember**: strings are immutable, so these methods always return a new string._\n", + "* `replace(old, new)`\n", + "* `upper()`\n", + "* `lower()`\n", + "* `capitalize()`\n", + "* `strip()`" ] }, { - "cell_type": "markdown", - "id": "2d186e61-b776-483a-a6b9-0890af512e80", + "cell_type": "code", + "execution_count": null, + "id": "292d8b56-1142-4927-9320-9c6331f5a962", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "# 8. Advanced string manipulation" + "line = \"the quick brown fox jumped over a lazy dog\"\n", + "print(line)\n", + "print(line.replace('brown', 'red'))" ] }, { - "cell_type": "markdown", - "id": "c9016a2e-dee1-4030-a1a0-8e519a84be6f", + "cell_type": "code", + "execution_count": null, + "id": "a95784ad-44fc-4e7c-9b16-caa09fedbc60", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "* Adjusting case\n", - "* Formatting strings\n", - " - _Note_: Modification requires assignment, because these functions return a copy, not modifying the original string\n", - "* Quering the existence, replacing, splitting" + "arc_update = \"ThE HAmILton suPERcompUTER is beiNg UPGraded\"\n", + "print(arc_update)\n", + "print(arc_update.upper())\n", + "print(arc_update.title())\n", + "print(arc_update.capitalize())" ] }, { - "cell_type": "markdown", - "id": "00e14678-81a2-4509-815a-53f9f2fdb332", + "cell_type": "code", + "execution_count": null, + "id": "22763b5f-7576-43c5-a237-925dce9b88aa", "metadata": { - "editable": false, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "## Finding values \n", - "* `find()` and `index()` both return index of a substring,\n", - " - `index()` raises a `ValueError` exception when not found (_exception handling_)\n", - " - `find()` returns `-1` when a values was not found\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0eab0a2d-eea9-4c33-b700-56eb293ef28b", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "line = \"the quick brown fox jumped over a lazy dog\"\n", - "print(line.find('fox'))\n", - "print(line.index('fox'))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "134c6eba-8897-4ee8-a6e5-f3740a0a4d21", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "print(line.find('wombat'))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fc5a28ef-8a31-434a-a653-1662cc274945", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "try:\n", - " print(line.index('wombat'))\n", - "except ValueError:\n", - " print(\"A wombat isn't mentioned in the text\")" - ] - }, - { - "cell_type": "markdown", - "id": "40d4c38b-9a07-4e49-a9b3-003dd13f129d", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Checking conditions on strings" - ] - }, - { - "cell_type": "markdown", - "id": "7b5ac28b-5cfb-4c43-bf54-093c240cbe2b", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "* Checking whether a string starts or ends a certain way is really common and easy" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "77d4d329-9e07-4100-a84e-bd8e55287b5d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "line = \"the quick brown fox jumped over a lazy dog\"\n", - "\n", - "print(line.startswith('the')) # True\n", - "print(line.endswith('dog')) # True - makes sense!\n", - "print(line.endswith('fox')) # False - now it's clear why" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7e401e7c-4cc2-4de7-8e11-45654b9592b9", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# Case sensitivity matters\n", - "print(line.startswith('The')) # False - capital T\n", - "print(line.startswith('the')) # True - lowercase t" - ] - }, - { - "cell_type": "markdown", - "id": "e040bf97-a6bd-493e-b047-2041b5a99131", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "* The canonical way to search a string (if not interested in the index):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "47c2d357", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "if \"fox\" in line:\n", - " print(\"A fox has been seen\")" - ] - }, - { - "cell_type": "markdown", - "id": "fe3ce02d-08bd-4c52-a935-d27b843dde39", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Replacing a value:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "292d8b56-1142-4927-9320-9c6331f5a962", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "line = \"the quick brown fox jumped over a lazy dog\"\n", - "print(line)\n", - "print(line.replace('brown', 'red'))" + "user_input = \" john.doe@email.com \"\n", + "email = user_input.strip()\n", + "print(f\"Original: '{user_input}'\")\n", + "print(f\"Cleaned: '{email}'\")" ] }, { "cell_type": "markdown", - "id": "bb4faee5-8c3f-4919-acbe-1b7b2cf7b700", + "id": "6cf8076f-8f50-49ae-b558-39336c323880", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] - }, - "source": [ - "## Bring all words to a common case" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a95784ad-44fc-4e7c-9b16-caa09fedbc60", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] + "tags": [], + "editable": false }, - "outputs": [], "source": [ - "arc_update = \"ThE HAmILton suPERcompUTER is beiNg UPGraded\"\n", - "print(arc_update)\n", - "print(arc_update.upper())\n", - "print(arc_update.title())\n", - "print(arc_update.capitalize())" + "## Splitting/joining string methods" ] }, { "cell_type": "markdown", - "id": "7a25cc7f-6040-4c03-ac38-b5f9a7baef41", + "id": "71a4546c", "metadata": { "editable": false, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Removing white space" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22763b5f-7576-43c5-a237-925dce9b88aa", - "metadata": { - "editable": true, "slideshow": { "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "user_input = \" john.doe@email.com \"\n", - "email = user_input.strip()\n", - "print(f\"Original: '{user_input}'\")\n", - "print(f\"Cleaned: '{email}'\")" - ] - }, - { - "cell_type": "markdown", - "id": "6cf8076f-8f50-49ae-b558-39336c323880", - "metadata": { - "editable": false, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] + } }, "source": [ - "## Extracting/concatenating the individual words or parts" + "These methods allow you to break strings apart into lists of substrings, or combine lists of strings into a single string. They're particularly useful for parsing text data or formatting output:\n", + "* `split(separator)` - splits string into a list at each occurrence of separator (defaults to whitespace)\n", + "* `join(iterable)` - joins elements of an iterable into a single string with the string as separator" ] }, { @@ -4996,7 +4595,6 @@ "execution_count": null, "id": "1f26c482", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5017,14 +4615,14 @@ "cell_type": "markdown", "id": "0b649711-58b1-4174-9277-2a921e6a3b6f", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "The operation in the other direction is `a_string.join()` where `a_string` is placed between every string of a list" + "The `join` operation is `a_string.join()` where `a_string` is placed between every string of a list" ] }, { @@ -5032,7 +4630,6 @@ "execution_count": null, "id": "5c81a93d-6fca-40e5-ae22-6697a9352272", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5049,7 +4646,6 @@ "execution_count": null, "id": "cb9837fc-dd67-447c-b503-8029678581ab", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5065,11 +4661,11 @@ "cell_type": "markdown", "id": "a965b5d9-59f4-4ed5-b7e9-89f5f0bcf60f", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Have a play!" @@ -5079,11 +4675,11 @@ "cell_type": "markdown", "id": "a2cd1c9a-967b-4f4b-8153-c4f55d50b377", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Practical Example: Text Processing Pipeline\n", @@ -5159,11 +4755,11 @@ "cell_type": "markdown", "id": "9fb3a479-cddd-4b00-8e5d-88194c82f9ed", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "#### Solution" @@ -5174,7 +4770,6 @@ "execution_count": null, "id": "d69d4356-f129-40c7-a682-2f2f5fb9d190", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "all", "slideshow": { @@ -5189,27 +4784,58 @@ }, { "cell_type": "markdown", - "id": "995ee9e7-cde0-483e-84c9-9df1b3238384", + "id": "586e5a27", "metadata": { - "editable": false, - "slideshow": { + "editable": false + }, + "source": [ + "# Thank You for Attending! \ud83d\udc4b\n", + "\n", + "- Feedback would really be appreciated.\n", + "- Check out our other training courses at ARC:\n", + " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/training-/\n", + "- RSE support by ARC at Durham University:\n", + " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/research-software-engineering/\n", + "\n", + "#### Contact\n", + "- Email: arc-rse@durham.ac.uk\n", + "\n", + "Happy Coding! \ud83d\udc0d" + ] + }, + { + "cell_type": "markdown", + "id": "25f9ad8e", + "metadata": { + "editable": false + }, + "source": [ + "# **Optional Topics**" + ] + }, + { + "cell_type": "markdown", + "id": "995ee9e7-cde0-483e-84c9-9df1b3238384", + "metadata": { + "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ - "# 9. (Optional) Working with modules: Examples and creating your own" + "# 8. (Optional) Working with modules: Examples and creating your own" ] }, { "cell_type": "markdown", "id": "b14a6818", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Some useful _modules_" @@ -5219,11 +4845,11 @@ "cell_type": "markdown", "id": "012efab2", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Python comes with a program called _pip_ (Python Package Installer) which will automatically fetch packages released and listed on PyPI: `pip install `" @@ -5233,11 +4859,11 @@ "cell_type": "markdown", "id": "eb000d98", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "| Name | Description |\n", @@ -5263,11 +4889,11 @@ "cell_type": "markdown", "id": "4e16a864", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Using _modules_" @@ -5277,11 +4903,11 @@ "cell_type": "markdown", "id": "17798548", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### _Example_\n", @@ -5293,7 +4919,6 @@ "execution_count": null, "id": "cf38baf4-5486-4c17-bc93-42510f8a6db7", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5311,7 +4936,6 @@ "execution_count": null, "id": "47affbe3-0eb6-4ed6-8717-3ef05b072a80", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5329,7 +4953,6 @@ "execution_count": null, "id": "98714766-5033-43d8-a9a3-0589b7bf32ec", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5347,7 +4970,6 @@ "execution_count": null, "id": "3fe290ad-e12f-4021-b8ef-a6d9bd6a7467", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5368,7 +4990,6 @@ "execution_count": null, "id": "cdcbc0b1-197d-4fc5-95e9-9501868b7525", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5386,7 +5007,6 @@ "execution_count": null, "id": "b33c4e26-ec82-405d-97a5-bd88488c06d8", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5405,7 +5025,6 @@ "execution_count": null, "id": "89847e34-7e99-4b89-904f-b7ec2c8dd774", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5423,11 +5042,11 @@ "cell_type": "markdown", "id": "4e9801e0", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -5438,11 +5057,11 @@ "cell_type": "markdown", "id": "a306f3cb", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Writing a csv file:" @@ -5453,7 +5072,6 @@ "execution_count": null, "id": "b10a1b92", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5482,12 +5100,12 @@ "cell_type": "markdown", "id": "3a9c7b35", "metadata": { - "editable": false, "jp-MarkdownHeadingCollapsed": true, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---\n", @@ -5499,7 +5117,6 @@ "execution_count": null, "id": "7d2b75d2-f0a2-490e-be7d-28dad71ef05c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5519,7 +5136,6 @@ "execution_count": null, "id": "9af8c87f-62db-4a04-86d8-d51428395210", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5542,11 +5158,11 @@ "cell_type": "markdown", "id": "6ee8121a", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "---" @@ -5556,11 +5172,11 @@ "cell_type": "markdown", "id": "a00f019b", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Building your own module\n", @@ -5580,11 +5196,11 @@ "cell_type": "markdown", "id": "dd9284d3-b9cc-43b1-a369-731c3e09351e", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### Simple example:" @@ -5627,11 +5243,11 @@ "cell_type": "markdown", "id": "a547c272-803a-46e8-af1f-00600ad11e92", "metadata": { - "editable": false, "slideshow": { "slide_type": "" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "Then you can use it in your main program:" @@ -5642,7 +5258,6 @@ "execution_count": null, "id": "2d3584bd-f99b-4fc8-9b19-db321634f329", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5661,11 +5276,11 @@ "cell_type": "markdown", "id": "47dd6a0c", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "### ```__main__``` special built-in variable\n", @@ -5680,11 +5295,11 @@ "cell_type": "markdown", "id": "7f4123ae", "metadata": { - "editable": false, "slideshow": { "slide_type": "fragment" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "\n", @@ -5704,11 +5319,11 @@ "cell_type": "markdown", "id": "bbe2196d", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, - "tags": [] + "tags": [], + "editable": false }, "source": [ "## Have a play!\n", @@ -5730,7 +5345,6 @@ "execution_count": null, "id": "be842bd3", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -5750,7 +5364,6 @@ "execution_count": null, "id": "506cd6b2", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -5769,7 +5382,6 @@ "execution_count": null, "id": "454b088a", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -5788,7 +5400,6 @@ "execution_count": null, "id": "faee9ea4", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -5808,7 +5419,6 @@ "execution_count": null, "id": "c8b612fa", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -5824,40 +5434,463 @@ }, { "cell_type": "markdown", - "id": "6522c182", + "id": "9e01e73d", "metadata": { - "editable": false, "slideshow": { - "slide_type": "fragment" - } + "slide_type": "slide" + }, + "tags": [], + "editable": false }, "source": [ - "---" + "# 9. (Optional) Brief introduction to Object-Oriented Programming" ] }, { "cell_type": "markdown", - "id": "ef9b73ae", + "id": "3627c2ef", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [], + "editable": false + }, + "source": [ + "* Python is an object oriented programming language. Object-Oriented Programming (OOP) is a programming paradigm based on the concept of \"objects\" which can contain:\n", + " - Data (attributes)\n", + " - Code (methods)" + ] + }, + { + "cell_type": "markdown", + "id": "8393fae9", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, + "source": [ + "\n", + "## 1. Classes and Objects\n", + " - Class: A blueprint for creating objects (Think a cookiecutter)\n", + " - Object: An instance of a class (The created cookies)\n", + "\n", + "\n", + "A simple example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5005c5bc", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Simple example\n", + "class CourseParticipant:\n", + " def __init__(self, name, email):\n", + " self.name = name\n", + " self.email = email\n", + "\n", + " def welcome(self):\n", + " print(f\"Welcome {self.name}! We're glad to have you.\")\n", + "\n", + "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", + "participant1.welcome()" + ] + }, + { + "cell_type": "markdown", + "id": "b2a91e2a", "metadata": { - "editable": false, "slideshow": { "slide_type": "slide" }, + "tags": [], + "editable": false + }, + "source": [ + "## 2. Encapsulation\n", + " - Bundling data and methods that work on that data within one unit\n", + " - Restricting access to certain details\n", + " - Is also often used to keep track of states." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74cd0847", + "metadata": { + "slideshow": { + "slide_type": "" + }, "tags": [] }, + "outputs": [], "source": [ - "# Thank You for Attending! \ud83d\udc4b\n", + "class CourseParticipant:\n", + " def __init__(self, name, email):\n", + " self.name = name\n", + " self.email = email\n", + " self.registered_attendance = False\n", "\n", - "- Feedback would really be appreciated (see the link in the email I've sent)\n", - "- Check out our other training courses at ARC:\n", - " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/training-/\n", - "- RSE support by ARC at Durham University:\n", - " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/research-software-engineering/\n", + " def welcome(self):\n", + " print(f\"Welcome {self.name}! We're glad to have you.\")\n", "\n", - "#### Contact\n", - "- Email: arc-rse@durham.ac.uk\n", + " def register_attendance(self):\n", + " self.registered_attendance = True\n", + " print(f\"{self.name} has been registered for attendance.\")\n", "\n", - "Happy Coding! \ud83d\udc0d" + "# use the class\n", + "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", + "participant1.welcome()\n", + "participant1.register_attendance()\n" + ] + }, + { + "cell_type": "markdown", + "id": "df442469", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, + "source": [ + "## 3. Inheritance\n", + " - Creating new classes that extend the functionality of existing classes\n", + " - We _inherit_ the properties of the base class `CourseParticipant`\n", + " - `super()` lets us invoke the function of the same name from the base class\n", + " - Carefully decide between inheritance and composition (see soon)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e94ff6d", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class ExternalParticipant(CourseParticipant):\n", + " def __init__(self, name, email, company):\n", + " super().__init__(name, email)\n", + " self.company = company\n", + "\n", + " def contact_company(self):\n", + " print(f\"Contacting {self.company} regarding course participation.\")\n", + "\n", + "external_participant1 = ExternalParticipant(\"Bob\", \"bob@example.com\", \"Cooperative Inc.\")\n", + "external_participant1.welcome()\n", + "external_participant1.contact_company()\n" + ] + }, + { + "cell_type": "markdown", + "id": "2cf3958b", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, + "source": [ + "## 4. Polymorphism\n", + "- Definition: Call the same method name on different object types and get type-specific behavior.\n", + "- Key idea: Write code to an interface, not a concrete class.\n", + "- Why it matters:\n", + " - Decouples caller from concrete types (extensible)\n", + " - Removes conditionals/type-checks (cleaner)\n", + " - Eases testing and substitution (mocks/fakes)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a414bc89", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class DurhamUniversityParticipant(CourseParticipant):\n", + " def register_attendance(self):\n", + " super().register_attendance()\n", + " print(f\" Also registered attendance with the internal additional system for {self.name}\")\n", + " \n", + "\n", + "participants = [\n", + " ExternalParticipant(\"Alice\", \"alice@example.com\", \"Acme Corp\"),\n", + " DurhamUniversityParticipant(\"Bob\", \"bob@durham.ac.uk\"),\n", + " CourseParticipant(\"Charlie\", \"charlie@example.com\")\n", + "]\n", + "\n", + "for participant in participants:\n", + " participant.register_attendance()" + ] + }, + { + "cell_type": "markdown", + "id": "fdb800a8", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, + "source": [ + "## 5. Composition\n", + "\n", + "- Definition: Build classes by combining other objects (a class has collaborators).\n", + "- Why choose it:\n", + " - Favors flexibility and reuse over tight inheritance ties\n", + " - Swap components easily\n", + "\n", + "- If your `__init__` functions have alternative optional parameters, this is often a sign you should use composition\n", + "- Especially favour composition if there are several options for different behaviours that can be combined interchangeably (_has-a_ vs interitance: _is-a_)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2cea837b", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class Messenger:\n", + " def send_message(self, message):\n", + " pass\n", + "\n", + "class EmailMessenger(Messenger):\n", + "\n", + " def __init__(self, email):\n", + " self.email = email\n", + "\n", + " def send_message(self, message):\n", + " print(f\"Sending email to {self.email}: {message}\")\n", + "\n", + "class TeamsMessenger(Messenger):\n", + "\n", + " def __init__(self, user_id):\n", + " self.user_id = user_id\n", + "\n", + " def send_message(self, message):\n", + " print(f\"Sending Teams message to {self.user_id}: {message}\")\n", + "\n", + "\n", + "class Participant:\n", + " def __init__(self, name, messenger):\n", + " self.name = name\n", + " self.messenger = messenger\n", + "\n", + " def welcome(self):\n", + " self.messenger.send_message(f\"Welcome {self.name}!\")\n", + "\n", + "# Use the Participant class\n", + "participants = [\n", + " Participant(\"Alice\", EmailMessenger(\"alice@example.com\")),\n", + " Participant(\"Bob\", TeamsMessenger(\"bob123\"))\n", + "]\n", + "\n", + "for participant in participants:\n", + " participant.welcome()\n" + ] + }, + { + "cell_type": "markdown", + "id": "129df112", + "metadata": { + "editable": false + }, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "d9c8cd20", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, + "source": [ + "## Have a play!" + ] + }, + { + "cell_type": "markdown", + "id": "28e31e47", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [], + "editable": false + }, + "source": [ + "### Plant Sensor API Exercise\n", + "You've been given a virtual sensor API module which you can import with (`import sensor_api`) that can monitor plants. \n", + "The API provides three functions:\n", + "\n", + "- `connect(sensor_id)`: Connects to a sensor (returns True/False)\n", + "- `disconnect(sensor_id)`: Disconnects from a sensor (returns True/False) \n", + "- `send_message(message)`: Sends a command and receives a reading (returns float or None)\n", + "\n", + "#### Message Format\n", + "Messages must be formatted as: `\"SENSOR_ID:COMMAND\"`\n", + "\n", + "Available commands:\n", + "- `SOIL_HUMIDITY`: Get soil humidity (0-100%)\n", + "- `AIR_HUMIDITY`: Get air humidity (0-100%)\n", + "- `TEMPERATURE`: Get temperature in Celsius\n", + "\n", + "#### Before\n", + "This is how working with the API would currently look:\n", + "\n", + "```python\n", + "import sensor_api\n", + "\n", + "sensor_id = \"GREENHOUSE_01\"\n", + "sensor_api.connect(sensor_id)\n", + "\n", + "soil_humidity = float(sensor_api.send_message(f\"{id}:SOIL_HUMIDITY\"))\n", + "air_humidity = float(sensor_api.send_message(f\"{id}:AIR_HUMIDITY\"))\n", + "temperature = float(sensor_api.send_message(f\"{id}:TEMPERATURE\"))\n", + "\n", + "print(f\"\\n=== Plant Sensor {sensor_id} Readings ===\")\n", + "print(f\"Soil Humidity: {soil_humidity}%\")\n", + "print(f\"Air Humidity: {air_humidity}%\")\n", + "print(f\"Temperature: {temperature}\u00b0C\")\n", + "print(\"=\" * 35)\n", + "sensor_api.disconnect(id)\n", + "```\n", + "\n", + "#### Your Task\n", + "Create a `PlantSensor` class that:\n", + "\n", + "1. Stores the sensor ID when created\n", + "2. Automatically connects when initialized\n", + "3. Provides easy-to-use methods for each measurement type\n", + "4. Properly disconnects when done\n", + "5. Displays all readings in a nice format\n", + "\n", + "\n", + "\n", + "#### Desired result\n", + "```python\n", + "# This is how your class should work:\n", + "sensor = PlantSensor(\"PLANT_01\")\n", + "soil = sensor.get_soil_humidity()\n", + "air = sensor.get_air_humidity()\n", + "temp = sensor.get_temperature()\n", + "sensor.display_readings()\n", + "sensor.disconnect()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "9cb57fee", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [], + "editable": false + }, + "source": [ + "### Implementation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb0d76f6", + "metadata": { + "remove_code": "all", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "1624a7a4", + "metadata": { + "editable": false + }, + "source": [ + "You can use this to try to use your class. You can comment out functionality, if you have not implemented it yet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49d66487", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "my_plant = PlantSensor(\"GREENHOUSE_01\")\n", + "\n", + "# Take readings\n", + "my_plant.get_soil_humidity()\n", + "my_plant.get_air_humidity()\n", + "my_plant.get_temperature()\n", + "\n", + "# Display results\n", + "my_plant.display_readings()\n", + "\n", + "# Clean up\n", + "my_plant.disconnect()" + ] + }, + { + "cell_type": "markdown", + "id": "6522c182", + "metadata": { + "slideshow": { + "slide_type": "fragment" + }, + "editable": false + }, + "source": [ + "---" ] } ], @@ -5877,7 +5910,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.2" + "version": "3.13.0" } }, "nbformat": 4, diff --git a/Intermediate_full.ipynb b/Intermediate_full.ipynb index 03331a1..c4653d8 100644 --- a/Intermediate_full.ipynb +++ b/Intermediate_full.ipynb @@ -4,7 +4,6 @@ "cell_type": "markdown", "id": "872c6494", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -20,7 +19,6 @@ "cell_type": "markdown", "id": "2cd478b7", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -47,7 +45,6 @@ "cell_type": "markdown", "id": "4d58fde4", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -72,7 +69,6 @@ "cell_type": "markdown", "id": "e673e2cd", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -86,7 +82,6 @@ "cell_type": "markdown", "id": "85069fdb", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -100,22 +95,23 @@ "- [Part I](#Part-I)\n", " - [1. Recap](#1.-Recap)\n", " - [2. Data structures](#2.-Data-structures)\n", - " - [3. Conditional expression](#3.-Conditional-expressions)\n", + " - [3. Conditional expressions](#3.-Conditional-expressions)\n", " - [4. Comprehensions](#4.-Comprehensions)\n", - " - [5. Exceptions](#5-exceptions)\n", "\n", "- [Part II](#Part-II)\n", - " - [5. Brief introduction to Object-Oriented Programming](#6-brief-introduction-to-object-oriented-programming)\n", - " - [6. Introduction to modules](#7-introduction-to-modules)\n", - " - [7. Advanced string manipulation](#8-advanced-string-manipulation)\n", - " - [8. (Optional) Working with modules: Examples and creating your own](#9-optional-working-with-modules-examples-and-creating-your-own)\n" + " - [5. Exceptions](#5.-Exceptions)\n", + " - [6. Introduction to modules](#6.-Introduction-to-modules)\n", + " - [7. Advanced string manipulation](#7.-Advanced-string-manipulation)\n", + "\n", + "- [Optional topics](#Optional-Topics)\n", + " - [8. Working with modules: Examples and creating your own](#8.-(Optional)-Working-with-modules:-Examples-and-creating-your-own)\n", + " - [9. Brief introduction to Object-Oriented Programming](#9.-(Optional)-Brief-introduction-to-Object-Oriented-Programming)\n" ] }, { "cell_type": "markdown", "id": "153ed362", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -129,7 +125,6 @@ "cell_type": "markdown", "id": "6ba842c0", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -143,7 +138,6 @@ "cell_type": "markdown", "id": "b1d20fc9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -164,7 +158,6 @@ "cell_type": "markdown", "id": "cdfa9441", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -178,7 +171,6 @@ "cell_type": "markdown", "id": "3eadf8e2", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -196,7 +188,6 @@ "cell_type": "markdown", "id": "26d2d446", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -210,21 +201,19 @@ "cell_type": "markdown", "id": "4e49802b", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, "tags": [] }, "source": [ - "# **1.** Recap" + "# 1. Recap" ] }, { "cell_type": "markdown", "id": "f99bdeea", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -245,7 +234,6 @@ "cell_type": "markdown", "id": "b721c83a", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -268,7 +256,6 @@ } } }, - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -286,7 +273,6 @@ "execution_count": null, "id": "decd8f2c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -302,7 +288,6 @@ "execution_count": null, "id": "1489fa3d", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -318,7 +303,6 @@ "execution_count": null, "id": "fb6110d3", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -333,7 +317,6 @@ "execution_count": null, "id": "ac31e498", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -347,7 +330,6 @@ "cell_type": "markdown", "id": "e1bd297e", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -365,7 +347,6 @@ "execution_count": null, "id": "94b6e716", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -381,7 +362,6 @@ "execution_count": null, "id": "d11dd969", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -396,7 +376,6 @@ "cell_type": "markdown", "id": "2a63c2dd", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -410,7 +389,6 @@ "cell_type": "markdown", "id": "7ab44bf2", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -428,7 +406,6 @@ "cell_type": "markdown", "id": "c33c20f5", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -442,7 +419,6 @@ "cell_type": "markdown", "id": "7a797eab", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -462,7 +438,6 @@ "execution_count": null, "id": "c13d9a15", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -478,7 +453,6 @@ "execution_count": null, "id": "26b8760c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -492,7 +466,6 @@ "cell_type": "markdown", "id": "b9324c88", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -506,7 +479,6 @@ "execution_count": null, "id": "3253e3d0", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -523,7 +495,6 @@ "cell_type": "markdown", "id": "397f9f86", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" } @@ -539,7 +510,6 @@ "execution_count": null, "id": "3342a922", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -555,7 +525,6 @@ "execution_count": null, "id": "36e671e1", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -569,7 +538,6 @@ "cell_type": "markdown", "id": "b68a5bbf", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" } @@ -593,7 +561,6 @@ "execution_count": null, "id": "af62e441", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -608,7 +575,6 @@ "execution_count": null, "id": "7e7ef933", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -623,7 +589,6 @@ "execution_count": null, "id": "28810d42", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -638,7 +603,6 @@ "execution_count": null, "id": "8b66a0a4", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -653,7 +617,6 @@ "execution_count": null, "id": "6984dbe1", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -668,7 +631,6 @@ "execution_count": null, "id": "74e37711", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -678,169 +640,10 @@ "print(\"Exponentiation:\", 2 ** 3)" ] }, - { - "cell_type": "markdown", - "id": "9ca15865", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "#### Boolean" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7b7abb8", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - } - }, - "outputs": [], - "source": [ - "b1 = False\n", - "b2 = True\n", - "print(b1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9296bb88", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - } - }, - "outputs": [], - "source": [ - "type(True) # boolean" - ] - }, - { - "cell_type": "markdown", - "id": "eae67d96", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "**Logical Operators** \n", - "We can also determine conditions based on Boolean logic: `and`, `or`, `not`" - ] - }, - { - "cell_type": "markdown", - "id": "b38b2739", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "**AND:**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db33e773", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "a = True\n", - "b = False\n", - "\n", - "a and b" - ] - }, - { - "cell_type": "markdown", - "id": "8b00b658", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "---\n", - "**OR:**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "725d0173", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - } - }, - "outputs": [], - "source": [ - "a = True\n", - "b = False\n", - "\n", - "a or b" - ] - }, - { - "cell_type": "markdown", - "id": "6a10fe2f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "---\n", - "**NOT:**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "27378611", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "a = True\n", - "\n", - "not a" - ] - }, { "cell_type": "markdown", "id": "a5e3ab30", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -854,7 +657,6 @@ "cell_type": "markdown", "id": "ba570bf4", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -868,7 +670,6 @@ "execution_count": null, "id": "ea3df5a1", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -886,7 +687,6 @@ "execution_count": null, "id": "e3c09d2d", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -901,7 +701,6 @@ "cell_type": "markdown", "id": "50a4347d", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -918,7 +717,6 @@ "execution_count": null, "id": "d9fadfdc", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -934,7 +732,6 @@ "cell_type": "markdown", "id": "d20cb9b3", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -948,7 +745,6 @@ "cell_type": "markdown", "id": "7ac031a7", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -963,7 +759,6 @@ "execution_count": null, "id": "41b7cdfe", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -981,7 +776,6 @@ "execution_count": null, "id": "9c50f102", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1000,7 +794,6 @@ "execution_count": null, "id": "3f72dedf", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1018,7 +811,6 @@ "cell_type": "markdown", "id": "8ee98ee9", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1032,7 +824,6 @@ "cell_type": "markdown", "id": "6b2e3c6e", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1047,7 +838,6 @@ "execution_count": null, "id": "a1178a62", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1064,7 +854,6 @@ "cell_type": "markdown", "id": "52819c95", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1078,7 +867,6 @@ "cell_type": "markdown", "id": "a0966820", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1103,7 +891,6 @@ "execution_count": null, "id": "38966db9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1121,7 +908,6 @@ "cell_type": "markdown", "id": "aadba414", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1141,7 +927,6 @@ "execution_count": null, "id": "7f0a6056", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1158,7 +943,6 @@ "execution_count": null, "id": "ec567746", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1174,7 +958,6 @@ "cell_type": "markdown", "id": "1f1185e6", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1188,7 +971,6 @@ "cell_type": "markdown", "id": "179f132a", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1202,7 +984,6 @@ "cell_type": "markdown", "id": "e998f8fe", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1217,7 +998,6 @@ "execution_count": null, "id": "911d44b3", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1234,7 +1014,6 @@ "cell_type": "markdown", "id": "b61a8691", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1248,7 +1027,6 @@ "cell_type": "markdown", "id": "9c82edee", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1266,7 +1044,6 @@ "cell_type": "markdown", "id": "8bb91a15", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1283,7 +1060,6 @@ "execution_count": null, "id": "fdc8600e", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1299,7 +1075,6 @@ "cell_type": "markdown", "id": "efc747a1", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1315,7 +1090,6 @@ "execution_count": null, "id": "2b2c4dee", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1330,7 +1104,6 @@ "execution_count": null, "id": "3f87d56b", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1345,7 +1118,6 @@ "execution_count": null, "id": "b686d58d", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1361,7 +1133,6 @@ "execution_count": null, "id": "1f916c68", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1375,7 +1146,6 @@ "cell_type": "markdown", "id": "b8369a1a", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1391,7 +1161,6 @@ "execution_count": null, "id": "e0fac9bf", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1407,7 +1176,6 @@ "execution_count": null, "id": "586edf14", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1422,7 +1190,6 @@ "execution_count": null, "id": "9f0dea38", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1437,7 +1204,6 @@ "execution_count": null, "id": "bab8e8a0", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1451,7 +1217,6 @@ "cell_type": "markdown", "id": "fe6ffaf2", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1467,7 +1232,6 @@ "execution_count": null, "id": "0edf3fa6", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1482,49 +1246,243 @@ "cell_type": "markdown", "id": "f87cfa0f", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, "tags": [] }, "source": [ - "## Repetitions and Conditions" + "## Repetitions and Conditions\n", + "\n", + "First, let's recap boolean logic. Boolean logic uses just two values: True, and False." ] }, { "cell_type": "markdown", - "id": "9303b3ff", + "id": "9ca15865", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" } }, "source": [ - "**Conditions** \n", - "In order to control program flow, and whether or not code is executed, we can do conditions based on variable values." + "#### Boolean" ] }, { "cell_type": "code", "execution_count": null, - "id": "a0af6ea1", + "id": "d7b7abb8", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } }, "outputs": [], "source": [ - "x = 5\n", - "\n", - "if x > 2:\n", - " print(\"x =\", x, \"is GREATER THAN 2\")\n", - "\n", - "if x == 3:\n", - " print(\"x =\", x, \"is EQUAL TO 3\")\n", + "b1 = False\n", + "b2 = True\n", + "print(b1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9296bb88", + "metadata": { + "slideshow": { + "slide_type": "" + } + }, + "outputs": [], + "source": [ + "type(True) # boolean" + ] + }, + { + "cell_type": "markdown", + "id": "eae67d96", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "**Logical Operators** \n", + "We can determine conditions based on Boolean logic: using `and`, `or`, `not` to *evaluate* boolean expressions:" + ] + }, + { + "cell_type": "markdown", + "id": "b38b2739", + "metadata": { + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "**AND:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "db33e773", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "a = True\n", + "b = False\n", + "\n", + "a and b" + ] + }, + { + "cell_type": "markdown", + "id": "5c8055b9-5863-486e-a741-de11eee3faa9", + "metadata": {}, + "source": [ + "We can display the results of the `AND` operation using a \"truth table\":\n", + "| *and* | True | False |\n", + "| --------- | ----- | ----- |\n", + "| __True__ | True | False |\n", + "| __False__ | False | False |" + ] + }, + { + "cell_type": "markdown", + "id": "8b00b658", + "metadata": { + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "---\n", + "**OR:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "725d0173", + "metadata": { + "slideshow": { + "slide_type": "" + } + }, + "outputs": [], + "source": [ + "a = True\n", + "b = False\n", + "\n", + "a or b" + ] + }, + { + "cell_type": "markdown", + "id": "4a4f35dc-5107-4589-984a-75f7a929958c", + "metadata": {}, + "source": [ + "| *or* | True | False |\n", + "| --------- | ----- | ----- |\n", + "| __True__ | True | True |\n", + "| __False__ | True | False |\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "6a10fe2f", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "---\n", + "**NOT:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27378611", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "a = True\n", + "\n", + "not a" + ] + }, + { + "cell_type": "markdown", + "id": "bf19d081-ce51-4b07-bc67-94c4569b9ca9", + "metadata": {}, + "source": [ + "| *not* | True | False |\n", + "| ----- | ----- | ----- |\n", + "| | False | True |" + ] + }, + { + "cell_type": "markdown", + "id": "9303b3ff", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "**Conditions** \n", + "In order to control program flow, and whether or not code is executed, we can do conditions based on variable values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7fd769b8-28d3-416a-823f-21f7ffcceef7", + "metadata": {}, + "outputs": [], + "source": [ + "if a:\n", + " print(\"a is True!\")\n", + "else:\n", + " print(\"a is False.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0af6ea1", + "metadata": { + "slideshow": { + "slide_type": "" + } + }, + "outputs": [], + "source": [ + "x = 5\n", + "\n", + "if x > 2:\n", + " print(\"x =\", x, \"is GREATER THAN 2\")\n", + "\n", + "if x == 3:\n", + " print(\"x =\", x, \"is EQUAL TO 3\")\n", "\n", "if x >= 3:\n", " print(\"x =\", x, \"is GREATER THAN or EQUAL TO 3\")\n", @@ -1540,7 +1498,6 @@ "cell_type": "markdown", "id": "3246bbe1", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1557,7 +1514,6 @@ "execution_count": null, "id": "8cab77e6", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1579,7 +1535,6 @@ "cell_type": "markdown", "id": "8c87d3f8", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1594,7 +1549,6 @@ "cell_type": "markdown", "id": "095edef4", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1610,7 +1564,6 @@ "execution_count": null, "id": "c7dc2e03", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1628,7 +1581,6 @@ "cell_type": "markdown", "id": "76e99a09", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -1641,7 +1593,6 @@ "cell_type": "markdown", "id": "e5b05a2c", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1657,7 +1608,6 @@ "execution_count": null, "id": "b14f546d", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1674,7 +1624,6 @@ "execution_count": null, "id": "713884f6", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1690,7 +1639,6 @@ "execution_count": null, "id": "b3078796", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1705,7 +1653,6 @@ "cell_type": "markdown", "id": "99b52e73", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1723,7 +1670,6 @@ "execution_count": null, "id": "136268d9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -1741,7 +1687,6 @@ "cell_type": "markdown", "id": "89cd06cc", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -1755,7 +1700,6 @@ "cell_type": "markdown", "id": "b6c7b631", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" } @@ -1768,7 +1712,6 @@ "cell_type": "markdown", "id": "ad3766a1", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1786,7 +1729,6 @@ "cell_type": "markdown", "id": "b83eb9fd", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1801,7 +1743,6 @@ "cell_type": "markdown", "id": "25dddacf", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1816,7 +1757,6 @@ "cell_type": "markdown", "id": "aa2983d4", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1831,7 +1771,6 @@ "execution_count": null, "id": "d4ca99fa", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1851,7 +1790,6 @@ "cell_type": "markdown", "id": "429c78c2", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1865,7 +1803,6 @@ "cell_type": "markdown", "id": "f64d31aa", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -1881,7 +1818,6 @@ "execution_count": null, "id": "643f4038", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -1904,7 +1840,6 @@ "cell_type": "markdown", "id": "b07b62ef", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -1917,7 +1852,6 @@ "cell_type": "markdown", "id": "7e95592e", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1934,7 +1868,6 @@ "cell_type": "markdown", "id": "aae1eed3", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -1950,7 +1883,6 @@ "execution_count": null, "id": "cb25df04", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -1968,7 +1900,6 @@ "cell_type": "markdown", "id": "50327676", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -1982,7 +1913,6 @@ "execution_count": null, "id": "250138ea", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -1998,7 +1928,6 @@ "cell_type": "markdown", "id": "5bda75d6", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2014,7 +1943,6 @@ "execution_count": null, "id": "e1027891", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2032,7 +1960,6 @@ "execution_count": null, "id": "48a12e4a", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2049,7 +1976,6 @@ "cell_type": "markdown", "id": "7e4b1b25", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -2063,7 +1989,6 @@ "execution_count": null, "id": "3a23bbd1", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2080,7 +2005,6 @@ "cell_type": "markdown", "id": "290722a8", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2096,7 +2020,6 @@ "execution_count": null, "id": "54db3f5f", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2113,7 +2036,6 @@ "cell_type": "markdown", "id": "81d1f392", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -2127,7 +2049,6 @@ "execution_count": null, "id": "230fdc57", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2145,7 +2066,6 @@ "cell_type": "markdown", "id": "f6fce9a1", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -2159,7 +2079,6 @@ "execution_count": null, "id": "100c9390", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2177,7 +2096,6 @@ "cell_type": "markdown", "id": "b26074d7", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -2191,7 +2109,6 @@ "execution_count": null, "id": "5279a6b8", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2208,7 +2125,6 @@ "execution_count": null, "id": "ad34c0bf", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2225,7 +2141,6 @@ "cell_type": "markdown", "id": "e00e5f84", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2242,7 +2157,6 @@ "execution_count": null, "id": "0e61b0ef", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2261,7 +2175,6 @@ "cell_type": "markdown", "id": "8be77c84", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2276,7 +2189,6 @@ "execution_count": null, "id": "867aa292", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2292,7 +2204,6 @@ "cell_type": "markdown", "id": "04d87890", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2308,7 +2219,6 @@ "execution_count": null, "id": "3afd38d5", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2326,7 +2236,6 @@ "execution_count": null, "id": "4bf75e76", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2348,7 +2257,6 @@ "execution_count": null, "id": "4775ecb7", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "fragment" @@ -2374,7 +2282,6 @@ "execution_count": null, "id": "8f3c40be", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2392,7 +2299,6 @@ "cell_type": "markdown", "id": "812d5a14", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -2406,7 +2312,6 @@ "cell_type": "markdown", "id": "66b0bb86", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2422,7 +2327,6 @@ "execution_count": null, "id": "a9622e5a", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2441,7 +2345,6 @@ "execution_count": null, "id": "95e68a89", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2460,7 +2363,6 @@ "execution_count": null, "id": "d84ee17a", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2477,7 +2379,6 @@ "cell_type": "markdown", "id": "4131293a", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -2506,7 +2407,6 @@ "cell_type": "markdown", "id": "03763f24", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2522,7 +2422,6 @@ "execution_count": null, "id": "18bac89c", "metadata": { - "editable": true, "remove_code": "after:# Generate new list with unique values", "slideshow": { "slide_type": "" @@ -2542,7 +2441,6 @@ "cell_type": "markdown", "id": "d0501b3f", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -2558,7 +2456,6 @@ "execution_count": null, "id": "a924df94", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -2578,7 +2475,6 @@ "cell_type": "markdown", "id": "245d1725", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2593,7 +2489,6 @@ "cell_type": "markdown", "id": "8b83afd4", "metadata": { - "editable": true, "slideshow": { "slide_type": null }, @@ -2615,7 +2510,6 @@ "execution_count": null, "id": "200a2eba", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -2632,7 +2526,6 @@ "execution_count": null, "id": "553707eb", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2653,7 +2546,6 @@ "execution_count": null, "id": "eb9476c1", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2672,7 +2564,6 @@ "execution_count": null, "id": "112e1c7b", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2691,7 +2582,6 @@ "execution_count": null, "id": "9affafb3", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2709,7 +2599,6 @@ "cell_type": "markdown", "id": "de3b6a25-6150-4fb7-8cab-e97872f8974e", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2732,7 +2621,6 @@ "execution_count": null, "id": "a71f9c99-e59e-4470-aa19-fde963cbb276", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2758,7 +2646,6 @@ "execution_count": null, "id": "3a6e30f1-c169-4ecb-9d59-f0e7cef1fb56", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2776,7 +2663,6 @@ "cell_type": "markdown", "id": "968a105e-1cc1-45e7-aa30-d19ce18943fe", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2799,7 +2685,6 @@ "execution_count": null, "id": "6081d62b-efd5-4b51-ba91-7307e53c9a36", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2818,7 +2703,6 @@ "execution_count": null, "id": "b65b03ae-768e-4bee-8502-b0ea4d633e5c", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2837,7 +2721,6 @@ "execution_count": null, "id": "2ff80eea-453f-44ac-8ddf-5f084008127b", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2855,7 +2738,6 @@ "cell_type": "markdown", "id": "f73a79d3", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2869,7 +2751,6 @@ "cell_type": "markdown", "id": "624091b9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -2885,7 +2766,6 @@ "cell_type": "markdown", "id": "7271e95a", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2903,7 +2783,6 @@ "execution_count": null, "id": "502cadb7", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2923,7 +2802,6 @@ "execution_count": null, "id": "3f76fba0", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -2942,7 +2820,6 @@ "cell_type": "markdown", "id": "b35c5868", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -2959,7 +2836,6 @@ "execution_count": null, "id": "662c5a6c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -2982,7 +2858,6 @@ "cell_type": "markdown", "id": "70429b28", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -2997,7 +2872,6 @@ "execution_count": null, "id": "ceb379c2", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3016,7 +2890,6 @@ "execution_count": null, "id": "d7738594", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3034,7 +2907,6 @@ "cell_type": "markdown", "id": "36c080f0", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -3052,7 +2924,6 @@ "execution_count": null, "id": "e4dfb2cb", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3070,7 +2941,6 @@ "cell_type": "markdown", "id": "b424a761", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3084,7 +2954,6 @@ "cell_type": "markdown", "id": "38cc0279", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" } @@ -3097,7 +2966,6 @@ "cell_type": "markdown", "id": "3f494a2e", "metadata": { - "editable": true, "lines_to_next_cell": 2, "slideshow": { "slide_type": "" @@ -3113,7 +2981,6 @@ "execution_count": null, "id": "3ae9acd3", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3153,7 +3020,6 @@ "cell_type": "markdown", "id": "1178f7dc", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3167,7 +3033,6 @@ "cell_type": "markdown", "id": "31e0b17b", "metadata": { - "editable": true, "jp-MarkdownHeadingCollapsed": true, "slideshow": { "slide_type": "" @@ -3185,7 +3050,6 @@ "execution_count": null, "id": "d3e579d3", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3215,7 +3079,6 @@ "cell_type": "markdown", "id": "07d53abe", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3229,7 +3092,6 @@ "cell_type": "markdown", "id": "6e83da5f", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -3243,7 +3105,6 @@ "execution_count": null, "id": "fb62cca7", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3267,13 +3128,14 @@ "cell_type": "markdown", "id": "8eb3bbf7", "metadata": { - "editable": true, "slideshow": { "slide_type": "notes" } }, "source": [ - "_Note_: the data structure returned by `dict.items()` is of type `dict_items`,\n", + "Speaker notes:\n", + "\n", + "The data structure returned by `dict.items()` is of type `dict_items`,\n", "which is an iterable view object displaying the dictionary’s (key, value) pairs" ] }, @@ -3281,7 +3143,6 @@ "cell_type": "markdown", "id": "f2ad81c8", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3295,7 +3156,6 @@ "cell_type": "markdown", "id": "7c84ec76", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -3309,7 +3169,6 @@ "execution_count": null, "id": "f964f97b", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3324,7 +3183,6 @@ "cell_type": "markdown", "id": "01378c1c", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -3338,7 +3196,6 @@ "execution_count": null, "id": "9ad284dd", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3367,7 +3224,6 @@ "cell_type": "markdown", "id": "5bc9a961", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3383,7 +3239,6 @@ "execution_count": null, "id": "56986833", "metadata": { - "editable": true, "remove_code": "after:# shorten by ternary expression", "slideshow": { "slide_type": "fragment" @@ -3409,7 +3264,6 @@ "cell_type": "markdown", "id": "21217bab", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -3425,7 +3279,6 @@ "execution_count": null, "id": "81768bf7", "metadata": { - "editable": true, "remove_code": "# catch None with or", "slideshow": { "slide_type": "" @@ -3445,7 +3298,6 @@ "cell_type": "markdown", "id": "63274497", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -3461,7 +3313,6 @@ "execution_count": null, "id": "40fb97c5", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3481,7 +3332,6 @@ "execution_count": null, "id": "23e5335e", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -3496,7 +3346,6 @@ "cell_type": "markdown", "id": "a6f9d70c-8116-4e65-b719-e3eb2afa7338", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3510,7 +3359,6 @@ "cell_type": "markdown", "id": "6dd1230b", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" } @@ -3525,7 +3373,6 @@ "execution_count": null, "id": "30eb5d01", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3547,7 +3394,6 @@ "cell_type": "markdown", "id": "f77b3d5e", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3561,7 +3407,6 @@ "cell_type": "markdown", "id": "0002904e", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" } @@ -3576,7 +3421,6 @@ "execution_count": null, "id": "d2d4f618", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -3593,7 +3437,6 @@ "cell_type": "markdown", "id": "2b2a108f", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" } @@ -3607,7 +3450,6 @@ "execution_count": null, "id": "8e6b943b", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3625,7 +3467,6 @@ "cell_type": "markdown", "id": "fba1d4bd", "metadata": { - "editable": true, "slideshow": { "slide_type": "" } @@ -3639,7 +3480,6 @@ "execution_count": null, "id": "7fa7800c", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3666,7 +3506,6 @@ "execution_count": null, "id": "ef3ac491-86bf-4e69-9c32-1e320773202d", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3683,7 +3522,6 @@ "cell_type": "markdown", "id": "23631ac8", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3698,7 +3536,6 @@ "execution_count": null, "id": "b19190dc", "metadata": { - "editable": true, "remove_code": "after:# print a dictionaries of lengths for the names", "slideshow": { "slide_type": "" @@ -3718,7 +3555,6 @@ "cell_type": "markdown", "id": "2d4e0235", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3733,7 +3569,6 @@ "execution_count": null, "id": "27175fde", "metadata": { - "editable": true, "remove_code": "non-comments", "slideshow": { "slide_type": "" @@ -3751,7 +3586,6 @@ "cell_type": "markdown", "id": "f8beaad4", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3771,7 +3605,6 @@ "execution_count": null, "id": "72ee6d83", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -3791,7 +3624,6 @@ "cell_type": "markdown", "id": "2092afdb", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3807,7 +3639,6 @@ "execution_count": null, "id": "9dc013da", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "after:# your solution", "slideshow": { @@ -3824,11 +3655,18 @@ "doubled_fruits\n" ] }, + { + "cell_type": "markdown", + "id": "13a0e98b", + "metadata": {}, + "source": [ + "# **Part II**" + ] + }, { "cell_type": "markdown", "id": "6e54d68e", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3854,14 +3692,13 @@ "cell_type": "markdown", "id": "b70b9fb0", "metadata": { - "editable": true, "slideshow": { "slide_type": "notes" }, "tags": [] }, "source": [ - "Notes:\n", + "Speaker notes:\n", " - We are using indented blocks again\n", " - All statements in the try block will be executed one by one\n", " - If one fails, the interpreter checks whether an except block with a matching exception type exists and execute the code in there\n", @@ -3875,7 +3712,6 @@ "cell_type": "markdown", "id": "e4ffd520", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3912,14 +3748,13 @@ "cell_type": "markdown", "id": "8986cf90", "metadata": { - "editable": true, "slideshow": { "slide_type": "notes" }, "tags": [] }, "source": [ - "Notes:\n", + "Speaker notes:\n", "- Do __not__ write out the function again, modify the original function to look like the result function\n", "- Demonstrate that you can catch the exception with a bare except\n", "- Change the function to use the `ZeroDivisionError` explicitely, to avoid catching errors we do not mean to catch" @@ -3929,7 +3764,6 @@ "cell_type": "markdown", "id": "d26956f3", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -3944,7 +3778,6 @@ "execution_count": null, "id": "6a7114a0", "metadata": { - "editable": true, "remove_code": "after:# Modify function to list the index and content of the entry that caused the error", "slideshow": { "slide_type": "" @@ -3984,14 +3817,13 @@ "cell_type": "markdown", "id": "7b376a1f", "metadata": { - "editable": true, "slideshow": { "slide_type": "notes" }, "tags": [] }, "source": [ - "Notes:\n", + "Speaker notes:\n", "- Do __not__ write out the function again, modify the original function to look like the result function\n", "- Using the from keyword we can add an exception to the error stack.\n", "- This can be used to give additional information, that makes the error source in the input easily traceable" @@ -4001,7 +3833,6 @@ "cell_type": "markdown", "id": "44d08a7e", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -4043,14 +3874,13 @@ "cell_type": "markdown", "id": "8903db8d", "metadata": { - "editable": true, "slideshow": { "slide_type": "notes" }, "tags": [] }, "source": [ - "Notes:\n", + "Speaker notes:\n", "- Do __not__ write out the function again, modify the original function to look like the result function\n", "- It is good practice to have these checks early in a function. Nobody likes to be 10h into a script execution to then fail a validation" ] @@ -4059,7 +3889,6 @@ "cell_type": "markdown", "id": "6011ded7", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -4085,7 +3914,6 @@ "execution_count": null, "id": "6401f075", "metadata": { - "editable": true, "remove_code": "after:# Modify function to always include the timing", "slideshow": { "slide_type": "" @@ -4133,14 +3961,13 @@ "cell_type": "markdown", "id": "e792e5a8", "metadata": { - "editable": true, "slideshow": { "slide_type": "notes" }, "tags": [] }, "source": [ - "Notes:\n", + "Speaker notes:\n", "- Do __not__ write out the function again, modify the original function to look like the result function\n", "- Finally is often used in clean up operations." ] @@ -4149,7 +3976,6 @@ "cell_type": "markdown", "id": "bbc81d0f", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -4172,7 +3998,6 @@ "cell_type": "markdown", "id": "67e040dc", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -4186,7 +4011,6 @@ "cell_type": "markdown", "id": "ff630616", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4238,74 +4062,66 @@ }, { "cell_type": "markdown", - "id": "930a9ea5", + "id": "ecad0562", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, "tags": [] }, "source": [ - "# **Part II**" + "# 6. Introduction to modules\n", + "A _module_ is a single file (or collection of files) that is intended to be imported and used in other Python programs. It can include functions, classes, variables, and runnable code." ] }, { "cell_type": "markdown", - "id": "9e01e73d", + "id": "dc4b7323-f4f7-4b51-b6da-f651abf5029e", "metadata": { "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, "source": [ - "# 6. Brief introduction to Object-Oriented Programming" + "Modules let us:\n", + "- Use code that others have already written and tested\n", + "- Load in only the functionality we need\n", + "- Know exactly where a piece of functionality comes from" ] }, { "cell_type": "markdown", - "id": "3627c2ef", + "id": "9e1c43a8", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" + "slide_type": "slide" }, "tags": [] }, "source": [ - "* Python is an object oriented programming language. Object-Oriented Programming (OOP) is a programming paradigm based on the concept of \"objects\" which can contain:\n", - " - Data (attributes)\n", - " - Code (methods)" + "## Importing _modules_" ] }, { "cell_type": "markdown", - "id": "8393fae9", + "id": "db90a278", "metadata": { - "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, "source": [ - "\n", - "## 1. Classes and Objects\n", - " - Class: A blueprint for creating objects (Think a cookiecutter)\n", - " - Object: An instance of a class (The created cookies)\n", - "\n", - "\n", - "A simple example:" + "There are several ways of importing _modules_:" ] }, { "cell_type": "code", "execution_count": null, - "id": "5005c5bc", + "id": "0f8ee4bb", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4313,61 +4129,51 @@ }, "outputs": [], "source": [ - "# Simple example\n", - "class CourseParticipant:\n", - " def __init__(self, name, email):\n", - " self.name = name\n", - " self.email = email\n", - "\n", - " def welcome(self):\n", - " print(f\"Welcome {self.name}! We're glad to have you.\")\n", + "# import the whole module\n", + "import math\n", "\n", - "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", - "participant1.welcome()" + "# module's function name is in the module's namespace\n", + "print(math.sqrt(16.0))" ] }, { - "cell_type": "markdown", - "id": "d9003b8b", + "cell_type": "code", + "execution_count": null, + "id": "338eca3f", "metadata": { - "editable": true, "slideshow": { - "slide_type": "notes" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "Speaker notes:\n", - "\n", - "The parts are:\n", - "- `class ClassName`: Classes are created with the `class` keyword and named in CamelCase\n", - "- `def __init__...`: The constructor method. This is used to create a new instance (cookie), with a given set of input variables. The first one is the reference to a given object created from the class (`self`), which is used to store the data/state.\n", - "- `def method_name(self)`: A method name. We again use `self` as the reference to an object created from the class" + "# import several modules at once\n", + "import pathlib, sys, time" ] }, { - "cell_type": "markdown", - "id": "b2a91e2a", + "cell_type": "code", + "execution_count": null, + "id": "2f29773e", "metadata": { - "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "## 2. Encapsulation\n", - " - Bundling data and methods that work on that data within one unit\n", - " - Restricting access to certain details\n", - " - Is also often used to keep track of states." + "# use 'as' keyword to change the name of the module\n", + "import math as m\n", + "print(m.sqrt(36.0))" ] }, { "cell_type": "code", "execution_count": null, - "id": "74cd0847", + "id": "77b96e95", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4375,45 +4181,33 @@ }, "outputs": [], "source": [ - "class CourseParticipant:\n", - " def __init__(self, name, email):\n", - " self.name = name\n", - " self.email = email\n", - " self.registered_attendance = False\n", - "\n", - " def welcome(self):\n", - " print(f\"Welcome {self.name}! We're glad to have you.\")\n", - "\n", - " def register_attendance(self):\n", - " self.registered_attendance = True\n", - " print(f\"{self.name} has been registered for attendance.\")\n", + "# import only a selected function from a module\n", + "from math import sqrt\n", "\n", - "# use the class\n", - "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", - "participant1.welcome()\n", - "participant1.register_attendance()\n" + "# the function's name is in the global namespace\n", + "print(sqrt(49))" ] }, { - "cell_type": "markdown", - "id": "915e7f40", + "cell_type": "code", + "execution_count": null, + "id": "ce4f29f0", "metadata": { - "editable": true, "slideshow": { - "slide_type": "notes" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "Speaker notes:\n", - " - Imagine we need a function to track whether users have attended the course.\n", - " - We can change the internal state of the object representing a given participant.\n", - " - By checking the registered_attendance attribute, we can track which participants have registered" + "# change the name of the function in the module\n", + "from math import sqrt as square_root\n", + "print(square_root(25))" ] }, { "cell_type": "markdown", - "id": "df442469", + "id": "04bec6e4-8e4d-4899-a3c3-c9abd332f275", "metadata": { "editable": true, "slideshow": { @@ -4422,17 +4216,15 @@ "tags": [] }, "source": [ - "## 3. Inheritance\n", - " - Creating new classes that extend the functionality of existing classes\n", - " - We _inherit_ the properties of the base class `CourseParticipant`\n", - " - `super()` lets us invoke the function of the same name from the base class\n", - " - Carefully decide between inheritance and composition (see soon)" + "## Why Namespaces Matter\n", + "\n", + "The word `log` means two very different things:" ] }, { "cell_type": "code", "execution_count": null, - "id": "8e94ff6d", + "id": "4de72e4c-2795-4b4d-8542-10729a74f44a", "metadata": { "editable": true, "slideshow": { @@ -4442,22 +4234,30 @@ }, "outputs": [], "source": [ - "class ExternalParticipant(CourseParticipant):\n", - " def __init__(self, name, email, company):\n", - " super().__init__(name, email)\n", - " self.company = company\n", + "import logging\n", "\n", - " def contact_company(self):\n", - " print(f\"Contacting {self.company} regarding course participation.\")\n", + "math.log(100, 10) # A logarithm: 2.0\n", "\n", - "external_participant1 = ExternalParticipant(\"Bob\", \"bob@example.com\", \"Cooperative Inc.\")\n", - "external_participant1.welcome()\n", - "external_participant1.contact_company()\n" + "logging.log(20, \"Hello\") # A logbook entry: records a message" ] }, { "cell_type": "markdown", - "id": "206d9ee0", + "id": "36f46ead-b9a1-481f-8798-edbfc58b5504", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "Without namespaces, Python, and your reader, couldn't tell them apart." + ] + }, + { + "cell_type": "markdown", + "id": "ccbef34a-9226-4735-859d-378640ee9cc7", "metadata": { "editable": true, "slideshow": { @@ -4467,36 +4267,29 @@ }, "source": [ "Speaker notes:\n", - "\n", - "Now imagine we can have external participants that are affiliated with a company. We want our object to have all the functionality of our `CourseParticipant` class, but also have additional functionality that is specific to our external participants." + "- In JupyterLite, logging output is suppressed by default unless you explicitly configure a handler." ] }, { "cell_type": "markdown", - "id": "2cf3958b", + "id": "fbf736e6-8dfb-4a00-86fb-5e71de650e9f", "metadata": { "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "fragment" }, "tags": [] }, "source": [ - "## 4. Polymorphism\n", - "- Definition: Call the same method name on different object types and get type-specific behavior.\n", - "- Key idea: Write code to an interface, not a concrete class.\n", - "- Why it matters:\n", - " - Decouples caller from concrete types (extensible)\n", - " - Removes conditionals/type-checks (cleaner)\n", - " - Eases testing and substitution (mocks/fakes)" + "----\n", + "This is why importing a whole module into namespace is usually a bad idea:" ] }, { "cell_type": "code", "execution_count": null, - "id": "a414bc89", + "id": "44c18b00", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4504,458 +4297,275 @@ }, "outputs": [], "source": [ - "class DurhamUniversityParticipant(CourseParticipant):\n", - " def register_attendance(self):\n", - " super().register_attendance()\n", - " print(f\" Also registered attendance with the internal additional system for {self.name}\")\n", - " \n", - "\n", - "participants = [\n", - " ExternalParticipant(\"Alice\", \"alice@example.com\", \"Acme Corp\"),\n", - " DurhamUniversityParticipant(\"Bob\", \"bob@durham.ac.uk\"),\n", - " CourseParticipant(\"Charlie\", \"charlie@example.com\")\n", - "]\n", - "\n", - "for participant in participants:\n", - " participant.register_attendance()" + "# import all functions, variables, and classes from a module - better to avoid this\n", + "from math import *\n", + "print(sqrt(4.0))" ] }, { "cell_type": "markdown", - "id": "5385bec2", + "id": "d1cc0855", "metadata": { - "editable": true, "slideshow": { - "slide_type": "notes" + "slide_type": "slide" }, "tags": [] }, "source": [ - "Speaker notes:\n", - "\n", - "Say for registering the attendance for our internal participants we are also required to call an API function (represented by the print statement here). We can overwrite the function to behave differently for the `DurhamUniveristyParticipant` class\n", - "\n", - " - We are using `super()` again. Note that this is not necessary\n", - " - We can still just use `register_attendance()` even though one of the functions now behaves differently.\n", - " - If there are lots of `if/else` statements depending on which type an programmed structure represents, objects with different types can simplify the structure significantly.\n", - " - It is quite easy to introduce an additional class that has another option for the behaviour." + "## Getting help\n", + "To get help on a module at the Python shell, import it the whole (the very first way), then you can..." ] }, { - "cell_type": "markdown", - "id": "fdb800a8", + "cell_type": "code", + "execution_count": null, + "id": "558e0d9e", "metadata": { - "editable": true, "slideshow": { - "slide_type": "slide" - }, - "tags": [] + "slide_type": "" + } }, + "outputs": [], "source": [ - "## 5. Composition\n", - "\n", - "- Definition: Build classes by combining other objects (a class has collaborators).\n", - "- Why choose it:\n", - " - Favors flexibility and reuse over tight inheritance ties\n", - " - Swap components easily\n", - "\n", - "- If your `__init__` functions have alternative optional parameters, this is often a sign you should use composition\n", - "- Especially favour composition if there are several options for different behaviours that can be combined interchangeably (_has-a_ vs interitance: _is-a_)\n" + "# get a list of the functions and variables in the module\n", + "dir(math)" ] }, { "cell_type": "code", "execution_count": null, - "id": "2cea837b", + "id": "01d2c703", "metadata": { - "editable": true, "slideshow": { "slide_type": "" - }, - "tags": [] + } }, "outputs": [], "source": [ - "class Messenger:\n", - " def send_message(self, message):\n", - " pass\n", - "\n", - "class EmailMessenger(Messenger):\n", - "\n", - " def __init__(self, email):\n", - " self.email = email\n", - "\n", - " def send_message(self, message):\n", - " print(f\"Sending email to {self.email}: {message}\")\n", - "\n", - "class TeamsMessenger(Messenger):\n", - "\n", - " def __init__(self, user_id):\n", - " self.user_id = user_id\n", - "\n", - " def send_message(self, message):\n", - " print(f\"Sending Teams message to {self.user_id}: {message}\")\n", - "\n", - "\n", - "class Participant:\n", - " def __init__(self, name, messenger):\n", - " self.name = name\n", - " self.messenger = messenger\n", - "\n", - " def welcome(self):\n", - " self.messenger.send_message(f\"Welcome {self.name}!\")\n", - "\n", - "# Use the Participant class\n", - "participants = [\n", - " Participant(\"Alice\", EmailMessenger(\"alice@example.com\")),\n", - " Participant(\"Bob\", TeamsMessenger(\"bob123\"))\n", - "]\n", - "\n", - "for participant in participants:\n", - " participant.welcome()\n" + "# get a long description\n", + "help(math)" ] }, { "cell_type": "markdown", - "id": "7ea0b8f0", + "id": "8e33b8e3", "metadata": { - "editable": true, "slideshow": { - "slide_type": "notes" - }, - "tags": [] + "slide_type": "fragment" + } }, - "source": [ - "Speaker notes\n", - " - In this example, participants can be contacted via e-mail or Teams\n", - " - The information we need for the two contact possibilities is completely independent\n", - " - The specific behaviour is used by the class, but the details are not important for the class\n", - " - So each object `has-a` messenger that can be used to contact the participant\n", - " - It is straightforward to inherit the different participant classes (External / DU) using this messenger, without creating four (Messing (2) x DU/External (2)) classes that would be needed with inheritance also\n" - ] - }, - { - "cell_type": "markdown", - "id": "129df112", - "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", - "id": "d9c8cd20", + "id": "2d186e61-b776-483a-a6b9-0890af512e80", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, "tags": [] }, "source": [ - "## Have a play!" + "# 7. Advanced string manipulation" ] }, { "cell_type": "markdown", - "id": "4858e58f", + "id": "e34aedb6", "metadata": { "editable": true, "slideshow": { - "slide_type": "notes" + "slide_type": "slide" }, "tags": [] }, "source": [ - "Speaker notes:\n", - "\n", - "While the explanations went quite a bit further, this example only needs the application of encapsulation. Packaging up basic Application Programming Interfaces (APIs) into a more useable form is a useful and common application of OOP. In the interest of time / scope we will keep the exercise a bit more simple, but feel free to also inquire about the other concepts while you work on it." + "## String Methods - Working with String Objects" ] }, { "cell_type": "markdown", - "id": "28e31e47", + "id": "ffef8f84", "metadata": { "editable": true, "slideshow": { "slide_type": "" - }, - "tags": [] + } }, "source": [ - "### Plant Sensor API Exercise\n", - "You've been given a virtual sensor API module which you can import with (`import sensor_api`) that can monitor plants. \n", - "The API provides three functions:\n", - "\n", - "- `connect(sensor_id)`: Connects to a sensor (returns True/False)\n", - "- `disconnect(sensor_id)`: Disconnects from a sensor (returns True/False) \n", - "- `send_message(message)`: Sends a command and receives a reading (returns float or None)\n", - "\n", - "#### Message Format\n", - "Messages must be formatted as: `\"SENSOR_ID:COMMAND\"`\n", - "\n", - "Available commands:\n", - "- `SOIL_HUMIDITY`: Get soil humidity (0-100%)\n", - "- `AIR_HUMIDITY`: Get air humidity (0-100%)\n", - "- `TEMPERATURE`: Get temperature in Celsius\n", - "\n", - "#### Before\n", - "This is how working with the API would currently look:\n", - "\n", - "```python\n", - "import sensor_api\n", - "\n", - "sensor_id = \"GREENHOUSE_01\"\n", - "sensor_api.connect(sensor_id)\n", - "\n", - "soil_humidity = float(sensor_api.send_message(f\"{id}:SOIL_HUMIDITY\"))\n", - "air_humidity = float(sensor_api.send_message(f\"{id}:AIR_HUMIDITY\"))\n", - "temperature = float(sensor_api.send_message(f\"{id}:TEMPERATURE\"))\n", - "\n", - "print(f\"\\n=== Plant Sensor {sensor_id} Readings ===\")\n", - "print(f\"Soil Humidity: {soil_humidity}%\")\n", - "print(f\"Air Humidity: {air_humidity}%\")\n", - "print(f\"Temperature: {temperature}°C\")\n", - "print(\"=\" * 35)\n", - "sensor_api.disconnect(id)\n", - "```\n", - "\n", - "#### Your Task\n", - "Create a `PlantSensor` class that:\n", - "\n", - "1. Stores the sensor ID when created\n", - "2. Automatically connects when initialized\n", - "3. Provides easy-to-use methods for each measurement type\n", - "4. Properly disconnects when done\n", - "5. Displays all readings in a nice format\n", + "In Python, strings are objects, and objects have **methods** - functions that belong to and operate on that object.\n", "\n", + "**Syntax**: `string_object.method_name(arguments)`\n", "\n", + "Key characteristics:\n", + "- Methods are called using _dot notation_: `variable.method()`\n", + "- String methods return a **new string** (strings are immutable)\n", + "- The original string is never modified\n", + "- You must assign the result if you want to keep it\n", "\n", - "#### Desired result\n", - "```python\n", - "# This is how your class should work:\n", - "sensor = PlantSensor(\"PLANT_01\")\n", - "soil = sensor.get_soil_humidity()\n", - "air = sensor.get_air_humidity()\n", - "temp = sensor.get_temperature()\n", - "sensor.display_readings()\n", - "sensor.disconnect()\n", - "```" + "**Example:**" ] }, { - "cell_type": "markdown", - "id": "9cb57fee", + "cell_type": "code", + "execution_count": null, + "id": "d5bd4280", "metadata": { "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "### Implementation" + "text = \"hello world\"\n", + "result = text.upper() # Creates new string\n", + "print(text) # Still \"hello world\" \n", + "print(result) # \"HELLO WORLD\"" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "fb0d76f6", + "cell_type": "markdown", + "id": "c9016a2e-dee1-4030-a1a0-8e519a84be6f", "metadata": { - "editable": true, - "remove_code": "all", "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [], "source": [ - "import sensor_api\n", - "\n", - "class PlantSensor:\n", - " def __init__(self, sensor_id):\n", - " \"\"\"Initialize the sensor with an ID and connect to it.\"\"\"\n", - " self.sensor_id = sensor_id\n", - " self.connected = sensor_api.connect(sensor_id)\n", - " \n", - " # Store readings\n", - " self.soil_humidity = None\n", - " self.air_humidity = None\n", - " self.temperature = None\n", - " \n", - " def get_soil_humidity(self):\n", - " \"\"\"Get soil humidity reading.\"\"\"\n", - " if self.connected:\n", - " message = f\"{self.sensor_id}:SOIL_HUMIDITY\"\n", - " self.soil_humidity = float(sensor_api.send_message(message))\n", - " return self.soil_humidity\n", - " return None\n", - " \n", - " def get_air_humidity(self):\n", - " \"\"\"Get air humidity reading.\"\"\"\n", - " if self.connected:\n", - " message = f\"{self.sensor_id}:AIR_HUMIDITY\"\n", - " self.air_humidity = float(sensor_api.send_message(message))\n", - " return self.air_humidity\n", - " return None\n", - " \n", - " def get_temperature(self):\n", - " \"\"\"Get temperature reading.\"\"\"\n", - " if self.connected:\n", - " message = f\"{self.sensor_id}:TEMPERATURE\"\n", - " self.temperature = float(sensor_api.send_message(message))\n", - " return self.temperature\n", - " return None\n", - " \n", - " def display_readings(self):\n", - " \"\"\"Display all sensor readings.\"\"\"\n", - " print(f\"\\n=== Plant Sensor {self.sensor_id} Readings ===\")\n", - " print(f\"Soil Humidity: {self.soil_humidity}%\")\n", - " print(f\"Air Humidity: {self.air_humidity}%\")\n", - " print(f\"Temperature: {self.temperature}°C\")\n", - " print(\"=\" * 35)\n", - " \n", - " def disconnect(self):\n", - " \"\"\"Disconnect from the sensor.\"\"\"\n", - " if self.connected:\n", - " sensor_api.disconnect(self.sensor_id)\n", - " self.connected = False" + "Common categories of string methods we'll explore:\n", + "- **Finding/searching**: `find()`, `index()`\n", + "- **Checking**: `startswith()`, `endswith()`\n", + "- **Transforming**: `replace()`, `upper()`, `lower()`, `capitalize()`, `strip()`\n", + "- **Splitting/joining**: `split()`, `join()`" ] }, { "cell_type": "markdown", - "id": "1624a7a4", - "metadata": {}, + "id": "00e14678-81a2-4509-815a-53f9f2fdb332", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, "source": [ - "You can use this to try to use your class. You can comment out functionality, if you have not implemented it yet" + "## Finding/searching string methods" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "49d66487", + "cell_type": "markdown", + "id": "a4fa9b5b", "metadata": { "editable": true, "slideshow": { "slide_type": "" - }, - "tags": [] + } }, - "outputs": [], "source": [ - "my_plant = PlantSensor(\"GREENHOUSE_01\")\n", - "\n", - "# Take readings\n", - "my_plant.get_soil_humidity()\n", - "my_plant.get_air_humidity()\n", - "my_plant.get_temperature()\n", - "\n", - "# Display results\n", - "my_plant.display_readings()\n", - "\n", - "# Clean up\n", - "my_plant.disconnect()" + "These methods help you locate substrings within a string, returning their position or checking for their presence:\n", + "* `index()`\n", + "* `find()`" ] }, { - "cell_type": "markdown", - "id": "ecad0562", + "cell_type": "code", + "execution_count": null, + "id": "0eab0a2d-eea9-4c33-b700-56eb293ef28b", "metadata": { - "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "# 7. Introduction to modules\n", - "A _module_ is a single file (or collection of files) that is intended to be imported and used in other Python programs. It can include functions, classes, variables, and runnable code." + "line = \"the quick brown fox jumped over a lazy dog\"\n", + "print(line.find('fox'))\n", + "print(line.index('fox'))" ] }, { - "cell_type": "markdown", - "id": "9e1c43a8", + "cell_type": "code", + "execution_count": null, + "id": "134c6eba-8897-4ee8-a6e5-f3740a0a4d21", "metadata": { - "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "## Importing _modules_" + "print(line.find('wombat'))" ] }, { "cell_type": "markdown", - "id": "eed64626", + "id": "714fc569", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" + "slide_type": "notes" } }, "source": [ - "Python comes with hundreds of _modules_ doing all sorts of things. Also, many 3rd-party modules are available to download from the Internet." + "Speaker notes:\n", + "\n", + "The key difference is how they handle missing substrings - `find()` returns `-1` while `index()` raises an exception:" ] }, { "cell_type": "markdown", - "id": "db90a278", + "id": "40d4c38b-9a07-4e49-a9b3-003dd13f129d", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" - } + "slide_type": "slide" + }, + "tags": [] }, "source": [ - "There are several ways of importing _modules_:" + "## Checking string methods" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "0f8ee4bb", + "cell_type": "markdown", + "id": "7b5ac28b-5cfb-4c43-bf54-093c240cbe2b", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [], "source": [ - "# import the whole module\n", - "import math\n", - "\n", - "# module's function name is in the module's namespace\n", - "print(math.sqrt(16.0))" + "These methods return boolean values (`True` or `False`) to verify if a string matches certain patterns or criteria:\n", + "* `startswith(substring)`\n", + "* `endswith(substring)`" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "338eca3f", + "cell_type": "markdown", + "id": "6ac1c80f", "metadata": { "editable": true, "slideshow": { - "slide_type": "" - }, - "tags": [] + "slide_type": "notes" + } }, - "outputs": [], "source": [ - "# import several modules at once\n", - "import pathlib, sys, time" + "Speaker notes:\n", + "\n", + "These methods are case-sensitive." ] }, { "cell_type": "code", "execution_count": null, - "id": "2f29773e", + "id": "77d4d329-9e07-4100-a84e-bd8e55287b5d", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4963,17 +4573,18 @@ }, "outputs": [], "source": [ - "# use 'as' keyword to change the name of the module\n", - "import math as m\n", - "print(m.sqrt(36.0))" + "line = \"the quick brown fox jumped over a lazy dog\"\n", + "\n", + "print(line.startswith('the')) # True\n", + "print(line.endswith('dog')) # True - makes sense!\n", + "print(line.endswith('fox')) # False - now it's clear why" ] }, { "cell_type": "code", "execution_count": null, - "id": "77b96e95", + "id": "7e401e7c-4cc2-4de7-8e11-45654b9592b9", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -4981,37 +4592,29 @@ }, "outputs": [], "source": [ - "# import only a selected function from a module\n", - "from math import sqrt\n", - "\n", - "# the function's name is in the global namespace\n", - "print(sqrt(49))" + "# Case sensitivity matters\n", + "print(line.startswith('The')) # False - capital T\n", + "print(line.startswith('the')) # True - lowercase t" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "ce4f29f0", + "cell_type": "markdown", + "id": "e040bf97-a6bd-493e-b047-2041b5a99131", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [], "source": [ - "# change the name of the function in the module\n", - "from math import sqrt as square_root\n", - "print(square_root(25))" + "The canonical way to search a string (if not interested in the index):" ] }, { "cell_type": "code", "execution_count": null, - "id": "44c18b00", + "id": "47c2d357", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5019,126 +4622,128 @@ }, "outputs": [], "source": [ - "# import all functions, variables, and classes from a module into the global namespace\n", - "# - better to avoid this as some names from the module can interfere with your own variable names in the global namespace\n", - "from math import *\n", - "print(int(sqrt(4.0)))" + "if \"fox\" in line:\n", + " print(\"A fox has been seen\")" ] }, { "cell_type": "markdown", - "id": "d1cc0855", + "id": "fe3ce02d-08bd-4c52-a935-d27b843dde39", "metadata": { - "editable": true, "slideshow": { - "slide_type": "fragment" + "slide_type": "slide" }, "tags": [] }, "source": [ - "---\n", - "To get help on a module at the Python shell, import it the whole (the very first way), then you can..." + "## Transforming string methods" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "558e0d9e", + "cell_type": "markdown", + "id": "80b12b8b", "metadata": { "editable": true, "slideshow": { "slide_type": "" } }, - "outputs": [], "source": [ - "# get a list of the functions and variables in the module\n", - "dir(math)" + "These methods create modified versions of strings by replacing content, changing case, or removing unwanted characters. _**Remember**: strings are immutable, so these methods always return a new string._\n", + "* `replace(old, new)`\n", + "* `upper()`\n", + "* `lower()`\n", + "* `capitalize()`\n", + "* `strip()`" ] }, { "cell_type": "code", "execution_count": null, - "id": "01d2c703", + "id": "292d8b56-1142-4927-9320-9c6331f5a962", "metadata": { - "editable": true, "slideshow": { "slide_type": "" - } + }, + "tags": [] }, "outputs": [], "source": [ - "# get a long description\n", - "help(math)" + "line = \"the quick brown fox jumped over a lazy dog\"\n", + "print(line)\n", + "print(line.replace('brown', 'red'))" ] }, { - "cell_type": "markdown", - "id": "8e33b8e3", + "cell_type": "code", + "execution_count": null, + "id": "a95784ad-44fc-4e7c-9b16-caa09fedbc60", "metadata": { - "editable": true, "slideshow": { - "slide_type": "fragment" - } + "slide_type": "" + }, + "tags": [] }, + "outputs": [], "source": [ - "---" + "arc_update = \"ThE HAmILton suPERcompUTER is beiNg UPGraded\"\n", + "print(arc_update)\n", + "print(arc_update.upper())\n", + "print(arc_update.title())\n", + "print(arc_update.capitalize())" ] }, { - "cell_type": "markdown", - "id": "2d186e61-b776-483a-a6b9-0890af512e80", + "cell_type": "code", + "execution_count": null, + "id": "22763b5f-7576-43c5-a237-925dce9b88aa", "metadata": { - "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "# 8. Advanced string manipulation" + "user_input = \" john.doe@email.com \"\n", + "email = user_input.strip()\n", + "print(f\"Original: '{user_input}'\")\n", + "print(f\"Cleaned: '{email}'\")" ] }, { "cell_type": "markdown", - "id": "c9016a2e-dee1-4030-a1a0-8e519a84be6f", + "id": "6cf8076f-8f50-49ae-b558-39336c323880", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" + "slide_type": "slide" }, "tags": [] }, "source": [ - "* Adjusting case\n", - "* Formatting strings\n", - " - _Note_: Modification requires assignment, because these functions return a copy, not modifying the original string\n", - "* Quering the existence, replacing, splitting" + "## Splitting/joining string methods" ] }, { "cell_type": "markdown", - "id": "00e14678-81a2-4509-815a-53f9f2fdb332", + "id": "71a4546c", "metadata": { "editable": true, "slideshow": { - "slide_type": "slide" - }, - "tags": [] + "slide_type": "" + } }, "source": [ - "## Finding values \n", - "* `find()` and `index()` both return index of a substring,\n", - " - `index()` raises a `ValueError` exception when not found (_exception handling_)\n", - " - `find()` returns `-1` when a values was not found\n" + "These methods allow you to break strings apart into lists of substrings, or combine lists of strings into a single string. They're particularly useful for parsing text data or formatting output:\n", + "* `split(separator)` - splits string into a list at each occurrence of separator (defaults to whitespace)\n", + "* `join(iterable)` - joins elements of an iterable into a single string with the string as separator" ] }, { "cell_type": "code", "execution_count": null, - "id": "0eab0a2d-eea9-4c33-b700-56eb293ef28b", + "id": "1f26c482", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5147,32 +4752,32 @@ "outputs": [], "source": [ "line = \"the quick brown fox jumped over a lazy dog\"\n", - "print(line.find('fox'))\n", - "print(line.index('fox'))" + "\n", + "# split by space\n", + "print(line.split())\n", + "\n", + "# split by word\n", + "print(line.split('jumped'))" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "134c6eba-8897-4ee8-a6e5-f3740a0a4d21", + "cell_type": "markdown", + "id": "0b649711-58b1-4174-9277-2a921e6a3b6f", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [], "source": [ - "print(line.find('wombat'))" + "The `join` operation is `a_string.join()` where `a_string` is placed between every string of a list" ] }, { "cell_type": "code", "execution_count": null, - "id": "fc5a28ef-8a31-434a-a653-1662cc274945", + "id": "5c81a93d-6fca-40e5-ae22-6697a9352272", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5180,327 +4785,59 @@ }, "outputs": [], "source": [ - "try:\n", - " print(line.index('wombat'))\n", - "except ValueError:\n", - " print(\"A wombat isn't mentioned in the text\")" + "string_list = [\"A\", \"list\", \"of\", \"split\", \"words\"]\n", + "print(\" \".join(string_list))" ] }, { - "cell_type": "markdown", - "id": "40d4c38b-9a07-4e49-a9b3-003dd13f129d", + "cell_type": "code", + "execution_count": null, + "id": "cb9837fc-dd67-447c-b503-8029678581ab", "metadata": { - "editable": true, "slideshow": { - "slide_type": "slide" + "slide_type": "" }, "tags": [] }, + "outputs": [], "source": [ - "## Checking conditions on strings" + "line_list = [\"First line\", \"Second line\"]\n", + "print(\"\\n\".join(line_list))" ] }, { "cell_type": "markdown", - "id": "7b5ac28b-5cfb-4c43-bf54-093c240cbe2b", + "id": "a965b5d9-59f4-4ed5-b7e9-89f5f0bcf60f", "metadata": { - "editable": true, "slideshow": { - "slide_type": "" + "slide_type": "slide" }, "tags": [] }, "source": [ - "* Checking whether a string starts or ends a certain way is really common and easy" + "## Have a play!" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "77d4d329-9e07-4100-a84e-bd8e55287b5d", + "cell_type": "markdown", + "id": "a2cd1c9a-967b-4f4b-8153-c4f55d50b377", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [], "source": [ - "line = \"the quick brown fox jumped over a lazy dog\"\n", + "### Practical Example: Text Processing Pipeline\n", "\n", - "print(line.startswith('the')) # True\n", - "print(line.endswith('dog')) # True - makes sense!\n", - "print(line.endswith('fox')) # False - now it's clear why" + "Let's combine several string manipulation techniques to clean and process some messy user data" ] }, { "cell_type": "code", "execution_count": null, - "id": "7e401e7c-4cc2-4de7-8e11-45654b9592b9", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# Case sensitivity matters\n", - "print(line.startswith('The')) # False - capital T\n", - "print(line.startswith('the')) # True - lowercase t" - ] - }, - { - "cell_type": "markdown", - "id": "e040bf97-a6bd-493e-b047-2041b5a99131", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "* The canonical way to search a string (if not interested in the index):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "47c2d357", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "if \"fox\" in line:\n", - " print(\"A fox has been seen\")" - ] - }, - { - "cell_type": "markdown", - "id": "fe3ce02d-08bd-4c52-a935-d27b843dde39", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Replacing a value:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "292d8b56-1142-4927-9320-9c6331f5a962", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "line = \"the quick brown fox jumped over a lazy dog\"\n", - "print(line)\n", - "print(line.replace('brown', 'red'))" - ] - }, - { - "cell_type": "markdown", - "id": "bb4faee5-8c3f-4919-acbe-1b7b2cf7b700", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Bring all words to a common case" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a95784ad-44fc-4e7c-9b16-caa09fedbc60", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "arc_update = \"ThE HAmILton suPERcompUTER is beiNg UPGraded\"\n", - "print(arc_update)\n", - "print(arc_update.upper())\n", - "print(arc_update.title())\n", - "print(arc_update.capitalize())" - ] - }, - { - "cell_type": "markdown", - "id": "7a25cc7f-6040-4c03-ac38-b5f9a7baef41", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Removing white space" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22763b5f-7576-43c5-a237-925dce9b88aa", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "user_input = \" john.doe@email.com \"\n", - "email = user_input.strip()\n", - "print(f\"Original: '{user_input}'\")\n", - "print(f\"Cleaned: '{email}'\")" - ] - }, - { - "cell_type": "markdown", - "id": "6cf8076f-8f50-49ae-b558-39336c323880", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Extracting/concatenating the individual words or parts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f26c482", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "line = \"the quick brown fox jumped over a lazy dog\"\n", - "\n", - "# split by space\n", - "print(line.split())\n", - "\n", - "# split by word\n", - "print(line.split('jumped'))" - ] - }, - { - "cell_type": "markdown", - "id": "0b649711-58b1-4174-9277-2a921e6a3b6f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "The operation in the other direction is `a_string.join()` where `a_string` is placed between every string of a list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5c81a93d-6fca-40e5-ae22-6697a9352272", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "string_list = [\"A\", \"list\", \"of\", \"split\", \"words\"]\n", - "print(\" \".join(string_list))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cb9837fc-dd67-447c-b503-8029678581ab", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "line_list = [\"First line\", \"Second line\"]\n", - "print(\"\\n\".join(line_list))" - ] - }, - { - "cell_type": "markdown", - "id": "a965b5d9-59f4-4ed5-b7e9-89f5f0bcf60f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Have a play!" - ] - }, - { - "cell_type": "markdown", - "id": "a2cd1c9a-967b-4f4b-8153-c4f55d50b377", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "### Practical Example: Text Processing Pipeline\n", - "\n", - "Let's combine several string manipulation techniques to clean and process some messy user data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3639015f-81e0-4abf-a574-0b2f1d08181b", - "metadata": {}, + "id": "3639015f-81e0-4abf-a574-0b2f1d08181b", + "metadata": {}, "outputs": [], "source": [ "# Raw user input with various issues\n", @@ -5564,7 +4901,6 @@ "cell_type": "markdown", "id": "9fb3a479-cddd-4b00-8e5d-88194c82f9ed", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5579,7 +4915,6 @@ "execution_count": null, "id": "d69d4356-f129-40c7-a682-2f2f5fb9d190", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "all", "slideshow": { @@ -5643,23 +4978,48 @@ }, { "cell_type": "markdown", - "id": "995ee9e7-cde0-483e-84c9-9df1b3238384", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, + "id": "586e5a27", + "metadata": {}, "source": [ - "# 9. (Optional) Working with modules: Examples and creating your own" - ] - }, + "# Thank You for Attending! 👋\n", + "\n", + "- Feedback would really be appreciated.\n", + "- Check out our other training courses at ARC:\n", + " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/training-/\n", + "- RSE support by ARC at Durham University:\n", + " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/research-software-engineering/\n", + "\n", + "#### Contact\n", + "- Email: arc-rse@durham.ac.uk\n", + "\n", + "Happy Coding! 🐍" + ] + }, + { + "cell_type": "markdown", + "id": "25f9ad8e", + "metadata": {}, + "source": [ + "# **Optional Topics**" + ] + }, + { + "cell_type": "markdown", + "id": "995ee9e7-cde0-483e-84c9-9df1b3238384", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "# 8. (Optional) Working with modules: Examples and creating your own" + ] + }, { "cell_type": "markdown", "id": "b14a6818", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -5673,7 +5033,6 @@ "cell_type": "markdown", "id": "012efab2", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5687,7 +5046,6 @@ "cell_type": "markdown", "id": "eb000d98", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5717,7 +5075,6 @@ "cell_type": "markdown", "id": "4e16a864", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -5731,7 +5088,6 @@ "cell_type": "markdown", "id": "17798548", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -5747,7 +5103,6 @@ "execution_count": null, "id": "cf38baf4-5486-4c17-bc93-42510f8a6db7", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -5765,7 +5120,6 @@ "execution_count": null, "id": "47affbe3-0eb6-4ed6-8717-3ef05b072a80", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5783,7 +5137,6 @@ "execution_count": null, "id": "98714766-5033-43d8-a9a3-0589b7bf32ec", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5801,7 +5154,6 @@ "execution_count": null, "id": "3fe290ad-e12f-4021-b8ef-a6d9bd6a7467", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5822,7 +5174,6 @@ "execution_count": null, "id": "cdcbc0b1-197d-4fc5-95e9-9501868b7525", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5840,7 +5191,6 @@ "execution_count": null, "id": "b33c4e26-ec82-405d-97a5-bd88488c06d8", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5859,7 +5209,6 @@ "execution_count": null, "id": "89847e34-7e99-4b89-904f-b7ec2c8dd774", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5877,7 +5226,6 @@ "cell_type": "markdown", "id": "4e9801e0", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -5892,7 +5240,6 @@ "cell_type": "markdown", "id": "a306f3cb", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -5904,24 +5251,15 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "b10a1b92", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Created example.csv with x and cos(x) values\n" - ] - } - ], + "outputs": [], "source": [ "import csv, math\n", "\n", @@ -5944,7 +5282,6 @@ "cell_type": "markdown", "id": "3a9c7b35", "metadata": { - "editable": true, "jp-MarkdownHeadingCollapsed": true, "slideshow": { "slide_type": "slide" @@ -5958,29 +5295,15 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "7d2b75d2-f0a2-490e-be7d-28dad71ef05c", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "First few lines of the file:\n", - "x_axis,y_axis\n", - "0.0,1.0\n", - "0.1,0.9950041652780258\n", - "0.2,0.9800665778412416\n", - "0.30000000000000004,0.955336489125606\n" - ] - } - ], + "outputs": [], "source": [ "# Show the first few lines to demonstrate what we created\n", "print(\"First few lines of the file:\")\n", @@ -5991,25 +5314,15 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "9af8c87f-62db-4a04-86d8-d51428395210", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The value of Y for X==1.0 saved in the file:\n", - "0.5403023058681398\n" - ] - } - ], + "outputs": [], "source": [ "# Show the value of Y for X==1.0 saved in the file\n", "print(\"The value of Y for X==1.0 saved in the file:\")\n", @@ -6026,7 +5339,6 @@ "cell_type": "markdown", "id": "6ee8121a", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -6040,7 +5352,6 @@ "cell_type": "markdown", "id": "a00f019b", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -6064,7 +5375,6 @@ "cell_type": "markdown", "id": "dd9284d3-b9cc-43b1-a369-731c3e09351e", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -6109,7 +5419,6 @@ "cell_type": "markdown", "id": "a547c272-803a-46e8-af1f-00600ad11e92", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -6124,7 +5433,6 @@ "execution_count": null, "id": "2d3584bd-f99b-4fc8-9b19-db321634f329", "metadata": { - "editable": true, "slideshow": { "slide_type": "" }, @@ -6143,7 +5451,6 @@ "cell_type": "markdown", "id": "47dd6a0c", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -6162,7 +5469,6 @@ "cell_type": "markdown", "id": "7f4123ae", "metadata": { - "editable": true, "slideshow": { "slide_type": "fragment" }, @@ -6186,7 +5492,6 @@ "cell_type": "markdown", "id": "bbe2196d", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, @@ -6212,7 +5517,6 @@ "execution_count": null, "id": "be842bd3", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -6247,7 +5551,6 @@ "execution_count": null, "id": "506cd6b2", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -6267,7 +5570,6 @@ "execution_count": null, "id": "454b088a", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -6287,7 +5589,6 @@ "execution_count": null, "id": "faee9ea4", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -6326,7 +5627,6 @@ "execution_count": null, "id": "c8b612fa", "metadata": { - "editable": true, "lines_to_next_cell": 0, "remove_code": "non-comments", "slideshow": { @@ -6344,40 +5644,599 @@ }, { "cell_type": "markdown", - "id": "6522c182", + "id": "9e01e73d", "metadata": { - "editable": true, "slideshow": { - "slide_type": "fragment" - } + "slide_type": "slide" + }, + "tags": [] }, "source": [ - "---" + "# 9. (Optional) Brief introduction to Object-Oriented Programming" ] }, { "cell_type": "markdown", - "id": "ef9b73ae", + "id": "3627c2ef", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "* Python is an object oriented programming language. Object-Oriented Programming (OOP) is a programming paradigm based on the concept of \"objects\" which can contain:\n", + " - Data (attributes)\n", + " - Code (methods)" + ] + }, + { + "cell_type": "markdown", + "id": "8393fae9", "metadata": { - "editable": true, "slideshow": { "slide_type": "slide" }, "tags": [] }, "source": [ - "# Thank You for Attending! 👋\n", "\n", - "- Feedback would really be appreciated (see the link in the email I've sent)\n", - "- Check out our other training courses at ARC:\n", - " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/training-/\n", - "- RSE support by ARC at Durham University:\n", - " - https://www.durham.ac.uk/research/institutes-and-centres/advanced-research-computing/research-software-engineering/\n", + "## 1. Classes and Objects\n", + " - Class: A blueprint for creating objects (Think a cookiecutter)\n", + " - Object: An instance of a class (The created cookies)\n", "\n", - "#### Contact\n", - "- Email: arc-rse@durham.ac.uk\n", "\n", - "Happy Coding! 🐍" + "A simple example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5005c5bc", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Simple example\n", + "class CourseParticipant:\n", + " def __init__(self, name, email):\n", + " self.name = name\n", + " self.email = email\n", + "\n", + " def welcome(self):\n", + " print(f\"Welcome {self.name}! We're glad to have you.\")\n", + "\n", + "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", + "participant1.welcome()" + ] + }, + { + "cell_type": "markdown", + "id": "d9003b8b", + "metadata": { + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "Speaker notes:\n", + "\n", + "The parts are:\n", + "- `class ClassName`: Classes are created with the `class` keyword and named in CamelCase\n", + "- `def __init__...`: The constructor method. This is used to create a new instance (cookie), with a given set of input variables. The first one is the reference to a given object created from the class (`self`), which is used to store the data/state.\n", + "- `def method_name(self)`: A method name. We again use `self` as the reference to an object created from the class" + ] + }, + { + "cell_type": "markdown", + "id": "b2a91e2a", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## 2. Encapsulation\n", + " - Bundling data and methods that work on that data within one unit\n", + " - Restricting access to certain details\n", + " - Is also often used to keep track of states." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74cd0847", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class CourseParticipant:\n", + " def __init__(self, name, email):\n", + " self.name = name\n", + " self.email = email\n", + " self.registered_attendance = False\n", + "\n", + " def welcome(self):\n", + " print(f\"Welcome {self.name}! We're glad to have you.\")\n", + "\n", + " def register_attendance(self):\n", + " self.registered_attendance = True\n", + " print(f\"{self.name} has been registered for attendance.\")\n", + "\n", + "# use the class\n", + "participant1 = CourseParticipant(\"Alice\", \"alice@example.com\")\n", + "participant1.welcome()\n", + "participant1.register_attendance()\n" + ] + }, + { + "cell_type": "markdown", + "id": "915e7f40", + "metadata": { + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "Speaker notes:\n", + " - Imagine we need a function to track whether users have attended the course.\n", + " - We can change the internal state of the object representing a given participant.\n", + " - By checking the registered_attendance attribute, we can track which participants have registered" + ] + }, + { + "cell_type": "markdown", + "id": "df442469", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## 3. Inheritance\n", + " - Creating new classes that extend the functionality of existing classes\n", + " - We _inherit_ the properties of the base class `CourseParticipant`\n", + " - `super()` lets us invoke the function of the same name from the base class\n", + " - Carefully decide between inheritance and composition (see soon)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e94ff6d", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class ExternalParticipant(CourseParticipant):\n", + " def __init__(self, name, email, company):\n", + " super().__init__(name, email)\n", + " self.company = company\n", + "\n", + " def contact_company(self):\n", + " print(f\"Contacting {self.company} regarding course participation.\")\n", + "\n", + "external_participant1 = ExternalParticipant(\"Bob\", \"bob@example.com\", \"Cooperative Inc.\")\n", + "external_participant1.welcome()\n", + "external_participant1.contact_company()\n" + ] + }, + { + "cell_type": "markdown", + "id": "206d9ee0", + "metadata": { + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "Speaker notes:\n", + "\n", + "Now imagine we can have external participants that are affiliated with a company. We want our object to have all the functionality of our `CourseParticipant` class, but also have additional functionality that is specific to our external participants." + ] + }, + { + "cell_type": "markdown", + "id": "2cf3958b", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## 4. Polymorphism\n", + "- Definition: Call the same method name on different object types and get type-specific behavior.\n", + "- Key idea: Write code to an interface, not a concrete class.\n", + "- Why it matters:\n", + " - Decouples caller from concrete types (extensible)\n", + " - Removes conditionals/type-checks (cleaner)\n", + " - Eases testing and substitution (mocks/fakes)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a414bc89", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class DurhamUniversityParticipant(CourseParticipant):\n", + " def register_attendance(self):\n", + " super().register_attendance()\n", + " print(f\" Also registered attendance with the internal additional system for {self.name}\")\n", + " \n", + "\n", + "participants = [\n", + " ExternalParticipant(\"Alice\", \"alice@example.com\", \"Acme Corp\"),\n", + " DurhamUniversityParticipant(\"Bob\", \"bob@durham.ac.uk\"),\n", + " CourseParticipant(\"Charlie\", \"charlie@example.com\")\n", + "]\n", + "\n", + "for participant in participants:\n", + " participant.register_attendance()" + ] + }, + { + "cell_type": "markdown", + "id": "5385bec2", + "metadata": { + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "Speaker notes:\n", + "\n", + "Say for registering the attendance for our internal participants we are also required to call an API function (represented by the print statement here). We can overwrite the function to behave differently for the `DurhamUniveristyParticipant` class\n", + "\n", + " - We are using `super()` again. Note that this is not necessary\n", + " - We can still just use `register_attendance()` even though one of the functions now behaves differently.\n", + " - If there are lots of `if/else` statements depending on which type an programmed structure represents, objects with different types can simplify the structure significantly.\n", + " - It is quite easy to introduce an additional class that has another option for the behaviour." + ] + }, + { + "cell_type": "markdown", + "id": "fdb800a8", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## 5. Composition\n", + "\n", + "- Definition: Build classes by combining other objects (a class has collaborators).\n", + "- Why choose it:\n", + " - Favors flexibility and reuse over tight inheritance ties\n", + " - Swap components easily\n", + "\n", + "- If your `__init__` functions have alternative optional parameters, this is often a sign you should use composition\n", + "- Especially favour composition if there are several options for different behaviours that can be combined interchangeably (_has-a_ vs interitance: _is-a_)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2cea837b", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class Messenger:\n", + " def send_message(self, message):\n", + " pass\n", + "\n", + "class EmailMessenger(Messenger):\n", + "\n", + " def __init__(self, email):\n", + " self.email = email\n", + "\n", + " def send_message(self, message):\n", + " print(f\"Sending email to {self.email}: {message}\")\n", + "\n", + "class TeamsMessenger(Messenger):\n", + "\n", + " def __init__(self, user_id):\n", + " self.user_id = user_id\n", + "\n", + " def send_message(self, message):\n", + " print(f\"Sending Teams message to {self.user_id}: {message}\")\n", + "\n", + "\n", + "class Participant:\n", + " def __init__(self, name, messenger):\n", + " self.name = name\n", + " self.messenger = messenger\n", + "\n", + " def welcome(self):\n", + " self.messenger.send_message(f\"Welcome {self.name}!\")\n", + "\n", + "# Use the Participant class\n", + "participants = [\n", + " Participant(\"Alice\", EmailMessenger(\"alice@example.com\")),\n", + " Participant(\"Bob\", TeamsMessenger(\"bob123\"))\n", + "]\n", + "\n", + "for participant in participants:\n", + " participant.welcome()\n" + ] + }, + { + "cell_type": "markdown", + "id": "7ea0b8f0", + "metadata": { + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "Speaker notes:\n", + " - In this example, participants can be contacted via e-mail or Teams\n", + " - The information we need for the two contact possibilities is completely independent\n", + " - The specific behaviour is used by the class, but the details are not important for the class\n", + " - So each object `has-a` messenger that can be used to contact the participant\n", + " - It is straightforward to inherit the different participant classes (External / DU) using this messenger, without creating four (Messing (2) x DU/External (2)) classes that would be needed with inheritance also\n" + ] + }, + { + "cell_type": "markdown", + "id": "129df112", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "d9c8cd20", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## Have a play!" + ] + }, + { + "cell_type": "markdown", + "id": "4858e58f", + "metadata": { + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "Speaker notes:\n", + "\n", + "While the explanations went quite a bit further, this example only needs the application of encapsulation. Packaging up basic Application Programming Interfaces (APIs) into a more useable form is a useful and common application of OOP. In the interest of time / scope we will keep the exercise a bit more simple, but feel free to also inquire about the other concepts while you work on it." + ] + }, + { + "cell_type": "markdown", + "id": "28e31e47", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Plant Sensor API Exercise\n", + "You've been given a virtual sensor API module which you can import with (`import sensor_api`) that can monitor plants. \n", + "The API provides three functions:\n", + "\n", + "- `connect(sensor_id)`: Connects to a sensor (returns True/False)\n", + "- `disconnect(sensor_id)`: Disconnects from a sensor (returns True/False) \n", + "- `send_message(message)`: Sends a command and receives a reading (returns float or None)\n", + "\n", + "#### Message Format\n", + "Messages must be formatted as: `\"SENSOR_ID:COMMAND\"`\n", + "\n", + "Available commands:\n", + "- `SOIL_HUMIDITY`: Get soil humidity (0-100%)\n", + "- `AIR_HUMIDITY`: Get air humidity (0-100%)\n", + "- `TEMPERATURE`: Get temperature in Celsius\n", + "\n", + "#### Before\n", + "This is how working with the API would currently look:\n", + "\n", + "```python\n", + "import sensor_api\n", + "\n", + "sensor_id = \"GREENHOUSE_01\"\n", + "sensor_api.connect(sensor_id)\n", + "\n", + "soil_humidity = float(sensor_api.send_message(f\"{id}:SOIL_HUMIDITY\"))\n", + "air_humidity = float(sensor_api.send_message(f\"{id}:AIR_HUMIDITY\"))\n", + "temperature = float(sensor_api.send_message(f\"{id}:TEMPERATURE\"))\n", + "\n", + "print(f\"\\n=== Plant Sensor {sensor_id} Readings ===\")\n", + "print(f\"Soil Humidity: {soil_humidity}%\")\n", + "print(f\"Air Humidity: {air_humidity}%\")\n", + "print(f\"Temperature: {temperature}°C\")\n", + "print(\"=\" * 35)\n", + "sensor_api.disconnect(id)\n", + "```\n", + "\n", + "#### Your Task\n", + "Create a `PlantSensor` class that:\n", + "\n", + "1. Stores the sensor ID when created\n", + "2. Automatically connects when initialized\n", + "3. Provides easy-to-use methods for each measurement type\n", + "4. Properly disconnects when done\n", + "5. Displays all readings in a nice format\n", + "\n", + "\n", + "\n", + "#### Desired result\n", + "```python\n", + "# This is how your class should work:\n", + "sensor = PlantSensor(\"PLANT_01\")\n", + "soil = sensor.get_soil_humidity()\n", + "air = sensor.get_air_humidity()\n", + "temp = sensor.get_temperature()\n", + "sensor.display_readings()\n", + "sensor.disconnect()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "9cb57fee", + "metadata": { + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Implementation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb0d76f6", + "metadata": { + "remove_code": "all", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import sensor_api\n", + "\n", + "class PlantSensor:\n", + " def __init__(self, sensor_id):\n", + " \"\"\"Initialize the sensor with an ID and connect to it.\"\"\"\n", + " self.sensor_id = sensor_id\n", + " self.connected = sensor_api.connect(sensor_id)\n", + " \n", + " # Store readings\n", + " self.soil_humidity = None\n", + " self.air_humidity = None\n", + " self.temperature = None\n", + " \n", + " def get_soil_humidity(self):\n", + " \"\"\"Get soil humidity reading.\"\"\"\n", + " if self.connected:\n", + " message = f\"{self.sensor_id}:SOIL_HUMIDITY\"\n", + " self.soil_humidity = float(sensor_api.send_message(message))\n", + " return self.soil_humidity\n", + " return None\n", + " \n", + " def get_air_humidity(self):\n", + " \"\"\"Get air humidity reading.\"\"\"\n", + " if self.connected:\n", + " message = f\"{self.sensor_id}:AIR_HUMIDITY\"\n", + " self.air_humidity = float(sensor_api.send_message(message))\n", + " return self.air_humidity\n", + " return None\n", + " \n", + " def get_temperature(self):\n", + " \"\"\"Get temperature reading.\"\"\"\n", + " if self.connected:\n", + " message = f\"{self.sensor_id}:TEMPERATURE\"\n", + " self.temperature = float(sensor_api.send_message(message))\n", + " return self.temperature\n", + " return None\n", + " \n", + " def display_readings(self):\n", + " \"\"\"Display all sensor readings.\"\"\"\n", + " print(f\"\\n=== Plant Sensor {self.sensor_id} Readings ===\")\n", + " print(f\"Soil Humidity: {self.soil_humidity}%\")\n", + " print(f\"Air Humidity: {self.air_humidity}%\")\n", + " print(f\"Temperature: {self.temperature}°C\")\n", + " print(\"=\" * 35)\n", + " \n", + " def disconnect(self):\n", + " \"\"\"Disconnect from the sensor.\"\"\"\n", + " if self.connected:\n", + " sensor_api.disconnect(self.sensor_id)\n", + " self.connected = False" + ] + }, + { + "cell_type": "markdown", + "id": "1624a7a4", + "metadata": {}, + "source": [ + "You can use this to try to use your class. You can comment out functionality, if you have not implemented it yet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49d66487", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "my_plant = PlantSensor(\"GREENHOUSE_01\")\n", + "\n", + "# Take readings\n", + "my_plant.get_soil_humidity()\n", + "my_plant.get_air_humidity()\n", + "my_plant.get_temperature()\n", + "\n", + "# Display results\n", + "my_plant.display_readings()\n", + "\n", + "# Clean up\n", + "my_plant.disconnect()" + ] + }, + { + "cell_type": "markdown", + "id": "6522c182", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "---" ] } ], @@ -6397,7 +6256,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.2" + "version": "3.13.0" } }, "nbformat": 4,