wnd's weblog


January 2010
Mo Tu We Th Fr Sa Su
28 29 30 31 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
Categories
Archive

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 need 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)

HVSC and me

6 October 2009 13:00:54 misc

Now that I'm done with up to date copy of High Voltage SID Collection I'm not sure if I should laugh or cry. In a way I should be happy to finish something as time consuming as this but on the other hand I feel sorry that's it's done. How did it all begin? While I've always been great fan of chip music, I started to actively listen SIDs as late as in 2001. Until then I had only listened to my favourite songs from my Commodore 64 times. I'm not sure what happened back in 2001, but I got this great idea of listening all songs in HVSC. At first I did very little progress. I ofter had the same song players for tens of minutes if not hours. I started from root directory of HVSC and entered directories manually one by one. On the bright side I only needed to keep track of current file. In any case all this trouble caused me to practically forget my plans. At this point I was listening to HVSC 4.2 (update 27), which contained around 16000 SIDs.

Then maybe a year or two later I started listening to SIDs again. I also realised that I needed a better player if I was ever planning to see my plans through. I knew exactly what I needed: a player that would change songs after a few minutes and a keyboard shortcut that would have the player skip to the next song. Luckily this was easily done with combination of command line player such as sidplay2, Perl and extensively configurable window manager such as FVMW2. In late 2005, during the new year break, I was finished with HVSC. Little I knew...

The update to HVSC 44 was big. Apart from changing the numbering scheme, HVSC 44 contained almost twice as many files as 4.2 did. Since many files were either renamed, moved or updated, I decided not to try to follow the updates but to start from zero. I decided that I would listen through HVSC 44 like HVSC had 4.2 never happened. I was glad to realise that HVSC now came with song length information, so after a few tweaks to my Perl-script I was all set for another go.

After four years, some updates to the player script and fine collection of scripts to determine changes in HVSC, I have now listened every single song, including subsongs, in HVSC 51. I'm still unsure why I did this but I'm glad I did it. SIDs have been great source of joy, and at times, peace, when things have gone noisy or hectic at work. Although many songs are simply horrible, most are fine when played on the background. There are many songs I like and some that I really love. I have collected a list of songs I have liked during the years. I may not agree with all the songs on it today, but at the time I liked every single one of them. You can get the list here.

And then some figures. All in all I have now listened some 60,000 individual SID files. According to Songlengths.txt, HVSC 51 consists of 36,937 files that total in 53,815 subsongs or 1639 hours or 68 days. Since I haven't listened all songs entirely, I cannot use these numbers as averages directly. It is simply impossible to tell how much time I have spent listening to SIDs, but considering the fact that for example I have listened /MUSICIANS/B/Beben_Wally/Tetris.sid for days if not weeks, I think it only fair to say I have listened to SIDs for at least 68 days. I even think I can go as far as to say that I have listened to SIDs for 68 * (60000 files / 36937 files * 0.75) = 83 days.

What about the artists? According to my list of favourites my top-11 preferred list of artists goes as follows.

  1. Rob Hubbard (14 songs)
  2. Sean Connolly (12)
  3. Chris Huelsbeck (11)
  4. Jeroen Tel (10)
  5. Laxity (9)
  6. Thomas Detert (9)
  7. Tomas Danko (9)
  8. Glenn Gallefoss (8)
  9. Johannes Bjerregaard (8)
  10. Geir Tjelta (7)
  11. Dwayne Bakewell (7)
Permalink | Comments (0)

SID of the day: Unforgivable by Stellan Andersson (Dane)

24 September 2009 22:20:12 maemo, misc, SID of the day

Unforgivable by Stellan Andersson (Dane)

I finished listening High Voltage SID Collection 50 a few days ago. If I remember right, this song was one of the last songs I had on my playlist. I only wish I had found it earlier.

In related news, sidplay1 (sidplay-base) and sidplay2 (sidplay) can now be found in Maemo Diablo extras devel. Naturally my repository contains both. Get your copy of sidplay1 for Diablo or Chinook, and sidplay2 for Diablo or Chinook.

Permalink | Comments (0)