Saturday, November 1, 2008

3 Days: Basketball Time

Have you ever noticed that the last part of any project seems to take much longer than it ought to? I call this phenomenon Basketball Time.

A typical college basketball game has a 40-minute clock and most games take about two hours of real time to play. But, the last 2 minutes of clock time takes about 20 minutes of real time. In other words, 5% of the game takes 17% of real time. Whereas the first 38 minutes run at a rate of 2.1 real minutes per clock minute, the last few minutes run at a rate of 10 real minutes per clock minute. It's like the game is heading toward a black hole and there's time dilation or something.

At the end of a software project, the same thing happens. Right now, my todo list isn't very large, but it seems that every time I remove something, I add something else (or two). And all sorts of little things take much longer than one thinks they will.

A case in point: The hours I just wasted trying to do something that I thought should be trivial -- creating a Django custom tag. The custom tag is the clean way to do it and I estimated that the alternative (code I probably would have had to throw away later) would have taken me an hour to get right. So, the custom tag seemed the way to go. But, as is frequently the case in open source projects, I was hampered by poor Django documentation, which left out some details. I found a number of blog posts about the problem, some with their own misinformation. Fortunately, it turns out that GAE provides an (apparently undocumented) mechanism which makes things easier.

For the record, here's how to set things up so that you can have a set of custom filters available to all templates in your Google App Engine application. Create a file custom_filters.py that looks like this:

from django import template
from django.template.defaultfilters import stringfilter
from google.appengine.ext import webapp
 
register = webapp.template.create_template_register()

@stringfilter              # If applicable
@register.filter
def myfilter(value):
    return value

myfilter.is_safe = True    # If applicable
Then, put the following at the bottom of main.py:
# Register custom Django filters so they're available to all templates
from google.appengine.ext import webapp 
webapp.template.register_template_library('custom_filters')
If you put custom_filters.py in a module, make sure to specify the module name (as in 'common.custom_filters').

P.S. I have looked for references to "Basketball Time" that predate my usage, but I have not found any. If you know of one, I'd be interested in hearing about it.

1 comments:

sb said...

Dude, you have NO IDEA how grateful I am for your posting this...

I've been trying all kinds of alternatives, since this was nowhere clarified until now.

Now instead of pre-fabricating all the data, I can push Datastore nodes through filters -- so much lighter on my sanity.

Thank you!

Post a Comment