Sunday 30 March 2008

Containment Versus Inheritance

In the stdtools package I recently released, there is a class called ResourceLoader. It's purpose is to provide a dictionary-like object that loads resources a game might need, like sound and images. The point is that the images are not loaded until they are accessed. A lazy loading mechanism, one might say. I wanted the object to behave like a dictionary, and make it generic enough so it could be easily adapted for a partical resource type.

The ResourceLoader class does exactly that. It overrides the __getitem__ and __delitem__ hooks to behave like a dictionary, and you can adapt it for a particular resource type by subclassing it, and overriding the load and locate methods. This is all very nice. However, there is a design issue in the class: It uses the dictionary through containment.

What I mean by that, is that the class has an attribute, self.resources, that is a dictionary of all the resources I have currently loaded. If the __getitem__ method is called, the class first tries to retrieve the requested item from the dictionary, and if it is not available, attempts to load it:
class ResourceLoader:
def __init__(self, paths):
self.paths = paths
self.resources = {}

def __getitem__(self, key):
if key not in self.resources:
self.resources[key] = self.locate(key)
return self.resources[key]
So why is this wrong? Remember that this class essentially is a dictionary, with some altered access mechanics. Therefore, it makes much more sense if the class is also derived from a dictionary, instead of containing one. This is the difference between an is-a and a has-a relationship. It makes no sense for this object to have a dictionary attribute if all access of the object is passed onto that dictionary anyway.

There are also concrete benefits to using inheritance in this case. Most importantly, we get all the nice things a dictionary can do, like iterating over it, retrieving it's length, etc. Another bonus is that it is a bit faster, since we don't have to look up self.resources each time. Another benefit we get in this case is that we can forget about the __getitem__ hook, and simply implement the __missing__ method, which is called if a key is missing.

It is not always so clear when to use inheritance, and when to use containment. Think about how your class should behave. If it's behavior is mostly like a dictionary or other type, and the class would benefit from having the methods that type has, inherit it. If the class uses the dictionary more as an implementation detail, and it makes no sense to call something like has_key on your object, it is better to use containment.

I have rewritten the ResourceLoader class as described here, and I'm going to push a new version of it out sometime in the future.

New Goals

I was never one for new year's resolutions. In my opinion, they are unnecessary, pointless things that usually end up broken anyway. Quitting smoking is a wonderful example. Though neither of my parents smoke, I have a few aunts and uncles that do. They have quit smoking countless times. Or, I should say, have attempted to do so. To this day, they are still smoking.

Nevertheless, in a recent evaluation of my life-style I have come to the conclusion that there are a few things I would like to see changed. Improved. I recognize that the best thing to do to improve, is to set goals. So it is now that I have to resort to these things I always dreaded, these resolutions. I do hope that my resolutions will not end up as abandoned and forgotten as so many others I have seen, and to that end I will try to keep track of them in a logbook of some form. Now, here is my list of goals (I avoid the name resolutions):
  • Exercise daily. I cycle a good 7 kilometers to school and back every day, so I am content with my leg muscles. I would, however, like some more muscle (and strength) in the chest, arms, and belly. To that end I will do some push-ups, pull-ups and crunches each morning. Something like fifteen minutes is the goal.
  • Shorten my time in the shower. I do enjoy a good hot shower. A lot. So much, in fact, that I sometimes shower for half an hour. This takes a lot of my time in the morning, which I will henceforth need for my exercises. Another bonus is the energy saving environmental effect. And possibly an increase in sleep time, which is another one of my hobbies. So ten minutes tops in the shower.
  • Go to bed earlier. I am truly a creature of the night (like batman, yes?). I have no problem at all staying up until 2 am or later. On weekdays, this cuts in my sleep time (Particularly tonight, because daylight savings time is going in effect here), and in weekends, I end up sleeping through most of the morning. I'd like to move my waking cycle more in sync with the cycle of the sun. Henceforth, midnight is the time I will go to bed, except when there are movies I want to see. Similarly, 9 am or earlier is the time I would like to rise. This gives me about 8 hours of sleep (I need some time to fall asleep) which is more than enough (If i recall correctly seven hours is recommended for people my age).
  • Drink more water. To measure the amount of soda I drink each day, I took a fresh glass for each drink, and left these glasses on my desk for one day. The result is a rather large amount of glasses sitting on my desk right now. In response, I have decided to drink more water. I will take a full half liter bottle with me to school, and have an empty one around dinner time. When thirsty, drink water instead of soda.
  • Spend more time learning Japanese. I want to learn this language for some time now, but progress is disappointing. Well, not anymore: I will set aside half an hour minimum each day for Japanese, specifically the half hour immediately after dinner.
These rules will all be followed during weekdays. On weekends, most of these rules are somewhat relaxed. There will still always be exceptions (like parties or other special occasions) where I allow myself to deviate from these rules. I'm talking mostly about my ordinary, daily life.
The rules will all go into effect immediately, and by that I mean next morning (I should say this morning, as it is already 3:28 am). I'm going to rigorously log how much these rules have been followed, in a file on my PC and perhaps also in this blog.

So there you have it. Wish me luck

Friday 28 March 2008

using reduce

Recently I've been reading this blog, about a guy who has set some goals for his life and is now trying to complete them. While I'm not especially interested in all that stuff, the guy is also trying to learn python. I have a sizable amount of experience with the language, so I've been sort of helping him along with his code, pointing out things that could be improved. recently he posted this code, about a function translating text to morse code. You can go over there and read that post, but basically he wrote this:
def translate(text):
text = text.lower()
for char in text:
print morse_code[char] + ' ',
morse_code represents a dictionary mapping characters to their morse code equivalents. Now this function is actually pretty pythonic and overall good, but as I commented, it is unnecessarily limited. The job of the function is to translate text, but it also prints it. What if you wanted to save the text to a file? to accomplish this, the 'what you do with the data' part (printing) should be moved out of the function. A function should do only one thing and return it's results.
You could easily modify this function: declare an empty string, add the characters to it in the loop, then return the result. But this makes the function a little bit unpythonic. There is a simpler, more elegant way to do it.

Cue reduce. Reduce is a really nice functional tool of python that in select situations simplifies the code A lot. It's not needed often, but when it is, marvel at it's simplicity. So, you ask eagerly, how do we use it?

reduce is a function used to reduce (aha) a sequence of values into a single value. It takes to arguments: a function, and a sequence. First, the function is called with the first and second arguments of the sequence. Then, it is called with the result of this call and the third argument. Then, with the result of this call and the next argument. This carries on until there is no more next sequence to apply the function to. At that point the result of the call is returned.
Let's look at a specific scenarion:
import operator
reduce(operator.add, [1, 2, 3, 4, 5])
operator.add is simply a function that adds its two arguments together. So, reduces takes the first and second elements, and calls the function with them. The resulting value is of course 1 + 2 = 3. Then, it takes this result and the next value, and calls the function again. The result is 3 + 3 = 6. As we go on like this, we can see that the result of reduce, in this case, is the sum of the numbers in the sequence. (note that, for adding a sequence of numbers, we have the sum function, which is better, cleaner and faster than this method)

using reduce to rewrite the translation method above, we can obtain the following:
def translate(text):
return reduce(str.__add__, (morse_code[c]+' ' for c in text.lower()))
Now there is a short function. I use a generator expression to obtain the translated text, and sum the characters together with the reduce function. the str.__add__ function is what is called behind the scenes if you add to strings together (i.e. 'str' + 'str2'). A generator expression is another one of those really useful tools to clear up your code. They are, however, an advanced subject. If you don't know what they are yet, first go look up list comprehensions. then, check out generators and finally generator expressions.

P.S.: while proofreading this post, I decided to check out the python documentation. It turns out that summing a sequence of strings is also such a common operation that it has a function just for that. Here is the correct, fastest and pythonic way to do write the above function:
def translate(text):
return ' '.join(morse_code[c] for c in text.lower())
the join function joins together the strings in the sequence, and uses the string it is called on as a separator. I didn't know about this function. The things we learn, right?

School ending

Spring is coming up, and with that come also what I believe you might informally call finals in American (like midterms, but at the end, right?). What I mean to say is, exams are coming up. There's about half a dozen of them next week (the 'school' part), and than the actual, official ones that make up 50% of your end grade are in may. That's pretty damn soon.

I was basically coasting along this last year, enjoying the ride, looking at the scenery, and then bam! Exams come up and you end up in this whirlwind of teachers trying to complete the course in time (apparently our Latin teacher will need to schedule some extra classes to get it done), having to suddenly know all sorts of stuff (how the hell do you calculate the mass of a certain gas, given temperature, pressure and the amount of mole?), and official lectures by dusty professors (seriously, respect to them. They know. A lot). The year that started so relaxed ends in tons of worries.

I must confess, though, I'm still pretty relaxed most of the time. The hardest part (oral exams) are already behind me, and I passed those (albeit barely). Chemistry and English are a breeze for me, so the real hard stuff is in math, physics and Latin. That's mostly managable. So like I said, most of the time I'm relaxed. It's just these evenings on the couch when I sigh, and my mom says "Only a month left, Hugo," and I just think "damn, just a month? That soon?"

I guess I've had mostly good grades for the past five or six years though (those passed pretty fast as well by the way), so I should be ok. It's about time school ended anyway. It's been dragging on like this for a few months now. And I'm really excited about the exchange.

P.S.: (volume * pressure) / temp = mole * gas constant
one formula down, tons of others to go.

Tuesday 25 March 2008

restructuring pygame flow

I've been programming in Python for quite some time now, and I have really fallen in love with the language. It's simple yet powerful, and there's a whole slew of libraries included. And even more out in the wild. Almost everything I do is in python now, and I'm liking it.

One of the things that has always had my particular attention is game programming. Python as no built-in library just for that, but there is an excellent library available for that called Pygame. It consists mostly of bindings to the SDL library (which is also pretty good), and a bit of python specific stuff to make everything easy for you. So I've been writing small games with pygame for a while, and it's mostly been good. One gripe I have with it, however, is the way the program is structured. I'm talking about the event loop:
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
player.move("up")
#et cetera et cetera
In short, checking for all events occurs in a single loop. That's good, but the actual handling of the event (player.move) occurs in the same single loop. This I find bad. Code used handling the player, enemies, menu options, all of it is gathered up in this single loop, which will grow into monstrous proportions because of that.

To counter this behavior, I have written an EventManager class that is based on callbacks: objects can register functions with the event manager, and these functions will be called if the event is triggered. The function is passed the event in question as an argument, and can act on the event accordingly. With this class checking for events occurs in the EventManager instance, and handling of events occurs inside the relevant objects. All the code is where it belongs, and everyone is happy.

Allow me to demonstrate how a simple class may make use of the eventmanager:
class SimpleObject:
def __init__(self):
EventManager.bindToGlobal(
(KEYDOWN, self.onKeydown),
(KEYUP, self.onKeyup),
(MOUSEBUTTONDOWN, self.onLeftMousebutton, {'button':1}))

def onKeydown(self, event):
print "keydown:", event.key

def onKeyup(self, event):
print "keyup", event.key

def onLeftMouseButton(self, event):
print "left mouse button pressed!"
the above is a simple example of how the event manager may be used. The bindToGloblal method is a class method which makes the requested event bindings to the global EventManager instance, which is stored inside the class itself (usually only one global instance is needed. This method simplifies acces to this instance). The arguments to the function are tuples consisting of the event type, the handling function, and optionally a filter which can make sure only events with certain attributes trigger the handler. In the above example, onLeftMouseButton is only called if event.type equals MOUSEBUTTONDOWN, and event.button equals 1.

So, you ask, where is the source to this elegant class, so I may use it in my games and reach ascension? Good Question. The EventManager class is part of a package that I now use to develop all of my games. Other parts of the package are collision detection, resource management (images, sounds), a primitive GUI, a simple vector class, and some more random tidbits I find useful in my projects. The entire package together is a complete mess, and I really wanted to clean things up a bit before I throw it to you wolves out there.

That said, though, the functionality is there for those who want it. I've tarred the package together under the (slightly) dubious name of stdtools, and it's available here. The entire package is unstable and subject to change. It's also under the GPL.

Passed the test

As part of the procedures that need to be followed in an exchange such as this, I took the CELT test last week (that's Comprehensive English Language Test. check it out here). I can assure anyone else who needs to take this test for some reason, it is almost too easy. I was told that no one in YFU had ever seen someone fail the test, ever. Me? I scored 296 out of 300. If you want to know, the required amount of points to pass the test is 160. With that behind me, I have now been definitively accepted into the YFU exchange program.

Now is also an appropriate time to address a few questions I have been asked regularly by friends and family. First and foremost, when I will be leaving. I don't have an exact date of departure, but the website tells me we leave somewhere near the first week of August. Secondly, where exactly will I be going? Unfortunately, I don't know yet. Allow me to explain.

The procedure I mentioned earlier involves filling out a whole bunch of forms (more like a whole book. It is really a lot), which together form a comprehensive profile of yours truly. The YFU then sets out and compares this with forms filled out by potential host families, and tries to find a good match. The forms include a lot of information, like health status, personality, likes and dislikes, teacher evaluations, the list is endless.

What I'm trying to explain, is that YFU will need some time to find a proper host family for me, someplace where I can fit in. That doesn't happen overnight, and these families are all over the states. So, until they find a host family, I won't know where I'm going to end up. It could be anything from Hawaii to Utah.

Monday 24 March 2008

random backgrounds

Excuse me for all the posts. Since I'm only just starting, I'm trying to get a lot of content out in a short time (get a good start, so to speak).

Recently I got bored with the default Ubuntu background. It's really nice looking with all the swirls and stuff, but I'd been staring at orange for long enough now. So I decided to find some cool looking new backgrounds. Sounds simple, right?

Well, not really. Sure finding a cool wallpaper is not that hard at all. In fact, it's so easy I couldn't decide which one to pick. What I really wanted was a way to get a different wallpaper each time I started my computer. Unfortunately, gnome offers no such option. So I decided to write a little script for it myself. Here's what I came up with:

path="/usr/share/backgrounds"
file=`ls $path | perl -e '@a=<>;print $a[rand(@a)]'`
gconftool-2 --type string --set /desktop/gnome/background/picture_filename "$path/$file"

It's really even simpler than I expected it would be. picking a file is a one-liner, as is changing the background. I put in a path variable so you can set the location of your backgrounds.
Now all you need is some hot backgrounds, and set this to run every time you log in (using gnome session management at system/preferences/sessions), and you have a random new background image every time you log in.

Huge block tower

So, while I was browsing through our archives looking for a passable photo to use in my blogger profile, I came across this gem that my brother and sister built last Christmas.

That is one freakin' huge block tower right there. It's not that clear in the picture, but it goes right up to the ceiling. I asked my sister about the exact length, but she couldn't remember anymore. She did, however, remember that there was only about two centimeters left between the ceiling and the top of the tower. Going by the height of our ceiling, that would make the tower about 2.40 m high!

I never actually saw the real thing, since I was not home that morning. My sister told me it took the entire morning to build, and it never fell down once. The biggest problem was breaking it down without damaging the wooden floor. They eventually just put all the cushions they had around it, and then threw a ball at the bottom. My sister told me it went down like the twin towers.

As an aside, I found a somewhat passable picture for my profile as well, and uploaded that. So go ahead and make jokes about how I look.

I declare the blogs opened!

Alright everybody, welcome to the official (well, sort of) opening of my going USA blog. Allow me to explain a few simple things:

This august I will go to America for a full year. This is organized by an international exchange organization called the YFU (Youth for Understanding, I believe. Don't ask me were they got the name). I will live for a year in a host family, and also go to a community college.
I thought it would be fun for friends and family if I set up a blog where I can talk about my experiences as an exchange student.

That should do it for the introduction. I also have a few short yet important notes for everyone:
  • As exercise, I have decided that I will always post in the English language. I believe the internet has made me fluent enough, but it can never hurt to practice some more.
  • The layout is a boring default template for the moment, sorry for that. I'll color it up with nice American flags and such in due time, don't worry
  • Since I will most likely take a computer science course for my college year, and I have a great interest in programming, Linux, and other things computer related, I will post about these subjects regularly. Apologies for family and friends more interested in my other experiences. My posts will be properly labeled, so sort the interesting stuff out yourself.
  • Like I said, the blog is foremost for friends and family. Anyone else is of course welcome, should they find my incoherent rambling amusing, but I don't expect many of you right now.
That's all for the moment. I will follow up with some more detail about the exchange soon. Now to get the word out this blog is starting.