two helper notebooks
This commit is contained in:
parent
f1d43d8e19
commit
902fbc70da
283
more-decorators.ipynb
Normal file
283
more-decorators.ipynb
Normal file
@ -0,0 +1,283 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "02e68cf1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# More Decorator Examples\n",
|
||||
"\n",
|
||||
"Some additional examples beyond what is in 08.decorators."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b985a33b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Modifying Arguments within newfunc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "31c291f2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def reverse_args(func):\n",
|
||||
" def newfunc(*args):\n",
|
||||
" # within newfunc we are able to write whatever we'd like\n",
|
||||
" # we could decide that we want to reverse the arguments\n",
|
||||
" reversed_args = reversed(args)\n",
|
||||
" return func(*reversed_args)\n",
|
||||
" return newfunc\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"@reverse_args\n",
|
||||
"def print_args(*args):\n",
|
||||
" for arg in args:\n",
|
||||
" print(arg)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "413cfac8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"3\n",
|
||||
"2\n",
|
||||
"1\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print_args(1, 2, 3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "95e01cf9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"0.2"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"@reverse_args\n",
|
||||
"def divide(a, b):\n",
|
||||
" return a / b\n",
|
||||
"\n",
|
||||
"divide(10, 2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d055880d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Example: Authorization"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "1590c5de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# perhaps we want a function that checks if a user can perform an action\n",
|
||||
"def auth_required(func):\n",
|
||||
" \n",
|
||||
" # list of allowed users. in practice, we'd look this up in a database\n",
|
||||
" allowed_users = (\"lauren\", \"mitch\")\n",
|
||||
" \n",
|
||||
" def newfunc(*args, **kwargs):\n",
|
||||
" # here, we're actually using an argument within newfunc\n",
|
||||
" # by checking if it is in the kwargs dictionary\n",
|
||||
" if kwargs.get(\"auth_user\") in allowed_users:\n",
|
||||
" func(*args, **kwargs)\n",
|
||||
" else:\n",
|
||||
" print(\"ACCESS DENIED\")\n",
|
||||
" return newfunc\n",
|
||||
"\n",
|
||||
"# these functions must also accept auth_user so that the above call to func(*args, **kwargs)\n",
|
||||
"# doesn't send an invalid parameter through\n",
|
||||
"@auth_required\n",
|
||||
"def withdraw_funds(account, amount, auth_user):\n",
|
||||
" print(f\"withdrew {amount} funds from account={account}\")\n",
|
||||
"\n",
|
||||
"@auth_required\n",
|
||||
"def delete_account(account, auth_user):\n",
|
||||
" print(\"deleted\", account)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "f9e8bcd0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"withdrew 100 funds from account=jim\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"withdraw_funds(\"jim\", 100, auth_user=\"lauren\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "77a82ae4",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"ACCESS DENIED\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"delete_account(\"kevin\", auth_user=\"jim\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cf9a611a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Modifying Keyword Parameters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "90161162",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# if we didn't want auth_user to be passed through, we'd make a small modification to newfunc\n",
|
||||
"\n",
|
||||
"def auth_required(func): \n",
|
||||
" allowed_users = (\"lauren\", \"mitch\")\n",
|
||||
" \n",
|
||||
" def newfunc(*args, auth_user, **kwargs):\n",
|
||||
" # newfunc now requires auth_user, and passes through all *other* parameters\n",
|
||||
" if auth_user in allowed_users:\n",
|
||||
" func(*args, **kwargs)\n",
|
||||
" else:\n",
|
||||
" print(\"ACCESS DENIED\")\n",
|
||||
" return newfunc\n",
|
||||
"\n",
|
||||
"# auth_user is no longer seen in the definition of these functions \n",
|
||||
"# but it can be passed in since the newfunc returned from auth_required accepts it\n",
|
||||
"@auth_required\n",
|
||||
"def withdraw_funds(account, amount):\n",
|
||||
" print(f\"withdrew {amount} funds from account={account}\")\n",
|
||||
"\n",
|
||||
"@auth_required\n",
|
||||
"def delete_account(account):\n",
|
||||
" print(\"deleted\", account)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "ee4cabe7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"withdrew 100 funds from account=jim\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"withdraw_funds(\"jim\", 100, auth_user=\"lauren\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "a22a86d9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"ACCESS DENIED\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"delete_account(\"kevin\", auth_user=\"jim\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dca4b1ec",
|
||||
"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.10.15"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": false
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
240
thinking-in-list-comprehensions.ipynb
Normal file
240
thinking-in-list-comprehensions.ipynb
Normal file
@ -0,0 +1,240 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "54ee872b-aa95-4e8a-b22f-7a42c7d3c0cf",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Thinking in list comprehensions\n",
|
||||
"\n",
|
||||
"Here is a way of thinking about list comprehensions that may help you write more complex comprehensions in a natural way:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "80df68a2-5a72-4b44-9c72-8dffffc57dfe",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def make_powers_lc(n, inputs):\n",
|
||||
" \"\"\"\n",
|
||||
" Given list of inputs, return each input raised to the 1st-Nth power\n",
|
||||
" \n",
|
||||
" e.g.\n",
|
||||
" >>> make_powers_lc(4, range(10))\n",
|
||||
" [[0, 0, 0, 0],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [2, 4, 8, 16],\n",
|
||||
" [3, 9, 27, 81],\n",
|
||||
" [4, 16, 64, 256],\n",
|
||||
" [5, 25, 125, 625],\n",
|
||||
" [6, 36, 216, 1296],\n",
|
||||
" [7, 49, 343, 2401],\n",
|
||||
" [8, 64, 512, 4096],\n",
|
||||
" [9, 81, 729, 6561]]\n",
|
||||
" \"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8eb3928f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "1caa3d73",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[[1]]"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 1) start with shape: \n",
|
||||
"# Output will be a list of list of ints, \n",
|
||||
"# so create simplest version of that\n",
|
||||
"def make_powers_lc(n, inputs):\n",
|
||||
" return [[1]]\n",
|
||||
"make_powers_lc(4, range(10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "cc3309a8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 2) expand outer list comprehension to have correct number of elements\n",
|
||||
"# using inputs as foundation, we haven't modified the first term yet\n",
|
||||
"def make_powers_lc(n, inputs):\n",
|
||||
" return [[1] for x in inputs]\n",
|
||||
"make_powers_lc(4, range(10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "8a531ebc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[[1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 1, 1, 1]]"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 3) Now expand inner list to have correct number of elements.\n",
|
||||
"def make_powers_lc(n, inputs):\n",
|
||||
" return [[1 for y in range(n)] for x in inputs]\n",
|
||||
"make_powers_lc(4, range(10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "80135012",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[[1, 0, 0, 0],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [1, 2, 4, 8],\n",
|
||||
" [1, 3, 9, 27],\n",
|
||||
" [1, 4, 16, 64],\n",
|
||||
" [1, 5, 25, 125],\n",
|
||||
" [1, 6, 36, 216],\n",
|
||||
" [1, 7, 49, 343],\n",
|
||||
" [1, 8, 64, 512],\n",
|
||||
" [1, 9, 81, 729]]"
|
||||
]
|
||||
},
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 4) Fix initial term to do calculation\n",
|
||||
"def make_powers_lc(n, inputs):\n",
|
||||
" return [[x**y for y in range(n)] for x in inputs]\n",
|
||||
"make_powers_lc(4, range(10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "513b22ba",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[[0, 0, 0, 0],\n",
|
||||
" [1, 1, 1, 1],\n",
|
||||
" [2, 4, 8, 16],\n",
|
||||
" [3, 9, 27, 81],\n",
|
||||
" [4, 16, 64, 256],\n",
|
||||
" [5, 25, 125, 625],\n",
|
||||
" [6, 36, 216, 1296],\n",
|
||||
" [7, 49, 343, 2401],\n",
|
||||
" [8, 64, 512, 4096],\n",
|
||||
" [9, 81, 729, 6561]]"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 5) With correct shape, make modifications to ranges/etc. as needed\n",
|
||||
"def make_powers_lc(n, inputs):\n",
|
||||
" return [[x**y for y in range(1, n+1)] for x in inputs]\n",
|
||||
"make_powers_lc(4, range(10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15faca48",
|
||||
"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.10.15"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": false
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
Loading…
Reference in New Issue
Block a user