Horror Code: the Impossible Function

This is one of the less readable functions that I've found in my life. I've removed any reference to structures and variable names, according to the Italian law about privacy ;-)

I don't want to add any other comment. Enjoy!
static int my_function( /* Parameters */ )
{
  /* Some code */
  int j;
  for(j = 0; j < 2; j++) {
    /* Some code */
    if (j == 0) {
      /* Some code */
    } else {
      /* Some code */
    }
    /* Some code */
    if ( /* Condition */ ) {
      if ( /* Condition */ ) {
        /* Some code */
        if ( /* Condition */ ) {
          /* Some code */
          if ( /* Condition */ ) {
            /* Some code */
            if ( /* Condition */ ) {
              int i;
              /* Some code */
              for(i = 0; i < length; i++) {
                /* Some code */
                if ( /* Condition */ ) {
                  /* Some code */
                  if ( /* Condition */ ) {
                    if ( /* Condition */ ) {
                      /* Some code */
                      if ( /* Condition */ ) {
                        /* Some code */
                        if ( /* Condition */ ) {
                          /* Some code */
                          if ( /* Condition */ ) {
                            /* Some code */
                          }
                          /* Some code */
                          if ( /* Condition */ ) {
                            /* Some code */
                          } else {
                            /* Some code */
                          }
                        } else {
                            /* Some code */
                        }
                        /* Some code */
                      } else {
                        /* Some code */
                      }
                      /* Some code */
                    } else {
                      /* Some code */
                    }
                  } else {
                    /* Some code */
                  }
                } else {
                  /* Some code */
                }
              }
            } else {
              /* Some code */
            }
          } else {
            /* Some code */
          }
        } else {
          /* Some code */
        }
        /* Some code */
      } else {
        /* Some code */
      }
      /* Some code */
    }
  }
  /* Some code */
  if ( /* Condition */ ) {
    /* Some code */
  } else {
    /* Some code */
  }
  /* Some code */
  return 0;
}
The real function has 113 rows and most of the code in the else's is made of debug prints. The innermost code, the only one that actually does something, is indented 13 (thirteen) times.

Wasn't there a clearer way to write that function?

Useful Git Commands: Stash

Tom knows best!
(Picture by dealingwith)
How wonderful would it be to do your job without interruptions? But unfortunately we live in a complex world and intermissions are part of the game.

A particular annoying disturbance is when you are in the middle of a big refactoring or adding a complex function to a software and someone comes to you asking to immediately fix a bug in the same code.

What you need is a function in your VCS to park your modifications, checkout the right version to modify, fix the bug and then return to your code, without copying files around the disk or make meaningless commits. What you need is git stash.

Simple and Powerful

To save your temporary work, you only need to type git stash. Use the flag --include-untracked to save also new files. When you need to go back to your previous situation, use git stash pop. You can stash how many commits you want and replay them in any order and potentially on top of different commits.

Stashing can be useful every time you need to save your partial work or obtain a clean workspace without losing your modifications, for example when pulling from a remote repository on a non-clean working tree. But it can also be used when you realize that you are working on the wrong branch: you have just to stash, checkout the right branch and then pop. Fast and easy.

In the man page you can find other options, such as the creation of a new branch starting from the commit at which the stash was originally created.

Is Google Enough?

let me Google that for you homepageFew days ago, two U.S. senators have proposed a bill to force Government Agencies to use Google for their searches instead of the service provided by the National Technical Information Service (NTIS).

Honestly I think this is a provocation, since the short title (Let Me Google That For You Act) is the name of an ironic site that can be used to answer people asking you for trivial questions - and indirectly telling them that they made a stupid question.

Moreover, the NTIS is focused on technical publications, that are hard to find using a general-purpose search engine.

I Bet You Like U2

(*)
But my perplexity is related to the implied concept: everyone is able to to find what he needs using Google. No Sirs, this is simply not true. Without speaking about individual abilities to use a search engine, there are three major reasons why I'm sure about that.
  1. Google database don't include all the sites. There's a large part of Internet that is not (yet) indexed by search engines. And there are many pages behind paywalls that are not reachable without a registration.

  2. About 90% of people never go beyond the first page of results. And since many results on the first page are usually there because of SEO optimizations, they might not be significant for your search.

  3. Often people don't know if they have found the best answer. People usually search things that they don't know. This is obvious. But since they don't know in deep the argument, how can they pick the best answer for their needs?
This last point has a corollary: not all the sites returned by a search engine have the same level of authority. Some experience is needed to understand if a site, an author or an article is reliable or not. In addition, you have also to consider the mass of sensationalist headlines that aim only to gain some visit.

Over all these consideration there is the time factor. How long an unexperienced person will take to find what she needs in the depht of Internet compared to the time needed by a skilled guy to query a database? And how many times the same thing will be searched by different people?

To Conclude, a Quote

If, indeed, the Internet has a lot to offer to those who know what they are looking for, it is also able to complete the stupidity of those who sail without a compass.
- Laurent Laplante

Throw it Away!

Take a look to this infographic about the creation of Instagram, one of the most popular social network (click on the image for a better view).

Image taken from here via +Riccardo Esposito 

Do you see something strange? Yes, the founders threw away a big part of their job. Twice in less than two months!

As +Seth Godin wrote last week (in this post):
I find that it's almost essential to fall in love with an idea to invest the time it takes to make it good and worth sharing. And then, the hard part: deleting that idea when it's just not what it could be.
The "hard part" is what makes the difference between a good product and billions of mediocre things out there. If you don't trust me nor Seth, try to ask Robert.

The Month Lengths Problem

The first time I've heard of this problem, I was 14.

At school, during the math class, we started to learn the basics of programming using a language called L2P (no, you won't find it on Wikipedia and, no, it's not worth learning it).

Anyway, this is, more or less, the problem the teacher gave us to solve:

Write a function that returns the number of days of a month in a given year.

Plain Solutions

Any solution must start with the management of February.
if (month == 2) {
        if (!(year % 100) && (year % 400))
                days = 28;
        else if (!(year % 4))
                days = 29;
        else
                days = 28;
}
Once we have done with the most troublesome month, one solution can involve an array of twelve integers filled at design time with the right numbers. This is probably the way that I'd solve it today but I don't think the teacher would have liked it.

Another good solution is to check first the months with 30 days since they are only four: April, June, September and November.
if ((month == 4) || (month == 6) || (month == 9) || (month == 11))
        days = 30;
else
        days = 31;
Obviously the above solution can be rewritten, in a more readable way, with a switch statement. I'll leave it to you as homework ;-)

Well, you can say that the above code is the solution to the problem. And, when I was 14, I was convinced too. But the teacher was not satisfied. She had another solution.

C'mon, Show Me How Smart You Are

The management of February was the same, but for other months the code was a little tricky.
if (((month < 8) && !(month % 2)) || ((month > 8) && (month % 2)))
        days = 30;
else
        days = 31;
Have you understood the logic behind this? Basically, the months with 30 days are:
  • the even ones between March and July and
  • the odd ones after August.
You can tell this if you think deeply about the numbers (like a math teacher is supposed to do). But is this a good solution? No, it isn't. And probably it's the worst.

Keep It Simple, Schoolteacher

It has at least two weaknesses: performances and readability. Speaking about the execution speed, two comparisons and two modules are definitely slower than four comparisons.

But the biggest issue is the second: you don't have to show me that you are a good programmer. If you write code that is not easily understandable, you will never be a good member for a development team where everyone should be able to modify each others code.

So, dear teacher, you have been rejected in Computer Science.

A Final Confession

OK, I confess. I've been a little too trenchant. The teacher's solution is not so bad. It has a big quality: the spur to think different, to explore different solutions. Because only comparing different things you can choose the best one.

4 Things to Do Before Starting a New Project

Are you ready to put your hands on the keyboard?
(Image by courtesy of +Riccardo Esposito)
This is the situation: the Project Manager has written the specifications, everything is clear and you only have to do the kick start to you team of developers.

This point is where you can start to fail. If you let every programmer (that is lazy by definition) to take its own decisions, your project will be pure anarchy.

Here there is a short list of things to consider before starting to write code to have some chance to do the job in an acceptable amount of time and without losing your mental health.

1. Select a VCS and Lay Down the Rules for Commits and Branches

I suggest you to use Git. I have already explained the reasons in this post but, to make it short, Git is fast, cheap (not because it's free but in terms of disk usage) and extremely powerful.

Once you have chosen Git ;-) you have to set clear rules for commit and branches to avoid developers transform your repository in a landfill. You can take inspiration from this great post.

The rules should also cover commit comments because it's important that every change in the repository is correctly documented.

2. Define Coding Styles

Using the same code style is very important if many developers are working on the same project. Everyone should be able to understand and modify every piece of code without spending time to feel comfortable with indentation and names.

To improve the adoption of a style, you can institute a fine of 1 euro/dollar/pound for every line of code that is not correctly formatted and, from time to time, use those money to go to eat a pizza all together. If you are wondering how you can detect the author of each line of code, git blame is the answer.

3. Define the Style for the Technical Documentation

Every function should be preceded by a comment and Doxygen is a wonderful tool to collect all those comments and generate a document or a website for a quick reference.

Obviously not everything can be specified in a comment into source files. To write documents that can be easily managed by a VCS, I suggest Markdown and Multi-Markdown. The idea behind MD is to have an easy-to-write language to create HTML snippets that is also easy-to-read while MMD adds some features (such as tables) maintaining the same philosophy.

If you prefer a WYSIWYG editor, you can save your documents in odt format and use odt2txt in order to let Git show the differences between revisions; here is how to do (unfortunately this works only for diffing, merge is not allowed).

4. Chose a Decent Bug Tracker

Maybe now you are asking why is important to choose a BT before having written a single line of code. There are three main reasons:
  • first, you can use it also to assign development tasks,
  • second, soon there will be the need to change something in the original architecture; use the bug tracker host the discussions, and
  • third, don't let the Quality Assurance team choose for you ;-)
Speaking about bug tracking tools, I would like to tell you how much Redmine is great but unfortunately I've not (yet) had the opportunity to test it. In my company we're using Mantis and I can say that it's not so bad for medium-size projects.

Remember You Are Not Alone

All the above points are useless if they are not agreed by the development team. For this reason, rules should not be imposed from the top but discussed with everyone is involved in the project to make sure they understand the logic behind them.

It's important to keep an open mind in this phase because developers can suggest some improvement, based on their experience, to better adapt those rules to the specific project and the team.

OK, now you are ready for the kick start. Good luck!