Sentimental Minions

The theatricalities of the humble bookmark

Archive for the ‘Social media’ Category

A look at Web 2.0 and its most promising forerunners.

I’ve moved!

Posted by Avadhut on 30 December 2014

To http://avadhutp.github.io/

moving

Advertisements

Posted in Social media | Leave a Comment »

Good bill/cheque design: Reliance Energy

Posted by Avadhut on 30 October 2008

I had never known that bills could look this good. Reliance has really scored a big one this time. It may seem trivial to a lot of people, but phone and electricity bills, at least in India, are in a dire need of some major overhauling. They are stupendously cryptic, and even knowing how much you have to pay and by when is a task requiring substantial digging-through-the-text. It is almost as if these utilities companies are trying to obfuscate our own information from us.

Take for example the MTNL bill, it is divided into numerous sections, lots of details, even the amount to pay is printed in red. And despite the plethora of numbers/sections it contains, most of the information printed does not make any sense to a layman—forget “the bill as a value add.”

The Vodafone bill does come close to being slightly more than useful. The language has a friendly tone, there are helpful visual cues all over the place, and I just love the cute little graphics all over the bill—it makes it seem like Vodafone is saying “Here’s your bill; we hope you like us enough to pay us” as opposed to “Oye! The bill’s here. Pay up.”

I thought that is as far as one could go with a bill. But then, today I saw the Reliance Bill stuck on my refrigerator. And, I think this is the only time I’d say this about a bill, it looked gorgeous. It made me—who usually just prefers to pay bills online—stand up, take notice, and actually blog about it.

It served on so many levels:
1. Told me who the bill is for.
2. What the amount is.
3. Told me what period was the bill for.
4. Gave me additional information about my electricity usage.

And all this without even flipping the first page. I mean, almost all bills take care of #1 and #2. But not in a manner that Reliance does. Take a look:

This is the first page. Flipping it over displays the more detailed conservatively-styled bill.

This is the first page. Flipping it over displays the more detailed conservatively-styled bill.

And #3 is something that most bills confuse me with. With their start periods and end periods and bill cycles. I pay bills on a monthly basis, and therefore I’d like to know which “month” the bill is for, not which “billing cycle.”

And what can I say about #4:

Detailed usage over past months.

Detailed usage over past months.

This is just good ole’ “Ha ha! Don’t act like your are not impressed.” I mean, my past usage as a small bar graph. Who’d have thought about it. This small section alone more helpful than MTNL’s entire bill.

It is all so well laid out, and epitomises the word “quick.” Almost the perfect bill for a city with barely enough time.

If we go ahead and deconstruct the bill, though, several things can be used for developing billing information screens for Web apps:

1. The font: Extremely important in setting the tone of the bill. I’d strongly recommend a san/semi-san serif font.
2. The language: Friendly. Informal yet professional. Helpful and approachable.
3. Layout: Clean. Uncluttered. One of the most important things here, which most designers overlook, is line-spacing.
4. Information: In stead of printing several sections on the same page, design a bill as “layers” that can be “peeled” off. The first layer could present the most basic information regarding the amount, due date, etc. Peeling off the first layer could present an itemized bill, and so on. This will also make your bill extremely interactive.

And lastly, deliver what your service promises even through your bill. Don’t let poor billing hamper an otherwise customer-friendly offering.

Posted in Bill/cheque design, Social media, System design, Visual sick | 1 Comment »

PHP script for the migration of data from Drupal 5.x to 6.x

Posted by Avadhut on 14 September 2008

Ok. Drupal 6 is probably the best thing since bread came sliced. Views 2, the new and improved CCK, and the updater—it’s like updating your anti virus—has made life so much easier. Updating Web application frameworks has never been easier.

This updater alone is incentive enough to upgrade your Drupal 4.x and 5.x installations to Drupal 6.x. Unfortunate it is then that this moat to be crossed is filled with non-upgraded module crocodiles and inexplicable PHP error sharks.

There are two approaches to converting a Drupal 5.x site to 6.x:
1. Upgrading: For this, all contrib. modules installed in your 5.x better be ported to 6.x, and also pray that Watchdog has encountered no life-threatening PHP errors. That periodic cron runs, database updates, & zilch-modification of core modules were a must go without saying.
2. Migration: Setup a crisp, clean Drupal 6.x site, and painstakingly port all data from your 5.x behemoth to your 6.x kiddo. Migration can be performed either manually (pray, lord, pray if your site has more than 500 nodes) or through scripts.

Although approach 1, if it works without spewing any errors, is enough to incite a hallelujah from even the most ardent of the non-believers, we all know how rare it is. And the pre-requisites to it are just too many and too hard to fulfill.

The only solution in cases where an upgrade is not possible, then, is the use of automated migration scripts. Currently, there is no such unified migration script available. I have broken down the script I used to migrate my 5.x site to 6.x for the migration of users, simple-content-type posts, comments, taxonomy, & forum posts. Migrating the theme itself (blocks, nodes, templates, etc.) would require one to get their hands dirty with PHP.

Before we begin, we need our PHP migration script to set certain variables:

< ?php
set_time_limit(0);
//MySQL globals
$mysql_server = "localhost";//change this server for your Drupal installations
$mysql_user = "root";//Ideally, should be root
$mysql_pass = "pass";//Corresponding password
$conn = mysql_connect($mysql_server,$mysql_user,$mysql_pass);//MySQL connection string
//If your 5.x and 6.x installations reside on different servers, you will need two sets of server names, usernames, and passwords.
?>

Also, in my scripts, tables prefixed “drupal.” and “timesnow.” belong to the 5.x and 6.x sites, respectively. Please change these accordingly for your databases.

Lastly, these scripts are not optimized with regard to execution. So do not expect unified inserts to insert multiple tuples.

User migration script:

This script, currently, only migrates users, e-mail addresses, uids, and passwords. It does not take care of the profile fields, which can be handled through other customized scripts as profile fields for each installation can differ. It does not import “usernode” content type either. This is coz’ usernodes are typically not required in 6.x, as user profile pages can be styled using tpl.php files themselves. Also, it is important that the uids from your orignal installtion be migrated to your current installation accurately coz’ comments and nodes that we will migrate later on are linked to the users through these uids.

There are absolutely no differences between the Users table in 5.x and 6.x. Both of them have the same 18 fields. So you can go ahead and use the following script without even thinking:

< ?php
//first, we delete all users, if any, from the new table, except for the admin
$query = "delete from timesnow.users where uid not in (0,1)";
mysql_query($query);
print "User table cleared.
";
//now we start inserting users into the new table
$query = "select * from drupal.users where uid not in (0,1)";
$queryresult = mysql_query($query);
while ($row = mysql_fetch_row($queryresult)) {
	$query = "insert into timesnow.users values('" . $row&#91;0&#93; . "','" . $row&#91;1&#93; . "','" . $row&#91;2&#93; . "','" . $row&#91;3&#93; . "','" . $row&#91;4&#93; . "','" . $row&#91;5&#93; . "','" . $row&#91;6&#93; . "','" . $row&#91;7&#93; . "','" . mysql_real_escape_string($row&#91;8&#93;) . "','" . $row&#91;9&#93; . "','" . $row&#91;10&#93; . "','" . $row&#91;11&#93; . "','" . $row&#91;12&#93; . "','" . $row&#91;13&#93; . "','" . $row&#91;14&#93; . "','" . $row&#91;15&#93; . "','" . $row&#91;16&#93; . "','" . $row&#91;17&#93; . "')";
	if (!mysql_query($query)) {
		print $query;
	}
	$ucnt += 1;
}
print $ucnt . " users inserted.";
?>

An easy one that was, wasn’t it. Now, for some taxonomy.

[Note: You can even take a backup of the old Users table using mysqldump and restore it into the new one. Just make sure that you delete the insertion statements for UIDs 0 and 1.]

Migrating taxonomy:

Now, this is the tricky part. Broken down, the minimal unit of taxonomy data in Drupal is a “term,” which has an associated “tid” (term id). Terms can be fixed taxonomies or free tags. Each node (if applicable) and forum post has an associated tid, which maps it to the term that the user has assigned to it. Therefore, it is imperative that this data is migrated accurately.

The migration script for taxonomy will migrate the hierarchies, term-node relations, vocabularies, etc.:

< ?php
$query = "truncate timesnow.vocabulary";
mysql_query($query);
print "Vocabulary table cleared.
";
$query = "truncate timesnow.vocabulary_node_types";
mysql_query($query);
print "Vocabulary_node_types table cleared. 

";
$query = "truncate timesnow.term_data";
mysql_query($query);
print "Term_data table cleared.
";
$query = "truncate timesnow.term_hierarchy";
mysql_query($query);
print "Term_hierarchy table cleared.
";
$query = "truncate timesnow.term_node";
mysql_query($query);
print "Term_node table cleared.
";
$query = "truncate timesnow.term_relation";
mysql_query($query);
print "Term_relation table cleared.
";
$query = "truncate timesnow.term_synonym";
mysql_query($query);
print "Term_synonym table cleared.
";
print "
";

$query = "select * from drupal.vocabulary";
$queryresult = mysql_query($query);
while ($row = mysql_fetch_row($queryresult)) {
	$query = "insert into timesnow.vocabulary values('" . $row&#91;0&#93; . "','" . mysql_real_escape_string($row&#91;1&#93;) . "','" . mysql_real_escape_string($row&#91;2&#93;) . "','" . mysql_real_escape_string($row&#91;3&#93;) . "','" . $row&#91;4&#93; . "','" . $row&#91;5&#93; . "','" . $row&#91;6&#93; . "','" . $row&#91;7&#93; . "','" . $row&#91;8&#93; . "','" . $row&#91;9&#93; . "','" . $row&#91;10&#93; . "')";

	if (!mysql_query($query)) {
			print $query;
	}
}
print "Vocabulary plugged in.
";

$query = "select * from drupal.vocabulary_node_types";
$queryresult = mysql_query($query);
while ($row = mysql_fetch_row($queryresult)) {
	$query = "insert into timesnow.vocabulary_node_types values('" . $row&#91;0&#93; . "','" . $row&#91;1&#93; . "')";

	if (!mysql_query($query)) {
			print $query;
	}
}
print "Vocabulary node types set.

";

$query = "select * from drupal.term_data";
$queryresult = mysql_query($query);
while ($row = mysql_fetch_row($queryresult)) {
	$query = "insert into timesnow.term_data values('" . $row&#91;0&#93; . "','" . $row&#91;1&#93; . "','" . mysql_real_escape_string($row&#91;2&#93;) . "','" . mysql_real_escape_string($row&#91;3&#93;) . "','" . $row&#91;4&#93; . "')";

	if (!mysql_query($query)) {
			print $query;
	}
}
print "Term_data plugged in.
";

$query = "select * from drupal.term_hierarchy";
$queryresult = mysql_query($query);
while ($row = mysql_fetch_row($queryresult)) {
	$query = "insert into timesnow.term_hierarchy values('" . $row&#91;0&#93; . "','" . $row&#91;1&#93; . "')";

	if (!mysql_query($query)) {
			print $query;
	}
}
print "Term_hierarchy plugged in.
";

$query = "select * from drupal.term_node";
$queryresult = mysql_query($query);
while ($row = mysql_fetch_row($queryresult)) {
	$nid = $row&#91;0&#93;;
	$tid = $row&#91;1&#93;;
	$query = "select vid from drupal.node where nid = " . $nid;
	$qr2 = mysql_query($query);
	$row2 = mysql_fetch_row($qr2);
	$vid = $row2&#91;0&#93;;
	$query = "insert into timesnow.term_node values('" . $nid . "','" . $vid . "','" . $tid . "')";

	if (!mysql_query($query)) {
			print $query;
	} else {
		$tncnt += 1;
	}
}
print "Term_node plugged in (" . $tncnt . " records entered).
";
?>

You must’ve noticed that I am clearing out all associated tables before each insert block. This is coz’ it is important that the tids, tid-vid pairings, and tid-nid pairings be unique and as they are in the old database. Otherwise it will cause either of the following two problems: (a) terms won’t get attached to your nodes accurately or (b) the insert statements will throw primary key and/or unique key errors.
This script is out-of-the-box too. With just the database name changes (from timesnow. to your database name), it can be run as it is.

And now for the big Kahuna—migrating forum posts.

Migrating forums:

Three parts to this script—forum topics have to be attached to their respective terms, forums posts have to go into the node table, and forum comments have to be migrated. The first part has already been taken care of in the previous script, so we are simply dealing with inserting comments and forum nodes. Again an out-of-box script, this one:

< ?php
$cnt = 0;
$commentcnt = 0;
$query = "select * from drupal.node where type = 'forum'";
$noders = mysql_query($query);
while ($row = mysql_fetch_row($noders)) {
	$nid = $row&#91;0&#93;;
	$vid = $row&#91;1&#93;;
	$type = $row&#91;2&#93;;
	$title = mysql_real_escape_string($row&#91;3&#93;);
	$uid = $row&#91;4&#93;;
	$status = $row &#91;5&#93;;
	$created = $row&#91;6&#93;;
	$changed = $row&#91;7&#93;;
	$comment = $row&#91;8&#93;;
	$promote = $row&#91;9&#93;;
	$moderate = $row&#91;10&#93;;
	$sticky = $row&#91;11&#93;;
	//Insertion into node
	$query="insert into timesnow.node values('" . $nid . "','" . $vid . "','" . $type . "','','" . $title . "','" . $uid . "','" . $status . "','" . $created . "','" . $changed . "','" . $comment . "','" . $promote . "','" . $moderate . "','" . $sticky . "','0','0')";
	if (!mysql_query($query)) {
		print $query;
	}

	$query = "select * from drupal.node_revisions where nid = " . $nid;
	$node_revisionrs = mysql_query($query);
	$nrow = mysql_fetch_row($node_revisionrs);
	$body = mysql_real_escape_string($nrow&#91;4&#93;);
	$teaser = mysql_real_escape_string($nrow&#91;5&#93;);
	$log = mysql_real_escape_string($nrow&#91;6&#93;);
	$timestamp = $nrow&#91;7&#93;;
	$format = mysql_real_escape_string($nrow&#91;8&#93;);
	//Insertion into node_revision
	$query="insert into timesnow.node_revisions values('" . $nid . "','" . $vid . "','" . $uid . "','" . $title . "','" . $body . "','" . $teaser . "','" . $log . "','" . $timestamp . "','1')";
	if (!mysql_query($query)) {
		print $query;
	}

	$query = "select * from drupal.node_comment_statistics where nid = " . $nid;
	$node_comment_statistics_rs = mysql_query($query);
	$ncsrow = mysql_fetch_row($node_comment_statistics_rs);
	$last_comment_timestamp = $ncsrow&#91;1&#93;;
	$last_comment_name = mysql_real_escape_string($ncsrow&#91;2&#93;);
	$last_comment_uid = $ncsrow&#91;3&#93;;
	$comment_count = $ncsrow&#91;4&#93;;
	//Insertion into node_comment_statisitcs
	$query = "insert into timesnow.node_comment_statistics values ('" . $nid . "','" . $last_comment_timestamp . "','" . $last_comment_name. "','" . $last_comment_uid . "','" . $comment_count. "')";
	if (!mysql_query($query)) {
		print $query;
	}

	$query = "select * from drupal.comments where nid = " . $nid;
	$commentrs = mysql_query($query);
	while ($row = mysql_fetch_row($commentrs)) {
		$query = "insert into timesnow.comments values ('" . $row&#91;0&#93; . "','" . $row&#91;1&#93; . "','" . $row&#91;2&#93; . "','" . $row&#91;3&#93; . "','" . mysql_real_escape_string($row&#91;4&#93;) . "','" . mysql_real_escape_string($row&#91;5&#93;) . "','" . $row&#91;6&#93; . "','" . $row&#91;7&#93; . "','" . $row&#91;9&#93; . "','" . $row&#91;10&#93; . "','" . $row&#91;11&#93; . "','" . $row&#91;13&#93; . "','" . $row&#91;14&#93; . "','" . $row&#91;15&#93; . "')";
		if (!mysql_query($query)) {
			print $query;
		}

		$commentcnt += 1;
	}
	$cnt += 1;
}

print $cnt . " rows inserted.
";
print $commentcnt . " comments inserted.
";

//Inserting into forum
$query = "select * from drupal.forum";
$queryresult = mysql_query($query);
while ($row = mysql_fetch_row($queryresult)) {
	$nid = $row&#91;0&#93;;
	$vid = $row&#91;1&#93;;
	$tid = $row&#91;2&#93;;
	$query = "insert into timesnow.forum values('" . $nid . "','" . $vid . "','" . $tid . "')";

	if (!mysql_query($query)) {
			print $query;
	} else {
		$forumcnt += 1;
	}
}
print $forumcnt . " records updated into the forum table.
";
?>

Certain table structures have changed in 6.x. But these scripts handle those too.

Now, moving on into content migration. Due to CCK, content migration will have to take into account many different things. I am not going to post a generic content migration script, coz’ I don’t have one, and that is coz’, frankly, I did not need one. I just needed one for a simple content type with just a title and body and terms of all sorts associated with it, with comments.

My content type was called “multi_user_blog.” You may have to change that for your needs. But basically, what the following script does is inserts content title, body, and associates comments. It is like a building block for all your node migrations. A lot of things have changed in Drupal 6.x when it comes to nodes and associated comments and revisions. There have been translation fields added to the node table itself. Also, the vid (version id) in the node_revision table is set to auto increment in 6.x. This vid is also associated with different terms. Thus, each version can now have its own terms in 6.x.

Moving right along to the script, it is pretty straight forward:

< ?php
$query = "truncate timesnow.node";
mysql_query($query);
print "Node table cleared.
";
$query = "truncate timesnow.node_revisions";
mysql_query($query);
print "Node_revisions table cleared.
";
$query = "truncate timesnow.node_comment_statistics";
mysql_query($query);
print "Node_comment_statistics table cleared.
";
$query = "truncate timesnow.comments";
mysql_query($query);
print "Comments table cleared.
";
$query = "truncate timesnow.forum";
mysql_query($query);
print "Forum table cleared.
";

?>
<hr />
Inserting multi_user_blogs
< ?php
$query = "select * from drupal.node where type = 'multi_user_blog'";
$noders = mysql_query($query);
while ($row = mysql_fetch_row($noders)) {
	$nid = $row&#91;0&#93;;
	$vid = $row&#91;1&#93;;
	$type = $row&#91;2&#93;;
	$title = mysql_real_escape_string($row&#91;3&#93;);
	$uid = $row&#91;4&#93;;
	$status = $row &#91;5&#93;;
	$created = $row&#91;6&#93;;
	$changed = $row&#91;7&#93;;
	$comment = $row&#91;8&#93;;
	$promote = $row&#91;9&#93;;
	$moderate = $row&#91;10&#93;;
	$sticky = $row&#91;11&#93;;
	//Insertion into node
	$query="insert into timesnow.node values('" . $nid . "','" . $vid . "','" . $type . "','','" . $title . "','" . $uid . "','" . $status . "','" . $created . "','" . $changed . "','" . $comment . "','" . $promote . "','" . $moderate . "','" . $sticky . "','0','0')";
	if (!mysql_query($query)) {
		print $query;
	}

	$query = "select * from drupal.node_revisions where nid = " . $nid;
	$node_revisionrs = mysql_query($query);
	$nrow = mysql_fetch_row($node_revisionrs);
	$body = mysql_real_escape_string($nrow&#91;4&#93;);
	$teaser = mysql_real_escape_string($nrow&#91;5&#93;);
	$log = mysql_real_escape_string($nrow&#91;6&#93;);
	$timestamp = $nrow&#91;7&#93;;
	$format = mysql_real_escape_string($nrow&#91;8&#93;);
	//Insertion into node_revision
	$query="insert into timesnow.node_revisions values('" . $nid . "','" . $vid . "','" . $uid . "','" . $title . "','" . $body . "','" . $teaser . "','" . $log . "','" . $timestamp . "','" . $format . "')";
	if (!mysql_query($query)) {
		print $query;
	}

	$query = "select * from drupal.node_comment_statistics where nid = " . $nid;
	$node_comment_statistics_rs = mysql_query($query);
	$ncsrow = mysql_fetch_row($node_comment_statistics_rs);
	$last_comment_timestamp = $ncsrow&#91;1&#93;;
	$last_comment_name = mysql_real_escape_string($ncsrow&#91;2&#93;);
	$last_comment_uid = $ncsrow&#91;3&#93;;
	$comment_count = $ncsrow&#91;4&#93;;
	//Insertion into node_comment_statisitcs
	$query = "insert into timesnow.node_comment_statistics values ('" . $nid . "','" . $last_comment_timestamp . "','" . $last_comment_name. "','" . $last_comment_uid . "','" . $comment_count. "')";
	if (!mysql_query($query)) {
		print $query;
	}

	$query = "select * from drupal.comments where nid = " . $nid;
	$commentrs = mysql_query($query);
	while ($row = mysql_fetch_row($commentrs)) {
		$query = "insert into timesnow.comments values ('" . $row&#91;0&#93; . "','" . $row&#91;1&#93; . "','" . $row&#91;2&#93; . "','" . $row&#91;3&#93; . "','" . mysql_real_escape_string($row&#91;4&#93;) . "','" . mysql_real_escape_string($row&#91;5&#93;) . "','" . $row&#91;6&#93; . "','" . $row&#91;7&#93; . "','" . $row&#91;9&#93; . "','" . $row&#91;10&#93; . "','" . $row&#91;11&#93; . "','" . $row&#91;13&#93; . "','" . $row&#91;14&#93; . "','" . $row&#91;15&#93; . "')";
		if (!mysql_query($query)) {
			print $query;
		}

		$commentcnt += 1;
	}

	$cnt += 1;
}
print $cnt . " rows inserted.
";
print $commentcnt . " comments inserted.
";
?>

Studying this script can you give you some clues/insights to migrating content on your own site.
I am working on an auto content migration script that will enable migration of all content types, associated tables, fields, etc.

Also in works is the profile migration script.

In the meanwhile, let me know if I can improve on these OR if you have some script to contribute (I will credit, promise). 🙂

If you do crack the auto content migration script for all CCK content types before me I will take you out for a meal, and throw in a free conversation, if you are in a can-buy-me-a-meal range. If you feel like my efforts deserve a meal, I am a complete meal slut. Oh, and why meals? Coz’ they are fun and desirable and leave one satisfied and contented.

That’s all folks!

Posted in Drupal, Drupal 6.x, Drupal migration, Meals, Open source, PHP scripts, Social media | 6 Comments »

Hear what the Chief Lizard Wrangler has to say

Posted by Avadhut on 31 January 2008

What has Mozilla Corporation’s chief contribution been? The Firefox browser? Or the email client Thunderbird? I would say neither. It has been its model of developer participation—of managing innovation outside corporate borders and passing on decision making to its community of developers. 40 percent of its code is not from employees—a staggering statistic if you consider that the company’s revenue-sharing arrangement with Google for searches that originate in Firefox delivered revenues three times greater than Mozilla’s expenses (a little over $50 million in 2006)!

Mozilla’s model proved that Open Source not only works but works extremely well when managed properly.

McKinsey Quarterly recently interviewed Mitchell Baker, CEO, Mozilla Corporation. A must read, despite the compulsory registration. She sums it up the best when she says

Turning people loose is really valuable. You have to figure out what space and what range, but you get a lot more than you would expect out of them, because they’re not you.

PS: A discussion on the same theme spawned a large number of really, really, huge comments some time back. Remember?

Posted in Mozilla, Office, Open source, Social media | 3 Comments »

My comeuppance

Posted by Avadhut on 24 August 2007

First, a question: How’s this for a pick-up line?

O Watery-eyed woman, please tell me your good name.

Moving on to more important matters now: Past few days of inactivity on the blog have actually been due to work. More precisely, Drupal. No no. Don’t get me wrong. Not the bad kind of work. The good kind of work. The kind that has you scrambling to your desk every morning to finish what you left incomplete the night before, but with a smile on your face. 🙂

Now, I am not going to delve into the inherent goodness of open source and how it is a great big boon to mankind and will one day save us from extinction. But it is, and it will!

You see, everything I have ever wanted to ask about Drupal, everything I ever wanted to make it do—I could and I could. Communities hold a plethora of knowledge, and not just about Drupal but also MySQL and PHP and Apache and Ubuntu.

But it wasn’t always this sweet.

Let me start a few years back. How back? When free open-source OSes were a rarity and Windows won the people’s choice award for facilitating easy downloading of backdoor trojans and spontaneous formatting of hard drives.

One of those evenings, I suddenly got into a fit of career pangs, as one is wont to at that age and time of day. All my usual a-wondering had disappeared. It suddenly occurred to me that I was not exactly what you would call prime recruitment material. The horror of horrors!

This was the time when software had just reversed the poor trends and IT companies were beginning to flock college campuses again. Anyone with serious job hopes was rushing to their “computer classes” after school/college and locking themselves away with the usual “computer” job preparation materials: SimCity, Basic, etc.

(I have been told that things are easier nowadays. Last year someone from NITT told me that some of the top IT names don’t even interview anymore. All you needed to do was just clear the written test. Sigh.)

Till then I had assured myself that software was not my cup of tea and I would save myself (one is cocky at that age and with that level of blood sugar on a daily basis) for one of Mumbai’s glitzier hotels—as a master chef. Hey, I could cut onions faster than Sanjeev Kapoor could say “khana khazana.”

And then one weekend morning I lay in bed and decided to quickly overview my career plans for a few minutes. But not for too long as the bread pakoda ran out after 8:30 or so.

Now, I knew, back then, that I couldn’t program to save my life. The meta syllabus included a moderately difficult course on Basic and Windows 98. I’d passed through with flying colors scoring one mark more than the required threshold. The highlight of the period used to be watching the bugger—a Mr. Camelius, the high strung nervous sort—struggle with an early morning class on BASIC, break into a sweat, and then finally faint into the arms of a vigilant fellow in the front row.

Later, in college, I often wondered why someone would want a C program that printed out a pyramid of prime numbers. What essential human endeavor struggles for the want of good pyramid prime programs?

“Houston we have a problem!”
“We know. Perhaps a particular problem pertaining to the pyramid prime processor?”
“We like the alliteration Houston!”
“Merely making the mundane mirthful mister!”
“Ok! cut it…”

I hated most forms of programming. And particularly, the fancy shmancy prime number, sorting, pyramid type programs.

But then what certainty was there that I could make it into one of those hotels? They seldom came to Modern Colleges, let alone the Ganeshkhind one. Was I being foolhardy I wondered, as I lay in bed with an eye on the clock.

Then later that evening I decided that I must hedge my risk. I had to ensure that I knew the bare minimum to make it into a software firm just in case my core hotelier dreams fell flat.

So I asked myself—what I could do on a war footing. The threat loomed large that I would have to give GRE and then do an MS and PhD because I couldn’t get a job.

“Unix man. Unix is the way to go. That and Networking. Just focus on those two.”

I shared my thoughts with myself during one of the many walks to the gate for chai.

For one whole month I sat hunched over a UNIX manual and a huge textbook on Networking.

Who was that networking by? Ah yes. Tennenbaum. Andrew Tennenbaum I think.

After a month I thought I was ready to try out some of my newly learnt computing skills on my computer—Octagon, that’s what I called it back then (don’t ask me why).

Two hours later I was back in my room pulling out an old Barron’s guide to the GRE from under the bed and already mouthing words like apothecary and apothegm, fighting back the tears.

It was the worst thulping by an open source operating system I have ever received in my life.

Why were there backslashes everywhere? Why was vi editor such a cold-hearted bitch? Why do I have to press seven keys simultaneously to scroll down one page? Why? Why? Why weren’t things like the way its said in the manual:

finger–display information about local and remote users

When in reality it was more like this:

finger–put in eye in one smooth motion to get in the mood for vi editor

It was a futile struggle. Around me Unix maestros were clearly enjoying themselves enormously:

“Hey there is a problem with my port. Can someone just finger me right now!” .

was the sort of thing one Unix maestro would say to the other excitedly

For close to a year I never crossed my path with Unix ever again.

Till one night, after much recommendation from a friend I decided to give this RedHat thing a shot. I followed the manual by the letter. I slipped in the CD, booted from the disc, played around with my partitions a little bit, set up a root user and finally waited with bated breath while the installation happened.

Everything except the sound card and the PPPOE connection for the internet at home seemed to be working fine.

I could try to get them to work too. I checked the user forums and there was a wealth of information such as this response from a RedHat expert:

This is bug 2825 (http://https://bugzilla.redhat.com/show_bug.cgi?i d=2825) . The work around is to ~# ln -f /etc/pppd/resolv.conf /etc/resolv.conf

To which, someone with a sense of humor replied:

I can confirm this bug. I am using a tap0 bridge to emulate PPPoE on a Globespan chipset-based USB aDSL bridge and the latests stable eciadsl-usermode drivers (which, btw are not in Universe). It would be nice to have an updated pppd perhaps backported from Dapper.
I know that Debian’s choice of using kernel-mode PPPoE makes rp-pppoe unnecessary, but I wonder if it would be possible to update rp-pppoe to 3.7 for those that still in using it.

I laughed heartily back then and decided that, for at least the time being, I was ok without the sound.

Its been more than six years since that day. I breathe open source now. All my development happens on a LAMP setup, and dabbling in Drupal is second nature to me. Forum posts are no longer cryptic, and even I have probably turned into one of those “humorous” responders on the several bug forums that are so ubiquitous today. Reverse engineering was never easier and manuals are a waste of time. Microsoft who? Ahhh … life is sweet indeed.

Posted in Drupal, Foo, Social media | 23 Comments »

Cognitive seduction

Posted by Avadhut on 7 April 2007

While conceptualizing the wire-frame for the office Intranet, I was always confused with regard to the amount of complexity/ease-of-use I should build into the user interface. Should it be amazingly simple or should I make it extremely techie. Should I go according to the textbooks just because they enumerates rules? When will I do something new then? Conventions say I should make sure all hyperlinks are blue because all over the Web they are blue. Conventions say that tagging works for blogs, Flickr, and Youtube; it would be of no use for enterprise content. Conventions say that my navigation should be extremely simple. What new groundbreaking feature do I build into my site so as to make it stand apart from the rest?

On doing research for solutions to this problem, I came across this foreword to the book “Steps to an ecology of mind” by Gregory Bateson. While discussing games, Gregory Bateson makes this important observation:

…there are important emotions that we feel and go through and enjoy and find in some mysterious ways to enlarge our spirit.

So, is solving Rubick’s cube even remotely sensual to our brains? Is formulating strategies sexy? Absolutely. This is what is referred to as “cognitive seduction.” While most of us do not refer to the word “seductive” in non-sexual contexts, game designers do. They are experts at the art of “cognitive arousal,” and I am looking for ways to build these type of features that ensure “repeated playability” of games in a Web model. I am not talking about the use of sex and imagery to keep users/readers interested. I am talking about the type of “experiential pleasure” one might derive out of solving a puzzle, finding something new in an existing framework, interacting with someone in a social networking model, discovering something new about themselves, etc. The premise here is people derive pleasure by having to work something out or to engage cognitively in a challenge.

How does one go about doing this?

Lets try to establish a sort of list of different types of user experiences in conjunction with cognitive seduction:

  1. Discovery: user experience as the exploration of something new
  2. Challenge: user experience as overcoming an obstacel in achieving something, going past previous individual thresholds and knowledge levels, etc.
  3. Narrative: user experience as a story
  4. Self-expression: user experience as self-discovery and creativity
  5. Social framework: user experience as interaction with colleagues or someone unknown in an Web model
  6. Cognitive arousal: user experience as a brain teaser
  7. Thrill: user experience as risk-taking in presence of a safety net
  8. Triumph: user experience as an opportunity to kick ass
  9. Flow: user experience as extreme concentration, extreme focus, lack of self-awareness
  10. Fantasy: user experience as alternate reality
  11. Learning: user experience as an opportunity to grow and improve

No. Its not possible to build a model equipped with all these features. An excellent example of the implementation of the above features would be game design. But even the best game designers do not, and cannot, build a game to mirror all of these requirements. The idea is to make sure that whatever you build—be it a game or, as in my case, a social collaborative tool—incorporates some of these features into its basic model. Or at least it should be tuned to realize a few of the above mentioned user experience types. In simple words, I do not want to make a site extremely simplistic, I do not want to provide just excellent usability; instead, I want to provide a user experience. I want to make sure that every time I design a site, I keep in my mind that my users are smart. I want to give them some credit and reward them if they use my system in an innovative way I had’nt thought of before. I want them to surprise me. I do not want things to get boring very fast!

Am I on the right track here? Or is convention the only way?

Posted in Knowledge management, Office, Social media | 7 Comments »

Knowledge management

Posted by Avadhut on 25 March 2007

Its been a difficult week. Hectic. Conveying the benefits of a social collaborative/knowledge management tool to CEOs and CIOs is a difficult task, especially when you weren’t even hired as a IT guy. A 16-page proposal and 15-slide presentation later, I am still waiting for an answer.

Our current Intranet is like any other corporate Intranet—blogs, forums, company policies, FAQs, ISO information, wikis, the works. Yet, considering the number of people who actually “use” it, it can be positively considered a failure. Infact, the Web/IT team went as far as to setting the Intranet page as the home page on our browsers just to have us visit it.

What then drives people to successfully adopt an Intranet tool?

The successfull adoption of an Intranet tool depends less on the characteristics of the tool itself and more on the motivation people have to use it, which is ofcourse helped by a heavy dose of ease-of-use. Someone proposed that if we had employees participate in the Intranet itself, it could help adoption. So they put up blogs and forums. Did these blogs/forums really have a purpose or were they deployed just to keep us occupied, entertained? In my opinion, if the Intranet isn’t tied to a business goal, the organisation could end up with an expensive system that takes up server space but has no real purpose or returns. Most of the existing implementations are technology solutions and curtail the need for subjective interpretation of information and try to minimise criticism and conflicts in order to achieve conformance and compliance. Here, one needs to understand that what needs to be done with data and information and knowledge is best decided by the individual or group that is using the data. As a result subjective interpretation of data is a must.

Ours is an intensely knowledge-based firm.  Given the amount of expertise each person brings in, it was surprising to know that we were doing nothing to capture tacit information—we were losing crucial knowledge without even knowing it. Our Intranet would have to be a knowledge intiative, a social collaborative tool facilitating something—not just storing information but making sure that it is actually useful.  What should a social collaborative system achieve then?

  • Capturing tacit information
  • Connecting experts
  • Realizing reach and discoverability of people, processes, and projects.

The Intranet would not be powered by technology but people.

With all the hype surrounding “knowledge management,” its surprising to see so little being done about it by Indian companies. Infact a thorough research of Indian knowledge companies in conjuction with knowledge management revealed disturbing facts. Not only were there very few adopters, but most of them were involved in what they wrongly believed to be knowledge management—false positives.

However, one of the companies with an impressive array of innovative KM solutions is Satyam. Satyam’s KM is known as K-Window comprising a problem broadcasting and response system (K-Radio), a knowledge sharing forum (Pathshala), and a mobile interface to K-Window for associates on the move (K-Mobile). But what grabbed my attention was “Communities of Excellence” (CoE)—groups of people with specific domain area expertise to whom questions can be directed through K-Radio. These, I found were quite similar to my proposal of “equal communities.” You see, our organization has employees from varied backgrounds—experts in linguisitics, computer science, Phds in physical sciences, geologists, engineers, doctors, etc. Yet, they do little to apply thier domain skills expect in thier day-to-day activities. Thier representation in our organization’s knowledge base is negligible if not non-existent. There is so much that they can contribute, if only they were made aware of what the problems are. An Intranet should establish equal communities—HR, core associates, IT, Web, admin, etc. If anyone faces a problem, he/she should post it on the broadcasting service. These problems will then be e-mailed to the respective community members. They can respond by either replying to the e-mail or by entering the solution on the intranet site itself. Moreover, no matter how this communication takes place—e-mail or through the intranet itself—it will all be stored in a documented manner on the intranet. If tomorrow, someone faces a similar problem, he/she can either post a new query or search through previous solutions to see if they match his/her requirements. Question: Why go through all this when a person can simply ask another person to help him/her out. Answer: The proposed process give you not one but several solutions from different perspectives; it documents these solutions so that when tomo, the solution provider leaves the company, the solution itself is not lost; and repeated instances of the same problem don’t need repeated discussions as anyone can simply pull up the solution from the Intranet.

With regard to my difficulty in conveying the benefits of such a knowledge management/social networking tool as an Intranet, Krishna Koneru, Satyam’s KI intiative’s vice president says

Measuring knowledge is a tricky affair and attaching a ‘monetary’ value is subject to endless debate. Measure an employee’s contribution by assessing how frequently his/her document gets referred to and who uses the document.

and

There is no clear way of measuring return on investment (ROI) for knowledge management. KM investments, like investments in people and training, are long-term investments for a company.

Bang on! Now why didn’t I come across that quote before sending in that presentation.

P.S: Koneru’s quotes were from Satyam’s KM page.

Posted in Office, Social media | 16 Comments »

Tags, memes, and wet chickens

Posted by Avadhut on 8 March 2007

Posted in Office, Social media | 7 Comments »