Thursday, December 22, 2011

Tic-Tac-Toe with Redis and Backbone.js

This post is a technical overview of my Tic-Tac-Toe implementation. It is a zero server-side logic, pub-sub based, realtime, multiplayer game which uses Redis and Backbone as the key enablers of real-time and moving logic to the client side, respectively. Now that all the buzz-words are out of the way, the source code is on Github. There are rough edges with reliable communication, security holes do exist, but for the most part it works well.
I would specially like to thank Nicolas Favre-Félix for Webdis without which this would’ve been impossible.

Basic functioning

On visiting the home page the user has an option to either join a game, or play with a friend. The join game option pairs the player with another player who also wants to play (if you are the only one online, you’ll have to wait). If you play with a friend you get a link you can send him/her so you can play together.
The players are asymmetric in the sense that there is a ‘hoster’ and a ‘joiner’, whose roles I’ll get into in a bit.

Technology Stack

Tic-Tac-Toe game me the opportunity to experiment with a ton of technologies/products I hadn’t handled before. The stack goes like this.
  • A Linode VM hosts the service
  • Redis powers base Pub/Sub
  • Webdis provides a REST API to Redis so that the clients can directly talk to it
  • nginx serves static files
  • haproxy routes requests to nginx or Webdis depending on the path
  • Backbone is used for MVC
  • Raphaël is used to draw the grid and pieces using SVG
  • jQuery is used for AJAX and the impromptu is used for modal dialogs
  • underscore is a utility belt
  • UUID.js for generating UUIDs
Yep, thats a lot of stuff for something so simple, so I’ve tried to rationalize it below :P

Clients

All clients are identified by a UUID. The ‘host’ player’s UUID is used as the name of the Redis Pub/Sub channel. The ‘joiner’ will also subscribe to this channel and publish to it. This is why the ‘host’, ‘join’ bifurcation, so that a common channel can be used for communication. All messages are JSON objects.
All communication is initiated by the ‘joiner’. The host player keeps waiting. The joiner starts the game, after which both players keep sending each other the moves made by the humans playing. After each move, both sides check for a win/lose/draw. Again, the joiner sends a gameover message when it detects somebody has won (or it’s a draw). The host then verifies that this is actually true, and responds back with it’s own gameover message. Then both parties change their UI accordingly. This causes the slight delay between the actual win and the notification.
WSD for Tic-Tac-Toe

Server side

The first question is ‘why both nginx and haproxy?’ I could’ve run Webdis and nginx on two different ports since Webdis supports CORS, but Opera does not support it. Running just nginx web-facing and then proxying to Webdis based on path is also not possible since nginx does not currently support HTTP chunked replies, while haproxy does. Chunked replies are used by Webdis to relay Pub/Sub messages.

Implementing ‘Join Game’

To allow two people to be paired, a Redis list is maintained. When a client clicks Join Game it attempts to LPOP a UUID off the list. If none are found (no other players), it RPUSHes itself onto the list.

Client side

The client side has all the logic and so is more interesting. I won’t go deep (you can read the source), but will discuss the key areas.
Once a game has been initiated, both clients open a XMLHttpRequest to the subscriber channel. They watch for readystatechange events and try to parse the messages. This is the Subscriber which fires events when it receives valid messages.
The Publisher component is used to send messages, while Webdis is used for other Redis commands (currently only LPOP and RPUSH).
The GameRouter is the controller, sets up models and views, watches for gameover and beginning a host or join. HTML5 pushState or hashes are used to offer permalinks for games. /host/UUID is for hosting and /play/UUID is the joiner. Backbone’s Router and History is used to cleanly handle this. One feature I wish there was, is a way to query what the current route is via Backbone instead of mucking with window.location.
The GridModel drives the game once it begins, triggering gameover events and checking the grid after every move, also handling the turns. GridView handles rendering the SVG grid and pieces based on GridModel and processes clicks while HUDView notifies the user of his turn, piece and game state. Events are an integral part of this entire setup and Backbone makes it very simple and modularized.
One thing that stands out in my use of Backbone is the absence of Sync. I’ve not used it, although it integrates well with Backbone. The game model didn’t seem suited to it, being more event-based rather than the model reflecting the game state. Collection is also not used since there is only one grid.

Issues

The lack of any server side code does lead to certain issues. None of them are serious when it comes to Tic-Tac-Toe but some affect the user experience and others are security issues.

Usability

On the usability front, the current code is very fickle. The joiner only tries to initiate the connection the first time it starts. If the host fails to respond for some reason (e.g. network connectivity) then both parties will keep waiting. If a joiner refreshes his page mid-way through a game, the game will restart for both parties (a good idea if you are a joiner and you are losing \:P). If the host refreshes the page, the joiner has to refresh after him.
The slight lag to decide win/lose/draw was probably unnecessary. Rather than verifying both sides are on the same page, the notification could’ve been shown directly since this is just a game. The UX would’ve benefited.

Security

Webdis sports a HTTP interface to Redis, but there is no real authentication support, which means the Redis instance hosting Tic-Tac-Toe is also effectively a public domain database (although the command set is restricted). Ideally this should run only in a trusted intranet. Ideally Webdis itself would be capable of serving files and deliver something like a nonce which it would then use to ensure that only its own connections are allowed to relay messages. Similarly nothing is stopping someone from grabbing the UUID and then playing future moves using a bot of some kind to always play optimally. In the case of Tic-Tac-Toe this is just a minor prick, but for actual client-side MVC applications this requires fixing.

Conclusion

Tic-Tac-Toe demonstrates that with a data structure server and HTTP interface to it, web applications where all logic is client-side are possible. Using the server as a Pub/Sub relay also allows near real-time performance, with WebSockets or SPDY possibly leading to better performance. Security policies still mean that true peer-to-peer isn’t possible. Authenticity and authorization also remain to be solved. On trusted intranets, such applications could be used for non-critical tasks. Meanwhile, games like this at least can be safely implemented and played as long as you have no sore losers :).

Tuesday, December 13, 2011

Why Indian students should attend college

In recent months, the number of posts extolling dropping out of college, or of people recounting their experiences (mostly positive, probably because the negatives won’t share) has increased substantially on Hacker News (I believe Steve Jobs effects on humanity extend here too). Meanwhile the The Story of Average Indian ‘Techie’, What’s your GPA? and other posts bring to the fore some things I do agree with:

  • Most computer science curricula are outdated or just poor quality
  • The majority of students are in it for the money
  • The professors are almost always bad

In fact I didn’t particularly like most of my CS courses either. There were a few gems like System Software and Computer Networks at DA-IICT, but the rest were totally out of sync with the real world. So if you are a precocious hacker should you drop out of college in India? (Assuming your Indian parents will let you do that!)

NO!

Try your utmost to get into a good college with good infrastructure. Here is why you would want to do so. Not only is the infrastructure itself important, it also attracts the smartest people. Do well in college while improving your own skills and knowledge.

My reasons are based on personal experience, and in ways document some of my shortcomings too :P

Like minded people

Unlike the dense technological concentration of Silicon Valley, India doesn’t have technological hotspots. Even in Bangalore, very few people are passionate about technology and are hacking on open source software or launching startups (while this is pretty high in India terms, it is nothing in Bangalore terms). FOSS talent is instead concentrated in the students of engineering colleges. (I focus on FOSS because it’s a good way to filter out passionate people.) You will get to discuss problems, hack on code and be inspired by these people. A concentration of geeks also leads to geek events like hackathons. During various college fests there will be programming contests and so on. You’ll get to have fun. Finally there will be a lot of smart people doing things other than computer science. But they will be equally as passionate as you are, they will be liberal and forward looking and it will be a pleasure to interact with them. Oh and please don’t think of every person you approach as a potential future employer, employee or general networking and increasing contacts kind of person. Sometimes you (and certain people in the Valley too) just need friends. Face it, do you want to spend the next few years talking to your mom about why REST-ful APIs are the bomb or why this is funny?

Facilities

High-speed Internet access in India is still not too common, but colleges will usually have a great LAN setup, a lease line to the Internet and generally good connectivity. Use these to experiment with your peer-to-peer applications, host websites, or write the next great DDoS program (I’m not advocating this). That said they also may have ridiculously bureaucratic system administrators, censorship and the like. You just have to deal with in (and in some cases, circumvent).

Your college will also have a certain ‘relic from the past’ which is far more useful than any of our modern day, 140 characters technology. The library. Specific technology education is always best done via Internet, but general concepts and deep theory is still found in books. Use it well, you will regret the day you leave college and books will have to be purchased. (To overseas readers – there is hardly a public library system in India.) Oh, and do remember the fiction section.

Motivation and Persistence

When you are working on personal projects it’s very easy to give up or change tracks. You also tend to focus only on the things you like. College courses will force you to persist at subjects you don’t like, and keep you onto one thing for 3-4 months. Valuable lessons when your first commercial project is 90% done and you don’t want to polish it up because node.js just came along and is much more fun to play with. Do a great and challenging final project and end your education on a high note.

Find some other interests

Your life isn’t going to be just about CAP theorems, cache invalidation and naming your projects. You will have to interact with society. Take a humanities course. Learn to loosen up a bit — travel, listen to music and play sports. Waste time with friends once in a while. Don’t burn out before you’ve even started. Your whole life before 25 should not be spent being a workaholic. Sometimes I think the Valley propagates Minimum Viable Product, pitching to VCs and beer and pizza far too much. You don’t want to end up like this. You might also want to try some of these things.

So if you were thinking of dropping out, just give it a second thought. If you are still convinced you should drop out, do it. But please let me know at nsm.nikhil@gmail.com why you did so.

Posted via email from nikhil's posterous

Monday, November 28, 2011

A High-Five Experiment

Final exam time is always a time of stress for students. When you have 6 exams in 6 days, the time just before the exam is one of general apprehension and attempts at mentally revising all the key points. Everybody notices that in the glum looks students have walking into the exam hall.

Fortunately, the fourth year in DA-IICT is pretty light, and due to a multitude of projects, me and Naman had only a couple of papers. Inspired by Charlie Todd’s TED video about Improv Everywhere we decided to inject some cheer into the poor souls of the other batches.

Four signs went up on Thursday, Nov 24, along the long, curved staircase leading to the hall.

Somebody wants to give you a high five

They were nicely spaced out so only one could be seen at a time, and we were standing at the end of it, right at the entry doors.

As the students started coming in and the high-fives started flying, accompanied by words of encouragement (and the occasional “Heap sort is O(nlgn)”), it was very satisfying to see those faces light up in the happiness of an unexpected surprise and lose some of the pressure.

So go out and spread some cheer! You can freely use and modify the above images for a noble cause :) There will of course always be people who are unable to take in why someone would do something like this, they’ll walk past you without an upward glance. Others will eye you with suspicion even as they raise a half-hearted hand. Grumpy administrators will tell you you aren’t supposed to be in the examination area if you don’t have an examination. But on that day I saw the most introverted student give a resounding high-five back and walk with a spring in his step. It was worth it.

Posted via email from nikhil's posterous

Thursday, October 13, 2011

Have some humanity

This article was first published in Entelechy (Issue 29, September 2011), the in-house DA-IICT magazine.


“Technology [is] the knack of so arranging the world that we don’t have to experience it.”

-- Max Frisch

DA-IICT is one of the few colleges in India to make humanities courses mandatory for students. It is sad then that most students treat it as a course to pass, and not as a way to gain insight into the world they’ll spend the rest of their lives in. I am going to try to convince you that humanities courses are perhaps more essential than even the technical courses.

Observe the typical young engineer as he gets placed and eventually graduates from college. Engineers used to have dreams. That is why we have the Taj Mahal and the Golden Gate bridge. Today the most skilled engineers end up sitting at a desk writing non-user-friendly software for some mega-corp. Or they start a startup which aims to make another form of real communication virtual and ‘social’ without considering the repercussions.

The humanities have always been a has-been simply because they offer no financial value. A poet does not produce a life-saving vaccine or the next Fortune 500 company.

The fundamental schism lies in the fact that engineers want concrete answers to problems, while the humanities never answers anything. It is about concepts and interpretations and I think engineers find that hard to fathom. Trust me, try it once, it is fun.

We engineers are children of the binary, decisions are absolute, choices are fundamental. That is not how the real world works. The humanities teach us to look hard into those gray areas, and how they end up shaping history. I remember in the Environmental Studies class when the professor remarked that in the case of the Narmada project, you could not simply relocate the tribals. An economist or engineer is trained to see the world in terms of resources and equations and profits and margins. Our problems are so simple. We think that by throwing more hardware at it, or building better technology things will fix themselves. That to build a dam, we can simply move the people out and give them good homes. But we have no way to measure social cost. So the moving of tribals seemed a trivial problem. But the land they live on has been theirs for thousands of generations and they associate traditions and religion with it. It would be like evicting you from your home. All technological problems are finally attempts to improve society and the context in which they are implemented is essential.

Even if you don’t want to be the decision maker or ideal citizen or a analysis spewing geek when all that your friends wanted to watch in the movie was the explosions, there is one concrete reason that you should take atleast a few humanities courses.

Writing. The Indian education system especially thrives on canned solutions for much of school. Even the technical courses in college do not require writing papers or projects. But much of real-world engineering today is a team activity where written communication is a very important skill. For all your career you will be writing documentation, making reports and presenting findings to your boss. A good command of English and an ability to deliver crisp writing can help immensely. The humanities courses will be the only ones where you will have to analyse some aspect of art or literature, critique it and back up your opinions with arguments. Since you can’t do a copy-paste in humanities (since it doesn’t have any concrete answers), it is a good lesson in writing.

Finally remember that as bits seep more and more into our lives, our cultures are framed by the file formats and user interfaces and other mechanisms that we will make. And they will enforce the way we think. Do we want to end up in Orwell’s 1984 or Huxley’s Brave New World? Facebook friends vs real friends, privacy vs sharing, customer-friendly or corporate-friendly, patent laws and other important ‘wars’ are going to start erupting. Yet I find engineers have no awareness for any of this as they sit in their cubes creating the most widely propagated products that ever existed, constantly connected via a medium whose drivers are human. All these are areas where theologians and philosophers and lawyers have been arguing for centuries, in the eternally fluid and muddy concepts of property, privacy and ethics. Except they used to be able to make these decisions before the technology spread. Now App stores and locked-in products arise everyday, social networks grow exponentially and international surveillance is easy as pie, and law makers cannot catch up, so the engineer will have to specify those decisions by product design itself. There you and I will enter into the indefinite world of humanities because these problems have never arisen before. Only someone who understands both technology and humanities can solve this, otherwise we end up with abominations like the Digital Millenium Copyright Act or Software Patent Law based on real patent laws when it doesn’t fit the software model. This requires an ability to mull over these concepts and use the various interpretations debated in the past and the present. In some literary passage somewhere may lie the perfect system you strive for. The times, they are a changin.

Posted via email from nikhil's posterous

Monday, October 03, 2011

Talk the Walk

Prelude

A few months ago, on the way back to Gandhinagar from attending DocTypeHTML5.in I wondered if it would be a good idea to walk from Ahmedabad to Gandhinagar to get home. The distance is 25km. The people accompanying me immediately shot down the idea :) but it stayed in my mind as something that had to be done at some point. So no, we didn’t just wake up at 4:30am one day and decide to walk to Ahmedabad. There was a plan. Over a busy semester I forgot about it, but in the summer I knew that the plan had to be executed as soon as I was back to college.

Are you crazy?

When I bounced the idea of a few people, pretty much all of the first reactions where “Are you crazy?” followed by refusal to accompany me. This kind of reaction was disappointing. Only two people stepped forward. One had had a similar idea in her head. The other was ready to do it. After significant rescheduling, the plan was finally put into motion on September 25, 2011. The latter had to drop out due to unforeseen circumstances.

The route

Our definition of ‘reaching’ Ahmedabad was to walk along the Sarkhej-Gandhinagar highway till Iscon Mega Mall. The Google Maps distance is 24.5km. The Google Maps walking estimate was 4 hours 58 minutes. The anticipation itself was a major stimulant.

We left the DA-IICT main gate at 5:23am. Here is a log of all the landmarks, distances, and when we reached there.

Start                  |  0.0km |  5:23
Adalaj                 |  7.3km |  6:45
Waterside              |  9.0km |  6:57
Sardar Patel Ring Road | 12.8km |  7:40
Nirma University       | 13.8km |  7:50
Gota Circle            | 15.3km |  8:25
Gujarat High Court     | 19.2km |  8:53
Gurdwara (Acropolis)   | 23.2km |  9:35
Iscon                  | 24.5km | 10:15

At Acropolis we took a 15 minute restroom break. We did not sit. If I had sat down, I probably wouldn’t have gotten up again. We were now officially in Ahmedabad, the rest was just a formality to satisfy predecided constraints.

The last 2km leg was finished in about 20 minutes. To be precise, we went up the south escalator and touched the glass door. The time was 10:15am. 4 hours 52 minutes with a 15 minute break.

The feeling: priceless!

(We took an auto back to DA-IICT after resting for 10 minutes.)

Tips

  • Don’t think about the distance, or how much is left and where you are. There is a difference between observing and thinking. We observed landmarks and kept a log, but if you keep thinking it’s 20 more kilometres, now it’s 10 more kilometres, especially when you are starting to feel the fatigue, you will want to give up.

  • Company is good – Not only is it an excellent way to pass some of the 5 hours, but it keeps the encouragement flowing. Again, avoid talking about the route, try playing games.

  • Less food, more drink – I had expected to be incredibly hungry through and after finishing the walk. This turned out to be wrong. Between 2 people the only food we had all morning was 2 chocolate bars and 4 biscuits. I don’t remember feeling hungry for atleast 3-4 hours even after the walk. So don’t bother carrying too much food (fortunately we didn’t). Carry a lot of water (fortunately we did) and some sugary drinks. Each of us had 2 litres of water, and about 500ml of mango drink. The lack of salt was noticed though, and we should have carried some salty drink like lime water. That said, even if you aren’t feeling hungry, keep snacking lightly after the walk.

  • Take care of your feet – Wear good shoes. I was initially planning to wear my Vibram Five Fingers, but didn’t because I have never walked more than 3-4km in them. I was a bit skeptical about the Saucony Kilkenny XC4 when I bought them 2 months ago, but they turned out to be brilliant shoes, never feeling uncomfortable or a burden. You will get blisters. Wear soft socks. If you tend to sweat a lot, powder your feet before you leave. Since we refused to take a break, friction did eventually catch up. I think my first blisters appeared about 15km in. By the end I had 6 reminders of the walk :) Carry flip flops to change into at the end of the walk. Your feet will love you for it.

  • When you reach the Wall, ignore it – During my first 8km run last year, I realized what I had only heard from others. The Wall exists, and it is all mental. Your body is an exceptional piece of engineering that can keep going for a lot more than a mere 25km. But eventually your mind will start cribbing and noticing the pain and say things like “I’ve already done 15, this is enough for now”. That is your Wall. Punch a fist into that wall, gather up the pieces and stuff it in a little corner. Left foot, right foot.

Awesome! Call me the next time you go

We succeeded. Objectively 25km is nothing, but subjectively it was the longest I’ve ever walked, and more than most normal people ever walk and so I consider it an achievement. When people found out, the “Are you crazy?"s were still the first question, followed by awe, followed by "Why did you do it?” and then “I want to do it too. Call me the next time you go”. Why did we do it? There was no point, no success to be achieved, no money to be won. It’s just that for me, life is about pushing myself. Where people shy away from pain, I embrace it. There is a difference between the pain of pushing oneself and the pain of real injury, and I think everyone should try for the former, but not push on till the latter. It turns out, that as soon as somebody proves it is possible, people see that and they go ‘I can do this too’ Till then, negativity keeps gnawing away, however much you explain it in terms of distances and times. The shortest answer is doing. That’s enough preaching :p

There is unlikely to be a next time. I enjoyed the journey, but there was no end goal, and there are better ways of reaching Ahmedabad :) This challenge is done, it’s time to move on.

Posted via email from nikhil's posterous

Tuesday, September 13, 2011

Life's Little Things: Chocolate

If you can afford to buy a slab of chocolate once in a while, enjoy it. Few things in life come in small packages yet have great joy inside them.
Chocolate

Life's Little Things: Board Shorts

If you tend to forget your shorts at home when you go swimming, board shorts that dry quick and can be squeezed hard are an invaluable investment.
men's board shorts-2

Sunday, September 04, 2011

Toolset

Inspired by The Setup and Pratul’s post, here is how I ‘get my work done’.

Hardware

I currently use a four-core i7 15" Macbook Pro with 8GB of RAM and a 500GB HDD. I love it. For backups I have a Western Digital 160GB hard drive. I use cheap Skullcandy earphones when I need them (I usually prefer speakers).

Operating System

I used to be on Arch Linux until I got the MBP. Now I use OS X Snow Leopard. I still run Arch + KDE on a VirtualBox instance to occasionally hack on KDE. With 8GB of RAM, both keep running snappy :)

Running OSX might come as a surprise considering my FOSS roots. But my software stack is such that it makes no difference what UNIX I use really.

Software

Considering I use the computer all day, the number of applications I actually run is tiny.

I use Firefox for browsing. I hide all chrome except the tab bar, and use the excellent Pentadactyl extension to get vim key bindings and other keyboard driven goodness to Firefox.

For viewing PDFs, I use Preview. The rare photo management is done with iPhoto. Music needs are satisfied with Clementine (my iTunes resides in the Trash), while VLC handles video.

I do use the excellent Notational Velocity for note taking and idea jotting and the like. It fast, it stays out of the way and is easy to sync if I have to.

iCal, synced with Google Calendar, is used for todos and submission reminders.

And that is all the GUI apps I usually run. Which is why it doesn’t matter what UNIX I use, since most of my work is in the shell.

Office suite you say? I find Google Docs suffices, to the point that if somebody sends me MS formats, I upload them to Google Docs. The Gmail web interface is also unbeatable so mail stays there.

Accessories include Dropbox, Temperature Monitor Lite, gfxCardStatus to manually control which graphics card is in use, ShiftIt to position windows, afloat to allow ‘Always on Top’ like KWin, Growl for notifications and Tunnelblick for VPN management.

Now we come to the terminal. My terminal emulator is iTerm. I have only one window running maximized, with tmux acting as my ‘window manager’ for shells. It has a slightly customized statusbar, with the solarized colour scheme. The shell is zsh with a custom zshrc based on stuff I pick up around the Internet, with the zsh-git prompt.

This exact same terminal configuration is also available in the Linux VM (including vim configuration) so that I don’t need to switch my behaviour for the different OSes.

For IRC I use irssi although I use it as a total newbie.

And the rest of my day is spent in vim. I do all my long writing in vim — code, articles, blog posts, configuration files — everything. I use the molokai theme rather than solarized for the editor.

Vim plugins

First Tim Pope’s pathogen is indispensible to easily manage other plugins.

a.vim is a convenient little script to toggle between headers and sources.

ack.vim allows the invocation of ack from vim and presents the results in the Quickfix buffer. I map the keystroke ‘sd’ to ack.vim.

fugitive is useful for Git integration with vim, but I don’t use it that much yet except to do blames.

fuzzyfinder is another indispensible script for me. I map ‘sf’ to fuzzyfinder so I can quickly invoke that.

Other plugins I use include nerdcommenter and vim-surround.

My Dream Setup

I would love a standing desk in my hostel room with an external monitor connected to my laptop, the way I worked at Mozilla. I am considering buying a Netgear Ultra 2 NAS to have redundant storage and sharing. Otherwise the MBP works great and is sufficient for now.

Posted via email from nikhil's posterous

Monday, July 25, 2011

Harry Potter and the Deathly Hallows Part 2

I first saw DH2 on Friday night, and my thoughts after watching it were:

Screen_shot_2011-07-20_at_11

On Wednesday night I saw it again, determined to find out why I disliked it so much, and whether I was just being too hard on it. Interestingly, most Potter fans seem to have liked it this time, which was not the case before. Mike Patterson though has this interesting writeup pointing out in very specific instances why the movie was bad. I myself have only raised my rating a couple of notches. Seen independently, the movie is decent, but after multiple readings of the book and ten years of association with Harry Potter it is plain bad.

To get the good parts out of the way, the Prince’s Tale was beautifully done, Alan Rickman brings his marvellous portrayal of Snape to a great ending. The movie was visually pretty good, and Hogwart’s defending itself was well done, though a bit artificial in the performances of the professors.

But in the bid to add action and drama to the movie, certain themes of the book were pushed aside, and that made this movie just another action thriller. There was some weak acting in places and just terrible situations too, but to focus:

Imperio

We start at Gringotts and Harry casts the Imperius Curse on the goblin. To lend some perspective, use of the Unforgiveable Curses is akin to murder in the Muggle world. Harry has demonstrated countless times before that he is not comfortable with hurting others (Expelliarmus anyone?). In fact, it is Griphook who has to put the idea in his head.

“Act now, act now,” whispered Griphook in Harry’s ear, “the Imperius Curse!” – Harry Potter and the Deathly Hallows, Page 531 of the US edition

and

And another memory darted through his mind, of the real Bellatrix Lestrange shrieking at him when he had first tried to use an Unforgivable Curse: “You need to mean them, Potter!” – Harry Potter and the Deathly Hallows, Page 533 of the US edition

The use of Imperio in the book is an act of desperation, because certain things are simply evil, even in the magical world, and making a person go against his will is one of them. In the movie, we aren’t even shown Harry’s face as he casts the spell, and when Ron casts it again in the depths of Gringotts, he does it trivially. Obviously you cannot explain thought processes on screen, but a touch of hesistation, an expression, goes a long way into conveying the seriousness of the act. After all the goblin does die in the movie due to the curse.

Wands

Wands are the crux of the books, the one way humans get access to magic. They are ‘alive’, and bond and grow up with the wizard. Wands are respected, even Death Eaters don’t just destroy their enemy’s wand. The breaking of the holly and phoenix feather wand is immensely important. That wand has kept him alive 6 years. Its breaking is also symbolic of how Harry has to sever connections with Voldemort to defeat him. The re-joining of his wand is the last thing Harry does in the book, signifying a new beginning. Where is the holly wand in the movie?!

Now to turn to the Elder Wand, the Deathstick, a wand with more lore than any other. The scene in the Headmaster’s office in “The Flaw in the Plan” is to show that Harry has the selflessness to give up that power and accept Death, but he still does not destroy it because it is an artifact, and Harry realizes that and puts it back in the grave, aware that its power is not really neutralized just yet.

In the movie, he just snaps it and throws the pieces away. You DO NOT snap a wand!

The Kiss

“Is this the moment?” Harry asked weakly… – Harry Potter and the Deathly Hallows, Page 625 of the US edition

Ron and Hermione do not kiss because they destroyed a Horcrux! The Kiss serves multiple purposes in the book. Tension between Ron and Hermione has been brewing since Book 3. Ron has always been attracted to Hermione, but she holds back, unsure of Ron’s seriousness. Book 6 and 7 are about Ron maturing and starting to think about others. Ron abandoning Harry and Hermione and then returning is the test of his growth.

Meanwhile Hermione has always been the one to watch out for others. She also has a fanatical desire for equality of all species. Rowling clearly wanted to point out against discrimination in our society, and what better way than to use a Muggle-born girl with no pre-conceptions. S.P.E.W. is just her being formal, but all through Book 4-7 Hermione has stood up for the down-trodden – even when Kreacher is lying she supports him.

Ron remembering that the house-elves need to be rescued flips the switch. It convinces her that Ron truly has changed and is capable of the compromises required in a relationship. Second his acceptance for something she supports is crucial for her to commit.

The Kiss was not spontaneous, it was building up for 4 books. The only thing spontaneous was the absurdity of the situation. All of this was lost in the movie.

The Flaw in the Plan…

was badly dealt with.

So there is the most powerful wizard of all time, he has the most powerful wand of all time, WHY would he try to rip out Harry’s face with bare hands?

And why would you show both Bellatrix’s and Voldemort’s bodies as some kind of container for their souls, so that once the curse hits, they just disintegrate? Voldemort was after all, only human and the falling of his frail body with “mundane finality” was supposed to indicate this.

Then the theme of love and remorse that is a cornerstone of the book is never raised. That Voldemort’s spells are no longer binding on anybody because Harry has effectively ‘pulled a Lily’ on everyone is skipped. That love and sacrifice defeat Death is ignored. I would have loved to see Voldemort scream “Accidents” like he does in the book, to show his ignorance of “house elves and children’s tales, of love, loyalty, and innocence”.

Expelliarmus and Avada Kedavra, Harry and Voldemort’s trademark moves were for a reason. For Voldemort it represents his conviction that Death is the worst damage you can inflict, while Disarming fits Harry’s character of not wishing death even to his attacker. In the movie the spells were never uttered (and we know that Harry is bad at non-verbal spells). The spells seemed to be different too, since Avada Kedavra does not disintegrate the body.

Dumbledore

Ah, were to start with this. Book 7 took this great great man that was Albus Dumbledore and tore him down, producing the flawed human every one of us is. Harry and Dumbledore are two characters shaped by death and Dumbledore’s reaction proves opposite to Harry’s reaction for a while. Dumbledore is the man who campaigns for equality, non-discrimination and all other things that are Voldemort. He is the character who brings out the deeper flaws in the wizarding world to casual readers. And contrary to being all this through wisdom, Rowling gave him these attributes by making him a man filled with remorse.

Rowling is trying to show throughout the books is that its the choices that matter!

If that wasn’t enough, Dumbledore is linked to the Hallows and Horcruxes and essentially scripts this entire storyline in a very high-level manner. His theories about the connection between Harry and Voldemort and how Magic is connected to conscious phenomena like Love is the only channel the reader has of deeper insights into the Wizarding World. To drop all mention of Dumbledore in the movie was representative of Hollywood’s bid to add only action and bling to known blockbusters, creating movies that do not make the reader think or disturb them.

Many readers judge of the power of a book by the shock it gives their feelings. – Henry Wadsworth Longfellow, Kavanagh, Chapter XIII.

In re-reading this article, I feel I haven’t been fully able to convince the reader due to a lack of writing skills. I’d take that up in specific comments if any :)

Summing it up the books are about death and love and innocence and good and evil, but also about moments and small scenes that create intricate characters in our minds, and frame unspoken laws about the world of the book. You cannot make a good movie without keeping those in mind.

Posted via email from nikhil's posterous

Friday, July 01, 2011

Simulating the Facebook Wall in Google+

Its been two days of Google+ and enough articles to fill a couple of
books, so I'm not going to say anything about what I think of it and
all that.

But a couple of friends have been wondering how to do something like
the Wall in Google+. The fine granularity of sharing means
that you can directly use your Stream as a wall in G+ which is very
convenient. If you are a programmer think of it in terms of Pub-Sub
with highly configurable channels.

To write on someone's wall, just create a new post, and share it only
with them. That way only that person sees it in the stream
which is effectively what a wall is. But a mutual friend can see the
wall post in Facebook. How do you do that in Google+? That is what
a circle is for. I think the real value of circles is as disposable
ribbons around friends. You can pull and push people into them as
required,
create temporary circles to share among really small niches or over a
set of overlapping circles and so on.

Tip: LIke Facebook uses @ to mention names, Google+ uses, quite obviously, +

What I would love to see is the ability to put one circle inside the
other and so on, so that information shared with outer circles leaks
to
inner ones, but not the other way around.

Posted via email from nikhil's posterous

Tuesday, June 14, 2011

6: Time for a change

It’s been a month now since the semester is over, but when you are sitting in California, and visiting amazing places on weekends, writing blog posts isn’t the highest priority :) But the 6th semester deserves 10 blog posts and atleast one is mandated.

6 not only had a personal highs, but in general wrought a lot of changes. I’ve begun taking a lot of pictures this semester. I always thought it was stupid of people to shoot images like crazy, but it turns out that photos are a very good way to trigger memories about past events. I also started scribbling down little notes about memorable days. Not only are they a great resource when writing posts a few months later, but you can capture your state of mind at that point which is impossible later. This is an outcome of the approach to the end of the college and seeing the emotional situation of the seniors during their final semester.

I’ve been torn between making this post a chronicle of events or focusing on deeper things, which I don’t write very well about. Apologies to the two friends whom I chided on not writing good enough entries. It is hard work :P.

Even semesters usually start with Synapse, and boy was this year’s Synapse blazing. The only reason this paragraph exists is so I could use the word blazing. But Synapse does not fit where this note is going, although it served as the beginning for many of the things that happened.

Life this semester was like American television shows, one larger story arc with lots of action in between :) That arc is of course trying for internships on two sides of the world. On the 22nd of March when Mozilla hired me past midnight – that was an EPIC moment! Living in Silicon Valley, working on Firefox and getting paid for it is a dream I never even considered, and it all became true in two hurried months of interviews with the nicest people, and visa procedures that make you an expert in filling up forms. I guess, now that I’m hired, I can reveal two interview gaffes I made. One of my interviews was during conf.kde.in when I was in Bangalore, with my Ahmedabad phone number. This meant I was on roaming. I conveniently forgot about the charges it entailed and was surprised when the call dropped half way through discussing hash tables. The second ‘disaster’ was on the final interview. Due to some time-zone blunder I was woken up by the interviewer and proceeded to give the interview in a most uncomfortable manner. That I still got the job seems like a bit of a shock now. (Note: Do not let the interviewer in on the fact that you’ve just woken up. Continue asking questions about the company until you are awake enough to deal with the technical parts.)

Most of my college life has been an attempt at improving some or the other part of my personality. Being more impulsive has been at the top of that list. I used to be too much of a planner with an inbuilt cron daemon and all that, and if you continue with that you can miss a lot of the fun parts of college life. With the switch I’ve lost a lot of sleep, but it was well worth it. The outcome – memorable all-nighters which had nothing to do with studying, going to a movie the day before the exam because it was a three day international film festival and spending a lot more time away from the computer. I now think this is also an attempt to break down every stereotype associated with me in college, and since the t-shirt incident last year, I’ve been performing brilliantly at it :)

As if determined to give me more reasons to be impulsive, India put on a massive World Cup win! I don’t really like cricket, but the crazy atmosphere in college, the constant cheering and the euphoria when the cup was won, was absolutely remarkable, and I think the Nikhil of yester-year would not have attended the matches.

The other change has been to experience as many things as possible, which means eating in new places, travelling around, attending just about everything I could. This has been at the cost of certain responsibilities, which might be seen as bad by others (ie. not holding enough OSID sessions) but I’ve finally decided that it is more important for me to be personally satisfied with what I am doing than to conform (again) to those stereotypes that the old Nikhil has built up.

I do not mean that I want to shirk my achievements. It feels good to know that you’ve set certain examples that others follow and to be a guide when jumping into the difficult world of FOSS development. This year, over 8 students were selected for Google Summer of Code from DA-IICT, and to know that me, Aditya and Dinesh had a part to play in it felt really good.

While I was having fun, the KDE India community ticked off its dream of having a conference here. conf.kde.in was a very special occasion because it was the first time the KDE community had a India conference. Pradeepto and Shantanu and others in Bangalore put in a ton of effort , and the eV provided full support, which led to a wonderful conference with well known KDE speakers and some great food :) The response was tremendous and some of the effects are already visible with the number of Summer of Code and other contributors who were conference attendees. My own contributions have been at an all time low and it seems it will be that way into the summer, but the motivation has not dwindled only due to the wonderful people.

Academically this semester was a personal disaster. I had really easy courses for the most part, but I did not like the amount of effort I put in. The parts which I thoroughly enjoyed, I did really well, but for the most part I was a pig-headed ass, and that has to change. I did get a 9.4/10 overall though :)

The software engineering course was Shakespeare all over again. I feared it, then I mocked it, then I rebelled against it, then I just mis-quoted it in desperation :), and in hindsight I respect it. It was a hard lesson in managing a team, getting work done and staying with one piece of software for four long months and polishing it. It proved to me that the hacker style of coding is not enough on its own to produce good software.

Finally, in my ‘thoughts document’ (see SEN ke side effects!) that I mentioned at the beginning, there are certain names of people that have affected or inspired me in college. While writing this I’ve been deliberating on whether now is a good time. It’s not, but two groups of students do deserve a special mention:

  • The Press Club – We’ve had an excellent year with readership through the roof and high-quality articles. The batch of 2007 has been the principal force in rejuvenating the magazine and the main source of the more argumentative and well analyzed articles. At the same time you’ve been humble mentors and this is getting really fluffy so thanks a lot is all I’ve got to say.

  • Special Ops – Ah, what to put here about the weirdest bunch of juniors and some batchmates, some of whom I got to know only this semester? Thanks for letting me enjoy the World Cup, listening patiently to my PJs, playing TT, and not treating me like a senior. Now just stop calling me bhaiya and we are cool. Also remember, you are all 10 pointers :)

There are other people, but I don’t want to embarass them and they don’t come under any group :P You know who you are.

If you’ve made it till here and know me, you may be surprised at how this post has played out, considering I’m the un-emotional, hug-less boy. Do NOT raise this slew of changes in a face-to-face discussion with me (especially you Mama and Baba :)), in some things I’m still closed source.

Posted via email from nikhil's posterous

Monday, May 02, 2011

Interning

DA-IICT 3rd year students usually do an internship in the summer. Good industrial internships are always hard to come by, although the situation is way better in IT than in other, more resource-intensive disciplines. 10 interviews, a hundred or so e-mails and lots of forms later this is part guide, part my internship search story. The first thing you’ve to decide is what kind of company you want to intern at. Most companies will have menial code jockey jobs which you don’t want. This is my first blog post typed out on the n900 for the most part while waiting for a flight home at Ahmedabad airport. What a keyboard!

Why not a GSoC again?

Having over two years of FOSS contribution and 7 years of usage and having done a GSoC previously, I could have done one again. While a GSoC is an invaluable experience, it is not the same as an internship. GSoC is excellent at improving e-mail communication skills and long distance collaboration and giving a feel of the open source development style. But it is not the same as going to office, talking to people, having lunch together and hanging out. In addition internships usually will be in a city or country other than the one you live so it can be a great excuse to explore a new place. So if you’ve already done a GSoC, getting a different sort of experience is way more important in my opinion. So I didn’t apply at all this year. Besides I was confident that my experience would serve me just as well to get into the kind of companies I wanted.

Have a good CV

Spell-check, design it well and put in only relevant things. If you are a good singer don’t put that in just to have stuff to show in a IT company. On the other hand positions of responsibility should always be highlighted. FOSS contributions top the charts in startups and other ‘cool’ or cutting-edge companies.

Start early

By luck or resolve my best move was starting to look for internships in December for an intern to start in May. Keep in mind that HR departments are busy places, resumes can take time to process and sometimes do get lost. Wait for a week for a reply when you submit your CV, then ping them aggressively on IRC, Twitter and e-mail to ensure you aren’t forgotten. Interview procedures can take upto a month and for international interns there are visa procedures that take time. Finally you are likely to get rejected by the first few and you should have time to apply for more. In any case companies with established internship programs have information available on their websites and start each season with prior planning.

Decide what you want to work on

The first two companies I applied to were Google India and RethinkDB. The RethinkDB folks were very positive about international interns. I had two interviews in early January which went ok. I was rejected, which in hindsight I know was due to me not really being passionate enough about what they were doing. So I narrowed down to the two specific interests I currently have.
  • Javascript engines and low level APIs
  • concurrency, distributed networking and web-scale computing.
and decided that I would only approach companies based on these work areas.

Stick to a few companies.

Interviews are always stressful because you have to think on the spot. If you are trying internationally they will be at very bad times (most of mine were at 6am and 10pm). Companies hiring solely on phone interviews will usually take atleast three interviews. In addition you will have to prepare atleast a bit for them. This adds up to a lot of things to do. So stick to a few companies at a time. Prioritise which company you want to work for if hired by multiples companies. When you agree for interview times, make sure you convert timezones properly and that you don’t have any appointments more important than the interview at that time. Finally, remember you have a life too :) I gave one of my interviews at conf.kde.in, and another during Synapse. At such times be very careful with scheduling.

Research

Off-campus internships (ie. ones you find on your own) are the way to go. The college will always aim for what is good for a majority of students, or towards established companies. But if your area of interest is niche you can do a much better job looking on your own.
Try to find out as much as you can about what interns do in the company. With some searching you can usually find blog posts of former interns which can be very informative. Talk to people in the domain. If you are a FOSS contributor ask fellow IRC users about intern opportunities or experiences.
Based on my areas I finally applied to:
  • RethinkDB
  • Google India
  • Directi
  • Opera
  • Mozilla
I was very lucky to meet a former Mozilla intern at the MIT Media Lab COEP workshop in late January. Without that I would never have thought of it as I was unaware of the Mozilla Foundation and Mozilla Corporation dichotomy.

Be confident, but ready for rejection.

During the interview what matters most is being able to keep up a continuous stream of conversation going to show that you are capable of thinking. So if you tend to think mentally for 15 minutes and then produce the answer in a flash, it would be good to think out loudly. If you are confused, clarify the question, it does not penalise you. Remember that in interviews no one expects perfect code, and classes and documentation. If you miss edge cases thats fine, performance – not an issue until the interviewer actually asks you for a better algorithm. Graph and string algorithms are a favourite of interviewers. For algorithms the TopCoder tutorials are a good read. For C++, the C++ FAQ is invaluable. In fact I suggest always having that page open during the interview. For C++, templates and virtual functions tend to be a question spot. In addition, know the warts and good points of your favourite language. If you have FOSS projects, be ready to explain what they are, and how you implemented them. One favourite interviewer question is, “What was the hardest part to implement?”. In such a case be prepared to explain in as general terms as possible, since the APIs you use may not be something the interviewer has experience with.
A typical telephone interview will last 30 minutes to an hour. Half of that time will be the technical interview and the other half when you can chat with the interviewer. A full recap of my interviews with each company are beyond the scope of this article, but suffice to say that I was lucky to have extremely nice interviewers. Google insists on algorithmic questions which you’ll usually answer via a shared Google Docs. Remember that in a phone interview it is important to know how to approach the problem. Since you have access to a computer, once you know what to do, you can look up your existing code or use the internet. Just keep discussing the approach on the phone and speak with utmost confidence. The interviewer may try to misguide you. For Mozilla and Opera the interview was purely on former experiences and some C++ stuff. Use the chat time later well. Good questions to ask are about prior interns, what they do, how they find the company etc. If you know their name before the interview, see if you can find out about them on the internet.

Get to know and learn from the interviewers

My most memorable interview was the fourth one with Mozilla when due to some daylight savings confusion I was woken up by the interview call. Desperate to get myself sane, I asked him a few questions before I let him start the technical round. After that I spent 45 minutes discussing spidermonkey and Mozilla’s general plans with Luke Wagner. It was a very humbling experience. If you can show the interviewer that you are passionate about the products and do you homework, there final review is much more likely to be glowingly positive. Finally they can tell you about some implementation features, constraints etc. that can be interesting to know about even if you never join that organization.

Congrats, now get to work!

After all this, I hope you get selected somewhere. I can’t really write the part about how to handle it if you get rejected. So what happened to me?
The response order was:
  • RethinkDB reject – January 16, 2011
  • Directi reject – March ??, 2011
  • Mozilla accept – March 22, 2011
  • Google accept – March 25, 2011
  • Opera reject – March 28, 2011
based on my interview experiences, stipend and location I opted for Mozilla Corporation! When I got the confirmation on March 22, it was unbelievable but I guess all the hard work paid off. The Mozilla folks have been really nice and punctual throughout the process, and damn they know how to take care of their interns :) I think a series of posts will of course pour out of me regarding the internship in the coming months. I will be working at Mozilla HQ in Mountain View, California from next week to the end of July. My first assignment is typed array implementation improvements in JavaScript so Firefox can perform WebGL, audio/video and binary data better. With Mozilla I found a great, FOSS friendly company, interesting work dealing directly with JavaScript engines, a new city to explore right in Silicon Valley and going to the United States of America for the first time ever. I couldn’t have asked for more :D

A note to DA-IICT students specifically! Our placement cell has an odd policy where when you apply for one or more internships through the placement cell, you are bound to accept the offer of whichever company accepts you first. So if a ‘better’ company delays their interviews, and a ‘lesser’ company hires you already, you are screwed.

Saturday, April 30, 2011

Why I love open source


Someone who found my code interesting, can use it as a launchpad and take it ahead!

Wednesday, March 23, 2011

Code reading and Bug fixing 101

Summer is here, and Google Summer of Code is on its way. The biggest hurdle new contributors often face (after compiling trunk ;)) is to get their head around the project they would like to work on, understanding how it works, where the parts fit in, and how to fix bugs or make improvements. Speaking from my experience, it took me the better part of a month to understand how KWin worked before I could actually hack on it for Season on KDE.

This is my attempt to explain how I approach new code and the tools I use. To demonstrate, I am going to try and fix this bug in Amarok. I am sorry for stealing a Junior Job.

The most important thing when working on existing code is:

DO NOT modify existing code that works, even if you absolutely have too1


This means, avoid changing function signatures, variable names, and especially surrounding code that does not affect you. You may inadvertently introduce bugs.
That said, remember that you are using a version control system, so code fearlessly. The best way to understand new code conceptually is to liberally insert some kind of debug/print statements all over relevant functions. With that in mind, let’s start.

Understand the problem

The bug report says:

When you filter all items in Amarok, a warning notice is shown that “tracks have been hidden in the playlist”. However, if you filter, and then delete all results of that filter from the playlist, this warning is not shown

Reproducible: Always

Steps to Reproduce:

Set a filter
Remove all matcheS
This is a fairly straight-forward bug with well written steps to reproduce. If not, its best to ask questions on the bug tracker or talk to someone more experienced to understand what the bug/feature actually requires. The next step is to reproduce the bug. If you cannot make the bug occur, you have no way to prove that your changes fix it. Again, try to reproduce bug in the bleeding edge version of the project. Otherwise it has already been fixed. So let’s add some tracks to the playlist, put something in the filter text. Observe that if you put a pattern that doesn’t match any track, you get the warning. Now change the pattern to match a few tracks. Remove those tracks from the playlist. No warning! This is what we have to fix.
Up to this point, the process has been just what a user would do, now its time to enter the code.

Where is the problem?

The Amarok source tree is pretty large. By convention, all source code is in the src/ directory. This is true for almost all open source projects. But what now?
The easiest way to find out the source of the problem is to find a nice clue in the interface that gives us a good idea of what the relevant file will be called or where we can make a change.
At this point, let me introduce a tool called ack, which is grep optimized for programmers. I won’t bother describing the features, but trust me, you should be using it!
Let’s enter the Amarok source tree, and try to find “Warning: tracks have been hidden in the playlist”. Why so, well, since it is being hidden and shown, it obviously has something to do with our task.

$ cs amarok
$ cd src # all code is here
$ ls
...
playlist
...
$ ack "Warning: tracks have been hidden" playlist/
playlist/ProgressiveSearchWidget.cpp
45: m_warningLabel = new QLabel( i18n("Warning: tracks have been hidden in the playlist"), this );

Notice a few things. First, I ran the search only on the playlist directory. You could have run it on src and it would just have taken more time. But its good to do a ls on src because knowing the directory structure is a good way to get the highest-level overview of a project. playlist is a suspiciously strong pointer to our bug. So let’s run it on this.

This seems like a good start, there is a label being created that has the message. But we need more information. So fire up your editor/IDE and go to line 45 of src/playlist/ProgressiveSearchWidget.cpp. Knowing nifty utilities in your editor is a good investment, you absolutely must know the shortcut to jump to a specific line since line numbers are used all over programming, in compilers, editors, and humans talking to each other. With vim it’s:

$ vim playlist/ProgressiveSearchWidget.cpp +45

Now, let’s see where this label is being manipulated. For this we need another useful editor feature, to find instances of symbol under cursor. QtCreator or KDevelop allow you to just right click on the variable name and find all uses. With vim I hit the * key.

void ProgressiveSearchWidget::showHiddenTracksWarning()
{
m_warningLabel->show();
}

void ProgressiveSearchWidget::hideHiddenTracksWarning()
{
m_warningLabel->hide();
}
And there is our first break. A pair of functions which show or hide the label. Continue this technique of ‘follow the useful symbol’. Let’s see where showHiddenTracksWarning() is being called. In this case, its just above the definition.
void ProgressiveSearchWidget::noMatch()
{
...
if( m_showOnlyMatches )
showHiddenTracksWarning();
}

void ProgressiveSearchWidget::showHiddenTracksWarning()
But if you try to follow noMatch(), it won’t be in this file. Running ack again:

$ ack 'noMatch' playlist/
playlist/ProgressiveSearchWidget.h
130: void noMatch();
playlist/ProgressiveSearchWidget.cpp
216:void ProgressiveSearchWidget::noMatch()
playlist/PlaylistDock.cpp
144: connect( m_playlistView, SIGNAL( notFound() ), m_searchWidget, SLOT( noMatch() ) );

At this point, I assume you are smart enough to follow the code on your own, because pasting every sample here is annoying :) If you see playlist/PlaylistDock.cpp, then m_playlistView represents the playlist in some manner. m_searchWidget on the other hand is the place where the user types the filter. So when the playlist can’t find any matches, it tells the search widget, which then shows the label!

Except, something is going wrong in the exact circumstances of the bug. One possible explanation is that noMatch() never gets called. Your first idea might be – lets call notFound() when tracks are deleted and be done with it. But let’s dig deeper.

So what is m_playlistView? Simple, open the header file for PlaylistDock.

PrettyListView* m_playlistView;

Hmm, now where might PrettyListView be? At this point, you can use your fancy IDE, but I am going to introduce another ancient UNIX tool – find. When programming, it is helpful to generalize assumptions about how the code is organized and named, since it makes navigation a lot easier. If you’ve seen even the Amarok code that is just in this article, you can see that classes usually map one-to-one to file names.
$ find -iname 'prettylistview*'
./playlist/view/listview/PrettyListView.cpp
./playlist/view/listview/PrettyListView.h
find takes a lot of powerful options, but here we say

Find all files from the current directory (src) downwards, whose name (-name) matches the pattern ‘prettylistview*’, but ignore case (-iname)

and there you go, open PrettyListView.cpp and search for notFound. So notFound is emitted by the PrettyListView::find method, which itself is incidentally connected to ProgressiveSearchWidget::filterChanged (connected in Playlist::Dock::polish). Here is how our mental model goes till now:


Mental model

When the user types something, ProgressiveSearchWidget::filterChanged is being invoked, which is triggering PrettyListView::find. When find sees that no tracks are visible, it emits notFound. This triggers ProgressiveSearchWidget::noMatch which shows the warning label.
With some more effort, you will also find that PrettyListView::find is only called due to filterChanged. We can now use this knowledge to figure out why the bug happens.
Deleting a track does not change the filter in any manner. So following the call chain, noMatch never gets called when tracks are deleted to re-evaluate the situation!


The solution

The obvious solution is to somehow call PrettyListView::find manually when tracks are deleted in the playlist. But how will we know that? We will again use some GUI hints. Tracks are deleted by right-clicking them and selecting ‘Remove From Playlist’. If you ack this, you will find the action triggers a removeSelection() (playlist/view/PlaylistViewCommon.cpp). The type of the receiver is just QWidget, so it would be a hassle to try and find out the type of parent, but there is only one definition of a method called removeSelection() related to playlists. It is in PrettyListView. At this point, you suddenly feel empowered as the solution clicks before your eyes.

As soon as we remove the tracks, we can just call find() again and we will be done!

A fundamental constraint that inhibits us is the loose coupling made possible by signals and slots.
PrettyListView is unaware of ProgressiveSearchWidget and its properties.
All it knows is that it is expected to emit certain signals (found/notFound) and things happen. PrettyListView also does not have direct access to whether items are being filtered or not. These things are passed on to it from the filterChanged() signal’s arguments.
At this stage, I hope that you now have a good idea of how things are connected. For a little indepth understanding of how things are playing out see 2.

With this in mind, there are atleast 2 solutions that come to mind. Our task is to somehow force the filter action to be performed again on the view so that it emits the relevant signals. Unfortunately the view itself does not have access to the showOnlyMatches attribute present in the dock, and in the SortFilterProxies. We can,

1. Use PlaylistDock, which has access to the search widget

A roundabout method I did first, involving:
  1. adding a getter, ProgressiveSearchWidget::currentSearchFields().
  2. Connecting to the controller’s (The::playlistController()) changed() signal, a custom slot in Playlist::Dock called slotReapplyFilter().
  3. slotReapplyFilter() calls PrettyListView::find() again with relevant arguments.

2. Make the view store showOnlyMatches

A much simpler three line change.
  1. Add a bool m_showOnlyMatches to PrettyListView.
  2. When PrettyListView::showOnlyMatches() is called, along with passing along the value to the playlist, we also set m_showOnlyMatches.
  3. In PrettyListView::removeSelection(), call PrettyListView::find() since we now have complete knowledge.

Programmers exchange changes in code with something called a diff, or a file which only logs the changes made in the code.

$ git diff
diff --git a/src/playlist/view/listview/PrettyListView.cpp b/src/playlist/view/listview/PrettyListView.cpp
index cd650f6..e81d396 100644
--- a/src/playlist/view/listview/PrettyListView.cpp
+++ b/src/playlist/view/listview/PrettyListView.cpp
@@ -194,6 +194,8 @@ Playlist::PrettyListView::removeSelection()
QModelIndex newSelectionIndex = model()->index( firstRow, 0 );
setCurrentIndex( newSelectionIndex );
selectionModel()->select( newSelectionIndex, QItemSelectionModel::Select );
+
+ find( The::playlist()->currentSearchTerm(), The::playlist()->currentSearchFields(), m_showOnlyMatches );
}
}

@@ -912,6 +914,7 @@ void Playlist::PrettyListView::updateProxyTimeout()

void Playlist::PrettyListView::showOnlyMatches( bool onlyMatches )
{
+ m_showOnlyMatches = onlyMatches;
The::playlist()->showOnlyMatches( onlyMatches );
}

diff --git a/src/playlist/view/listview/PrettyListView.h b/src/playlist/view/listview/PrettyListView.h
index f22a7c8..612be0b 100644
--- a/src/playlist/view/listview/PrettyListView.h
+++ b/src/playlist/view/listview/PrettyListView.h
@@ -139,6 +139,8 @@ private:

QTimer *m_animationTimer;

+ bool m_showOnlyMatches;
+
public:
QList<int> selectedRows() const;
};
Since this is a minor patch, I could just commit this change. But I’m not going to for two reasons:
  1. You don’t have commit access, so I will show you how its done in that case.
  2. This is not code that I have worked with before, so however small, it should go through review. The reason is that I may have inadvertently affected the system due to incomplete knowledge. This is were unit and regression tests can also come in handy.
So let’s first get our diff into a file

$ git diff > /tmp/amarok-bugfix-260352.patch
Now hop on to reviewboard, and submit it. (Don’t actually do it, I’ve already done it!). Here is how the final submission looks.
Now wait for somebody to reply or commit on behalf of you. That is it! Your first bug fix.

Code reading only gets easier as you go along. It does not involve complex equations, but instead mentally executing the program just as a computer would. The catch is to be able to go from the low level details to creating the software architecture in your head, and watching the messages flow through the program. You must know your tools really well since they are a big time-saver.

To summarise, the following usually help to get a good idea of the code and allow you to fix bugs or add features.


  1. Use UI hints
  2. Use debug statements where required.
  3. Sometimes purposely crashing a program (assert(0); anyone?) is a great way to see what code-path is being followed.
  4. Follow the code along, until you can build a mental model.
  5. Use the mental model to figure out multiple solutions.
  6. Implement a solution.
  7. Test it.
  8. Submit for review or commit.

I hope this post has been useful. If you do wish to continue participating in an open source project, it is a good idea to spend the first few days just glossing over various parts of the code to get a feel of the system. Then you can go into your little section and get comfortable.



  1. except when really required


  2. If you don’t understand what I say in this paragraph, accept it at face value and continue. There is a powerful design pattern called Model-view-controller that allows separation of concern between the playlist contents, modifying them and drawing them. This is embedded into Qt using the various Item/View classes. Amarok uses this extensively. (probably one of the biggest uses of Model View within KDE?) The PrettyListView is just deciding how to show and draw the tracks, which are actually stored in a set of models. Similarly a Controller will often modify the models as required, and the changes will automatically show up in the PrettyListView.


Wednesday, February 16, 2011

Why you should be at conf.kde.in

conf.kde.in is happening in Bangalore from 9th-13th March. This is a golden opportunity for students to have fun and learn some really interesting things that no college or class can teach. It is also a chance to form friendships that last forever.

If you don’t like long posts: here is the gist.

  • Short term benefits – a great time and a cool t-shirt.
  • Long term benefits – create something awesome, lots of friends and an impressive CV that recruiters will notice.

Remember that feeling you had the first time you made a paper boat all by yourself and set it on the water? Or the time when you sang really well on stage and a hundred people gave you a standing ovation? With KDE, its possible to create beauty everyday!

When I first started using Linux in 2004, KDE 3.2 was an eye-opener about what truly functional and powerful computing could be. It was liberating. But the real magic of KDE is in its people, highly talented, motivated and very warm individuals with a lot of free hugs. So come and join the community. You don’t have to be a top-grade programmer, a really great designer or a Indian language expert to enter. At KDE we welcome everybody who has the passion to improve the computing experience for millions of people.

If you are a programmer, at conf.kde.in you have a chance to take away intimate knowledge about working with technologies like Qt, a cross-platform library which allows you to create high-quality applications on Linux, Windows, Mac OS, Symbian and even Android. With so much web and social and information, you might want to make use of KDE’s excellent Nepomuk framework to create semantically aware apps that can look at things like humans. Or the lab sessions will have you get started with submitting bug fixes for KDE in no time.

If drawing and painting is your forte, we have sessions to get you contributing your skills to open source applications and improving the KDE look and feel. You could create the next UI paradigm and dominate the world! :)

A billion people are waiting to use computers, and one of the things stopping them from having cheap, affordable machines is the lack of English literacy. So if you know more than one language, you could jump in and translate applications to Indian languages and bring a smile to some kid, and make his future!

Don’t think that as a student you lack the qualifications to attend. A HUGE chunk of KDE is made of students, with even teenage contributors! I myself am just a 3rd year undergraduate. We encourage students through programs like Google Summer of Code, Season of KDE and Google Code-In for high-school students. conf.kde.in is here to guide you even if you have never programmed before. We have excellent talks for all levels, by notable members of the KDE community. We also have interactive lab sessions where you will get to hack and explore more code than you will ever do in your college courses :P

Make sure you drag along your teachers too. They can be introduced to the educational tools that make KDE such a great platform to learn new things on. Whether its astronomy or jigsaw puzzles or Ph. D. level computer courses, KDE has applications for them to make their teaching more tangible!

Student passes are Rs. 500 (for all 3 days, including lunch), teachers can register for Rs. 700. For others its Rs. 900. Register online before 25th February to attend conf.kde.in. Although you can register after that, even on the spot at the day of the conference, it will be more expensive later (Students: Rs. 700, Teachers: Rs. 900, Normal: Rs. 1200). Remember to enter discount codes to get a discount, and get your college ID card to the event.

  • Student discount: KDEIN_DIS_STU
  • Teacher discount: KDEIN_DIS_TCR

If you need a letter to get permission from your college, we can arrange that.

PS. If you can get a laptop with Linux on it to conf.kde.in, you can have twice the fun :)

conf.KDE.in badge

Posted via email from nikhil's posterous

Sunday, February 06, 2011

QHttpServer: Web Apps in Qt

Qt is a great GUI toolkit, but it is also an entire C++ standard library waiting to be used for other tasks. In addition the network module is really powerful. I’ve been playing around with node.js for a while now, and realized that Qt’s default asynchronous nature maps over perfectly to create a event-based web server. To make things better, Ryan Dahl’s small and fast http-parser is freely available. So I just combined the two, and here is QHttpServer.



Here is a ‘web-application’ written completely in C++/Qt. You can even try it out.



#!cpp
#include "greeting.h"

#include <QCoreApplication>
#include <QRegExp>
#include <QStringList>

#include <qhttpserver.h>
#include <qhttprequest.h>
#include <qhttpresponse.h>

Greeting::Greeting()
{
QHttpServer *server = new QHttpServer;
server->listen(QHostAddress::Any, 5000);
connect(server, SIGNAL(newRequest(QHttpRequest*, QHttpResponse*)),
this, SLOT(handle(QHttpRequest*, QHttpResponse*)));
}

void Greeting::handle(QHttpRequest *req, QHttpResponse *resp)
{
QRegExp exp("^/user/([a-z]+)$");
if( exp.indexIn(req->path()) != -1 )
{
resp->setHeader("Content-Type", "text/html");
resp->writeHead(200);
QString name = exp.capturedTexts()[1];

QString reply = tr("<html><head><title>Greeting App</title></head><body><h1>Hello %1!</h1></body></html>");
resp->end(reply.arg(name).toAscii());
}
else
{
resp->writeHead(403);
resp->end("You aren't allowed here!");
}
}

int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);

Greeting hello;

app.exec();
}


Awesome isn’t it? You launch an instance of QHttpServer, it emits a signal whenever a new request comes in, you can handle and respond to it. The code is fully documented, so you can do a git clone and run doxygen in the docs/ folder to get API documentation. For now it doesn’t deal with everything that can happen in HTTP, but it does know about keep-alives (no chunked encoding though). QHttpServer is streaming, see the body data example.



Here is a simple ApacheBench run comparing qhttpserver and node.



QHttpServer Greeting app:



> ab -n 1000 -c 100 http://localhost:5000/user/nikhil
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)


Server Software:
Server Hostname: localhost
Server Port: 5000

Document Path: /user/nikhil
Document Length: 88 bytes

Concurrency Level: 100
Time taken for tests: 0.467 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 151000 bytes
HTML transferred: 88000 bytes
Requests per second: 2142.47 [#/sec] (mean)
Time per request: 46.675 [ms] (mean)
Time per request: 0.467 [ms] (mean, across all concurrent requests)
Transfer rate: 315.93 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 4.7 0 23
Processing: 14 43 18.9 40 123
Waiting: 13 43 18.9 40 123
Total: 14 45 18.9 41 130

Percentage of the requests served within a certain time (ms)
50% 41
66% 48
75% 53
80% 58
90% 69
95% 80
98% 98
99% 117
100% 130 (longest request)


node.js greeting app:



> ab -n 1000 -c 100 http://localhost:5000/user/nikhil
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)


Server Software:
Server Hostname: localhost
Server Port: 5000

Document Path: /user/nikhil
Document Length: 88 bytes

Concurrency Level: 100
Time taken for tests: 0.441 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 151000 bytes
HTML transferred: 88000 bytes
Requests per second: 2267.94 [#/sec] (mean)
Time per request: 44.093 [ms] (mean)
Time per request: 0.441 [ms] (mean, across all concurrent requests)
Transfer rate: 334.43 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 4.4 0 18
Processing: 4 40 22.7 37 101
Waiting: 4 40 22.9 37 101
Total: 4 42 21.7 39 101

Percentage of the requests served within a certain time (ms)
50% 39
66% 50
75% 57
80% 63
90% 73
95% 83
98% 91
99% 95
100% 101 (longest request)


While not a very scientific benchmark, this does show them pretty close. C++ is compiled, but I believe node has less ‘layers’ and a particularly efficient I/O infrastructure which allows it to be better even with an interpreted language.



I would really like to see this being used in Qt apps that need a web interface for remote control, or for simple delivery of files.



In addition, if you will be attending conf.kde.in in Bangalore, India on March 9th-13th, my talk on Qt Scripting will involve writing a thin JavaScript wrapper over this and doing some other cool stuff! So be there.

Wednesday, January 05, 2011

Spreading the KDE love in India

conf logo

The first ever KDE conference in India takes place this March. On March 9th, 2011, gearheads will descend to the RV College of Engineering for conf.kde.in. If you are interested in using or contributing to KDE, we look forward to meeting you there.

There have been KDE contributors in India since the late 90s, but in recent years we have reached a more sizeable number. Contributors usually hang out on #kde-in, the KDE India IRC channel. The idea for a pure KDE conference in India first emerged about 2 months ago, and we’ve been doing the behind-the-scenes work since then. Now it’s time to GO! So we have this superb website made by Sayak Banerjee, brilliant artwork by Eugene Trounev, and hosting on the excellent KDE infrastructure.

conf.kde.in will take place from 9th-11th March followed by a 2 day sprint/hackathon for existing contributors. conf.kde.in is a platform for Qt and KDE contributors and enthusiasts to meet up, share their knowledge, contribute, learn, play, have fun and create limitless possibilities. The primary objective is to have fun while learning something. We are especially looking forward to students and teachers, as they are the ones who benefit the most from KDE, but also have the most to give back to it, by contributing and promoting KDE throughout India. Registrations for the conference will begin soon. Meanwhile, the FAQ should answer most questions. If not, contact us.

There will of course be excellent talks by Qt and KDE contributors from around the world. If you would like to give a talk or conduct a workshop, the Call for Participation is now in progress. It will end on 22:00 IST 15th January, 2011.

For more updates, follow us on Twitter, Identi.ca, or Facebook.

Posted via email from nikhil's posterous