Sunday, November 20, 2011

Care Driven Development: Javascript

There is * Driven Development, where they listed "all possible thing" driven development and dedicated a whole website to it! Well, I am adding one more to the list, "Care Driven Development", with an emphasis to Javascript coding.

Javascript coding, do you care enough?
CSS is the most hairy spagetti piece of almost any web project. And its not leading by a far distance to it's first cousin; Javascript. But, the good thing is, it just takes a little care to clean the bush out of Javascript and make it pretty.

Do you care enough not to use the following ever again?

  • $('#deep_under_the_ocean').parent().parent().hide()?
  • $.ajax(url: 'bank_accounts/transfer_money', amount: 500...)
  • $('#eiffel_tower').height($('#paris').height() +  $('#eiffel_tower base').height() + $('#eiffel_tower tower').height() + ...)
  • populateNewYork('east', 'north', 50, 100, 23, ...)
  • $('.shark').click(function(){$('.small_fish').attacked(function(){...})})
  • parseInt($('.selected').id().split('-').last())
I am compiling a list of such careless JS coding examples and this is just a start. If you have a few to add to this list, please keep sending!


Friday, November 18, 2011

Enterprise Software Projects: oh, yeah!

I just rolled off my first ever enterprise software project couple of weeks ago. After staying six months on the project and while the memory is still fresh, I thought I would write a retrospect on the project and on my role.

The program is rather big, I guess it had ~300 people for the last couple or so years. I joined late for the program. So, by the time I went there, a massive amount of work has already been done, meaning a huge learning curve for me. On retrospect, I think I did well :)

My team was small, 4-5 people including 3 devs. But we were responsible for really high value enterprise integration work, especially, linking the two most important applications in the program. This was a great place to learn some of the core business domain specific knowledge and I loved it!

However, enterprise integration stuff is full of XML messaging and translation. While XSLT works when it works, in our situation we had too much logic and stateful data involved in the translation. So, we had to write a hell lot of custom code for all the XML messaging... and it sucks! Why?
Service APIs change all the time! 
I was mostly writing Java at work in this project for the first time in my professional career. This was a big change as well as a good exposure, considering my recent work mostly being in C# and Ruby.  In retrospect, I would say, I would rather not use Java, its a great platform but offers your an aging language.

Being in the enterprise world means dealing with enterprise service buses, queues, oracle database, weblogic, load balancers, risk and compliance and you name it... sometimes the complexity of these things seemed to be unnecessarily troublesome, but then again, at times they made sense as well.

People factors matter way greater than any other factor in such a big project. In retrospect, I think a hierarchical system often leads to longer meetings, useless communication and less ownership for most people.

I will continue this post to a second episode where I will talk about development practices, challenges with multi-project communication, politics and power relations etc. Stay tuned! 

Sunday, November 13, 2011

Aligning an HTML DIV Inside Another One

Across different projects, I have found people taking CSS shortcuts for translating the Photoshopped design templates into HTML. Back in the days, layout used to be all Table based and it was kind of straight forward to fit everything into grid cells. However, with CSS styling the extra flexibility to put elements in any arbitrary layout came extra responsibility - to make sure things still align nicely while being fluid to accommodate different screen resolutions and form factors.


Aligning the child div in red inside a parent div in green using CSS

Here's a quick and dead simple example to create CSS alignment for a div inside another one!

Pro Tip: Use position:relative for the parent div and position:absolute for the child div.

This will make sure the parent is positioned relatively to other elements in the page. However, the absolutely positioned child can be positioned anywhere inside the parent without making the whole layout fixed.


Tuesday, November 01, 2011

Using instanceof is mostly a Code Smell

When using static programming languages such as Java, often time I have seen people writing methods that accept Object as a parameter. These methods typically don't really work on any Object, but works with multiple types of classes that don't have any common base class. Here's an example of such a method:

As you can see in this example, the process method actually expects one of CleanFloor or LaunchRocket instances. However, since the two don't have a common subclass, it falls back to an Object type. And that results in the smelly code as you see in the example.

An ideal solution would be to change the design of the classes so that you can either use a common base class or a generic method. But if you can't just do that

Get rid of the instanceof anyway!

However, this doesn't need to be smelly. Turning to basics of OO programming concepts, you will recall that there's this thing called method overloading that is specifically there to solve this very problem.

It seems so obvious in this example that you might question, why someone would use the former code? Well, I have seen quite a few of them and if you search for instanceof in your Java project, I won't be surprised if you see a few code fragments that match the former example.

Tuesday, October 04, 2011

Nightly Build is a Warning (or Horror)

Photo credits: insidethemagic

I think, Nightly build is an anti-pattern for Continuous Integration. If you are integrating continuously, then you shouldn't need a nightly build, that would be too discrete :(

If you already have a per-commit continuous integration setup, you shouldn't need the so called nightly build unless there's something bad about the code.

Often times, builds taking >10 minutes are put in the bucket of nightly builds.
Some people put batch processing related tests under such nightly builds. A colleague told me they used nightly build to clean up resources (disk space, recreate the database etc.) on a nightly build - to ensure the apps worked fine on a fresh state.
Under most circumstances, a nighly build means something long running. That in itself can be an indication of poor performance.
But what I have seen is, when such nightly builds are broken - they are rarely looked after or cared for. Because, first thing in the morning, who the hell wants to look at that broken nightly build? Even if someone takes a look, since its long running, it might well eat up all morning to actually try/fix/commit changes and see it go green again! Since it takes longer to make the build green, people keep delaying it for later... meaning
it becomes generally acceptable to let the nightly build stay in RED. 
And once people get used the redness of the nightly build, they start ignoring it, inevitably.

So, here's what I would do:
Avoid nightly builds altogether.
Avoid nightly builds altogether.
Avoid nightly builds altogether.
Otherwise, make one person from the team responsible for the build (rotate people).

Wednesday, September 28, 2011

The Perils of Soft Delete

Often times, applications cannot get rid of the database records for business rules. For example, if you are a cable TV provider, you might have a customer calling you to stop the National Geographic Channel subscription from next month. Ideally you would like to delete this record, but you can't do it until the effective date:( If you delete it, the next invoice will not be able to charge for this channel, although it's still being used.

In such scenarios, its common to fall back to a soft delete model. As an example, here's a little code:


This code looks simple and harmless at a first sight. But, as you develop your app, you'll run into a lot of issues from this. Here's a short list:
  1. You need to take care of cascading soft delete, for example, cancelling a customer's subscription needs to cascade down to all channels and other objects under it.
  2. Whenever, you are listing the current subscriptions of a customer, you need to filter out the ended ones.
  3. You need to figure out a strategy to periodically clean the ended subscriptions so that your database is not filled with outdated data.
  4. If you have a business key used as a primary key as well, you will be in trouble if an ended subscription is restarted.
  5. Your code will eventually have a lot of if-else blocks to apply changes to only on active objects.
So, what is the solution? Its best to avoid them as much as possible. Richard Dingwall has a detailed blog post on some alternative techniques to avoid soft-delete. But if you have to have soft delete, as shown in the example, its worth remembering the aforementioned points.

Friday, September 23, 2011

Hardcoded URLs in Javascript are too Slippery

Photo credits to Esteban Cavrico


I was working on a web project that lets you delete some records using Ajax. The following is just an example, but you might be familiar with a similar code already:


This code used to work when the DELETE endpoint was indeed under '/blog/posts'. However, at some point a developer wants to remove the '/blog' from all the endpoints to put them directly under '/posts'! You can see, in such cases it is very hard to catch the bug that would be caused by the faulty JS code.

Here's a quick recommendation:
Don't hardcode the URLs (or anything that is actually a server configuration) inside your JS. 
This is a code smell, as its duplicating code. But its also dangerous, because its hard to catch/fix these defects since they can be buried deep under an untested Javascript file. Instead feed this data from your server side code and you'll mitigate risk that way.

Tuesday, September 20, 2011

Excess of Private Methods is a Code Smell

Private methods, when used meaningfully, are a great tool for writing beautiful object oriented code. But as many other things in life, excess of private methods is bad, too!

In my opinion, we use private methods to:

1.  isolate a block of code to be reused inside the class.
2.  extract code from another method for code readability.

Now, taking these two use cases in mind, here's an easy conclusion:
The lower the ratio of public to private methods, the harder it is to write unit tests since the "units" are potentially larger.
I don't know if there is any rule of thumb, but you will smell it when you see your unit tests require a lot of setup and assertions. Here's a code example from the Play! framework, an MVC franework for Java developers.

ActionInvoker.java

You will see there are public methods with 100+ lines. I hope you agree with me:
"The ActionInvoker.java code is not readable"
For the sake of readability, introducing private methods with good names would help. However, that doesn't eliminate any of the possible code paths from the public methods. So, if you are lucky, you will see really long unit tests with complex setup conditions and mock expectations. Otherwise, there will be no tests at all! Without any tests for such long and complex methods, use them at your own risk. I won't :(

Disclaimer: I like the play! framework a lot. However, if you take a look at their code and if you think unit testing is important, you'll see they have a lot of rooms for improvement with simple extract method refactoring.

Friday, September 16, 2011

Quiz: C# Async and Await. What is the Output of this Code?

C# 5.0 (CTP version at this point) has support for async and await to allow clean implementation of non-blocking IO using a task-continuation model. I was just playing with it and here's the sample code to tease your brain. Tell me what is the output of this program?

How to Extend a Ruby Module?

Modules in Ruby are like classes with a few important differences. One of the differences is, a module cannot inherit from another module using the same syntax as class inheritance. However, its pretty easy to inherit a module's method into another module, by just using the include ModuleToInclude syntax. Here's an example if you are looking for one:

Monday, August 15, 2011

Should You Unit Test Interaction with Static Methods?

No. You should not. Here's an example:


If you are somehow mocking this static method, you are potentially making it dangerous for other places where this static method is used. Eventually, this will create red test results that are hard to find and make your tests dependent on each other.

Tuesday, August 09, 2011

Should you unit test methods with a lot of mocking?

Well, anytime you have a lot of mocking, it is probably a smell. Particularly, a first smell is violation of the law of demeter. However, we were having discussion about whether or not we should write unit test for something like the following example:



As you can see, this method actually does a quite important task. It invokes the search method with specific parameters that will determine your search results. Now, we were debating whether or not the example unit test actually brings any value.

Here's what we have discussed:
Pros:
It confirms that you are actually calling the third party method with the right parameter.
Cons:
The test is too tightly coupled with the implementation, so it will break if something changes inside the method irrespective of its actual output.

But we failed to come to an unanimous decision on its usefulness. We all agreed on the point that it definitely needed some integration tests to make sure the search had actually worked.

Here are two questions for you:

  1. Would you skip the unit test altogether for this method and rely completely on an integration test? Why/Why not?
  2. If you are to rewrite this code, how would you write this using TDD?

Looking forward to see your input on this!

Friday, August 05, 2011

Ruby present? Method

Ruby has a nice little keyword called unless, that checks the opposite of if. So, you are probably used to a code like this:

return customer.first_name unless customer.nil?

If you haven't used present? before, you can in fact turn the above unless into a more familiar and easy to understand if statement:

return customer.first_name if customer.present?

So, in most cases when you are using unless with a negative condition, you can use present? and if instead. I find it way easier to read.

present? does the opposite of blank?. So, you will get the following:

nil.present? #=> false
[].present? #=> false
"hello".present? => true
["a"].present? #=> true
Hope it helps!

Tuesday, July 26, 2011

Constructors Are Methods, too!


Yes, if your constructor does something meaningful. This is just like another method and should be treated equally for unit testsing purpose. Here's an example that should need unit test:

It looks simple, so testing it should be simple, too. I would only skip the default constuctors, as long as they don't do anything interesting.

Friday, July 22, 2011

How to Annoy Your Customers? Learn from GoDaddy Account Status Email

Just looking at this screenshot alone, what do you think it is?
I have a few domains registered with GoDaddy. I went with them, because at that time, I didn't know of another renowned provider. But they have always been the best of producing the most confusing ever user interface. The account status email is one step ahead in that same direction.

This is how it starts:

At the top right corner, it says July 2011, in grayed out font! A deliberate attempt to de-emphasize the statement period!

Just below the date, there is a fake input box and a button labeled Go. This is an image and if you click it, it will actually open a new page instead of asking for user input right inside the search box. This is just following the theory of most surprise (as opposed to principle of least surprise)!

Next, in red background, they welcome me by saying, Welcome, S. M. Sohan! Customer Number: ### wtf? Customer Number? Do I give a shit what my customer number is? Why is the welcome grouped together with search and contact? How are these related?

Then it says, Log in to your account on our secure website to view your most recent account statement. What does this mean? Does it mean, this statement is not recent? Is this not secure?

Then it says, Summary of your account as of 7/21/2011**. That f'ing footnote will tell you that, the information may not reflect recent changes! What? Is this good enough till 7/21? If not, why do you even send this bullshit to me?

Then it has 4 boxes side by side. The first one, Messages has Alerts: No, Notification(s): Yes. View now is a button to their site. How stupid is this? Why bother saying alerts "No"? If you know I have notifications, why not put it right here? Why are you confused about notification"(s)" - you should know if its just one (notification) or more (notifications). How lazy is that?

Items Expiring is the other funny one. It says, Domain names: No. Then it says renew now. What? You're saying nothing is expiring. Why on earth I would renew something?

Then it takes almost 50% of the screen for asking me to contact with them through a number of channels including Facebook. Really? Facebook fan of GoDaddy? Crazy people!

In the end, they don't care putting a note of thanks, let alone personalize it with the name of an actual person. Isn't it rude to end an email this way?

Now, with all these hammerings - as if it fell short of creating enough fun, it says, More for You: followed by tens of fine print links to things that don't matter at all to me. Oh boy! you are awesome!

I am not a designer by any means. However, I think, even I can design a better version than this crap. Here's my version in a screen mockup.






Monday, July 11, 2011

Avoid Duplication in Config Files

Any kind of configuration file, be it an ugly xml file or a prettier yml or properties file, its been a source of frustration to me. Here's a list of few such pain points:

  1. There are two config keys that point to the same value. e.g. db_username=master, data_source_user=master
  2. There are two config keys for urls that point to the same domain, but different paths. e.g. market.com/cameras and market.com/undies
  3. Config entries with placeholders. e.g. weather_url= weather.com/%s or weather_url= weather.com/%s/hourly
  4. Config entries with default values that should not default to anything.
  5. Config entries that are required but don't fail the application deployment when not set.

Are you having to deal with similar pain points? Some more?

Saturday, June 25, 2011

How Not To Provide Feedback When Doing Code Review

Code review, as any other review process, can often be an attack on someone's ego and incite anger and frustration. Being both on sending and receiving end of such code reviews for years, I have learned a few how-not-to-do-it, or as one might say, anti-patterns of providing code review feedback. Let me know if you agree/disagree with me on the following:
  • You are always reviewing Adam's code while Adam is never reviewing yours.
  • Your feedback is like "Adam, you should break down part of this method into a private method" instead of "we can probably extract a part of..."
  • You are always suggesting, for example "we should do x and y and z", instead of asking interesting questions "can we do x? what if we did y?"

Wednesday, June 22, 2011

Service API and Exceptions


Too often I see I am using a REST/SOAP API to talk to a third party system that frustrates me because of poor error messaging. Here's an example to illustrate a typical frustration:

Call: city_service.update_residence_address(city_dueler, new_address)
Response: <status>Failed</status><error>Invalid address</error>

But the address just seems right to me. So, I need to know specific reason about why the address is wrong. The error message leaves this critical detail. What happens next is, I look for the log files created by the city_service, conceptually supposed to be a third party hosted service. To do this, I SSH to the server, then cd to the logs folder and get lost in many of the cryptic log files. Then eventually I find a log and if I am lucky, I find something like the following:

InvalidAddressException at:...
...
Street number is not listed..
...

Now, I know I had an issue with the streer number. But I can see this only after I looked into the log of the thirdparty server. In an ideal case, I don't have an access to their server. Even if I have it, I cannot easily understand their logs and stack traces! In most API calls to third party applications I have had this frustration to varying degrees.

Here's a lesson learned:
Next time you expose an API for another app, expose error messages as specific as possible - so that, no details is left buried into your log files.

Thursday, March 17, 2011

NuGet - Why Should You Care?

Traditionally the .NET community, or more appropriately the users of .NET framework relied on products from Microsoft - so, in a product stack you are likely to see almost everything coming from Microsoft. However, some community contribution made its way into the main stream - for example, NUnit or Log4Net. But you can literally count the number of such main stream non-Microsoft products in your development stacks with your fingers (sparing a few)!
NuGet makes it easy to share your reusable library/utility code to the community. So, if you've done something cool that you wanna share, you should utilize the platform.
One important difference between your and Microsoft's contribution is, whatever you are contributing is likely to be a piece of software extracted from one of your real world projects. On the other hand, Microsoft attempts to produce something based on public interest and their imagination - often missing the real pain that you or I have. So, this mismatch between the designer and the actual consumer of the product often leaves a lot of opportunity for you. If you did something to solve your own pain on a project, its likely you're not alone. So, share it with us.
NuGet official feed and website is a great place to get feedback.
Did something cool? Well, you should feel good as people will use and appreciate your work. More importantly, they will provide you with interesting ideas and reviews that you haven't thought about. Does this sound useful to you? People will go even further - they will directly contribute to the project with code!
NuGet will challenge you with competition from other contributors.
A healthy competition is a great way of learning from others too. You'll see other contributors attacking the same pain you are solving in a different approach, often directly challenging you! You love challenge, don't you?
If you need hard numbers to get motivated, here's some data from my MvcMailer project:
  • Downloaded 600+ times in less than 2 months.
  • Received 60+ emails from people using MvcMailer, mostly encouraging feedback.
  • 300%+ increase in my blog traffic.

Bottom line is, you should publish your NuGet package if there's any cool project you have done. Or, look out for what others are doing and possibly contribute with your code/suggestions. If you need an idea, look for StackOverflow questions, you'll see there are solvable problems that people are fighting against time and again.

Monday, March 14, 2011

My 2011 Q1 developer roadmap

For me, 2011 Q1 has so far been a good exposure to new techniques, tools, articles and books, thanks to ThoughtWorks book allowance! However, if you are interested, here's what's keeping me busy:
  1. User Experience: I find a good user experience is THE thing that you want in anything you design, and if you are writing a software, its even more important. After I read a few books, I have a feeling that its not just a common sense approach, it takes some education and a deep care to produce something usable. Check out my reading list at http://smsohan.com
  2. HTML5: HTML5 is so more than just knowing How To Meet Ladies (HTML)! The popular browsers are all way ahead of the official HTML5 release date, so if you are building something on the web, its time you give it a real shot. Again, I shared my reading list on my website.
  3. .NET NuGet: Microsoft .NET just got a major component, NuGet package manager, that greatly simplifies the sharing and consuming of reusable libraries. Already there are tens of thousands of downloads for the popular .NET libraries and I believe its just a start. So, if you've done something cool in your project and want that to share with the .NET crowd, you should consider NuGet as a distribution channel and get some traction on it.
  4. MvcMailer: MvcMailer has got all my developer attention in the recent past. If you haven't checked already, I highly encourage you take a look at its features at this page and you'll see its a full stack elegant emailing solution that you need in your ASP.NET MVC projects. However, while working on this, I got familiar with the internals of the ASP.NET MVC source code and I consider this as a good experience.
  5. Functional Programming: Did you learn one? Which one? Please suggest me your favorite functional language. In the remaining of this Q1, I want to spend some time on a functional programming language, probably F#.
Its inspiring to see Calgary getting warmer these days - hope we get some outdoor soccer by the end of 2011 Q1, that would be awesome!

Monday, March 07, 2011

MvcMailer 1.0 Released

Just released MvcMailer 1.0 as promised in my previous post. Download your copy using the following:
Install-Package MvcMailer
Of course, you will find a comprehensive tutorial at: this github wiki page.

Friday, March 04, 2011

Whats Coming in MvcMailer NuGet 1.0?

Thanks to 365+ downloads of the MvcMailer NuGet before it hit version 1.0 and now its time to wrap up the NuGet package for an official first release. I got several encouraging feedback on this package and here's what you get from this first release:
  1. Use Scaffold Mailer to generate your mailers with views.
  2. Compose rich emails using your favorite ASP.NET MVC view engine.
  3. Use master pages and pass data using ViewData/ViewBag.
  4. Send multi-part emails for both text and html email readers.
  5. Put images inline so that they are visible even when email client is offline.
  6. Write unit test for your mailers and controllers that use the mailers.
  7. Send attachments.
  8. Send emails asynchronously.
To my knowledge, MvcMailer is gonna be the first full stack ActionMailer like Emailing library for ASP.NET MVC 3. If you are an ASP.Net MVC programmer who deeply care about high quality work and maximizing efficiency - you gotta try MvcMailer 1.0 for writing pretty email sending code.
The github wiki page has everything you will need to know about MvcMailer. Version 1.0 comes out on Monday. Stay tuned.

Friday, January 28, 2011

ActionMailer 3 - why do you call instance methods as class/self methods?

I didn't even notice this little trick! As long as I didn't have to call deliver_welcome_message (or deliver_*) methods that would magically call welcome_message, I was happy that now the magic is gone. Things are transparent!
Here's an example showing the change: Say you have the following mailer:
class Notifier < ActionMailer::Base
  def welcome_message(new_user)
    #a warm welcome message
  end
end
Now, prior to Rails 3, or ActionMailer 3, you would write the following to actually call this method to get the benefits of ActionMailer magics, such as finding the view based on method name and so on:
Notifier.deliver_welcome_message(new_user_instance)  
I am sure this deliver_* was a clever design decision to solve a hard problem, that is, finding the view name based on the method name. However, in ActionMailer 3, this is gone. Now the question is, if this trick is gone, how come it still finds the view name from the method name? Who sets the view name? To know the answer, first, let's take a look at how we call the welcome_message now.
Notifier.welcome_message(new_user_instance).send
Instead of

Notifier.new.welcome_message(new_user_instance).send

So, the magic deliver_ prefix is gone. But, did you see the new trick? Well, its a clever design again. The trick this time is, you call your instance method, welcome_message as if it was a class method. But there is no class method called welcome_message, so it instead goes to method_missing and thats how it sets up the view name from this call. Here's the code that does this little trick!
def method_missing(method, *args) #:nodoc:
    return super unless respond_to?(method)
    new(method, *args).message
  end
All it does is, instantiates the mailer with the method name!

However, this design decision has interesting side effects as well. Or may be not side effects, but rather core effects. For example, since you are calling your mailer methods as class methods, you cannot use a single mailer instance to send out multiple emails at the same time. In fact, every mailer has only one instance of message. So, it cannot store two messages at the same time. This is as if, you can have multiple methods in a class, but you cannot call more than one class or you will mess up the class's state!

Wonder why? Well, this is rooted in another key design choice: ActionMailer::Base is a subclass of AbstractController::Base. Now, if you look at controllers, you will notice that at any given point of time, a controller instance is only responsible for responding to a single action. This is logical for controllers. But how about mailers? I see a mismatch in my mental model and the actual implementation model. I don't see a reason why a mailer is a controller! For the sake of code reuse? But that could be done via delegation anyway.

I will end this post with one question:
Do you think mailer is a controller? hints: think about LSP.

Friday, January 14, 2011

Social Helpers in ASP.Net MVC3 (Facebook, Twitter, Gravatar etc.)

This site shows the examples!
http://www.asp.net/webmatrix/tutorials/13-adding-social-networking-to-your-web-site

Now, the social links and buttons are no longer from a third-party source, its straight from Microsoft. I don't know if this is first-party or second-party :p

Thursday, January 13, 2011

My Article at CodeProject: MvcMailer

I just released a .Net NuGet package called MvcMailer and to get people super easily started, put an article at CodeProject.com. You are most welcome to the article at http://www.codeproject.com/KB/aspnet/MvcMailerNuGet.aspx
I welcome your comments and suggestions!

Friday, January 07, 2011

C# Named Parameters Can be Very Useful

Think about the following code example:
htmlHelper.InputHelper(InputType.CheckBox, name, "true", true /* useViewData */, false /* isChecked */, true /* setId */, false /* isExplicitValue */, htmlAttributes);
This line is taken from the source code of ASP.NET MVC, or to be more specific its a line from the InputExtension class. I think the intent of the original developer is clear:
Add comment next to arguments so that one can easily read the method call without getting lost in a who's who since there are quite some arguments to pass.
To learn more about named parameters using C#, you can visit this post by ScottGu.

Sunday, January 02, 2011

2011: Yet Another New Year

Dear Readers:
Happy 2011. 2010 was a great year. Why?

  • Defended my MSc thesis after a moderate 16 months of grad school life.
  • Published 3 papers in 3 international conferences.
  • Visited 4 new countries - Netherlands, Sweden, Finland and Norway.
  • Visited a few interesting cities - Vancouver, Victoria, Edmonton.
  • 100+ posts on DrinkRails.com.
  • 25,000+ visits to my two blogs from all over the world.
  • Developed a fresh new app, Plexina Central, for Wairever Inc.
  • Lived a healthy life.
  • Bought my first (98 Corolla) and second (2000 CR-V) cars (also sold my first car)!
To live up to this standard, 2011 is surely challenged by 2010. Let's see how 2011 rolls: To give you a heads up, I am joining ThoughtWorks as a Consultant on January 4th!
However, 2010 was the only year in my life when I didn't see my parents and siblings. I hope, 2011 does a better job in this regard. It is getting essential now.
This is how I look at the close of 2010
And I want to look leaner at the close of 2011 or even before that :(