wnd's weblog


March 2010
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 1 2 3 4
Categories
Archive

wanha 2010-03-22-r224

22 March 2010 09:57:40 my software

This release of wanha fixes an HTML-injection issue that affected some browsers. Also, wanha IRC robot can now be told to check URLs and announce them on the chanel if they're not wanha. Finally, some output strings were fixed.

Sources.

Permalink | Comments (0)

SID of the day: Tetris by Wally Beben

18 March 2010 12:51:03 SID of the day

Tetris by Wally Beben

Tetris by Wally Beben isn't just SID of the day but rather The SID of All Time. Seriously. I have loved this song ever since I first heard it back in 1990s. Since then I've made tape recordings of it, had it on my media player for long flights and such, listened to it to relax and to concentrate. At work I've been listening to this song for almost a week non-stop now. By now I'm fairly sure I have listened to this song literally for days if not weeks. It really is that good.

In all honesty though I'm sure not everyone will like it. This track keeps going for almost 26 minutes and it starts slowly. However, unlike many other long songs on C64 (such as Knuckle Busters by Rob Hubbard), I have never found this song boring. While I can't hear an actual story in this song, it nonetheless describes me a journey through constantly changing scenery and all its wonders. Take your time, don't stop after the first three minutes but listen it through once and then again. The song is worth it. You are worth it.

Permalink | Comments (0)

Rome, August 2008

3 January 2010 16:43:45 photos, travel, update

Colosseum, Rome, Italy These pictures have been waiting for a review and tagging for ages. I almost finished the task last summer but somehow that final push was missing. Without further introduction here are the pictures -- only 15 months late.

Permalink | Comments (0)

Python (2.5) and me

28 December 2009 13:53:17 rant, software

I have always thought that the fastest, the easiest, and the most convenient way to learn a new (programming) language is to start using it. Not little by little, but just using it as much as you can. Now that I have spent about a month writing Python as Python-like as I can, I have to get a few things out of my head. Obviously I'm still total newbie to Python so don't take my rant too seriously. After all, so far I've only been rewriting one of my (unpublished) 5000-line Perl-scripts to Python from scratch. Rewriting things from scratch is another great way to improve your stuff but that's another story.

Variable declaration not required

Python does not expect you to declare variables. In fact, as far as I can tell, variables cannot be declared in the first place. I don't like this because I make typos. I make a lot of typos. Well, maybe not that much. In any case, I hate to hunt for typos in my code only because greater power decided that declaring variables is for losers. Perl doesn't require declaration either, but at least in Perl I can opt in for that. Nobody has been able to tell me how to do that in Python.

found = False
for item in get_stuff():
    if item.name() == the_one:
        founs = True
        break

if found and foobar:
    # and no, the point isn't in "why can't you call do_stuff while still
    # in the loop?"
    do_stuff

No real encapsulation

There is no real encapsulation. Lack of data encapsulation combined with no declaration needed -variables means that typos in assignments such as foo.bar = 3 can do real damage -- without a single warning. If I want to prevent that I need to have identifiers to begin an underscore or two. I just love how the code looks with all those underscores around.

foo.py:
class Foo(object):
    s = True
    def a(self):
        pass

    _hidden = True
    def get_hidden(self):
        return self._hidden

bar.py:
from foo import *
x = Foo()
x.a = False
x.d = False
print x.get_hidden()
x.a()

Python properties aren't the thing either. When I asked around whether I should access class instance variables directly (thanks to lack of encapsulation) or through get_*() and set_*(), I was basically told that properties was the next big thing. At first properties looked like a great idea but then I tried using them. To begin with, using properties means that you practically must use those ugly _underscore variables. Also, using properties only makes your code more vulnerable to nearly undetectable typos.

foo.py:
class Foo(object):
    def __init__(self):
        self._s = 0

    def get_s(self):
        return self._s
    def set_s(self, s):
        self._s = s
    def del_s(self):
        del self._s
    s = property(get_s, set_s, del_s, 'a')

bar.py:
from foo import *
x = Foo()
x.a = 3    # whereas x.get_a() would have at least given an error!

Scope of variables

I just don't like the way the scope is defined. I haven't studied the inner workings of Python so my rant is probably all wrong here. It seems that variables inside methods are always bound to that method but not the block they are used in. Even though I would prefer to be able to reuse variables in nested blocks like in C, I can live with this. However this all gets much more interesting when you try to use the same identifier in and outside a method.

a = True

def x():
    if a:
        print "ok"

print a
x()

--- vs. ---

# this example does /not/ work

a = True

def x():
    if a:
        a = False

print a
x()

--- vs. ---

a = True

def x():
    global a
    if a:
        a = False

print a
x()

Coarse-grained exceptions

Exception system is too coarse-grained to my taste. This was one of my first issues with Python. I was writing a parser to extract information from not well-formed text file and create objects using that information. In practice I was using regular expressions to get the data and then calling object.set_foo() to save it. Naturally I added exception handlers to deal with errors, but at the end this turned out to be a bad idea.

import re

class Foo(object):
    a = None
    def set_a(self, a):
        self.a = a

data = 'fooxyzzybar'    # in reality this contains entire source file
a = Foo()
try:
    x = re.search(r'foo(.*?)bar', data)
    a.set_s(x.group(1))    # set_S, not set_A
except AttributeError, e:
    print 'oops'

If the regexp doesn't match given data, search() returns None. If I'm too lazy to check the return value against None, None.group(1) throws an AttributeError. This can then be easily dealt with. The problem is that if I make a typo in object call in try-except -block and call a function that does not exist, that also throws an AttributeError. Sane languages would die at such an atrocity -- but not Python. I guess this is just another way Python encourages you to write nice and cleanly structured code. In any case, I think the exception system could be improved.

UTF-8

This complaint is probably based on completely wrong assumptions and such, but dealing with UTF-8 seems to be unnecessarily complicated. I don't know what there's going on under the hood but whatever it is, it can caused me a lot of trouble. I want my application to output UTF-8. Most of my source HTML data is encoded in UTF-8, but it also contains HTML entities such as ä and charrefs such as A and ☎. I use HTMLParser to parse the data, and htmlentitydefs to convert the entities. The problem is that htmlentitydefs.entitydefs has the characters in ISO-8859-1(5) and Python doesn't like mixing two character sets. It also seemed overly complicated to deal with charrefs, but at the end it all worked out, however what I ended up doing wasn't pretty. From what I've read Python 3 should help with these issues.

def handle_entityref(self, name):
    if name == 'nbsp':
        self.handle_data(' ')
    else:
        try:
            self.handle_data(htmlentitydefs.entitydefs[name].
                    decode('ISO-8859-1').encode('UTF-8'))
        except KeyError:
            self.handle_data(name)

def handle_charref(self, name):
    if name[0] == 'x':
        v = int(name[1:], 16)
    else:
        v = int(name)

    if 128 <= v <= 255:
        try:
            self.handle_data(chr(v).decode('ISO-8859-1').encode('UTF-8'))
        except UnicodeDecodeError and UnicodeEncodeError:
            self.handle_data('0x%x' % v)
    elif 0x100 <= v <= 0xffff:
        try:
            self.handle_data(unichr(v).encode('UTF-8'))
        except UnicodeDecodeError and UnicodeEncodeError:
            self.handle_data('0x%x' % v)
    else:
        self.handle_data('0x%x' % v)

Random complaints

Permalink | Comments (0)

SID of the day: Smo0oth Crimin4l by Owen Crowley (CRD)

6 October 2009 19:32:59 SID of the day

Smo0oth Crimin4l by Owen Crowley (CRD)

I'm not the world's biggest Michael Jackson fan, but do like some of his songs, this being one of them. In my opinnion Smooth Criminal (and this SID) makes it clear why Michael Jackson's music is not your usual pop music that you can barely notice from all that background noise. Late events with HVSC and Michael Jackson make this SID a great pick as SID of the Day.

Permalink | Comments (0)