Wednesday, November 10, 2010

Have you seen the elephant?

In case you're wondering, my upcoming work for KACE doesn't imply that I'm leaving Dayton. Like most of my coworkers, I'll work for KACE by telecommute. It's enormously flattering to be offered a position when the competitors for the job are potentially anybody on the surface of the earth. (Anybody who's interested in a Dayton jelly or telecommuters' club, let me know.)

That's good, but honestly, it's not the aspect of the new job I'm most excited about. It's this.

I'll migrate an important MySQL database to PostgreSQL and become its caretaker. I don't expect to use Oracle at all in the new job (though I'll stay active in the local Oracle community, and do some personal Oracle projects just for fun). Basically, I'll be a full-fledged PostgreSQL DBA.

Oracle has been practically a part of my identity for years, but those who have paid close attention have noticed me sighing in longing for PostgreSQL for years, too; I've said more than once that I'd drop everything to work full-time with PostgreSQL. I didn't think it would ever happen, since Dayton's main employer (the Air Force) has a strong prejudice for proprietary software. But, thanks to KACE, the impossible finally happened.

It's a funny coincidence - but yes, a coincidence - that this happens during a downswing in relations between Oracle and open-source communities; many F/OSS lovers are upset about Oracle's decisions since acquiring Sun. For me, though, it's not a matter of techie politics; PostgreSQL is simply a wonderfully-written database and a joy to work with.

As my relationship with PostgreSQL matures from a clandestine affair conducted at night to a full-time committed relationship, I'm sure we'll get past the honeymoon period and have some arguments, like any couple. Even the best software is still software, after all, and human-software relationships always have their difficult moments. Still, I'm enormously excited to begin this new phase in my love of free software.

Hmm. "PyOraGeek" might not be the most accurate subtitle anymore, but "PyPostgreSQL geek" violates uniqueness constraints in a big way. The rebranding is the hardest part...

sqlpython 1.7.2

sqlpython 1.7.2 has been released! Install it, pretend that your Oracle/PostgreSQL/MySQL database is a UNIX filesystem, and have a blast.

This release doesn't really add any new features. However, it does clean up the sluggishness in metadata operations (like ls and desc) and the major outright bugs that were making sqlpython frankly unusable for an embarrassing number of months.

Sorry for the wait! Hope you'll find the new sqlpython worth it. Functionality for PostgreSQL and MySQL are now fully-fledged, with some relatively minor exceptions (like image BLOB displays). Furthermore, my upcoming position guarantees that the sqlpython/PostgreSQL will get lots of love in coming months.

Monday, November 08, 2010

Moving to KACE

For almost ten years, I've worked for IntelliTech on contract at Wright-Patterson Air Force base. IntelliTech has been a very supportive employer, and my government boss at WPAFB (Ralph Ranard) has been an absolutely amazing supervisor; that's why I've been there so long.

This month, though, an opportunity has come up that I absolutely can't resist. I met Mike Gray and Tyler Gingrich of Dell KACE at Columbus Code Camp, which KACE sponsored partially to make contact with potential employees. (This, incidentally, shows excellent management right there. If you want skilled and passionate geeks, do you hire a recruiter to try to read the tea leaves of the self-promoting buzzwords of a huge stack of resumes? Or do you go to where the most passionate geeks congregate all on their own?)

Everything I've seen about KACE delights me so far. It's a subsidiary of Dell that has intentionally retained its startup spirit since its acquisition. Technical decisions are made by technical people for technical reasons - in other words, people are allowed to use the expertise they were hired for. (I know, that shouldn't be exceptional.) It's got a developer-centered culture that is a huge breath of fresh air. It's friendly to newer technologies and very friendly to open source. For example, I'll be taking over an important database currently in MySQL and migrating it to PostgreSQL. (Getting somebody to pay me for working with PostgreSQL has been a dream of mine for years...) And of course I'll be using Python. I'd wait tables before taking a job with no Python.

During my entire process of interviewing with KACE, it never felt like "job interviews" - those nerve-wracking, superficial, semi-adversarial dances described so depressingly in career publications. Rather, it felt like some long conference-hallway conversations between geeks - very real and very techie.

So... hello KACE! I'm delighted to join you!

Monday, October 18, 2010

Camping in Ohio

This Saturday was the Columbus Code Camp, and I have to say I was really impressed. The quality of the talks - and the audiences - was excellent, and it was a nice broad set of interesting topics. Mike Reed and the other organizers should feel great about putting together such a good event, especially for its maiden voyage. I look forward to it as a regular event.

My talk slides and materials are the same as the Ohio LinuxFest versions. Thanks to my audience for the great questions!

Next weekend comes the Southwest Ohio GiveCamp, a big hackfest to rapidly produce software for area nonprofits. I've never been to a GiveCamp before, and I'm really looking forward to it; I've heard great things from people who have participated before. Python folks, step forward - I want to make sure there are enough of us to form at least one strong team writing Python-based software.

Scheduling of tech events is an interesting topic. If it's held on a weekend, you know you're getting genuinely passionate professionals, people who want to spend their own time learning new things and improving their skills. If it's held on a weekday, you know you're getting people who work for smart companies that value their employees' skill and know that user-driven events are a great (and cheap) form of training... as well as a few attendees who are so hard-core that they'll actually take their own vacation time for learning. Either way, it reveals a lot about which people and employers are really dedicated to being and staying sharp.

Monday, September 13, 2010

pdb with Sikuli

As I mentioned in my last post, the big barrier to debugging a Sikuli script with pdb is that, when you enter a debugging command like "next", "continue", etc. that is supposed to allow program flow to continue, you are in the debugging console window, and your Sikuli script will send the keyclicks and mouse actions into the debugging console window instead of the application your script was supposed to be driving.

Here's a minor modification to pdb that can change that by using Alt-TAB to switch back to the application window every time program flow moves from the debugger to the application. Save this code as in the Lib directory that you unzipped Sikuli into, for example, ~/Sikuli-IDE/Lib. (/Lib is not created by default, but it is the first item in sys.path.)

#! /usr/bin/env python

"""A Python debugger.

A slight modification of ``pdb``; attempts to switch
screen focus back to the invoking app before running commands
in the program being debugged. This should prevent Sikuli
commands from being "typed" or "clicked" into the debugger
window when they should go into the window of the app being
# (See pdb.doc for documentation.)

import pdb
import sys

class Pdb(pdb.Pdb):
def _to_running_window(self):
"""Moves focus to the window a Sikuli script was running
before the debugger was invoked, so that subsequent commands
will act in the app instead of the debugger."""
self.onecmd("SCREEN.type(Key.TAB, KEY_ALT)")

def do_step(self, arg):
return pdb.Pdb.do_step(self, arg)
do_s = do_step

def do_next(self, arg):
return pdb.Pdb.do_next(self, arg)
do_n = do_next

def do_return(self, arg):
return pdb.Pdb.do_return(self, arg)
do_r = do_return

def do_continue(self, arg):
return pdb.Pdb.do_continue(self, arg)
do_c = do_cont = do_continue

def set_trace():

Now, at the point in your Sikuli script where you want to enter the debugger, insert
import sikpdb; sikpdb.set_trace()

Also remember that you need to add -Dsikuli.console=false to your .sh or .bat script in order to allow pdb input/output to appear in the console window you used to invoke Sikuli. Otherwise, Sikuli will just hang when you attempt to enter the debugger (it's waiting for your input - in some nonexistant interactive session). For instance:
$ cat
DIR=`dirname $0`
java -Xms64M -Dsikuli.console=false -Xmx512M -Dfile.encoding=UTF-8 -jar $DIR/sikuli-ide.jar $*

The remaining problem is that depends on the notion that ALT-TAB will reliably return you to the application's window. This is true, but only if you do not browse around among your open windows while in the debugger; if you do, you'll change the z-ordering of the windows. It would be more reliable to call switchApp() with the title of the application's window, but I don't know of a cross-platform way to automatically detect it - the best I can think of would be to manually pass it as an argument to set_trace, have set_trace store it in an instance variable like self._application_window_title, then call self.onecmd("switchApp('%s')" % self._application_window_title) in place of self.onecmd("SCREEN.type(Key.TAB, KEY_ALT)") . It's more complex to use, but more reliable... feel free to use that approach if you prefer it.

Sunday, September 12, 2010

Sikuli talk follow-up

Thanks to everybody who made time in a busy Ohio LinuxFest schedule to make it to my talk on Project Sikuli! I appreciated your attention and your questions.

You can browse my slides at, and/or download a tarball with all the code demonstrated at

I promised to follow up on the questions that stumped me, so here are the first couple answers...

- I mentioned how debugging with pdb is difficult because switching to the command-line window to interact with pdb interrupts the program flow, and when you issue a "continue" in the debugger, your Sikuli script will barrel along in the command-line window with the debugger instead of in the application you wanted Sikuli to drive. A couple people suggested debugging the script from a remote machine, connecting with pdb and attaching the debug process to the Sikuli process. I still don't know whether that's possible - definitely maybe - but I realized that there's a very simple remedy that I feel silly for not suggesting before.

In your Sikuli script at the point you want to enter the interactive debugger, instead of simply inserting import pdb; pdb.set_trace(), insert import pdb; pdb.set_trace(); switchApp('Window Title Of The App I Am Debugging') - that should put the script you're debugging back on track.

EDIT: WAIT - I got this wrong - this doesn't make sense. You do need to switchApp() back to the window your script was running in, but not immediately after invoking pdb.set_trace(); rather, it needs to be invoked just before running, pdb.continue, etc. I think the right way to do this is to subclass pdb; give me a bit to produce and test something like that.

- I confirmed that there isn't yet a "Recording" mode, or anything to automatically translate your actions into Sikuli commands. Really, though, I'm not sure how much that would help - writing the Sikuli commands is actually the easy part of the automation. The hard part is figuring out precisely which actions to take to get the effects you want most reliably.

OLF was really good this year. I especially enjoyed the hallway track - met lots of really interesting people that I need to follow through with on some neat ideas. The exhibit hall was a great place for PyOhio folks to meet new people and connect them with the Python community - thanks so much for all the PyOhio crew who came out to staff the booth! Thanks to the organizers for all their work!

Thursday, September 09, 2010

Quran troll

Ian Bicking hit it right on the nose: this Quran-burning pastor is a troll, no more.

Arguably, I shouldn't even be posting this. Trolls should be ignored. The trouble is, even internet-savvy people have trouble living up to that prescription. The world as a whole definitely doesn't know what to do about trolls. There are already people in Afghanistan holding demonstrations because of this troll... so I feel like "just ignore it" maybe isn't enough right now.
John Shimek: The best suggestion I have heard it to ignore it and donate towards the Pakistan flood relief.
Very good. But I'm wondering if one step further would be a good idea: an explicit linkage. You know, "I pledge a $x donation for Pakistan flood relief for every copy of the Quran burned." Isn't there a webservice out there that facilitates making this sort of pledge? Help me out, lazyweb - this should happen fast if it's going to happen.

Granted, Pakistan flood relief shouldn't be an issue of the victims' religion one way or the other, so there's something a little odd about using it as an anti-bigotry statement. And maybe this does amount to feeding the troll. But at least it would feed some real-live human beings at the same time. It's the only way I can think of to turn this stupidity into something good.

And, if you can permit me just one little troll-foodish comment...

To be an a**hole is one thing. (I really struggled to find another word here. This time, though, it really is the only word.) But to say, "It's not me - it's God who's the a**hole, and I'm just obeying him"... I don't understand how anybody can say that without being 100% flat-out certain that there is no God. Why would anybody take the slightest chance of ever standing before God and having Him say, "Could you repeat that to My face, please?"

Saturday, August 21, 2010

Setting the turtle free with Sikuli

Have you played with turtle graphics? I enjoyed Logo ages and ages ago. Nowadays there's a turtle module in Python's standard library, plus several other implementations.

But all the implementations I know of keep the poor little turtle stuck inside a dull little window. Last night I realized that, with Sikuli, I can set the turtle free! It can roam freely beyond one little window and have adventures in the big, wide world. Here it is marching right past the edge of TuxPaint and onto GNU Paint.

Note that this is an invisible turtle. But you can see its effects.

For the new free-range turtle, "penDown" and "penUp" are actually "mouse button down" and "mouse button up". If it's walking across a drawing program with a paintbrush turned on, it will paint a line like a traditional Logo turtle. Otherwise, it will click and drag its way across your desktop and your other applications. This turtle can be mischievous!

What really pleased me was just how easy it was to implement with Sikuli. Here's the code in an .skl bundle - it's a zipfile that Sikuli can use directly.

import math

class Turtle(object):
def __init__(self):
self.heading = 0
self.loc = Env.getMouseLocation()
def forward(self, distance):
sin = math.sin(math.radians(self.heading))
cos = math.cos(math.radians(self.heading))
endpoint = (int(self.loc.x + cos * distance),
int(self.loc.y + sin * distance))
if self.down:
dragDrop(self.loc, endpoint)
self.loc = Location(*endpoint)
def backward(self, distance):
self.forward(distance * -1)
def right(self, degrees):
self.heading = (self.heading + degrees) % 360
def left(self, degrees):
self.right(-1 * degrees)
def penUp(self):
self.down = False
def penDown(self):
self.down = True
def circle(self, radius, extent=360., steps=20):
circ = 2 * math.pi * radius
fraction = extent / 360.
step_length = (circ * fraction) / steps
for i in range(steps):
self.left(360. * fraction / steps)

def zigzag(startHeading, size, angle, steps):
t = Turtle()
t.heading = startHeading
t.left(angle * 0.5)
for i in range(steps):

Tuesday, August 17, 2010

gmail filter appender with Sikuli

Gmail filters are great, but I've got some filters that apply to a hundred different senders - and I'm always adding new senders to them. I've wished for an automated way to add the sender of the message I'm currently viewing to one of my filters.

I'm sure this could be done in Greasemonkey, Selenium, etc., but Sikuli is my tool of interest for the moment - and, after some fumbling, I'm really happy with it.

A partial screenshot, just to give you the idea:

View the Sikuli code, or download it and run it with /path/to/your/ spammy.skl - except you'll probably want to edit the keywords identifying your filter, and possibly recreate the graphics to match your own Firefox theme. Mostly, it's there as an example to learn from.

I'm learning plenty that will go into my Ohio LinuxFest talk, but the big lesson for today is to rely on keyboard-based and text-based techniques rather than picture-finding whenever they're available. For instance, how should I click a button that might have scrolled off the bottom of the screen? There are lots of ways - I could embed find() in a loop with type(Key.PAGE_DOWN), for example - but it's more reliable to piggyback off Firefox's "Find" to zoom in on the text on (or near) the button and then find it.

Wednesday, August 11, 2010

Sikuli at Ohio LinuxFest

And now, for my next trick, one month from today, I shall demonstrate how to script virtually any program with a GUI... without touching an API! (audience gasps)

If You Can See It, You Can Automate It: Sikuli
Your computer should save you from doing tedious and repetitive tasks yourself, but automation programming has been too difficult for casual uses. MIT's Project Sikuli changes that. It fuses traditional text-base scripts with actual screenshots of targets on your screen, making programming simple, versatile, and useful. If you've ever told a friend, "Go here, now click on this, then on that", you know enough to start using Sikuli. Let Project Sikuli shake up your notions of what programming is like.

I'll be spending most of this month using Sikuli to build a test suite for a complex GUI app at work, recording the pain points as I go. I'd also appreciate your questions and comments about Sikuli - I may be able to work them into my talk (or at least be prepared when they're asked from the audience.)

Ohio Linux Fest, Sep. 10 - 12.

Sunday, August 08, 2010

"Many Eyeballs" - HA!

Oh, yes, I feel I should record this little incident from PyOhio 2010, for the sake of evidence during Nick's trial.

I used PyOhio's Lightning Talks to give away our swag prizes; and, in the spirit of open-source, I put the code on the projector for everyone to see.

import csv
import random

regfile = open('registrations.csv')
reader = csv.DictReader(regfile)
registrants = list(reader)

def pick():
winner = random.choice(registrants)
return '%s %s' % (winner['First Name'],
winner['Last Name'])

Then I realized that I didn't have the Lightning Talk sign-up board, so I went out into the hall to get it. I was gone maybe 60 seconds. When I got back, I called pick() and got... Nick Bastin!

The room giggled. Nick said, "Wow, that's the first time I've written bug-free code on the first try!" I didn't get it, so he said, "Why don't you pick another winner?"

Nick Bastin!

The nice thing is, my code was intact. However, this was lurking in my directory.

$ cat
def choice(foo):
return {"First Name" : "Nick", "Last Name" : "Bastin"}

The lesson here is: Many eyeballs can help protect you from malicious code... unless they're all in on it!

PyOhio 2010 review

My own PyOhio 2010 wrap-up post is highly suspect, because I'm probably not one to deliver an unbiased opinion. So, when I say that


you can be forgiven for being a little skeptical. In fact, one of my few regrets is that I didn't collect firm, objective data on just how awesome it was. I don't have accurate numbers on attendance yet - our sign in sheets are, um, somewhere around here. We had 179 pre-registrations; subtract some no-shows, add some walk-ins, and you get... I don't know. But the place was bustling!

The talks were good, and more importantly, they stimulated some excellent informal activity. The Open Space activity was stronger than ever this year; some of them packed our Open Space rooms to the walls. There were a fair number of Python newcomers there - yay! - and I was glad that we had a good Beginners' Track for them. An After-Hours Board helped people coordinate some evening fun together. Overall, it was not at all just "a place to see talks", but a full immersion in the awesomeness of Python people. Of course, the sprints were the big after-hours event, but they deserve their own post (soon to follow).

OSU's new Ohio Union was a great locale. It helps a lot that it has a design and a staff specialized in holding meetings and conferences, and it's just fantastic that the OSU Open Source club was able to provide the space at incredibly good rates. We look forward to using virtually the same space next year, with just some minor tweaks.

And, for everybody who wondered how we put on a great show at no charge... thank our sponsors!
  • Microsoft
  • Intellovations
  • AGInteractive
  • Dayton Microcomputer Association
Anyway, I'm delighted. I had fun and learned a ton. I hope you did, too! Thanks so much to everybody who took part!

Here are a couple other wrap-up posts I've happened across. Let me know about others you find.

Alex Gaynor
William Chambers
Richard Harding

Wednesday, July 28, 2010

PyOhio: photos plz

We have 138 PyOhio registrants so far - that's greater than the total number of attendees last year. I'm excited!

Is there a shutterbug in the house? I'm always envious of the photos taken at some conferences, like this one of Python core sprinters at EuroPython. (Hi, guys! Our contribu-palooza-ers will be joining you soon!) I want to join the fun. Our PyOhio attendees are just as pretty as any of them!

So if you enjoy taking pictures, and you're coming to PyOhio (and who wouldn't?), please don't forget your camera! Get some group shots, and let me know about them afterward. Thanks!

See you Saturday!

Friday, July 16, 2010


PyOhio staff badge
We are 15 days from the third PyOhio, and I am so excited... My first hope for PyOhio was that it would become a little slice of PyCon-ish goodness in our region... we've definitely accomplished that. This year we're adding on some very serious sprinting that, I think, will make PyOhio an important part of the Python scene not just here, but worldwide.
  • The Android Scripting Workshop has the potential to make Python-lovers of a whole new class of people who wouldn't even call themselves programmers (yet)... people who love their powerful Android phones and will love them even more once they learn the power of scripting on them. One question I'd like your advice on: how do we let these people know about the workshop? They're not reading my blog, after all...
  • The Contribu-palooza is a set of linked events (a classic talk, a "Teach Me" talk, and a big fat sprint) designed to make you into a contributor to the Python language, starting from nothing - we supply the motivation, the skills, and then the hands-on practice. I'd like to see this produce both an immediate new set of Python contributors (including me) and a new way of bringing contributors in.

I hope to see you there!

Friday, July 02, 2010

talking with women

A man at a conference I was at a couple months ago approached me to talk about databases.

It was, in all ways, a good and appropriate conversation, and an example of the reason I go to conferences like that in the first place. But he later confessed to me that he'd been very hesitant to speak to me because he was afraid it would come across as cover for some kind of flirtation. It seemed ridiculous, because he was so far from anything inappropriate, but his uncertainty came a hair's breadth from actually diminishing the conference's benefit to both of us.

You see the big fat irony. Avoiding sexualizing a woman's professional environment is an absolutely appropriate and important goal. But sidelining women from a professional community's social aspects is genuinely harmful.

Most men can easily judge for themselves the difference between friendly and creepy, but geekdom is infamous for its high proportion of the awkward.* I'd love it if there were a really clear and well-known rule of thumb that would assure even the most shy and awkward guys about where "the line" is. The hard part is that men differ so widely in their judgements and self-judgements. Some will be critical or suspicious of themselves at virtually anything, and some find excuses for even the most egregious of their own behavior. It's hard to know how to encourage the former but not the latter.

My first thoughts -
  • Imagine that she were a man. Would you still do or say what you're doing or saying now, or would it feel too awkward?**
  • If you're genuinely worried about it, you're probably not a problem guy in the first place.
What are your thoughts?

* - Understand that, when I say this, it's with affection. I love the socially awkward! I find communities where everybody adheres smoothly to a single social standard to be boring and uncreative. I hope geekdom will always be a haven for the awkward.
** - Obviously not a very useful standard for bisexual people.

Thursday, June 10, 2010

Dayton Dynamic Languages User Group

In Dayton, we don't have a dedicated Python user group; instead, we have the Dynamic Languages User Group. I always struggle to explain why I enjoy this group so much, because a quick description doesn't sound that impressive. Each meeting is 5-10 people scattered across the entire dynamic language landscape: Python, Ruby, Perl, JavaScript, PHP... now and then somebody will throw in some LISP or whatnot. There's only occasionally a formal presentation.

Instead, there are people who are very open about sharing both what they know (which is impressive) and what they don't know (which is more important). I've never been in a group where people are more uninhibited about saying, "Wait -- I don't get it." As a result, everything we do gets enriched by some extremely good discussion.

When we don't have a formal presentation, we sometimes walk through a code project somebody's working on, or research a programming topic together (like dependency injection). Recently we've started publishing a simple programming problem and asking the members to bring a solution in their favorite language - reviewing the various solutions is a nice exercise in both language details and programming approaches.

Come see us sometime. We meet the second Wednesday of the month at 7:00 PM at the Dayton Chess Club.

Wednesday, June 09, 2010

On the error message soapbox again

Q. What's wrong with this message?

Database Configuration Assistant: Info - There is an error in creating the following process: /data/ora/oracle/product/11.2.0/dbhome_1/bin/sqlplus -s -N /NOLOG  The error is: /data/ora/oracle/product/11.2.0/dbhome_1/bin/sqlplus: error while loading shared libraries: /data/ora/oracle/product/11.2.0/dbhome_1/lib/ cannot restore segment prot after reloc: Permission denied
A. The window that it pops up in doesn't support copy-and-paste (on Fedora 13, at least). If you want to websearch for this message, you have to type it in by hand.

Hey, Oracle - fix it, please? It's the sort of usability problem that I wouldn't nag you about if you were a little FOSS project or a mom-and-pop software shop, but you're a big company with fifty bazillion programmers and entire committees on usability, so I know you can do it.

I'm sure that's the fault of whatever Java GUI library underlies your graphical tools like dbca... so go on and fix the library, and the whole world will benefit!

Also, in keeping with my fixation with good error messages, I implore you to think about error message usability ahead of time. I suspect that error messages get the short end of developer attention because they never appear in sales presentations. Well, actually, they do appear in sales presentations, they're just not supposed to... (although, frankly, watching somebody work through an error is a million times more interesting than watching a polished sales pitch)

Q. What else is wrong?

A. The workaround to this error is to disable SELinux. For the ultimate bestest securest database EVAR, doesn't that seem a little cheesy?

Q. Anything else?

A. Until you actually achieve SELinux compatibility, how about trapping the error with a message that describes the workaround? Failing that, mentioning in the Installation Guide that SELinux should be turned off is a next-best solution... no, come to think of it, forget I said that. "It's on page 732 of the docs" is actually a terrible excuse for leaving a bug unfixed. I don't know how "document it" became an acceptable alternative to "fix it".

Q. Are you finished yet?

A. Almost. After more than 10 years of DBA work, I actually don't know what the proper channel is for making suggestions to Oracle Corp. I end up ranting about it on my blog, approximately the equivalent of wandering into the street and yelling about it. Is that silly or what?

I'm Catherine Devlin, and I approved this message.

Thursday, May 27, 2010

templating engine cookoff updated

Ian wished for loop syntax examples in the Templating Engine Cookoff, so I just added them.

And none of you Django programmers have given me code to include Django templates in the cookoff. You can't throw an exception in this town without hitting a Django programmer, so what's up? C'mon, it's easy - I just need something analogous to this:

The answer to the Ultimate
Question is ${everything['universe'].answer}.

Among our weapons are:
% for weapon in weapons:
% endfor

import mako
import mako.template
class MakoDemo(Demo):
name = 'mako'
version = mako.__version__
def demo(self, vars):
self.template_name = 'mako.txt'
template = mako.template.Template(filename=self.template_name)
return template.render(**vars)

[EDIT: Well done, Django folks! Django is in the cookoff now. Except... hmm... it reacts to missing variables by leaving blanks instead of throwing an exception... so I need a new trick if I want to actually see the Django error stack.]

Tuesday, May 25, 2010

Richard Jones alerted me to Martin Blais', and I like it very much.

Richard's post focuses on the improvements to bind variable handling. I love for another reason: it provides query results as namedtuples, a class so perfect for database resultsets that they make me sob with relief.

>>> import cx_Oracle, dbapiext
>>> connection = cx_Oracle.connect('username/password@SID')
>>> results = dbapiext.execute_obj(connection, 'SELECT * FROM crew')
>>> row =
>>> row
Row(ID=1, NAME='Kaylee Frye', ROLE='Mechanic')
>>> row[1]
'Kaylee Frye'
>>> row.ROLE

When memory isn't an issue, I like to transform the result into a list and tack on a simple equality filter method for convenience.

class Filterable(list):
def filter(self, **kw):
for itm in self:
for k in kw:
if not (getattr(itm, k) == kw[k]):
yield itm
yield StopIteration

>>> result = Filterable(dbapiext.execute_obj(connection, 'SELECT * FROM crew'))
>>> result.filter(NAME='Jayne Cobb').next()
Row(ID=5, NAME='Jayne Cobb', ROLE='Public Relations')

It is, of course, no SQLAlchemy, and isn't meant to be. It's meant to be a roadmap toward a less awful DB-API for Python. (I still wake up in the middle of the night, gasping, "Five incompatible bind variable formats! It's heresy!") In the meantime, is a nice lightweight layer for times when SQLAlchemy is too much. For instance, I write lots of database administration tools that poke around in lots of different views of Oracle's data dictionary, and setting up SQLAlchemy mappings for each of them is a pain. is perfect for that. Thanks, Martin!

Monday, May 03, 2010

Penguicon wrap-up

Thanks to the wonderful audience at my Ren'Py talk. Your patience and your questions got us through the painful time of waiting for the projector to work... bless you all! I hope you have fun with Ren'Py. I've posted my slides and sample game in the Ren'Py forum * here *.

Oh, and I saw a flashbulb during the talk... if you're reading this, could you send me a copy of the photo? I don't have a good recent photo of myself presenting. Unless it sucks, that is. :)

Some of Penguicon's other highlights, from my POV:

Adrian Crenshaw's talk on Mutillidae was delightful. I am so tempted to quit my job and become a security researcher; they have all the fun. He tipped us off to some Firefox extensions for conveniently testing websites for some common vulnerabilities, too.

Matt Arnold's talk on Inform7, which showed me wonderful tools the Inform IDE comes with. It's amazing to see how much work has gone into a language that has such a specialty purpose. I hope I'll find time to put some more work into Inform7 games. I loved this exchange:
Attendee: Is there a limit to how many [options] there can be?
Matt: No! The limit is your sanity!

The dance. I love dancing with nerds. It's so much more fun when the cool kids aren't there. I miss the good old days, though, when we danced to songs, instead of to interminable dance beats. Ah well.

During Mark Ramm's talk about implementing Sourceforge's new TurboGears/MongoDB infrastructure, a questioner invited him to complain about strict schedules for completing a job. Instead, he said that he likes demanding, inflexible deadlines; having flexibility on a project's scope is how you get things done. I thought that was a wondefully wise point of view. A flexible timetable can be an excuse for not triaging a project's scope; a firm deadline helps you make those necessary decisions and actually get something done.

Friday, April 23, 2010

Dayton Oracle meeting

DAY-O, the Dayton Oracle user group, is meeting May 4 - a week from this Tuesday. We've got a full-day meeting planned with lots of great content... see for full details.

09:00 AM - 09:30 AM Meeting Registration / Door Prize Raffle Registration
09:30 AM - 10:00 AM Sun / Oracle Merger Update - Gary Hall (Sun / Oracle Corp.)
10:00 AM - 10:30 AM Leading Spaces and Their Diagnosis with Toad for Oracle, A Toad® for Oracle Case Study - Michael Allen (
10:30 AM - 10:45 AM Break
10:45 AM - 11:45 AM Oracle Fusion Middleware 11g Update / Roadmap - Eric Rudie (Oracle Corp.)
11:45 AM - 12:40 PM Lunch - Pizza
12:40 PM - 01:25 PM Exadata 2 Database Machine - Gary Hall (Sun / Oracle Corp.)
01:25 PM - 01:30 PM Break
01:30 PM - 02:30 PM Security and Compliance with Oracle Database 11g Release 2 - Eric Rudie (Oracle Corp.)
02:30 PM - 02:45 PM Announcements / Raffle

Thanks to Matt Morrisey and Vicki Blommel for their organizational work, and to Oracle for being our meeting sponsor!

Thursday, April 22, 2010

Bugfixing at PyOhio

Jesse Noller wants to know what's holding you back from working on Python.

He's looking to make the process of contributing to Python more smooth and self-explanatory, less intimidating. That's a good discussion, and I'm not sure what to tell him right now, but it does bring to mind something I really want to see.

Let's have a Python Bug Fixing Tutorial at PyOhio!

Walk everybody nice and slooooowly through the process of browsing through the Python bug tracker (for bugs in Python itself, in its standard library, etc.), checking out code, fixing and testing, making a diff file, submitting the fix. Don't assume that people are familiar with VCS, diff files, the test suite, etc. - all those tools and jargon that separate veterans from intimidated users. Let's break down that separation.

Our Call for Proposals is open right now (through May 10). What a coincidence! I'm not actually on the program committee, so I can't promise that such a proposal would be accepted, but let's just say that the committee will give it serious consideration if they know what's good for them. :)

I'm asking you to propose this, not me, because I am not crazy enough to think that I can lead such a tutorial while chairing the conference; especially since I've never actually done it before myself. Actually, maybe there's one way I could do it: taking the role of the leader/learner in a "Teach Me Twisted"-style you-teach-me session. In that case, I'd want commitments from... hmm... let me say 3+ experienced bugfixers to talk me through it in front of a live audience.

One way or the other, let's see to it that PyOhio transforms some Python users into contributors!

Pythonic PL/SQL

Pythonic PL/SQL exists!

I imagine it will grow in fits and starts as my job needs dictate, but it shouldn't ever be abandoned, since I'm incorporating it gleefully into my own production code.

So far, format (Python 3-style string formatting) and join are available. I'm not using object-oriented PL/SQL at all (I find it very unsatisfactory), so instead of
','.join(mylist), you use pythonic.join(',', mylist).

I'm very open to contributions from others! There's plenty of room to participate, since implementation has barely begun.

There are Quest Code Tester tests for it, too, but unfortunately that's a closed-source project and I have to check on what the rules are for releasing tests produced with it.

Of course, most hard-core PL/SQL developers will already have written or found code to handle basic, common operations like this. But, by sticking close to names and APIs we're familiar with from another increasingly well-known language, I hope to reduce the amount of brainspace you need to remember how to do it all.

Usage samples::
crewlist pythonic.string_list
:= pythonic.string_list ('Wash', 'Kaylee', 'Mal');
crewdictionary pythonic.string_dictionary;
template VARCHAR2 (100);
DBMS_OUTPUT.PUT_LINE (pythonic.join ('; ', crewlist));
-- output: "Wash; Kaylee; Mal"
SELECT name FROM crew ORDER BY name;
DBMS_OUTPUT.PUT_LINE (pythonic.join (' *** ', curs));
-- output: "Kaylee *** Mal *** Wash"
template := '{2}! {1} says we''d better replace that catalyzer!';
DBMS_OUTPUT.PUT_LINE (pythonic.format (template, NULL, 'Kaylee', 'Captain'));
-- output: "Captain! Kaylee says we'd better replace that catalyzer!"
DBMS_OUTPUT.PUT_LINE (pythonic.format (template, crewlist));
-- output: "Mal! Kaylee says we'd better replace that catalyzer!"
crewdictionary ('First Officer') := 'Zoe';
crewdictionary ('Public Relations') := 'Jayne';
template := '{First Officer}: (to {Public Relations}) "I can hurt you."';
DBMS_OUTPUT.PUT_LINE (pythonic.format (template, crewdictionary));
-- output: Zoe: (to Jayne) "I can hurt you."

Monday, April 19, 2010


I'm itching to begin creating a bunch of PL/SQL packages that will emulate certain handy Python features. Before I sink too much time into it, does the LazyWeb have anything to recommend? Or, perhaps, volunteers to help make the dream come true?

I want to start with a package for Pythonic string manipulation:

'The {0} brown fox jumped over the {1} dog'.format('quick','lazy')

... and so forth

I think this package would not just implement the ones that don't exist in SQL or PL/SQL, it will provide Pythonically familiar names and interfaces to the ones that do exist.

Granted, there's only so Pythonic you can get in PL/SQL. A perfect set of packages would be a heroic task. Still, it's easy to imagine helping PL/SQL to suck less...

Sunday, April 18, 2010

templating engine cookoff

There are more Python string templating engines in the world than homemade chili recipes. Which is tastiest? Let's have a cookoff!

We all have different criteria, of course. The only organized comparisons I've seen between them are based mostly on measuring speed of rendering. Huh? I have never said to myself, "Wow, I'm wasting so much time because these templating engines aren't rendering fast enough. If only they would finish in 0.4 seconds each instead of 0.6!"

I have said to myself, "Wow, I'm wasting so much time because there are errors in my templates, and my templating engine isn't helping me find them." Writing templates is tricky. Errors are common. So, for me, clear error messages are the key virtue. My cookoff focuses on recognizing the engines that report the filename and the offending string when a rendering failure occurs. It also displays a typical simple syntax for writing and using each type of template (so it can serve as a cheatsheet as well).

My results? So far, only jinja2 and genshi report both filename and the error-causing string. The jinja2 error stack is more concise overall, so I award it the prize by a nose.

I'm really happy with the framework I wrote for doing the cookoff, too, so I posted it on Launchpad. It is really, really easy to add new engines for comparison - feel free to suggest or submit them! In fact, I hope that others can adapt my cookoff framework to other situations that call for side-by-side package comparisons.

Incidentally, why are comparisons like this usually styled "smackdowns" or "shootouts"? What's up with that? We're not trying to put anybody in the hospital! We're just trying to select our favorite from a banquet of delicious offerings. Eat up!

Monday, April 12, 2010

I'm speaking at Penguicon

Ren'Py: A Visual Novel Engine

Computer gaming, anime/manga, Python programming, fiction writing: Ren'Py is everything you love about Penguicon rolled up into one. It's an open-source visual novel engine that lets you program graphical games and stories with the greatest of ease. Creating basic linear or branched stories is almost as easy as writing them on paper - yet Ren'Py is also a full-fledged Python environment, so there's no limit to what you can program as you learn. This intro will show you everything you need to start creating your own masterpiece. Ikimashou, otaku-san!

May 1, 2010, 12 noon - 1 PM
Detroit Marriott Troy
200 W. Big Beaver Rd.
Detroit MI 48084

YOU: Okay... but will you give the presentation wearing a homemade Elizabethan-era dress?
ME: Yes!
YOU: Cool! Um... why?
ME: Because this is Penguicon!

What's Penguicon? It's an open-source software conference... it's a science fiction fandom conference... it's an awesome hybrid of the two! Super-sharp technical people come for some awesome knowledge sharing, and the SF fans help make the atmosphere even more relaxed and imaginative than at a normal FOSS con. I love both sides of the con and especially the ways they mix together, which is why I wanted to give a talk this time that would really encompass it all. (Costumes are totally optional, by the way. But they sure are fun!)

(Psst - if you install Operator, you'll be able to automatically process the microformatted data in this post and add it to your calendar. Cool, huh?)

See you in Detroit!

PyOhio Call for Proposals

PyOhio's is out, due May 10. Let your imagination run wild; PyOhio is what we make it, no more and no less. Help us make this year's PyOhio the best yet!

Friday, April 09, 2010


A free service aggregating information about tech events in Dayton

There's too much geeky awesomeness going on in town to track with your brain alone. daytontechevents fixes that. If you're in or near Dayton, keep an eye on it so that you don't miss something fantastic! If you know of a group or event around here that isn't yet on daytontechevents, add it!

Thanks to Sarah Dutkiewicz, who got the idea and put the infrastructure in place not just for Dayton, but also for Columbus and her hometown Cleveland. Ohio thanks you, Sarah!

Thursday, April 08, 2010

Pooled nonprofit IT

File this one under "Daydreaming".

There are lots of small, local nonprofit organizations that really can't afford to do their IT well. They can't afford a full-time professional, so they make do with unskilled labor, plus a smattering of donated services and what short-term contractual help they can afford. Each time, the solutions implemented depend on the skills and tastes of the implementor, and rarely build usefully on what has been implemented before.

Imagine the efficiencies if many organizations could share a small, full-time IT staff dedicated to their needs. Most organizations share many of the same needs, and could share the same set of solutions. A full-time pro would become familiar with those needs and could efficiently apply a well-known solution to each group. (S)he would provide continuity, well-informed decisionmaking, and perfectly specialized skills.

Providing this would seem like a natural role for, say, an organization like the United Way; or perhaps for a small meta-charity created for the purpose. I'm sure private firms have attempted to set themselves up in this role, but anything that demands a steady funding outflow from the benefiting agencies is a tough sell, no matter how beneficial it would be in the long run.

I'm just daydreaming, but I'm interested in people's comments. Has anybody heard of something like this being done?

Wednesday, March 24, 2010

Community Service Award

Facundo Batista and I received the 4th-quarter Python Software Foundation Community Service Awards!

I actually heard about it several days ago, and have been tongue-tied (keyboard-tied?) since then. I'm mostly seen in and around Ohio these days, but I grew up thoroughly Minnesotan. If you pay Minnesotans a really extravagant compliment, you'll send them into a kind of blushing panic. All of our ancestors who enjoyed the limelight were found and eaten by bears, you see, so we evolved a genetic terror of having attention called to us.

Anyway, this is one of the most flattering honors I've ever received. THANK you, PSF! I hope I'll always be one of the Python world's many valuable contributors.

Wednesday, March 03, 2010

cmd2 0.6.1

Many thanks to the audience at my PyCon cmd/cmd2 talk for your interest and enthusiasm! It was my first full-scale PyCon presentation and I absolutely loved it.

I need to follow up on three things I claimed in my talk:

1. "My presentation is already online at". FALSE (at the time I said it, and for several days afterward). I actually had posted the docs and edited the PyPI page to point to them, but forgot to update url in, so it overwrote the link when I registered cmd2's 0.6.0 release.

It's fixed now, though. The cmd2 PyPI page has a link to the cmd2 documentation, which in turn links to my talk slides. You can also watch the talk thanks to the fantastic PyCon video crew!

2. "A more stable version will be out within a couple weeks of PyCon." TRUE. 0.6.1 is not exactly stable stable, but I think I've smoothed out bugs that snuck in while I was pushing to release 0.6.0 for PyCon.

3. "sqlpython will be more presentable in a couple weeks, too." TRUE. The new sqlpython 1.7.1 brings the postgreSQL functionality (thanks Andy!) to pretty near 100% (except for the can't-see-other's-schemas problem, which should be fixed for 1.7.2.) I believe that MySQL should be fully functional, too, but that's very lightly tested because I barely use MySQL and don't know much about how to test it.

Tuesday, February 16, 2010

Computer Engineer Barbie

I'm happy about Computer Engineer Barbie. No doll will save the world, but every little bit helps.

It's annoying, though, that some people only see one more opportunity to trot out this classic:
def belittle(geek):
prejudice = "Well, then, she's not much of a {0}, is she?"
if geek.is_femme:
excuse = 'geek'
excuse = 'woman'
return prejudice.format(excuse)

Wednesday, February 10, 2010

sqlpython 1.7 pre-release

First off: PyCon online registration ends TODAY. Go do it NOW.

I intend to show off sqlpython at PyCon. Version 1.7 works with postgreSQL and MySQL as well as Oracle. (In fact, a single sqlpython session can keep connections to all three types of databases open at once!)

1.7 isn't quite ready for PyPI yet; I've just posted an appeal for sqlpython testing, with instructions for getting the development version, to the sqlpython google group. If you'd like to take the new-and-improved sqlpython for a spin around your databases, I would hugely appreciate it. Anticipate a PyPI release just before PyCon, once the ugliest of the bugs are worked out.

See you in Atlanta!

Tuesday, February 02, 2010

Hey, Oracle!

You're scaring me!

In the last couple months, we've learned that the new Sun will be going forward without Frank Wierzbicki, the Jython project lead, and now without Ted Leung.

The Oracle Technology Network is working hard to foster dynamic language use with Oracle. It's got publications, PyCon sponsorship, resources, and so forth. OTN delights me.

I'm afraid, though, that the larger Oracle corporation doesn't share OTN's interest. Oracle's absorption of Sun is proceeding without any apparent interest in dynamic languages. Oracle is discarding some of the finest talent it could possibly acquire, people who could have helped bring on a real flowering of dynamic language use in Oracle environments.

I, for one, would have loved to see Jython harnessed on Oracle's many Java-based tools and even the JVM in the Oracle database - imagine the wonders Frank and Ted could have worked with that, had Oracle assigned them to! Instead... there will be nothing Oracle-related from them. Meanwhile, Microsoft funds development of several dynamic languages, including IronPython, which integrate to SQL Server through .NET.

I don't know. I just dread the thought that, five years from now, SQL Server will be the proprietary database of choice for any environment where dynamic languages are used... which will soon be most environments. Oracle, you really want to give this market away?

Wednesday, January 20, 2010

How to write a bad abstract

Ironically, the only talk that disappointed me at all at CodeMash was... mine. I thought my delivery was a little rough - pretty much because it's a really bad time of year for me to practice a talk.

I had a (great, attentive, but) smallish audience, too. One of the reasons was simple scheduling - there were some amazing talks opposite me. I was tempted to slip out and watch one myself! The biggest problem, though, was me. I wrote a bad title and abstract for the program guide.
reStructuredText: Plain Text Gets Superpowers
Technology/Platform: Python
Difficulty Level: Beginner

Abstract: Write a document, just once, in plain text. Enjoy all plain text's benefits - speed, simplicity, scriptability, version control. Now, from this single plain text source, automatically generate beautifully-formatted webpages, presentations, .PDFs, auto-indexed documentation trees, and more. It's time to quit slacking on documenting your software. reStructuredText will make you actually enjoy writing docs!
What's wrong with this? It's a nice narrative that fits together and builds to a nice little conclusion... but it's bad for a program guide.

I assumed attendees would read the whole abstract carefully. Then, when I got to CodeMash, what did I do to select sessions I would attend? I quickly scanned over the list of titles, and based on that, hastily read some of the abstracts. I forgot that geeks are pressed for time, especially at conferences!

There were three important messages for attendees to know to decide whether to come:

1. This is a talk about writing documentation
2. It is independent of what programming language you use
3. This talk provides a helpful tool (i.e., it's not just a preachy sermon)

You have to read all the way to the end of my abstract to get messages #1 and #3, and #2 is never communicated clearly at all. So, what would a good title and abstract have looked like?
Your Docs Won't Suck Anymore
Technology/Platform: Other *
Difficulty Level: Beginner

Abstract: No matter what programming language you write in, it's the English language that's killing you - your lack of good documentation is driving potential users away. reStructuredText is a technology and a family of tools that will make writing documentation easy, powerful, and satisfying. We'll introduce reStructuredText and get you started on writing beautiful documentation for any program or language.
* - "platform-independent" would have been the best choice for "Technology", but it wasn't in the dropdown. I worried that choosing "Other" would imply reST was implemented in Scala or something. I should have done it anyway, though, because most CodeMash attendees don't know Python and probably read "Python" as "not for me".

The take-home lesson here: when writing titles and abstracts, be very mindful of the divided and rushed attention of the typical geek. Don't be coy and save the good stuff for the fine print. Get your message across up front.

Monday, January 18, 2010

Fear is not a virtue

I know there have been a million news items like this, but this is the one that puts me over the edge.
SAN DIEGO — Students were evacuated from Millennial Tech Magnet Middle School in the Chollas View neighborhood Friday afternoon after an 11-year-old student brought a personal science project that he had been making at home to school, authorities said.

Maurice Luque, spokesman for the San Diego Fire-Rescue Department, said the student had been making the device in his home garage. A vice principal saw the student showing it to other students at school about 11:40 a.m. Friday and was concerned that it might be harmful, and San Diego police were notified.

The school, which has about 440 students in grades 6 to 8 and emphasizes technology skills, was initially put on lockdown while authorities responded.

Luque said the project was made of an empty half-liter Gatorade bottle with some wires and other electrical components attached. There was no substance inside.
Luque said the project was intended to be a type of motion-detector device.
Both the student and his parents were "very cooperative" with authorities, Luque said. He said fire officials also went to the student's home and checked the garage to make sure items there were neither harmful nor explosive.

"There was nothing hazardous at the house," Luque said.

The student will not be prosecuted, but authorities were recommending that he and his parents get counseling, the spokesman said. The student violated school policies, but there was no criminal intent, Luque said.

I finally understand Al-Qaeda's master plan, and it's freaking brilliant. Resenting American technological dominance, they have found a way to end it, convincing us to semi-criminalize technical curiosity and thus lobotomize our culture. I'm just surprised that we're choosing to participate in the plan. I thought we were on opposite sides?...

Is there a political movement or group I can join to fight this? Common-sense people grousing about how stupid each incident is is failing to hold back the tide. Something vaguely like the EFF but with a broader scope - because all science and technology is under attack now.

Fear is not patriotic. Fear is not a public service. Fear is not a virtue.

Sunday, January 17, 2010


Gloria Jacobs told me about MongoDB at PyOhio, but I was too busy conference-chairing to see her talk, and time has flown by. Her enthusiasm prompted me to see Mike Dirolf's MongoDB talk at CodeMash, though, and wow. Thanks, Gloria and Mike! I like it, I really like it!

My frustrating experience with BigTable had given me a "Bah, humbug!" attitude toward the NoSQL fad, but it really looks like MongoDB is the cure for that. It surrenders much less query capability than the other NoSQL contenders do. The simplest of those are useful only if you already have the key for your desired record in hand, and BigTable's limitations make it feel only moderately better to me. But MongoDB's query capabilities are really rich, good enough for many (though of course not all) real query needs.

Now, don't get me wrong; there are a *whole lot* of tasks for which an RDMBS is still very much the answer. When you need transactions, or child items that aren't tucked neatly under single parents, or complex queries - and how often do you really *know* that you'll never need complex queries? - it's safer to use an RDMBS.

I think that, when the database is an enduring construct, important in itself - when multiple applications may be written against it, and new applications yet unforeseen may appear in the future - then a good RDBMS is the only way to go. In such cases, it's just impossible to safely predict what you'll need to do with the data one day, so you need database software that can do virtually anything.

But when the database will play a supporting role to a single, well-defined application, and will not outlive the application. then a non-relational database could be very convenient, and MongoDB looks to me like a fantastic choice.

Let's call this Devlin's Doggy Directive of Databases:
If the application is the dog, and the database is the tail, consider a non-relational database.
If the database is the dog, and the application is the tail, stick with a relational database.
If you doubt that I'm qualified to go naming rules of thumb after myself, let me remind you that have ten years of relational database experience, a sparse smattering of non-relational experience along the way, and that my parents owned a boarding kennel when I was young.

CodeMash general recap

Believe the hype. CodeMash is all that. It's people from all over the region and beyond whose enthusiasm and intelligence is too much to stay channelled in one technology. There are consistent preferences - for agile methods, open-source code, etc. - and a majority user community - .NET - but it's full of people who know that cross-pollination and cross-training are where it's at.

The one problem is the same one that all big conferences have: the scheduled talk track is so rich that it's almost impossible to pull yourself away to the Open Spaces. As next year's planning begins, I'll agitate for a schedule that somehow makes some Open Space time that doesn't run parallel to sponsored talks; I actually think Open Spaces on the precompiler day (maybe as the entire content of the precompiler day) would be a great idea. Except that it's probably best to let the regular conference content prime the pump first... hmm...

Saturday, January 16, 2010

reStructuredText talk follow-up

Thanks to everybody who saw my reStructuredText talk at CodeMash 2010! My slides are at the end of Those who asked questions I couldn't answer - thank you! I'll be researching the ones I remember so that I can post on them; commenting or emailing me reminders of your questions - or new ones - would be much appreciated.

I had a great time at CodeMash; the organizers deserve a huge round of applause. I'll post more extensively with some of what I learned... after catching up on sleep.

Thursday, January 14, 2010

Codemash - day 0 (precompiler) report

A good start to CodeMash. I started with a session on the Ruby Koans, a very nice way of teaching; it tempts me to join the crew building a corresponding set of Python Koans. In fact, it would be really interesting to host Python Koans on Google App Engine... Hmm...

Next I went to Mary Poppendieck's session on leadership in software; alas, for me, it was as much frustrating as inspiring. She described techniques proven to produce good software consistently, and I see very few of them in use in the Air Force. Worse, the Air Force is driving hard to make the problem worse: centralizing, centralizing, centralizing - building up the separation between decisionmakers and IT professionals and IT users with thicker and thicker walls made of miles, layers of management, internal organziational boundaries, and government:contractor barriers. *sigh*

She did, however, make me realize that my employer - a small contractor that sends IT professionals in ones and twos to work on projects as our customers need - can do a lot more to improve skills among our employees. We could get together occasionally from our various customer sites to work together on our skills, or at least have a mailing list for technical chat among our employees.

But here's a question - from a purely selfish point of view, is this the right way to spend my energy? After all, there are already plenty of groups of professionals dedicated to mutual skill improvement. They're called user groups, and the time I spent on internal skill development could just as well be spent deepening my involvement in local user groups; the payoff may be bigger, because I'd be involved with a self-selecting group, with people who already believe it's worth going out of their way to hone their own skills and others'. User group members have an attitude, a hunger and thirst and personal committment to excellence, and trying to create that attitude among my company coworkers may be a lot less fruitful than taking advantage of people who alreay have it.

Your thoughts?

Anyway, today begins CodeMash in earnest, and I'm loving it. Most of all, I like meeting up with old friends and meeting new ones. Geeks - particularly geeks who are active in the user community - are just fun, interesting people to be around!

Tuesday, January 05, 2010