emacs :: autocompletion and code-commenting

I’m a believing member in the church of emacs, and in honor of the new release I went looking for solutions to a couple of outstanding issues I’ve had with my emacs installation.

Today’s first emacs find is M-; which, although undocumented, works excellently to comment and uncomment code blocks in Python (it had puzzled me for a while that the comment-block command on the Python menu was C-c # and that there was no mapping for the uncomment command). The M-; command works in a plethora of other modes as well to comment and uncomment blocks.

The second emacs treasure I found today was how to turn on autocompletion. Not the mind-numbingly annoying kind that some editors have that pops up and obscures half your program whenever you type a key, but rather cycling through options when pressing M-RET. To enable it, simply put this in your .emacs file:

(define-key global-map (read-kbd-macro "M-RET") 'hippie-expand)

Searching for some info on hippie-expand, I ran into dabbrev-expand which is bound to M-/. I couldn’t tell you what the difference is, but the ESC-Enter combination is easier to find blindfolded so that’s what I’m going with.

Posted in emacs, Python | Leave a comment

OpenID

I was checking out a number of 37signals’ webapps today (Highrise, Basecamp, and a few others… well worth a look). When I discovered I could sign in with OpenID. After a little googling and watching an excellent screencast over at Simon Willisons weblog, I figured out what it was and managed to turn my other site into an OpenID for myself. I might take a stab at implementing OpenID login for the site I’m working on, although it might not be the right audience… So what is it, you ask? Go watch the screencast, it explains it better than I ever could 🙂

Posted in it | Leave a comment

Python :: property set

It looks like Python is getting tuples with named members in 2.6 (http://www.oluyede.org/blog/2007/03/11/updates-from-python-svn-part-2/ and http://docs.python.org/dev/lib/named-tuple-factory.html). I suspect many of us have implemented similar functionality ourselves, e.g. Shannon -jj Behrens describes how he sometimes uses dictionaries to return composite polymorphic values (http://jjinux.blogspot.com/2007/03/python-returning-multiple-things-of.html). The problem with dictionaries is of course that they require too much excercise of your little finger in typing [‘xx’]. That’s even worse for me since I’m using a keyboard layout that switches national characters onto those keys when I tap the caps-lock key, so I can use my American-keyboard touch typing skillz and eat my national characters as well (I’m looking forward to the Metaphor-off!)

It looks like the new Python NamedTuple type is going to limit the fields to those that are defined at creation time. It’s based on a tuple, so I suppose that follows naturally, however it doesn’t seem natural for the abstract-data-type of a container of named fields with iteration and indexing. I’ve called my implementation of this ADT a property set since most of the motivating use cases for this was returning returning values that had properties attached to them. The use is as follows…

You can assign to random fields, the only limitation is that they cannot start with an underscore, but public fields wouldn’t have that anyway so it’s not really a limitation (the limitation comes from the fact that the implementation overrides __setattr__ and being able to interpret fields starting with an underscore as internal to the implementation simplifies things quite a bit):

[sourcecode language=”Python”]
>>> p = pset()
>>> p.a = 42
>>> p.b = ‘hello’
>>> p.c = [p.a, p.b]
>>> p
pset(a=42, b=’hello’, c=[42, ‘hello’])
[/sourcecode]

You can iterate over the values:

[sourcecode language=”Python”]
>>> for key, value in p:
… print key, value

a 42
b hello
c [42, ‘hello’]
[/sourcecode]

Notice that it maintains the insertion order, and you can also access by index:

[sourcecode language=”Python”]
>>> p[1]
‘hello’
[/sourcecode]

For technical reasons it is not possible to maintain the order when creating a pset from keyword arguments (I was hesitating to put this functionality in, but practicality beats purity, and it’s turned out to be very practical). Equality does not require isomorphism, which means that as long as the sets have the same fields they compare equal:

[sourcecode language=”Python”]
>>> q = pset(a=42, b=’hello’, c=[42,’hello’])
>>> q
pset(a=42, c=[42, ‘hello’], b=’hello’)
>>> p == q
True
[/sourcecode]

You can keep the order given to the constructor by initializing with a list of tuples:

[sourcecode language=”Python”]
>>> list(p.items())
[(‘a’, 42), (‘b’, ‘hello’), (‘c’, [42, ‘hello’])]
>>> r = pset(p.items())
>>> r
pset(a=42, b=’hello’, c=[42, ‘hello’])
[/sourcecode]

The example above does of course not mean that you can’t create a pset from a pset directly (this also maintains order):

[sourcecode language=”Python”]
>>> s = pset(p)
>>> s
pset(a=42, b=’hello’, c=[42, ‘hello’])
[/sourcecode]

It’s also extremely useful to be able to use field indexing notation as well:

[sourcecode language=”Python”]
>>> p
pset(a=42, b=’hello’, c=[42, ‘hello’])
>>> p.b
‘hello’
>>> p[1]
‘hello’
>>> p[‘b’]
‘hello’
>>> p[‘b’] = ‘world’
>>> p
pset(a=42, b=’world’, c=[42, ‘hello’])
>>> p[1] = ‘foo’
>>> p
pset(a=42, b=’foo’, c=[42, ‘hello’])
[/sourcecode]

Here’s the code:

[sourcecode language=”Python”]
class pset(dict):
"""This code is placed in the Public Domain.

Property Set class.
A property set is an object where values are attached to attributes,
but can still be iterated over as key/value pairs.
The order of assignment is maintained during iteration.
Only one value allowed per key.

>>> x = pset()
>>> x.a = 42
>>> x.b = ‘foo’
>>> x.a = 314
>>> x
pset(a=314, b=’foo’)
"""
def __init__(self, items=(), **attrs):
object.__setattr__(self, ‘_order’, [])
super(pset, self).__init__()
for k, v in items:
self.add(k, v)
for k, v in attrs.items():
self.add(k, v)

def add(self, key, value):
if type(key) in (int, long):
key = self._order[key]
elif key not in self._order:
self._order.append(key)
dict.__setitem__(self, key, value)

def __eq__(self, other):
"""Equal iff they have the same set of keys, and the values for
each key is equal. Key order is not considered for equality.
"""
if set(self._order) == set(other._order):
for key in self._order:
if self[key] != other[key]:
return False
return True
return False

def __iadd__(self, other):
for k, v in other:
self.add(k, v)

# should probably have an __radd__ method too…
def __add__(self, other):
tmp = self.__class__()
tmp += self
tmp += other
return tmp

def __repr__(self):
vals = ‘, ‘.join(‘%s=%s’ % (k, repr(v)) for (k,v) in self)
return ‘%s(%s)’ % (self.__class__.__name__, vals)

def __getattr__(self, key):
if key not in self:
raise AttributeError(key)
return self.get(key)

def __getitem__(self, key):
if type(key) in (int, long):
key = self._order[key]
return self.get(key)

__str__ = __repr__

def __iter__(self):
return ((k, self.get(k)) for k in self._order)

def items(self):
return iter(self)

def __setattr__(self, key, val):
if key.startswith(‘_’):
object.__setattr__(self, key, val)
else:
self.add(key, val)

def __setitem__(self, key, val):
self.add(key, val)
[/sourcecode]

Posted in Python | Leave a comment

django :: media, admin and otherwise

Django’s handling of media files such as images, css, etc. has confused me from the very beginning. I’m not going to claim that I fully understand the full ramifications yet, but at least I got something working… hopefully it’ll be helpful for someone. I’m running Django from an Apache 2.0.59 server, and I will be serving media files from the same apache server. The Django documentation suggests that a separate webserver for serving media files will boost performance significantly… which is good, since it gives me something to worry about if I run out of things to do 🙂

I’ve checked out my copy of Django to /home/djangosrc and created a symbolic link in Python’s site-packages directory to /home/djangosrc/django.

My Django server lives in /home/django and I’ve got media files in /home/django/media, and template files in /home/django/templates.

I created a virtual host on Apache and set it up for Django:

[sourcecode language=”xml”]
<VirtualHost 1.2.3.4:80>
ServerName www.mydomain.com
ServerAdmin webmaster@mydomain.com
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE datakortet.settings
PythonPath "[‘/home/django’] + sys.path"
PythonDebug on
</Location>
[/sourcecode]

Then I created a symbolic link from the Apache DocumentRoot directory (htdocs) to the media files for the admin interface: ln -s /home/djangosrc/django/contrib/admin/media htdocs/admin_media. In the settings.py file I put: ADMIN_MEDIA_PREFIX = ‘/admin_media/’ I’m pretty sure this tells Django that it should look for the admin interface media files in http://www.mydomain.com/admin_media/ (the first part of the url coming from the server Django is running on). Continuing the virtual host definition to reflect this I got

[sourcecode language=”xml”]
<Location "/admin_media">
SetHandler none
</Location>
<LocationMatch "\.(jpg|gif|png)$">
SetHandler none
</LocationMatch>
[/sourcecode]

For regular media files I added a symbolic link in Apache’s htdocs directory to my media directory: ln -s /home/django/media htdocs/media, then over in settings.py I added MEDIA_ROOT = ‘/home/django/media’ and MEDIA_URL = ‘http://web.datakortet.no/media’, and finally I could finish off the virtual host definition with:

[sourcecode language=”xml”]
<Location "/media">
SetHandler none
</Location>
</VirtualHost>
[/sourcecode]

So far it seems to be working well. The next project in my queue requires uploading of image files, so I haven’t tested that yet, but hopefully I’m not too far off..

Posted in django | Leave a comment