Skip to content

Commit db20054

Browse files
Replace "Eye Color" exercise with "Triathlete" (#359)
* Replace eye-color exercise with triathlete * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent ea7847b commit db20054

File tree

3 files changed

+117
-108
lines changed

3 files changed

+117
-108
lines changed

13_object_oriented_programming_advanced.ipynb

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
" - [Composition](#Composition)\n",
2323
" - [`super()`](#super())\n",
2424
" - [Quiz on Inheritance](#Quiz-on-Inheritance)\n",
25-
" - [Exercise: Child Eye Color](#Exercise:-Child-Eye-Color)\n",
25+
" - [Exercise: Triathlete](#Exercise:-Triathlete)\n",
2626
" - [Abstract Classes](#Abstract-Classes)\n",
2727
" - [Quiz on Abstraction](#Quiz-on-Abstraction)\n",
2828
" - [Exercise: Banking System](#Exercise:-Banking-System)\n",
@@ -494,22 +494,21 @@
494494
"id": "36",
495495
"metadata": {},
496496
"source": [
497-
"### Exercise: Child Eye Color\n",
497+
"### Exercise: Triathlete\n",
498498
"\n",
499-
"In this exercise, we will implement the following simplified theory on how to predict a child's eye color, based on the eye color of its parents.\n",
499+
"A triathlon is a race consisting of three disciplines: **swimming**, **cycling**, and **running**, completed back-to-back.\n",
500500
"\n",
501-
"We assume that the only existing eye colors are <span style=\"color:blue\">blue</span> and <span style=\"color:brown\">brown</span>. We also assume the following rules:\n",
502-
"- If both parents have <span style=\"color:brown\">brown</span> eyes, their child will also have <span style=\"color:brown\">brown</span> eyes.\n",
503-
"- If both parents have <span style=\"color:blue\">blue</span> eyes, their child will also have <span style=\"color:blue\">blue</span> eyes.\n",
504-
"- If one parent has <span style=\"color:brown\">brown</span> eyes and the other one has <span style=\"color:blue\">blue</span> eyes, the dominant color will be <span style=\"color:brown\">brown</span>.\n",
501+
"We model this using the following class hierarchy:\n",
502+
"- **Swimmer** with attribute `swim_time`.\n",
503+
"- **Cyclist** with attribute `bike_time`.\n",
504+
"- **Runner** with attribute `run_time`.\n",
505+
"- **Triathlete** with attributes `name` and `total_time`, which is the sum of all three split times inherited from `Swimmer`, `Cyclist`, and `Runner`.\n",
505506
"\n",
506507
"<div class=\"alert alert-block alert-warning\">\n",
507508
" <h4><b>Question</b></h4>\n",
508509
" <ul>\n",
509-
" <li>Complete the solution function such that it defines classes <strong>Mother</strong> and <strong>Father</strong>, each with an attribute for the eye color.</li>\n",
510-
" <li>Define class <strong>Child</strong>, which inherits from <strong>Mother</strong> and <strong>Father</strong> and has an attribute called <strong>eye_color</strong>.\n",
511-
" Then, based on the eye colors of the parents, calculate the child's eye color, according to the rules above and assign it to the attribute <code>eye_color</code>.</li>\n",
512-
" <li>Create an instance of <strong>Child</strong>, which is being initialized by using the arguments passed in the solution function, namely the eye colors of its parents. Lastly, return this instance.</li>\n",
510+
" <li>Define the four classes described above.</li>\n",
511+
" <li>Create and return an instance of <code>Triathlete</code> using the arguments passed to the solution function.</li>\n",
513512
" </ul>\n",
514513
"</div>"
515514
]
@@ -533,19 +532,21 @@
533532
"source": [
534533
"%%ipytest\n",
535534
"\n",
536-
"def solution_child_eye_color(mother_eye_color: str, father_eye_color: str) -> list:\n",
535+
"def solution_triathlete(name: str, swim_time: float, bike_time: float, run_time: float):\n",
537536
" \"\"\"\n",
538-
" Given the eye colors of the mother and father, defines the eye color of the child.\n",
539-
" The possible eye colors are: brown or blue, with brown being the dominant one.\n",
540-
" This function defines a class Mother and a class Father, which are used to create an instance of the class Child.\n",
541-
" It returns an instance of the class Child with the eye color defined by the parents.\n",
537+
" Defines three parent classes: Swimmer (swim_time), Cyclist (bike_time), Runner (run_time).\n",
538+
" Triathlete inherits from all three.\n",
539+
" Triathlete has attributes name and total_time, which is the sum of all three split times.\n",
542540
"\n",
543541
" Args:\n",
544-
" mother_eye_color (str): Eye color of the mother.\n",
545-
" father_eye_color (str): Eye color of the father.\n",
542+
" name (str): Name of the triathlete.\n",
543+
" swim_time (float): Swim split time in hours.\n",
544+
" bike_time (float): Bike split time in hours.\n",
545+
" run_time (float): Run split time in hours.\n",
546546
" Returns:\n",
547-
" - an instance of class Child\n",
547+
" - an instance of class Triathlete\n",
548548
" \"\"\"\n",
549+
"\n",
549550
" return"
550551
]
551552
},

tutorial/quiz/object_oriented_programming_advanced.py

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ def __init__(self, title=""):
66
q1 = Question(
77
question="Which special method is used for object initialization in Python?",
88
options={
9-
"__init__": "Correct! The `__init__` method is called when an object is created and is used to initialize the object.",
10-
"__repr__": "The `__repr__` method is used to provide an unambiguous string representation of an object.",
11-
"__eq__": "The `__eq__` method is used to define equality comparison between objects.",
9+
"__init__": "Correct! The <code>__init__</code> method is called when an object is created and is used to initialize the object.",
10+
"__repr__": "The <code>__repr__</code> method is used to provide an unambiguous string representation of an object.",
11+
"__eq__": "The <code>__eq__</code> method is used to define equality comparison between objects.",
1212
},
1313
correct_answer="__init__",
1414
hint="This method is automatically called when an object is instantiated.",
@@ -27,11 +27,11 @@ def __init__(self, title=""):
2727
)
2828

2929
q3 = Question(
30-
question="What is the purpose of the `super()` function in Python?",
30+
question="What is the purpose of the <code>super()</code> function in Python?",
3131
options={
32-
"To call a method from the parent class": "Correct! `super()` is used to call a method from the parent class.",
33-
"To create a derived class": "Incorrect. `super()` is not used for creating derived classes.",
34-
"To initialize an object": "Incorrect. Object initialization is done using the `__init__` method.",
32+
"To call a method from the parent class": "Correct! <code>super()</code> is used to call a method from the parent class.",
33+
"To create a derived class": "Incorrect. <code>super()</code> is not used for creating derived classes.",
34+
"To initialize an object": "Incorrect. Object initialization is done using the <code>__init__</code> method.",
3535
},
3636
correct_answer="To call a method from the parent class",
3737
hint="This function is used to access inherited methods.",
@@ -58,9 +58,9 @@ def __init__(self, title=""):
5858
q1 = Question(
5959
question="Which module in Python is used to create abstract classes?",
6060
options={
61-
"abc": "Correct! The `abc` module provides the infrastructure for defining abstract base classes.",
62-
"abstract": "There is no module named `abstract` in Python.",
63-
"abstractmodule": "There is no module named `abstractmodule` in Python.",
61+
"abc": "Correct! The <code>abc</code> module provides the infrastructure for defining abstract base classes.",
62+
"abstract": "There is no module named <code>abstract</code> in Python.",
63+
"abstractmodule": "There is no module named <code>abstractmodule</code> in Python.",
6464
},
6565
correct_answer="abc",
6666
hint="This module's name is an abbreviation for 'Abstract Base Classes'.",
@@ -100,22 +100,22 @@ def __init__(self, title=""):
100100
question="Which decorator is used to define a method that belongs to the class rather than an instance?",
101101
options={
102102
"@staticmethod": "Incorrect. A static method does not belong to the class or instance.",
103-
"@classmethod": "Correct! A class method belongs to the class and takes `cls` as its first parameter.",
104-
"@property": "Incorrect. The `@property` decorator is used to define getter methods.",
105-
"@abstractmethod": "Incorrect. The `@abstractmethod` decorator is used in abstract classes.",
103+
"@classmethod": "Correct! A class method belongs to the class and takes <code>cls</code> as its first parameter.",
104+
"@property": "Incorrect. The <code>@property</code> decorator is used to define getter methods.",
105+
"@abstractmethod": "Incorrect. The <code>@abstractmethod</code> decorator is used in abstract classes.",
106106
},
107107
correct_answer="@classmethod",
108-
hint="This method takes `cls` as its first parameter.",
108+
hint="This method takes <code>cls</code> as its first parameter.",
109109
shuffle=True,
110110
)
111111

112112
q2 = Question(
113-
question="What is the purpose of the `@property` decorator?",
113+
question="What is the purpose of the <code>@property</code> decorator?",
114114
options={
115-
"To define a computed attribute": "Correct! The `@property` decorator is used to define computed attributes.",
116-
"To define a static method": "Incorrect. Static methods are defined using the `@staticmethod` decorator.",
117-
"To define a class method": "Incorrect. Class methods are defined using the `@classmethod` decorator.",
118-
"To define an abstract method": "Incorrect. Abstract methods are defined using the `@abstractmethod` decorator.",
115+
"To define a computed attribute": "Correct! The <code>@property</code> decorator is used to define computed attributes.",
116+
"To define a static method": "Incorrect. Static methods are defined using the <code>@staticmethod</code> decorator.",
117+
"To define a class method": "Incorrect. Class methods are defined using the <code>@classmethod</code> decorator.",
118+
"To define an abstract method": "Incorrect. Abstract methods are defined using the <code>@abstractmethod</code> decorator.",
119119
},
120120
correct_answer="To define a computed attribute",
121121
hint="This decorator allows you to define methods that can be accessed like attributes.",
@@ -126,20 +126,20 @@ def __init__(self, title=""):
126126
question="Which decorator is used to define a method that does not access the class or instance?",
127127
options={
128128
"@staticmethod": "Correct! A static method does not access the class or instance.",
129-
"@classmethod": "Incorrect. A class method accesses the class using `cls`.",
130-
"@property": "Incorrect. The `@property` decorator is used to define getter methods.",
131-
"@abstractmethod": "Incorrect. The `@abstractmethod` decorator is used in abstract classes.",
129+
"@classmethod": "Incorrect. A class method accesses the class using <code>cls</code>.",
130+
"@property": "Incorrect. The <code>@property</code> decorator is used to define getter methods.",
131+
"@abstractmethod": "Incorrect. The <code>@abstractmethod</code> decorator is used in abstract classes.",
132132
},
133133
correct_answer="@staticmethod",
134134
hint="This method is often used for utility functions.",
135135
shuffle=True,
136136
)
137137

138138
q4 = Question(
139-
question="A method with which decorator takes `cls` as its first parameter?",
139+
question="A method with which decorator takes <code>cls</code> as its first parameter?",
140140
options={
141-
"@classmethod": "Correct! A class method is bound to a class rather than its instances and the parameter `cls` represents the class itself.",
142-
"@staticmethod": "A static method does not have access to `cls` or `self` and cannot modify the class state.",
141+
"@classmethod": "Correct! A class method is bound to a class rather than its instances and the parameter <code>cls</code> represents the class itself.",
142+
"@staticmethod": "A static method does not have access to <code>cls</code> or <code>self</code> and cannot modify the class state.",
143143
"@abstractmethod": "This decorator defines a method in an abstract class that **must** be implemented by all its concrete subclasses.",
144144
},
145145
correct_answer="@classmethod",
@@ -148,27 +148,27 @@ def __init__(self, title=""):
148148
)
149149

150150
q5 = Question(
151-
question="What is the purpose of the `@classmethod` decorator?",
151+
question="What is the purpose of the <code>@classmethod</code> decorator?",
152152
options={
153-
"To define a method that belongs to the class rather than an instance": "Correct! A class method belongs to the class and takes `cls` as its first parameter.",
153+
"To define a method that belongs to the class rather than an instance": "Correct! A class method belongs to the class and takes <code>cls</code> as its first parameter.",
154154
"To define a method that does not access the class or instance": "Incorrect. This describes a static method.",
155-
"To define a computed attribute": "Incorrect. Computed attributes are defined using the `@property` decorator.",
156-
"To define an abstract method": "Incorrect. Abstract methods are defined using the `@abstractmethod` decorator.",
155+
"To define a computed attribute": "Incorrect. Computed attributes are defined using the <code>@property</code> decorator.",
156+
"To define an abstract method": "Incorrect. Abstract methods are defined using the <code>@abstractmethod</code> decorator.",
157157
},
158158
correct_answer="To define a method that belongs to the class rather than an instance",
159-
hint="This method takes `cls` as its first parameter.",
159+
hint="This method takes <code>cls</code> as its first parameter.",
160160
shuffle=True,
161161
)
162162

163163
q6 = Question(
164-
question="What is the difference between `@staticmethod` and `@classmethod`?",
164+
question="What is the difference between <code>@staticmethod</code> and <code>@classmethod</code>?",
165165
options={
166-
"`@staticmethod` does not access the class or instance, while `@classmethod` takes `cls` as its first parameter": "Correct! This is the key difference between the two decorators.",
167-
"`@staticmethod` is used for utility functions, while `@classmethod` is used for abstract methods": "Incorrect. Abstract methods are unrelated to these decorators.",
168-
"`@staticmethod` is faster than `@classmethod`": "Incorrect. Performance is not the defining difference.",
169-
"`@staticmethod` is used for computed attributes, while `@classmethod` is used for class-level attributes": "Incorrect. Computed attributes are defined using `@property`.",
166+
"<code>@staticmethod</code> does not access the class or instance, while <code>@classmethod</code> takes <code>cls</code> as its first parameter": "Correct! This is the key difference between the two decorators.",
167+
"<code>@staticmethod</code> is used for utility functions, while <code>@classmethod</code> is used for abstract methods": "Incorrect. Abstract methods are unrelated to these decorators.",
168+
"<code>@staticmethod</code> is faster than <code>@classmethod</code>": "Incorrect. Performance is not the defining difference.",
169+
"<code>@staticmethod</code> is used for computed attributes, while <code>@classmethod</code> is used for class-level attributes": "Incorrect. Computed attributes are defined using <code>@property</code>.",
170170
},
171-
correct_answer="`@staticmethod` does not access the class or instance, while `@classmethod` takes `cls` as its first parameter",
171+
correct_answer="<code>@staticmethod</code> does not access the class or instance, while <code>@classmethod</code> takes <code>cls</code> as its first parameter",
172172
hint="Think about the parameters each decorator uses.",
173173
shuffle=True,
174174
)
@@ -207,9 +207,9 @@ def __init__(self, title=""):
207207
question="What is the purpose of encapsulation in OOP?",
208208
options={
209209
"To bundle data and methods into a single unit": "Correct! Encapsulation bundles data and methods into a single unit.",
210-
"To define abstract methods": "Incorrect. Abstract methods are defined using the `abc` module.",
210+
"To define abstract methods": "Incorrect. Abstract methods are defined using the <code>abc</code> module.",
211211
"To create a class that cannot be inherited": "Incorrect. Encapsulation does not restrict inheritance.",
212-
"To define static methods": "Incorrect. Static methods are defined using the `@staticmethod` decorator.",
212+
"To define static methods": "Incorrect. Static methods are defined using the <code>@staticmethod</code> decorator.",
213213
},
214214
correct_answer="To bundle data and methods into a single unit",
215215
hint="Encapsulation is one of the fundamental principles of OOP.",
@@ -233,11 +233,11 @@ def __init__(self, title=""):
233233
class OopAdvancedAttrsDataclasses(Quiz):
234234
def __init__(self, title=""):
235235
q1 = Question(
236-
question="What is something that `attrs` provides but `dataclasses` doesn't?",
236+
question="What is something that <code>attrs</code> provides but <code>dataclasses</code> doesn't?",
237237
options={
238-
"__init__()": "Both packages automatically generate `__init__()`: `dataclasses` uses the `@dataclass` decorator, while `attrs` uses `@define`.",
239-
"__repr__()": "Both packages automatically generate `__repr__()` to help you easily print a class instance.",
240-
"validators": "Correct! You need to define the attribute as a `field()` and then use the validator decorator.",
238+
"__init__()": "Both packages automatically generate <code>__init__()</code>: <code>dataclasses</code> uses the <code>@dataclass</code> decorator, while <code>attrs</code> uses <code>@define</code>.",
239+
"__repr__()": "Both packages automatically generate <code>__repr__()</code> to help you easily print a class instance.",
240+
"validators": "Correct! You need to define the attribute as a <code>field()</code> and then use the validator decorator.",
241241
},
242242
correct_answer="validators",
243243
hint="",

0 commit comments

Comments
 (0)