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.