diff options
Diffstat (limited to 'notebooks/python/python_oo.ipynb')
| -rw-r--r-- | notebooks/python/python_oo.ipynb | 151 |
1 files changed, 108 insertions, 43 deletions
diff --git a/notebooks/python/python_oo.ipynb b/notebooks/python/python_oo.ipynb index e38d7f3..1ef2a72 100644 --- a/notebooks/python/python_oo.ipynb +++ b/notebooks/python/python_oo.ipynb | |||
| @@ -66,7 +66,55 @@ | |||
| 66 | "\n", | 66 | "\n", |
| 67 | "- improving modularity\n", | 67 | "- improving modularity\n", |
| 68 | "\n", | 68 | "\n", |
| 69 | "- providing foundation for a more intuitive design" | 69 | "- providing foundation for a more intuitive design\n", |
| 70 | "\n", | ||
| 71 | "A pseudo code example:\n", | ||
| 72 | "\n", | ||
| 73 | "```c\n", | ||
| 74 | "/* crating and drawing a (pseudo) widget in C */\n", | ||
| 75 | "my_widget = mylibrary_widget_init(); /* a struct of the type widget */\n", | ||
| 76 | "mylibrary_widget_draw(my_widget);\n", | ||
| 77 | "```\n", | ||
| 78 | "\n", | ||
| 79 | "```python\n", | ||
| 80 | "# creating and drawing a (pseudo) widget in Python\n", | ||
| 81 | "import mylibrary\n", | ||
| 82 | "\n", | ||
| 83 | "my_widget = mylibrary.Widget()\n", | ||
| 84 | "my_widget.draw()\n", | ||
| 85 | "```" | ||
| 86 | ] | ||
| 87 | }, | ||
| 88 | { | ||
| 89 | "cell_type": "markdown", | ||
| 90 | "id": "878cb805-a2d7-46a3-a34a-0507495420f7", | ||
| 91 | "metadata": {}, | ||
| 92 | "source": [ | ||
| 93 | "# Do I need to know / understand OOP when I am programming in Python?\n", | ||
| 94 | "\n", | ||
| 95 | "Most definitely - **yes**.\n", | ||
| 96 | "\n", | ||
| 97 | "While using programming language that is not object-oriented (like *C* and / or *Rust*) is always possible,\n", | ||
| 98 | "when using Python there are no *sane* alternatives that have ever been demonstrated:\n", | ||
| 99 | "\n", | ||
| 100 | "- Understanding OO behaviour and syntax is a must in order to understand Python code in general\n", | ||
| 101 | "- OOP is at the core of Python's design - everything in Python is an object\n", | ||
| 102 | "- Good programming and design is not only about solving a particular task. It is about reusing code and making your code reusable in turn\n", | ||
| 103 | "- Following the priciples described above is more challenging when not using OO in general." | ||
| 104 | ] | ||
| 105 | }, | ||
| 106 | { | ||
| 107 | "cell_type": "markdown", | ||
| 108 | "id": "b83dc815-ed51-4e5a-a30e-fa0252217194", | ||
| 109 | "metadata": {}, | ||
| 110 | "source": [ | ||
| 111 | "# I am doing only simple things with Python. Do I still need to learn OOP?\n", | ||
| 112 | "\n", | ||
| 113 | "Most definitely - **yes**.\n", | ||
| 114 | "\n", | ||
| 115 | "- A simple task provides a great opportunity to learn and practice OOP\n", | ||
| 116 | "- Using OOP **does not mean overcomplicating** your code. When applied correctly - it means the opposite\n", | ||
| 117 | "- Doing \"simple things\" exclusively is not very ambitious approach to programming and learning in general" | ||
| 70 | ] | 118 | ] |
| 71 | }, | 119 | }, |
| 72 | { | 120 | { |
| @@ -109,13 +157,20 @@ | |||
| 109 | "\n", | 157 | "\n", |
| 110 | "- object - an instance of a class that may contain its own attributes as well as references to its class' attributes\n", | 158 | "- object - an instance of a class that may contain its own attributes as well as references to its class' attributes\n", |
| 111 | "\n", | 159 | "\n", |
| 112 | "- attribute - variable, property, function defined in the class and present in its instances\n", | 160 | "- attribute - variable, property, function defined in the class and present in its instances - in Python: any name following a dot. Attributes may be *read-only* or *writable*. In the latter case, assignment to attributes is possible.\n", |
| 113 | "\n", | 161 | "\n", |
| 114 | "- class variable - attribute of which a single copy exists, regardless of how many instances of the class exist\n", | 162 | "- class variable - attribute of which a single copy exists, regardless of how many instances of the class exist\n", |
| 115 | "\n", | 163 | "\n", |
| 116 | "- object / instance variable, object / instance attribute - attribute for which each instantiated object of the class has a separate copy, or instance\n", | 164 | "- object / instance variable, object / instance attribute - attribute for which each instantiated object of the class has a separate copy, or instance\n", |
| 117 | "\n", | 165 | "\n", |
| 118 | "- method - member function - function that is an attribute" | 166 | "- method - member function - function that is an attribute\n", |
| 167 | "\n", | ||
| 168 | "```python\n", | ||
| 169 | "# my_str_obj is an object (instance) of the class str\n", | ||
| 170 | "my_str_object = str(\"Test\") # or my_str_object = \"Test\"\n", | ||
| 171 | "my_str_object.lower # attribute that is a function -> method\n", | ||
| 172 | "my_str_object.lower() # calling the method \"lower\"\n", | ||
| 173 | "```" | ||
| 119 | ] | 174 | ] |
| 120 | }, | 175 | }, |
| 121 | { | 176 | { |
| @@ -218,7 +273,7 @@ | |||
| 218 | }, | 273 | }, |
| 219 | { | 274 | { |
| 220 | "cell_type": "code", | 275 | "cell_type": "code", |
| 221 | "execution_count": 1, | 276 | "execution_count": 41, |
| 222 | "id": "a9c30a5d-aa86-45ab-b897-f051df80f1d8", | 277 | "id": "a9c30a5d-aa86-45ab-b897-f051df80f1d8", |
| 223 | "metadata": {}, | 278 | "metadata": {}, |
| 224 | "outputs": [ | 279 | "outputs": [ |
| @@ -226,17 +281,17 @@ | |||
| 226 | "name": "stdout", | 281 | "name": "stdout", |
| 227 | "output_type": "stream", | 282 | "output_type": "stream", |
| 228 | "text": [ | 283 | "text": [ |
| 229 | "car1.get_obj_info_str() = \"I am <__main__.Car object at 0x7f70e643d590> with id 140122876269968 from <class '__main__.Car'> with id 93964809433504\"\n", | 284 | "car1.get_obj_info_str() = \"I am <__main__.Car object at 0x7fd00029ff80> with id 140531332677504 from <class '__main__.Car'> with id 93887620597168\"\n", |
| 230 | "car2.get_obj_info_str() = \"I am <__main__.Car object at 0x7f70e63ddf10> with id 140122875879184 from <class '__main__.Car'> with id 93964809433504\"\n", | 285 | "car2.get_obj_info_str() = \"I am <__main__.Car object at 0x7fd00029ea50> with id 140531332672080 from <class '__main__.Car'> with id 93887620597168\"\n", |
| 231 | "car1.model = 'BMW', car1.reg_nr = 'EC76183', car1.extras = ['GPSnav', 'Sound system'], id(car1.cls_extras) = 140122875882432, id(car1.get_obj_info_str) = 140122875878080\n", | 286 | "car1.model = 'BMW', car1.reg_nr = 'EC76183', car1.extras = ['GPSnav', 'Sound system'], id(car1.cls_extras) = 140531337557440, id(car1.get_obj_info_str) = 140531251735488\n", |
| 232 | "car2.model = 'Scoda', car2.reg_nr = 'BD77655', car2.extras = ['GPSnav'], id(car2.cls_extras) = 140122875882432, id(car2.get_obj_info_str) = 140122875880192\n", | 287 | "car2.model = 'Scoda', car2.reg_nr = 'BD77655', car2.extras = ['GPSnav'], id(car2.cls_extras) = 140531337557440, id(car2.get_obj_info_str) = 140531251728064\n", |
| 233 | "id(Car.cls_extras) = 140122875882432, id(Car.get_obj_info_str) = 140122875964416\n", | 288 | "id(Car.cls_extras) = 140531337557440, id(Car.get_obj_info_str) = 140531252010400\n", |
| 234 | "car1.cls_extras = ['GPSnav', 'Sound system'], id(car1.cls_extras) = 140122875882432\n", | 289 | "car1.cls_extras = ['GPSnav', 'Sound system'], id(car1.cls_extras) = 140531337557440\n", |
| 235 | "car2.cls_extras = ['GPSnav', 'Sound system'], id(car2.cls_extras) = 140122875882432\n", | 290 | "car2.cls_extras = ['GPSnav', 'Sound system'], id(car2.cls_extras) = 140531337557440\n", |
| 236 | "True\n", | 291 | "True\n", |
| 237 | "hasattr(car1, 'import_tax_paid') = True\n", | 292 | "hasattr(car1, 'import_tax_paid') = True\n", |
| 238 | "hasattr(car2, 'import_tax_paid') = False\n", | 293 | "hasattr(car2, 'import_tax_paid') = False\n", |
| 239 | "id(car1.__class__) = 93964809433504, id(car2.__class__) = 93964809433504, id(Car) = 93964809433504\n" | 294 | "id(car1.__class__) = 93887620597168, id(car2.__class__) = 93887620597168, id(Car) = 93887620597168\n" |
| 240 | ] | 295 | ] |
| 241 | } | 296 | } |
| 242 | ], | 297 | ], |
| @@ -288,7 +343,7 @@ | |||
| 288 | "# - checks if 'attr' is an instance attribute\n", | 343 | "# - checks if 'attr' is an instance attribute\n", |
| 289 | "# - checks if 'attr' is a class attribute (through the method resolution order - MRO)\n", | 344 | "# - checks if 'attr' is a class attribute (through the method resolution order - MRO)\n", |
| 290 | "# - raises AttributeError\n", | 345 | "# - raises AttributeError\n", |
| 291 | "# setter:\n", | 346 | "# setter (making the attribute writable):\n", |
| 292 | "# - (re)defines an instance attribute\n", | 347 | "# - (re)defines an instance attribute\n", |
| 293 | "\n", | 348 | "\n", |
| 294 | "# Details not covered in this course:\n", | 349 | "# Details not covered in this course:\n", |
| @@ -323,7 +378,7 @@ | |||
| 323 | }, | 378 | }, |
| 324 | { | 379 | { |
| 325 | "cell_type": "code", | 380 | "cell_type": "code", |
| 326 | "execution_count": 2, | 381 | "execution_count": 42, |
| 327 | "id": "391e816e-c53b-454b-9e9f-3587234f1fea", | 382 | "id": "391e816e-c53b-454b-9e9f-3587234f1fea", |
| 328 | "metadata": {}, | 383 | "metadata": {}, |
| 329 | "outputs": [ | 384 | "outputs": [ |
| @@ -413,7 +468,7 @@ | |||
| 413 | }, | 468 | }, |
| 414 | { | 469 | { |
| 415 | "cell_type": "code", | 470 | "cell_type": "code", |
| 416 | "execution_count": 3, | 471 | "execution_count": 43, |
| 417 | "id": "e82feefb-025d-4cbb-a8ac-ddc3cc01269c", | 472 | "id": "e82feefb-025d-4cbb-a8ac-ddc3cc01269c", |
| 418 | "metadata": {}, | 473 | "metadata": {}, |
| 419 | "outputs": [ | 474 | "outputs": [ |
| @@ -495,7 +550,7 @@ | |||
| 495 | }, | 550 | }, |
| 496 | { | 551 | { |
| 497 | "cell_type": "code", | 552 | "cell_type": "code", |
| 498 | "execution_count": 4, | 553 | "execution_count": 44, |
| 499 | "id": "71a90ec6-3cc0-441e-a866-c2c2b9984559", | 554 | "id": "71a90ec6-3cc0-441e-a866-c2c2b9984559", |
| 500 | "metadata": {}, | 555 | "metadata": {}, |
| 501 | "outputs": [ | 556 | "outputs": [ |
| @@ -613,7 +668,7 @@ | |||
| 613 | }, | 668 | }, |
| 614 | { | 669 | { |
| 615 | "cell_type": "code", | 670 | "cell_type": "code", |
| 616 | "execution_count": 5, | 671 | "execution_count": 45, |
| 617 | "id": "a4d2735d-d167-4f43-ad55-cb3d13ece2dc", | 672 | "id": "a4d2735d-d167-4f43-ad55-cb3d13ece2dc", |
| 618 | "metadata": {}, | 673 | "metadata": {}, |
| 619 | "outputs": [ | 674 | "outputs": [ |
| @@ -656,7 +711,7 @@ | |||
| 656 | }, | 711 | }, |
| 657 | { | 712 | { |
| 658 | "cell_type": "code", | 713 | "cell_type": "code", |
| 659 | "execution_count": 6, | 714 | "execution_count": 46, |
| 660 | "id": "a6ead5e6-e987-4bda-bf48-30f91877278d", | 715 | "id": "a6ead5e6-e987-4bda-bf48-30f91877278d", |
| 661 | "metadata": {}, | 716 | "metadata": {}, |
| 662 | "outputs": [ | 717 | "outputs": [ |
| @@ -715,7 +770,7 @@ | |||
| 715 | }, | 770 | }, |
| 716 | { | 771 | { |
| 717 | "cell_type": "code", | 772 | "cell_type": "code", |
| 718 | "execution_count": 7, | 773 | "execution_count": 47, |
| 719 | "id": "11f6a3fb-64d7-40a9-a130-27548ec4b802", | 774 | "id": "11f6a3fb-64d7-40a9-a130-27548ec4b802", |
| 720 | "metadata": {}, | 775 | "metadata": {}, |
| 721 | "outputs": [ | 776 | "outputs": [ |
| @@ -797,7 +852,7 @@ | |||
| 797 | }, | 852 | }, |
| 798 | { | 853 | { |
| 799 | "cell_type": "code", | 854 | "cell_type": "code", |
| 800 | "execution_count": 8, | 855 | "execution_count": 48, |
| 801 | "id": "c345a69f-02da-40e7-bb37-c0511b6af096", | 856 | "id": "c345a69f-02da-40e7-bb37-c0511b6af096", |
| 802 | "metadata": {}, | 857 | "metadata": {}, |
| 803 | "outputs": [ | 858 | "outputs": [ |
| @@ -806,6 +861,9 @@ | |||
| 806 | "output_type": "stream", | 861 | "output_type": "stream", |
| 807 | "text": [ | 862 | "text": [ |
| 808 | "9\n", | 863 | "9\n", |
| 864 | "9\n", | ||
| 865 | "140531251904896\n", | ||
| 866 | "140531251904896\n", | ||
| 809 | "Vector.from_str('1:1:5:6') = Vector(start=Point(x=1, y=1), end=Point(x=5, y=6))\n" | 867 | "Vector.from_str('1:1:5:6') = Vector(start=Point(x=1, y=1), end=Point(x=5, y=6))\n" |
| 810 | ] | 868 | ] |
| 811 | } | 869 | } |
| @@ -837,7 +895,14 @@ | |||
| 837 | " Point(coordinates[2], coordinates[3]),\n", | 895 | " Point(coordinates[2], coordinates[3]),\n", |
| 838 | " )\n", | 896 | " )\n", |
| 839 | "\n", | 897 | "\n", |
| 840 | "print(Point.get_manhattan_distance(Point(1, 1), Point(5, 6)))\n", | 898 | "point1 = Point(1, 1)\n", |
| 899 | "point2 = Point(5, 6)\n", | ||
| 900 | "print(f\"{point1.get_manhattan_distance(point1, point2)}\") # works, but should not be used in that way\n", | ||
| 901 | "print(f\"{Point.get_manhattan_distance(point1, point2)}\")\n", | ||
| 902 | "print(f\"{id(point1.get_manhattan_distance)}\")\n", | ||
| 903 | "print(f\"{id(point2.get_manhattan_distance)}\")\n", | ||
| 904 | "# print(f\"{id(point1.from_str)}\") <-- not available as an instance attribute\n", | ||
| 905 | "\n", | ||
| 841 | "print(f\"{Vector.from_str('1:1:5:6') = }\")" | 906 | "print(f\"{Vector.from_str('1:1:5:6') = }\")" |
| 842 | ] | 907 | ] |
| 843 | }, | 908 | }, |
| @@ -890,7 +955,7 @@ | |||
| 890 | }, | 955 | }, |
| 891 | { | 956 | { |
| 892 | "cell_type": "code", | 957 | "cell_type": "code", |
| 893 | "execution_count": 9, | 958 | "execution_count": 49, |
| 894 | "id": "44d47e1c-1a06-4577-8db6-6ec78ce5cef8", | 959 | "id": "44d47e1c-1a06-4577-8db6-6ec78ce5cef8", |
| 895 | "metadata": {}, | 960 | "metadata": {}, |
| 896 | "outputs": [ | 961 | "outputs": [ |
| @@ -903,32 +968,32 @@ | |||
| 903 | "\n", | 968 | "\n", |
| 904 | "class TigerShark(Fish)\n", | 969 | "class TigerShark(Fish)\n", |
| 905 | " | TigerShark(weight: int, alive: bool = True, **kwargs)\n", | 970 | " | TigerShark(weight: int, alive: bool = True, **kwargs)\n", |
| 906 | " | \n", | 971 | " |\n", |
| 907 | " | Base class for all tiger sharks\n", | 972 | " | Base class for all tiger sharks\n", |
| 908 | " | \n", | 973 | " |\n", |
| 909 | " | Method resolution order:\n", | 974 | " | Method resolution order:\n", |
| 910 | " | TigerShark\n", | 975 | " | TigerShark\n", |
| 911 | " | Fish\n", | 976 | " | Fish\n", |
| 912 | " | Animal\n", | 977 | " | Animal\n", |
| 913 | " | builtins.object\n", | 978 | " | builtins.object\n", |
| 914 | " | \n", | 979 | " |\n", |
| 915 | " | Methods defined here:\n", | 980 | " | Methods defined here:\n", |
| 916 | " | \n", | 981 | " |\n", |
| 917 | " | __init__(self, weight: int, alive: bool = True, **kwargs)\n", | 982 | " | __init__(self, weight: int, alive: bool = True, **kwargs)\n", |
| 918 | " | Initialize self. See help(type(self)) for accurate signature.\n", | 983 | " | Initialize self. See help(type(self)) for accurate signature.\n", |
| 919 | " | \n", | 984 | " |\n", |
| 920 | " | ----------------------------------------------------------------------\n", | 985 | " | ----------------------------------------------------------------------\n", |
| 921 | " | Data descriptors inherited from Animal:\n", | 986 | " | Data descriptors inherited from Animal:\n", |
| 922 | " | \n", | 987 | " |\n", |
| 923 | " | __dict__\n", | 988 | " | __dict__\n", |
| 924 | " | dictionary for instance variables (if defined)\n", | 989 | " | dictionary for instance variables\n", |
| 925 | " | \n", | 990 | " |\n", |
| 926 | " | __weakref__\n", | 991 | " | __weakref__\n", |
| 927 | " | list of weak references to the object (if defined)\n", | 992 | " | list of weak references to the object\n", |
| 928 | " | \n", | 993 | " |\n", |
| 929 | " | alive\n", | 994 | " | alive\n", |
| 930 | " | getter property alive\n", | 995 | " | getter property alive\n", |
| 931 | " | \n", | 996 | " |\n", |
| 932 | " | weight\n", | 997 | " | weight\n", |
| 933 | " | getter property weight\n", | 998 | " | getter property weight\n", |
| 934 | "\n", | 999 | "\n", |
| @@ -1064,7 +1129,7 @@ | |||
| 1064 | }, | 1129 | }, |
| 1065 | { | 1130 | { |
| 1066 | "cell_type": "code", | 1131 | "cell_type": "code", |
| 1067 | "execution_count": 10, | 1132 | "execution_count": 50, |
| 1068 | "id": "e6076925-75f0-456c-aed5-7db0a24a67a1", | 1133 | "id": "e6076925-75f0-456c-aed5-7db0a24a67a1", |
| 1069 | "metadata": {}, | 1134 | "metadata": {}, |
| 1070 | "outputs": [ | 1135 | "outputs": [ |
| @@ -1169,7 +1234,7 @@ | |||
| 1169 | }, | 1234 | }, |
| 1170 | { | 1235 | { |
| 1171 | "cell_type": "code", | 1236 | "cell_type": "code", |
| 1172 | "execution_count": 11, | 1237 | "execution_count": 51, |
| 1173 | "id": "cf79617a-95d2-48f2-be66-fa1fa34e4e04", | 1238 | "id": "cf79617a-95d2-48f2-be66-fa1fa34e4e04", |
| 1174 | "metadata": {}, | 1239 | "metadata": {}, |
| 1175 | "outputs": [ | 1240 | "outputs": [ |
| @@ -1192,14 +1257,14 @@ | |||
| 1192 | " | Adam\n", | 1257 | " | Adam\n", |
| 1193 | " | Eve\n", | 1258 | " | Eve\n", |
| 1194 | " | builtins.object\n", | 1259 | " | builtins.object\n", |
| 1195 | " | \n", | 1260 | " |\n", |
| 1196 | " | Data descriptors inherited from Adam:\n", | 1261 | " | Data descriptors inherited from Adam:\n", |
| 1197 | " | \n", | 1262 | " |\n", |
| 1198 | " | __dict__\n", | 1263 | " | __dict__\n", |
| 1199 | " | dictionary for instance variables (if defined)\n", | 1264 | " | dictionary for instance variables\n", |
| 1200 | " | \n", | 1265 | " |\n", |
| 1201 | " | __weakref__\n", | 1266 | " | __weakref__\n", |
| 1202 | " | list of weak references to the object (if defined)\n", | 1267 | " | list of weak references to the object\n", |
| 1203 | "\n" | 1268 | "\n" |
| 1204 | ] | 1269 | ] |
| 1205 | } | 1270 | } |
| @@ -1256,7 +1321,7 @@ | |||
| 1256 | }, | 1321 | }, |
| 1257 | { | 1322 | { |
| 1258 | "cell_type": "code", | 1323 | "cell_type": "code", |
| 1259 | "execution_count": 12, | 1324 | "execution_count": 52, |
| 1260 | "id": "95a1d0cc-0006-4ddc-b08d-d0b8b02acfba", | 1325 | "id": "95a1d0cc-0006-4ddc-b08d-d0b8b02acfba", |
| 1261 | "metadata": {}, | 1326 | "metadata": {}, |
| 1262 | "outputs": [ | 1327 | "outputs": [ |
| @@ -1324,7 +1389,7 @@ | |||
| 1324 | }, | 1389 | }, |
| 1325 | { | 1390 | { |
| 1326 | "cell_type": "code", | 1391 | "cell_type": "code", |
| 1327 | "execution_count": 13, | 1392 | "execution_count": 53, |
| 1328 | "id": "38066107-0190-4383-ba14-a4e9cd454a9c", | 1393 | "id": "38066107-0190-4383-ba14-a4e9cd454a9c", |
| 1329 | "metadata": {}, | 1394 | "metadata": {}, |
| 1330 | "outputs": [ | 1395 | "outputs": [ |
| @@ -1418,7 +1483,7 @@ | |||
| 1418 | "name": "python", | 1483 | "name": "python", |
| 1419 | "nbconvert_exporter": "python", | 1484 | "nbconvert_exporter": "python", |
| 1420 | "pygments_lexer": "ipython3", | 1485 | "pygments_lexer": "ipython3", |
| 1421 | "version": "3.11.7" | 1486 | "version": "3.13.9" |
| 1422 | } | 1487 | } |
| 1423 | }, | 1488 | }, |
| 1424 | "nbformat": 4, | 1489 | "nbformat": 4, |
