views:

228

answers:

5

I am teaching Python to undergraduate math majors. I am interested in the optimal order in which students should be introduced to various Python concepts. In my view, at each stage the students should be able to solve a non-trivial programming problem using only the tools available at that time. Each new tool should enable a simpler solution to a familiar problem. A selection of numerous concepts available in Python is essential in order to keep students focused. They should also motivated and should appreciate each newly mastered tool without too much memorization. Here are some specific questions:

  • For instance, my predecessor introduced lists before strings. I think the opposite is a better solution.
  • Should function definitions be introduced at the very beginning or after mastering basic structured programming ideas, such as decisions (if) and loops (while)?
  • Should sets be introduced before dictionaries?
  • Is it better to introduce reading and writing files early in the course or should one use input and print for most of the course?

Any suggestions with explanations are most welcome.

Edit: In high school the students were introduced to computers. A few of them learned how to program. Prior to this they had a course, covering word, excel, powerpoint, html, latex, a taste of Mathematica, but no programming. 5 years ago I used Mathematica in this course and the follow-up course uses C and later Java. Now I teach introduction to Python and in the follow-up course my colleague teaches object-oriented programming in Python. Later a student may take special courses on data structures, algorithms, optimization and in some elective courses they learn on their own Mathematica, Matlab and R.

+1  A: 

This really depends on how much programming they know, but I've seen R successfully introduced to people with absolutely no knowledge of programming successfully. I'm going to guess that they don't have much knowledge of programming.

This may sound obvious, but teach only as much of the language as they need to solve the problem, don't get in too deep with "proper" and efficient coding styles, you can start working this in slowly once your students have some understanding, e.g. comment on style, but don't be too strict on it.

To solve a problem you have to understand at least some basic part of the language. I'm going to assume that everything you do will likely be contained in a single line and namespacing, modules, performance, etc really won't be top priorities.

Start by getting them setup with a development environment, and create a simple program for them to run. Make sure they have an environment that has everything they need (if they need numpy, walk them through installation), walk them through starting a program from the command line, and of course have an editor that's easy to use (e.g. Eclipse + PyDev, probably too complicated). The most frustrating thing is when you can't get an working environment. Pray you don't have to support windows or don't have many libraries to contend with.

Once you have that, introduce them to the language in general. Cover types and the subtle problems one may encounter, e.g.:

>>> 1/2
0
>>> 1./2
0.5

I would even instill a habit of making everything floats. Introduce strings for output and how to cast that output if you want it on the same line. Cover operations and logic, then provide an introduction to "functions," making sure to create a distinction between the mathematical equivalent. I think command flow structures should be fairly simple and include the simple ones (if, else, elif, possibly while).

At this point they should be able to create a simple program to solve a simple problem. Start building on this, introducing more complex command flows, more complex data types (lists, sets, dicts), possibly iterators and generators (be careful with these, they can be a pain and you may not need them).

Edit:

I forgot to touch on input and output. I would provide a simple framework your students can use for this, if you want to. The command line should be sufficient unless you want to trace what's happening in which case a file output is much more reasonable. Alternatively, piping output to a file works just as well.

I think sets are much more mathematically relevant (and useful!) then dicts are, and would introduce them first.

Aea
I agree with you that problem-solving is the most important motivation for learning programming. However, if I had to choose between sets and dictionaries I would choose the one that is more powerful.
Tomaž Pisanski
+13  A: 

After some try / except as a teacher, I chose to stick to something like:

(starting from nothing, adjust to their level)

  1. Shortly, what is Python and what you can do with it. Skip the speech on technical stuff and focus on what they want to do : music, GUI, Web site, renaming files, etc.
  2. Installing Python, running the interpreter. If you can, use iPython.
  3. Variables, basic strings and print().
  4. Int and types (including type errors and casting).
  5. Basic calculus. Show them 1 / 0, 10 / 3 but don't bother them with details.
  6. Putting calculus results in variables.
  7. Using variables in calculus.
  8. String formating with %. Show only "%s", it's enough and always works. Always use a tuple (with an ending coma), even if it contains only one item.
  9. Lists, indexing, slicing and common errors. Then show tuples as frozen lists (and casting). Show that then can contain each others. Make them work on that until they master it perfectly: this is very, very important.
  10. Dictionaries, with common errors. Nesting with tuples and lists. Insist on the last point.
  11. For loop on strings, then lists, then tuples, then dictionaries.
  12. For loop on nested types. Be nasty. Take your time. Knowing that part well changes everything.
  13. Dictionary items(), values() and keys().
  14. Reading files using for, including IOErrors.
  15. Writing files.
  16. Using methods. Use a string as an example showing strip(), lower(), split(), etc. Don't explain OOP, just how to use a method. Use the world "method" a lot from now.
  17. Creating a module file and using it. One module only. Everything in it.
  18. Functions (only with return, no print(). Forbid print() in functions).
  19. Function parameters.
  20. Named parameters.
  21. Default value parameters.
  22. Try / Except and exceptions.
  23. Import and creation of your own directory modules. Show all the special cases (it takes way more time to explain it than you think).
  24. Demonstrate some standard modules (but don't spend too much time on it, it's just to show): datetime, string, os and sys. Avoid abstract stuffs like itertools, they are a coder dream but a student nightmare.

After that you can bring OOP on the table, but it a bit more complicated. Use strings, lists and files to introduce the notion of object. When they got it, start with classes. Then may the force be with you :-)

It is tempting to use print in functions to show how it works, and even more tempting to use raw_input. You should avoid it at all cost. The first one makes it very difficult to bring the concept of a "returned value", the second hides the real flow of a program and students have a hard time to understand that you need to chain functions, not ask the user for every value you need.

Generally, choose one method that works for something and stick to it. Don't show alternative ways. E.g:

Show only string formating using %, and ignore + and ,. You can always add a little "going further" block in your lecture material for the ones who want to know more. Show only for and not while. You can code almost 90% of Python programs without while. Avoid +=. Don't show that you can multiply strings/lists/dict with ints. This is not wrong, but will lead them to misconception. You need them focused on the main concepts.

Don't show sets. Sets are very useful but rarely used. Encourage them to code at home and to ask you if they can't solve a problem. In that case show sets if they are the solution. Knowing sets take times and student brain resources that could be used for something more often used. They will have plenty of time to learn new tools later, without you: focus on what is hard or time consuming to learn alone.

Same goes for enumerate. Students with a C or a Java background will use indexes to loop instead of for if you give them enumerate. For similar reasons, keep len, fd.read, fd.realines and range for one of the last courses entitles "advanced python" if you have any time for it.

Don't even think about generators, metaclasses and decorators. These can be apprehended by very few students, even after months of practice. List comprehensions, with and ternary operations can be brought in some of the last courses if you feel your students are smart arses.

Eventually, enforce good practices arbitrarily. PEP8 formating, good architecture, name conventions, no immutable default parameters, etc. They just can't know about it right now. Don't bother, you are the teacher, you have the right to say "this is just how it is" from time to times.

Oh, and they will be better programmers if they don't start by learning things like bytecode, recursion, assembly, complexity, bubble sort, stack, implementation details, etc. You waste time teaching this to somebody that can't code a decent Python program, he just can't see what's this is all about. Practice is your best tools to bring theory. And again, they will learn everything else by them-self later if you prepare them correctly, so prioritize and and don't be afraid to skip concepts, even simple/important ones.

e-satis
Thanks a lot! That is very helpful. Just a short question: why #8 so early?
Tomaž Pisanski
Because they will want to format strings quickly, but "," and "+" is very error prone. Even if they master types, line breaks and else, they will spend more times on debugging prints than learning the new concepts. "%" is hard to understand first, but it works all the time, very easily. What's more, C students will understand it quickly because of printf.
e-satis
Make them write lots of repeating code to get annoyed, then introduce functions :)
Bart van Heukelom
Hey, that's an idea. Better, let's make them write a lot of assembly then introduce Python :-p
e-satis
+2  A: 

You can see my outline here: http://homepage.mac.com/s_lott/books/nonprog/html/index.html

This presentation order is based on experience teaching C, Ada, C++, PL/SQL (and even a COBOL course once).

There's a great book, that has a sensible pedagogical ordering of concepts.

R. C. Holt, G. S. Graham, E. D. Lazowska, M. A. Scott. Structured Concurrent Programming with Operating Systems Applications. 1978. Addison-Wesley. 0201029375

http://openlibrary.org/b/OL4570626M/Structured_concurrent_programming_with_operating_systems_applications

S.Lott
Thanks for useful information. I think I will spend some time using random module.
Tomaž Pisanski
+1  A: 

I have recently taught a short Python crash course to 1st-3rd year Computer Science students the majority of whom knew only C and C++, and even that not so well. My approach was quite different from what you are suggesting.

Disclaimer: The aim of my course was to introduce the language to people who are already familiar with basic ideas of programming, so this might not be appropriate if you are teaching people who have never been exposed to programming at all.

  • First, I did a short introduction to the language with its strengths and weaknesses and showing some simple Python programs that even someone who does not know Python can easily get.
  • Then I did a thorough run through data structures, using the REPL prompt extensively for examples. Sure, at this point they could not write a program, but writing any program (even if just a toy example) without using data structures is really not what Python is about; I would even say that attempting that suggests unpythonic habits to the students. I went in this order:
    • Numbers (int -> float)
    • Sequences (list & tuple -> string -> bytearray)
    • Sets
    • Dictionaries
    • Bools, including auto-casting to bools.
  • Next up was the basic syntax, in the order:
    • Statements (line breaks, etc.)
    • Printing
    • Variables, focusing on the peculiarities of dynamic binding and the major difference between the C concept of variables and its Python counterpart.
    • Conditionals
    • Loops
    • List comprehension
    • Function/method calls, including function chaining, keyword parameters and argument lists.
    • Modules, including importing and dealing with namespaces.
  • Forth was a deep dive into functions. There's a surprising lot to teach about Python functions, including various ways of defining arguments (keywords, lists), multiple returns, docstrings, scoping (a large subject area by itself), and an important but oft-missed part which is using functions as objects, passing them around, using lambdas, etc.
  • Fifth was a more practical overview of files including I/O and encoding issues and exceptions (concept -> catching -> raising).
  • Finally an overview of OO features in Python, including instance variables, method types (instance/class/static), inheritance, method naming (private, mangled, special), etc.

For your particular questions:

For instance, my predecessor introduced lists before strings. I think the opposite is a better solution.

I disagree. Conceptually, a string is just a list that gets a lot of special treatment, so it makes sense to build upon the simpler list concept. If you start with data structures as I did, you also won't have to deal with not being able to use strings in I/O examples.

Should function definitions be introduced at the very beginning or after mastering basic structured programming ideas, such as decisions (if) and loops (while)?

Definitely after. Calling functions should be taught around the same time as basic structured programming ideas, but defining your own should be postponed.

Should sets be introduced before dictionaries?

Well, dictionaries are certainly much more used in practice, but if you've introduced sequences, explaining sets (especially to math students) shouldn't take long, and it makes sense to progress from simpler to more complex structures.

Is it better to introduce reading and writing files early in the course or should one use input and print for most of the course?

Python's IO capabilities are really simple, so it shouldn't matter much, but I'd say these are unnecessary for basic exercises, so you might as well leave them off for the second half of the course.

In my view, at each stage the students should be able to solve a non-trivial programming problem using only the tools available at that time. Each new tool should enable a simpler solution to a familiar problem.

The incremental approach is obviously very different from my more academic one, but it certainly has its advantages, not least of which is that it keeps people more interested. However, I always disliked the fact that when you're done with learning a subject this way, you are left with the feeling that there might well be an easier solution than what you've learned so far to even the simplest problems, since there always have been during the span of the course.

Max Shawabkeh
Thanks for your time. I will make some changes in my approach for the next year. However, I think strings are familiar to students and are much easier to grasp since there is no nesting possible. In addition, the "for loop" looks both natural and very powerful for strings.
Tomaž Pisanski
+2  A: 

e-satis's list is pretty good, but since this is for a math class, I'd add the following suggestions:

First of all, either use Python 3.x or tell them to always use

from __future__ import division

Otherwise, they will get bitten by integer division. It's easy enough to remember when you type 1/2 at the interactive prompt, but you'll get bugs in subtle places like:

def mean(seq):
    """Return the arithmetic mean of a list."""
    return sum(seq) / len(seq)

When you teach functions, show them the math module and the built-in sum function. Also show the ability to pass a function to another function, which is useful for writing generic derivative/integral approximations:

def derivative(f, x, delta_x=1e-8):
    """Approximate f'(x)."""
    return (f(x + delta_x) - f(x - delta_x)) / (2 * delta_x)

print(derivative(math.sin, 0))
dan04
Yes, we moved to Python 3.x this year. Thanks for the nice function examples. Do you prefer "import math" or "from math import *"?
Tomaž Pisanski
"import *" is discouraged because of namespace pollution, but it's useful when working at an interactive prompt.
dan04
+1. I never taught to maths students, so I guess it's important to take in consideration these specials cases. But when, I'm not sure yet.
e-satis