Wednesday, February 29, 2012

Python 2, Python 3, and Pygame

I've been using Al Sweigart's excellent book as the core of a beginning programming curriculum for middle school students for the past four weeks. So far, it's going great.

But there have been some problems.

First, I was originally intending to use the version of Python already installed on our new Mac Minis. It's a version of Python 2.7, perfectly adequate for new programmers with no interest in which version of a language they're using. That would save me the trouble of doing 14 installs of a different version of Python.

But the book uses Python 3. I had looked at several possible books for the class, and hadn't entirely cottoned on to the fact this one had the exercises in Python 3. So I had a choice of trying to have the students see the differences between 2 and 3 on their own from the very first, before they have any idea what they're up to, rewriting the programs for the installed version of Python, or installing Python 3.

I decided to install Python 3.

Later, the book uses the pygame library to give Python graphics and sound capabilities. Unfortunately, there's no distribution package of pygame for Python 3 on Macintosh, only Windows (and possibly some of the Linux distros.)

So I tried to install pygame for 2.7. At least by the time my students get to chapter 17 in the Invent Your Own Computer Games with Python, I believe I'll be able to discuss the 2 vs. 3 syntax differences with them. Hopefully they'll be able to translate on their own. I expect to be doing Python 2 rewrites of the programs myself for next year's classes (unless a working pygame package appears for Python 3 on OS X Lion in the meanwhile).

It took me quite a few tries and a fair bit of my limited class prep time to find a combination of Python and Pygame that works on our school's lab computers. I discuss the details of that on my other blog. But I found a combo that appears to work today (pygame imports, and the first graphics program from the book runs.) I have installed it on 3 out of 14 computers so far, hopefully I'll have time to get it everywhere before the students reach that chapter.

Ass it is, I had already had to spend significant amounts of time developing alternatives to using the rest of the book after Chapter 16. My plan was to shift to turtle graphics, which appear to be bundled with Python 3.2 regardless of platform.

A Bit of a Rant

Frankly, as much as python has worked well for my students so far, if I had known the time and trouble I'd be running into I would never have even started using Python in class. There is no good Python solution here, everything is no better than a 9/10s solution.

Python, by itself, is pretty darn good. The current features in the standard distribution include graphics without requiring any external package installs on all 3 platforms I've run it on: Mac OS X, both 10.6 and 10.7, Win7, and Ubuntu 9.04 and 9.10. It's turtle graphics, but for the needs of my new programmers that fits the bill. I'd like to see standard sound support across platforms. Really, anything that supposes itself to be a general purpose language on this side of AmigaBASIC should be expected to support graphics and sound as standard features. Preferably without a ton of boilerplate. Here's hoping future Python versions can manage this.

The change in the print statement between Python 2 and 3 is maddening. The rationalizations aren't especially convincing to me, at least with respect to breaking backward compatibility and requiring silliness like "end=''" to suppress newlines. What great new ability has been gained for this cost? Nothing that's convinced me of the value yet. I expect this was discussed in PEPs somewhere. Parens, OK, I can possibly see adding those if it does something for added functionality (orthagonality with functions is not a convincing argument, to me.) But failing to provide a simple means of suppressing a newline like the earlier trailing comma, while going to a parametric assignment...that certainly appears well out of line with Python's apparent philosophy.

Now, pygame. No 3.X distributable for OS X? On what's touted as so wonderfully multi-platform? And it's not as if we're talking about a new version of Python that we need to just wait a week or two to get a binary for platform X ready. But Windows gets first class treatment. Mac OS? Not so much. Great multi-platform commitment, there.

I'm not at home to suggestions of compiling my own, I'm afraid. I could, for myself. But the world has a lot of machines that aren't just my own development system. The OS and hardware in our school's lab differs to what I run on my own systems. I haven't the time or desire to set up one of the school's systems as a dev box for porting software, then porting what claims to be a highly popular multi-platform package to the school's computers. Especially when they are a very popular hardware/OS mix already. I shouldn't be expected to put a large commitment of time and energy into getting this working at a point when I don't even know if it has any value to me yet.

And that still doesn't get me a package for Python 3, just for 32/64-bit, unless I move files by hand or make my own installer. While I'm a newcomer to python, for the most part, myself.

Good, but Not Quite Ready for Prime Time

That all said, I think I and my students will get plenty of value out of Python, pygame, and Al's book. But the price of entry for the package deal was too high. And we've still got this Python 2/3 version switch problem sitting in front of us, which I hope isn't going to turn into another big problem, but stay a little problem--though one that still needlessly eats up our limited class time with explanations of syntax differences rather than real new material.

Frankly, I couldn't possibly recommend doing this to others teaching at this level, as things stand at present. Things that would change this:

  • A book of the character and caliber of Al's that relies on no external package installs, just a current version of Python. Or,

  • An unambiguous install of Python and a matching compatible version of pygame, plus a book with matching code for that version in the exercises. Preferably as a single bundle installed all at once.

Edit: I've read PEP 3105 now. I still don't agree with breaking backward compatibility, as opposed to adding the function and deprecating the statement syntax. I also think there's reason for a simpler newline suppression syntax than the end parameter. Not every Python programmer is going to share the viewpoint of a python-dev wonk. ;) Some of them just want something simple that does the basics (print a string, suppress linefeed as needed--that's all.) In this case, the extended usage has broken the basic usage.

Addt'l edit: Reading "Python Regrets" now. The example syntax there of write() and writeln() would do the trick, from my teacher's standpoint. While I'm aware that redundancy is not a Python value, I think adding write() and writeln() to 3.x while keeping but deprecating the print statement for the term of one major version would have been a better approach (drop print when 4 comes.) Possibly limit print by rolling it back to a more limited version that doesn't allow redirection during 3, if the clock could be rolled back. Obviously at this point it's somewhat too late for that.


  1. I'm not sure, but maybe this will help you?

    1. Thanks for the pointer. (The URL is missing an 'l' at the end, but I got to the page.)

      I actually managed to install pygame under 10.5 and 10.6:

      The problem here is a bit different.

  2. I'm doing python bindings for a game engine. While I'm using Python 2 right now, I want it to be as compatible with Python 3 as possible, so I always type this at the beggining:

    from __future__ import division, print_function

    1. Nice. What I was expecting to do if I end up using Python 2 was just use something like print('whatever') to introduce the idea. But this will be better even if the syntax of the import will take some explaining.

      The double underscore will also be fraught with peril in a room full of 11-13 year old students. ;)

      This is why it's so important to have stuff that "just works."

    2. Do you realize that "print ('whatever')" behaves identically in 2.6+ and 3? The only case where it does not is a bare "print" in 2 (equivalent to "print('')" in 3).

    3. What I've found is that there are a few cases where the syntax is the same. But what I've found is that there are many common cases where they aren't the same.

      If I could get done what I wish with just one version, this wouldn't be much of an issue.

  3. Also, try this:

    import sys
    write = lambda x: sys.stdout.write(str(x))
    writeln = lambda x: sys.stdout.write(str(x)+'\n')

    1. Umm...for me, for my personal programming, none of this is an issue. For my students, in a classroom where the computers get shared between several classes, etc., etc. this is more than I can expect to use or explain to my students in the one hour per week of class time we get while still meeting our other objectives (like keeping them engaged.) It's a nice trick, but it doesn't make up the difference for it not being in the language.

  4. There were no parentheses added to a print statement for orthogonality with functions. The print statement was removed from python; a print function was added. To my mind, the best thing it gains us (which is definitely worth it for me) is the ability to replace it when necessary (for instance, to improve testability).

    1. You're playing with semantics. I think you understand my meaning.

      I'm glad that it's a valuable change for your use. I'm sure it's got a lot of value, I get what the PEP is talking about. But that's a usage model that doesn't apply at the beginner or casual programmer level.

      I think both needs can be accommodated. Personally, I'm disappointed the write() and writeln() functions weren't used instead of the present print().

  5. Mark:

    First up, I agree 150% that people should NOT today be writing introductions to Python that rely on 3.x - for all the reasons you've stated and more.

    BUT you are poorly informed with your criticisms of losing the "print" statement in 3.0.

    I could write and explain to you again why this is so: that the "print" statement is a unique element in the Python grammar that causes all sorts of problems; that being able to override the print statement in code you write isn't "playing with semantics" or "a use model that doesn't apply at the beginner or casual program level" but instead the *only* way to neatly move from a "two-minute quickie" to a more general purpose script without rewrites; and more.

    But, you know, I shouldn't have to do this. There is some level of responsibility on you when you make such harsh criticisms of this decision to inform yourself as to the reasons behind it. This decision wasn't made casually in a vacuum; this, and indeed every other decision regarding Python 3, was systematically discussed by hundreds of thoughtful people over years on public mailing lists for years before it was finally resolved.

    No one likes to break backward compatibility. No one would have broken backward compatibility just to fix the print statement! But it came to a time in the life of Python where there were too many changes that needed to made that could not be backward compatible. This is the only chance to do it.

    And there aren't that many changes, frankly. I have a pretty large codebase - it took me half an afternoon to port it entirely into 3.0, and there were no surprises at all. The automatic tool is impressively effective...

    The fact is that you bought hardware that had Python 2.7 installed, and bought a book intended for a different language, Python 3. It is a shame that this caused you grief - blaming the maintainers of the Python language is however unfair.

  6. I think I have a good understanding of why it had to happen, I don't disagree with that. I disagree with how it's been handled. And going on about the internals of the language isn't a convincing argument when considering beginning and casual programmers.

    I don't accept the tag of irresponsible when I'm just a commentator, as opposed to someone who's changing a tool that has a large group of users and would-be users.

    The problem also comes from having to deal with it both ways. The python ecosystem is what's causing this. For all the value that ecosystem adds (which is incredibly fantastic), it also adds mass to python that ties it to its past. That's why we've still got the 2/3 split in the language, and why decisions of what to do going forward are so important.

    The theory that this is my problem because our school received boxes from their supplier with 2.7 installed while I chose a book that uses 3 is silly. This falls into the "can't see past my dev system on my own desktop" camp of incorrect thinking.

    What I do with one box, of my own, running the software I've selected is far less constrained that what happens on a larger number of systems with very limited IT support in an institutional environment. What's only a minor hitch on my desktop can be a show-stopper when it involved a number of boxes I don't own, with shared use, and over which I have limited control. Welcome to the real world. It's not your desktop.

    I have reason to believe that python has application beyond the desktop systems of individuals, and beyond an audience that judges python by its internal operation. I can hope that the current problems caused by the 2/3 split (and I mean problems more significant than print and division) will help inform python's future development.

    I only represent one specific use case for python in my statements. I don't think making my issues public is at all irresponsible. What I do think is irresponsible is taking a negative attitude toward well meant criticism.

    Fortunately, I have received very, very kind responses from the pygame development community that I think are exemplary of what's right about the python community. And those far outweigh any negative criticism I've received. I'm looking forward to having some real achievements here to post an article with positivism easily exceeds any perceived negativism here.

    I like python, I think it's great. My students' achievements using it as a tool are exceeding my expectations. It has blemishes that have impacted my ability to use it. I would like to help remove them.

    And it looks like that's happening.