Skip to content

Commit 1a690fb

Browse files
committed
update slides for session 8
1 parent 31b093b commit 1a690fb

File tree

1 file changed

+163
-21
lines changed

1 file changed

+163
-21
lines changed

slides_sources/source/session08.rst

Lines changed: 163 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
.. include:: include.rst
22

3-
**************************************************************************
3+
****************************************************
44
Session Eight: More OO: Properties, Special methods.
5-
**************************************************************************
5+
****************************************************
66

77

88
================
@@ -27,8 +27,6 @@ Lightning Talks Today:
2727

2828
Paul Briant
2929

30-
Brandon Chavis
31-
3230
Jay Raina
3331

3432
Josh Hicks
@@ -48,7 +46,7 @@ The bulk of the homework for the rest of the class will be a personal project:
4846
* I don't require any specific python features (i.e. classes): use
4947
what is appropriate for your project
5048

51-
* Due the Friday after the last class (December 11)
49+
* Due the Sunday after the last class (December 11)
5250

5351
|
5452
| By next week, send me a project proposal: short and sweet.
@@ -75,10 +73,164 @@ And there is no need to check if it's empty before trying to loop through it.
7573
7674
no need for ``!= {}`` -- an empty dict is "Falsey"
7775

78-
**but** no need for that check at all. If the dict (or ist, or tuple) is
76+
**but** no need for that check at all. If the dict (or list, or tuple) is
7977
empty, then the loop is a do-nothing operation:
8078

81-
* notes on Duck Typing: :ref:`exercise_html_renderer` and code review
79+
.. code-block:: python
80+
81+
for key, value in self.attributes.items():
82+
self.atts += ' {}="{}"'.format(key, value)
83+
84+
will not run if self.attributes is an empty dict.
85+
86+
87+
Dynamic typing and class attributes
88+
-----------------------------------
89+
90+
* what happens if we change a class attribute after creating instances??
91+
92+
- let's try ``Element.indent`` ...
93+
94+
* setting an instance attribute overwrites class attributes:
95+
96+
``self.tag =`` overrights the class attribute (sort of!)
97+
98+
Let's experiment with that.
99+
100+
101+
dict as switch
102+
--------------
103+
104+
.. rst-class:: medium
105+
106+
What to use instead of "switch-case"?
107+
108+
A number of languages have a "switch-case" construct::
109+
110+
switch(argument) {
111+
case 0:
112+
return "zero";
113+
case 1:
114+
return "one";
115+
case 2:
116+
return "two";
117+
default:
118+
return "nothing";
119+
};
120+
121+
How do you spell this in python?
122+
123+
``if-elif`` chains
124+
-------------------
125+
126+
The obvious way to spell it is a chain of ``elif`` statements:
127+
128+
.. code-block:: python
129+
130+
if argument == 0:
131+
return "zero"
132+
elif argument == 1:
133+
return "one"
134+
elif argument == 2:
135+
return "two"
136+
else:
137+
return "nothing"
138+
139+
And there is nothing wrong with that, but....
140+
141+
.. nextslide::
142+
143+
The ``elif`` chain is neither elegant nor efficient.
144+
145+
There are a number of ways to spell it in python -- one elegant one is to use a dict:
146+
147+
.. code-block:: python
148+
149+
arg_dict = {0:"zero", 1:"one", 2: "two"}
150+
dict.get(argument, "nothing")
151+
152+
Simple, elegant, and fast.
153+
154+
You can do a dispatch table by putting functions as the value.
155+
156+
Example: Chris' mailroom2 solution.
157+
158+
Polymorphism as switch:
159+
-----------------------
160+
161+
It turns out that a lot of uses of switch-case in non-OO languages is to
162+
change behaviour depending on teh type of object being worked on::
163+
164+
switch(object.tag) {
165+
case 'html':
166+
render_html_element;
167+
case 'p':
168+
render_p_element;
169+
...
170+
171+
I saw some of this in the html renderer:
172+
173+
.. nextslide::
174+
175+
.. code-block:: python
176+
177+
def render(out_file, ind=""):
178+
....
179+
if self.tag == 'html':
180+
tag = "<html>"
181+
end_tag = "</html>"
182+
elif self.tag == 'p':
183+
tag = "<p>"
184+
end_tag = "</p>"
185+
186+
This will work, of course, but:
187+
188+
* it means you need to know every tag that you might render when you write this render method.
189+
190+
* In a more complex system, you will need to go update all sorts of things all over teh place when you add a tag.
191+
192+
* It means anyone extending the system with more tags needs to edit the core base class.
193+
194+
Polymorphism
195+
------------
196+
197+
The alternative is to use polymorphism:
198+
199+
Your ``render()`` method doesn't need to know what all the objects are
200+
that it may need to render.
201+
202+
All it needs to know is that they all will have a method
203+
that does the right thing.
204+
205+
So the above becomes, simply:
206+
207+
.. code-block:: python
208+
209+
def render(out_file, ind=""):
210+
....
211+
tag, end_tag = self.make_tags()
212+
213+
This is known as polymorphism, because many different objects are behave
214+
the same way.
215+
216+
.. nextslide::
217+
218+
This is usally handled by subclassing, so they all get all teh same
219+
methods by default, and you only need to specialize the ones that need it.
220+
221+
But in Python -- it can be done with duck-typing instead, as the TextWrapper example.
222+
223+
Duck typing and EAFP
224+
--------------------
225+
226+
* notes on Duck Typing: :ref:`exercise_html_renderer`
227+
228+
* put the ``except`` as close as you can to where you expect an exception to be raised!
229+
230+
* Let's look at a couple ways to do that.
231+
232+
Code Review
233+
-----------
82234

83235
* anyone stuck that wants to work through your code?
84236

@@ -90,10 +242,12 @@ Lightning Talks:
90242
.. rst-class:: medium
91243

92244
|
93-
| Paul Briant
245+
| Paul Briant
94246
|
95-
| Brandon Chavis
247+
| Jay Raina
96248
|
249+
| Josh Hicks
250+
97251

98252

99253
==========
@@ -261,17 +415,6 @@ For now, Let's do steps 1-4 of:
261415

262416
:ref:`exercise_circle_class`
263417

264-
Lightning talks:
265-
-----------------
266-
267-
.. rst-class:: medium
268-
269-
|
270-
| Jay N Raina
271-
|
272-
| Josh Hicks
273-
|
274-
275418

276419
========================
277420
Static and Class Methods
@@ -289,7 +432,6 @@ Static and Class Methods
289432
And you've seen how you can call *unbound* methods on a class object so
290433
long as you pass an instance of that class as the first argument.
291434

292-
|
293435

294436
.. rst-class:: centered
295437

0 commit comments

Comments
 (0)