Curiosity-Ordering and the Challenge of Teaching Python to Well-Seasoned Software Engineers

[ In this post, we welcome a guest -- Marilyn Davis. We're interested in how Python is being and can be taught, so we are excited to welcome her to our blog! ]

by Marilyn Davis, Ph.D.
http://www.pythontrainer.com

Marilyn-pythontrainer

As a Python instructor in corporate environments and at UCSC-Extension in the Silicon Valley I mostly teach to working software engineers, who are already well-practiced in at least one other computer language, and are interested in getting back to work as quickly as possible.

These students are usually well-paid, very smart, and anxious to learn this new language that promises to increase their productivity 300% - 900%, depending on their current language.  And, they want this new knowledge fast: in four days.

To survive as an instructor to these engineers with high expectations, I have to be spot-on, as spot-on as the Python language itself.

Guido Van Rossum invented a language that embodies the real point of any programming task: to communicate with other programmers (in a way that, also, the computer understands).  It is a language that respects a programmer's time more than it respects interpreters, machines, or traditions.  It endeavors to move all the hard work of programming out of the programmers view and keep us focused on our own application and on having fun.

To do justice to this marvelous language, I sought to show maximum respect for the student's time by finding a method that keeps them involved and curious, transforming the hard work of learning into fun.

While I teach, I am always listening to the students to discover "curiosity order" for the Python topics.  When a person is curious, learning happens without effort.

And, as with learning to dance, or absolutely anything, the only way is to "learn by doing".

The answer, then, is to present topics in curiosity-order, as short example-filled lectures; followed by lab exercises that are carefully designed to provide practice with the current concepts, and generate curiosity about the next concepts.

When we start a new lab, it always begins with a discussion of solutions to the previous lab.  Again, we are following the pattern of curiosity, then satisfaction.

Here I discuss the curiosity order for Python.

Python In Curiosity Order

The first skill every programmer wants with every new language is to get the computer to say something.  So the first lab is labeled "Output".

Lab 1 -- Output

       Executing a Python program
       Writing to "stdout"
       Assigning: labels and objects
       "str"ings
       "if", "elif", and "else"
       "while" and another "else"
       Iterating with a "for" loop
       Counting loop with "range"
       Relational and logical operators
       "tuples"

The first program shown displays code blocks delimited by indentation, "else" connected with "while", a "for" loop over a range, "if", "else", "+=", the "%" operator.  It leaves students with questions, answered by subsequent code examples involving variously delimited strings, and filling in the blanks about the two looping devices in Python.  And it ends with a list of Python's relational and logical operators.

We start casually, but immediately, with an explanation of Python's memory model (disguised as an explanation of the assignment operator). And we immediately use the word "iterating" because this particular concept is built into most Python objects.

At times a seasoned programmer will find the logical operators "and", "or", and "not", confusing, expecting these operators to be obscure symbols instead of plain English.

That's how the mind-blowing trip of learning Python begins!

Lab 2 -- Input

       Input from "stdin"
       Factory functions
       Catching an exception:
         yet another "else"
       Formatted strings
       Integer division issue

Next, a programmer wants to accept input from the user, which raises questions about user error, which naturally leads to an understanding of the "try" and "except" keywords for catching exceptions.

And here we fill in the blanks about formatting strings and taking complete control of output.

Lab 3 -- Functions

       Function protocol
       "import" and "reload"
       Modules: "math" & "random"
       Introspection
       Identifier scope
       Default function arguments
       Keyword function arguments

The previous lab exercises left the student with no choice except to create duplicate code, which led to an interest in function protocols. The complete function protocol facilities aren't explained at this point because students do not yet know about dictionaries.  No one seems to notice the omission.

While creating their first function namespaces, it is natural to seek to import other namespaces, i.e. libraries; and to call those libraries' functions.  So here we visit the "math" and "random" libraries and learn to introspect their facilities.

Lab 4 -- Sequences

       Sequence types: "str", "tuple", "list"
       Sequence slicing and other manipulations

By now, students have been using tuples and lists naturally and asking the difference between these two types.  So it is time to meticulously compare and contrast the three sequence types and their facilities, reinforcing the concepts of namespaces, introspection, and iteration.

Lab 5 -- Important Trick

       Module: "sys"
       Important trick:
         "__name__" and "'__main__'"

I like introducing the "sys" module at this point; to give the students the power to read command lines, to get to raw IO, and to know how to stop their program cold with "sys.exit".

After that quick power shot, we slow down to understand how the "__name__" attribute of every namespace can be used to conditionally test the module's code; and simultaneously, make that code useful as a library.

It's a deep and powerful lab, well worth the effort.

Lab 6 -- Comprehensions

       Scope issues
       List comprehensions

To lighten the mood after Lab 5, we practice list comprehensions and other functional programming facilities of Python.  These facilities are easy, powerful, and fun, thereby leaving the students in a good mood.

Lab 7 -- Dictionaries

       Importing with "from"
       Dictionaries

After that mood-lifter, and after being familiar with a plain import, the students are interested to to hear an exhaustive lecture on the danger of the "from" keyword so they can apply it wisely in their own work.  This lecture is also a good review of "mutability", which we've been struggling to understand since Lab 4.

Next comes a study of Python dictionaries, always appreciated for their power and straight-forward implementation; and, another surprising, but very useful, iterating object.

Lab 8 -- File IO

       File I/O
       Module: "os"
       Walking A Directory

Now it is time to manipulate files, which brings in more details about exception handling.  We look at the "os" package and its sub-package "os.path".  We use os to walk a directory structure, once again iterating.

Lab 9 -- Packages

       Modules: "shutil", "tempfile"
       Python Packages

The exercises for the previous lab brought up the need for two libraries that are important to some engineers: "shutil" and "tempfile".  So it is a good opportunity to slip in quick examples of
their use.

A zippy explanation of those facilities at this point is also useful to quicken the pace before the packaging lecture, where we need to go slowly.

Making Python packages is the most difficult and tedious lab we have. The steps that are necessary to build a package are hard to believe until they are experienced.

Lab 10 -- Dynamic Code

       Dynamic Code Generation
       Modules:
         "subprocess"
         "glob"
         "profile"

By now, students are willing to study examples of "subprocess", "glob", and "profile"; both to acquire these particular facilities, and also to have practice with more imports and solidify their understanding of the gist of gluing libraries together.

And, being human, not machines, they are getting weary of too much material, too fast.

It is the right time reward and awaken students by demonstrating "exec", "eval", "setattr", and "getattr", the dynamic code generation facilities.  I say "reward" because these mind-blowing facilities are so exciting, powerful, and Pythonic.  Everyone loves this part.

Lab 11 -- Function Fancies

       Function protocols: variable length argument lists
       Formatted printing using a dictionary for replacement
       Unpacking sequences and dictionaries
       Generators (Optional)
       Decorators (Optional)

The study of the remaining function protocol mechanisms is fun enough to again awaken students.  The dictionary replacement into formatted strings usually brings gasps as students realize how much time and aggravation they will save using this facility.

At this time, I always invite students to take a break, or put their heads down for a nap, as we study the facilities that Guido says are "not for the faint of heart".

Being human, this always gets students' undivided attention. And, as they come to understand these facilities, they are quite blown away.

Lab 12 -- OOP

       Module: "shelve"
       Classes
       Inheritance
       Class variable

When we get to the OOP lab, I like to start with a simple import into a familiar code example from the Dictionary lab.  The "shelve" import, with a few new lines of code, provides persistent memory for a dictionary.  This is ridiculously easy.

This then, puts us in a namespace frame of mind; and we're ready to take a tiny leap from there into OOP with Python.


Lab 13 -- Overriding

       Overriding
       "Has-A" vs "Is-A" relationships

The last lab left people finding ordinary, clumsy ways to print their objects' attributes.  They are delighted and relieved to learn how to override Python's special "__str__" method so that the built in "print", "%s", and "str" will interact with their objects.  From there we learn a few other useful overrides, including how to make our own objects iterable.

Once we get that piece of magic, we are real Python programmers.

At this point, I can't resist explaining a few symbols from Unified Modeling Language because I have been using them all along like they were my own.

Lab 14 -- New Style Classes

       Useful attributes
       Iterators
       New style classes
       Attribute control (Optional)
       "property" (Optional)
       Static methods (Optional)
       Class methods (Optional)
       Diamond inheritance (Optional)

We go a little deeper into more esoteric considerations of OOP, if there is interest.

Lab 15 -- Developer Modules

       Context Manager class
       Module: "unittest"
       Module: "optparse"

We finish with a few simple tools that many good software shops like to use.

Lab 16 -- Wrap Up

       Exceptions
       Namespaces
       Nests
       Pitfalls
       Finding Modules and Help

Finally, we are essentially done and a wrap-up is in order.

We fill in the holes in our knowledge of exceptions, and experience a few Python pitfalls in the lab so that the engineers will not waste any time at work worrying about them.

Time permitting, and if there is interest, we study the ubiquitous regular expression facility and learn the few very useful extensions given to us by Python.

Lab 17 -- re Module - a library example (Optional)

       re - Regular Expressions (Optional)
       Search and replace (Optional)
       Named groups (Optional)

Lab 18 -- re Syntax

       Regular expression syntax (Optional)
       Testing regular expressions (Optional)

By now, each student wants to be left alone to delve into one, or many, of the thousands of libraries for Python: the libraries specific to their own work.  And, as with a person who has been taught to fish: the student no longer needs the teacher.

(C)opyright 2011, Marilyn Davis, Ph.D. http://www.pythontrainer.com 

Marilyn specializes in Python training for corporate clients, either through UCSC Extension Corporate Training Department, where students earn University credit; or independently. She has taught Python for Google, Nokia, Cisco, VMware and more. Even the marketing department at Google took a class.

This is a guest post on the CoderBuddy blog. Check out our new service, CoderBuddy, if you'd like a quick way to start coding Python applications, especially with Django and Google App Engine. Please follow us on Twitter as well!