[Edu-sig] Re Python's role (one of them)

Kirby Urner pdx4d@teleport.com
Mon, 01 May 2000 12:10:02 -0700


Although I think David wrote intelligently and accurately 
about the "movable line" between "intelligible code" 
versus "black box" (with an API/interface between the
two), there's a way to generalize this which takes us 
out of the realm of computer codes and hardware.

I think where I've mostly come down in my use of Python 
in the curriculum (not to the exclusion of, nor at the 
expense of other approaches), is to help deobfuscate and 
demystify what may come across, at first (and even second)
reading, as rather cryptic mathematical notations.

In other words, the "black box" I want to shine a light 
into, is pre-computer in origin, is "legacy code" on 
paper, not in some magnetic or laser-pitted medium 
(although that's where a lot of it will be going).

I think many individuals besides myself have sometimes
found the FORTRAN or BASIC implementation of some algorithm 
really clarifies what seemed rather inaccessible when 
just encoded as text book squiggles, in some notation 
advertised as "internationally accepted" but which is 
nevertheless rather "crypto-compressed" plus infested 
with ancient greek symbols.

But in the early days, computer languages were still 
too mired in machine dependent details, had too much syntax 
devoted to irrelevant hardware concerns, to really rise 
to the level of an alternative "math notation" -- a set 
of symbols suitable for both explaining and implementing
math-related concepts.

This really started to change when core syntax was distilled 
from platform concerns, the latter being encapsulated in 
libraries, hidden away from programmers. This was done 
in the name of "portability" and C is a primary example 
of this architecture.

A major pioneer in bridging between "computer langauge" and 
"math notation" was Kenneth Iverson's A Programming Language 
(APL).  This language originally evolved as a chalkboard 
notation, and looks an awful lot like some geeky ancient 
greek -- lots of specialized symbols that serve as primitive 
operators in an interpretive, interactive environment.  

APL was the first real computer language I ever learned (not 
counting my experience with the HP65 in the Philippines). 
Princeton had APL terminals scattered around campus, including 
in my dorm and Firestone Library (this was 1976) and I taught 
it to myself, outside of any formal computer class (although 
I enrolled in quite a few of those as well).

In a lot of ways, I realize I'm coming at Python as a kind 
of APL.  The range() primitive is a lot like the lower-case i 
(I don't remember all those symbols any more).  And I'm 
looking at Python as a kind of math notation, another way 
to get across what's going on in that "black box" of vector 
algebra, for example.

Like, lets look at vectors.  The curriculum as presently 
designed does number lines and Cartesian coordinates without 
mentioning vectors.  Then it backs up and goes over the same 
territory again, this time with the vector concept phased in.  

Seems wasteful and redundant in a lot of ways, plus has the 
effect of making vectors seem a bit superfluous -- like why 
do we need them now if we didn't need them then?  We're 
doing the same 3D traces in space, after all.  Or, conversely,
if they were so important from the beginning, why were they 
kept from us until now?

I think the curriculum contains a lot of these twists and 
turns, which accrue through history by happenstance, and 
then stay there.  People don't really go back and sort it 
all out, rationalize the structure.  Like, I think we really 
_could_ do vectors right from the beginning, and Python's 
object-orientation makes this especially easy:  vectors 
are a kind of object, contain data and methods.  Here is 
the data, here are the methods, and we're done.  Pretty 
straightforward, especially when kids are already quite 
familiar with language primitives like tuples, lists, 
range() etc.

Consider the Wolfram Research web page on the tetrahedron, 
we find the following formula for its volume:

  V = (1/6)[a dot (b cross c)]        [1]

In Python, if we've already defined our vector object,
we can write:

  V = (1.0/6.0) * ( a.dot(b.cross(c)) )

Not that much different.  We see a,b,c as objects, with
dot and cross as methods internal to these objects.  Inside 
the Python vector class, we find the corresponding function 
defs:

def dot(self,v1):
    # return the dot product of self with another vector
    # return a scalar
    scalar = 0
    for i in range(3):
        scalar = scalar + v1.coords[i] * self.coords[i]
    return scalar

def cross(self,v1):
    # return the cross product of self with another vector
    # return a vector
    newcoords = [0,0,0]
    newcoords[0] = self.coords[1]*v1.coords[2]-self.coords[2]*v1.coords[1]
    newcoords[1] = self.coords[2]*v1.coords[0]-self.coords[0]*v1.coords[2]
    newcoords[2] = self.coords[0]*v1.coords[1]-self.coords[1]*v1.coords[0]
    return Vector(newcoords)

It's clear, from reading the above, that dot returns a scalar, 
while cross returns a vector.  coords is just a 3-member tuple, 
storing the (x,y,z) coordinates of vector v such that v = xi + yj + zk 
where i,j,k are the 3 unit vectors along the x,y and z axes of 
the Cartesian apparatus.

We instantiate vectors like this:

>>> v1 = Vector((2,1,0))
>>> v2 = Vector((-1,0,3))

and then use our methods:

>>> v1.angle(v2)
106.42994
>>> v1.dot(v2)
-2
>>> v3 = v1.cross(v2)
>>> v3.coords
(3, -6, 1)
>>> v3.dot(v1)
0
>>> v3.dot(v2)
0

Students learn that v1.cross(v2) returns a vector pependicular to 
both v1 and v2, and that a dot product of 0 indicates this orthogonal 
relationship in Cartesian space i.e. v3.dot(v1) and v3.dot(v2) 
are both 0, as expected, given v3 is orthogonal to both v1 and v2.

Notice that we haven't really done much with graphics so far.
That's all part of the presentation of course, but a lot of the 
insights come from just working at the command line, putting 
in values, and getting values back.  You have that immediate 
reinforcement of an answer and/or error (both kinds of 
feedback helpful).

In sum, where I see Python being useful is as a way of making 
crypto-compressed math notations more understandable. Familiarity 
with the Python language will give students was to see the 
vectors "spelled out" in familiar object-oriented notation, 
and to operate with them interactively.  

With this kind of background, operations like dot and cross 
product will seem like old friends even at the high school
level, and vector calculus concepts like grad, div and curl 
will not present the high hurdles they do today, given the 
twisted/tangled obstacle course we present, as if this mess 
had anything much to do with training clear thinkers [2].

Kirby

[1] http://mathworld.wolfram.com/Tetrahedron.html

[2] in fact, the present-day math curriclum produces the 
    opposite, and thereby feeds bureaucracies, which 
    thrive on keeping _all_ thinking, including math-
    related, as "fuzzy" as possible (because a chief 
    function of bureaucracies is to give phonies a safe 
    place to hide their incompetence from scrutiny)