Wednesday, August 27, 2008

Enomalism update

I'm currently working on the second release candidate of Enomalism 2.1. I know the first release candidate hasn't been released yet, but that shouldn't stop the ongoing development.

A lot of progress has been made on the second release candidate. I've made small name enhancements in the core abstraction modules. Although, I've spent most of the development time fixing code in the core extension modules. The core extension modules are the extension modules that are shipped with Enomalism and are required to accomplish anything useful.

As of today, the most notable enhancements have been made in the static_networks, and the valet modules. The code in these modules was quite difficult to follow. Both now have a much more elegant, object-oriented feel to them.

Tuesday, August 26, 2008

The art of delegation

Delegation seems like a pretty simple concept. That is, why should it be considered an art? Well, there is a fine balance between having a proper distribution of responsibilities and having operations that try to accomplish everything under the sun. A common delegation use is the pure fabrication design pattern. Pure fabrication should be introduced when there no logical way to distribute the responsibilities among a society of classes.

For example, lets examine the following class implementation:

class BlogEntry:
def __init__(self, *args, **kw):
if kw.has_key('title') and kw['title']:
self.title=kw['title']
else:
self.title=None
if kw.has_key('body') and kw['body']:
self.body=kw['body']
else:
self.body=None
if kw.has_key('date') and kw['date']:
self.date=kw['date']
else:
self.date=None
Now, this constructor looks pretty straight forward. We have three attributes to initialize; title, body, and date. There is a pattern here. Each attribute initialization is four lines of code long, the only difference being the name of the attribute. It seems that we could pass the responsibility of initializing keyword parameters to another party. One that is better at the task. Blog entries are good at representing the blog entry. The blog entry class wasn't designed with Python dictionary processing in mind.

Here is another class implementation we can introduce in order to offload some of the responsibilities.

class BlogEntryTools:
@classmethod
def init_param(cls, name, kw):
if kw.has_key(name) and kw[name]:
return kw[name]

@classmethod
def init_title(cls, kw):
return cls.init_param('title', kw)

@classmethod
def init_body(cls, kw):
return cls.init_param('body', kw)

@classmethod
def init_date(cls, kw):
return cls.init_param('date', kw)

Using this new utility class, we can now better distribute the responsibilities throughout our code. To complete the picture, here is our new implementation of BlogEntry. The constructor is much more elegant and maintainable at a very low cost.

class BlogEntry:
def __init__(self, *args, **kw):
self.title=BlogEntryTools.init_title(kw)
self.body=BlogEntryTools.init_body(kw)
self.date=BlogEntryTools.init_date(kw)

Thursday, August 21, 2008

The invoke once principle

I often come across code in a method or function definition that will use another function or method invocation to return some value. This invocation is then used more than once throughout the body of code in question. This is done because the value returned by the method is used in this new context.

The problem is, this probably isn't very efficient. Function or methods that return a value should only be invoked once in a particular context. This is usually done at or near the beginning of the code we are writing. We invoke the function or method and assign the return value to a meaningful variable name which is then used throughout the rest of the method we are developing.

This is useful when the code we are developing has no effect on the state of the value returned by the function or method invocation. There are same scenarios when invocation is necessary every time the value is needed. This is seldom the case but it does happen.

The general idea behind this principle is to avoid method invocation wherever possible. If we only need to initialize a value once in our code and there is no chance of our code disrupting the value's state, than this is the way to go.

Tuesday, August 19, 2008

Enomalism 2.1RC1

I'd like to mention some of the many changes that have taken place in the first Enomalism2.1 Release Candidate.

  • A large number of name changes have been made to better conform to the Python PEP8 coding guidline. This resulted in massive changes throughout the codebase. Not all changes in this area have been implemented. Although, this is an ongoing effort and is a future goal of Enomalism.
  • The select code that retrieves sets of objects has been vastly improved. There is new functionality that retrieve objects based on the specified permission. This will check the permissions inside the SQL statement which is much more efficient. This is another area of improvement which is incomplete and ongoing.
  • Much of the javascript that makes requests to the Enomalism REST API will handle failure much better. There were several cases in the last release that the javascript would either utterly fail or just show no response. In most cases, it is very obvious what has gone wrong.
  • Some new REST API features have been added. These are mostly GET requests that list Enomalism objects.
  • Several improvements have been made to the JSON architecture in Enomalism in which the objects are converted to a JSON representation.
  • The structure of the core modules is more package oriented. The idea behind Enomalism extension modules is that they are in there own right, applications that run on the Enomalism platform.
The release should be available shortly and I will provide a link as soon as it exists.

Thursday, August 14, 2008

Tag qualifies as a buzzword

Tags. Labels. Folders. Etc. In software, they all serve the same purpose. To categorize and to classify. I can't help but chuckle a little inside when I hear terms like tag-enabled and tag cloud. Wouldn't term hierarchy be a more accurate description? I suppose not. It just goes to show how powerfully attached people are to popular buzzwords.

Tuesday, August 12, 2008

Keeping Python objects backward compatible

In Python, its easy to maintain backward compatibility with your object designs. The most common problem is changing the interface of objects. This includes replacing old attribute names with old ones, etc.

With Python, the client which requires these interfaces, does not even need to change their code! This is easy if you just keep the old attributes. But this can lead to a maintenance nightmare. A better alternative might be to define a __getattr__() method that groups deprecated attributes. For instance,

class Blog:
def __init__(self):
self.new1='New1'
self.new2='New2'
self.old1='Old1'
self.old2='Old2'
self._attrmap=['old1':self.new1,\
'old2':self.new2]

def __getattr__(self, name):
return self._attrmap[name]

This gives us a _attrmap dictionary which we can then use to easily manage deprecated attributes.

Thursday, August 7, 2008

The future of TurboGears

I wonder what the future holds for TurboGears? The current version is 1.0.5 and it doesn't look like the next major release is going to be available anytime soon.

Hopefully this changes. There are a lot of great features that the TG framework provides and it would be a shame if developers start moving away due to lack of development. That's not to say that there isn't ongoing development on the project, the releases just need to happen more frequently. There is talk about the 2.0 TG release being based on the Pylons web framework. This could be really good except for the fact that there nothing stopping developers from using Pylons on its own.

So, the future looks bleak for TurboGears. I hope I'm wrong and the project stays on track while keeping people interested in the project. This is especially hard with Django out in the wild.

Wednesday, August 6, 2008

The problem of migrating virtual machines

The problem in cloud computing is the need to send virtual machines over a network connection. This basic requirement is illustrated in the following diagram.



Virtual machines need to have the ability to migrate from one physical machine to another. The problem is the huge latency involved, caused by the network bottleneck of transferring these machines over a network. The basic idea is illustrated in the following figure.



As you can see, the target physical machine has to wait until the entire machine has arrived before anything can be done with it. It would be nice if there were something the target machine could do with partial virtual machine data. In essence, a streaming virtual machine migration.

Tuesday, August 5, 2008

User interface testing

Although there are several tools available today that enable the automation us user interface unit testing, they are not ready to use as the only testing procedure of any given application.

There are several issues that these tools fail to catch. Mainly, the work flow errors. Your application could pass the GUI testing framework with flying colors and yet, once your application is human-accessible, it fails colossally. This is because the slightest misinterpretation by the testing framework as to what the work flow should look like (work flow in this context is the sequence of user interface actions, not application logic). This is not to say that the user interface testing frameworks are not capable of fully automating the interface testing, it is a question of effort involved. A simple user interface validation test done by a human may take an hour to perform where designing a test may take much longer.

In the long run is it worth it? Maybe. If your application is user interface centric (some would argue that all applications be designed using the interface as a starting point), it might make sense. In this case, the user interface designers will most likely be designated to this task. They will not likely care about application work flow.

What if you are in a situation where the user interface takes a "back seat" to other "more important" tasks? Well, this is bound to happen. After all, a user interface with no application behind it isn't terribly useful. Perhaps what is needed here is two sets of use cases. One for the application, which is independent of how external actors interact with the system. And, one for the user interface that describes the interface cases in much detail while keeping the application cases vague.