Wednesday, 26 November 2014

Debugging code in a competitive setting, Part 1


Writing code in a competitive setting is an especially tiring and frustrating task, for a multitude of reasons. The rush of wanting to code fast prevents one from applying good coding standards and leads to trivial errors. Also, there is no time to set up a testing framework etc. How do you prevent (or at least find and correct) any errors in the code you write?

What I personally do is to use a combination of gdb and a custom debug message function.

The first part of this series of posts will explain the function

First, I always put the following code at the start of my programs:

#ifdef DEBUGIT
  #define DEBUG(X) cerr << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << X << endl
#else
  #define DEBUG(X) (void)0
#endif

Now, whenever there is a need to check the value of a variable (or expression), all that is left to be done is to call the DEBUG() function like so:

DEBUG(x); // debugging variable x
DEBUG((a<<3)+2); // debugging an expression

The way that the "function" (or macro, to be precise) is defined, whenever DEBUGIT is defined at compilation, debug statements are shown, and otherwise, they are just skipped.

Hence, whenever you want to look at the debug statements, use g++ -DDEBUGIT to compile instead of just g++.

Here's an example program and its output:

#include <iostream>

using namespace std;

#ifdef DEBUGIT
  #define DEBUG(X) cerr << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << X << endl
#else
  #define DEBUG(X) (void)0
#endif

int main() {
  int x = 5, y = 10;
  DEBUG(x);
  DEBUG(y);
  ++x += y++;
  DEBUG(y+1);
  cout << x << endl;
}

Output:

>>> DEBUG(13) x = 5
>>> DEBUG(14) y = 10
>>> DEBUG(16) y+1 = 12
16

The advantage with the DEBUGIT technique is that you can directly submit code (without any modifications) and the grader will not run the DEBUG statements at all.

I have added the following line to my .bashrc file:

alias d++='g++ -DDEBUGIT'

Hence, I can directly run d++ for compiling with the debug statements.

In my next post, I will explain how to use gdb to further make life easier.

Monday, 24 November 2014

Terminal based Spell Check

Here's a cool little script I wrote (added to my .bashrc) file in order to test spellings, or to generate them when I don't remember them.

function spelling {
if [ $((`grep -c "^$1$" /usr/share/dict/american-english`)) -gt 0 ]; then
   echo -e "Spelling of\e[1;32m" `grep -m 1 "^$1$" \
    /usr/share/dict/american-english` "\e[0mseems fine"
else 
   echo -e "\e[1;31mThere seems to be a mistake in spelling\e[0m"
fi
}

The script is run quite simply by saying "spelling word-to-be-checked". For example,
spelling look
would say
Spelling of look seems fine
but
spelling louk
would say
There seems to be a mistake in spelling

Where this is extremely useful is when you cannot remember some part of the spelling of a word. For example allitaration or alliteration. Here, I can just use a regex.

Running
spelling allit.ration
would say
Spelling of alliteration seems fine
thereby giving the right spelling.