[Edu-sig] Topics for CS2
kirby urner
kirby.urner at gmail.com
Fri Jan 23 01:24:05 CET 2009
> I think many of us who grew up with the "old gestalt" had a hard time with the transition to OOP. Maybe the old gestalt still includes administrators, but I would be surprised if it includes high-school students. It did include engineering students a few years ago, when we had a junior-level course in OOP taught in Smalltalk, so the students would be forced to break out of their old habits and do everything in the style of OOP. We still have that course, but now the pre-requisite is a course in Java, and it has morphed to more software-engineering and less pounding on the necessity of OOP.
>
Yes, reminds me of the New Math of the 1960s and the subsequent
backlash, teachers bitter about having their authority undermined by
all this newfangled set notation, unions and intersections of this and
that, a lotta b.s. some of 'em thought, made 'em hate Sputnik, all
that bleeping noise.
But then a lot from that era did stick around, a lot of reforms in
early math curriculum writing (e.g. Dolciani). Newer text books
helped glue together our current algebra thru calculus pipeline, which
colleges still treat as a superhighway through admissions, aka ye old
"Calculus Mountain" of Pycon 2008.
Besides just OO, lambda calculus made the leap to machine executable,
with its functional concepts ("big lambda"). Then we've got Haskell
and like that, so it's not like OO is all alone in this brave new
world of executable logics, anticipated by Leibniz, Ada, and Dr.
Vannevar Bush, the latter writing about hypertext and search engines
in the 1940s if not in those terms.
Left behind on the far side of the digital divide were the calculator
crowd with their "white board" logics -- stuff that only "works" on
paper. Mathematica rescued a lot of that stuff, forcing long overdue
house-cleaning.
In the old typography, f(x) is quite ambiguous as it might as well
mean f * x or f eats x.
In Python, those aren't so different, in that __mul__ eats a name as
its argument. a * b and a(b) are really quite similar, in that ()
triggers __call__, just another __rib__, like __mul__.
We think different now, thanks not just to Smalltalk, but to Apple and
NeXT, all helping to make OO real in the workplace.
High schools languish because there's this "you can't make me
attitude" on the part of professionals, who perceive evolutionary
pressures as "other people telling me what to do". Pride gets in the
way. Not saying this is a unique case. We all tend to get stuck in
the mud of our own generation. That's why we've each got this TTL I
suppose, like in tcp/ip -- a sensible design.
As a result of this languishing, many future engineers must do their
serious studying after hours, in cyberspace, where we yak about SQL,
RSA, Unicode, Ruby... -- all "the good stuff" they're likely not
getting from Portland Public (yet).
> It seems that the "new gestalt" should not require breaking old habits. Objects should be introduced early, the noun.verb syntax is simple, and there is little need for motivation, revelation, or elaborate analogies by the time the students get to crafting their own objects. That seems to be the approach taken by newer texts, and it would have been beneficial for me also. It really wasn't the difficulty of the OOP paradigm that held us back, but the awkwardness of the languages, which perhaps created a need to force-feed and over-sell the idea of OOP, which turned off pragmatic folks like myself. We still have that awkwardness in our intro Java courses, but it seems to have been accepted as a minor inconvenience ("Just memorize this stuff, we'll explain it later.").
>
An early algebra class, lesson plan:
Ms. Jones shows her students how to use their totatives function to
populate a list with Modulo Numbers. Their "closure checker", written
as a Python generator, inspires discussion about groups.
Use a prime modulus next time, talk about fields.
Source code:
from random import choice
def gcd(a,b):
while b:
a, b = b, a % b
return a
def totatives(n):
return [ x for x in range(1, n) if gcd(x, n) == 1]
class Modulo:
m = 12
def __init__(self, n):
self.n = n % Modulo.m
def __mul__(self, other):
return Modulo(self.n * other.n)
def __eq__(self, other):
return self.n == other.n
def __repr__(self):
return str(self.n)
def closure_checker(pool):
while True:
a = choice(pool)
b = choice(pool)
result = a * b
assert result in pool
yield "%s * %s == %s" % (a, b, result)
>>> from algebra import *
>>> p = totatives(12)
>>> thegroup = [Modulo(x) for x in p]
>>> thegroup
[1, 5, 7, 11]
>>> g = closure_checker(thegroup)
>>> next(g)
'5 * 7 == 11'
>>> next(g)
'5 * 7 == 11'
>>> next(g)
'11 * 11 == 1'
>>> next(g)
'5 * 5 == 1'
>>> next(g)
'7 * 7 == 1'
>>> next(g)
'11 * 7 == 5'
The Modulo class is somewhat subtle in that the self.__dict__ n values
are simply integer type, so whereas the __mul__ intercepts, it doesn't
do so recursively i.e. it's Modulo(self.n * other.n) or int * int for
an arg, not Modulo(self * other) -- which goes into a recursive
tailspin.
We'll use these same Modulo Numbers to talk about their powers (**
operator, or __pow__), assert Euler's theorem.
>>Thank you for making your work public and open source in this way.
>>You are kind to offer it up for comments and to handle the feedback
>>graciously, especially given my many different biases.
>
> And thank you for your constructive criticism, which is always appreciated.
>
> -- Dave
Let's hope you continue getting a lot of useful feedback from a
variety of viewpoints.
Kirby
More information about the Edu-sig
mailing list