Learn Kannada, Get Rich!
So, learning Kannada has been made mandatory if you want to work in Bangalore. Within a year from now, every non-Kannadiga (aka expatriate, alien) living in Karnataka has to clear the Std. VII Kannada exam.
The rationale provided behind this, by MLC ‘Mukhyamantri’ Chandu, head of the Kannada Development Authority (KDA), is this:
“With several IT companies and MNCs coming to Karnataka, lakhs of non-Kannadigas have settled in the state. If they could live with the land, water, air and other resources of the land, they should also understand the culture, history and language of the land.
Wasn’t that just cute? He buried language between culture, history and land; making it seem like a patriotic issue. So, you’re not Indian enough if you don’t pass the Std. VII local language exam. Over 35% of the 52 million people (2001 census) living in Karnataka are not frikking Kannadiga enough for the KDA.
This is not about culture, language or history. It was enough that we were made to memorise the innumerable volcanoes, rivers, mountain ranges and other spectacular geographical features of India, along with the mighty rulers who ruled different parts of India during different periods of time. Don’t get me wrong, I’m a sucker for history. But one thing I’m not a fan of ? Forcing people to do things.
It’s unfair to make an adult drop everything he’s doing and learn a language. And I think I speak for most North Indians when I say this: South Indian languages look, sound and feel the same ! They’re just squiggly ants going around in random paths.
Many people (mostly Kannadigas) have commented : “Get a grip. It’s just a Std. VII exam”. But wait, it’s not that simple. I believe children are some of the quickest learners around - especially at picking up languages. So, in one year, an adult (who’s also working full-time), has to match the Kannada skills of a kid who’s been learning it for over 12 years? You’ve got to be kidding me.
Also, can you imagine the excruciating pain of being forced to learn a new language? Don’t get me wrong but I’m better off knowing just Hindi and English. Another form of commentary on this story that has been disturbing, “Oooh you go and learn French and Spanish. But when we ask you to learn Kannada you’re cribbing. You anti-Indian hypocrites. Go Die.” Wait, first of all - I might want to learn French. Second of all , you can’t force me to learn something I don’t want to - especially squigglies!
Also, what about people with learning disabilities? Will they be forced to clear the examination within a year, or will they be given more time? What about SC/ST - do they have a quota ? What about foreigners who reside in Bangalore ? What about old people? Implementing a legislation like this brings so much fear, uncertainty and doubt (FUD) along with it. Why are these people trying so hard to save Kannada, and trying to save it from what? Extinction? As someone noted on Twitter, “Let Kannada find its (own) saviors.”. We had enough of moral and cultural policing. We’re now entering a new phase - one with linguistic policing.
To wrap it up, let’s take a moment, sit back and think, what is this piece of legislation going to achieve? 10 years down the line we’re going to have a bunch of people who know half-baked Kannada.
Learn to think beyond the IITs, IIMs and IIPMs! Learn Kannada, go to Silicon Valley of India and Get Rich or Die Tryin’!
A Simple Twitter DM Enhancement
One of the most irritating things I find about Twitter is interacting privately with people who don’t follow me. Twitter presumes that people who know each other follow each other - which is quite often the case. However, on many occasions, I receive DMs from people I follow, and who don’t follow me back, and I need to relay private information to them.
So, what do I do? Do I try finding out their e-mail address ? Do I scour the interwebs for their presence on other social networking websites? Do I ask them to follow me?
Instead, what if I’m allowed one DM as a reply to a DM I receive from that person? Surely I can’t be spamming because it’s a reply to a DM I received. This feature will increase the usability of Twitter DMs, while not contributing to the increasing spam on Twitter.
When a News Publication Sells its Soul
The 22 May, 2011 edition of Bombay Times (a supplement of Times of India (TOI) ) has a front-page article about Brett Lee (the cricketer) endorsing the WhatsApp application on the Nokia Ovi store, explaining how it made it really easy to help him keep in touch with family and friends. It’s not Brett Lee actually appreciating the application, in which case he would’ve described his experiences with the application, but a blatant advertisement, since he explicitly mentions his Nokia cellphone, and the Nokia Ovi store.
It doesn’t take a genius to realize Nokia paid through their noses for this advertisement morphed into an article. Nokia is one of the major sponsors of the Kolkata Knight Riders IPL team, who employ Brett Lee. Obviously, this is just an allegation, and I have no sources; but as I said, it doesn’t take a genius to figure out this stuff. Also, this isn’t the first time Times of India has run such an ad-article.
This is a classic case of a newspaper selling it’s soul. As a content provider, when advertisements start infiltrating the content section, it means you have absolutely nothing left to sell. I’m no expert in journalism, but I do have a sense of the ethics involved. It’s as simple as this: No money should be involved when crafting the content of your article.
TOI’s quality of content has been declining for a long time now. When corporations start to prioritize money over ethics, we result with like something like TOI. If you notice their website, you would fail to find their logo on the front-page (or any page for that matter), but you wouldn’t fail to see a bunch of advertisements.
I fail to understand this obsession with increasing income. TOI is the largest selling English daily in India, and a part of The Times Group - it’s short of saying they are very, very rich. Surely they can do without ads on their website. For avid readers like me, TOI has become a useless piece of junk. After a week of TOI, when I pick up The Economist, I wonder if they are both reporting about the same planet, because I wouldn’t really have heard of anything that The Economist is reporting about.
This culture of increasing income at-all-costs is spread across Indian media. Sponsorships have become the de-facto standard of Indian media, and very few people seem to be concerned about the quality of the content they deliver. They focus mainly on “branding opportunities” and assign sponsorships to anything and everything - the Indian Premier League being one of the major culprits - but that deserves a piece of it’s own.
But that’s not all. There’s another way in which TOI sells it’s soul - By having a full-page advertisement as the first page. I firmly believe that the first page of a publication is it’s identity - there’s a history, a tradition and sentiment attached to the logo and the name. But when I pick up the Times of India on some days, all I see is a huge color advertisement, and I throw it back down.
TOI seems like an aggregation of news stories that some lazy reporters are handpicking from AP / Reuters, and rewriting/modifying, often with excessive grammatical mistakes and minimal coherence. There’s no real reporting. There are no ethics. There is nothing interesting to read. 90% of stories are mundane reports on Indian politics, crime and sex.
Journalism is one of those places in India where mediocrity pays off by virtue of the entity’s history. TOI is surviving just because it started many years ago. If TOI were to launch today, nobody would spare a second glance. Another example of mediocrity flourishing is the Bollywood “actors” of today. They are employed solely because their parents were actors. I am willing to wager on many of these “actors” failing a basic acting audition.
However, things are looking brighter with the emergence of publications like LiveMint. Their weekly Mint Lounge is a pleasure to read, and is somewhat comparable to superior publications like The Economist, New York Times, NY Times Magazine, Readers Digest, Vanity Fair, Slate, The New Yorker, Rolling Stone, The Atlantic, Esquire et al. who employ real reporters who have a passion for journalism and writing. Granted many of the aforementioned publications are magazines, but TOI can learn a thing or two about journalism, English, and writing nevertheless.
Otherwise, I predict we’re going to have Nivea Editorials, DLF Sports News, Idea World News and Nokia Tech News in TOI very soon. And, the problem in India is, if one person does this, everyone will follow, blinded by the promise for greater profits. Someone really needs to teach TOI a lesson in journalism, and I hope that happens soon.
A Gentle Introduction to Node - 2
Update: Oct, 2011 The API of Node has changed ever so slightly, and it renders this tutorial obsolete. I am not working on Node right now - So head over to Node’s homepage and pick up the latest API docs from there!.
Previously: A Gentle Introduction to Node - 1
If you’ve not read the first post, please read it ! (especially the resources section to get a good understanding of how Node works.
So let’s dive in. We’re going to be building a simple looking homepage for me using a static file server in Node.JS. I agree that’s probably not what Node is best at, but at some point in your life you are going to want to serve static files to the browser.
Let’s dive in. The code may look big and mean, but it’s actually really easy to understand. And please, type out the code, especially if you’re new to Javascript. If you want to view it in your code editor, grab the code here.
var http = require('http');
var fs = require('fs');
var server = http.createServer(function (req,res) {
var path = req.url;
switch(path) {
// This is a trivial implementation of URL routing.
case '/' :
res.writeHead(200, {'Content-Type' : 'text/html'});
res.write('Welcome, you have reached my homepage. ' +
'You can check out my twitter profile ' +
'<a href="https://twitter.com/hardikr">here</a>' +
'<p>Sitemap</p>' +
'<li><a href="about">About</a>' +
'<li><a href="image.png">My Favorite XKCD comic</a>'
);
res.end();
break;
case '/about' :
res.writeHead(200, {'Content-Type' : 'text/html'});
res.write('My name is Hardik. That\'s all :| ' +
'<br/> <a href="/">Go Back</a>'
);
res.end();
break;
case '/image.png' :
fs.readFile(__dirname + path, function(err, data) {
if(err) throw err;
res.writeHead(200, {'Content-Type' : 'image/png'});
res.write(data,'utf8');
res.end();
});
break;
case 'default':
res.writeHead(404, {'Content-Type' : 'text/plain'});
res.write('Page Not Found. 404');
res.end();
}
}).listen(8080);
console.log('Server started at http://localhost:8080');
As discussed before, Node uses modules which you can include in your code to let you do awesome stuff. Just like Python, Node is an uber-cool Swiss Army Knife, only there’s no limit to how far you can customize the modules you need to include. You can even use the hundreds of third party modules already available, and when you’re confident enough, you can build your own modules to serve your needs.
var http = require('http');
var fs = require('fs');
So, we start off with importing the http module (which we used in the previous post), along with the fs module. The fs module is the File System module, which we’ll use to read a local file and display it to the browser.
var server = http.createServer(function (req,res) {
var path = req.url;
Next, we initialize our server object, with our req (request) and res (response) objects coming in as parameters to the callback function. If you read the last post carefully, you may have realized we never used the request object for anything. Well, we’re gonna do that right now.
We obtain the requested URL by accessing req.url value (from the req object). To illustrate, if I accessed http://example.com/about, then req.url returns /about. (Note, you can get a detailed look at the request object by simply doing console.log(req). Similarly, you can log pretty much anything if you’re not sure about something. It’s actually a good way of debugging Node.JS code. Note that the log will appear in your terminal and not in your browser since this is server-side Javascript.)
Note: I’m taking a little detour here. In several open-source projects, I’ve seen the following code used to extract the pathname:
var url = require('url') // Include the url module for url.parse
/**
* similar code until we get to defining our path
**/
var path = url.parse(req.url).pathname;
To make sure you’re on track, if the browser requested http://example.com/about, then req.url contains /about. Coming to the above code, url.parse is a method from the url module that creates a url object out of a URL string. Don’t be confused, hang on! I’m illustrating the use of url.parse() on a sample string:
var urlString = 'http://example.com/about';
var urlObject = url.parse(urlString);
console.log(urlObject);
This returns the url object of the string we declared:
{ protocol: 'http:',
slashes: true,
host: 'example.com',
hostname: 'example.com',
pathname: '/about',
href: 'http://example.com/about' }
So, going back to the code,
var path = url.parse(req.url).pathname;
Since the requested URL is http://example.com/about, req.url already contains /about. So, if we were to use url.parse(req.url) , it would convert /about into an object, like so:
{ pathname: '/about', href: '/about' }
Summing up, the code is unnecessarily (in my opinion) converting /about into a URL object, and extracting the pathname which would return the same /about. I’m not too sure why so many projects use this. It’s almost like I’m missing out something. If you know why, do tweet me !
Alright, let’s get back to our own code. To recap, we just assigned path to the requested path by using req.url.
After that, it’s pretty self explanatory. We use the switch method (which I presume you know). The first case, we test for the root of our homepage - for which the pathname would be /. We write the response headers and body just like last time, and end the output with res.end(). Don’t forget to put your break statement. Similarly, we test for /about and send my about page.
fs.readFile(__dirname + path, function(err, data) {
if(err) throw err;
res.writeHead(200, {'Content-Type' : 'image/png'});
res.write(data,'utf8');
res.end();
});
But now, I want to send over a PNG image as my favorite XKCD comic. I have a file named image.png lying in the same folder as my server.js file which I want to serve. Logically, I have to read the file from my Node.JS code first. I can do this with the readFile method.
__dirname specifies the current working directory (where the Node server file is present), and we append to it the path that we extracted from url.parse(req.url).pathname hence building the absolute path to the image.png file on the UNIX filesystem. We use an anonymous callback function which will return the file as an object data.
I check for any errors, if found will be thrown. I write the HTTP response header, but this time my Content-Type is set to image/png since I’m returning a PNG image. I pass along the file object data which contains the PNG file and end my output stream with res.end().
The default case will be selected if the client requests one of the paths we’re not checking for; and it sends over a simple 404 error.
That’s pretty much it. We have our working homepage, and you can test it out! If you want something like this for yourself on the Internet, you can get to designing your webpage in Node and host it over at Amazon EC2 which I think is still offering one year of free micro-instances :)
Since this is just a demo, the number of files are small, and the amount of HTML is small. Realistically, for a bigger homepage, obviously we would not want to include all your HTML in the Node.JS server code. That wouldn’t be too smart of us!
One way would be to use the excellent Express framework along with Connect middleware; but let’s leave that for later on, when we’re more experienced with pure Node.JS code. I suggest this in the same vein as people will tell you to start off with pure Javascript and then to go jQuery.
Another way would be to build a static file server function, to which we can pass as parameter the file we wish to serve. Good ol’ functions !
You should try writing that code on your own. But, here are a few hints.
- You’ll have to write the
/as an index.html file, and/aboutas about.html, and pass them as parameters to the static file server. - You can use the same static file server function above and generalize it.
The solution can be found, if you know where to look! So, till next time, where we’ll run bash functions through Node code!
A few words before we part, as I said before, keep perusing the Node documentation. It’s quite small and easy to understand. There are a lot of methods which you may like to play around with. I’m deliberately keeping it simple in the blog post, since I want everyone to read the Node docs.
You could also look at the hundreds of thousands of lines of open-sourced Node.JS code. Just search on GitHub. At the end of next week’s post on running bash functions, we’ll take a look into a third-party Node.JS module that’ll turn our command line into a dictionary! How cool is that ?! Hang on till next week!
A Gentle Introduction to Node - 1
Update: Oct, 2011 The API of Node has changed ever so slightly, and it renders this tutorial obsolete. I am not working on Node right now - So head over to Node’s homepage and pick up the latest API docs from there!.
There are many great introductions to Node, and I’m not going to waste my time reinventing the wheel. Instead, I’m trying to fill a gap that exists, somewhere between the hello world program and the node-chat example, all while linking to great resources already out there. At the end of the post series, you should be able to comfortably create real-time web applications using NodeJS + Socket.IO. Now it’s really easy to create real-time web applications :)
First off, a few points to note:
- I’m in the midst of learning Node myself, so do not expect super high-performance code. Let’s leave premature optimization to the pros and focus on getting the basics of Node down.
- A lot of the code examples have probably been inspired from the thousands of lines of open-source code I’ve read (which invariably is the best way to learn Node). So, thanks to them.
- As far as possible, I give credit to the original authors of any code I may have borrowed. If I may have unintentionally missed something, please tweet me @hardikr.
- Keep referring the Node docs when you learn something new. The API is fairly small and straightforward.
- The latest version of Node as of this writing is 0.4.5. That’s the version I’ll be using
- Consult the Javascript style guide by Felix Geisendörfer, to learn about best practises while writing JS code.
I’ll link to some interesting webpages about Node, so you get a broad view of Node. First, give Node website’s about section a casual read. Even if you don’t understand much, it’s alright. Next, to get a gentler introduction to Node, check out this paragraph from a Net.Tuts blog post about Node over a year ago. Don’t bother with the code samples just yet, we’ll get into that. Finally, read the Introduction section oN Net.Tuts’ new new post on Node.
In short, just keep the following in mind:
Node is an implementation of server-side Javascript and is written using the V8 Javascript engine (which is a blazing fast JS engine written by Google, and it’s part of the reason why Chrome is so fast). Node uses an event-driven programming model, that is non-blocking in nature.
If you still don’t understand, don’t fret. Later on in the article I’ll link you to a few articles that make things crystal clear.
Right, so let’s dive into some code now. First, install Node using the instructions on the Node Github Wiki. If you’re on a Debian based system, just use:
sudo apt-get install node
Node can run as an REPL. So fire up your terminal.
hardik@voodoo:~$ node
> console.log('Hello World!');
Hello World!
>
That was easy, wasn’t it? You may remember console.log() from using client side Javascript. Yes, you can use it on Server-Side Javascript too. Although in real-world environments, we would use sys.debug.
So, you’re probably not too excited about using Node in the terminal. Right, let’s create our first server! Open up your favorite text editor, and type in this code. That’s right, type it. Not copy-paste. Trust me, it’ll help.
var http = require('http'),
server;
server = http.createServer(function (req,res) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.write('<b>Hello World</b>');
res.end();
}).listen(8080); // Defaults to localhost (127.0.0.1)
console.log('Server started on http://localhost:8080');
Fine, if you really don’t want to type it, grab it (right click, Save Link As) here. But I warned you.
Let’s break it down here. Natively, Node supports program components known as modules. These modules have to be imported by Node whenever you want to use any of them, just like you would use require in Python, Javascript etc.
var http = require('http'),
First, we require the http module, which comes packaged with Node. We create a HTTP server object. So, let’s take a pause here and understand that HTTP !== Apache. Many people new to Node believe we’re creating an Apache server. That’s wrong. We’re creating a simple HTTP server object. Next, we define a variable called server, which will act as the placeholder for the server we create in the next line.
server = http.createServer(function (req,res) {
function (req,res) is the callback function for http.createServer. This is the crux of the event-driven programming style of Node. Because Javascript provides extensive capabilities for callbacks and anonymous functions, it seemed to be the perfect choice for implementing Node.
But, what’s a callback function? A callback function is attached to a listener, and is fired on a particular event.
In the above example, the addListener event is automatically added to the http.createServer method. In essence, whenever a client connects to our server (aka the listener receives an event), the aforementioend anonymous function is called.
res.writeHead(200, {'Content-Type' : 'text/html'});
Now, we have an HTTP server setup, but we still have to output Hello World to the browser. So, let’s set the HTTP headers for the output. (If you have no idea about the HTTP protocol, you should probably read RFC 2616, which defines the HTTP/1.1 protocol. It’s a very comprehensive document and it’ll be worth the time you spend on it. If you’re in a hurry, you always have Wikipedia.)
Right, so the 200 status code implies everything’s okay (see the complete list of HTTP status codes), and we set the Content-Type to text/html, since we’re going to be sending a snippet of HTML code to our client. The headers are set so the browser knows how to render the incoming stream.
res.write('<b>Hello World</b>');
res.end();
We’ve set the headers, and now we actualy have to send the output. We write to the output stream. It’s important to understand that we’re just writing the snippet Hello World to the stream that is being sent by the HTTP server object, and nothing else. This could be anything: a jpeg image, an ogg audio or even an mp4 video, as long as we set the headers correctly. Next, with res.end(), we end the output stream, and that’s an indication for the server to finally send it over to the client.
}).listen(8080);
But, how will the server know who’s listening? That’s the next part, we make the server listen on a particular port and host. If you don’t specify the host, it defaults to localhost (127.0.0.1). I choose port 8080 because I usually have an Apache server running on 80.
console.log('Server started on http://localhost:8080');
Finally, we output to the terminal saying we’ve started the server at a particular address. This line is not required. But if it appears once you’ve run the code, it means the server has at least started listening.
Now, save the file as server.js, and run it in the terminal like:
hardik@voodoo:~$ node server.js
Server started on http://localhost:8080
That’s it, fire up your favorite browser, and navigate to http://locahost:8080 and you should see your Hello World, all bolded up, because remember, we sent an html output.
So, that’s enough for the first post, but I’ll leave with providing a few links, which you should read, and I cannot emphasize that enough. Even if you take nothing away from this post apart from these digesting the content of these links, it would be acceptable.
- Understanding Node by Felix Geisendörfer
- Understanding Event-Driven programming by Dan York
- Understanding Event Loops and Writing Great Code for NodeJS - Part 1 by Yahoo
- Deep Inside Node.Js with Ryan Dahl by InfoQ
- Ryan Dahl on NodeJS on Yahoo
- Understanding Threading in Node on StackOverflow
The InfoQ interview goes into great detail about Node, and will give you a great overall review of Node. As with everything to do with Node, always check the date of publication of the resource you’re using. Things might have changed already, new features implemented, old ones deprecated and even a few API methods changed. So, learn to keep up, as you’ll be doing a lot of that when using Node.
In the next post, I’ll introduce static file servers and basic URL routing! Till then, happy reading and make sure you thoroughly read the above mentioned links.
Net.Tuts has started a screencast series on NodeJS just as I was about to publish this. They’ll be building a blog engine using Node. You can check it out here. I haven’t seen it yet, but knowing NetTuts, I can only vouch for it to be pretty easygoing on beginners. As I mentioned before, we’ll concentrate on building real-time web applications using Node and Socket.IO.
One more thing, make sure to thank Ryan Dahl/Joyent for the awesome work they’re doing. You could e-mail them, or even a tweet @ryah/@joyent would be good enough. There are a bunch of other very influential people in the Node community, Felix Geisendörfer , Guillermo Rauch (the main guy behind Socket.IO), TJ Holowaychuk and many others. Check out an incomplete list here.
If you’ve lost track of all the links I’ve provided, check them out as a nice consolidated at the bottom of the source of this post.
If you liked (or more importantly, hated) this post, do tweet and follow me on Twitter at @hardikr as a little thank-you :)
