Python T-Shirt
Originally published on macresearch.org, around 2008. Reproduced from the author's archive; some links may no longer resolve.
Gift Ideas for the Scientist with Everything
My research group has a tradition of giving PhD students lavish gifts upon their departure. Recently, one of our flock was successfully promoted to the rank of Doctor of Philosophy, and we went through the usual brainstorming to decide upon an appropriate present. The student in question is an enthusiastic Python scripter, so one of the more creative types in the group came up with the idea of a Python themed T-Shirt, to go with the iPod that just about everyone seems to get.
Since I am also an avid Python scripter, it came down to me to come up with ideas for what should go on the shirt. We decided it should include a short Python script on one side, and possibly the output of the script on the other. My thoughts immediately turned to Quartz 2D (link no longer available), and its Python bindings (link no longer available).
I’ve written about the Quartz bindings on MacResearch once before (link no longer available); they really are a relatively painless way to generate automated graphics on Mac OS X. My idea was to take a folder full of photos of the research group, and run a script over them to generate a pretty pattern, which would then be printed on the T-Shirt. The question was, could I write a script short enough to fit on a T-Shirt that generated something visually pleasing?
This is the script that I came up with.
#!/usr/bin/env python
import math, string, os, os.path, sys
from CoreGraphics import *
def RenderFriends(photoFiles, context):
context.setShadow(CGSizeMake(0,0), 10)
context.translateCTM(792/2,792/2)
context.scaleCTM(0.005,-0.005)
for iz in range(37):
filename = photoFiles[iz%len(photoFiles)]
photo = CGImageImport(CGDataProviderCreateWithFilename(filename))
context.scaleCTM(1.2,1.2)
context.rotateCTM(30*math.pi/180.0)
rect = CGRectMake(100,0,photo.getWidth()*0.25,photo.getHeight()*0.25)
context.drawImage(rect, photo)
pagerect = CGRectMake(0, 0, 792, 792)
context = CGPDFContextCreateWithFilename('friends.pdf', pagerect)
context.beginPage(pagerect)
RenderFriends(sys.argv[1:], context)
context.endPage()
context.finish()
That’s not bad, length-wise, but what does it do? It generates a spiral of photos, similar to this.
[image: A spiral of friends. — no longer available]
It’s also very simple to add a border to the photos by drawing a white rectangle before drawing each photo; the example scripts in /Developer/Examples/Quartz/Python show you how.
To run the script, you simply supply the photo file names on the command line, or use a wild card.
If you are wondering how it works, don’t think too hard about it. I derived all of the numbers in there by trial and error, until I got something that looked OK. The idea is simply to draw each photo, modifying the current transform matrix (CTM) each iteration, scaling up the photo, and rotating it about an axis. This generates a spiral effect. If you want to get really adventurous, you could create multiple spirals, and possibly add a small random component to each transform, which would produce a patch of flower like spirals.
I’m sorry to say that after all that, the idea wasn’t accepted by my peers, and did not end up on the T-Shirt. Instead, another script that I wrote made the cut:
python -c "from string import *; print join([map(lambda x:x[1],
filter(lambda x:x[0] in [1,14,17,4,3],
enumerate([lowercase[i] for i in range(26)])))[j] for
j in [0,3,4,2,1]],'') + '?'"
This is a single Python command, and can be entered directly on the command line. The idea behind this one was to make something extremely cryptic, which would actually run and do something. Well, it doesn’t do much, but you can find that out for yourself. As for the output, let’s just say, it should describe your state of mind having spent 5 minutes typing it in.