Gedit rewrap plugin 0

Ola is writing her dissertation in LaTeX using gedit (GNOME Text Editor). Gedit is nice, but it can’t do hard wrap, not to mention text reformatting. Now she has lots of extremely long lines.

As vim has both mentioned features (gq) I don’t have this problem, but I decided to help her, knowing that gedit supports python plugins. Two hours of browsing documentation and, lo and behold, rewrap plugin is finished. You can see it on bitbucket: http://bitbucket.org/oinopion/gedit-rewrap-plugin/

I know that there probably is something similar (and probably better) done already, but it’s great fun to hack for your girlfriend!

Enter Tasklight 0

My time at University of the West of Scotland is about to end shortly. In two weeks I will submit my project along with lengthy dissertation for assessment. This is honours year project and should be a real-world web-application of considerable complexity including integration with some proprietary APIs.

My project, Tasklight, is lightweight task management system. It’s running on Google App Engine (Python runtime). It is build with libraries such as Werkzeug, Jinja2, wtforms and jQuery.

Tasklight is fairly complete, in terms of university project. So that is why I’m announcing public beta testing. If you feel like trashing my little, cute Python app than go to: Tasklight log in with your Google Account and … well, test it!

Tasklight logo

PS: Any feedback can go here or to uservoice forum

Python’s Augmented Assignments 0

Everyone knows that in Python variables are just references and passing such reference to function effectively copies value of the reference to functions local scope, hence any assignment within function has no effect on original variable. Knowing that, this took me by surprise:


>>> def add_eggs(foo):
...     foo += ['eggs']
...
>>> spam = ['spam']
>>> add_eggs(spam)
>>> print spam
['spam', 'eggs']

This seemed to me as an error in Python interpreter, but after checking language reference I discovered it’s not; it’s intended behaviour (emphasis is mine):

An augmented assignment expression like x += 1 can be rewritten as x = x + 1 to achieve a similar, but not exactly equal effect. In the augmented version, x is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.

Quoted after: python docs

Equality is not always sufficient 0

I’ve just got hit by one of really typical errors while writing simple value type in Python. Consider following code:

class Simple(object):
    def __init__(self, val):
        self.val = val
    def __eq__(self, other):
        return self.val == other.val

The class Simple overrides equality operator delegating it to it’s value. Seems dead simple and easy for the first time. But not quite so. What will following snippet print?

a, b = Simple(3), Simple(3)
set_a, set_b = set([a]), set([b])
print 'a == b: ', a == b
print 'set_a == set_b', set_a == set_b

You’ve guessed it: True, False. This is because two sets may be equal only if all elements hashes are equal. So I thought I will fix it with this:

class Hashimple(object):
    def __init__(self, val):
        self.val = val
    def __eq__(self, other):
        return self.val == other.val
    def __hash__(self):
        return (self.val * 5) + 7

Seems better, but look at this snippet and guess once more:

a, b = Hashimple(3), Hashimple(3)
set_a, set_b = set([a]), set([b])
print 'Hashimple'
print 'a == b: ', a == b
print 'set_a == set_b', set_a == set_b
print 'a != b', a != b

True, True, True?!? Well, Python will not imply that a != b , not even when a == b.

This bug has been made thousands times by thousands of coders, it occurs not only in Python, but also in various other languages (Java, Ruby), it’s been described in lots of books, but I just keep forgetting about it. Maybe writing a blog post will help me remember?

Docs: __eq__, __hash__

Idea about Expires header 10

Since the Steve Sounder’s High Performance Web Sites everyone knows to set far future Expires header on their static assets. What he didn’t say was how to deal with the file changes. You can’t instruct browser to download the file so you actually have to change the file’s URL.

Ruby on Rails handles this by automatically adding file’s timestamp as a query-string when using build-in helper methods — simple and not requiring server-side URLs rewriting. This is good enough, but only for files accessed from HTML directly and doesn’t work for files accessed from CSS: background images (unless you have dynamically generated styles).

I was thinking for some time about those background images, because they can be heavy and if you’re not using CSS sprites they make lots of requests. As I don’t like dynamically generated style sheets, I didn’t want any additional processing. And so it came to me: why not incorporate some changing value into the domain name? You could put a revision number or a timestamp in domain name of your statics server, just like this: static-1566.example.com. Both Rails and Django provide easy ways to change static assets domain.

This requires you to set-up wildcard subdomain, but is’s easier than processing CSS files. It works because url function in a style sheet is resolved using the style sheet’s own address.

PS: This is only a brain-dump — I didn’t test it.

Next Page »