Flickr Badge

Friday, April 28, 2006

What should a PM do when the project is late?

So, let us say that you are the project manager for a project. The delivery date is in a weeks time and you know pretty well that you will not make the date. What do you do? Think about this for a while.

Here is what should be done
  1. Inform the client that you will not be able to make the delivery date and reschedule it for later.
  2. Remove any roadblocks that are slowing down the development team (this should be done always, not just when the team is behind schedule).


Sounds pretty simple? Yet, most PMs don't do this. Why? Because owning up to the client is hard. It's a lot easier to imagine that some miracle is going to occur and the team will make the date. But of course, what will happen is that the team won't make the date and you'll have to inform the client anyway - on the day of the delivery.

PMs also worry a lot about meeting the schedule, but they don't write code, so they cannot change the team progress in any way. But they can help the team speed up. How? Remove roadblocks that affect the team. Yet, many times they are so busy worrying about the schedule that they do not think about the things that really affect the team.

I like think of PMs as outward-looking or inward-looking. Outward-looking PMs are looking at the schedule and pressurising the team, whereas inward-looking PMs are looking at the team and protecting the team. As an extreme, neither completely outward-looking, nor completely inward-looking PMs are desirable, because you need to satisfy both the customer and take care of the team. However, I find that most PMs are too outward-looking, to the detriment of the team.

This post is a part of the selected archive.

Thursday, April 27, 2006

Recursion Part 4: Tree Recursion and Dynamic Programming

The following is a part of a series of articles I had written on recursion.

This part introduces tree recursion, a form of recursion that occurs when a function calls itself more than once in a path. We then introduce dynamic programming, a class of algorithms to tackle certain types of tree recursive problems.

All Parts:

Recursion Part 1: Introduction to recursion
Recursion Part 2: Tail recursion, Accumulators and Iteration
Recursion Part 3: Exercises in tail recursion
Recursion Part 4: Tree Recursion and Dynamic Programming
Recursion Part 5: Structural and Generative Recursion
Recursion Part 6: References and Further Information


Some recursive functions call themselves more than once. Consider the function to calculate the nth term of a fibonacci series:


int fibonacci(int n)
{
if (0 == n) {
return 0;
} else if (1 == n) {
return 1;
} else {
return fibonacci(n - 2) + fibonacci(n - 1);
}
}

In order to calculate fibonacci(4), we need to calculate fibonacci(2) and fibonacci(3). For each call, there are two more recursive calls. This proceeds until n becomes 0 or 1, which are the terminating points of the recursion. We see that execution follows a tree form like this:


fibonacci(4)
+------------------------------
| |
fibonacci(2) fibonacci(3)
+----------------- +---------------
| | | |
fibonacci(0) fibonacci(1) fibonacci(1) fibonacci(2)
+-----------
| |
fibonacci(0) fibonacci(1)

Each node has two children, one for each recursive call. A function with 'n' recursive calls will have 'n' children at each node. Since program execution follows a tree like structure, we call this form of recursion tree recursion

Is there any way to convert tree recursion to iteration?

The short answer is no1. There is no general algorithm to convert tree recursion to iteration. However, specialised algorithms do exists for certain problems. These algorithms (if they exist) are usually specific to each problem.

And it just so happens that our fibonacci algorithm falls into a class of tree recursive problems that can be converted to iteration using a technique called dynamic programming!

Look at the execution pattern for fibonacci(4) again. Notice how fibonacci(2) is calculated twice: Once in the computation of fibonacci(4) and once again in the computation of fibonacci(3). fibonacci(1) is computed thrice!

What if we could save the values of previous fibonacci terms when they are first computed and reuse the values later on without having to compute them again? This optimisation is the cornerstone of dynamic programming.

Here is how we can proceed:
1. Store the initial values of fibonacci(0) and fibonacci(1)
2. Compute fibonacci(2) from fibonacci(0) and fibonacci(1). The saved value of fibonacci(0) is now no longer required, so we can discard it.
2a. In general, compute fibonacci(n + 1) from the saved values of fibonacci(n - 1) and fibonacci(n). Discard the value of fibonacci(n - 1).
4. Repeat step 2a until we have computed the desired term

Look at the execution tree again. Notice how we start the computation from the leaf nodes of the tree and work our way up the tree computing each node, until we reach the root, which is the value we desire.

Here is the implementation using iteration:


int fibonacci(int n)
{
int a = 0, b = 1, temp = 0;
int i = 0;

for (i=1; i<=n; i++) {
temp = a + b;
a = b;
b = temp;
}
return a;
}

We have just used dynamic programming to convert a tree recursive algorithm into an iterative algorithm. The basic idea of dynamic programming is to look at the execution tree, identify repeated computations and perform the calculations 'bottom-up' from leaf to root. At each step, the computed values of the subproblems are stored to be reused later.

Dynamic programming cannot be used on every problem. Some problems can be converted to iteration using other methods, and some problems cannot be converted to iteration at all. Nevertheless, dynamic programming works on a large class of problems, and it is a useful tool to have in the toolbox


1 You can write an iterative loop that manages it's own stack, but that is basically equivalent to recursion.

Any questions? Comments? Please leave a comment using the comment form below.


This post is a part of the selected archive.

Monday, April 17, 2006

Agile India 2006

So the Agile India 2006 conference is around the corner once again. Too bad I'll be in Singapore when it happens.

Going through the list of topics once, I'm struck by a sense of deja vu. Yet another introduction to Agile. Yet more introductions to developer testing. Didn't we go through much of this last time?

And, how many sessions on tools!! Selenium, Watir, Frenkenstein, J2EE Testing, Sahi.. please, enough already! Last time it was FIT, Marathon, CppUnit, Cruisecontrol and DamageControl. Tool discussions should be limited to workshops. That's where they are the most useful. Nothing more boring than watch someone explain xml configuration files on a powerpoint slide.

Presentations should be for concepts: To illustrate, explaining why continuous integration is so damn cool should be done in a presentation. You want to generate people to buy in and believe in the concept. Describing a specific CI tool like Cruisecontrol or DamageControl should go into the workshop.

Two topics that caught my eye were "Design And Implementation of Robotics Languages" by Ravi Mohan and "Agile Approach to Bootstrapping a custom Firmware for Lego Mindstorms" by Rajesh Babu, just because they are so different from the rest.

I heard Ravi Mohan talk last year and it was very interesting for its "geek" factor. It was about using Agile techniques with AI software (using a combination of Lisp, Erlang, C and Ruby :) ). And then ripped up a few people on the panel discussion.. that was fun. We had a chat later on. His website is One Man Hacking.

The two keynotes also sound interesting, especially the one on DSDM. Most people equate Agile to XP, or sometimes Scrum. The fact is that there are many agile methods, some of which differ drastically from XP. From what I've read, DSDM is one of those. For instance, DSDM teams have specialist roles, whereas XP says that most team members should be cross-functional. And DSDM does emphasise some modelling, unlike the XP mantra of No Big Design Up Front.

A couple of people I'd really like to hear are Alistair Cockburn and David Anderson, (both are Scots incidentally) simply because they bring in such a different perspective on Agile. I'm a BIG fan of both of them. [Sometimes I think that the term Agile has been co-opted by the XP and Scrum groups, but that's a topic for another post.]

There are a few other interesting sessions here and there, but I just get this nagging feeling in my gut that most of the other sessions are just going to rehash the same old stuff yet again.

Anyway, for Rs.500, the conference is an absolute steal! Definately worth going to. It was excellently organised last year and certainly worth going to again this year. If you haven't registered yet, hurry up and register already. You can register online, and you only have to pay at the counter when you get there. The registration form is here.

This post is a part of the selected archive.

Recursion Part 3: Exercises in tail recursion

The following is a part of a series of articles I had written on recursion.

This part provides some exercises related to the concepts introduced in the previous part.

All Parts:

Recursion Part 1: Introduction to recursion
Recursion Part 2: Tail recursion, Accumulators and Iteration
Recursion Part 3: Exercises in tail recursion
Recursion Part 4: Tree Recursion and Dynamic Programming
Recursion Part 5: Structural and Generative Recursion
Recursion Part 6: References and Further Information


Try out the following problems: Ask any questions/answers in the comments.

Is this tail recursion?

int fibonacci(int n)
{
if (n <= 2) {
return 1;
} else {
return fibonacci(n - 2) + fibonacci(n - 1);
}
}

What about this?

node findRoot(node child)
{
if (NULL == child->parent) {
return child;
} else {
findRoot(child->parent);
}
}

And this?

node findNodeInList(node head, int dataToFind)
{
if (NULL == head) {
return NULL;
} else if (head->data == dataToFind) {
return head;
} else {
return findNodeInList(head->next);
}
}

Try converting the above three programs to iterative versions. Do you find some harder than the others?


Convert this iterative program into a tail recursive version. First convert it to an accumulator based function and then convert that to an ordinary tail recursive version. Hint: First convert the for loop into a while loop.

int sumOfFirstNnumbers(int n)
{
int i = 0, sum = 0;

for (i=1; i<=n; i++) {
sum += i;
}
return sum;
}

How about this one? Assume all numbers are positive (> 0). Hint: The accumulator does not always have to perform some mathematical operation. It can also be used to keep track of the state so far.

int findMax(int *numberArray, int arrayLength)
{
int i = 0, max = 0;

for (i=0; i<arrayLength; i++) {
if (max < numberArray[i]) {
max = numberArray[i];
}
}
return max;
}

Any questions? Comments? Please leave a comment using the comment form below.


This post is a part of the selected archive.

Sunday, April 16, 2006

Frog & Lily


Frog & Lily
Originally uploaded by Siddhi.
Taken at the Botanical Garden in Singapore

Thursday, April 13, 2006

J2ME notes

Some J2ME notes :
  1. Antenna : Ant tasks for building and packaging J2ME midlets
  2. J2ME performance tips
  3. Remember to catch those OutOfMemoryExceptions! It is all too easy to run out of memory on a contrained device and programmers used to writing code for PCs or servers are just not in the habit of handling out of memory errors

Recursion Part 2: Tail recursion, Accumulators and Iteration

The following is a part of a series of articles I had written on recursion.

This article introduces an important concept in recursion: the tail recursion. We see what tail recursion is, and where it is used. We end the article with the relationship between tail recursion and iteration.

All Parts:

Recursion Part 1: Introduction to recursion
Recursion Part 2: Tail recursion, Accumulators and Iteration
Recursion Part 3: Exercises in tail recursion
Recursion Part 4: Tree Recursion and Dynamic Programming
Recursion Part 5: Structural and Generative Recursion
Recursion Part 6: References and Further Information


Let us get back to the factorial program:


int factorial(int n)
{
if (0 == n) {
return 1;
} else {
return n * factorial(n - 1);
}
}

As we saw in Part 1, the execution of this program goes like this:


factorial(4)
4 * factorial(3)
4 * 3 * factorial(2)
4 * 3 * 2 * factorial(1)
4 * 3 * 2 * 1 * factorial(0)
4 * 3 * 2 * 1 * 1
4 * 3 * 2 * 1
4 * 3 * 2
4 * 6
return 24

In this program, the multiplication with 'n' is the deferred operation (See Part 1 of this series for an introduction on deferred operations). Apart from the deferred operation, there is the recursive call to calculate factorial(n - 1).

Since the recursive call is the last step of the function, this type of recursion is called tail recursion. The name derives from the fact that the recursive call occurs at the end of the function. Oridinary tail recursion has a deferred operation and a recursive call. Pure tail recursion has no deferred operation, it only has a recursive call. The above implementation of the factorial is ordinary tail recursion because it has a deferred operation.

As we saw in Part 1, the deferred operation is carried out when the stack gets popped. Is there any way we can carry out the operation immediately and pass in the value to the function? Take a look at this implementation of factorial:


int factorial(int n)
{
return factorial_acc(1, n);
}

int factorial_acc(int acc, int n)
{
if (0 == n) {
return acc;
} else {
return factorial_acc(n * acc, n - 1);
}
}

Let us trace the execution of this program to calculate factorial(4):


factorial(4)
factorial_acc(1, 4)
factorial_acc(4, 3)
factorial_acc(12, 2)
factorial_acc(24, 1)
factorial_acc(24, 0)
return 24

Notice the difference with the normal factorial implementation? In this version, there are no deferred operations. Instead, the value of the deferred operation is calculated immediately and passed as the first parameter to the recursive function. This parameter is known as the accumulator parameter (in case you were wondering, that is why it is called acc, and the function is called factorial_acc). The role of the accumulator parameter is to accumulate the result of the operations at each step. Note that this version computes the multiplication during a stack push rather than a stack pop. Nothing is done during stack pop, and so this version is pure tail recursion.

Take a look at this iterative implementation of a factorial:


int factorial_iter(int n)
{
int fact = 1, i = n;

while (i > 0) {
fact = fact * i;
i--;
}
return fact;
}

Notice any similarities with the accumulator version? Look at how the variables change with each iteration while calculating factorial(4):


factorial_iter(4)
fact = 1, i = 4
fact = 4, i = 3
fact = 12, i = 2
fact = 24, i = 1
fact = 24, i = 0
return 24

Compare the fact and i variables in the iterative version with the acc and n parameters in the accumulator version. They are identical! In other words, the accumulator version simply implements a while loop using recursion!

So here is the big result: Any ordinary tail recursive program can be converted to a pure tail recursive program with accumulator, which in turn can be converted to a while loop. Thus, ordinary tail recursion and iteration are equivalent, and the above steps give us a way to convert between the two forms!

Because iteration is nothing but a special case of recursion, some languages like Lisp, Scheme and others do not have any iteration methods. There are no for loops, while loops or do-while loops in these languages. All looping is accomplished by using either ordinary or pure tail recursion! These languages have special mechanisms for optimising tail recursion so that they do not increase the stack size.

Languages like C include iterative methods and offer no special support for tail recursion. Since tail recursion is exactly equivalent to iteration, it makes sense to convert all tail recursion into iteration. However, beware of trying to convert non-tail recursion into iteration. As we shall see in later articles in this series, non-tail recursion is a very different beast altogether.


Any questions? Comments? Please leave a comment using the comment form below.


This post is a part of the selected archive.

Wednesday, April 12, 2006

Recursion Part 1: Introduction to Recursion

The following is a part of a series of articles I had written on recursion for a newsletter.

This is the first part of a mini-series of full length articles dealing with recursion. In this, the first part, we talk about some theory behind recursion. This theory will form the foundation and help in understanding the remaining parts of the series. Most of this theory will already be known and it is just a quick overview to refresh your memory.

All Parts:

Recursion Part 1: Introduction to recursion
Recursion Part 2: Tail recursion, Accumulators and Iteration
Recursion Part 3: Exercises in tail recursion
Recursion Part 4: Tree Recursion and Dynamic Programming
Recursion Part 5: Structural and Generative Recursion
Recursion Part 6: References and Further Information


Let us start with the most common example of recursion, calculating the factorial of a number.Here is the C code:


int factorial(int n)
{
if (0 == n) {
return 1;
} else {
return n * factorial(n - 1);
}
}

How does this work? Say we want to calculate factorial(4). Since 4 is not equal to 0, the expression evaluates to 4 * factorial(3). factorial(3) in turn is expanded to 3 * factorial(2). At each point, the previous state of execution is pushed on to the stack. Continuing this way, the expression evaluates to:


4 * 3 * 2 * 1 * factorial(0)

factorial(0) is 1, so we get:


4 * 3 * 2 * 1 * 1
4 * 3 * 2 * 1
4 * 3 * 2
4 * 6
24

The final answer is 24, which is indeed the factorial of 4. Let us summarize the state of execution at every step:


factorial(4)
4 * factorial(3)
4 * 3 * factorial(2)
4 * 3 * 2 * factorial(1)
4 * 3 * 2 * 1 * factorial(0)
4 * 3 * 2 * 1 * 1
4 * 3 * 2 * 1
4 * 3 * 2
4 * 6
24

Note an important point: No multiplications are performed until the stack starts to get popped. Thus, the execution of this function consists of a series of "deferred operations" which are stored in the stack state during the push operation, and which are executed after the pop operation.

Understanding the above point is the key to understanding many concepts in recursion. We will be using it in the other articles in this series.


Any questions? Comments? Please leave a comment using the comment form below.


This post is a part of the selected archive.

Tuesday, April 11, 2006

Elliot's Beach


Elliot's Beach
Originally uploaded by Siddhi.
Karl Schmidt memorial on Elliot's beach in Chennai.

The memorial is named after a Dutch sailor who lost his life rescuing a drowning swimmer.

Wikipedia article : Elliot's beach

Monday, April 10, 2006

Flickr Uploads

I'm uploading to flickr after a while, so just a reminder that the flickr bar that runs across the top of the page should now show some new photographs (finally!)

Friday, April 07, 2006

Really cool rube goldberg video

[via Ned Batchelder] : Google video has a really cool video of various Rube Goldberg machines done by some japanese students. Check it out here. It starts about 1:30 in the video, so you can skip to that point. There is an interruption in the middle which can also be skipped. If Google Videos doesnt work for you, then there are some instuctions on how to view the videos here : http://labnol.blogspot.com/2006/01/download-watch-google-videos-in-any.html