Sunday, January 29, 2012

Why Schipica failed

One of the first year computer science courses given at Utrecht is the introductory project; a team assignment in which we had three months to write a program that would create a schedule for an airport.  To be specific, we have been writing a program that would allocate gates to flights, with things like the arrival times and plane type being predetermined.  The final product must be handed in in three days, and I thought I'd take a look at why we have failed to get anywhere near what we were planning to do.

I'll do my best to cover the problems in chronological order; this isn't particularly easy, as most have been present for the duration of the project, and are not particularly independent.  In cases where the order is unclear, I've put the less severe ones first.

Problem One:  Unclear Goals

When we first started on the project, we knew we had to write a gate allocation algorithm, and we knew we had to show the resulting schedule somehow, but we had absolutely no clue how to tell whether a schedule was good or not.  It wasn't just that we could phrase it as an algorithm: I know for myself that given two schedules, I would not have been able to tell which one is better, or how either could be improved, and being my arrogant self, I had not realised that.

The greatest mistake made as a result of this was that the logic for judging a schedule was written much, much later than it should have been.  Instead of asserting that the algorithm should be the key part and that everyone should help in writing it, the project was split into parts, with different people getting different responsibilities.  This sounded great on paper, and may have by itself not significantly hurt matters, but the delay with which work began on the algorithm ended up too great, leading to almost all of it being done by one person.

Problem Two:  Setting a Bad Example

My responsibility in the project was creating suitable representations for the gates, flights, schedules, and all related things.  It wasn't a small task, but seeing as I knew it was important for work on the algorithm to begin, I promised to get something that could be used done in a week.  Unsurprisingly, the result wasn't quite as impressive as I had hoped, and although work could begin, things were still being moved around a lot; all in all, the impression I think I left was that getting some skeleton up by the due date and then fixing it later was okay.

As a result, things didn't go all that fast.  The day the algorithm was supposed to be presentable, its code did absolutely nothing -- returning dummy values from any functions that did any calculations, and recursing endlessly when asked to make a change.  It was eventually fixed, but by that time it was too late to start adding many of the features we wanted it to have.

I think that after the first week or two, I became a good deal better at estimating how much I can do and thus left less of an impression of goals not being reached, but the damage seemed to have been done.  Which brings us to the next point...

Problem Three:  Too Much Procrastination

Unlike most students, who only have one other subject during this project, everyone in my group was also doing mathematics, meaning we had three.  This was, in my opinion, manageable:  I had enough time for most of my commitments, and could have spared a lot more for my study had I felt the need for it.  It was, however, a great excuse for people to put off doing practically any work on the project until after the winter vacation -- and as if that wasn't bad enough, things were then put off until after the test week, which was a week ago.

As the team leader, I should simply have not allowed this.  The next time someone tells me that they will delay starting work on a project by any amount of time, I will (hopefully) be a lot more critical as to why, for how long, and what deadlines they will achieve once they do start working.  Anything longer than two weeks is almost certainly a bad idea; two months of a three month project is just out.  If two studies is too much, the answer is to drop one, and just ignoring it until there's time is not acceptable.

Problem Four:  Too Much Code

Related to that problem is that once people did start working, the project was, well, big.  My projects tend to be fairly large; I'm used to putting everything that looks like it could be encapsulated in a class, and my part must have been about fifteen classes in size.  This is a problem I am aware of, and I am trying to remove the amount of abstraction that does not help in my code.  Usually, however, it is not a particularly big deal, as I am working alone and understand the code despite it being too complex.

In this case, however, some of the other team members had trouble diving in once the monster had grown a little.  I don't blame them for it, although better communication on both sides could have probably mitigated a lot of this: fact was, however, that the code had to be simplified.  The situation became better after some feature cuts and the removal of the corresponding code, but I think that getting it right immediately would have been a significant improvement.

The sad part about this is that I still don't see how the code could have been simplified in any noticeable way without some features being cut.  That does lead to the following point, though...

Problem Five:  Wrong Order of Action

When designing, I tried my best to get the big picture, then write the code to work in that case.  It didn't work out very well, and I ended up doing quite a bit of work that I later got rid of, and didn't anticipate things that I should probably have seen coming.

In particular, one thing that I did not employ at all were data flow diagrams.  Just by looking at what data the user interface and local search algorithm could reasonably be expected to have, and what data they would want, I could probably have started out with a much better design.  For example, I expected both to know about the airport, and that the airport would know about the flights and gates being worked on.  However, it was only much later that I realised that nobody knew about what time period was being worked on.  It ended up being the GUI code that decided it, and I have the feeling that running the program around midnight may lead to interesting errors.

Another point was that the data structures came long before the algorithms, and while this sounded good in theory (easy to test), it meant that it was unclear which methods were worth writing and testing, and which were probably best thrown away.  All in all, YAGNI is certainly something I intend to follow more often in the future.

Problem Six:  Poor Communication

Last but certainly not least, the communication within the team was not quite as good as it should have been. The meetings were too much about what we wanted to do, and too little about people showing what they have done.  There were vague expectations.  People didn't immediately contact others about the problems they ran into.

I think part of this was caused by the low quantity of work being done, which lead to people not realising it when they were unable to proceed: having stricter deadlines and it being clearly visible when people failed to reach them would allow for much faster reactions, and more effort to be put into fixing the issues currently present.

I also think that meeting once a week was not enough.  The amount of work that can be done in a week is simply too great: expecting people to cover even most of the changes they made simply isn't realistic.  We had meetings on Wednesdays; another meeting on Sunday would probably have revealed some issues, and would at worst keep people informed on what was going on.

Finally, a significant method of communication that was underused were commits.  In a project this small, committing as often as possible gives people an idea of who is working on what, what is being done, and how much of their new code has been broken by the latest changes.  The last is doubly important when not everyone has experience with merging: figuring out how to fix merge errors can take a while the first few times, and larger merges make bugs more likely.  In the future, I will do my best to enforce weekly commits in the early stages of the assignment, and possibly increase that to two or three commits per week if that seems realistic.

All in all, I think problem three was the most important to address, and problem six would have been the hardest.  So, resolutions for my next project:

  • Set deadlines
  • Demand progress be shown
  • Everyone starts coding at the same time
  • Most important part of the program first
  • Meetings focused on immediate problems, not long-term goals
Hopefully there'll be a chance to put these to the test soon; I can't wait to start building something again.

No comments:

Post a Comment