-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d61dd56
commit 3f6ca05
Showing
2 changed files
with
350 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
layout: post | ||
title: "Functions, docstrings and a mistake by me at the end" | ||
tags: | ||
- functions-and-data-structures | ||
--- | ||
|
||
In class today we spoke about group coursework a bit but mainly spent time | ||
looking at docstrings. | ||
|
||
You can see a recording of this here: [https://cardiff.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=7c020a93-9855-44f2-9f30-b1050118b4a9](https://cardiff.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=53ced2ac-b8f5-4b07-9b3a-b10201087ba1) | ||
|
||
We spoke about the numpy docstring format, which is specified here: [https://vknight.org/pfm/building-tools/02-functions-and-data-structures/how/main.html#how-to-write-a-docstring](https://vknight.org/pfm/building-tools/02-functions-and-data-structures/how/main.html#how-to-write-a-docstring) | ||
|
||
I used the example of verifying the following identity to demonstrate this: | ||
|
||
$$(a + b) ^ n = \sum_{i=0}^n\binom{n}{i} a ^ i b ^ {n - i}$$ | ||
|
||
You can find a notebook with all this [here]({{site.baseurl}}/assets/nbs/2023-2024/functions-and-data-structures.ipynb) | ||
|
||
**I'm really sorry about how confusing the ending of class today must have been | ||
I made a mistake (my fault entirely)**. | ||
|
||
The notebook linked to above does not contain the error. | ||
|
||
When it came to fixing the floating point error I wrote: | ||
|
||
```python | ||
sum(int(scipy.special.binom(n, i) * a ** i * b ** (n - i)) for i in range(n + 1)) | ||
``` | ||
|
||
But the mistake I made here (and again I apologise for the crash and burn at the | ||
end of the class) is that the closing bracket of `int` should have been after | ||
the `binom` and not after the entire calculation. | ||
|
||
```python | ||
sum(int(scipy.special.binom(n, i)) * a ** i * b ** (n - i) for i in range(n + 1)) | ||
``` | ||
|
||
The difference is subtle but it is important as `scipy.special.binom(n, i)` | ||
will always be a float with 0 fractional part. So taking the `int` of it will | ||
give what we need. | ||
|
||
I'll happily go over this again on Tuesday if I can clarify things. The | ||
important thing to take from today is the approach and the docstrings. |
305 changes: 305 additions & 0 deletions
305
assets/nbs/2023-2024/functions-and-data-structures.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,305 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "e2a3479d-96ef-46fe-80f0-46a0e0c97e8d", | ||
"metadata": {}, | ||
"source": [ | ||
"Verify the following identity for all integer values of $0 \\leq a \\leq\n", | ||
"100$, $0 \\leq b \\leq 100$ and $1 \\leq n \\leq 10$:\n", | ||
"\n", | ||
"$$(a + b) ^ n = \\sum_{i=0}^n\\binom{n}{i} a ^ i b ^ {n - i}$$" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"id": "bf66ec35-d431-418d-82c9-7ff01a5f3b03", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"102010" | ||
] | ||
}, | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"101 * 101 * 10" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"id": "065b9e1f-d124-481c-a790-03e90fb2a409", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def get_lhs(a, b, n):\n", | ||
" \"\"\"\n", | ||
" This calculates the left hand side of the identity.\n", | ||
" It does it directly, using python exponentiation.\n", | ||
"\n", | ||
" Parameters\n", | ||
" ----------\n", | ||
" a : int\n", | ||
" This is the value of a in the equation.\n", | ||
" b : int\n", | ||
" This is the value of b in the equation.\n", | ||
" n : int\n", | ||
" This is the value of n in the equation. It is the value of the exponent.\n", | ||
"\n", | ||
"\n", | ||
" Returns\n", | ||
" -------\n", | ||
" int\n", | ||
" The value of the left hand side.\n", | ||
" \"\"\"\n", | ||
" return int((a + b ) ** n)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"id": "63635921-e137-40a5-b776-fe32d02d4e39", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"1" | ||
] | ||
}, | ||
"execution_count": 3, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"get_lhs(a=1, b=0, n=5)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"id": "7054d82e-98d3-4810-8d9a-953b3911f5f3", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"int" | ||
] | ||
}, | ||
"execution_count": 4, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"type(get_lhs(a=1, b=1, n=5))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"id": "6a12fc60-ce48-4786-9de3-4d2f4943df38", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import scipy.special\n", | ||
"\n", | ||
"def get_rhs(a, b, n):\n", | ||
" \"\"\"\n", | ||
" Obtain the right hand side of the equation.\n", | ||
"\n", | ||
" This uses scipy's special import for the binomial coefficient.\n", | ||
"\n", | ||
" Note that this also makes use of the fact that the rhs is an integer.\n", | ||
" Thus we take `int` of the output of scipy's binom. This is important as otherwise\n", | ||
" some numerical errors are not captured for the values for example of a=0, b=85 and n=10.\n", | ||
" \n", | ||
" Parameters\n", | ||
" ----------\n", | ||
" a : int\n", | ||
" This is the value of a in the equation.\n", | ||
" b : int\n", | ||
" This is the value of b in the equation.\n", | ||
" n : int\n", | ||
" This is the value of n in the equation. It is the value of the exponent.\n", | ||
"\n", | ||
"\n", | ||
" Returns\n", | ||
" -------\n", | ||
" int\n", | ||
" The value of the left hand side.\n", | ||
" \"\"\"\n", | ||
" return sum(int(scipy.special.binom(n, i)) * a ** i * b ** (n - i) for i in range(n + 1))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"id": "81202b71-0fd2-4e58-858e-043aae4b63cf", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def check_identity(a, b, n):\n", | ||
" \"\"\"\n", | ||
" This calculates the lhs and the rhs of the equation.\n", | ||
"\n", | ||
" It then compares them to check if the equality holds.\n", | ||
"\n", | ||
" Note this uses `get_lhs` and `get_rhs`.\n", | ||
"\n", | ||
" Parameters\n", | ||
" ----------\n", | ||
" a : int\n", | ||
" This is the value of a in the equation.\n", | ||
" b : int\n", | ||
" This is the value of b in the equation.\n", | ||
" n : int\n", | ||
" This is the value of n in the equation. It is the value of the exponent.\n", | ||
"\n", | ||
" Returns\n", | ||
" -------\n", | ||
" bool\n", | ||
" Whether or not the lhs is equal to the rhs\n", | ||
" \"\"\"\n", | ||
" return get_lhs(a=a, b=b, n=n) == get_rhs(a=a, b=b, n=n)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 8, | ||
"id": "d2ec3399-20c8-4ff8-bb9b-2f48bcbbf091", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"checks = [\n", | ||
" check_identity(a=a_value, b=b_value, n=n_value)\n", | ||
" for a_value in range(101)\n", | ||
" for b_value in range(101)\n", | ||
" for n_value in range(1, 11)\n", | ||
"]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 9, | ||
"id": "a74c3063-ed2a-4113-b146-3db282b267fc", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"True" | ||
] | ||
}, | ||
"execution_count": 9, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"all(checks)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 13, | ||
"id": "353ade53-0572-47ed-b0ae-f282c49335a4", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"True" | ||
] | ||
}, | ||
"execution_count": 13, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"all(checks)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 16, | ||
"id": "a76536bf-b7d7-4a24-9a3b-e1c8edb60855", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"19687440434072265625" | ||
] | ||
}, | ||
"execution_count": 16, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"get_lhs(a=0, b=85, n=10)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 17, | ||
"id": "b7e524ae-f284-49dc-9640-41fc83b08bc6", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"19687440434072265625" | ||
] | ||
}, | ||
"execution_count": 17, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"get_rhs(a=0, b=85, n=10)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "da5ce263-565f-4aa8-8fcf-15e641d3fe04", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.4" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |