October 18, 2005
Izabella, Icons, and Py2App
After I posted the first few articles in the "six-year-old Anthony learns how to program in python" series, a friend asked me, "does Anthony really understand the program he typed?" Honestly, I wasn't sure. I did have to help and teach him quite a bit to get "GuessANumber" working. Maybe I was actually doing all the programming, and Anthony was just a spectator.
It turns out we had a good chance to test this theory a couple weeks later. The original GuessANumber game was too hard for Anthony's little sister Piper. At 3, Piper could just barely count up to 20 and didn't have any way of knowing whether 75 should bigger than 57 or not. And so every time she would try to guess a number from 1 to 100 in five guesses, she would lose and be unhappy. The booming vampire audio echoing "I win!!!" did not help.
Soon Piper told us she wasn't really into vampires. She wanted a princess game.
So Anthony decided to make an "easyguessanumber.py" game. This time, as an experiment, I set up the text editor, typed in the #!/usr/bin/env python magic, and then left the room to see what Anthony would come up with.
Anthony did need answers to a couple questions, such as how to call "random.randint" - but I kept myself in the other room to see if he could get it working on his own. The results are pasted below, complete with spelling errors and a "highly secret" variable named "sx4". My conclusion: python is indeed a language a 6-year-old can learn.
#!/usr/bin/env python import random print "hello." print"I am queen Izabella" sx4=random.randint(1,20) print"and I have a secret." print"And what is it?" print"A number 1-20" print"Now you guess." guesses_left = 5 while guesses_left != 0: guess=input() if guess == sx4: print"you got it!" break else: print"nope" if guess > sx4: print "smaller" else: print"biger" guesses_left -=1 if guesses_left == 0: print"I won!" print sx4
With numbers limited to 20 and a new Princess character, Piper was far happier with this new version.
Cutting and Pasting
But Anthony was still not satisfied with his Vampire version. "I can't see the vampire!" And, he wanted to know, how come the icon that showed when we were running the app was a big black screen? Why couldn't it be a vampire?
He wanted me to draw a vampire for him. But, of course, a Daddy-drawn vampire wouldn't have been in the spirit of our project.
So we struck a deal. If he could make a vampire out of construction paper, I would figure out how to make it into the icon for his program.
A few days later, the following creation was dropped on my office desk.
Vampire, my nemisis. We finally meet.
Fit and Finish is Daddy's Job
Here is where daddy took over the last steps in the project. The last 10% of fit and finish in software requires 90% of the effort. It's fun to put together the algorithm for a program, but who wants to write the setup code? And handle all the error cases, and deal with the usability problems?
When you're six, Daddy will do it for you.
So I took out the digital camera and took a photo of Mr. Vampire; used a bit of photoshop magic to make it into a transparent png (hint: photograph your object on a piece of solid-color background paper, then use photoshop to select that color and delete it); this got converted into an OS X icon file.
To use an app icon, we needed to make our python script into an app. So I wrote the following py2app script to package the app up:
#!/usr/bin/env python """ setup.py Usage: % python setup.py py2app """ from distutils.core import setup import py2app py2app_options = dict( iconfile='Vampire.icns', ) setup( app=['GuessANumber.py'], data_files=[ 'big.wav', 'guess.wav', 'guess_again.wav', 'i_win.wav', 'intro.wav', 'last_guess.wav', 'number.wav', 'small.wav', 'you_win.wav', 'Vampire.png', ], options=dict( py2app=py2app_options, ) )
The app also needed to be modified so that it wasn't a console program - using stdin and stdout would be no good, so input() and print had to be replaced with a pygame library that would take input and print to a graphics screen. There is a package called "pgterm" that does this job well. The details aren't that interesting, but you can take a look at the source code if you'd like (I have included it all below). There were some issues with getting fonts on the mac to work.
The results were great. Now Anthony has a little "vampire" icon in the tray on the Mac, and he can play it any time. The graphical input and output is just like the console interface, but the fonts are bigger and there is no problem with typeahead (a common source of confusion!)
We were ready to unleash the vampire on the world.
We would release the source code, but it seems like the standard way of distributing OS X files is in a compressed .dmg file of the binary. No problem. The following command seemed to do the trick just fine.
hdiutil create -imagekey zlib-level=9 -srcfolder dist/GuessANumber.app dist/GuessANumber.dmg
So, now you can download it. We haven't actually tried running this program anywhere other than on my own computer, so your mileage may vary. We're including the source, so if you have problems you may be able to fix them yourself. Be sure to let us know :-).
Downloads (for OS X)
guessanumber-source.tar.gz source code.
GuessANumber.dmg compressed disk image of the binary.
Happy number guessing - Haaaarg!
For more on this blog about learning to program:Posted by David at October 18, 2005 05:52 PM
|Copyright 2005 © David Bau. All Rights Reserved.|