Leading a Group Project

During the first 4 months of my MSc Computer Science course, there was a major group programming project that focused on the entire lifecycle of programming projects, from capturing requirements, use case analysis, implementation to testing. The class was split into 5 groups of 5 to 6 members and we were given a set of Phidgets, easy-to-program USB devices that included sensors, motors, and various other input devices (similar to Arduino).

Why do we need leaders in projects at university?

The year previous to my conversion course I was involved heavily with 2 group projects. If they taught me anything, it taught me that every team requires some kind of a leader. It doesn’t really matter what you call it: leader, manager, captain, or even the hero. It’s of paramount importance because of a few reasons:

  • a leader with a view of the ‘big picture’ will ensure the project stays on track and on time,
  • when the team cannot agree on something, the leader will have the power to make decisions,
  • the leader can inspire and motivate the team when the ideas just don’t seem to come.

It was because I appreciated the importance of leadership so much that I suggested that we nominate a leader in our first meeting. I did it because I know that it could be a bit socially-awkward to call for a leader, or worse still, to self-nominate! A soft suggestion is a good way to go about this.

It turned out that I became responsible for what I suggest so I took on that role. To be honest, it was my first time leading a team on a project of this scale. Previous leadership attempts included a small report that was easily split between 5 people and put back together; there was very little scope for failure. This project was different because of the sheer amount of work we had to do.

The Group Project

We had 4 major deliverables: a project proposal with our proposed idea, a requirements specification, our implementation of the project (the code), and a final report. One of the pivotal decisions the team had to make was the choice of the project. We had several interesting ideas, such as a gesture-based control device or a device that would, using image recognition, compose a frame automatically for taking photographs. We went with a simple idea: a library system demonstrating the use of RFID tags. This was chosen to minimise the risk of not being able to pull off a programmatically complex project and yet it provided enough scope for us to work on it. A lesson learnt here: the leader should not push his idea (mine was the gesture device) but to ensure that the decision is made in the best interest of the team.

This experience gave me several insights into what a leader of any team might be faced with. Good leaders will recognise that active encouragement is an important trait; they will be quick to admit their mistakes while refraining from pointing out the mistakes of others in a tactless manner. I learnt that patience is really a virtue—-it is unproductive and obviously unharmonious to lose patience when your colleagues are trying their hardest. When the pressure is on, the good leader will not be swayed easily; he will be a stable rock that will not falter, that will provide a shelter and a base for its members.

Speaking of admitting mistakes, I am pretty sure I made many mistakes along the way. There were times I lost my patience when the pressure was mounting—I think this is by far the worst kind of mistake anyone can make; it shows a lack of control and in some cases, it could represent uncertainty and unreliability. I also like to take on many tasks that could have been delegated to the team. When I did delegate, they produced outstanding work that benefitted the team in various ways, which brings me to my last point about leadership.

What leadership means to me now

Before the project, leadership meant to contribute as much as you can to the team; have control on how the team works, and to steer and provide direction for the team at all times. Although it’s not entirely incorrect, I now have a slightly different view that is slightly more subtle. Leadership is bringing out the best of your team. After all, a leader can do so much on his own, but a leader backed by an inspired and motivated team is worth much more.

All that’s well ends well

That much is true. The result was released today and the team achieved a 79, the best in the class, and a whopping 10 marks above average. I cannot attribute this to any one person but to the entire team. The leader was only there to ensure that the team could achieve their maximum potential, and achieve it we did. Well done Team Sophia!

Team Sophia Photo

Concatenating a list of files in bash

I had the need to concat a list of files like this:

~/Downloads
    file_1.001
    file_1.002
    file_2.001
    file_2.002
    file_3.001
    file_3.002
    file_4.001
    file_4.002

The command to concat the files individually would be:

$ cat file_1.00* > file_1

But to do it individually would take a while. Luckily, a simple bash script did the trick:

for f in $(ls *.001); do
    target=${f%.*}
    catname=".00*"
    cat $target$catname > $target;
done

MATLAB Tricks

MATLAB has become part of my life recently. As I used it more often, I realised that there were a few things I needed to do that required scripting in MATLAB. For example, I wanted to create same-sized .eps figures for my research project, or be able to reorder the legend for graphs.

Creating same-sized figures

Visiting the MATLAB documentation solved my question.

set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperUnits', 'inches');
set(gcf, 'PaperPosition', [0 0 4 2]);

PaperPosition follows this format:

[left bottom width height]

Finally, save the file as .eps:

print -despc output.eps

This can be repeated reliably, which will guarantee consistently-sized figures.

Reordering the legend

Visiting this forum thread helped.

% get the figure handle
h = 1 % or whatever fig
% get the axes handle
a = get(h, 'CurrentAxes')
% get the handles for children of the axes -- these are the data series handles
c = get(a, 'Children')
% generate a legend command using these "children"
legend(c([1 3 5]), 'label for data 1', 'label for 3', 'label for 5')

Remove all variables

Sometimes it is nice to remove all the variables using the command line:

clear all

Using MATLAB to Control Simulink

The final year of university is taking its toll on me. The act of balancing a research project, a team design project, several reports, numerous job applications, and MSc applications has took all my time away. Fortunately, there’s still a little glimmer of hope in all that work – in the form of MATLAB.

This is a short snippet of code used to interface the simulink package in MATLAB. There’s a model simulating the frequency response to a sinusoidal wave of a first order dynamic system and I wanted a way to use MATLAB to loop over a range of input frequencies into the model. The documentation isn’t even half as good as Django’s but I got there in the end. Here’s the code:

i = 1
for h = [10:10:1000]
    % change the frequency from 10 to 1000
    frequency = h
    % run simulink
    sim('frequencyresponse')
    % output is the response
    % take values from 1 s onwards: (1000th number as step is 0.001)
    steady_output = output(1000:2002)
    % take the maximum value of steady_output to find the steady state gain
    steady_max = max(steady_output)
    % assign the max value into an array
    result(i,1) = steady_max
    i = i + 1
end

The important part was the sim('frequencyresponse') part. ‘frequencyresponse’ is the name of my Simulink model and the sim command runs the model. The rest was easy.

A bit of geeking on a Friday night and good progress made on my project cheers me up.

git and fabric

I have been a Subversion user for a while, and I wanted to learn another version control system. I chose git. From the start, I found converting to using git a pleasure. There are plenty of guides out there to get you started. In this entry, I will talk about how I used git to store my blog’s code. In addition, I will talk about fabric, an excellent automation tool for deploying your website to multiple servers, but works just as well if you are only doing it to one.

Getting familiar with git

In my previous entry, I mentioned briefly how to initialize a git repository and committed files to it. It was as simple as running a git init command in your current working directory and you have a free repository. However, I wanted to be able to push these commits to a server where my other computers could do a pull. I logged into my remote server via SSH and initialized a barebones git repository:

$ ssh wf
$ mkdir /var/git/kennethkam-django.git
$ cd /var/git/kennethkam-django.git
$ git init --bare .
Initialized empty Git repository in /var/git/kennethkam-django.git

Locally, I added the remote repository and pushed the commits.

$ cd ~/Workspace/kennethkam-django
$ git remote add origin ssh://wf/var/git/kennethkam-django.git
$ git push origin master
Counting objects: 72, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (53/53), done.
Writing objects: 100% (54/54), 4.66 KiB, done.
Total 54 (delta 42), reused 0 (delta 0)
To ssh://kenkam@web58.webfaction.com/home/kenkam/git/kennethkam-django.git
   6e663a9..685aecc  master -> master

On another computer, I pulled the repository.

$ cd ~/Workspace/kennethkam-django
$ git remote add origin ssh://wf/var/git/kennethkam-django.git
$ git pull origin master
remote: Counting objects: 711, done.
remote: Compressing objects: 100% (620/620), done.
remote: Total 711 (delta 425), reused 121 (delta 75)
Receiving objects: 100% (711/711), 1.22 MiB | 323 KiB/s, done.
Resolving deltas: 100% (425/425), done.
From ssh://wf/home/kenkam/git/kennethkam-django
 * branch            master     -> FETCH_HEAD

That’s it.

Don’t you do a reset —hard without thinking

I continued coding and committing. I often made a mistake with typing the commit message, I found myself using the git commit —amend flag often. On one occasion, I made several bad commits. I wanted to undo the commits but still keep the changes in the staging area. This is that I did:

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... "Commit message 1"

All the bad changes were discarded, but then all my good changes disappeared along with it. git anticipates this and even allows you to reset your reset:

$ git reflog
1a75c1d... HEAD@{0} reset --hard HEAD^: updating HEAD
f67d23f... HEAD@{1} "Commit message 2"
$ git reset --hard 1a75c1d
HEAD is now at f67d23f... "Commit message 2"

Phew. I was back to where I started. What I wanted to do was:

$ git reset --soft HEAD^

Sometimes I wanted to reset files that are added to the staging area but I did not want to commit them:

$ git reset HEAD file.txt

That was about all the things I did with git.

Automating deployment with fabric

Fabric is an excellent application that allows you to automate the deployment of your website. I am currently using the old 0.1.1, but there is a stable 0.9 which has some syntactic differences, same philosophy.

First, grab fabric off PyPI.

$ pip install fabric

Fabric needs a ‘fabfile’ to work with:

$ cd ~/Workspace/kennethkam-django
$ touch fabfile.py

A fabfile needs to define several configs and a few functions:

config.fab_hosts = ['someserver.com']
config.path = '/path/to/srv'

def deploy():
    # To deploy, we require the fab_hosts variable
    require('fab_hosts')
    deploy()
    restart()

def upload():
    local("git archive --format=tar master | gzip > upload.tar.gz")
    put('upload.tar.gz', '/home/kenkam/uploaded.tar.gz')
    local("rm -f "   'upload.tar.gz')
    run('cd /home/kenkam

Furthering A Simple Django Blog

(These posts are no longer relevant as I’ve migrated to Posterous!)

The last entry talked about using virtualenv, simple git commands, and a simple model and URLconf for the blog application. This entry will focus on Django contrib packages, which provide free RSS, a sitemap, generic comments, and many more.

Django’s got what you need

Django has a lot more than an ORM and some URL routing. A casual peek inside django.contrib will reveal many add-on apps that provide additional functionality where most websites will find useful. Apart from the default contrib apps, kennethkam.com uses comments, flatpages, humanize, markup, sitemaps, and syndication.

humanize and markup are template filters that provides formatting niceties to text. For example, markup has a markdown filter plus codehilite.

{{ entry.text|markdown:"codehilite" }}

I would consult Django’s contrib documentation for further usage. For now, I want to talk about how kennethkam.com implemented the other contrib apps.

Comments are for free

Django’s generic comments framework is easy to work with. To hook this up with your model, all you need is a bit of templatetag magic. Load comments and pass your object to the templatetag to hook it up.

{% load comments %}
{% get_comment_list for object as comment_list %}
{% for comment in comment_list %}
    ...
{% endfor %}

Rendering the form is no problem.

{# continuing from the above example #}
{% get_comment_form for object as form %}
{{ form }}

The default form for the comments app required the email field, but not the name of the poster. I wanted the opposite, so I customized the comments framework (documentation). I started by creating a comments app and added forms.py to the app. I copied the templatetags folder from the default comments app into my own app. Now to work on the form.

from django.contrib.comments.forms import CommentForm
from django import forms
from django.utils.translation import ugettext_lazy as _

class CommentFormRequireName(CommentForm):

    email = forms.EmailField(label=_("Email address"), required=False)
    name = forms.CharField(label=_("Name"), max_length=50, required=True)

I subclassed the default CommentForm, copied the lines for the two fields I wanted to change, and passed the required keyword argument. Simple.

To finish, I added the setting COMMENTS_APP = ‘kennethkam.comments’ and implemented get_form method in the init.py of my comments app. This is well documented in the Django documentation.

The world is flatpages

Flatpages are ideal for one-off content. kennethkam.com uses flatpages for the

A Simple Django Blog

(These posts are no longer relevant as I’ve migrated to Posterous!)

I developed a simple Django application that powers kennethkam.com. This entry will describe the workflow I used, from using git as my repository, using fabric for deployment, and various Django apps that can be used to plug straight into your project. This first entry will focus on using virtualenv, git, and knocking up a simple blog while the second one will focus on Django contrib packages, more git topics, and Fabric.

virtualenv is your friend

virtualenv will save you so much time. If you haven’t got it, do this right now.

$ easy_install pip
$ pip install --no-site-packages virtualenv
$ virtualenv django-1.1
New python executable in test-env/bin/python
Installing setuptools............done.

The no-site-packages flag means your environment will not attempt to load packages in your Python’s site-packages. Activate the environment and install the necessary packages into this folder.

$ source django-1.1/bin/activate
(django-1.1)$ pip install django markdown psycopg2

psycopg2 is the Python PostgreSQL driver and markdown is a text-to-HTML conversion tool. Django has support for Markdown but you must have the package for it to work.

There is a cool feature with pip. You can freeze your environment’s site-packages so you can recreate the same environment elsewhere, say, on your production box.

(django-1.1)$ pip freeze > requirements.txt
# Install packages on server
$ pip install -f requirements.txt

To exit the environment, use the deactivate command.

(django-1.1)$ deactivate

git – The Stupid Content Tracker

git is a distributed version control system, and it is extremely easy to use with any project. I used subversion before, but I found that having to run a daemon or a service to maintain access was cumbersome. Git, on the other hand, deals away with this overhead. First, initiate your repository:

(django-1.1)$ mkdir blog_project
(django-1.1)$ cd blog_project
(django-1.1)$ git init
Initialized empty Git repository in /home/kenneth/blog_project

That was easy. I continued to start a Django project.

(django-1.1)$ django-admin.py startproject blog_project

Then I made my first commit.

$ git add .
$ git commit -m "Committing default project"
Created initial commit 8f3eaee: Committing default project
 3 files changed, 107 insertions(+), 0 deletions(-)
 create mode 100644 blog_project/__init__.py
 create mode 100755 blog_project/manage.py
 create mode 100644 blog_project/settings.py
 create mode 100644 blog_project/urls.py

The git add and git commit commands were the most used. You will work on a feature, add it to the staging area, commit it to the repository, repeat. There are other useful commands to do with branches, undoing a commit, unstaging files, viewing diffs, etc. The git docs are a great place to start.

How do you model this

At this time I only have the default Django project files. I wanted a blog, so I started with a new Django app.

(django-1.1)$ cd blog_project
(django-1.1)$ django-admin.py startapp blog

My model for the blog is called Entry. Here it is.

from django.db import models
from tagging.fields import TagField

class Entry(models.Model):
    text = models.TextField()
    title = models.CharField(max_length=100)
    slug = models.SlugField()
    excerpt = models.TextField()
    date = models.DateTimeField()
    draft = models.BooleanField()
    enable_comments = models.BooleanField()
    tags = TagField()

    class Meta:
        verbose_name_plural = "entries"
        ordering = ('-date',)

I said it was simple. The only thing that might raise an eyebrow is TagField, which comes from the django-tagging package. django-tagging gives you generic tagging functionality that works in a similar way to Django’s generic comments framework. You hook your tagging functionality using templatetags in your templates.

There are two interesting things on settings.py I learnt from the djangoproject.com code that I want to share.

# templates are in ./templates relative to settings.py
TEMPLATE_DIRS = [os.path.join(os.path.dirname(__file__), "templates")]

# debug mode if server not run on the production box
import platform
DEBUG = (platform.node() != "web58.webfaction.com")

I had settings.py setup to use a PostgreSQL database on my Ubuntu box. I then ran python manage.py syncdb to create the tables and to setup the admin username and password.

(django-1.1)$ python manage.py syncdb

Routing the traffic

There are no URLs setup at this stage. Before I wrote any code to urls.py, I did a rough sketch of the sitemap. It helped me see what urls I needed to write. Luckily, there weren’t many.

from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()

blog_data = (
    ("queryset", Entry.objects.exclude(draft=True)),
    ("template_name", "blog/index.html"),
)

blog_info = dict(blog_data + (
    ("paginate_by", 10),
))

single_blog_info = dict(blog_data + (
    ("date_field", "date"),
    ("month_format", "%m"),
    ("template_name", "blog/single.html"),
    ("slug_field", "slug"),
))

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls,)),
    (r'^$', 'django.views.generic.list_detail.object_list', blog_info),
    url(r'^(?P\d{4})/(?P\d{2})/(?P\d+)/(?P[A-Za-z0-9_-]+)/$', \ 
        'django.views.generic.date_based.object_detail', single_blog_info, name="single"),
)

I have no need for my own custom views, so I helped myself to Django’s excellent generic views. I also uncommented the admin lines to give me free admin. I created two quick templates at blog/index.html and blog/single.html. I fired up the development server and, sure enough, everything works.

Playing nice with Django

Having configured my urls.py, I thought I would play nice with Django and implement the get_absolute_url method for my Entry model, which is all documented very nicely.

class Entry(models.Model):
    ...
    @property
    def year(self):
        return self.date.strftime("%Y")

    @property
    def month(self):
        return self.date.strftime("%m")

    @property
    def day(self):
        return self.date.strftime("%d")

    @models.permalink
    def get_absolute_url(self):
        return ('single', (), \
            {'year': self.year, 'month': self.month, 'day': self.day, 'slug': self.slug})

Implementing it means that your code adheres to the DRY principles, and you can do this in your templates:

Django Powered

(These posts are no longer relevant as I’ve migrated to Posterous!)

Welcome to my humble blog. If I recall correctly, this is my fifth attempt at writing a blog. The first blog was powered by WordPress and it was laden with teenage angst; the second one was also powered by WordPress, but I fail to recall what I wrote about; the third one was also powered by WordPress, and the topic was more football than teenage angst. The last blog aimed at documenting my internship at Airbus UK, but feeble efforts resulted in sporadic entries, which resulted in a blog that didn’t have much to offer.

After completing my Python joint at Airbus, I decided to pick up Django again. While it is easy and fun to pick things up, it can quickly become boring reading documentation after documentation. I realized I needed to do something with Django. So I developed this blog.

While I was coding my blog, I found out I was looking for things that I have once searched for, something that I have simply forgotten. Then I was sure. I am going to document things that I have learnt on here, in the hope that I can come back here to look for things that are fuzzy in my memory and to share with the community.

Although I am an Engineering student, I have always loved the web; I love expressing ideas on the web; I love the way people help each other on the web, etc. I understand that I am not a designer by profession, nor am I a computer scientist. I know I can overcome these shortcomings with my enthusiasm and maintain a blog that both I and others can use.

But it looks like someone else’s blog

Indeed, it does. Django introduced me to @ubernostrum, the release manager responsible for Django. I loved his layout because it emphasized the site’s content, which offers quality discussion on different techniques and the current development of Django. There is another blog that takes on the emphasize on content. That’s why I decided to go a similar route. I want to focus on quality rather than the fluff.

The design will coerce me into thinking more about my entry before posting, as there is nowhere for the text to hide.

Help aplenty

I can’t say I used a tremendous effort to set this blog up. After all, Django did all the work for me. It took me around 3 days from setting up the Django project to deploying it on the excellent webfaction server. I received a lot of help regarding deploying the site using fabric using a tremendous guide from morethanseven. This brings me back to my point of blogging these kind of information where I and others might find useful someday.

kennethkam.com has one app, which is the blog itself. The category/tagging app comes from django-tagging; comments and comments moderation are courtesy of Django’s comments framework, and additional akismet filter from sciyoshi; feeds are generated by Django’s feed framework; and the Google sitemap by Django’s sitemap framework. The blog entries uses markdown and typogrify to make it look aesthetically pleasing.

The next stop is

I plan to document on the steps I took to complete a simple blogging system in Django in the near future, followed by many more. Also, I will be focusing on reading other blogs and learning from them. At the end of the day, I know I want to become a developer, and I am certain that blogging on a specific topic will help me get closer to my goal.