What I hate about PIL and Image in Python

October 19, 2009
6 comments Python

One really annoying thing about PIL is that it's importable as Image and PIL. It leads me and other newbies to think if it's different. I don't want choices:


Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import PIL
>>> import Image
>>> ?

When PIL/Image is put into standard lib, can we call the module: imaging?

Messed up columns in Django Admin

October 16, 2009
1 comment Django

In case this bites someone else like it bit more and chewed off many many minutes of debugging time.

If you ever get weird columns in your Django Administration interface, I now know why that happens. See this screenshot example:

Messed up columns in Django Admin

This happens when you've defined a TEMPLATE_STRING_IF_INVALID in your settings.py. I always put in my local_settings.py this line:


TEMPLATE_STRING_IF_INVALID = '{{ %s }}'

So that I can quickly see which variable references in template code is potential typos. I'm not a big fan of the implicit magic of equating absence to False/None so I try to avoid the confusion altogether.

Automatically strip whitespace in Django forms

October 12, 2009
2 comments Django

The current project I'm working has at the time of writing 20 different forms (90% model forms) instantiated in different scenarios. Django doesn't automatically strip whitespace in text based fields. So instead of doing this:


class ContactMarketingForm(forms.ModelForm):
   class Meta:
       model = ContactMarketing
       exclude = ('contact',)

   def clean_notes(self):
       return self.cleaned_data['notes'].strip()

   def clean_name(self):
       return self.cleaned_data['name'].strip()

Instead I wrote a common class for all of my form classes to use:


class _BaseForm(object):
   def clean(self):
       for field in self.cleaned_data:
           if isinstance(self.cleaned_data[field], basestring):
               self.cleaned_data[field] = self.cleaned_data[field].strip()
       return self.cleaned_data

class BaseModelForm(_BaseForm, forms.ModelForm):
   pass

class ContactMarketingForm(BaseModelForm):
   class Meta:
       model = ContactMarketing
       exclude = ('contact',)

Now all text inputs and textareas are automatically whitespace stripped. Perhaps useful for other Djangonauts.

A user-friendly TinyMCE config

October 8, 2009
4 comments Web development

A user-friendly TinyMCE config When you enable TinyMCE you can either choose theme="simple" or theme="advanced". If you go for the simple you get one lovely little bar of buttons but it's missing the link button which is more important than most other buttons altogether. When you enable "advanced" you get three rows of buttons that makes you dizzy. I mean, should really be editing advanced tables in a WYSIWYG editor or mathematical equations?

Here's a config that I think works great. It's all in one row and it's got the bare minimum in terms of additional plugins (no extra downloads required). It's in Python but translates quite easily into Javascript:


TINYMCE_DEFAULT_CONFIG = {
   'plugins': "fullscreen,paste,autoresize",
   'theme': "advanced",
   'theme_advanced_buttons1' : "bold,italic,strikethrough,bullist,numlist,"\
                               "separator,undo,redo,separator,link,unlink,image"\
                               ",separator,cleanup,code,removeformat,charmap,"\
                               "fullscreen,paste",
   'theme_advanced_buttons2' : "",
   'theme_advanced_buttons3' : "",
}

London Frock Exchange launched

September 26, 2009
0 comments Work, Django

London Frock Exchange launched Today we launched The London Frock Exchange which is a joint project between Fry-IT, Charlotte Davies and Sarah Caverhill

Elevator sales pitch: Unlike other clothes swapping sites, with Charlotte, Sarah and Rani as an expert hub in the middle you don't swap straight across; no you swap one frock in and can choose a frock (of equal value) from the pool of frocks.

Fry-IT is co-founding this venture and hope it'll make us billionaires by the end of the year (They take a small admin fee of £25 for sending you a frock back but sending it in is free with freepost). It's been great fun to work on it over the last couple of months as it means we (Fry-IT is a all-male highly technical company) have had to learn about sizes, body shapes and trying to learn how a female web audience thinks. The ladies have done a great job of seeding it with lots and lots of frocks all of which you can wear in a matter of days if you just swap one of equal value in first. Enjoy!

My first Twitter app - KungFuPeople.com

September 22, 2009
0 comments Python, Kung Fu

My first Twitter app - KungFuPeople.com I've just finished my first Twitter app. It's basically a just a about using OAuth to allow people to sign up to KungFuPeople.com without having to pick yet another password.

I simply took the oauth.py module by Leah Culver and wrapped it with some useful functions taken from a similar Twitter app we've done at work.

Unlike other Twitter apps for this one I'm using Twitter solely for handling authorization and authentication. That means that it has to work with the existing user + profile functionality but just side-step the sign up and login.

Next goal: Google OAuth

Comparing jsmin and slimmer

September 17, 2009
3 comments Python

JSMIN - The Javascript Minifier is written in C and it does an excellent job of minifying Javascript code. After all, Douglas Crockford wrote it. I noticed there's a Python implementation of it so I wanted to see how it stacks up against my slimmer which is also written in Python.

For sake of argument I compiled the C version and ran that in my little benchmark and did so by using the subprocess module. Also, for the sake of comparison I threw in a run with YUI Compressor. Here are some quick results:


On js/signup-core.js
--------------------
js_slimmer
from 9708 to 6905 in 0.0245039463043 seconds
jsmin
from 9708 to 6720 in 0.0850019454956 seconds
jsmin.c
from 9708 to 6721 in 0.0026159286499 seconds
yuicompressor
from 9708 to 6102 in 0.914173126221 seconds

On js/zoom.js 
-------------
js_slimmer
from 5920 to 3712 in 0.0106379985809 seconds
jsmin
from 5920 to 3582 in 0.0582370758057 seconds
jsmin.c
from 5920 to 3583 in 0.00282216072083 seconds
yuicompressor
from 5920 to 2771 in 0.839382171631 seconds

On js/diypack.js
----------------
js_slimmer
from 21559 to 14059 in 0.0409741401672 seconds
jsmin
from 21559 to 13655 in 0.177556037903 seconds
jsmin.c
from 21559 to 13656 in 0.00346994400024 seconds
yuicompressor
from 21559 to 11638 in 0.891603946686 seconds

So, roughly, slimmer is 4 times faster than jsmin.py but fails to minify a couple of bytes. jsmin.c is about 6 times faster than slimmer.py but is awkward since it's in C. I guess jsmin.c is the way forward when you want speed and the best result. slimmer has the advantage of being all in python and PyPi and contains functions for CSS, HTML and XHTML as well.

It's clear the YUI Compressor does a wicked job at minifying but by running a .jar file every time in a subprocess is crazily slow if that matters for you.

Python Code Dojo London - 17 Sep 2009

September 14, 2009
0 comments Python

If you're on the python-uk mailing list you will have already seen this but if you're not, here we go.

Fry-IT is hosting a Code Dojo in our offices. It's free and open to anyone. My colleague Nicholas has written up a little bit about what a Code Dojo is which should get you excited.

Details are available on this page which is also the place to go to secure your place. Currently there are 12 people who say they're coming and we've decided to cap the geek influx to 30 people.

Cheers,
Peter-san