diff options
Diffstat (limited to 'notebooks/python/python_intro.ipynb')
| -rw-r--r-- | notebooks/python/python_intro.ipynb | 120 |
1 files changed, 81 insertions, 39 deletions
diff --git a/notebooks/python/python_intro.ipynb b/notebooks/python/python_intro.ipynb index f129ffe..f101400 100644 --- a/notebooks/python/python_intro.ipynb +++ b/notebooks/python/python_intro.ipynb | |||
| @@ -50,6 +50,19 @@ | |||
| 50 | }, | 50 | }, |
| 51 | { | 51 | { |
| 52 | "cell_type": "markdown", | 52 | "cell_type": "markdown", |
| 53 | "id": "779bac39-4646-4b80-9970-343a3daef1e7", | ||
| 54 | "metadata": {}, | ||
| 55 | "source": [ | ||
| 56 | "## Important PEPs\n", | ||
| 57 | "\n", | ||
| 58 | "- [PEP0](https://peps.python.org/) - Index of Python Enhancement Proposals\n", | ||
| 59 | "- [PEP8](https://peps.python.org/pep-0008/) - Style Guide for Python Code\n", | ||
| 60 | "- [PEP257](https://peps.python.org/pep-0257/) - Docstring Conventions\n", | ||
| 61 | "- [PEP484](https://peps.python.org/pep-0484/) - Type Hints" | ||
| 62 | ] | ||
| 63 | }, | ||
| 64 | { | ||
| 65 | "cell_type": "markdown", | ||
| 53 | "id": "6d1edcfc-b001-4393-9c24-72adc9b5fccf", | 66 | "id": "6d1edcfc-b001-4393-9c24-72adc9b5fccf", |
| 54 | "metadata": {}, | 67 | "metadata": {}, |
| 55 | "source": [ | 68 | "source": [ |
| @@ -72,7 +85,7 @@ | |||
| 72 | }, | 85 | }, |
| 73 | { | 86 | { |
| 74 | "cell_type": "markdown", | 87 | "cell_type": "markdown", |
| 75 | "id": "4f144f73-51c1-419d-b71e-ee513f68f41c", | 88 | "id": "81573ed5-b76e-4726-9f44-7dc017fd0896", |
| 76 | "metadata": {}, | 89 | "metadata": {}, |
| 77 | "source": [ | 90 | "source": [ |
| 78 | "## Built-in functions\n", | 91 | "## Built-in functions\n", |
| @@ -81,8 +94,6 @@ | |||
| 81 | "\n", | 94 | "\n", |
| 82 | "[https://docs.python.org/3/library/functions.html](https://docs.python.org/3/library/functions.html)\n", | 95 | "[https://docs.python.org/3/library/functions.html](https://docs.python.org/3/library/functions.html)\n", |
| 83 | "\n", | 96 | "\n", |
| 84 | "- `dir([obj])` - returns a list of valid attributes for that object\n", | ||
| 85 | "\n", | ||
| 86 | "- `id(obj)` - returns the \"identity\" of an object - an integer which is guaranteed to be unique\n", | 97 | "- `id(obj)` - returns the \"identity\" of an object - an integer which is guaranteed to be unique\n", |
| 87 | "\n", | 98 | "\n", |
| 88 | "- `print(...)` - prints objects to a text stream\n", | 99 | "- `print(...)` - prints objects to a text stream\n", |
| @@ -94,6 +105,12 @@ | |||
| 94 | }, | 105 | }, |
| 95 | { | 106 | { |
| 96 | "cell_type": "markdown", | 107 | "cell_type": "markdown", |
| 108 | "id": "bc180243-fe11-405c-beb9-83db4f793a05", | ||
| 109 | "metadata": {}, | ||
| 110 | "source": [] | ||
| 111 | }, | ||
| 112 | { | ||
| 113 | "cell_type": "markdown", | ||
| 97 | "id": "a0c57535-e285-47af-80f9-1d4a16de5f25", | 114 | "id": "a0c57535-e285-47af-80f9-1d4a16de5f25", |
| 98 | "metadata": {}, | 115 | "metadata": {}, |
| 99 | "source": [ | 116 | "source": [ |
| @@ -116,26 +133,28 @@ | |||
| 116 | "source": [ | 133 | "source": [ |
| 117 | "# Common built-in types:\n", | 134 | "# Common built-in types:\n", |
| 118 | "\n", | 135 | "\n", |
| 119 | "s = 'foo' # this is a string / str, same as str('foo'), may be encoded, immutable (s[0] = 'r' is NOT possible)\n", | 136 | "my_string = 'foo' # a string / str, same as str('foo'), may be encoded\n", |
| 137 | " # immutable (s[0] = 'r' is NOT possible)\n", | ||
| 120 | "\n", | 138 | "\n", |
| 121 | "b = b'foo' # bytes, same as bytes('foo', 'utf-8'), may be decoded, immutable\n", | 139 | "my_bytes = b'foo' # bytes, same as bytes('foo', 'utf-8'), may be decoded, immutable\n", |
| 122 | "\n", | 140 | "\n", |
| 123 | "i = 6 # int, same as int('6'), immutable\n", | 141 | "my_int = 6 # int, same as int('6'), immutable\n", |
| 124 | "\n", | 142 | "\n", |
| 125 | "f = 0.1 # float, same as float('0.1'), immutable, Note!!: Floats have a fixed size,\n", | 143 | "my_float = 0.1 # float, same as float('0.1'), immutable, Note!!: Floats have a fixed size,\n", |
| 126 | "# hence they don't necessarily behave they way we expect from math class.\n", | 144 | " # hence they don't necessarily behave they way we expect from math class.\n", |
| 145 | "# 24732847234232342892343428.3 == 24732847234232342892343428.1 # True\n", | ||
| 127 | "\n", | 146 | "\n", |
| 128 | "b = False # bool, same as bool(0), bool(''), bool(None)... immutable / constant\n", | 147 | "my_bool = False # bool, same as bool(0), bool(''), bool(None)... immutable / constant\n", |
| 129 | "\n", | 148 | "\n", |
| 130 | "n = None # NoneType, similar to 'null' in other languages, immutable / constant\n", | 149 | "my_none = None # NoneType, similar to 'null' in other languages, immutable / constant\n", |
| 131 | "\n", | 150 | "\n", |
| 132 | "l = [1, False, 'foo'] # list, same as list((1, False, 'foo'))\n", | 151 | "my_list = [1, False, 'foo'] # list, same as list((1, False, 'foo'))\n", |
| 133 | "\n", | 152 | "\n", |
| 134 | "t = (1, False, 'foo') # tuple, same as tuple([1, False, 'foo']), immutable\n", | 153 | "my_tuple = (1, False, 'foo') # tuple, same as tuple([1, False, 'foo']), immutable\n", |
| 135 | "\n", | 154 | "\n", |
| 136 | "d = {'foo': 1, 'bar': 8} # dict, same as dict(foo=1, bar=8), similar to hash in other languages\n", | 155 | "my_dict = {'foo': 1, 'bar': 8} # dict, same as dict(foo=1, bar=8), similar to hash in other languages\n", |
| 137 | "\n", | 156 | "\n", |
| 138 | "s = {'foo', 'bar', 1, 1, 4} # set, same as set(['foo', 'bar', 1, 1, 4]), removes duplicates" | 157 | "my_set = {'foo', 'bar', 1, 1, 4} # set, same as set(['foo', 'bar', 1, 1, 4]), removes duplicates" |
| 139 | ] | 158 | ] |
| 140 | }, | 159 | }, |
| 141 | { | 160 | { |
| @@ -203,7 +222,7 @@ | |||
| 203 | "s3[0] # Out: S\n", | 222 | "s3[0] # Out: S\n", |
| 204 | "s3[-1] # Out: t\n", | 223 | "s3[-1] # Out: t\n", |
| 205 | "s3[1:] # Out: tatnett\n", | 224 | "s3[1:] # Out: tatnett\n", |
| 206 | "s3[1:-1] # Out: tatnett\n", | 225 | "s3[1:-1] # Out: tatnet\n", |
| 207 | "s3[-3:] # Out: ett\n", | 226 | "s3[-3:] # Out: ett\n", |
| 208 | "s3[1:-1:2] # Out: tte\n", | 227 | "s3[1:-1:2] # Out: tte\n", |
| 209 | "\n", | 228 | "\n", |
| @@ -223,6 +242,29 @@ | |||
| 223 | }, | 242 | }, |
| 224 | { | 243 | { |
| 225 | "cell_type": "markdown", | 244 | "cell_type": "markdown", |
| 245 | "id": "25d0f9dc-d783-4a23-a3ee-c0b6cee3d4ab", | ||
| 246 | "metadata": {}, | ||
| 247 | "source": [ | ||
| 248 | "## Lists vs. tuples\n", | ||
| 249 | "\n", | ||
| 250 | "Tuples are not sumply \"read-only\" lists.\n", | ||
| 251 | "\n", | ||
| 252 | "\"Though tuples may seem similar to lists, they are often used in different situations and for different purposes.\n", | ||
| 253 | "Tuples are immutable, and usually contain a heterogeneous sequence of elements that are accessed via unpacking ... or indexing.\n", | ||
| 254 | "Lists are mutable, and their elements are usually homogeneous and are accessed by iterating over the list.\n", | ||
| 255 | "\n", | ||
| 256 | "```python\n", | ||
| 257 | "my_tuple = (1,2)\n", | ||
| 258 | "my_list = [1,2] \n", | ||
| 259 | "\n", | ||
| 260 | "# tuples are immutable and hashable, hence they can be used as keys in mapping objects as dicts\n", | ||
| 261 | "d = {my_tuple: 1} # OK\n", | ||
| 262 | "d = {my_list: 1} # Error\n", | ||
| 263 | "```" | ||
| 264 | ] | ||
| 265 | }, | ||
| 266 | { | ||
| 267 | "cell_type": "markdown", | ||
| 226 | "id": "6b2bc8fa-a5dc-4a58-92b2-abfb19bfe2ed", | 268 | "id": "6b2bc8fa-a5dc-4a58-92b2-abfb19bfe2ed", |
| 227 | "metadata": {}, | 269 | "metadata": {}, |
| 228 | "source": [ | 270 | "source": [ |
| @@ -302,7 +344,7 @@ | |||
| 302 | "id": "40db50e4-fb7a-4a77-a074-bc4413f27212", | 344 | "id": "40db50e4-fb7a-4a77-a074-bc4413f27212", |
| 303 | "metadata": {}, | 345 | "metadata": {}, |
| 304 | "source": [ | 346 | "source": [ |
| 305 | "## Creating and maintaining a Python environment (cont...)\n", | 347 | "## Creating and maintaining a Python environment - goals\n", |
| 306 | "\n", | 348 | "\n", |
| 307 | "Desired qualities for a flexible Python environment:\n", | 349 | "Desired qualities for a flexible Python environment:\n", |
| 308 | "\n", | 350 | "\n", |
| @@ -324,10 +366,11 @@ | |||
| 324 | "id": "c661bf56-add0-402c-a629-a857f81d0758", | 366 | "id": "c661bf56-add0-402c-a629-a857f81d0758", |
| 325 | "metadata": {}, | 367 | "metadata": {}, |
| 326 | "source": [ | 368 | "source": [ |
| 327 | "## Creating and maintaining a Python environment (cont...)\n", | 369 | "## Creating and maintaining a Python environment - using devbox / WSL / UNIX systems directly\n", |
| 328 | "\n", | 370 | "\n", |
| 329 | "Exploting the operating system can be done by:\n", | 371 | "Exploting the operating system can be done by:\n", |
| 330 | "\n", | 372 | "\n", |
| 373 | "- using the official Python packages that are maintained by the OS (Ubuntu packages in the case of WSL @ Statnett or a Red Hat enterprise VM @ Statnett) is often good enough\n", | ||
| 331 | "- (re)defining `PYTHONPATH`\n", | 374 | "- (re)defining `PYTHONPATH`\n", |
| 332 | "- using symlinks to point at packages placed at different locations" | 375 | "- using symlinks to point at packages placed at different locations" |
| 333 | ] | 376 | ] |
| @@ -337,7 +380,7 @@ | |||
| 337 | "id": "db8952aa-0944-4644-9626-7460786fd72a", | 380 | "id": "db8952aa-0944-4644-9626-7460786fd72a", |
| 338 | "metadata": {}, | 381 | "metadata": {}, |
| 339 | "source": [ | 382 | "source": [ |
| 340 | "## Creating and maintaining a Python environment (cont...)\n", | 383 | "## Creating and maintaining a Python environment - using the Python virtual environment - *venv*\n", |
| 341 | "\n", | 384 | "\n", |
| 342 | "Using venv can be done by directly invoking python:\n", | 385 | "Using venv can be done by directly invoking python:\n", |
| 343 | "\n", | 386 | "\n", |
| @@ -365,10 +408,13 @@ | |||
| 365 | "id": "299641e6-3d87-4a86-a124-eb49edb75b4b", | 408 | "id": "299641e6-3d87-4a86-a124-eb49edb75b4b", |
| 366 | "metadata": {}, | 409 | "metadata": {}, |
| 367 | "source": [ | 410 | "source": [ |
| 368 | "## Creating and maintaining a Python environment (cont...)\n", | 411 | "## Creating and maintaining a Python environment - using Poetry\n", |
| 369 | "\n", | 412 | "\n", |
| 370 | "Poetry [https://python-poetry.org](https://python-poetry.org) is the prefered environment and dependency management tool at Statnett.\n", | 413 | "Poetry [https://python-poetry.org](https://python-poetry.org) is the prefered environment and dependency management tool at Statnett.\n", |
| 371 | "\n", | 414 | "\n", |
| 415 | "Although Poetry creates and uses vierual environment(s) behind the scenes,\n", | ||
| 416 | "it is centered around the concept of \"projects\" and not the virtual environment itself\n", | ||
| 417 | "\n", | ||
| 372 | "```bash\n", | 418 | "```bash\n", |
| 373 | "# create project and a virtual environment from scratch\n", | 419 | "# create project and a virtual environment from scratch\n", |
| 374 | "poetry new my-project\n", | 420 | "poetry new my-project\n", |
| @@ -411,7 +457,7 @@ | |||
| 411 | { | 457 | { |
| 412 | "data": { | 458 | "data": { |
| 413 | "text/plain": [ | 459 | "text/plain": [ |
| 414 | "-42990858669078524" | 460 | "-3158428850515418558" |
| 415 | ] | 461 | ] |
| 416 | }, | 462 | }, |
| 417 | "execution_count": 15, | 463 | "execution_count": 15, |
| @@ -435,8 +481,8 @@ | |||
| 435 | "hash(t) # returns f.i. -6333845781340707986\n", | 481 | "hash(t) # returns f.i. -6333845781340707986\n", |
| 436 | "# hash(l) # TypeError: unhashable type: 'list'\n", | 482 | "# hash(l) # TypeError: unhashable type: 'list'\n", |
| 437 | "\n", | 483 | "\n", |
| 438 | "s = 'the long and winding road'\n", | 484 | "s = \"the long and winding road\"\n", |
| 439 | "s2 = 'the long and winding road'\n", | 485 | "s2 = \"the long and winding road\"\n", |
| 440 | "\n", | 486 | "\n", |
| 441 | "# check if s and s2 are the same object:\n", | 487 | "# check if s and s2 are the same object:\n", |
| 442 | "id(s) # Out: 139858905258704\n", | 488 | "id(s) # Out: 139858905258704\n", |
| @@ -816,7 +862,7 @@ | |||
| 816 | "# the function will behave differently depending on what parameters were\n", | 862 | "# the function will behave differently depending on what parameters were\n", |
| 817 | "# used when calling its enclosing function (factory function)\n", | 863 | "# used when calling its enclosing function (factory function)\n", |
| 818 | "\n", | 864 | "\n", |
| 819 | "def get_multiplier_of(base: int) -> str:\n", | 865 | "def get_multiplier_of(base: int):\n", |
| 820 | " \"\"\"the function enclosing its nested functions\"\"\"\n", | 866 | " \"\"\"the function enclosing its nested functions\"\"\"\n", |
| 821 | " # this function is the enclosing function of the function `multiplier_function`\n", | 867 | " # this function is the enclosing function of the function `multiplier_function`\n", |
| 822 | "\n", | 868 | "\n", |
| @@ -958,19 +1004,7 @@ | |||
| 958 | "execution_count": 22, | 1004 | "execution_count": 22, |
| 959 | "id": "4346260d-76af-437e-9c10-1c1d0c478695", | 1005 | "id": "4346260d-76af-437e-9c10-1c1d0c478695", |
| 960 | "metadata": {}, | 1006 | "metadata": {}, |
| 961 | "outputs": [ | 1007 | "outputs": [], |
| 962 | { | ||
| 963 | "ename": "NameError", | ||
| 964 | "evalue": "name 'is_admin' is not defined", | ||
| 965 | "output_type": "error", | ||
| 966 | "traceback": [ | ||
| 967 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||
| 968 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", | ||
| 969 | "Cell \u001b[0;32mIn[22], line 25\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m decorated\n\u001b[1;32m 21\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m api_access_decorator\n\u001b[1;32m 24\u001b[0m \u001b[38;5;129m@requires_access\u001b[39m(access_secret\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mb28cfeaa65b73cf\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m---> 25\u001b[0m \u001b[38;5;129m@is_admin\u001b[39m\n\u001b[1;32m 26\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21msensitive_function\u001b[39m(data, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 27\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"very sensitive function\"\"\"\u001b[39;00m\n\u001b[1;32m 28\u001b[0m db\u001b[38;5;241m.\u001b[39msave(data)\n", | ||
| 970 | "\u001b[0;31mNameError\u001b[0m: name 'is_admin' is not defined" | ||
| 971 | ] | ||
| 972 | } | ||
| 973 | ], | ||
| 974 | "source": [ | 1008 | "source": [ |
| 975 | "# Decorators (cont ...) - a complete example\n", | 1009 | "# Decorators (cont ...) - a complete example\n", |
| 976 | "\n", | 1010 | "\n", |
| @@ -996,7 +1030,7 @@ | |||
| 996 | "\n", | 1030 | "\n", |
| 997 | "\n", | 1031 | "\n", |
| 998 | "@requires_access(access_secret='b28cfeaa65b73cf')\n", | 1032 | "@requires_access(access_secret='b28cfeaa65b73cf')\n", |
| 999 | "@is_admin\n", | 1033 | "# @is_admin - decorators can be \"chained\"\n", |
| 1000 | "def sensitive_function(data, **kwargs):\n", | 1034 | "def sensitive_function(data, **kwargs):\n", |
| 1001 | " \"\"\"very sensitive function\"\"\"\n", | 1035 | " \"\"\"very sensitive function\"\"\"\n", |
| 1002 | " db.save(data)" | 1036 | " db.save(data)" |
| @@ -1030,11 +1064,19 @@ | |||
| 1030 | "\n", | 1064 | "\n", |
| 1031 | "\n", | 1065 | "\n", |
| 1032 | "# modern Python >= 3.6 f-strings\n", | 1066 | "# modern Python >= 3.6 f-strings\n", |
| 1033 | "f'{s} - {i} - {f:5.2f}' # Out: 'another string - 27 - 6.58'\n", | 1067 | "f\"{s} - {i} - {f:5.2f}\" # Out: 'another string - 27 - 6.58'\n", |
| 1034 | "``` \n", | 1068 | "``` \n", |
| 1035 | "\n", | 1069 | "\n", |
| 1036 | "See https://docs.python.org/3/library/string.html#formatspec for the complete format specification" | 1070 | "See https://docs.python.org/3/library/string.html#formatspec for the complete format specification" |
| 1037 | ] | 1071 | ] |
| 1072 | }, | ||
| 1073 | { | ||
| 1074 | "cell_type": "code", | ||
| 1075 | "execution_count": null, | ||
| 1076 | "id": "23972592-e838-4fa7-81f1-ca3ca129e757", | ||
| 1077 | "metadata": {}, | ||
| 1078 | "outputs": [], | ||
| 1079 | "source": [] | ||
| 1038 | } | 1080 | } |
| 1039 | ], | 1081 | ], |
| 1040 | "metadata": { | 1082 | "metadata": { |
| @@ -1053,7 +1095,7 @@ | |||
| 1053 | "name": "python", | 1095 | "name": "python", |
| 1054 | "nbconvert_exporter": "python", | 1096 | "nbconvert_exporter": "python", |
| 1055 | "pygments_lexer": "ipython3", | 1097 | "pygments_lexer": "ipython3", |
| 1056 | "version": "3.11.7" | 1098 | "version": "3.13.9" |
| 1057 | } | 1099 | } |
| 1058 | }, | 1100 | }, |
| 1059 | "nbformat": 4, | 1101 | "nbformat": 4, |
