
I want to suggest that the much-used metaphor (by me included): "class is a blueprint, with instances the buildings made from it" (houses usually) is a good start, but not nuanced enough to take us all the way to the end of our story. These days I've taken a two pronged approach: yes, OO is meant to model how we think normally, about things with properties and behaviors. "The language gets out of the way and lets you think in terms you're already familiar with, from work" and such PR, some truth in it... ... However (big pause), OO also is it's own knowledge domain with its own concepts and those are better faced directly and dealt with than dismissed as mere noise. The blueprint metaphor, in being so simple, is maybe too simple, and therefore dismissive, at least if left in place for too long. So yes, OO has its cost, the knowledge domain that is OO with all its twisted tails of multiple inheritance and the method resolution order. But learning that little overhead is more than worth the price of admission (the PR again). The whole idea of inheritance, and of static and class methods, undermines this simplistic beginning of "blueprint" and so could become corrosive vectors of entropy (leaking sense), if not contained within more fitting metaphors. I like to say the class is a "mother ship" and serves as a kind of "home base" or "platform". How about an "amusement park"? Each self brings its little __dict__ to the theme park, but all the "rides" (the "stuff happening") are anchored in the class's __dict__. The self parameter is like an empty seat in a ride, which the rider's self then fills. This so-called "blueprint" is where the methods are happening, which is so not what it's like in the case of houses. The many instances (the selves) are but little bags of state, little "var stashes" (uh oh, JavaScript creeping in... :-D). Anyway, ya catch my drift, right? If we over-stress the blueprint metaphor they'll not be as open minded about blueprints having their own "batteries included" and doing stuff on their own, no "selves" need apply in some cases (not all methods need a self). Literal blueprints don't light up and do stuff all on their own like that. Our classes often behave a lot more like objects with a life of their own. ... and that's true of course as they're each instances of the type "type", one more example of what that "bag o' tricks" we called 'a class' might look like. Kirby

I like to say the class is a "mother ship" and serves as a kind of "home base" or "platform". How about an "amusement park"? ...
I don't think any of that is any better. When explaining OOP, I have two points I try to drive home. 0. you can do anything in any language any way you please. OOP does not give you any new capabilities, it is just a way of keeping your code organized and readable. 1. I describe a parent class and some of the subclasses used in my video processing system parent: find a list of videos to work on, iterate over the list, self.work() on each one. work is defined in the subclasses: subclass 1 - encode subclass 2 - upload subclass 3 - email the URL to the presenter On Wed, Apr 20, 2016 at 3:53 PM, kirby urner <kirby.urner@gmail.com> wrote:
I want to suggest that the much-used metaphor (by me included):
"class is a blueprint, with instances the buildings made from it"
(houses usually) is a good start, but not nuanced enough to take us all the way to the end of our story.
These days I've taken a two pronged approach: yes, OO is meant to model how we think normally, about things with properties and behaviors.
"The language gets out of the way and lets you think in terms you're already familiar with, from work" and such PR, some truth in it...
... However (big pause), OO also is it's own knowledge domain with its own concepts and those are better faced directly and dealt with than dismissed as mere noise.
The blueprint metaphor, in being so simple, is maybe too simple, and therefore dismissive, at least if left in place for too long.
So yes, OO has its cost, the knowledge domain that is OO with all its twisted tails of multiple inheritance and the method resolution order.
But learning that little overhead is more than worth the price of admission (the PR again).
The whole idea of inheritance, and of static and class methods, undermines this simplistic beginning of "blueprint" and so could become corrosive vectors of entropy (leaking sense), if not contained within more fitting metaphors.
I like to say the class is a "mother ship" and serves as a kind of "home base" or "platform". How about an "amusement park"?
Each self brings its little __dict__ to the theme park, but all the "rides" (the "stuff happening") are anchored in the class's __dict__. The self parameter is like an empty seat in a ride, which the rider's self then fills.
This so-called "blueprint" is where the methods are happening, which is so not what it's like in the case of houses.
The many instances (the selves) are but little bags of state, little "var stashes" (uh oh, JavaScript creeping in... :-D).
Anyway, ya catch my drift, right?
If we over-stress the blueprint metaphor they'll not be as open minded about blueprints having their own "batteries included" and doing stuff on their own, no "selves" need apply in some cases (not all methods need a self).
Literal blueprints don't light up and do stuff all on their own like that.
Our classes often behave a lot more like objects with a life of their own.
... and that's true of course as they're each instances of the type "type", one more example of what that "bag o' tricks" we called 'a class' might look like.
Kirby
_______________________________________________ Edu-sig mailing list Edu-sig@python.org https://mail.python.org/mailman/listinfo/edu-sig

Sounds like we agree Carl. The "blueprint" metaphor is not that great. It keeps us from thinking more fluently about OO after awhile. A straitjacket. Kirby

Our classes often behave a lot more like objects with a life of their own.
For example I might do something like this. One could argue this is not describing an "is a" relationship i.e. how can each member of the landing party be a "ship". I'm saying we internalize our type inheritance and "is a" might not apply in quite the same way in this particular knowledge domain. Keep an open mind. # -*- coding: utf-8 -*- """ Created on Wed Apr 20 14:56:55 2016 @author: Kirby Urner 10 Cloverfield Lane, Nowhere, Nebraska """ import random class MotherShip: attack_mode = False # note to self, need to learn more Earthling names earthling_names = ['Alan', 'Helga', 'Ahmed', 'Jerome', 'Achio', 'Kelly'] @classmethod def toggle(M): if M.attack_mode: M.attack_mode = False; else: M.attack_mode = True @classmethod def spawn(M, n): # size of pod pod = [] for _ in range(n): pod.append(M()) # blessings return pod def __init__(self): # rarely used except by spawn self.name = random.choice(self.__class__.earthling_names) def __repr__(self): return self.name # we each feel empowered by the whole! # ship lands... landing_party = MotherShip.spawn(10) # spawn a swarm of little selves print("Landing Party:", landing_party) print("Hostile?: ", landing_party[3].attack_mode) # what hath triggered their ire? Everything was going so well... MotherShip.toggle() # each self has a shared collective hive mind print("Hostile?: ", landing_party[3].attack_mode) # uh oh... === Anaconda.console (blank rows added for readability): runfile('/Users/kurner/Documents/classroom_labs/martians_landed.py', wdir='/Users/kurner/Documents/classroom_labs') Landing Party: [Kelly, Kelly, Achio, Kelly, Jerome, Alan, Alan, Helga, Achio, Alan] Hostile?: False < some triggering event? > Hostile?: True

I also don't show real code right away. I scribble on the white board. class MotherShip; ... yeah, that's correct, but to me it looks too wordy for what is a fairly simple concept. hmm... simple? ok, inheritance is the concept that I think is fairly simple if you don't dive into all the other neat stuff. Once they see the elegance of talks=self.get_list_of_talks_to_process() for talk in talks: self.work(talk) their eyes light up and I let them bask in the benefits of elegant programming. After that, I think they will be receptive to learn all that other neat stuff on their own. On Wed, Apr 20, 2016 at 5:19 PM, kirby urner <kirby.urner@gmail.com> wrote:
Our classes often behave a lot more like objects with a life of their own.
For example I might do something like this. One could argue this is not describing an "is a" relationship i.e. how can each member of the landing party be a "ship".
I'm saying we internalize our type inheritance and "is a" might not apply in quite the same way in this particular knowledge domain. Keep an open mind.
# -*- coding: utf-8 -*- """ Created on Wed Apr 20 14:56:55 2016
@author: Kirby Urner
10 Cloverfield Lane, Nowhere, Nebraska
""" import random
class MotherShip:
attack_mode = False # note to self, need to learn more Earthling names earthling_names = ['Alan', 'Helga', 'Ahmed', 'Jerome', 'Achio', 'Kelly']
@classmethod def toggle(M): if M.attack_mode: M.attack_mode = False; else: M.attack_mode = True
@classmethod def spawn(M, n): # size of pod pod = [] for _ in range(n): pod.append(M()) # blessings return pod
def __init__(self): # rarely used except by spawn self.name = random.choice(self.__class__.earthling_names)
def __repr__(self): return self.name # we each feel empowered by the whole!
# ship lands...
landing_party = MotherShip.spawn(10) # spawn a swarm of little selves print("Landing Party:", landing_party)
print("Hostile?: ", landing_party[3].attack_mode)
# what hath triggered their ire? Everything was going so well...
MotherShip.toggle() # each self has a shared collective hive mind
print("Hostile?: ", landing_party[3].attack_mode) # uh oh...
=== Anaconda.console (blank rows added for readability):
runfile('/Users/kurner/Documents/classroom_labs/martians_landed.py', wdir='/Users/kurner/Documents/classroom_labs')
Landing Party: [Kelly, Kelly, Achio, Kelly, Jerome, Alan, Alan, Helga, Achio, Alan]
Hostile?: False
< some triggering event? >
Hostile?: True
_______________________________________________ Edu-sig mailing list Edu-sig@python.org https://mail.python.org/mailman/listinfo/edu-sig

On Wed, Apr 20, 2016 at 3:58 PM, Carl Karsten <carl@nextdayvideo.com> wrote:
I also don't show real code right away. I scribble on the white board.
Yeah, I think we're just talking about different points along the journey. I'm fine with Blueprint and/or Cookie Cutter at first, as the predominant metaphor, and not too much code. But then in my code school boot camp model they might have 12 weeks x 40 hours to learn all this JavaScript -> Other Language -> Python -> JavaScript (they go round and round in a spiral in this curriculum). So down the road a ways, when it's important to understand more of the Python grammar, I might move away from Blueprint and Cookie Cutter to MotherShip and AmusementPark. [ The version below keeps statistics at the class level (turnstyles...). ] I like your relating programming to processing video. I'm working to forge that connection more explicitly myself. The idea of "frames" (as in time frames, frames of file, intervals of action) figures in. Kirby # -*- coding: utf-8 -*- """ Created on Wed Apr 20 16:44:44 2016 @author: Kirby Urner Carnival Guy (aka "geek", luvs chicken) version 0.2 (copyleft) MIT License """ import random class Blech(Exception): pass class AmusementPark: # euphemism for carnival ferris_riders = 0 coaster_riders = 0 riders_born = 0 @classmethod def report(A): return "Ferris rides: {}\nCoaster rides: {}\nRiders: {}".\ format(A.ferris_riders, A.coaster_riders, A.riders_born) @classmethod def ferris_wheel(A, me): A.ferris_riders += 1 me.sick = False return me @classmethod def roller_coaster(A, me): A.coaster_riders += 1 # moral: don't eat before riding the roller coaster if len(me.stomach) > 0: me.sick = True # sick state persists me.stomach = [] # ... this should help though return me @classmethod def make_rider(A): A.riders_born += 1 return A() def __init__(self): # born to ride self.stomach = [] self.sick = False def __call__(self, food): # born to eat if self.sick: raise Blech("too sick to eat") self.stomach.append(food) def __repr__(self): if self.sick: return "I don't feel so good" else: return "I feel fine" A1 = AmusementPark alice = A1.make_rider() # a child of her profession bob = A1.make_rider() carl = A1.make_rider() def time_frame(): while True: rider = random.choice([alice, bob, carl]) ride = random.choice([A1.ferris_wheel, A1.roller_coaster]) ride(rider) yield A1 frame = time_frame() for time_tick in range(10): next(frame) print(A1.report())

I'm working to forge that connection more explicitly myself. The idea of
"frames" (as in time frames, frames of file, intervals of action) figures in.
Kirby
"frames of film" I meant to say (not "file"). The browser window frame = puppet theater is part of it. JavaScript pulls the string of its "DOM-puppets". Then there's a "back stage" where the client makes calls to the server via whatever protocols.... ...while the show on stage continues, lets hope smoothly (at whatever frame rate). Kirby

On Wed, Apr 20, 2016 at 1:53 PM, kirby urner <kirby.urner@gmail.com> wrote: << SNIP >>
I like to say the class is a "mother ship" and serves as a kind of "home base" or "platform". How about an "amusement park"?
Another one to limber up on: # -*- coding: utf-8 -*- """ Created on Wed Apr 20 15:27:35 2016 @author: Kirby Urner Carnival Guy (aka "geek", luvs chicken) """ class Blech(Exception): pass class AmusementPark: # euphemism for carnival @classmethod def ferris_wheel(A, me): me.sick = False return me @classmethod def roller_coaster(A, me): # moral: don't eat before riding the roller coaster if len(me.stomach) > 0: me.sick = True # sick state persists me.stomach = [] # ... this should help though return me @classmethod def make_rider(A): return A() def __init__(self): # born to ride self.stomach = [] self.sick = False def __call__(self, food): # born to eat if self.sick: raise Blech("too sick to eat") self.stomach.append(food) def __repr__(self): if self.sick: return "I don't feel so good" else: return "I feel fine" A1 = AmusementPark alice = A1.make_rider() # a child of her profession A1.ferris_wheel(alice) print("Sick after ferris wheel:", alice) # time to eat! try: alice("cotton candy") alice("diet doctor pepper") alice("hot dog with onions") except: print("I'll eat later...") A1.roller_coaster(alice) print("Sick after roller coaster?", alice) # it always happens # time to eat! try: alice("popcorn") alice("gum drops") alice("another diet doctor pepper") except: print("I'll eat later...") Runtime: runfile('/Users/kurner/Documents/classroom_labs/having_fun.py', wdir='/Users/kurner/Documents/classroom_labs') Sick after ferris wheel: False Sick after roller coaster? True I'll eat later...

Hi Kirby, You may be interested in Dijkstra's take on teaching via metaphor: https://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1036.html I am not sure exactly how it applies to your case. It seems to me that OO tends to get taught in terms of the mechanisms present in OO languages and how that is implemented. Things like the notion of inheritance, polymorphism and the idea of putting behaviour and data together. When I learnt OO we were taught about concepts, how they're defined by intention/extension and how they can be reasoned about in terms of set theory. We were taught about how to produce OO analysis models. That shows you how to think about a problem. Language features and how they work are—out of necessity—a very limited shadow of such models. Language features are not even necessary for implementing an OO model - you can happily reap OO benefits writing C code. My feeling is teaching OO by language features is like giving people a physical tool without giving them the mental tool that gives direction on how to and why and where use it (or not). One nice book that does explain the fundamentals really well IMHO is "Object-Oriented Methods: A Foundation" by James Martin/James Odell. http://www.amazon.com/Object-Oriented-Methods-Foundation-UML-2nd/dp/01390559... Regards - Iwan -- Reahl, the Python only web framework: http://www.reahl.org

On Wed, Apr 20, 2016 at 11:00 PM, Iwan Vosloo <iwan@reahl.org> wrote:
Hi Kirby,
You may be interested in Dijkstra's take on teaching via metaphor: https://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1036.html I am not sure exactly how it applies to your case.
I'm going through this. Interesting. I've not plumbed his writing much. There're some hours of me on-line doing a workshop in Chicago where I cite the guy, as the father of structured programming (new idea at the time, the Age of Spaghetti Code). Steve Holden, co-presenter, interjects that Dijkstra's medicine could be hard to swallow given he had no bedside manner (paraphrase). [1] I just heard the joke about arrogance being measured in nano-dijkstras (some Youtube from the Javascript culture). Anyway, I'm glad for the link, so thank you. What about coding just to experiment, as an art project? He seems very fixated on his model program with its "functional specification" along with some "proof". But some styles of coding are much more like experimenting in a lab, just trying stuff, not knowing the result in advance. He seems to have a rather narrow definition of what it means to program? The languages were lower level back then, is maybe part of it. It seems to me that OO tends to get taught in terms of the mechanisms
present in OO languages and how that is implemented. Things like the notion of inheritance, polymorphism and the idea of putting behaviour and data together.
I really want to anchor OO in human language (human-executable: Hx). It's in English that we have "things" (etymology is closer to "meetup" but that's another story). Things have properties and behaviors. Not news. Plus we also understand about inheritance, not only in agronomy and animal husbandry (including of humans by humans) but in terms of cultural heritage (memes not just genes). These metaphors are ingrained in how we think about everything and for all the "radical novelty" a computer may represent, sometimes the goal is not to be amazed and agog at the stunning genius of computer architecture, and to get on with cell biology, the real focus, the work at hand. [3] To that end, the fact that an OO language that lets us start right away with "class Cell:" (immediately and not after two years of computer science), is a big relief, a boon, a godsend. What I want is for students to daydream about their own lives in Python code. I go to start my car, there's an exception. How do I handle that exception? Is the battery dead (raise BatteryDead)? Or did the key break off? (raise KeyBreak). The latter is pretty rare but happened to me in the code school parking lot. The next day, I shared a little program about it. https://github.com/4dsolutions/Python5/blob/master/carkeys.py Thinking in Python includes thinking about ordinary everyday things in Python. It doesn't mean fantasizing about the guts of a Von Neumann architecture computer unless you really need that to be your knowledge domain i.e. that's your line of work. Lets think about Cells and Proteins in Python. What attributes do they have, what behaviors? And what inherits from what? https://github.com/4dsolutions/Python5/blob/master/genetics.py (just native Python types here, no use of class semantics) Lets talk about ancestral trees in the discipline at hand. Are there any? OO is a way of analyzing a knowledge domain D into an expressive language L that is also machine executable (Mx). Mx <----- L -----> Hx Fig. 1: a spectrum
When I learnt OO we were taught about concepts, how they're defined by intention/extension and how they can be reasoned about in terms of set theory. We were taught about how to produce OO analysis models. That shows you how to think about a problem.
Language features and how they work are—out of necessity—a very limited shadow of such models. Language features are not even necessary for implementing an OO model - you can happily reap OO benefits writing C code.
Indeed, given Python is just a pile of C code (some Pythons that is).
My feeling is teaching OO by language features is like giving people a physical tool without giving them the mental tool that gives direction on how to and why and where use it (or not).
I'm suggesting Human Language already has a lot of what we need in its toolbox. For all Dijkstra's criticizing how we dumb it down with misshapen metaphors, OO is intentionally and by design aimed it implementing everyday experiential concepts we learn in Hx languages -- way before we try our hand at using Ls closer to the Mx end of the spectrum (see Fig. 1). Concrete (computable) <----- L -----> Speculative (non-computable) Fig. 2: same spectrum
One nice book that does explain the fundamentals really well IMHO is "Object-Oriented Methods: A Foundation" by James Martin/James Odell. http://www.amazon.com/Object-Oriented-Methods-Foundation-UML-2nd/dp/01390559...
Regards - Iwan
I'll check this out as well. I have Safari On-Line, maybe it's there. Kirby [1] http://worldgame.blogspot.com/2009/03/urner-workshop.html

On Thu, Apr 21, 2016 at 11:23 AM, kirby urner <kirby.urner@gmail.com> wrote: << SNIP >>
Thinking in Python includes thinking about ordinary everyday things in Python. It doesn't mean fantasizing about the guts of a Von Neumann architecture computer unless you really need that to be your knowledge domain i.e. that's your line of work.
Since posting the above some weeks back, I've been informed that "Von Neumann architecture computer" is maybe not the best jargon to be spreading around. Source: https://vimeo.com/145672920 about 4:55 into it. I've watched quite a few of these Eric Smith vimeos. I've learned a lot. Given I'm flying the lambda calculus banner on Mathfuture, trail-blazing a new track, it behooves me to catch up on what that means in more detail, Y combinator and all that. ;-D Kirby <http://worldgame.blogspot.com/2009/03/urner-workshop.html>
participants (3)
-
Carl Karsten
-
Iwan Vosloo
-
kirby urner