This happens to me all the time, especially when running programs that takes hours to complete.

  1. Start the code

  2. Go out for some tea or movie.

  3. When you come back, you find that the program had decided to piss you off by crashing 2 seconds after you went away from the keyboard.

The amount of cuss words thrown at the code/program is directly proportional to the silliness of the cause of the crash or error. Even more, if its a typo. Now that twitter allows tweets to be sent to Bharti AirTel (Boohoo others) numbers, and add Python + python-twitter + konsole (Terminal emulator from KDE) to the mix, you can get a very rudimentary notification system which can DM you when konsole activity changes.

To do this, First Enable ‘Monitor for Silence’ in ‘View’ Menu

Then ‘Settings’ –> ‘Configure Notifications’. In the dialog that pops us, configure the notifications such that it executes a python script. The dialog should look something like this,

dialog

The real deal is in the script. It uses the python-twitter module to send a DM from a dummy account to whatever account you want the notifications to go to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python

import twitter

username = "dummy_account"
password = "password"

receiver = "sup3rkiddo"

def sendDM():
    try:
        api = twitter.Api(username=username, password=password)
        stats = api.PostDirectMessage(receiver, "*Done compiling*")
    except:
        print "Error!"

if __name__ == '__main__':
    sendDM()

Thats it! Simple but useful ;p (Of course, change the message according your needs)

Recently I had to make use of Google’s translation engine to translate phrases at work. Given the lazy big bum I am, I found using the Google’s web UI a bit tiresome to use. I thought “heck, why not write a little jabber bot to make things a bit easier..”. (Agreed, writing a bot is nowhere near to the best solution.)

Writing a Jabber bot is incredibly easy with python. You will need the JabberBot package, which offers a really really simple and straightforward way to write bots. The little script below proves how easy it is.

The bot translates phrases/sentences using the python-pygtrans package. I had to name the script something and Nai Sekar seemed to be a good idea. Apologies if you just went ‘WTF?!’. (I am quite lame when it comes to naming code/function/classes)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#
# Released Under WTFPL
# http://sam.zoy.org/wtfpl/
#
from jabberbot import JabberBot
import gtrans
import random

# Gmail uses Jabber, but their TOS doesn't allow automated scripts. So be warned
username = 'yourJabberID@example.com'
password = 'password'

# Just some famous dialogues from Vadivelu comedy tracks. Might not make sense if you
# don't know who or what vadivelu is.
error_dialogues = [
    "Nee yaaru kitta paysikittu irrukaynu theriyuma? Sekar ngara oru TERROR kitta",
    "Saykar settutaan",
    "Tirisa illana Divya",
    "Huh.. yennaku body strong basement weeeku",
    "Naanum rowdy.. naanum rowdy.. naanum rowdy",
    "Shabba... ippovae kannu kattudae",
    "Heloooo.. Ennoda biruther maark irukaara",
    "Don't worry.. Be gaaapy",
    "But andha dealing enaku pudichi irundhuchi",
    "lighta...",
    "Vaynda... Vallikidu.... Azuthuduvane.. Azhuthuduvane",
    "Sing in the raine... I am swoying in the raine..",
    "Helloo.. Prabha wine shop ownerungala? Kadaiya.. yeppo saar tharapeenga?",
    " romba nallavanu enna pathu sollitanmaaaaa..."
]

class NaiSaykarBot(JabberBot):

    def bot_trans(self, msg, args):
       """Translate the phrase/sentence from the source language to the required language
          ex: trans en pl Apples grow in trees
          would translate the above phrase from english to polish
       """
       split = args.split()
       if len(split) == 0:
            return
       src_language = split[0].strip()
       required_language = split[1].strip()
       phrase = ' '.join(split[2:])
       try:
            translated = gtrans.translate(src_language, required_language, phrase)
            return translated
       except gtrans.InvalidLanguage, e:
            print "Invalid args : %s" %(args)
            # Return a random error message
            return random.choic e(error_dialogues)

    # Overridden from JabberBot
    def unknown_command( self, mess, cmd, args):
        print "Unknown Command %s" %(args)
        return random.choice(error_dialogues)

if __name__ == '__main__':
     bot = NaiSaykarBot(username, password)
     bot.serve_forever()

Oh yeah!. With the power of DBus and libpurple APIs it is possible to give your boss the illusion of managing you. Just run the following script (under WTFPL). Tested with jabber accounts in a live office environment :P.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python
# By Sudharshan S, released under WTFPL

import dbus
import gobject
import time

class PointyHairedBoss:

   def __init__(self, boss_id, source, frequency=30):
        self.boss_id = boss_id
        self.source = source
        self.frequency = frequency
        bus = dbus.SessionBus()
        _pidgin_proxy = bus.get_object("im.pidgin.purple.PurpleService", \
                                                       "/im/pidgin/purple/PurpleObject")
        self.purple = dbus.Interface (_pidgin_proxy, "im.pidgin.purple.PurpleService")
        # FIXME:
        account_id = self.purple.PurpleAccountsGetAllActive()[0]
        self.boss_conversation = self.purple.PurpleConversationNew(1, account_id, self.boss_id)
        self.boss_im = self.purple.PurpleConvIm(self.boss_conversation)
        print self.boss_im

    def start_nonsense(self):
        question_list = open(self.source)
        for q in question_list:
            self.purple.PurpleConvImSend(self.boss_im, q)
            time.sleep(self.frequency)

if __name__ == "__main__":
   # Change the jabber id and the path to your questions, with an optional frequency
   o = PointyHairedBoss("foo@gmail.com", "questions")
   o.start_nonsense()
Comments

When it comes to fitness, I am one of those nerdy couch potatoes with a rather rotund tummy. Burning away calories has become an important priority now and boy, do I miss those Lays and the local Iyengar Bakery Bun Butter Jam and Puffs. For the last week, I have been waking up early and jogging for 30-40 minutes (I also got a good pair of running shoes). Should increase the workout time as weeks progress.

Oh, I also got a new job :D….

Comments

Ever had that feeling of insignificance? The feeling that your very existence is a microscopic peanut in the grand scheme of things. By grand, I mean the Whole Sort of General Mish Mash. I am going through that right now. We are, according to our own theories an extremely smart species, yet for every answer we discover, 10 more questions creep up like one of those annoying LOLCATS shouting ‘OH HAI’. What the hell is the purpose of life? Why do we exist? What is our place in this infinite Cosmos (See the embedded video)? Its incredibly creepy even to think that our entire life is just a mega-complex probability equation, which most likely is too complex for our puny brains to comprehend.

Yeah, so basically what I am coming at is simple. Party now, Life is too short to be spent over unnecessary complications. Or in other words Frigging Use Python!!!!

Brainfuck is one of those turing complete languages that has no apparent use in the real world. But hey, being very very simple with a limited grammar, writing an interpreter should be easy. So here it is, under WTFPL. The code works (I hope so) with the examples from the Wikipedia article.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <stdio.h>
#include <error.h>

#include <config.h>

static char cellspace[30000];
static char *data_pointer;

int process_command(char command, FILE *file_ptr)
{
  char c;
  long pos;

  switch(command) {
  case '>':
      ++data_pointer;
      break;
  case '<':
      --data_pointer;
      break;
  case '+':
      ++*data_pointer;
      break;
  case '-':
      --*data_pointer;
      break;
  case '.':
      putchar(*data_pointer);
      break;
  case ',':
      *data_pointer = getchar();
      break;
  case '[':
      pos = ftell (file_ptr);
      while(*data_pointer != NULL) {
          fseek (file_ptr, pos, SEEK_SET);
          c = getc(file_ptr);
          while( c!= ']' && c != EOF) {
              process_command(c, file_ptr);
              c = getc(file_ptr);
          }

      }

  }

}

int interpret_source(const char *source) {

  /*
  *  Allowed brainfuck commands are,
  *  >    increment the data pointer (to point to the next cell to the right).
  *  <    decrement the data pointer (to point to the next cell to the left).
  *  +   increment (increase by one) the byte at the data pointer.
  *  -   decrement (decrease by one) the byte at the data pointer.
  *  .   output the value of the byte at the data pointer.
  *  ,   accept one byte of input, storing its value in the byte at the data pointer.
  *  [   if the byte at the data pointer is zero,
  *      then instead of moving the instruction pointer forward to the next command,
  *      jump it forward to the command after the matching ] command.
  *  ]   if the byte at the data pointer is nonzero,
  *      then instead of moving the instruction pointer forward to the next command,
         *      jump it back to the command after the matching [ command.
  */

  char command;
  FILE *file_ptr = fopen(source, "r");

  if (!file_ptr) {
      fprintf(stderr, "Error: No such file %s\n", source);
      return FALSE;
  }

  while((command = getc(file_ptr)) != EOF)
      process_command(command, file_ptr);
  fclose(file_ptr);
  return TRUE;
}

int main(int argc, char **argv)
{
  /* Init data_pointer to the left most cell */
  data_pointer = &cellspace[0];

  /* Use getopts? */
  if (argc > 1)
      interpret_source(argv[1]);
  return 0;
}

2-3 back came a sad and shocking news (atleast to me) that Openmoko has sacked/let go of 50% of its work force and has ceased all developments for GTA03. Furthermore Openmoko has stopped funding FSO. Both of which were grim developments to hear.

On a brighter note, FSO has started work on the Vala/C implemention of the reference Python implementation named cornucopia, which mainly aims at the general defragmentation of all the middleware code out there for handheld devices. Whats more, the first subsystem to be ported to this new codebase will be odeviced, which happened to be my project for the Google Summer of Code 2008.

For more, check this recent blog entry by Mickey.

Patches all the way :D…

Comments

I know I am pretty late but finally I got myself a new Yamaha FZ. A nice revvy pickup and wide tyres is making me go ‘whee’ over long sweeping curves.

Drinks about a litre every 40-45 kilometres

Pics soon :)

Comments

About 10 minutes ago, my brain switched from neutral to first gear and started pondering about ways to teach someone how to program (Not that I am particularly good at programming in the first place :D).

For example, how would you explain the concept of variables, references, names. etc, which seemingly form the corner stone of programming language syntax. Sometimes this can make you struggle a bit when you are switching languages.

Consider the following,

1
2
3
4
5
6
>>> a = 10
>>> b = a
>>> id(a)
37688272
>>> id(b)
37688272

One teency weency thing I learnt the hardway was the fact that when the interpreter evaluates ‘a = 10’, it creates a “box”, slaps the label ‘a’ on it and puts the integer 10 in it. Consequently, something like swapping of two numbers becomes as easy as,

1
a, b = b, a

This is actually emphasised on most, if not all Python tutorials I have come across. This didn’t sound all that important when I learnt Python for the first time.

Then I found C to be doing things differently (Am I even right?), Take this for example,

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main(int argc, char **argv) {
  int x = 5;

  /* This however creates a new "box"
           containing the value 5 and a name y */
  int y = x;

          printf("Value of x = %d, Address of x is %x\n" \
         "Value of x = %d, Address of y is %x\n", x, &x, y, &y);
  return 0;
}

Gives the following output, where x and y are named on different boxes and yet have the same values.

1
2
Value of x = 5, Address of x is 98e6cecc
Value of x = 5, Address of y is 98e6cec8

Hmm, This is where I hit it. Suddenly realisation dawned. Sun shone again. Birds twittered. The darkness was gone. I suddenly found myself telling “Its called the pointers.. stupid!”

Now, to mirror the the Python “box” analogy (not exactly) well, a in a language like C, we have to our disposal the good old pointers.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main(int argc, char **argv) {
  int x = 5;

        /* Pointer to the "box" that is name 'x'. */
  int *y = NULL;
  y = &x;
          printf("Value of x = %d, Address of x is %x\n" \
         "Value of y = %d, Address of y is %x\n", x, &x, *y, y);
  return 0;
}

This would give me, Value of x = 5, Address of x is c07ec844 Value of y = 5, Address of y is c07ec844

where ‘*’ and ‘&’ are the de-reference (value-of) and reference (value-at) operators.

So folks, Is it right to think along the lines of “a box at c07ec844 is labelled ‘x’ with the integer value 5” when I see something as mundane as “int x = 5” . It did help me to understand pointers better, but are there any better analogies when speaking about variables, references etc. than say, picturing a row of shelves with lots of boxes, each of which can have multiple sticky notes with names at a given point of time.