Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Expand Functions introductory notebook #211

Merged
merged 15 commits into from
Apr 17, 2024
Merged
241 changes: 190 additions & 51 deletions functions.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,45 @@
"id": "c9a51b45-de42-4887-9244-f6cc1d74aa0e",
"metadata": {},
"source": [
"## Table of contents\n",
"# Table of Contents\n",
"\n",
"- [References](#References)\n",
"- [Functions are building blocks](#Functions-are-building-blocks)\n",
"- [Best practices](#Best-practices)\n",
"- [Anatomy of a function](#Anatomy-of-a-function)\n",
" - [Signature](#Signature)\n",
" - [Type hints](#Type-hints)\n",
" - [Body](#Body)\n",
" - [Docstrings](#Docstrings)\n",
"- [Signature](#Signature)\n",
" - [Type hints](#Type-hints)\n",
"- [Body](#Body)\n",
"- [Docstrings](#Docstrings)\n",
"- [Parameters and arguments](#Parameters-and-arguments)\n",
" - [Parameters](#Parameters)\n",
" - [Arguments](#Arguments)\n",
" - [Positional arguments](#Positional-arguments)\n",
" - [Keyword arguments](#Keyword-arguments)\n",
" - [Default values](#Default-values)\n",
"- [Exercise 1](#Exercise-1)\n",
"- [Exercise 2](#Exercise-2)\n",
"- [How Python executes a function](#How-Python-executes-a-function)\n",
" - [Calling](#Calling)\n",
" - [Executing](#Executing)\n",
" - [Returning](#Returning)\n",
"- [The scope of a function](#The-scope-of-a-function)\n",
" - [Different types of scope](#Different-types-of-scope)\n",
"- [Global scope](#Global-scope)\n",
"- [`*args` and `**kwargs`](#*args-and-**kwargs)\n",
"- [Exercises](#Exercises)\n",
" - [Quiz on functions](#Quiz-on-functions)\n",
" - [Longest consecutive sequence 🌶️🌶️](#Longest-consecutive-sequence-🌶️🌶️)\n",
" - [Part 2 🌶️🌶️🌶️](#Part-2-🌶️🌶️🌶️)\n",
" - [Password validator](#Password-validator)\n",
" - [Part 1 🌶️](#Part-1-🌶️)\n",
" - [Part 2 🌶️🌶️](#Part-2-🌶️🌶️)\n",
" - [Buckets reorganization](#Buckets-reorganization)\n",
" - [Part 1 🌶️](#Part-1-🌶️)\n",
" - [Part 2 🌶️🌶️](#Part-2-🌶️🌶️)\n"
"- [Exercise 3](#Exercise-3)\n",
"- [Quiz on functions](#Quiz-on-functions)\n",
"- [Bonus exercises](#Bonus-exercises)\n",
" - [Longest consecutive sequence](#Longest-consecutive-sequence)\n",
" - [Example 1](#Example-1)\n",
" - [Example 2](#Example-2)\n",
" - [Part 2](#Part-2)\n",
" - [Password validator](#Password-validator)\n",
" - [Part 1](#Part-1)\n",
" - [Part 2](#Part-2)\n",
" - [Buckets reorganization](#Buckets-reorganization)\n",
" - [Part 1](#Part-1)\n",
" - [Part 2](#Part-2)"
]
},
{
Expand Down Expand Up @@ -170,7 +180,7 @@
"\n",
"Type hints improve code readability and can help catch potential type-related bugs early during development.\n",
"\n",
"<div class=\"alert alert-block alert-warning\">\n",
"<div class=\"alert alert-block alert-danger\">\n",
" <h4><b>Warning</b></h4> The Python interpreter <b>does not</b> enforce type hints and will not check them during runtime. Type hints are primarily intended for improving code readability, serving as documentation for developers, and making IDEs much more helpful when writing code.\n",
"</div>\n",
"\n",
Expand Down Expand Up @@ -402,6 +412,104 @@
"print(greet(\"John\"))"
]
},
{
"cell_type": "markdown",
"id": "28ee880e-0ecd-44b1-b9e2-07865a21a7da",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "336848ef-90e1-4149-9640-b22eea872f09",
"metadata": {},
"outputs": [],
"source": [
"%reload_ext tutorial.tests.testsuite"
]
},
{
"cell_type": "markdown",
"id": "468fad87-0005-4278-ba12-4caf0f43af86",
"metadata": {},
"source": [
"## Exercise 1"
]
},
{
"cell_type": "markdown",
"id": "2779a92e-6aa2-49a4-b950-164fba120edd",
"metadata": {},
"source": [
"Write a Python function called `greet` that takes two parameters: `name` (a string) and `age` (an integer).\n",
"The function should return a greeting message in the following format: `\"Hello, <name>! You are <age> years old.\"`\n",
"\n",
"**Do not** forget to write a proper docstring and add the correct type hints to the parameters and the return value."
edoardob90 marked this conversation as resolved.
Show resolved Hide resolved
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5212084f-9742-4f29-b3be-132e361eaee6",
"metadata": {},
"outputs": [],
"source": [
"%%ipytest\n",
"\n",
"def solution_greet():\n",
" return"
]
},
{
"cell_type": "markdown",
"id": "7f19f0ba-08de-4717-8f08-7255bed0bcfd",
"metadata": {},
"source": [
"## Exercise 2\n",
"\n",
"Write a Python function called `calculate_area` that takes three parameters: `length` (a float), `width` (a float), and `unit` (a string with a **default** value of `\"cm\"`).\n",
"The function should calculate the area of a rectangle based on the given length and width, and return the result **as a tuple** with the correct, default unit (i.e., `cm^2`).\n",
"If the unit parameter is \"m\", the function should convert the length and width from meters to centimeters before calculating the area.\n",
"\n",
"Your solution function **must** handle the following input units (the output unit is **always** `cm^2`):\n",
"\n",
"- centimeters (`cm`)\n",
"- meters (`m`)\n",
"- millimeters (`mm`)\n",
"- yards (`yd`)\n",
despadam marked this conversation as resolved.
Show resolved Hide resolved
"- feet (`ft`)\n",
"\n",
"If you pass an unsupported unit, the function should **return** a string with the error message: `Invalid unit: <unit>`, where `<unit>` is the unsupported unit.\n",
"\n",
"<div class=\"alert alert-block alert-warning\">\n",
" <h4><b>Note</b></h4>\n",
" <strong>Do not</strong> forget to write a proper docstring and add the correct type hints to the parameters and the return value.\n",
"</div>"
despadam marked this conversation as resolved.
Show resolved Hide resolved
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "464259d4-dda5-4451-9d1e-50b1c0161b76",
"metadata": {},
"outputs": [],
"source": [
"%%ipytest\n",
"\n",
"def solution_calculate_area():\n",
" pass"
]
},
{
"cell_type": "markdown",
"id": "8dfdeb76-3592-4b78-9cbc-d41125dc6f20",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"id": "dd593351-58d2-4cab-886e-d7f093445bee",
Expand Down Expand Up @@ -917,58 +1025,67 @@
"source": [
"You can see that with iterables unpacking and the two `*`/`**` operators, Python is showing all its versatility when it comes to writing your own function.\n",
"\n",
"If all this seems confusing, **try to experiment with these concepts** here in the notebook to better understand the behaviour. Create and call all the functions you want and check if their outputs is what you expect."
"If all this seems confusing, **try to experiment with these concepts** here in the notebook to better understand the behaviour. Create and call all the functions you want and check if their outputs is what you expect.\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "af454573-8da4-4b1c-9b93-24c2a6d511eb",
"metadata": {
"tags": []
},
"cell_type": "code",
"execution_count": null,
"id": "f3dee1be-c1bf-4ecb-8dc5-3b83c11f5f91",
"metadata": {},
"outputs": [],
"source": [
"# Exercises"
"%reload_ext tutorial.tests.testsuite"
]
},
{
"cell_type": "markdown",
"id": "f7b29753-e4d0-41c6-9a2c-1a815942f981",
"id": "bab6bfa7-58f4-4c38-8ee6-fbff5911e9bb",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-danger\">\n",
" <h4><b>Heads-up</b></h4>\n",
" Please, don't forget to evaluate the cell below ⬇️\n",
"</div>"
"## Exercise 3\n",
"\n",
"Write a Python function called `summing_anything` that is able to sum **any** kind of arguments.\n",
"It therefore must accept a *variable* number of arguments.\n",
"You must **not** use the built-in function `sum()` to solve this exercise: you should write your own (generalized) implementation.\n",
"\n",
"A few examples of how the function should work:\n",
"\n",
"| Arguments | Expected result |\n",
"| --- | --- |\n",
"| `('abc', 'def')` | `'abcdef'` |\n",
"| `([1,2,3], [4,5,6])` | `[1,2,3,4,5,6]` |\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f3dee1be-c1bf-4ecb-8dc5-3b83c11f5f91",
"id": "73472136-0e08-45b6-a51f-755f49c2b46b",
"metadata": {},
"outputs": [],
"source": [
"%reload_ext tutorial.tests.testsuite\n",
"import pathlib"
"%%ipytest\n",
"\n",
"def solution_summing_anything():\n",
" pass"
]
},
{
"cell_type": "markdown",
"id": "9e2e78c7-6208-47cc-97dc-e1c196346b7c",
"id": "b8e67ba8-61c7-4fe6-8659-27ade39dbe9c",
"metadata": {},
"source": [
"## Quiz on functions"
"---"
]
},
{
"cell_type": "markdown",
"id": "f811e2d6-1466-4430-9ceb-339867456b7c",
"id": "9e2e78c7-6208-47cc-97dc-e1c196346b7c",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-danger\">\n",
" <h4><b>Heads-up</b></h4>\n",
" Please, don't forget to evaluate the cell below ⬇️\n",
"</div>"
"## Quiz on functions"
]
},
{
Expand All @@ -980,8 +1097,8 @@
},
"outputs": [],
"source": [
"from tutorial import functions as f\n",
"f.Functions()"
"from tutorial import functions as quiz\n",
"quiz.Functions()"
]
},
{
Expand All @@ -991,7 +1108,23 @@
"tags": []
},
"source": [
"## Longest consecutive sequence 🌶️🌶️"
"## Bonus exercises\n",
"\n",
"<div class=\"alert alert-block alert-danger\">\n",
" <h4><b>Note</b></h4>\n",
" The following are recap exercises of increasing difficulty.\n",
" Please, try to solve the previous ones before attempting with those in this section.\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "c30daf6d-1250-4928-8c60-a896506075b7",
"metadata": {
"jp-MarkdownHeadingCollapsed": true
},
"source": [
"### Longest consecutive sequence"
]
},
{
Expand Down Expand Up @@ -1031,9 +1164,11 @@
{
"cell_type": "markdown",
"id": "ba435a6b-caac-48e2-a0e2-80edabdf1215",
"metadata": {},
"metadata": {
"jp-MarkdownHeadingCollapsed": true
},
"source": [
"### Part 2 🌶️🌶️🌶️\n",
"#### Part 2\n",
"\n",
"Suppose that you are dealing with a *very* long list of integers (e.g., a few thousands or a million). Can you write an alternative solution that takes **less than 1 minute** to run?\n",
"\n",
Expand Down Expand Up @@ -1065,10 +1200,11 @@
"cell_type": "markdown",
"id": "1c93c572-7890-4bd7-a0f6-d4015679df39",
"metadata": {
"jp-MarkdownHeadingCollapsed": true,
"tags": []
},
"source": [
"## Password validator"
"### Password validator"
]
},
{
Expand All @@ -1078,7 +1214,7 @@
"tags": []
},
"source": [
"### Part 1 🌶️"
"#### Part 1"
]
},
{
Expand Down Expand Up @@ -1147,7 +1283,7 @@
"tags": []
},
"source": [
"### Part 2 🌶️🌶️"
"#### Part 2"
]
},
{
Expand Down Expand Up @@ -1191,18 +1327,19 @@
"cell_type": "markdown",
"id": "503a18e5-8ee4-4a02-89f9-09cbca3a8e50",
"metadata": {
"jp-MarkdownHeadingCollapsed": true,
"tags": []
},
"source": [
"## Buckets reorganization"
"### Buckets reorganization"
]
},
{
"cell_type": "markdown",
"id": "957eb5a0-5331-48e3-86b6-7b99299d710f",
"metadata": {},
"source": [
"### Part 1 🌶️"
"#### Part 1"
]
},
{
Expand Down Expand Up @@ -1276,9 +1413,11 @@
{
"cell_type": "markdown",
"id": "1085e791-f1df-4fce-89ae-9c169dbf8aa2",
"metadata": {},
"metadata": {
"jp-MarkdownHeadingCollapsed": true
},
"source": [
"### Part 2 🌶️🌶️"
"#### Part 2"
]
},
{
Expand Down Expand Up @@ -1338,7 +1477,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
"version": "3.10.14"
}
},
"nbformat": 4,
Expand Down
Loading