summaryrefslogtreecommitdiff
path: root/notebooks/python/python_oo.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'notebooks/python/python_oo.ipynb')
-rw-r--r--notebooks/python/python_oo.ipynb151
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,