Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ffbc6c8

Browse filesBrowse files
despadamdespadamedoardob90
authored
Expand OOP introductory notebook (empa-scientific-it#213)
Co-authored-by: despadam <despina.adamopoulou@empa.ch> Co-authored-by: Edoardo Baldi <edoardo.baldi@empa.ch>
1 parent 823c146 commit ffbc6c8
Copy full SHA for ffbc6c8

File tree

Expand file treeCollapse file tree

3 files changed

+363
-150
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+363
-150
lines changed

‎object_oriented_programming.ipynb

Copy file name to clipboardExpand all lines: object_oriented_programming.ipynb
+142-57Lines changed: 142 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@
1414
"metadata": {},
1515
"source": [
1616
"# Table of Contents\n",
17-
"\n",
18-
"- [References](#References)\n",
19-
"- [A `class` as a blueprint of objects](#A-class-as-a-blueprint-of-objects)\n",
20-
"- [Properties and methods](#Properties-and-methods)\n",
21-
"- [Python's *special methods*](#Python's-*special-methods*)\n",
22-
" - [`__str__` and `__repr__`](#__str__-and-__repr__)\n",
23-
" - [Exercise 1: Ice cream scoop 🌶️](#Exercise-1:-Ice-cream-scoop-🌶️)\n",
24-
" - [Comparison methods](#Comparison-methods)\n",
25-
" - [Exercise 2: Ice cream bowl 🌶️🌶️](#Exercise-2:-Ice-cream-bowl-🌶️🌶️)\n",
26-
"- [The `@property` keyword](#The-@property-keyword)\n",
27-
"- [Quick glossary](#Quick-glossary)\n",
28-
"- [Exercise 3: Intcode computer 🌶️🌶️🌶️](#Exercise-3:-Intcode-computer-🌶️🌶️🌶️)"
17+
" - [Object-oriented Programming](#Object-oriented-Programming)\n",
18+
" - [References](#References)\n",
19+
" - [A `class` as a blueprint of objects](#A-class-as-a-blueprint-of-objects)\n",
20+
" - [Properties and methods](#Properties-and-methods)\n",
21+
" - [Python's *special methods*](#Python's-*special-methods*)\n",
22+
" - [`__str__` and `__repr__`](#__str__-and-__repr__)\n",
23+
" - [Exercise 1: Ice cream scoop 🌶️](#Exercise-1:-Ice-cream-scoop-🌶️)\n",
24+
" - [Exercise 2: Ice cream bowl 🌶️🌶️](#Exercise-2:-Ice-cream-bowl-🌶️🌶️)\n",
25+
" - [Comparison methods](#Comparison-methods)\n",
26+
" - [Exercise 3: Ice cream shop 🌶️🌶️🌶️](#Exercise-3:-Ice-cream-shop-🌶️🌶️🌶️)\n",
27+
" - [The `@property` keyword](#The-@property-keyword)\n",
28+
" - [Quick glossary](#Quick-glossary)\n",
29+
" - [Quiz](#Quiz)\n",
30+
" - [Exercise 4: Intcode computer 🌶️🌶️🌶️🌶️](#Exercise-4:-Intcode-computer-🌶️🌶️🌶️🌶️)"
2931
]
3032
},
3133
{
@@ -270,7 +272,7 @@
270272
"id": "0f394fcf-6dca-4867-b098-51e97adcd268",
271273
"metadata": {},
272274
"source": [
273-
"Special methods are methods that Python define automatically. If you define a custom class, then you are responsible of definining the **expected behavior** of these methods. Otherwise, Python will fallback to the default, built-in definition, or it will raise an error if it doesn't know what to do.\n",
275+
"Special methods are methods that Python defines automatically. If you define a custom class, then you are responsible of defining the **expected behavior** of these methods. Otherwise, Python will fallback to the default, built-in definition, or it will raise an error if it doesn't know what to do.\n",
274276
"\n",
275277
"These are also called **dunder methods**, that is, \"double-underscore methods\", because their names look like `__method__`. There are special **attributes** as well."
276278
]
@@ -478,7 +480,7 @@
478480
"id": "0d793886-49fd-4300-87e5-664fc7a3eb3c",
479481
"metadata": {},
480482
"source": [
481-
"As you can see we still get that default. That's because here Python is **not** converting `r1` to a string, but instead looking for a string *representation* of the object. It is looking for the [`__repr__` method](https://docs.python.org/3/reference/datamodel.html#object.__repr__), which is defined as\n",
483+
"As you can see we still get the default. That's because here Python is **not** converting `r1` to a string, but instead looking for a string *representation* of the object. It is looking for the [`__repr__` method](https://docs.python.org/3/reference/datamodel.html#object.__repr__), which is defined as\n",
482484
"\n",
483485
"> the “official” string representation of an object\n",
484486
"\n",
@@ -543,7 +545,7 @@
543545
"\n",
544546
"<div class=\"alert alert-block alert-warning\">\n",
545547
" <h4><b>Question</b></h4>\n",
546-
" Complete the solution function such that it creates <strong>three</strong> instances of the <code>Scoop</code> class with the following flavors: chocolate, vanilla, persimmon. This function should return a list that collects the <strong>string representations</strong> of the ice cream scoops.\n",
548+
" Complete the solution function such that it creates an instance of the <code>Scoop</code> class for every flavor contained in the argument <code>flavors</code>. This function should return a list that collects the <strong>string representations</strong> of the ice cream scoops.\n",
547549
"</div>"
548550
]
549551
},
@@ -557,14 +559,70 @@
557559
"outputs": [],
558560
"source": [
559561
"%%ipytest\n",
560-
"class Scoop:\n",
561-
" \"\"\"A class representing a single scoop of ice cream\"\"\"\n",
562-
" # Write your class implementation here\n",
563562
"\n",
563+
"def solution_ice_cream_scoop(flavors: tuple[str]) -> list[str]:\n",
564564
"\n",
565-
"flavors = # TODO: create a tuple containing the flavors\n",
565+
" class Scoop:\n",
566+
" \"\"\"A class representing a single scoop of ice cream\"\"\"\n",
567+
" # Write your class implementation here\n",
568+
"\n",
569+
" # Write your solution here\n",
570+
" pass"
571+
]
572+
},
573+
{
574+
"cell_type": "markdown",
575+
"id": "4abfe0ba-c893-4ffd-b40b-5931821bcc62",
576+
"metadata": {
577+
"tags": []
578+
},
579+
"source": [
580+
"### Exercise 2: Ice cream bowl 🌶️🌶️"
581+
]
582+
},
583+
{
584+
"cell_type": "markdown",
585+
"id": "7f366029-6fa1-48f9-95ee-578b02addecd",
586+
"metadata": {},
587+
"source": [
588+
"Create a class `Bowl` that can hold many ice cream scoops, as many as you like. You *should use* the custom class you created in the previous exercise.\n",
589+
"\n",
590+
"The `Bowl` class should have a method called `add_scoops()` that accepts **variable number** of scoops.\n",
591+
"\n",
592+
"<div class=\"alert alert-block alert-info\">\n",
593+
" <h4><b>Hint</b></h4>\n",
594+
" In the <code>__init__</code> method of the <code>Bowl</code> class, you should define an attribute that acts as a container to hold the scoops you might want to add.\n",
595+
"</div>\n",
596+
"\n",
597+
"<div class=\"alert alert-block alert-warning\">\n",
598+
" <h4><b>Question</b></h4> \n",
599+
" Complete the solution function such that it creates a bowl of scoops with every flavor contained in the argument <code>flavors</code>. The output of this function should be a <strong>string</strong> that reports the content of the bowl you just created.\n",
600+
"</div>\n",
601+
"\n",
602+
"For example:\n",
603+
"\n",
604+
"```\n",
605+
"Ice cream bowl with chocolate, vanilla, stracciatella scoops\n",
606+
"```"
607+
]
608+
},
609+
{
610+
"cell_type": "code",
611+
"execution_count": null,
612+
"id": "0a634345-9799-4d1d-967b-9634c5672e5f",
613+
"metadata": {
614+
"tags": []
615+
},
616+
"outputs": [],
617+
"source": [
618+
"%%ipytest\n",
619+
" \n",
620+
"def solution_ice_cream_bowl(flavors: tuple[str]) -> str:\n",
621+
"\n",
622+
" class Bowl:\n",
623+
" \"\"\"A class representing a bowl of ice cream scoops\"\"\"\n",
624+
" # Write your class implementation here\n",
566625
"\n",
567-
"def solution_ice_cream_scoop(flavors: tuple[str]) -> list[str]:\n",
568626
" # Write your solution here\n",
569627
" pass"
570628
]
@@ -766,7 +824,7 @@
766824
"id": "72254316-200d-4a6d-bf93-d669f041c08b",
767825
"metadata": {},
768826
"source": [
769-
"That's because our `Rectangle` class automatically return `False` if we try to compare for equality an instance of `Rectangle` and any other Python object"
827+
"That's because our `Rectangle` class automatically returns `False` if we try to compare for equality an instance of `Rectangle` and any other Python object."
770828
]
771829
},
772830
{
@@ -951,58 +1009,50 @@
9511009
},
9521010
{
9531011
"cell_type": "markdown",
954-
"id": "4abfe0ba-c893-4ffd-b40b-5931821bcc62",
955-
"metadata": {
956-
"tags": []
957-
},
1012+
"id": "af6a4710",
1013+
"metadata": {},
9581014
"source": [
959-
"### Exercise 2: Ice cream bowl 🌶️🌶️"
1015+
"### Exercise 3: Ice cream shop 🌶️🌶️🌶️"
9601016
]
9611017
},
9621018
{
9631019
"cell_type": "markdown",
964-
"id": "7f366029-6fa1-48f9-95ee-578b02addecd",
1020+
"id": "883794ff",
9651021
"metadata": {},
9661022
"source": [
967-
"Create a class `Bowl` that can hold many ice cream scoops, as many as you like. You *should use* the custom class you created in the previous exercise.\n",
1023+
"Create a class `Shop` that sells many ice cream flavours. \n",
9681024
"\n",
969-
"The `Bowl` class should have a method called `add_scoops()` that accept **variable number** of scoops.\n",
1025+
"The `Shop` class should implement the comparison methods `__eq__`, `__lt__`, `__le__`.\n",
9701026
"\n",
9711027
"<div class=\"alert alert-block alert-info\">\n",
972-
" <h4><b>Hint</b></h4>\n",
973-
" In the <code>__init__</code> method of the <code>Bowl</code> class, you should define an attribute that acts as a container to hold the scoops you might want to add\n",
1028+
" <h4><b>Hints</b></h4>\n",
1029+
" <ul>\n",
1030+
" <li>In the <code>__init__</code> method of the <code>Shop</code> class, you should define an attribute that acts as a container to hold the available flavours.</li>\n",
1031+
" <li>You can use <code>__eq__</code> and <code>__lt__</code> to define <code>__le__</code>.</li>\n",
1032+
" </ul>\n",
9741033
"</div>\n",
9751034
"\n",
9761035
"<div class=\"alert alert-block alert-warning\">\n",
9771036
" <h4><b>Question</b></h4> \n",
978-
" Complete the solution function that creates a bowl of three scoops with flavors chocolate, vanilla, and stracciatella. The output of this function should be a <strong>string</strong> that reports the content of the bowl just created.\n",
979-
"</div>\n",
980-
"\n",
981-
"For example:\n",
982-
"\n",
983-
"```\n",
984-
"Ice cream bowl with chocolate, vanilla, stracciatella scoops\n",
985-
"```"
1037+
" Complete the solution function so that it creates two ice cream shops. <code>Shop 1</code> should sell the flavors provided by the parameter <code>flavor_1</code> and <code>Shop 2</code> should sell the flavors provided by the parameter <code>flavor_2</code>. The output of this function should be a <strong>boolean value</strong>: Does <code>Shop 1</code> sell <strong>fewer or the same</strong> number of flavors as <code>Shop 2</code>?\n",
1038+
"</div>"
9861039
]
9871040
},
9881041
{
9891042
"cell_type": "code",
9901043
"execution_count": null,
991-
"id": "0a634345-9799-4d1d-967b-9634c5672e5f",
992-
"metadata": {
993-
"tags": []
994-
},
1044+
"id": "2f203841",
1045+
"metadata": {},
9951046
"outputs": [],
9961047
"source": [
9971048
"%%ipytest\n",
998-
"class Bowl:\n",
999-
" \"\"\"A class representing a bowl of ice cream scoops\"\"\"\n",
1000-
" # Write your class implementation here\n",
10011049
"\n",
1050+
"def solution_ice_cream_shop(flavors_1: list[str], flavors_2: list[str]) -> bool:\n",
1051+
"\n",
1052+
" class Shop:\n",
1053+
" \"\"\"A class representing an ice cream shop\"\"\"\n",
1054+
" # Write your class implementation here\n",
10021055
"\n",
1003-
"flavors = # TODO: create a tuple containing the flavors\n",
1004-
" \n",
1005-
"def solution_ice_cream_bowl(flavors: tuple[str]) -> str:\n",
10061056
" # Write your solution here\n",
10071057
" pass"
10081058
]
@@ -1165,14 +1215,42 @@
11651215
"---"
11661216
]
11671217
},
1218+
{
1219+
"cell_type": "markdown",
1220+
"id": "027ae22c",
1221+
"metadata": {},
1222+
"source": [
1223+
"## Quiz\n",
1224+
"\n",
1225+
"Run the following cell to test your knowledge with a small quiz."
1226+
]
1227+
},
1228+
{
1229+
"cell_type": "code",
1230+
"execution_count": null,
1231+
"id": "da20c27f",
1232+
"metadata": {},
1233+
"outputs": [],
1234+
"source": [
1235+
"from tutorial import object_oriented_programming as oop\n",
1236+
"\n",
1237+
"oop.OopQuiz()"
1238+
]
1239+
},
11681240
{
11691241
"cell_type": "markdown",
11701242
"id": "419b5378-ff17-4ed3-8203-97c132918cb7",
11711243
"metadata": {
11721244
"tags": []
11731245
},
11741246
"source": [
1175-
"## Exercise 3: Intcode computer 🌶️🌶️🌶️"
1247+
"## Exercise 4: Intcode computer 🌶️🌶️🌶️🌶️\n",
1248+
"\n",
1249+
"<div class=\"alert alert-block alert-danger\">\n",
1250+
" <h4><b>Note</b></h4>\n",
1251+
" This is a recap exercise of intermediate difficulty.\n",
1252+
" If you <strong>never</strong> used classes or objects before, please try to solve and understand the previous exercises first.\n",
1253+
"</div>"
11761254
]
11771255
},
11781256
{
@@ -1273,16 +1351,23 @@
12731351
},
12741352
"outputs": [],
12751353
"source": [
1276-
"%%ipytest\n",
1277-
"class Computer:\n",
1278-
" \"\"\"An Intcode computer class\"\"\"\n",
1279-
" # Write your class implementation here\n",
1280-
"\n",
1281-
" \n",
1354+
"%%ipytest \n",
12821355
"def solution_intcode_computer(intcode: str) -> int:\n",
1356+
" class Computer:\n",
1357+
" \"\"\"An Intcode computer class\"\"\"\n",
1358+
" # Write your class implementation here\n",
1359+
"\n",
12831360
" # Write your solution function here\n",
12841361
" pass"
12851362
]
1363+
},
1364+
{
1365+
"cell_type": "code",
1366+
"execution_count": null,
1367+
"id": "d107aab6-4225-4407-8613-19d74407c41a",
1368+
"metadata": {},
1369+
"outputs": [],
1370+
"source": []
12861371
}
12871372
],
12881373
"metadata": {
@@ -1301,7 +1386,7 @@
13011386
"name": "python",
13021387
"nbconvert_exporter": "python",
13031388
"pygments_lexer": "ipython3",
1304-
"version": "3.10.14"
1389+
"version": "3.10.13"
13051390
}
13061391
},
13071392
"nbformat": 4,
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from .common import Question, Quiz
2+
3+
4+
class OopQuiz(Quiz):
5+
def __init__(self, title=""):
6+
q1 = Question(
7+
question="Based on what you learned about Python's special methods, which of the following statements is <strong>true</strong>?",
8+
options={
9+
"__repr__ is also used for __str__, but not vice versa.": "Correct! This statement is true.",
10+
"__str__ is also used for __repr__, but not vice versa.": "The opposite is true.",
11+
"__repr__ and __str__ are completely independent.": "__repr__ is also used for __str__, but not vice versa.",
12+
},
13+
correct_answer="__repr__ is also used for __str__, but not vice versa.",
14+
hint="",
15+
shuffle=True,
16+
)
17+
18+
q2 = Question(
19+
question="Based on what you learned about Python's comparison methods, which of the following statements is <strong>false</strong>?",
20+
options={
21+
"If we implement __gt__, Python will also use it for __lt__": "This statement is true.",
22+
"If we implement __lt__, Python will also use it for __le__": "Correct! This statement is false.",
23+
"If we implement __eq__, Python will also use it for __ne__": "This statement is true.",
24+
},
25+
correct_answer="If we implement __lt__, Python will also use it for __le__",
26+
hint="",
27+
shuffle=True,
28+
)
29+
30+
q3 = Question(
31+
question="Based on what you learned about the @property keyword, which of the following statements is <strong>false</strong>?",
32+
options={
33+
"@property creates attributes that act like methods but can be accessed and assigned as regular attributes.": "This statement is true.",
34+
"@property helps implement attributes that require additional logic or validation when getting or setting their values.": "This statement is true.",
35+
"@property makes code more readable but restricts dynamic attibute behaviour.": "Correct! This statement is false.",
36+
},
37+
correct_answer="@property makes code more readable but restricts dynamic attibute behaviour.",
38+
hint="",
39+
shuffle=True,
40+
)
41+
42+
super().__init__(questions=[q1, q2, q3])

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.