<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-15759408</id><updated>2009-04-22T11:29:19.101-07:00</updated><title type='text'>Always learning</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15759408.post-2777963540321114300</id><published>2009-04-21T14:55:00.000-07:00</published><updated>2009-04-21T15:10:02.528-07:00</updated><title type='text'>Ubuntu adventures - django install a breeze!</title><content type='html'>Installed &lt;a href="http://djangoproject.com"&gt;django&lt;/a&gt; on ubuntu today. Do not make the mistake of installing django from the synaptic package manager. Firstly, its an older version than the current 1.0.2 and secondly, it does not install it in your python "site-packages" folder.&lt;br /&gt;&lt;br /&gt;The best way to do it is as they say on the &lt;a href="http://docs.djangoproject.com/en/dev/topics/install/#installing-official-release"&gt;django site&lt;/a&gt;. Download the tar file and install using python setup.py install. The cool thing about this is is that I found that the symlinks were also created for you. I could access django-admin.py from any directory in my machine.&lt;br /&gt;&lt;br /&gt;I also installed &lt;a href="http://www.postgresql.org/"&gt;postgreSQL&lt;/a&gt; and psycopg2 (the python interface for postgres) from the synaptic package manager and I was good to go with django in a matter of minutes! For now I am developing with the webserver bundled inside django but I hope to be switching to apache with mod_wsgi soon.&lt;br /&gt;&lt;br /&gt;I hope to be tinkering a lot with django over the next few weeks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-2777963540321114300?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/2777963540321114300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=2777963540321114300' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/2777963540321114300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/2777963540321114300'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2009/04/ubuntu-adventures-django-install-breeze.html' title='Ubuntu adventures - django install a breeze!'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-9049373076870052966</id><published>2009-04-21T14:39:00.000-07:00</published><updated>2009-04-22T11:29:19.111-07:00</updated><title type='text'>Perl power! Sorting dictionaries (or hashes in Perl lingo)</title><content type='html'>Theres a dictionary dict1 with keys key1, key2, etc such that $dict1{keyn} has a value which itself is a dictionary. Lets call this dictionary %subdict. Now subdict has different keys subkey1, subkey2 and so on such that $subdict{subkey5} = subvalue5.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;Problem: How do I sort dict1 such that the keys are in the ascending order of subvalue5?&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This would not be easy to do in a single line of code, unless of course the language is Perl! Ready? here it is:&lt;br /&gt;&lt;br /&gt;dict1_keys_sorted = sort {$dict1{$a}{subkey5} cmp $dict1{$b}{subkey5}} keys %dict1&lt;br /&gt;&lt;br /&gt;Lets take this apart. Going from the right side, you start of with dict1. Now, keys %dict1 returns a list of the keys. With the sort command being invoked, Perl feeds the first two values of the keys into $a and $b. So, $dict1{$a}{subkey5} gives the value of subvalue5 for that key value of dict1. The values are compared and depending on true or false value, it puts the value into the new list dict1_keys_sorted which is sorted.&lt;br /&gt;&lt;br /&gt;Note: "cmp" is for sorting strings. To sort number use "&lt;=&gt;".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-9049373076870052966?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/9049373076870052966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=9049373076870052966' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/9049373076870052966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/9049373076870052966'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2009/04/perl-power-sorting-dictionaries.html' title='Perl power! Sorting dictionaries (or hashes in Perl lingo)'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-8555503636751949755</id><published>2008-05-13T09:03:00.000-07:00</published><updated>2008-05-13T09:09:58.193-07:00</updated><title type='text'>Ubuntu journey II - Printing and scanning</title><content type='html'>Printing and scanning in Ubuntu proved to be much easier than expected. Ubuntu easily recognized the HP Photosmart C3500 series that I had, and right away I was able to print documents off the text editor. The Scanning application (XSANE) was a breeze to operate and I was able to scan documents to various formats.&lt;br /&gt;&lt;br /&gt;However, my favorite lightweight editor on windows was SciTe, so I installed it in ubuntu also, and tried to print from it. Turns out SciTe uses the "a2ps" program to print, and it was not able to direct the output to the printer. A bit of googling told me that replacing a2ps with "enscript" would be able to do it. So I replaced the print options in SciTeGlobal.properties file, but now I get an error that its not able to find the printer class. Guess I will have to look into this more.&lt;br /&gt;&lt;br /&gt;But besides that, the printing and scanning functionality works like a charm in Ubuntu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-8555503636751949755?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/8555503636751949755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=8555503636751949755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/8555503636751949755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/8555503636751949755'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2008/05/ubuntu-journey-ii-printing-and-scanning.html' title='Ubuntu journey II - Printing and scanning'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-1707130701287537</id><published>2008-05-12T09:35:00.000-07:00</published><updated>2008-05-12T09:45:10.292-07:00</updated><title type='text'>Ubuntu journey - Hardy Heron</title><content type='html'>I just upgraded my ubuntu distro to Hardy Heron (8.0.4) from Gutsy Gibbon (7.10). I did not use it a lot when I had Gutsy but now, hearing about how much better the distros are getting everytime theres an upgrade, I am setting out to explore it more. The major  difference I noticed in Hardy was that I am able to make ubuntu work on dual monitors directly without running additional scripts. In Gutsy, I actually had to run an XRANDR command everytime I logged in, so that I could switch it from clone mode to dual monitor mode. Not anymore in Hardy.&lt;br /&gt;&lt;br /&gt;Further things I will be exploring on Ubuntu in the coming days:&lt;br /&gt;- Printing and Scanning&lt;br /&gt;- IPOD and music play&lt;br /&gt;- Python, Django&lt;br /&gt;- Java Development with Eclipse&lt;br /&gt;- Ant, CVS, Tomcat&lt;br /&gt;- MySQL&lt;br /&gt;&lt;br /&gt;If I find that the above are easily setup and software development in that environment is as easy as windows, theres no reason why I should not completely switch to Ubuntu.&lt;br /&gt;&lt;br /&gt;Oh I will have to go back to windows frequently though, since Cricket games for PC do not run on Linux yet!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-1707130701287537?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/1707130701287537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=1707130701287537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/1707130701287537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/1707130701287537'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2008/05/ubuntu-journey-hardy-heron.html' title='Ubuntu journey - Hardy Heron'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-5940975162103507867</id><published>2007-11-28T14:06:00.000-08:00</published><updated>2007-11-28T14:08:08.087-08:00</updated><title type='text'>Thoughts on Agile techniques - I</title><content type='html'>Over the past few years, I have observed the agile movement and I feel that I have to put down some of my thoughts regarding this. The main reason for me writing it is to clarify my thoughts, and also, but not necessarily, to invite some feedback.&lt;br /&gt;I cannot dispute the fact that in the process of evangelizing it, the people have talked about some software practices that contribute to making better software. But somehow I feel that the useful practices are all those that have to be part of writing software in general, rather than being attributed to a process.&lt;br /&gt;Its my belief that there are mostly only two qualities that a developer has to have in order to deliver successful software. This is of course only in context on enterprise software development where the developer in employed to create and maintain internal software systems within the company. The two qualities are: one - not being afraid to go in and change code and two - constant communication of the status of his work.&lt;br /&gt;The second one is an auxillary capability, since it solely exists to put people mind's at rest, so that they don't bother him/her while he's actually trying to solve a problem. I would think its an equally necessary quality to possess as the primary one because when it comes to deploying a fix or a system, its never only about the code. There's always a dynamic between the current users that have to look for a workaround or need to be informed about systems that will be down, etc. &lt;br /&gt;In such an environment, if the developer possesses the confidence of being able to tackle changing the codebase or developing something new with the confidence that it can always be changed later, there's not many more practices that he needs to religiously follow to deliver working software.&lt;br /&gt;&lt;br /&gt;This confidence comes from constantly learning from a good amount of experience as well as possessing a couple of tools that come in handy. I will delve on this aspect more in the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-5940975162103507867?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/5940975162103507867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=5940975162103507867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/5940975162103507867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/5940975162103507867'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2007/11/thoughts-on-agile-techniques-i.html' title='Thoughts on Agile techniques - I'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-6971825053205048684</id><published>2007-03-06T13:14:00.000-08:00</published><updated>2007-03-08T10:51:47.370-08:00</updated><title type='text'>The beauty of Python Generators</title><content type='html'>Say you had to read a file line by line and change the delimiter from comma to semi-colon. The python code would look like this: &lt;br /&gt;&lt;pre&gt;f = open("c:\\testfile.txt") &lt;br /&gt;for line in f.readlines(): &lt;br /&gt;    ';'.join(line.split(','))&lt;/pre&gt; Now say you wanted to do the same thing, but only to the first 5 lines of the file. The impulse for a Python newbie would be to write the following code: &lt;br /&gt;&lt;pre&gt;f = open("c:\\testfile.txt") &lt;br /&gt;counter = 0 &lt;br /&gt;for line in f.readlines(): &lt;br /&gt;  if counter &lt;&gt; 5 &lt;br /&gt;    ';'.join(line.split(',')) &lt;br /&gt;    counter += 1 &lt;/pre&gt;A more savvy python newbie would write the following code taking the advantage of the beautiful enumerate() function: &lt;br /&gt;&lt;pre&gt;f = open("c:\\testfile.txt") &lt;br /&gt;for counter,line in enumerate(f.readlines()): &lt;br /&gt;  if counter &lt;&gt; 5 &lt;br /&gt;    ';'.join(line.split(',')) &lt;/pre&gt;The problem with is code is that it has two concepts intermingled, one to read 5 lines and the other for the actual process of changing delimiters. If we wanted to keep the concepts separate, we would have to be able to write something like this: &lt;br /&gt;&lt;pre&gt;f = open("c:\\testfile.txt") &lt;br /&gt;for line in f.readfirst5lines(): &lt;br /&gt;  ';'.join(line.split(',')) &lt;/pre&gt;Here the process of stopping after 5 lines is encapsulated by the readfirst5lines() method in the file object and the method body only does the changing of delimiters as before. Now this code will actually work! The reason that we can write code like this is due the python generators feature. readfirst5lines will look like this: &lt;br /&gt;&lt;pre&gt;import itertools &lt;br /&gt;class myfile(file): &lt;br /&gt;  def readfirst5lines(self): &lt;br /&gt;    for i in itertools.count(): &lt;br /&gt;      if i == 5: &lt;br /&gt;        break &lt;br /&gt;      next = self.readline() &lt;br /&gt;      i += 1 &lt;br /&gt;      yield next &lt;/pre&gt;This is of course more lines of code, but the concept is abstracted away nicely. We are separating the conditions for processing the file from the actual processing. And whats more, this method can be slightly changed to take number of lines as the argument. So if you want choose to read the first 2, 3, 5 or how many ever lines, the method will look like this: &lt;br /&gt;&lt;pre&gt;import itertools &lt;br /&gt;class myfile(file): &lt;br /&gt;  def readfirstfewlines(self, n): &lt;br /&gt;    for i in itertools.count(): &lt;br /&gt;      if i == n: &lt;br /&gt;        break &lt;br /&gt;      next = self.readline() &lt;br /&gt;      i += 1 &lt;br /&gt;      yield next &lt;/pre&gt;And you can use it like this: &lt;br /&gt;&lt;pre&gt;f = myfile("c:\\testfile.txt") &lt;br /&gt;for line in f.readfirstfewlines(3): &lt;br /&gt;  ';'.join(line.split(',')) &lt;/pre&gt;This will process the first 3 lines. &lt;br /&gt;&lt;br /&gt;(Note that we used the 'myfile' constructor method instead of the 'open' function to open the file, since we need an object of type 'myfile' and not 'file'. There are other ways to downcast in python but this is probably the simplest way to do it in this case.)&lt;br /&gt;&lt;br /&gt;Python generators go a long way in making the code more elegant and encapsulating separate concepts. I will blog about the mechanics of how generators work and its other uses as and when I learn more about them. For Rubyists, this concept of generators is pretty much similar to "blocks".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-6971825053205048684?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/6971825053205048684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=6971825053205048684' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/6971825053205048684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/6971825053205048684'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2007/03/say-you-had-to-read-file-line-by-line.html' title='The beauty of Python Generators'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-115168617541226938</id><published>2006-06-30T09:36:00.000-07:00</published><updated>2006-06-30T10:59:33.790-07:00</updated><title type='text'>[Rails] How to work with non-autogenerated primary keys</title><content type='html'>Oddly enough, I have not found a clear explanation of how to make ActiveRecord work with a table that has a non-autogenerated primary key. In other words, the table has a column as a primary key for which the value has to be inserted manually. (Of course this is not good practice but what other better reason to do this than to say such a table already exists and needed a user interface for maintaining its values!)&lt;br /&gt;So how do we go about doing this? Simple. First, set the primary key in the Model object to be the column in the table (since ActiveRecord always assumes primary key is a column called "id"). If we just run this and try to save the model object by firing up the rails console, rails gives an error saying there are no attributes "col1". This is because, rails assumes that the primary key is not editable. So all we have to do is define attributes for the primary key column col1. The overall changes are shown below:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;class MyModel &lt; ActiveRecord::Base&lt;br /&gt;&lt;blockquote&gt;set_primary_key "col1"&lt;br /&gt;def col1&lt;br /&gt;read_attribute "col1"&lt;br /&gt;end&lt;br /&gt;def col1=(value)&lt;br /&gt;write_attribute "col1", value&lt;br /&gt;end&lt;/blockquote&gt;end&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Now fire up the rails console and create and save the model object, setting values for the required columns. Voila!&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Note: since you are departing a bit from rails convention of primary keys, you will need to make sure that the required validations are added in the model so that you dont get errors from the database.&lt;/em&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-115168617541226938?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/115168617541226938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=115168617541226938' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/115168617541226938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/115168617541226938'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2006/06/rails-how-to-work-with-non.html' title='[Rails] How to work with non-autogenerated primary keys'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-114909711759224121</id><published>2006-05-31T10:06:00.000-07:00</published><updated>2006-05-31T10:38:37.656-07:00</updated><title type='text'>Data comparison? Python file comparison to the rescue!</title><content type='html'>I had to update some data in a production database for a new functionality. I had already done that in the test database during development, but it was not just a simple insert. The steps that I did went something like this:&lt;br /&gt;&lt;br /&gt;1. Generate a file with a set of insert statements (used Python for this!).&lt;br /&gt;2. Manually change some data in the insert statements.&lt;br /&gt;3. Run the insert statements&lt;br /&gt;&lt;br /&gt;Now since I had to do the same in production, I wanted to make sure that after this insert, the data would look exactly the same as it did now in test. In other words, I wanted to be able to repeatedly run the process above, and make sure that the steps produced always the same set of data. This would guard against any mistakes being done during step 2, which is a manual edit of a file and prone to error.&lt;br /&gt;Sounds simple - I could generate the file of insert statements, and then compare it against the file that was already changed and used to load the data in the table. Problem is, I no longer had that file I could compare against. So instead of comparing insert statements, I would have to compare data. The process I did went something like this:&lt;br /&gt;&lt;br /&gt;1. Export current data in the table to a file, say file1.txt&lt;br /&gt;2. Delete the inserted rows from the table.&lt;br /&gt;3. Generate insert statements again, manually edit, and insert rows into the table.&lt;br /&gt;4. Export data in the table to a file, say file2.txt&lt;br /&gt;&lt;br /&gt;Now all I had to do, was compare file1.txt and file2.txt. If they are equivalent, it means my manual edits were on target.&lt;br /&gt;&lt;br /&gt;So how did I compare the two files? Python to the rescue! This is all it took:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;import filecmp&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;filecmp.cmp('file1.txt', 'file2.txt')&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If they are equal it returns true, else false.&lt;br /&gt;&lt;br /&gt;I have to admit that that the only reason I thought about comparing data rather than the insert statements was because I was sure Python would have something neat for file comparison. The database-oriented guys might have fired up some magic by using stored procedures and temporary tables, and it would have been equally satisfying to them.&lt;br /&gt;&lt;br /&gt;Its all a matter of what you are comfortable with, I guess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-114909711759224121?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/114909711759224121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=114909711759224121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114909711759224121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114909711759224121'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2006/05/data-comparison-python-file-comparison.html' title='Data comparison? Python file comparison to the rescue!'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-114901295981831432</id><published>2006-05-30T10:44:00.000-07:00</published><updated>2006-05-30T11:15:59.856-07:00</updated><title type='text'>Churning out Rails dishes - I</title><content type='html'>What I learnt from Rails Recipes today:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;You can run tests in rails without connecting to the database&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;test_help.rb&lt;/em&gt; is reponsible for the database connection code, so remove reference of &lt;em&gt;test_help.rb&lt;/em&gt; from &lt;em&gt;test_helper.rb&lt;/em&gt; put in the code yourself. Remove the lines that access &lt;em&gt;Activerecord&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;You can connect to multiple databases&lt;/strong&gt;&lt;br /&gt;All model classes inherit &lt;em&gt;ActiveRecord::Base's&lt;/em&gt; connection.  So create a parent model class that inherits from &lt;em&gt;ActiveRecord::Base&lt;/em&gt; and override the &lt;em&gt;establish_connection&lt;/em&gt; method to access the other database. All models inherited from this model class will connect to the new database. Make sure not to instantiate the parent model class since theres no corresponding table.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Integrate with legacy databases&lt;/strong&gt;&lt;br /&gt;Use attributes and methods like &lt;em&gt;ActiveRecord::Base.table_name_prefix, ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore, ActiveRecord::Base.set_primary_key, ActiveRecord::Base.pluralize_table_names&lt;/em&gt; to tailor your model class according to the table specifications.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Avoid code repetition(use DRY) in your database configuration YAML files&lt;/strong&gt;&lt;br /&gt;You can define a section and give it a key. Using that key in various places in your yaml file will substitute the values from that section in those places.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-114901295981831432?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/114901295981831432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=114901295981831432' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114901295981831432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114901295981831432'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2006/05/churning-out-rails-dishes-i.html' title='Churning out Rails dishes - I'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-114865813973726433</id><published>2006-05-26T08:32:00.000-07:00</published><updated>2006-05-26T08:42:19.753-07:00</updated><title type='text'>Preparing for RailsConf</title><content type='html'>When you go to a conference, its always a better experience if you are somewhat knowledgeable about the topics. :) Otherwise the only benefit would be the t-shirts and coffee mugs! And even though the price of RailsConf is a steal judging by the speakers and the topic itself, its quite a bit for just conference paraphernalia!&lt;br /&gt;So starting today(yesterday actually), I am going to be reading up on &lt;a href="http://www.pragmaticprogrammer.com/titles/fr_rr/index.html"&gt;Rails Recipes&lt;/a&gt;, a wonderful book by &lt;a href="http://chadfowler.com"&gt;ChadFowler&lt;/a&gt; et al, that details tips and tricks that you an do with Rails. The plan is to read or work through 3 or 4 rails recipes a day. Hopefully this will get me into "Rails mode" and I will be able to avoid a blank, stunned stare when the magicians whip up their rails magic!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-114865813973726433?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/114865813973726433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=114865813973726433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114865813973726433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114865813973726433'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2006/05/preparing-for-railsconf.html' title='Preparing for RailsConf'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-114865675902609047</id><published>2006-05-26T08:00:00.000-07:00</published><updated>2006-05-26T08:19:19.053-07:00</updated><title type='text'>Onward to Railsconf 2006</title><content type='html'>This is the first conference I am attending in quite a while. Last one was XML Devcon 2000! It was good, but not as enriching as I hoped it would be. I suspect that maybe because of 2 factors: one, the general concept of XML was not very appealing to me, ie, while developing, consuming or writing out xml, it does not give me a rush. Second, my understanding of software concepts was clouded too much by what was happening in the world, without me having my own perspective. As folks dished out their own takes and the "one right way" to do stuff, I lapped it all up, not thinking much for myself.&lt;br /&gt;Six years later, I dont how much has changed on my side, but I do like where I am now. I do have perspectives on what "superior" languages or frameworks are, and I do feel a certain rush when I understand or implement concepts. At the same time, having these perspectives has also oddly left me with more tolerance for accepting other concepts or approaches that were previously frowned upon by the "best practice" advocates. So with this bent of mind, I am eager to see how my experience will be at the conference.&lt;br /&gt;Besides the fact that the conference is about a subject that I love developing with,  it also boasts speakers that I have always wanted to hear - like &lt;a href="http://martinfowler.com"&gt;Martin Fowler&lt;/a&gt; and &lt;a href="http://paulgraham.com"&gt;Paul Graham&lt;/a&gt;. In the beginning of the year, while announcing the keynote speakers for the conference, &lt;a href="http://chadfowler.com"&gt;Chad Fowler&lt;/a&gt; said "If you can only make it to one conference this year, let RailsConf be the one".&lt;br /&gt;&lt;br /&gt;I am happy I listened.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-114865675902609047?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/114865675902609047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=114865675902609047' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114865675902609047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/114865675902609047'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2006/05/onward-to-railsconf-2006.html' title='Onward to Railsconf 2006'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-113269579931230967</id><published>2005-11-22T13:43:00.000-08:00</published><updated>2005-11-22T13:43:19.333-08:00</updated><title type='text'>Debugging python with IDLE</title><content type='html'>If you are playing with Python and eager to get the feel of this wonderful language, you might be already using the interpreter and the in-built GUI "IDLE". I have been using the interpreter to explore the language's various commands and features and its been very easy to use. However, I tried to use the debugging feature of the IDLE tool a few days ago and struggled with it. To me it seemed like someone who has a background of using debuggers in PowerBuilder, Eclipse etc, would find it rather hard to grasp. So if you think you dont know your way around the IDLE bugger, here are the steps. Once you follow these, it will actually be quite easy to debug your favorite Python script. The hard part is getting used to it, but I am sure we can suffer through a little discomfort - just for the sake of Python!&lt;br /&gt;&lt;br /&gt;1. Start up IDLE and as soon as the shell launches, click on 'Debug' menu and then 'Debugger'. This will open up the Debug popup. Do not close this throughout the session.&lt;br /&gt;2. Make sure to check all 4 checkboxes, including 'Source' and 'Globals' (Why this is necessary is explained further below)&lt;br /&gt;3. Open up the file you want to debug using 'File/Open'.&lt;br /&gt;4. Right-click on the line you want to set a breakpoint on and click 'Set Breakpoint'.&lt;br /&gt;5. On the menu of the window on which you have opened the file, click 'Run' and then 'Run module'.&lt;br /&gt;&lt;br /&gt;This should start the debug process.&lt;br /&gt;&lt;br /&gt;This debug feature also debugs any code you enter through the interpreter! So if you start the debugger as outlined above in steps 1 and 2, and then type commands on the interpreter, it will open up the relevant file and walk you through the source. Cool huh??&lt;br /&gt;&lt;br /&gt;A couple of glitches: If you dont check the 'Source' checkbox on the debug popup, you will not be able to see the interpreter going through each line of the code. Also, even if you check the 'Source' checkbox, you will be able to see the lines being highlighted only if you take the focus away from the debug popup and set the focus on the window with the source file (say by clicking on the titlebar of the window)&lt;br /&gt;&lt;br /&gt;Other than that, the IDLE debugger is very handy in giving you a picture of how the code progresses. As any good developer would say, debugging should NOT be the only way to explore a program but its a good thing to switch back to sometimes!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-113269579931230967?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/113269579931230967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=113269579931230967' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/113269579931230967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/113269579931230967'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2005/11/debugging-python-with-idle.html' title='Debugging python with IDLE'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-113209154879187419</id><published>2005-11-15T13:52:00.000-08:00</published><updated>2005-11-15T13:52:28.823-08:00</updated><title type='text'>What makes a good IT manager?</title><content type='html'>Sometime back while commenting on a blog entry by &lt;a href="http://ravimohan.blogspot.com/"&gt;Ravi&lt;/a&gt;, I managed to elucidate what my idea was of a good IT manager.&lt;br /&gt;&lt;br /&gt;1. Someone who makes every team member comfortable in his presence. This is actually very difficult to achieve and has to be done only by letting one's guard down, admitting there are areas which the manager doesn't himself understand, and is very eager to go a developer for help.&lt;br /&gt;2. If the developer is having a technical problem the manager says "hmm cmon lets see how this will work" and actually sits down, pairs with him to do a tracer bullet - a small proof of concept. &lt;br /&gt;3. The manager should show by his actions that he is concerned by the well-being of the team. This means hes genuinely interested in the developers career growth and to some extent personal issues.&lt;br /&gt;4. Last but most important, he sits with the team and all the team members sit together. I am a very strong proponent of this and really cringe when I see people isolated in cubes.&lt;br /&gt;&lt;br /&gt;This might be in conflict with some people that think managing is removed from the technical aspect of what the manager manages, but I believe that the opinion is flawed. In short, if the manager has not had adequate technical history, he will always be found wanting regardless of how good he is at dealing with people. This of course assumes that the role of the manager is to make sure that the product or service developed by the "workers" is delivered on time to the customers and reasonably within budget.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-113209154879187419?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/113209154879187419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=113209154879187419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/113209154879187419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/113209154879187419'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2005/11/what-makes-good-it-manager.html' title='What makes a good IT manager?'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-112835381260333808</id><published>2005-10-03T08:36:00.000-07:00</published><updated>2005-10-03T08:36:52.646-07:00</updated><title type='text'>Convention over configuration...but of course!</title><content type='html'>I have been reading and working out examples in the book &lt;a href="http://www.pragmaticprogrammer.com/titles/rails/index.html"&gt;Agile Web Development with Rails&lt;/a&gt;, written by &lt;a href="http://blogs.pragprog.com/cgi-bin/pragdave.cgi"&gt;Dave Thomas&lt;/a&gt; and &lt;a href="http://www.loudthinking.com"&gt;David Heinemeier Hansson&lt;/a&gt;. I discovered rails about 6 months ago and started reading about it. I was fascinated by the simplicity and the ease of development that it offered in quickly putting together a fully functional web application. Needless to say, in just over a year after its creation, it has captured the hearts and minds of programmers and web designers alike.&lt;br /&gt;&lt;br /&gt;There are many facets to rails that make it worthy of being the one of the foremost choices in developing web applications, like clear separation of model view controller functionality and in-built testing support - besides the inherent advantage of having a dynamic language like Ruby at its core. However, there is one more rarely-exploited paradigm that it uses that really struck a chord with me - the fact that it stresses "convention over configuration". Rails does not have XML files for specifying the configuration aspects of the application. It assumes certain values and uses those to power the rest of the application. &lt;br /&gt;&lt;br /&gt;What does this exactly mean? It means that configuration information is already predetermined by rails and it urges the programmer to name objects a certain way and put files and resources in specific predetermined directories. One would think that this is very restrictive, but the fact is that it doesnt seem restrictive at all when most of it is done by the framework itself! It creates the directories, creates the templates for the files, so that what falls on the shoulders of the programmer is the actual business logic. It is like it says, "Dont worry about maintaining configuration info, I will lay it out and make sure its all in place. You just worry about implementing the requirements in code."&lt;br /&gt;Imagine what this means in terms of application maintenance. A new programmer entrusted with making changes to a rails application coded by another developer already knows where everything is, and how the basic components are named. No flailing around trying to make sense of variable and object names!&lt;br /&gt;&lt;br /&gt;It definitely is worthwhile trying out and working on a framework that works on the "convention over configuration" principle. This may not be for all, but is perfect for a framework if it has to be true to its promise of blazing speed in putting together a working application. And Rails does a great job there, no question.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-112835381260333808?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/112835381260333808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=112835381260333808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/112835381260333808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/112835381260333808'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2005/10/convention-over-configurationbut-of.html' title='Convention over configuration...but of course!'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-112664606293870775</id><published>2005-09-13T14:14:00.000-07:00</published><updated>2005-09-13T14:14:22.976-07:00</updated><title type='text'>The Craft of Classification</title><content type='html'>Ravi mohan writes another &lt;a href="http://ravimohan.blogspot.com/2005/09/nostalgia-for-guilds-and-other.html"&gt;thought-provoking post&lt;/a&gt; on this blog in response to the notion of classifying  programmers into 3 categories - apprentice, journeyman and master.&lt;br /&gt;&lt;br /&gt;I have to admit I was a bit swayed by &lt;a href="http://www.amazon.com/gp/product/customer-reviews/0201733862/002-8244689-5536006"&gt;Pete mcBreen's book&lt;/a&gt; when I first read it - mainly because I had read about that idea for the first time. But then Ravi is onto something when he shows how that classification may have no real value. The book talks about a situation where it says its okay for a "master" to learn a new language from an "apprentice" and that this doesnt invalidate him of his current category of "master". How is this possible? A student is always supposed to see himself as lower in that relative situation when he learns something from a teacher.&lt;br /&gt;When Pete McBreen and others advocate this idea, I suspect they have an underlying assumption about the quality of the learning. Maybe they are saying that the master already has the fundamental concepts down(which is a higher quality of learning) and he just learns another language syntax which is of a lower quality of learning. But will this always be the case?&lt;br /&gt;Imagine a UNIX guru in the league of Eric Raymond or Richard Stallman. Lets call him Mr X. He has been working on UNIX for years and written dozens of open-source tools, is very active in communities and is usually approached when his UNIX peers have issues. According to McBreen, he would be a master. Lets say he is hired by a shop that does development mostly in UNIX tools but also have a smattering of applications in Scheme. He starts working with a candidate who has a good knowledge of Scheme but is not active in the public domain (as a result of which he is not well-known). Now, I am sure Mr X will definitely not breeze through Scheme, since its not just a new language - it requires a different way of thinking. Now in this situation, there is a lot of "higher" quality learning involved where the "master" learns from the "apprentice". Whos the master here then?&lt;br /&gt;&lt;br /&gt;All my thoughts are based on the following premise:&lt;br /&gt;&lt;b&gt;&lt;i&gt;There are too many varied things in software for them to be grouped into a "general" category that somebody can be said to be good at.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt; If somebody has sound concepts of OO design, he may be quick to pick up Java, C, C++, C#, etc but it may not be easy to pick up Python or Ruby or Smalltalk. That is to say, it will not be easy to think "the Ruby way". And also by the same token, sound programming concepts in even Python or Ruby or any language will not make you a good webdesigner, adept at CSS, HTML or Flash. &lt;br /&gt;&lt;br /&gt;I guess then what can conclude is:&lt;br /&gt;&lt;b&gt;1. The only thing one can categorize a person is with respect to a particular paradigm and/or language&lt;/b&gt; ("OO programming", "Functional programming" is a paradigm - "Java", even ".NET" is a language for purposes of explaining). If he has to work on another area he doesnt know, he is a novice there and there is nothing wrong with that fact. So Mr X is a UNIX "master" but an "apprentice" in Scheme. There is nothing wrong with a classification which relates to a particular technology/paradigm/language/framework.&lt;br /&gt;&lt;b&gt;2. The only way to categorize a person with respect to a technology is by seeing his work.&lt;/b&gt;&lt;br /&gt;There can be no other parameter. No writings, no talks, or drawing on the board. Now, the question is, how do you know if his work is good? Sadly, it cant be judged right away. This can only be decided over a period of time. Say over a course of 2,3,5 years, how many times was it changed? How easy was it to change? Has he constantly delivered running, "not-getting-in-the-way" software to the users?&lt;br /&gt;&lt;br /&gt;After reading McBreens book, I started thinking, "I am an apprentice now..I want to be a journeyman in X years, and then a master in a another Y years." Looks like it wont work. I am now going to say - "I know java and I want to learn Python this year. Next year I will dig into Scheme. And hey, OCAML looks interesting, why not try it after that?" And when I get that job in the Python firm that wants me to maintain some apps in Erlang on the side, I will seek out the "Erlang guy" and become his "apprentice"!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-112664606293870775?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/112664606293870775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=112664606293870775' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/112664606293870775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/112664606293870775'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2005/09/craft-of-classification.html' title='The Craft of Classification'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15759408.post-112491566950497517</id><published>2005-08-24T13:11:00.000-07:00</published><updated>2005-08-24T13:34:29.506-07:00</updated><title type='text'>This may work...</title><content type='html'>I think writing and keeping an online journal does help in quite a few ways. This weblog is to explore, refine, clarify and elucidate ideas in software development - a profession that has helped me earn a living, and by virtue of doing which continuously for a few years, I have developed a deep interest and love for. This interest is the result of a cycle that has been set in motion by a yearning to learn more about it so that one can be better, which in turn infuses in one an enthusiasm to learn more just because they enjoy their achievements attained by learning.&lt;br /&gt;The interesting about this is now I feel that I am in a different plane of existence. Seems like the constant spinning of the cycle has catapulted me into a different mental state, where I feel there is so much more to learn and knowledge seems never-ending. This is different from my previous plane of existence, where I was doing just what was supposed to be done, limiting myself to only knowledge of my specialization.&lt;br /&gt;I must admit that at first, this new mental state left me more insecure, as its like exposing a huge waterfall to a camel thats happy drinking just the small amounts of water available in the desert. But then I realized that it is necessary to see the waterfall so that you can get an idea of how small the desert water sources are. And it is necessary to know that the water sources are small. It is necessary to know that you are ignorant....because only then can you think about achieving mastery.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15759408-112491566950497517?l=programmingnirvana.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnirvana.blogspot.com/feeds/112491566950497517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=15759408&amp;postID=112491566950497517' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/112491566950497517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15759408/posts/default/112491566950497517'/><link rel='alternate' type='text/html' href='http://programmingnirvana.blogspot.com/2005/08/this-may-work.html' title='This may work...'/><author><name>chandrakant</name><uri>http://www.blogger.com/profile/14510468393909662305</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17388509188446331445'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>