[Tutor] Teaching computer programming

Christian Tismer tismer@appliedbiometrics.com
Wed, 07 Apr 1999 15:01:48 +0200


John Kleinjans wrote:

<snip/>

> You call it a "script". Is this the same as a "program"? Or is there
> a functional/conceptual difference? I know Python is sometimes
> called a "scripting language"--maybe you can tell me what that is?

There is no princial difference between scripts and programs.
It seems to depend from the application.
Usually, a program which does a specific task for a web
server is called a script.
Sometimes, scripts have the flavor of being a short time solution,
where a program is a more general solution, but this is a matter
of taste.
Scripts tend to be small, and to perform a specific task.
I often generate a script which contains a lot of simple calls
to some functions, where the script is itself generated by
another script. Such scripts can make sense if you want to
perform a specific task, like special renaming or copying
of file trees, generating a number of new Unix accounts and
other stuff, where the OS shell script is sometimes less handy.

I would name a Python program which transferres my starship
account to a different machine a script.
A python program which does no special action but just
defines a bulk of useful functions and objects for, say,
polynomial calculations, is a module. It will usually
be not run alone, but be imported.
A bunch of related modules which sit in a directory
can be called a package. If the directory contains an
__init__.py file, it is a true package, and one can import
from it: import directory.pyfile
Hmm. What is a program?
Guido's idle package, when used as your shell, is for sure
a program. Don't ask me why.

...

> But back to teaching programming with Python.
> 
> >Much less with my grown-ups, there is not much
> >chance to install something completely different, since
> >the brains are very much settled already.
> >And I have to fight the "what is it good for" question
> >all the time, since I'm wasting paid working time.
> 
> So what is a baby good for?  ;-)

Good for teachers who need some success.

...

> But for a person first learning programming, that is far away.
> First crawl, then walk, then run, and fly... then maybe "beam me up,
> Scotty".

Well, let me try to scott you up, Beamie.

[objects]
> >Well, let me dig in here. It is correct to give this simple
> >view to beginners in the first place. But yu need to be aware
> >that this is not very true in a language like Python. Some
> >day later, you must try to get the full truth to them.
> 
> This is why I (John) put this here. I don't know objects--this is one
> reason why I feel that Python is a good next step for me. And I want to
> test ideas with you.

Then let's look at an object.
here comes a commented session:

>>> range(7)
[0, 1, 2, 3, 4, 5, 6]
>>> 

What do we have here?
I called the function "range" with an argument of "7".
But range is more than a function, since everything
is an object. Functions are first class objects, which
means that I can refer to the function itself, not only
by calling it but by spelling its name:

>>> range
<built-in function range>
>>> 

The range object is an object. Instead of calling it, I can
use it itself as an argument for another function. In this
case I use the dir() function to inspect range:

>>> dir(range)
['__doc__', '__name__', '__self__']
>>> 

You can see that range has three attributes which are itself
objects. The "__doc__" attribute is very useful if you want
to know what range does:

>>> print range.__doc__
range([start,] stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
>>> 

Now, let's go back to the beginning of this session where
we called range() to get a list. This time, we do this again,
but assign the result to a variable.

>>> x=range(7)
>>> x
[0, 1, 2, 3, 4, 5, 6]
>>> 

After the assignment, no output is printed. Python prints
the output of expressions, but "x=range(7)" is an assignment
statement. To see the result, I added the expression "x"
which then was printed.

More interesting, we now have the label x tied to the resulting
object of our range(7) call. We nw can plax with this one
as well. Let's have a look:

>>> dir(x)
['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove',
'reverse', 'sort']
>>> 

Whow, what a lot of attributes! Actually, these are all
callables. That means, we see here the list of available
methods which a list understands. Let's call one:

>>> x.reverse()
>>> x
[6, 5, 4, 3, 2, 1, 0]
>>> 

The reverse method changed the list object by reversing the
positions of its elements. This happenes "in-place", and
x.reverse() returned nothing (the None object) which
gets not printed, for brevity.

To relate this to what I said before, let's inspect this
reverse method:

>>> dir(x.reverse)
['__doc__', '__name__', '__self__']
>>> x.reverse.__doc__
'L.reverse() -- reverse *IN PLACE*'
>>> 

You see, I used this method (think "function of an object")
again as a first class object, by not calling it. Instead,
I used the method itself and printed its doc.

> When teaching procedural languages, we need to teach variables
> quite soon, because programs with no variables don't let us do
> interesting things.
> 
> I have this feeling that objects are different ('feeling' because my ideas
> aren't clear, because I don't know, and I know that I don't know). So,
> what should you teach to a person learning programming for the very first
> time? Is there a more productive first look to show them?

I never did. But I would think like this:
Programming means to teach something to a machine in some way.
Now that we have this nice machine with Python, let's teach
it do do something simple: Add one to any number we give it.

>>> def addone(num):
... 	return num+1
... 	
>>> addone(5)
6
>>> 

Great, isn't it?
From here on, you can continue endlessly and keep it fun
to the audience.

And after a while, you can also show how similar this
little function is to other callable objects:

>>> dir(addone)
['__doc__', '__name__', 'func_code', 'func_defaults', 'func_doc',
'func_globals', 'func_name']
>>> 

It is just an object with a number of attributes. You can use it
like any other object. For example, I'll create a list with
quite a mixture of objects and do something with it:

>>> x = [2,3,5, "hello", max, addone]
>>> x[2]+5
10
>>> x[4](3,5)
5
>>> x[-1](3.14)
4.14
>>> len(x[3])
5
>>> 

Step by step: I created a 6 element list. It is indexed from
0 to 5, as always in Python. You can also number from the back,
by using negative indexes.
I took the element with index 2 (which is the 5) and added 5.
Then I took elemend with index 4 which is the function "max",
and called it with two arguments.
Then I used the last element (index -1 in this case) which
happened to be out addone function, and called it.
Then I used the len function to get the length of the string
"hello" which was sitting at index 3.
Got an idea?

[boxes and lables]

> >They will ask you what happened, and you must be prepared
> >to give a good answer which they understand. The list is an
> >object, with a and b being labels sticked at it.
> >This is also true for many of the simple types like string
> >and numbers. They are often shared objects, although in this
> >case it makes no difference since they cannot be changed.
> >If they get that right, they will avoid a lot of mystic
> >errors in their future programs.
> 
> Because we gave to one thing more than one name? We have one
> box, but we put two (or more) labels on it?

Right. And in the example above, we have some functions,
accessible through a list, without the need of any labels.
I could also rename any function simply by assignment:

>>> f2 = addone
>>> f2
<function addone at 15f2d00>
>>> f2(7)
8
>>> f2.__doc__ = "there should be some doc"
>>> addone.__doc__
'there should be some doc'
>>> 

As you can see, the function retains its original name, but that
needn't be the name under which I access it. "f2" and "addone"
are both labels which hld exactly the same object.
I changed the __doc__ attribute of f2 and afterwards
inspected addone's __doc__ attribute which had changed as well,
since it is only one object.

<snip/>

> There's some language here that I don't understand. "first class
> objects", "assigned", "callable", "invoke", "arguments", "inspect",
> "look at its __doc__", "take a dir()"  ...
> well, I know some of them--but students think that "callable" is
> someone with a telephone, and an "argument" is when you don't
> agree, "assigned" is where you sit, and so on. There's a lot of ideas
> inside each of those words. We have to help students build each
> idea, and then help put them together.
> 
> Of course, it's better if they can experience it first. Then when you
> name it, they already know it--then it's easy.

Well, while they play with it, you can carefully inject the 
one or other word to name the things.
While writing "addone(7)", you tell them that you call the function
addone and give it the argument 7.
You might want to avoid "first class" for your first class 101
students, instead you would explain how to fetch the function itself,
as seen above. There isn't much more about it.

I think I touched some of the points you asked.
Now you should play for yourself and feel the difference.

good luck - waiting for the next questions - chris

-- 
Christian Tismer             :^)   <mailto:tismer@appliedbiometrics.com>
Applied Biometrics GmbH      :     Have a break! Take a ride on Python's
Kaiserin-Augusta-Allee 101   :    *Starship* http://starship.python.net
10553 Berlin                 :     PGP key -> http://wwwkeys.pgp.net
PGP Fingerprint       E182 71C7 1A9D 66E9 9D15  D3CC D4D7 93E2 1FAE F6DF
     we're tired of banana software - shipped green, ripens at home