<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2687820185167366196</id><updated>2011-12-20T18:43:10.982-08:00</updated><category term='Random'/><category term='Experiences'/><category term='Sport'/><category term='Microsoft'/><category term='Netflix'/><category term='Technology'/><category term='Interviewing'/><category term='Meebo'/><category term='FriendFeed'/><category term='Security'/><category term='Apple'/><category term='Jerry Seinfeld'/><category term='iPhone 3G'/><category term='Programming'/><category term='Web'/><category term='Politics'/><category term='Testing'/><category term='Coupon'/><category term='Etiquette'/><category term='Fiji'/><category term='World'/><category term='Chrome'/><category term='Travel'/><category term='Paris'/><category term='Career'/><category term='Safari'/><category term='Software'/><category term='iOS'/><category term='Miscellaneous'/><category term='Groupon'/><category term='Android'/><category term='Yahoo'/><category term='Facebook'/><category term='Windows 7'/><category term='Audiogalaxy'/><category term='XBox'/><category term='Facebook Connect'/><category term='Entertainment'/><category term='SecureCRT'/><category term='Engineering'/><category term='YouTube'/><category term='Vacation'/><category term='Google'/><category term='Elections'/><category term='Three20'/><category term='Windows Phone 7'/><category term='LiveMesh'/><category term='Live Search'/><category term='Technology Predictions'/><category term='Bill Gates'/><category term='iPhone'/><category term='Tools'/><category term='Cocoa'/><category term='WWDC 08'/><category term='Mac Development'/><category term='Movies'/><category term='Buzz'/><category term='Google Voice'/><category term='Virgin America'/><category term='Media'/><category term='Silverlight'/><title type='text'>Mulligan!</title><subtitle type='html'>Viraj does it once over...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-2382935949569843585</id><published>2011-11-11T12:50:00.001-08:00</published><updated>2011-11-11T13:32:46.908-08:00</updated><title type='text'>Customer Support Rule #1 - Don't be a Robot</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;A recent user support interaction, pictured below, is one of many examples I've experienced where being honest and human goes a long way in winning over users, and humor doesn't hurt. You don't have to be 'nice', don't have to follow a strict template or be formal. You just have to communicate with your user like a real human being.&lt;br /&gt;&lt;br /&gt;Users love it when they realize there's a human on the other end, and not a robot that's spewing stock replies crafted by corporate types. That is, often, the start of a loyal relationship.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-ruwnr9mQKvg/Tr2NIHMxfCI/AAAAAAAAAE4/1N_NImYDV0o/s1600/Support.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="272" src="http://1.bp.blogspot.com/-ruwnr9mQKvg/Tr2NIHMxfCI/AAAAAAAAAE4/1N_NImYDV0o/s640/Support.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-2382935949569843585?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/2382935949569843585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=2382935949569843585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2382935949569843585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2382935949569843585'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2011/11/customer-support-rule-1-dont-be-robot.html' title='Customer Support Rule #1 - Don&apos;t be a Robot'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-ruwnr9mQKvg/Tr2NIHMxfCI/AAAAAAAAAE4/1N_NImYDV0o/s72-c/Support.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-280563728677888812</id><published>2011-08-22T10:58:00.000-07:00</published><updated>2011-08-23T15:06:17.000-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Audiogalaxy'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='iOS'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><title type='text'>Don't Let Apple's Latency Mess With Your iOS App</title><content type='html'>Last week, I released an update for the iOS &lt;a href="http://www.audiogalaxy.com/"&gt;Audiogalaxy&lt;/a&gt; app which featured its first in-app purchase that allows users to &lt;a href="http://www.audiogalaxy.com/blog/2011/08/audiogalaxy-mobile-2-0-for-ios-with-offline-playback-and-more/"&gt;'pin' songs to their devices&lt;/a&gt;. Users can try the feature by pinning a limited number of songs for free, and are then prompted to purchase if they wished to continue pinning more songs. As suggested in Apple's SDK documentation, I built and tested the in-app purchase against the &lt;a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/DevelopingwithStoreKit/DevelopingwithStoreKit.html"&gt;sandbox&lt;/a&gt;. After everything checked out as I expected, I submitted both the app update and the in-app purchase for approval by Apple.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://webkilled.tv/wp-content/uploads/2010/01/apple-fail.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 250px; height: 220px;" src="http://webkilled.tv/wp-content/uploads/2010/01/apple-fail.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div&gt;The application and the in-app purchase were concurrently approved. After verifying that the status of in-app purchase product in iTunes Connect was "Ready for Sale", I released the updated application. It usually takes about an hour for app updates to start propagating to users, so I anxiously waited to get the update on my iPhone and verify that in-app purchasing worked fine. Once I got the update, I tried to purchase the in-app product but it failed. I had written code to handle potential errors, and looking at the error message I realized that the StoreKit API wasn't able to identify the in-app product I was requesting. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I went back and verified that the product identifier was correct, and everything still worked fine in the sandbox. Users had started hitting the same problem - not good! It's definitely not the best first impression for users to upgrade, try new features and immediately see an error. I scoured the web for clues and found a &lt;a href="http://stackoverflow.com/questions/5753162/in-app-purchase-does-not-work-when-live"&gt;StackOverflow question&lt;/a&gt; which suggested that it can take up to 24-36 hours for in-app products to 'go live'. &lt;i&gt;Uh-oh&lt;/i&gt;! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is no mention of such a delay anywhere in Apple's documentation, and neither is it reflected in the status of the in-app purchase product. If I had known, I obviously would have waited to release the update. Apple doesn't provide the ability to roll back to previous versions, so basically I was SOL. If indeed it took ~24 hours for the in-app product to show up, it could be disastrous. The fallout could include:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;Disappointed users&lt;/u&gt;. There is nothing more disappointing that looking at the "What's New" section of an app before upgrading, getting excited and then watching the feature just not work as expected.&lt;/li&gt;&lt;li&gt;&lt;u&gt;Negative reviews/ratings&lt;/u&gt;. App Store ratings/reviews provide a medium for users to vent their frustrations or to shower praise. For developers, it's really a matter of making sure that the people with exceedingly pleasurable experiences with your application exceed the number of people with even remotely dissatisfying experiences. Audiogalaxy was a 5-star rated app, but this snafu could potentially affect that negatively, really fast.&lt;/li&gt;&lt;li&gt;&lt;u&gt;Personal disappointment&lt;/u&gt;. I take a lot of &lt;a href="http://crazyviraj.blogspot.com/2011/01/on-mediocre-software-where-is-love.html"&gt;pride&lt;/a&gt; in making sure that I deliver delightful experiences to users, and this would be the exact opposite of delightful. The hurt would be tempered by the fact that this was beyond my control, but it would hurt nonetheless.&lt;/li&gt;&lt;li&gt;&lt;u&gt;Lost revenue&lt;/u&gt;. From my experience with &lt;a href="http://www.audiogalaxy.com/blog/2011/07/offline-music-for-android/"&gt;in-app purchases on Android&lt;/a&gt; (and now also on iOS) it was abundantly clear to me that purchase volume is very high in the first few days of a new in-app purchase being available. Users upgrade, try what's new and buy it if they like it. If they're unable to, they might never come back to buy it. &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I was really hoping that the problem was the delay-to-propagate issue and not anything more serious. Damage would be limited if the in-app purchase went live before too many users upgraded and started using the new feature, and I was secretly hoping that this was a matter of a few hours instead of 24-36 as suggested in the SO question. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I started monitoring how many users were pulling down the update and trying this new feature (yay for building simple monitoring tools that are fully in your control) and also dumping these userIDs into a table so I could keep track - a subset of these users were (hopefully) trying to purchase the add-on, but were failing to do so. The number started growing rapidly, and I began to panic. 5-6 hours later, the in-app product still wasn't live, negative reviews had started showing up and folks had started emailing us to let us know. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Watching user behavior, I knew something needed to be done. We decided that the best option was to make it impossible to even attempt to purchase the add-on. I updated the server to make it believe that all iOS users had already purchased the add-on - the app would then automatically hide all purchase related options. The plan was to just let everyone use the feature for free until the in-app purchase showed up for real. I wrote the code, tested it and pushed it to production. I watched it work for a bit, and then went to sleep.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The next morning, 14 hours after the status was "Ready for Sale", I was finally able to purchase the in-app product from the app. Thankfully, the server tweaks had helped and there were no new negative reviews or support emails. I rolled back the code from the previous night and waited for purchases to start showing up. Within minutes, I could see folks buying so I knew things were working fine now. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last thing that needed to be done was informing users who might have previously had trouble and might potentially never try buying again. I wrote a script to run through the list of all users who had tried the feature and to send them a personal note thanking them for their support, explaining what had happened and letting them know that the in-app purchase was now available if they wished to purchase it. A surprisingly large percentage of users went ahead and purchased it, and a few also went back and updated their reviews.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I took away three lessons from this experience -&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Design your apps/clients to be as dumb as possible and the server as much in control as possible. We've always tried to do that with Audiogalaxy, and it certainly helped in this situation (as it has on a few previous occasions).&lt;/li&gt;&lt;li&gt;Spamming all your users isn't a good idea, but it's perfectly OK to email a subset of users directly impacted by specific issues. Users are receptive to personally addressed emails with honest dialogue, and don't consider it spam.&lt;/li&gt;&lt;li&gt;Wait for 24 hours before releasing iOS app updates if you have added new in-app purchases.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;All in all, this didn't turn out as badly for us as it could have - but it shouldn't have happened. I still believe Apple is at fault for not communicating this information to developers, but that's not a rare occurrence for Apple - it's best to anticipate and prepare for the unexpected. I hope this blog post helps other who might be planning to add in-app purchases to their apps. In addition to better documenting such gotchas, it would also be awesome if Apple added the ability for developers to roll back to previous versions (or at least 1 previous version) like Google's Android Market recently did.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-280563728677888812?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/280563728677888812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=280563728677888812' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/280563728677888812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/280563728677888812'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2011/08/dont-let-apples-latency-mess-with-your.html' title='Don&apos;t Let Apple&apos;s Latency Mess With Your iOS App'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-542846657935064441</id><published>2011-06-22T15:01:00.000-07:00</published><updated>2011-06-23T18:29:12.263-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>A Capitalistic Fix for America's Broken Immigration System?</title><content type='html'>&lt;div&gt;Immigration in America is &lt;a href="http://www.competeamerica.org/"&gt;broken&lt;/a&gt;. There is no way to &lt;a href="http://techcrunch.com/2009/12/05/the-startup-visa-and-why-the-xenophobes-need-to-go-back-into-their-caves/"&gt;sugarcoat&lt;/a&gt; it, unfortunately. Failure of the administration to separate legal and illegal immigration concerns and to treat the politics of both as distinct from each other is &lt;a href="http://techcrunch.com/2011/03/06/why-silicon-valley-immigrant-entrepreneurs-are-returning-home/"&gt;jeopardizing&lt;/a&gt; the &lt;a href="http://www.politico.com/news/stories/0611/57013.html"&gt;future of America&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are &lt;a href="http://www.cfr.org/terrorism/broken-immigration-system-risks-serious-damage-us-national-interests-warns-cfr-task-force/p19743"&gt;several&lt;/a&gt; &lt;a href="http://immigrationvoice.org/index.php?option=com_content&amp;amp;task=view&amp;amp;id=5&amp;amp;Itemid=47"&gt;articles&lt;/a&gt;, &lt;a href="http://www.uscis.gov/portal/site/uscis/menuitem.5af9bb95919f35e66f614176543f6d1a/?vgnextoid=a294b16dedc0f210VgnVCM100000082ca60aRCRD&amp;amp;vgnextchannel=aa290a5659083210VgnVCM100000082ca60aRCRD"&gt;memos&lt;/a&gt; and &lt;a href="http://techcrunch.com/2011/03/06/why-silicon-valley-immigrant-entrepreneurs-are-returning-home/"&gt;blog posts&lt;/a&gt; which &lt;a href="http://www.washingtonpost.com/wp-dyn/content/article/2007/02/23/AR2007022301697.html?sub=AR"&gt;articulate what is wrong&lt;/a&gt; in a lot of detail, so I won't repeat those. To illustrate the problem though, here is a short blurb about my own situation. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have been a legal immigrant in America since I arrived to study Computer Science at the University of Texas at Austin in 2000. I graduated with a BS in Computer Science, interned at National Instruments for many months and went on to work at Microsoft for several years. I now work at a software startup. I'm a legal resident alien, but I'm still awaiting my permanent resident card ("green card"). I've been in the US for over 11 years now. I pay my taxes (TurboTax computes that ~16% of all income I've earned over the last 10 years has gone towards taxes, and this doesn't include local sales taxes), I occasionally speed on freeways and get pulled over, I spend money to stimulate the local economy (&lt;a href="http://www.mint.com/"&gt;Mint.com&lt;/a&gt; says I spend ~2.5x what the average American my age spends), I eat junk food, I save money for retirement and invest it in American companies, I volunteer at a local high school, I support the &lt;a href="http://www.texassports.com"&gt;Texas Longhorns&lt;/a&gt; and the &lt;a href="http://www.seahawks.com"&gt;Seattle Seahawks&lt;/a&gt;, I drink a lot of coffee, I donate to &lt;a href="http://liveunited.org/"&gt;local&lt;/a&gt; and &lt;a href="http://www.cry.org"&gt;international causes&lt;/a&gt;, I whine about the weather... basically, I do what most average Americans do. I have a decent life here in America, and I'm thankful for it. But, barring any change in legislation, the estimated date for my green card being issued is &lt;b&gt;2024&lt;/b&gt;. Yep, that's not a typo. If nothing changes, I will get my green card &lt;b&gt;24 years&lt;/b&gt; after I legally entered the United States of America. Not citizenship, just permanent residence!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I assume I don't need to explain to any reasonable person how ridiculous and ironic this situation is, given that American was built by immigrants. I won't get into how my personal and professional life are impacted by this silly situation. Instead, I want to propose a possible solution, one that I haven't heard mentioned previously. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What if one of the criteria for issuing a green card was - if your stay in America has been legal and you have paid more in federal+local taxes than the average American pays over his/her&lt;i style="font-weight: bold; "&gt; entire lifetime&lt;/i&gt; then your green card application should be fast-tracked.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If this sounds too simple, it's because it is -a simple, capitalist, pragmatic approach to immigration. This rule ensures that prospective immigrants enter America using legal means and remain legal, that they are employable and have documented income that is in line with or exceeds that of average Americans, that they will not be a burden to society but an asset and that they have an incentive to contribute to the success of their adopted nation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thoughts?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately, immigration reform is a political issue instead of a practical one, and a solution to legal immigration doesn't seem possible without a solution to illegal immigration (which just baffles me - anyone know why the two are joined at the hip?). America and Americans will eventually have to suffer the consequences of such nearsightedness, I fear. Illegal immigration is a political minefield though, so I don't have much hope for any real reform anytime soon, but then again... "hope and change", right?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-542846657935064441?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/542846657935064441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=542846657935064441' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/542846657935064441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/542846657935064441'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2011/06/capitalistic-fix-for-americans-broken.html' title='A Capitalistic Fix for America&apos;s Broken Immigration System?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3157181040565612757</id><published>2011-06-20T22:42:00.000-07:00</published><updated>2011-06-21T15:27:00.185-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Some Notes on Implementing In-App Billing on Android</title><content type='html'>About a year ago, I implemented &lt;a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction/Introduction.html"&gt;in-app payments for iOS&lt;/a&gt;, and it was painful. Technically, it wasn't too hard but there were a number of hoops to jump though to get everything working. Lack of clear documentation and undocumented error responses seemed to be the primary problem - I think a hold up with verifying tax information on the developer account resulted in strange, undocumented failure codes in my case. There were several dozen blog posts complaining about many such "magic" issues back then. It was almost comical, to be honest.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This last weekend, I decided to add &lt;a href="http://developer.android.com/guide/market/billing/index.html"&gt;in-app billing&lt;/a&gt; to an app that's already shipping for Android, and I ran into a couple of hiccups that I think are worth documenting here to save others some time/pain. Overall, I think the Android folks learnt from some of the pitfalls that early developers hit with in-app payments on iOS and worked to fix those. The documentation is a lot clearer and precise compared to where iOS was a year ago. Android Market also has a nifty &lt;a href="http://developer.android.com/guide/market/billing/billing_testing.html#billing-testing-static"&gt;static test/response facility&lt;/a&gt; which makes it easy to test code without worrying about external influences. iOS was desperately lacking something of this sort (not sure if it's better now) - I even wrote a dummy implementation of the iOS in-app payment API and the different response conditions to let me test my code in an emulator, which was really helpful. I'm glad Android got this right (still no testing in an emulator though, which is a bummer because of the inability to test with different Android OS versions).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At a high level, the in-app billing protocol on Android is extremely chatty (see the &lt;a href="http://developer.android.com/guide/market/billing/billing_overview.html"&gt;diagrams on this page&lt;/a&gt;). It seems particularly so when compared to &lt;a href="https://www.x.com/community/ppx/xspaces/mobile/mep"&gt;PayPal's rival offering&lt;/a&gt;. PayPal's in-app billing module handles payment using &lt;a href="http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int)"&gt;&lt;code&gt;startActivityForResult&lt;/code&gt;&lt;/a&gt; and &lt;a href="http://developer.android.com/reference/android/app/Activity.html#onActivityResult(int, int, android.content.Intent)"&gt;&lt;code&gt;onActivityResult&lt;/code&gt;&lt;/a&gt; methods which can be used for communicating between child/parent activities. This is very similar to how &lt;a href="https://github.com/facebook/facebook-android-sdk/"&gt;Facebook's Android SDK&lt;/a&gt; handles single sign on. That model is extremely simple to understand and implement for developers - you could probably have it coded up and tested faster than you can finish reading this blog post. I think part of this chattiness is to ensure a higher level of security and also to handle &lt;a href="http://developer.android.com/guide/market/billing/billing_admin.html#billing-purchase-type"&gt;managed purchases&lt;/a&gt;, which are both likely harder to do using PayPal's approach. I assume they had good reason to make it as chatty as it is now, but my gut says that Google loses out on a lot of developers because of this apparent complexity. Having said that, the &lt;a href="http://developer.android.com/guide/market/billing/billing_integrate.html#billing-download"&gt;sample application&lt;/a&gt; Google provides does a really good job of illustrating the various communications that need to occur, so studying that code makes the chattiness easier to understand (for some reason, code registers more easily in my brain than verbose documentation - good code and good documentation together are very rare, and Android seems to have gotten this right - kudos!)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the biggest red flags with using Android's in-app billing, however, is the development teams non-responsiveness to critical bugs. &lt;a href="http://code.google.com/p/marketbilling/issues/detail?id=14"&gt;This issue&lt;/a&gt;, marked critical and accepted, talks about transactions failing 4-6% of the time, and has been active for over two months without an owner being assigned. An equally disturbing issue with &lt;a href="http://code.google.com/p/marketbilling/issues/detail?id=19"&gt;unacceptably long latency&lt;/a&gt; when handling authorization has been open for almost two months without any comment from Google or even an owner being assigned. In fact, browsing the &lt;a href="http://code.google.com/p/marketbilling/issues/list"&gt;issues list&lt;/a&gt; certainly doesn't inspire confidence in the platform. It would be a big mistake by Google to not take these issues seriously. In my case, I'm certainly debating the merit of jumping into this as an early adopter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some other notes about implementing in-app billing on Android:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;It sounds obvious in hindsight, but you need to make sure that your application is signed with the release key before testing in-app billing, even the static response stuff. Developer's aren't used to doing this while debugging, so it's worth calling out in the documentation.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;If you want valid signatures for the JSON responses as suggested by the &lt;a href="http://developer.android.com/guide/market/billing/billing_testing.html#billing-testing-static"&gt;table here&lt;/a&gt;, the "debuggable" attribute in the app manifest should be set to false, even if you're using a release-key-signed APK and static responses. I was a little annoyed by this un-documented restriction because it basically meant that I had to resort to using logging as the only real means of debugging my code. If there is indeed some way to debug this using a debugger (and yet receive valid  signatures), it’s definitely not obvious to me. Again, not a terribly big deal once you realize that this attribute actually seems to affect signatures, but that isn't documented anywhere.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;If you're using a server to validate signatures (&lt;a href="http://developer.android.com/guide/market/billing/billing_best_practices.html#billing-security"&gt;as you should&lt;/a&gt;), be aware that the public key you obtain from the Android Market profile page is a base-64 encoded string. You will almost certainly need to convert it to PEM/DER format or use the x509 certificate for it to be usable with most server openssl implementations.  For instance, this command can be used to convert the base-64 encoded key into a key usable by PHP: &lt;pre&gt;openssl enc -base64 -d -in publickey.base64 -A | openssl rsa -inform DER -pubin &amp;gt; publickey.pem&lt;/pre&gt; Also, if you're using the PHP function &lt;a href="http://php.net/manual/en/function.openssl-verify.php"&gt;&lt;code&gt;openssl_verify&lt;/code&gt;&lt;/a&gt;, remember that &lt;code&gt;$signature&lt;/code&gt; needs to be the binary signature, not the base-64 encoded signature string that the Android Market app sends (I found out the long way).&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Unavailability of subscriptions/auto-billing is a big gap in the offering currently, but I assume support for it is coming soon, since &lt;a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/RenewableSubscriptions/RenewableSubscriptions.html#//apple_ref/doc/uid/TP40008267-CH4-SW2"&gt;iOS already supports it&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;I hit an issue when testing payments using carrier billing, where accepting the carrier ToS basically causes the transaction to get lost somewhere between the carrier and Android Market. I logged &lt;a href="http://code.google.com/p/marketbilling/issues/detail?id=30"&gt;this bug&lt;/a&gt; to track the issue.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Well, I hope that the web-search spiders do their job and this post helps others out there looking at implementing in-app billing on Android. And making Google get a move on those bugs.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://news.ycombinator.com/item?id=2680273"&gt;Discuss this post on Hacker News&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3157181040565612757?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3157181040565612757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3157181040565612757' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3157181040565612757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3157181040565612757'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2011/06/some-notes-on-implementing-in-app.html' title='Some Notes on Implementing In-App Billing on Android'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-6866267991906770319</id><published>2011-03-03T21:42:00.000-08:00</published><updated>2011-03-03T22:55:01.092-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Travel'/><category scheme='http://www.blogger.com/atom/ns#' term='Vacation'/><title type='text'>The India-Trip Penalty</title><content type='html'>Vacations to India from America have a pretty high fixed-cost that significantly eats into the time that can 'actually' count as vacation. Here's the composition of this 'penalty':&lt;div&gt;&lt;ul&gt;&lt;li&gt;Average flying time to get to India, if you don't need a connecting flight at the destination, is 18-22 hours each way depending on where you fly from, the route and layovers. Assuming the actual flight time is an optimistic 20 hours, let's add the 3 hours that it takes to head out to the airport/check-in/security/etc each way, and another 2 hours to clear immigration/customs/etc each way. So, the time to get to and from the vacation is 50 hours.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;When you fly half way around the world, it's hard not to get jet-lagged. Optimistically, you've got to account for at least a half day (&lt;a href="http://cultureshock.kristiejoy.net/jet-lag-help-please/"&gt;a very optimistic assumption&lt;/a&gt;) wasted on both ends of the trip. So you have another 24 hours spent jet-lagged.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;A special perk of visiting India is the high probability that you'll fall ill. Over the years, I've noticed my immunity to the Indian environment (food, water, air, etc) fade. This is true for most people I know who have lived outside of India for &gt; 5 years. During each trip, it's very likely that you'll catch a stomach flu, get food poisoning, a fever, or generally fall sick. If you're lucky, it takes a day of complete rest and another half day of extreme caution to get back on track. So that's another 36 hours of lost vacation right there.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Packing for a trip back from India isn't like packing for a quick flight to San Diego. A good deal of your last day is usually spent planning to pack, and then packing, and then re-packing to make sure your bags are all within weight limits. For those who don't live in metro areas, there's the additional time of travelling to metro areas. So let's throw in another 6 hours for all this.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;So the total penalty of a trip to India is, roughly, 116 hours (a little under 5 days). Regardless of how long your vacation is, you're likely to incur this penalty, give-or-take a few hours. Heck, I would consider a 5-day trip within the US, or even a quick 5-day trip to Mexico, to be a decent vacation in itself. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's pretty amazing to think that for many, the penalty of a vacation to visit friends and family is a whole other vacation. It's no wonder that most people who go to India need/want at least 3 weeks for the vacation to be worth it, and even then they feel gypped (rightly so?).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This also puts into perspective things that you otherwise might not think about. How much would you pay to avoid a 6-hour layover in Amsterdam en-route to India? Would a business-class ticket be worth the time it helps you shave off with airport formalities, jet-lag and worrying about luggage limits?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-6866267991906770319?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/6866267991906770319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=6866267991906770319' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6866267991906770319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6866267991906770319'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2011/03/india-trip-penalty.html' title='The India-Trip Penalty'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3596571275873656661</id><published>2011-01-26T10:46:00.000-08:00</published><updated>2011-01-26T12:58:54.811-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><category scheme='http://www.blogger.com/atom/ns#' term='iOS'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Hey Bing, iOS isn't Windows Phone 7</title><content type='html'>The Bing app for iOS was decent, until recent updates. It looks like someone at Microsoft decided they needed to make the Bing app for iOS look and feel more like a Windows Phone 7 app. So they did, and the result is an ugly, unusable disaster.&lt;br /&gt;&lt;br /&gt;On Windows Phone 7, buttons look like traditional 'labels', but in lower-case font. Clickable elements are very subtly different from text, but yet it's obvious what is clickable and what isn't. The hardware 'back' button, standard on all phones, is used to dismiss modal dialogs. That's how the native interface of the phone (called 'Metro', I believe) is, and it all comes together quite beautifully. Here's what a menu on a native Windows Phone 7 app looks like:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Ec26D924Y3U/TUBudGDnCjI/AAAAAAAAACE/DiVvcq6WMf8/s1600/wp7.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 212px; height: 354px;" src="http://2.bp.blogspot.com/_Ec26D924Y3U/TUBudGDnCjI/AAAAAAAAACE/DiVvcq6WMf8/s400/wp7.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5566570585550948914" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;On iOS, buttons looks like, well, buttons. Clickable elements have depth and curves and are strikingly different from text/labels. There is no hardware back button, so Apple has provided built-in buttons with system fonts and colors which are placed on the top right corner to dismiss modal dialogs. Just like Windows Phone 7, it's well thought out, coherent and comes together beautifully. Here's how menus, buttons and dialogs look on iOS.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center;"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Ec26D924Y3U/TUB8g8cHhgI/AAAAAAAAACU/EkrEO-xBQxM/s1600/IMG_0341.PNG"&gt;&lt;img style="margin:0px auto 10px; padding:0 10px; text-align:center;cursor:pointer; cursor:hand;width: 250px; height: 400px;" src="http://1.bp.blogspot.com/_Ec26D924Y3U/TUB8g8cHhgI/AAAAAAAAACU/EkrEO-xBQxM/s400/IMG_0341.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5566586044851652098" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Ec26D924Y3U/TUB8gthX8PI/AAAAAAAAACM/o3B884vd2n8/s1600/IMG_0342.PNG"&gt;&lt;img style="margin:0px auto 10px;padding:0 10px; text-align:center;cursor:pointer; cursor:hand;width: 250px; height: 400px;" src="http://4.bp.blogspot.com/_Ec26D924Y3U/TUB8gthX8PI/AAAAAAAAACM/o3B884vd2n8/s400/IMG_0342.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5566586040847167730" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Good apps follow &lt;a href="http://en.wikipedia.org/wiki/Human_interface_guidelines"&gt;Human Interface Guidelines&lt;/a&gt; of the platform they're built for, which gives them consistency with the rest of the system and makes interactions with the application intuitive. For some reason, the developers/designers of the Bing iOS app decided to follow the Human Interface Guidelines for &lt;a href="http://docs.google.com/viewer?a=v&amp;q=cache:iax1gbnImpsJ:download.microsoft.com/download/D/8/6/D869941E-455D-4882-A6B8-0DBCAA6AF2D4/UI%2520Design%2520and%2520Interaction%2520Guide%2520for%2520Windows%2520Phone%25207%2520Series.pdf+windows+phone+7+human+interface+guidelines&amp;hl=en&amp;gl=us&amp;pid=bl&amp;srcid=ADGEESjDgT3ywDjqaUzI3V2K9jgDttjbSzj2XbLsSTzDOfFiTmCXOflF1oiRd8pI7Ld_R6HEGKb6IzDGyBEXSqrQgL5Hrsr_vzFlZ0-z0BxhywmEx4haKFrGX9r8gokB_TmsJDqG0jgc&amp;sig=AHIEtbQswcIrqpWDl8j0wljGlixIiUj-tQ&amp;pli=1"&gt;Windows Phone 7&lt;/a&gt; for their iOS app, instead of following the &lt;a href="http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mobilehig/Introduction/Introduction.html"&gt;iOS&lt;/a&gt; HIG guidelines, and the result is just awful.&lt;br /&gt;&lt;br /&gt;Below is what a modal menu on the Bing app looks like on my iPhone (the rest of the app looks similar, and has the same flaws). I have been using apps on my iPhone for two years and yet it took me several minutes to figure out what I needed to do on that dialog. It wasn't obvious how to toggle options on the menu, nor was it obvious how I could dismiss the dialogs. It took me a good two minutes to realize that the 'done' label was infact a button, and that almost everything on that screen was clickable, except the tiny header that reads "MENU". The font size on that label (page header) is smaller than that on the label-buttons, which sounds inverted, and makes the page look ugly. &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center;"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Ec26D924Y3U/TUB-NKkpr2I/AAAAAAAAACc/iBFSNS58xOM/s1600/IMG_0339.PNG"&gt;&lt;img style="margin:0px auto 10px; padding:0 10px; text-align:center;cursor:pointer; cursor:hand;width: 250px; height: 375px;" src="http://4.bp.blogspot.com/_Ec26D924Y3U/TUB-NKkpr2I/AAAAAAAAACc/iBFSNS58xOM/s400/IMG_0339.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5566587904071413602" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Compare this with the image below and notice how obvious and beautiful some of those same options are on the native iPhone mapping application. (This isn't a modal dialog on the native app - if it was, I can guarantee that there would be a blue 'Done' button in the top right corner). &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center;"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Ec26D924Y3U/TUB-NMaoVLI/AAAAAAAAACk/b-zAzAlzrlg/s1600/IMG_0340.PNG"&gt;&lt;img style="margin:0px auto 10px; padding:0 10px; text-align:center;cursor:pointer; cursor:hand;width: 250px; height: 375px;" src="http://3.bp.blogspot.com/_Ec26D924Y3U/TUB-NMaoVLI/AAAAAAAAACk/b-zAzAlzrlg/s400/IMG_0340.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5566587904566252722" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In fact, the entire experience of using the Bing app is so jarring that I refuse to use it at all, in spite of some of its nifty features. And I would be very surprised if I'm the only one who feels that way. It literally feels like Microsoft ported an app that is likely beautiful and usable on Windows Phone 7 to iOS without putting any thought into iOS usability. In fact, my guess is that the developers spent more time trying to make those buttons and table-views looks like Windows Phone 7 than they would have if they just used what the system provided with minor tweaks.&lt;br /&gt;&lt;br /&gt;I cannot come up any reasonable explanation for why the designers of Bing chose to do this. If they want their application to be used, I sincerely hope they fix it soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3596571275873656661?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3596571275873656661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3596571275873656661' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3596571275873656661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3596571275873656661'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2011/01/hey-bing-ios-isnt-windows-phone-7.html' title='Hey Bing, iOS isn&apos;t Windows Phone 7'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Ec26D924Y3U/TUBudGDnCjI/AAAAAAAAACE/DiVvcq6WMf8/s72-c/wp7.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-7695100970856013845</id><published>2011-01-21T15:30:00.000-08:00</published><updated>2011-01-21T16:58:39.059-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><title type='text'>On Mediocre Software - Where is the Love?</title><content type='html'>&lt;div&gt;A recurring theme in some of the feedback we've seen for &lt;a href="http://www.audiogalaxy.com/"&gt;Audiogalaxy&lt;/a&gt; in reviews and direct feedback from users is how surprised they are when everything just works. A lot of the praise that the product has received goes something like this:&lt;/div&gt;&lt;br /&gt;&lt;div style="font-style:italic;padding:5px 20px;"&gt;"Having tried and failed with several similar products I was shocked that when I used Audiogalaxy, it worked! No long delays, no dropping back to the initial screen, no anything wrong, just the music playing for as many hours as I needed."&lt;/div&gt;&lt;br /&gt;&lt;div style="font-style:italic;padding:5px 20px;"&gt;"It does exactly what it's supposed to do. How often do you see that?"&lt;/div&gt;&lt;br /&gt;&lt;div style="font-style:italic;padding:5px 20px;"&gt;"I never write reviews because most apps usually suck, but this is... different."&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I won't feign modesty - we've worked pretty hard to make sure that Audiogalaxy works well. But that's not the point of this post. What statements like the ones above imply is that users are accustomed to underwhelming software. Most people, it seems, approach new software products with skepticism and wariness. Having been bitten by bad software several times in the past, they have become conditioned to assume the worst, and to be surprised when software works as it's expected to. While this might be true of other things too, in this case it points to a collective failure of the software development community. Commoditization of software developers/development and easy software distribution channels seem, on the surface, a boon to the software industry but are also a root cause for this mediocrity that people seem to now expect.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;A telling sign of how extensive this perception is the following email I received from a friend after he used Audiogalaxy:&lt;/div&gt;&lt;br /&gt;&lt;div style="font-style:italic;padding:5px 20px;"&gt;"Frankly speaking, my expectations were not very high. I was like, 'it's gonna be yet another process sucking the life out of my machine'. I was expecting to spend at least 30 minutes configuring everything, but was pretty much done in a couple of clicks and listening to music in a couple of minutes. It blew away my expectations in terms of how light weight it was (like 5 MB of memory and close to 0-1% cpu) and also super responsive in the browser to!!!"&lt;/div&gt;&lt;br /&gt;&lt;div&gt;On the surface, this comment seems to fall into the same bucket at the others above. However, this friend is actually a really good software developer himself. So this default notion of 'crappy software' isn't just users' perception. It is a dirty insider secret - we know about it, we expect it and yet we just suck it up and deal with it.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;It's time to fix this, my fellow software geeks. You may say that people will vote with their money, and that bad software will fall by the wayside, and that the wheat will separate from the chaff, yada yada... All that may be true. But by producing crappy software, we're diluting the value of software as a whole, which eventually trickles down and affects each one of us.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Now this is the part of the post where I really should offer a silver bullet that will 'fix it all' and permanently change users' perceptions. Alas, I'll leave that to folks who are smarter than I. The one thing that I've learnt in my short career, and the only advise I can offer is this:&lt;/div&gt;&lt;br /&gt;&lt;div style="font-style:italic;"&gt;Build software with love, nurture it with care, take pride in its successes and share blame in its failures.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;This mantra won't make you write bug free code or automatically make your software user friendly overnight - that's what experience, skills, iteration and good engineering practices are for. Heck, no software developer is anywhere close to writing 100% bug-free code. However, it will guide you in making decisions that lead to good, solid software which does what it says and says what it does. After all, software isn't just code - it is the culmination of every decision made in its journey from its inception to its current state.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;A world where bad software/technology is an anomaly, not the norm, would be a good world - and it starts with us.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-7695100970856013845?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/7695100970856013845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=7695100970856013845' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7695100970856013845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7695100970856013845'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2011/01/on-mediocre-software-where-is-love.html' title='On Mediocre Software - Where is the Love?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-8600674293146114219</id><published>2010-12-25T23:25:00.000-08:00</published><updated>2010-12-26T11:12:41.076-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Fiji'/><category scheme='http://www.blogger.com/atom/ns#' term='Travel'/><title type='text'>Off the Grid - Food, Diving, Love and Cholera in Paradise</title><content type='html'>Bula! We recently took a trip to the Fiji Islands, and I took this opportunity to go completely off the grid - no cellphone, no computer, no TV, no newspapers. I was afraid I wouldn't last the week and succumb to withdrawal symptoms, but I decided I would give it my best shot. Not happy with just being off the grid, I decided to bring a book with me. If I read it, it would be &lt;a href="http://crazyviraj.blogspot.com/2008/10/regret-not-reading-enough-books.html"&gt;the first book I would read in almost 4 years&lt;/a&gt;. I had heard great things about &lt;a href="http://www.amazon.com/Cholera-Penguin-Great-Books-Century/dp/0140119906"&gt;Love in the Time of Cholera&lt;/a&gt; and it was a genre of books I hadn't ever attempted to read before, so I figured it would be ideal. As luck would have it, the &lt;a href="http://www.kcls.org/bellevue/"&gt;King Country public library in Bellevue&lt;/a&gt; (a most excellent library, by the way) had the book available to check out.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, turns out that the world does continue to turn even if I don't read the news, write some code, catch up on blogs and scan Facebook. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It was a great week full of excellent scuba diving, phenomenal tropical foods and magnificent living in resorts bathed in luxury and relaxation. We spent a few days at &lt;a href="http://new.outrigger.com/hotels-resorts/fiji/viti-levu/outrigger-on-the-lagoon-fiji?hotel=37&amp;amp;"&gt;Outrigger on the Lagoon&lt;/a&gt; near &lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Sigatoka,+Western+Division,+Fiji&amp;amp;sll=37.020098,-95.712891&amp;amp;sspn=83.493485,209.53125&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Sigatoka,+Nadroga-Navosa,+Western+Division,+Fiji&amp;amp;z=16"&gt;Sigatoka&lt;/a&gt; on the main island, Viti Levu. It was larger than I would've preferred, but our plan here was to primarily relax and explore some of the surrounding villages/towns and interact with local Fijians and experience Fijian culture. We did 2 dives at &lt;a href="http://www.dive-the-world.com/diving-sites-fiji-beqa-lagoon.php"&gt;Beqa Lagoon&lt;/a&gt;, but saved the majority of our diving for the latter half of our trip, which was near the more renowned dive sites. Instead, we spent a day relaxing at the resort and enjoying a local bar and another exploring some not-so-touristed surrounding. We got invited to dinner at a local family's house (our taxi driver, who happened to be a 4th generation Fijian Indian), and it was a humbling experience. Our hosts were a warm-hearted family who lived in a modest home in a tiny village who served us lovingly prepared Fijian dishes. The fish lovo, made with a snapper that was caught the previous night, and vegetable curry made with Taro root and star fruit, were delicious.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At the end of this part of the trip, I was done reading about a third of my book, and I hadn't felt the urge to get wired in at all, although internet access was readily available. I read by the pool, on the beach and in the lounge - the book was more interesting than I had imagined, and written in a style that was very refreshing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Our next stop was the &lt;a href="http://www.namalefiji.com/"&gt;Namale Resort &amp;amp; Spa&lt;/a&gt;, home to the &lt;a href="http://www.blogger.com/Most%20Sexiest%20Villas%20in%20the%20South%20Pacific."&gt;Sexiest Villas in the South Pacific&lt;/a&gt;. I knew the resort was good and I had lofty expectations for the price I had paid, but it exceeded my every expectation. From the warm welcome to the teary send-off, I could not have imagined a better way celebrate love. We spent the mornings diving, after having devoured a scrumptious breakfast. We were lucky enough to dive &lt;a href="http://www.youtube.com/watch?v=SWu4DOtkQqY"&gt;Chimneys&lt;/a&gt; and &lt;a href="http://www.youtube.com/watch?v=gfRYAE9Y-RQ"&gt;Grand Central&lt;/a&gt; at the &lt;a href="http://www.namena.org/"&gt;Namena Barrier Reef&lt;/a&gt; on our last day of diving. I cannot imagine a better dive site than Chimneys anywhere in the world. It was magical - I think I could dive Chimneys every day for a year and still be amazed after every dive. After diving, we would partake of the phenomenal 3-course lunch served at a location of our choice (beach, deck, bure... anywhere we felt like eating) and spend the afternoon lazing on the beach, in the spa or indulging in more water activites (snorkel, water ski, etc). After that, some more R&amp;amp;R and drinks to whet the appetite for the gastronomical extravaganza that was dinner, accompanied by island cocktails or wine pairings and the Kava Boys. Every day, we were made to feel special with several personal touches by the staff at the resort - they really treated us like family. If there is paradise, Namale was pretty darn close to what I'd like it to be. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My reading progressed surprisingly well, and I found myself carrying my book to the beach, to the spa and to the outdoor jacuzzi. Save for about a 100 pages in the middle, I was enthralled by the story and the writing. I completed the book at the airport lounge prior to departure, and it had lived up to it's hype. It was Gabriel Marquez' ode to the myriad forms of love - spurned love, unrequited love, illicit love, love at first sight, true love, love that grows and fades over time and love that cannot really be classified. I got lucky with this book - I couldn't have picked a more appropriate book for the occasion. The fact it was a literary masterpiece didn't hurt either.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyways, all good things end, and so did our week in paradise. I hope one day to return to this lap of luxury in the midst of the &lt;a href="http://www.interestingworldfacts.com/general/10-friendliest-countries-in-the-world.html"&gt;friendliest people in the world&lt;/a&gt;. Until then, it's back to regularly scheduled programming.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-8600674293146114219?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/8600674293146114219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=8600674293146114219' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8600674293146114219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8600674293146114219'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/12/off-grid-food-diving-love-and-cholera.html' title='Off the Grid - Food, Diving, Love and Cholera in Paradise'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-8888502399577351944</id><published>2010-09-28T18:14:00.000-07:00</published><updated>2010-09-28T20:11:11.226-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random'/><title type='text'>Fun facts about Pilots</title><content type='html'>On a recent flight, I sat alongside a pilot who was returning home to the Seattle area. A lot of interesting things came up in my chat with the pilot, stuff I didn't really know about:&lt;div&gt;&lt;ul&gt;&lt;li&gt;Pilots fly free on all domestic routes, regardless of airlines. All airlines have an agreement to lets each others' pilots occupy empty seats.&lt;/li&gt;&lt;li&gt;If no seats are available, the travelling pilot can also occupy an extra seat in the cockpit that is usually empty.&lt;/li&gt;&lt;li&gt;Pilots retire at 65(!).&lt;/li&gt;&lt;li&gt;The pilot I spoke with had been flying for 30 years. His pay/benefits today are half what they were 20 years ago (adjusted for inflation).&lt;/li&gt;&lt;li&gt;Until ~10 years ago, most commercial pilots came from the military (air force/navy). Now, it's about 50% military and 50% from pilot schools.&lt;/li&gt;&lt;li&gt;For pilots, career all about seniority. If this guy (a captain currently) were to leave his airline and join another airline he would start as a flight engineer. That's one level below first officer, who is below captain. This is a result of unionization.&lt;/li&gt;&lt;li&gt;Flights longer than 8 hours require 3 pilots (1 captain and 2 first officers) to rotate flying duties. Flights longer than 12 hours require 4 pilots (1 captain and 3 first officers). They usually fly 3-4 hour shifts.&lt;/li&gt;&lt;li&gt;Pilots at traditional airlines (American, Continental) make more than pilots at startup airlines (Virgin America, Jet Blue).&lt;/li&gt;&lt;li&gt;Airlines like Horizon Air/American Eagle/etc serve as training grounds for pilots, who then move to the more lucrative airlines.&lt;/li&gt;&lt;li&gt;On average, pilots fly between 9 and 14 days a month.&lt;/li&gt;&lt;li&gt;Pilots train on simulators every 9 months, and typically work on hard scenarios like dual engine failures once every couple of years.&lt;/li&gt;&lt;li&gt;Boeing and MD planes have "steering wheel" type controls. Airbus has fly-by-wire joystick like controls.&lt;/li&gt;&lt;li&gt;A 737 needs about 6000 feet to land comfortably. Headwind makes a huge difference in amount of runway needed.&lt;/li&gt;&lt;li&gt;Airbus planes felt more "robust" to this pilot.&lt;/li&gt;&lt;li&gt;Bird hits are more common than passengers realize.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=iAxAso8xSo0"&gt;Tegucigalpa, Honduras&lt;/a&gt;, is the hardest airport that he's landed in. Overshooting the 5000 foot runway drops you off a cliff and on to a strip mall. There have been 2 crashes in the last few years, with one dead pilot.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-8888502399577351944?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/8888502399577351944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=8888502399577351944' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8888502399577351944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8888502399577351944'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/09/fun-facts-about-pilots.html' title='Fun facts about Pilots'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-4116431680482321906</id><published>2010-09-09T10:29:00.000-07:00</published><updated>2010-09-09T10:37:46.108-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Google Instant's biggest win? Teaching users to search better</title><content type='html'>&lt;div&gt;The biggest impact of Google Instant is that it teaches users how to search more effectively. Based on these dynamic results, users can tweak their query such that it helps them find the exact answer they were looking for, even if they started with a bad query. Teaching users how to improve their search query is huge. The immediate impact is that it improves users' perception of Google's search results. Same with speed - users will perceive Google as being much faster than anything else out there because of the instant results.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Perception is reality. Speed and relevance are a search engines bread &amp;amp; butter. I think Google just upped the ante by a lot. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Credit to Microsoft though - this probably wouldn't have happened if it weren't for Bing's recent gains. Proof that competition provides the best kick-in-the-pants needed to innovate.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-4116431680482321906?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/4116431680482321906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=4116431680482321906' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4116431680482321906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4116431680482321906'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/09/google-instants-biggest-win-teaching.html' title='Google Instant&apos;s biggest win? Teaching users to search better'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3603962518244077862</id><published>2010-09-03T12:30:00.000-07:00</published><updated>2010-09-03T16:06:12.296-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Three20'/><title type='text'>Integrating Core Data into your Three20 App</title><content type='html'>The &lt;a href="http://three20.info/"&gt;Three20 library&lt;/a&gt; for iPhone app development is pretty cool - it take care of a lot of the 'mundane' code that you might need to write to accomplish basic tasks. Apple really should include some of the functionality of Three20 in the iPhone SDK itself, specially the Network stack.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As I built a more advanced app using Three20, I realized that it would be great to be able to persist to a database to make loading quicker when state on the server is unchanged. I needed some pretty basic Core Data integration in my app, and it was a little annoying that Three20 didn't have a Core Data-backed implementation of TTModel built into it. It seems like a lot of people want this, but there isn't any good post about it I could find. Jeff Verkoey, who currently maintains Three20, started writing a &lt;a href="http://github.com/jverkoey/Three20-Tutorials"&gt;Core Data based tutorial&lt;/a&gt; but didn't get around to actually doing much with it. And there are a few threads in the Three20 Google group but nothing too comprehensive.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having built this for my app, I figured I would post some more concrete information here for others who might find it helpful. I really want to just contribute a clean cut of this code as a &lt;code&gt;TTCoreDataModel&lt;/code&gt; with unit tests to the Three20 source, but I don't have the luxury to spend time on it currently.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So here's a quick step-by-step on how to modify your existing Three20 based app to add basic Core Data support. The specific example I use fetches data from a server using &lt;code&gt;TTURLRequestModel&lt;/code&gt; and writes it out to SQLite using Core Data entities. When displaying data to the user, it fetches data from Core Data using a &lt;code&gt;&lt;a href="http://developer.apple.com/iphone/library/documentation/CoreData/Reference/NSFetchedResultsController_Class/Reference/Reference.html"&gt;NSFetchedResultsController&lt;/a&gt;,&lt;/code&gt; which efficiently interacts with Core Data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Step 1:&lt;/u&gt;&lt;br /&gt;Add CoreData.framework to your list of dependencies. Then, add the Core Data stack. Usually, you would do this in the AppDelegate. Jeff's &lt;a href="http://github.com/jverkoey/Three20-Tutorials/tree/master/github/Classes/"&gt;AppDelegate files&lt;/a&gt; have this implemented, if you want an example. In my case, I wanted different databases for different Models, so I had these in my TTModel implementations.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Step 2:&lt;/u&gt;&lt;/div&gt;&lt;div&gt;Create your model. Add a new file of type "Data Model" in XCode (available in the 'Resource' section). Make sure the .xcdatamodel file gets added to your Target so that it's compiled into your binary. Look &lt;a href="http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeCoreDataTools/Introduction/Introduction.html"&gt;here&lt;/a&gt; for information on using the modeling tool. Once you've created your model, &lt;a href="http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeCoreDataTools/Articles/xcdCodeGeneration.html#//apple_ref/doc/uid/TP40006872-SW1"&gt;import the code for the Entity objects&lt;/a&gt; into your project. Now you're ready to start using Core Data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Step 3:&lt;/u&gt;&lt;/div&gt;&lt;div&gt;Update your TTURLRequestModel implementation. Let's assume you're simply downloading some JSON and want to write it out to Core Data as an Entity you created in Step 2. Update your &lt;code&gt;(void)requestDidFinishLoad:(TTURLRequest*)request&lt;/code&gt; implementation of &lt;code&gt;TTURLRequestDelegate&lt;/code&gt; as follows:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://pastebin.com/embed_iframe.php?i=yJebq7Mz" style="border:none;width:100%"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;A few notes about the code above:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;DBResource&lt;/code&gt; is my simple entity containing an "id" and a "name".&lt;/li&gt;&lt;li&gt;The&lt;code&gt; NSAutoreleasePool&lt;/code&gt; helps clean up memory allocated in this tight loop here&lt;/li&gt;&lt;li&gt;&lt;code&gt;-reset&lt;/code&gt;ing the context makes sure that the data &lt;a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html"&gt;faults in&lt;/a&gt; as needed instead of staying in memory when you read it using the &lt;code&gt;NSFetchedResultsController&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Step 4:&lt;/u&gt;&lt;/div&gt;&lt;div&gt;In your &lt;code&gt;TTTableViewDataSource&lt;/code&gt; implementation, create a &lt;code&gt;NSFetchedResultsController&lt;/code&gt; and configure it to fetch your Entities as needed. Then, override the &lt;code&gt;(id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)indexPath&lt;/code&gt; method to return a &lt;code&gt;TTTableItem&lt;/code&gt; built using the Entity you fetched from Core Data&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://pastebin.com/embed_iframe.php?i=zYXEADhb" style="border:none;width:100%"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Now, your TTTableViewDataSource is configured to read results from the DB you created and display them in your view. Remember that &lt;code&gt;tableViewDidLoadModel&lt;/code&gt; can be called multiple times, so clean up any previously allocated &lt;code&gt;NSFetchedResultsController&lt;/code&gt; if you need to.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Step 5:&lt;/u&gt;&lt;/div&gt;&lt;div&gt;Implement your logic to delete/update your Core Data entities. Depending on how your app uses data persistence, you want to ensure that you update/delete your entities from Core Data. For instance, if you always want to fetch data from the server and load them into Core Data on first run, then update Step 3 to first delete all entities. If you wish to show local data when available but fetch when not, then update Step 3 to not hit the server before checking locally. When deleting entities, remember that Core Data only lets you delete a single entity at a time (so you must fetch all and loop through each to delete it). If you want &lt;code&gt;DROP TABLE ...&lt;/code&gt; semantics you're going to need to maintain different &lt;code&gt;NSManagedObjectContent&lt;/code&gt; and &lt;code&gt;NSPersistentStoreCoordinator&lt;/code&gt; for each such table, and then simply delete the database file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, this isn't too hard really. Assuming you're familiar enough with building your Three20 app, my notes above should help you get started with integrating Core Data into your app. My app uses a &lt;code&gt;TTSectionedDataSource&lt;/code&gt;, and with a few tweaks to &lt;code&gt;NSFetchedResultsController&lt;/code&gt; it's simple to do that too.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3603962518244077862?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3603962518244077862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3603962518244077862' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3603962518244077862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3603962518244077862'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/09/integrating-coredata-with-three20.html' title='Integrating Core Data into your Three20 App'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-7519454376542459291</id><published>2010-08-07T08:31:00.000-07:00</published><updated>2010-08-07T09:38:17.102-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><title type='text'>An Apple A Day Keeps the Bugs Away</title><content type='html'>I've been working from home for the last year or so, and it has tremendously increased my productivity as a developer. Besides the obvious reasons (lack of distractions, no meetings, etc) there is one other advantage that I haven't often heard people mention before.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have been able to find solutions to some really hard technical problems much quicker, and I attribute it to the fact that I work from home instead of in a more office-like environment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Most software engineers will tell you that some of their best ideas have come to them when doing the most mundane of things - taking a shower, strolling across lawns, eating a snack and so on. I don't know the psychology behind this, but I know it's true for me. Something about being alone and thinking about your problem subconsciously, and yet being physically distracted with an unrelated task seems to work wonders. I have solved more tough problems while in the shower, when sitting down to eat an apple, when watering the plants or simply doing the dishes than I have sitting at a desk and just thinking. So obviously, being at home makes it much easier for me to find one of these mundane tasks that let me 'detach' and yet perform an activity that is beneficial to me both personally and professionally.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's become a pretty important weapon in my software development arsenal - if I'm stuck on something for more than 30 minutes, I get out of my workspace and go do something mundane around the house or eat a quick snack. More often than not a solution magically appears in my head. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Back when I worked in an office, if I was stuck trying to solve a hard problem my best option was to find someone familiar enough with the problem space and bounce ideas off of them. This worked pretty well initially but didn't scale too well with problems that became narrower and deeper in scope - I often found myself spending a lot of time trying to catch others up to where it would be valuable to bounce ideas off them. And heading off into the office kitchen to reorganize stuff or watering random plants around the office would just make me look weird.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, the next time you're having a hard time finding a solution to a problem in the office think about taking the next day off and working from home. Oh, and make sure the dishes aren't done. ;)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-7519454376542459291?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/7519454376542459291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=7519454376542459291' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7519454376542459291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7519454376542459291'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/08/apple-day-keeps-bug-away.html' title='An Apple A Day Keeps the Bugs Away'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-5661900898763607998</id><published>2010-06-02T00:50:00.000-07:00</published><updated>2010-06-02T10:28:20.332-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Chrome'/><title type='text'>Slow onclick Javascript handling in Google Chrome 5.0.375.55</title><content type='html'>&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Google's&lt;/span&gt; Chrome has been a pretty slick browser, and it's speed was the primary reason it became my default browser. The &lt;a href="http://code.google.com/p/v8/"&gt;V8 Javascript engine&lt;/a&gt; supposedly blows other engines out of the water, and it did feel noticeably faster than others - until this latest version.&lt;div&gt;&lt;br /&gt;Sometime last week, my version of Chrome was auto updated to 5.0.375.55, and I noticed that the website I've been developing became terribly slow. Because of &lt;a href="http://code.google.com/p/chromium/issues/detail?id=33441"&gt;a previous Chrome bug&lt;/a&gt;, I hadn't migrated my site from &lt;a href="http://jquery.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;jQuery&lt;/span&gt;&lt;/a&gt; 1.3 to 1.4, so one of the first things I did was verify the fix and then update my site to use the newer, faster &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;jQuery&lt;/span&gt;. As I began testing, I noticed a significant reduction in performance of some features on my site.&lt;br /&gt;&lt;br /&gt;Initially I suspected it had something to do with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;jQuery&lt;/span&gt; upgrade. After a few hours of changing things around, I was pretty convinced the problem wasn't &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;jQuery&lt;/span&gt; 1.4. I noticed that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Firefox&lt;/span&gt; and even IE 8 didn't exhibit this latency, so now I started to suspect the new version of Chrome. I hacked up a couple of test pages, and I think I found the culprit. It looks like the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;onclick&lt;/span&gt; handler's performance degrades with the size of the HTML page, resulting in a very noticeable (1-2 second) lag once you have a table with 3000/4000 rows. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Firefox&lt;/span&gt; and IE 8 don't seem to have any trouble handling this.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've logged &lt;a href="http://code.google.com/p/chromium/issues/detail?id=45620"&gt;Issues 45620&lt;/a&gt; in the Chromium project with details and a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;repro&lt;/span&gt; to track this problem. This definitely isn't good news for me - with growing adoption of Chrome and general perception that Chrome is the fastest browser, problems like these make website look faulty even when they might not be.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As an aside, I have noticed that Chrome feels like it has regressions more often than other browsers (perhaps a function of shipping more often?) I've run into several issues developing for Chrome - the silver lining is that bug fixes are quicker than rival browsers, but better &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;QA&lt;/span&gt; before release would certainly help developers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Other Chromium issues that I've had trouble with and have had to work around are &lt;a href="http://code.google.com/p/chromium/issues/detail?id=7771"&gt;Issue 7771&lt;/a&gt;, &lt;a href="http://code.google.com/p/chromium/issues/detail?id=30693"&gt;Issue 30693&lt;/a&gt;, &lt;a href="http://code.google.com/p/chromium/issues/detail?id=33441"&gt;Issue 33411&lt;/a&gt; and &lt;a href="http://code.google.com/p/chromium/issues/detail?id=36559"&gt;Issue 36559&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Update&lt;/b&gt;: An &lt;a href="http://code.google.com/p/chromium/issues/detail?id=45620#c1"&gt;comment on Issue 45620&lt;/a&gt; identifies one of the reasons for the slowdown and a workaround.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-5661900898763607998?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/5661900898763607998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=5661900898763607998' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5661900898763607998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5661900898763607998'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/06/slow-onclick-javascript-handling-in.html' title='Slow onclick Javascript handling in Google Chrome 5.0.375.55'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-5714641633322182811</id><published>2010-05-19T01:26:00.000-07:00</published><updated>2010-05-19T02:07:01.322-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><title type='text'>Showing the Cancel button in UIActionSheets on iPad</title><content type='html'>In it's &lt;a href="http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadHIG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009446"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;iPad&lt;/span&gt; Human Interface Guidelines&lt;/a&gt; Apple provides several guidelines about how user experience should differ between &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;iPhones&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;iPads&lt;/span&gt;. One such element that should behave differently is the &lt;a href="http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadHIG/UIElements/UIElements.html#//apple_ref/doc/uid/TP40009446-CH6-DontLinkElementID_32"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;UIActionSheet&lt;/span&gt;&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Apple recommends that cancel buttons not be shown for action sheets on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;iPad&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  ;font-family:'Lucida Grande', Geneva, Helvetica, Arial, sans-serif;font-size:13px;"&gt;&lt;blockquote&gt;Because taps outside the popover dismiss the action sheet without selecting an item, this results in a default way to cancel the sheet. Including a cancel button would therefore only cause confusion.&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;But the guidelines do allow exceptions to this rule:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  ;font-family:'Lucida Grande', Geneva, Helvetica, Arial, sans-serif;font-size:13px;"&gt;&lt;blockquote&gt;However, if you have an existing popover and are displaying an action sheet on top of other content using an animation, a cancel button is still appropriate.&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;So you would think following this guideline is as simple as not specifying a cancel button in most cases, and only specifying a cancel button when you have carefully considered the exception case, right? Wrong. Even when you do specify a cancel button, it looks like the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;iPad&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;runtime&lt;/span&gt; &lt;i&gt;automatically always hides it&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So how do you provide a cancel button in the exception case? You could just provide another normal button that has cancel behavior, but that's not ideal because you really want the difference in appearance that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;UIActionSheets&lt;/span&gt; on iPhone provide by default. After some tinkering, the best solution I could find was to set the &lt;span class="Apple-style-span"   style="  ;font-family:Courier, Consolas, monospace;font-size:13px;"&gt;&lt;a href="http://developer.apple.com/iphone/library/documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html#//apple_ref/occ/instp/UIActionSheet/actionSheetStyle" style="text-decoration: none; "&gt;&lt;span class="Apple-style-span"  style="color:#3366FF;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;actionSheetStyle&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="color:#3366FF;"&gt; &lt;/span&gt;&lt;/span&gt;property of the &lt;a href="http://developer.apple.com/iphone/library/documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;UIActionSheet&lt;/span&gt;&lt;/a&gt; to &lt;span class="Apple-style-span"  style="color:#3366FF;"&gt;&lt;a href="http://developer.apple.com/iphone/library/documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UIActionSheetStyleBlackOpaque" style="text-decoration: none; "&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;UIActionSheetStyleBlackOpaque&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I can speculate why this works, but I don't know for certain so I'd rather not. If you know of a better/more correct way to do this, please do leave a comment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am surprised that Apple was mindful enough to list the exception case, and yet careless enough to not provide documentation on how to handle this case - they even seem to have forgotten to document that the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;iPad&lt;/span&gt; automatically overrides user-provided cancel buttons by default.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-5714641633322182811?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/5714641633322182811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=5714641633322182811' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5714641633322182811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5714641633322182811'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/05/showing-cancel-button-in.html' title='Showing the Cancel button in UIActionSheets on iPad'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-1496669558462322777</id><published>2010-05-08T18:21:00.000-07:00</published><updated>2010-05-10T09:35:21.266-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Paris'/><category scheme='http://www.blogger.com/atom/ns#' term='Travel'/><title type='text'>Notes from a Week in Paris</title><content type='html'>&lt;div&gt;I just got back from a lovely week in Paris with my wife - it was a rejuvenating and much required holiday for both of us. Work has been crazy, for her especially. Paris was wonderful and more than lived up to my expectations. We rented a tiny little studio in &lt;a href="http://www.parismarais.com/welcome-to-le-marais.htm"&gt;Le Marais&lt;/a&gt; (~120 sq ft, fully equipped including a washer - extremely efficient use of space!) Spending the entire week gave us enough time to explore sights, sounds and tastes of Paris without too much of a rush.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are lots of books and blogs about visiting Paris and things to do/see. We used a bunch of resources - advice from friends, &lt;a href="http://www.lonelyplanet.com/campaigns/iphone/"&gt;Lonely Planet's excellent iPhone app&lt;/a&gt;, the very insightful &lt;a href="http://www.secretsofparis.com/"&gt;Secrets of Paris&lt;/a&gt; website with lots of tips on what to see and do and &lt;a href="http://parisbytrain.com/"&gt;Paris By Train&lt;/a&gt; for everything related to using Paris' excellent rail network. However, there were some things I hadn't read about or was surprised by:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Cafés, brasseries and boulangeries/patisseries often have different prices for take away (&lt;i&gt;emporter&lt;/i&gt;), eating inside (&lt;i&gt;sallé&lt;/i&gt;) and terrace dining. Most cafés/brasseries offer set menus (&lt;i&gt;Formulae&lt;/i&gt;) and chef's recommendations which change daily (menu and price). They are almost always much more cost effective than ordering a-la-carté.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The French are very proper. You greet business owners when you enter their store/café and thank/greet them before you leave. Sprawling across lush, green lawns in the several Parisian parks (&lt;i&gt;Jardins&lt;/i&gt;) or putting your feet up on empty train seats is frowned upon. You sit in chairs provided in the &lt;i&gt;Jardins&lt;/i&gt; and sit up straight in trains.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Freshly squeezed orange juice (&lt;i&gt;jus d'orange pressé&lt;/i&gt;) is extremely popular. You'll find orange juice machines pretty much everywhere (including Starbucks), but it's best to find a green-grocer/fruit vendor and get a half-litre jar of fresh squeezed juice each morning. Fruit vendors are everywhere.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;By default, coffee means espresso. A cappuccino/café-au-lait at most Cafés is expensive (between 4-8 EUR) and isn't that great (for a Seattlelite, at least). A mocha at Starbucks is EUR 4.50. Little créperies or street cafés have better deals for coffee that tastes identical (1-2 EUR). Or, hit up a &lt;a href="http://www.mccafecoffee.com/"&gt;McCafé&lt;/a&gt;. A 'mocha' is called a 'chocochino' and isn't commonly available.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sit-down créperies are totally not worth the price/experience. Get a crépe from a street vendor/corner shop and sit in a park or a street bench. The more exotic crépes (savory &amp;amp; sweet) are only available in nicer establishments, obviously.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Wine/liquor is available in grocery stores (&lt;i&gt;supermachés&lt;/i&gt;). &lt;i&gt;Supermachés&lt;/i&gt; open around 8:30am and shut around 8:30pm. You are expected to bag your own groceries. For late-night grocery runs, there's usually a little-store-that-sells-most-things every few blocks which stays open late (2am)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Bars have later Happy Hours than in the US. Happy Hour generally runs from 6pm to 9-10pm. Folks eat dinner late (most restaurants stay open until 11pm).&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Time is specified using 24 hour notation. "What time do you shut?" is answered with "23 hours". Most people don't understand am/pm.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Take binoculars to fully appreciate the amazing art/architecture details.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use the '&lt;a href="http://www.velib.paris.fr/"&gt;Vélib&lt;/a&gt;' shared bike service. Vélib stations are everywhere, the roads and drivers are biker-friendly and it is the cheapest and most convenient way to get between locations in the city. Buy a map-book that has streets sorted by districts (&lt;i&gt;arrondissements&lt;/i&gt;) and also has metro/Vélib stations marked.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It is not common for &lt;i&gt;crémeries&lt;/i&gt;/gelaterias to offer tastes.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;On the metro, or just walking around, you'll see a significant number of people going home (presumably) with one or more fresh baguettes from the bakery. For some reason almost all of these people are men. Join the crowd - fresh baguettes are the only way to go. Bread is baked fresh twice a day (if not continuously).&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When you pay cash, check the change you get back. Parisians are either terrible at math or prone to short-changing customers. I routinely got back incorrect change, on average twice a day.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Before you go to a specific place (café, boulangerie, museum, grocery store, monument) on a Saturday/Sunday/Monday check before you head out. Almost every establishment is closed on at least one or more of these days.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Strange, English speaking 'beggar women' holding hand-written post cards will randomly approach you at monuments/museums and ask "Speak English?". I didn't quite figure out what the scam was (I never answered "Yes") but this is most certainly some sort of scam.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Comt%C3%A9_(cheese)"&gt;Comté&lt;/a&gt; tastes awesome, and is the most popular cheese. &lt;a href="http://en.wikipedia.org/wiki/Camembert"&gt;Camembert&lt;/a&gt; is a close second. Get cheese fresh from your neighborhood &lt;i&gt;fromagerie&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you decide to cook at home, chances are good that you'll find an Italian store nearby selling freshly prepared pastas and raviolis that you can cook at home, in addition to a large number of other Italian foods (including freshly prepared Tiramisu).&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-1496669558462322777?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/1496669558462322777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=1496669558462322777' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1496669558462322777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1496669558462322777'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/05/notes-from-week-in-paris.html' title='Notes from a Week in Paris'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-6040203816803263246</id><published>2010-04-19T06:40:00.000-07:00</published><updated>2010-04-19T06:40:00.659-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Voice'/><title type='text'>Why I use Google Voice for SMS</title><content type='html'>I have an iPhone with AT&amp;amp;T service, but I recently started using Google Voice for most of my SMS needs. SMSes sent to my Google Voice number are forwarded to my email. It works great for me:&lt;div&gt;&lt;ul&gt;&lt;li&gt;I don't want to pay AT&amp;amp;T any more than I have to. I use AT&amp;amp;T out of necessity, not choice.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;GMail has support for Exchange ActiveSync, and is the default Exchange account on my iPhone. So I get notified of the SMS in email on the phone as soon as it is received (assuming I have data coverage, which is pretty much all of the time) giving me the equivalent of the native SMS experience.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;a href="https://chrome.google.com/extensions/detail/kcnhkahnjcbndmmehfkdnkjomaanaooo"&gt;Google Voice extension for Chrome&lt;/a&gt;. Chrome is my default browser, I'm in front of a computer for a large part of the day, and my browser is usually open. I can read, send and reply to SMSes using a full keyboard and without exiting the browser, instead of pulling out my iPhone and fiddling with the tiny keyboard to type out a message. So much more convenient!&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;All my SMSes are archived and made searchable not only by Google Voice, but also by GMail. Win.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-6040203816803263246?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/6040203816803263246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=6040203816803263246' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6040203816803263246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6040203816803263246'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/04/why-i-use-google-voice-for-sms.html' title='Why I use Google Voice for SMS'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-1032030866786999370</id><published>2010-04-18T11:07:00.000-07:00</published><updated>2010-04-18T19:19:15.362-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Experiences'/><title type='text'>Living Every Developer's Wet Dream</title><content type='html'>Back in June I wrote about &lt;a href="http://crazyviraj.blogspot.com/2009/06/new-technology-for-me-roundup.html"&gt;new technologies I had started working with&lt;/a&gt; and my experiences learning those technologies. Having continued working with most of those since then, I've become incredibly comfortable and proficient with them. It's pretty normal to have a week where I write a bunch of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;PHP&lt;/span&gt;, a few &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;SQL&lt;/span&gt; queries, some fancy Javascript, learn new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;CSS&lt;/span&gt; tricks, hack up features in client software using Win32/Cocoa, debug some corner-case issue using logs and a mini-dump and also write some straight up C/C++ server side code with unit tests. Initially, jumping languages and client/server boundaries came with large context-switch penalties but it's become almost second nature now, which feels very empowering and has had a dramatic impact on productivity.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then, there are the one-offs - new technologies that need to be learnt, integrated into the product/service (in a way that's easy to understand/change in the future) and then 'forgotten' before moving on to the next one. These tend to be client-side technologies usually - server side stuff is much more on-going and stable. Some of the 'bigger' things I've done in the last 6-9 months that would fall into this one-off category are:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;Fiddling around with HTML5 &amp;amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;lt&lt;/span&gt;;audio&amp;gt; and &amp;amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;lt&lt;/span&gt;;video&amp;gt; before giving up&lt;/u&gt;&lt;br /&gt;For all the promise of new HTML5 multimedia standards, the sad reality is that we are far from any consensus. Different stakeholders have different motivations, which leaves the issue of a &lt;a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-June/020620.html"&gt;single standard &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;codec&lt;/span&gt; up in the air&lt;/a&gt;. The proprietary nature of &lt;a href="http://www.adobe.com/products/flash/"&gt;Flash&lt;/a&gt;, licensing issues surrounding &lt;a href="http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC"&gt;H.264&lt;/a&gt;, Apple's opposition to including &lt;a href="http://en.wikipedia.org/wiki/Ogg_Theora"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Ogg&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Theora&lt;/span&gt;&lt;/a&gt; in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Quicktime&lt;/span&gt; and Microsoft's silence have resulted in the current stalemate. And this shows when you experiment with the different browsers. Development for web/mobile-web is poised to become radically easier once/if this is sorted out, but there is a lot of pain to be endured before then - pain that wasn't worth it to me presently.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Flash audio support&lt;/u&gt;&lt;br /&gt;Having decided to not want to build a flash media &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;plugin&lt;/span&gt; myself, I first played around with &lt;a href="http://flash-mp3-player.net/"&gt;this MP3 Player&lt;/a&gt; and later switched to the much more powerful &lt;a href="http://www.schillmania.com/projects/soundmanager2/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;SoundManager&lt;/span&gt;2&lt;/a&gt;. With a few tweaks, I was able to make it do exactly what I wanted.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.developers.facebook.com/index.php/Facebook_Connect"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Facebook&lt;/span&gt; Connect&lt;/a&gt;&lt;br /&gt;For single sign-on and any sort of social media integration, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Facebook&lt;/span&gt; Connect is a must have. Having implemented &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;Facebook&lt;/span&gt; Connect for my website and for &lt;a href="http://wiki.developers.facebook.com/index.php/Facebook_iPhone_SDK"&gt;iPhone&lt;/a&gt;, I must say that I am very pleased with the facilities offered by the platform and the consistency across client/server applications. &lt;a href="http://wiki.developers.facebook.com/index.php/XFBML"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;XFBML&lt;/span&gt;&lt;/a&gt; and &lt;a href="http://wiki.developers.facebook.com/index.php/FQL"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;FQL&lt;/span&gt;&lt;/a&gt; are nice touches. My only gripe is that, for a mature and widely adopted platform, documentation seems disproportionately poor as compared to the richness of the Platform &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;APIs&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Online Payments&lt;/u&gt;&lt;br /&gt;There's a lot you learn about how safe online transactions really are (&lt;i&gt;they're not) &lt;/i&gt;when you dive into how payments really work. I developed a quick payment portal using &lt;a href="https://www.paypal.com/cgi-bin/webscr?cmd=_payflow-pro-overview-outside"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Payflow&lt;/span&gt; Pro&lt;/a&gt; by &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;PayPal&lt;/span&gt;. Can't really vouch for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;Payflow&lt;/span&gt; Pro yet, though. A few weeks after I finished working with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;Payflow&lt;/span&gt; Pro, &lt;a href="https://www.x.com/index.jspa"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;PayPal&lt;/span&gt; X&lt;/a&gt; was announced. I'll eventually get around to migrating to it, I guess.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Identicon"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;Identicons&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;Simple, cute, pretty. I use the ones provided by &lt;a href="http://blog.gravatar.com/2008/04/22/identicons-monsterids-and-wavatars-oh-my/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;Gravatar&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Javascript Craziness&lt;/u&gt;&lt;br /&gt;One of the crazier things I've done, among others, with Javascript is to try and emulate a desktop-software like user experience in a website. Dragging, dropping, keyboard navigation, sorting, multi-select with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;Ctrl&lt;/span&gt;/Shift/Meta... oh boy! It look a while, but with some help from &lt;a href="http://jqueryui.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;jQuery&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;UI&lt;/span&gt;&lt;/a&gt; (the different components work great individually, but try to also make a sortable a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;draggable&lt;/span&gt; and a selectable, and you're in a world of hurt) and a lot of long nights, I finally got a lot of this done. For &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;Forefox&lt;/span&gt;. Then I spent some time making it work for Chrome. And then a whole bunch of more time making it work for IE8. It sorta works in IE7, and not at all in IE6, but honestly if you're still using those browsers you should be chastised. Someday, I want to wrap all this into my own little &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;plugin&lt;/span&gt; that others can use. If you told me a year ago that I would be some kind of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;JS&lt;/span&gt; nut, I would have laughed. Ha!&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;iPhone web-app (before I ditched it for a full blown iPhone app)&lt;/u&gt;&lt;br /&gt;Not wanting to deal with Apple and their strange &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;AppStore&lt;/span&gt; practices, I decided to try and be really creative with native &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;Quicktime&lt;/span&gt; support built into Safari on the iPhone. I almost got all the way to hacking up really neat functionality, complete with callback from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;Quicktime&lt;/span&gt; into my website, background playback and an rich interactive experience. With Flash coming soon to other mobile platforms, this would have been ideal for providing mobile experiences without needing multiple platform-specific applications. However, the iPhone web app felt clumsy and not polished, so I ditched it and went the iPhone app route. I reserve comment on my experiences with development for the iPhone - my app hasn't been submitted/approved yet. ;)&lt;br /&gt;I also foresee myself playing with other mobile development platforms in the very near future. I think a blog post comparing my experiences with the different platforms might make for good reading.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;In addition to these one-offs, there are the perpetual how-will-it-scale and how-will-it-perform issues that need to be considered for every little feature. One of the harder lessons for me was to change my default mindset about how I approached design. While I wouldn't say I optimized prematurely, my design was heavily influenced by potential for optimization. (segue: This, I now realize, is a result of my years at Microsoft. At companies like Microsoft, you do things once and you do them right - rapid iteration is often not possible or not practical. So, while this approach has its merits it's not ideal for agility in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;startup&lt;/span&gt; environments). The new approach that's imbued into me now is to build it quick and make it simple first. Simplicity is the bedrock of agility. Simpler code is easier to revisit and to scale. Complexity is technical debt that you don't really need or want.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What's the biggest thing I've learnt in the last year? I learnt how to learn efficiently. &lt;/div&gt;&lt;div&gt;You can spend hours studying/learning about something and barely scratch the surface. Or you can study to retain information for very short periods of time. Exceptional developers are able to identify when they need to deep-dive vs when they need to simply skim the surface. They can instinctively answer the "How do you learn enough to make well informed decisions and yet don't spend a disproportionate amount of time learning without producing?" question. Transient learning is only good when you never need to revisit a decision - such cases are rare. Otherwise, learning to execute quickly and leaving a trail behind you is a crucial skill. I believe I'm well on my way down this path.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So yes, in many ways I am living a developer's wet-dream. And fortunately, I am able to do a little more than just development stuff. But I know this probably won't last forever. This series of blog posts is my attempt to capture my memories for when I'm not doing this everyday anymore.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-1032030866786999370?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/1032030866786999370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=1032030866786999370' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1032030866786999370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1032030866786999370'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/04/every-developers-wet-dream.html' title='Living Every Developer&apos;s Wet Dream'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3983019770876101331</id><published>2010-03-05T09:06:00.000-08:00</published><updated>2010-03-05T13:31:20.358-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='SecureCRT'/><title type='text'>SecureCRT and Windows 7 - The Case of the Magically Disappearing Window</title><content type='html'>&lt;div&gt;Ever since I upgraded my copy of &lt;a href="http://www.vandyke.com/products/securecrt/index.html"&gt;SecureCRT &lt;/a&gt;to 6.5.1 on Windows 7 x64, I started noticing really strange behavior. Occasionally, my SecureCRT window would just 'disappear'. What do I mean by 'disappear'? The SecureCRT icon on the Windows 7 taskbar, which appears like this when a window is open:&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Ec26D924Y3U/S5E7sE4caTI/AAAAAAAAABc/8cZd6Dt6zBs/s1600-h/SecureCRT1.PNG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 85px; height: 54px;" src="http://4.bp.blogspot.com/_Ec26D924Y3U/S5E7sE4caTI/AAAAAAAAABc/8cZd6Dt6zBs/s320/SecureCRT1.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5445199052878407986" /&gt;&lt;/a&gt;&lt;br /&gt;would suddenly change to this, which is what an icon looks like when the process has no windows open:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Ec26D924Y3U/S5E7_hKgbhI/AAAAAAAAABk/fxCIfIIuRro/s1600-h/SecureCRT2.PNG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 63px; height: 48px;" src="http://2.bp.blogspot.com/_Ec26D924Y3U/S5E7_hKgbhI/AAAAAAAAABk/fxCIfIIuRro/s320/SecureCRT2.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5445199386887876114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I could still see SecureCRT.exe running, but didn't find any windows for it, even in the Alt+Tab menu. Nothing appeared in my system tray either except for the network connection, volume and system time information.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once this happened even after a system restart (isn't that the usual fix for everything?! ;)) I got curious. Eventually, I realized that this happened each time I minimized the window. Somehow, minimizing the window is muscle memory for me now and I don't really notice I'm doing it until I consciously try.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Minimizing a windows shouldn't ever cause the window to just 'disappear' so I started looking at the different SecureCRT settings and noticed a curious "Minimize to Activator" setting that was checked, and seemed suspicious. Unchecking it was all it took to restore sanity. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What is this 'Activator'? It's an icon that sits in your system tray. But Windows 7, by default, &lt;a href="http://helpdeskgeek.com/windows-7/windows-7-system-tray/"&gt;hides away all my system tray icons&lt;/a&gt; so I had no idea this even existed until I started investigation this issue. This is the 'Activator':&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Ec26D924Y3U/S5FAipXd59I/AAAAAAAAABs/n2uXes-MDrs/s1600-h/SecureCRT3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 128px; height: 174px;" src="http://3.bp.blogspot.com/_Ec26D924Y3U/S5FAipXd59I/AAAAAAAAABs/n2uXes-MDrs/s320/SecureCRT3.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5445204388431652818" /&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SecureCRT removes the window and sticks it into this Activator. Without any sort of visual cue or notification bubble. By default. Ugh! To restore it, you need &lt;i&gt;right click&lt;/i&gt; the icon and select the "Restore" option. Umm... isn't that the whole point of Windows' built-in minimize implementation?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This seems like a poorly designed feature, especially given how Windows 7 treats tray icons (and I know SecureCRT v6.5.1 has some Windows 7 specific features so this isn't accidental). Making the process 'appear' like it's not running and sticking into into the 'Activator' (why isn't it called 'system tray icon'?) instead seems like bad design. If anything, this should definitely not be on by default. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Ed: Title inspired by &lt;a href="http://blogs.technet.com/markrussinovich/"&gt;Mark Russinovich's blog&lt;/a&gt; posts&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Update: Just got an email response back from SecureCRT's support staff to a query about I this I had sent last night. She clarified "... the global option  is **not** enabled by default. The session option by default is a "tri-state"  option, meaning it uses the setting found in the global option."&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3983019770876101331?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3983019770876101331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3983019770876101331' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3983019770876101331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3983019770876101331'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/03/securecrt-and-windows-7-case-of.html' title='SecureCRT and Windows 7 - The Case of the Magically Disappearing Window'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Ec26D924Y3U/S5E7sE4caTI/AAAAAAAAABc/8cZd6Dt6zBs/s72-c/SecureCRT1.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-6939215440531744392</id><published>2010-03-03T17:55:00.001-08:00</published><updated>2010-03-03T18:37:05.487-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random'/><title type='text'>Discouraging Tardiness in Social Circles</title><content type='html'>&lt;div&gt;What's the best way, if any, to incentivize punctuality in a social setting i.e. among friends and family? Alternately, is there any way to dis-incentivize/discourage &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;impunctuality&lt;/span&gt;? &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;In professional environments this isn't usually a problem. There is generally one party which has some form of authority (the boss running a meeting, the doctor who is so booked up that you got an appointment only after months, the VP who can only meet for 20 minutes before he has to run to another meeting, the senior engineer whose time really is more precious than yours) who sets an example that is expected to be followed, and can dangle a carrot or wield a stick to manage tardiness. There is also a personal incentive to be on time - you want to make a good first impression, not appear to be the one holding the team behind,  or not miss out on something important if you're late.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The social dynamics that exist among friends and family are vastly different though. Often times, no one person holds a position of authority over another, the 'meetings' aren't usually that important and outcasting the offenders as a group isn't really an option either. Hence the repercussions of tardiness are pretty mild, if any. In many ways, the punctual folk have more to lose.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The ideal solution wouldn't make any individual or sub-group appear to be 'jerks' and yet make each member of the group &lt;i&gt;want&lt;/i&gt; to be punctual. Poking fun at the offenders or just generally being prudish isn't going to help, I think. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, any ideas? I'm drawing blanks...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-6939215440531744392?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/6939215440531744392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=6939215440531744392' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6939215440531744392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6939215440531744392'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/03/tardiness-in-social-circles.html' title='Discouraging Tardiness in Social Circles'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-2620847149779103699</id><published>2010-02-19T09:26:00.000-08:00</published><updated>2010-02-19T09:36:44.708-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Etiquette'/><category scheme='http://www.blogger.com/atom/ns#' term='Coupon'/><category scheme='http://www.blogger.com/atom/ns#' term='Groupon'/><category scheme='http://www.blogger.com/atom/ns#' term='Random'/><title type='text'>Coupon etiquette?</title><content type='html'>What's the 'correct' social etiquette about using restaurant coupons purchased online (such as those from &lt;a href="http://www.restaurant.com"&gt;restaurant.com&lt;/a&gt; or &lt;a href="http://www.groupon.com/"&gt;groupon.com&lt;/a&gt;) when you go out in a group and split the check? &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For coupons you get in the mail, or basically free stuff, I assume common etiquette is to offer the coupon to the group to use and split the remainder. Does it work the same way when you've bought, say, a $50 coupon for $25 (i.e. you use the coupon to cover $25 off your tab and offer the discount value to the group)? Do you use the entire $50 to cover just your tab? Or maybe simply not using the coupon when dining as a group is the right way to go?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-2620847149779103699?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/2620847149779103699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=2620847149779103699' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2620847149779103699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2620847149779103699'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/02/coupon-etiquette.html' title='Coupon etiquette?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3089239754360696001</id><published>2010-02-09T10:27:00.000-08:00</published><updated>2010-02-09T10:57:08.988-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='Buzz'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Hey Google Buzz, I don't email my friends anymore</title><content type='html'>I just &lt;a href="http://www.youtube.com/feb0910googleevent"&gt;saw the presentation&lt;/a&gt; from Google about Google Buzz. The quick summary of the announcements - creating a social network using my email contacts and emailing history as the source of my social graph, and using rich geo-tagged status messages (buzz-es) to keep it updated. It comes with rich mobile apps to help this take off. They also promised enterprise versions of Buzz.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Buzz sounds pretty exciting. Some of the geo-tagged updates sounds really slick. My first reaction - this is going to be 'public follow' thing more than a 'follow my friends' things. Because emailing my friends is like, so 2007! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Fact is, I don't email my closest friends/family anymore. I either IM them, post on their Facebook page, send them SMS or call them. Email is more for work type, non-personal stuff. Having said that, it's important to note that Google does have GTalk and Google Voice so I hope they weigh activity from GTalk and Google Voice higher than GMail activity when figuring out who I must 'auto-follow'.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Time for someone to write a Buzz-to-Facebook cross poster. :)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3089239754360696001?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3089239754360696001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3089239754360696001' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3089239754360696001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3089239754360696001'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/02/hey-google-buzz-i-dont-email-my-friends.html' title='Hey Google Buzz, I don&apos;t email my friends anymore'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-7582221626533192907</id><published>2010-01-25T15:26:00.000-08:00</published><updated>2010-01-25T22:30:05.164-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Facebook Connect'/><title type='text'>Test cases for basic Facebook Connect integration</title><content type='html'>&lt;div&gt;I recently spent a couple of days adding some basic &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Facebook&lt;/span&gt; Connect functionality to an existing site with it's own &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Login&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Auth&lt;/span&gt; system. The process isn't too hard and there are several &lt;a href="http://www.facebook.com/connectnews?v=app_7146470109"&gt;examples&lt;/a&gt; and even a nice &lt;a href="http://www.goldsteintech.com/facebook_connect/tutorial.php"&gt;tutorial&lt;/a&gt; which shows you exactly how to hook this up.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The tutorials and the &lt;a href="http://wiki.developers.facebook.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Facebook&lt;/span&gt; developer wiki&lt;/a&gt; to a good job of getting you on the right path and putting up a quick working implementation. However, there are several subtleties that need to be addressed, depending on the requirements of the existing site. I didn't really find a good compilation of these 'test cases' anywhere. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Facebook's&lt;/span&gt; own documentation probably references several of these but they're scattered all over their &lt;a href="http://wiki.developers.facebook.com/"&gt;wiki page&lt;/a&gt; and are very easy to miss if your primary focus is getting this stuff up and running quickly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This blog post is my attempt to compile of list of things you need to think about when adding &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Facebook&lt;/span&gt; Connect support for sign up/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;login&lt;/span&gt; or linked accounts on an &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;existing&lt;/span&gt; site with its own authorization system. Here are a few characteristics (pretty standard) of the existing site:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Authentication using a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;username&lt;/span&gt;/email address and password&lt;/li&gt;&lt;li&gt;Cookies to help keep users logged in&lt;/li&gt;&lt;li&gt;Accounts keyed by email address (i.e. 1:1 mapping between accounts and email address)&lt;/li&gt;&lt;li&gt;Ability to reset accounts by having a temp password send to user's email address&lt;/li&gt;&lt;li&gt;Fully &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ajax&lt;/span&gt; navigation (which complicates matter a little bit)&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Logout&lt;/span&gt; functionality which clears up cookies&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;The goals for the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Facebook&lt;/span&gt; Connect integration are pretty simple:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;New User Sign Up without needing to create a site-specific password (&lt;a href="http://wiki.developers.facebook.com/index.php/Roadmap_Email"&gt;email address&lt;/a&gt; needed)&lt;/li&gt;&lt;li&gt;Ability for existing users to link with their &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Facebook&lt;/span&gt; account&lt;/li&gt;&lt;li&gt;1:1 mapping between accounts on your site and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Facebook&lt;/span&gt; accounts&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.developers.facebook.com/index.php/Detecting_Connect_Status"&gt;Single sign-on&lt;/a&gt; experience&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Let's call the existing site &lt;a href="http://blogs.wsj.com/digits/2009/12/11/30-rock-introduces-youface/tab/article/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;YouFace&lt;/span&gt;&lt;/a&gt;. I won't go into how to get stuff hooked up or explaining how to implement this - it's not too complicated and there's a bunch of information online for it. Instead, treat this as a list of a few things you probably want to test when you're done. There shouldn't really be anything ground breaking here - this was just a convenient way for me to build a list of things to test on my own site. Some of these are handled by the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Facebook&lt;/span&gt; Connect client library, while some need your application to do the right thing. Please comment if I've missed any cases or if some just appear wrong - I would love to fix my site!&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Sign Up should fail if the user denies permission to the app &lt;i&gt;(category: sign up)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Since we need access to an &lt;a href="http://wiki.developers.facebook.com/index.php/Roadmap_Email"&gt;email address&lt;/a&gt;, Sign Up should fail if the user provides publish permission but denies email permission &lt;i&gt;(category: sign up)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If the user provides an email address that already exists in your system, fail Sign Up. Make sure no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;YouFace&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;backend&lt;/span&gt; tables are modified &lt;i&gt;(category: sign up, 1:1 mapping) &lt;/i&gt;&lt;i&gt;PS - when this happens, I didn't find a way for you to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;de&lt;/span&gt;-authorize &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;YouFace&lt;/span&gt; on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;Facebook&lt;/span&gt; user's behalf. The user must manually do this if they wish you use the same account but provide a different email address.&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Accounts created using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;Facebook&lt;/span&gt; Connect should not be able to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;login&lt;/span&gt; using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;YouFace's&lt;/span&gt; default email/password &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;login&lt;/span&gt; system &lt;i&gt;(category: sign in, account security). PS: Since &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;YouFace&lt;/span&gt; accounts require a password and those created using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;Facebook&lt;/span&gt; Connect don't, make sure to insert a random password hash into your table to avoid silly errors&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Accounts created using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;YouFace&lt;/span&gt; should be able to sign in without requiring to be signed into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;Facebook&lt;/span&gt;, even if when a link to a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;Facebook&lt;/span&gt; accounts exists &lt;i&gt;(category: sign in)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Attempting to Sign Up with a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;Facebook&lt;/span&gt; account that's already linked and authorized should result in the Sign In experience &lt;i&gt;(category: sign up, sign in)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Attempting to Sign In with a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;Facebook&lt;/span&gt; account that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;YouFace&lt;/span&gt; hasn't seen before should lead to the Sign Up experience, i.e. create a new account &lt;i&gt;(category: sign up, sign in)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Linking a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;Facebook&lt;/span&gt; account with an existing &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;YouFace&lt;/span&gt; account should add the email address from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;Facebook&lt;/span&gt; to the list of 'used addresses' in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;YouFace&lt;/span&gt; system &lt;i&gt;(category: linking, 1:1 mapping)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;When a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;Facebook&lt;/span&gt; linked account &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;de&lt;/span&gt;-authorizes &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;YouFace&lt;/span&gt;, your system should record this action and change state as needed &lt;i&gt;(category: authorization)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Linking a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;YouFace&lt;/span&gt; account with a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;Facebook&lt;/span&gt; account that's already been linked to some other account in your system should be denied &lt;i&gt;(category: linking, 1:1 mapping, authorization)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Users with linked accounts can continue to sign in using their &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;YouFace&lt;/span&gt; credentials even after they &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;de&lt;/span&gt;-authorize &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;YouFace&lt;/span&gt; from their &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;Facebook&lt;/span&gt; account &lt;i&gt;(category: linking, authorization)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Linking a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;Facebook&lt;/span&gt; account different from one you originally linked to an existing &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;YouFace&lt;/span&gt; account should be denied. This can happen when an existing user links a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;YouFace&lt;/span&gt; account to Foo@FB, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;de&lt;/span&gt;-authorizes the app and then tries to link Bar@FB to that account &lt;i&gt;(category: linking, 1:1 mapping, authorization)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A user who Signed Up using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;Facebook&lt;/span&gt; Connect should not be allowed to link their account to another &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;Facebook&lt;/span&gt; account &lt;i&gt;(category: sign up, 1:1 mapping)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Attempting to Sign In or Sign Up with a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;Facebook&lt;/span&gt; account that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;YouFace&lt;/span&gt; has seen, but one that has currently not authorized the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;YouFace&lt;/span&gt; app (maybe the user revoked authorization) should ask to re-authorize before proceeding. It must log the user into the &lt;span class="Apple-style-span" style="text-decoration: underline; "&gt;original&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;YouFace&lt;/span&gt; account linked with that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;Facebook&lt;/span&gt; account, i.e. no new account should be created. If that account was originally created using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;Facebook&lt;/span&gt; Connect, the primary email address should be updated to reflect the user's current &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;Facebook&lt;/span&gt; contact email address else the primary email address should not be changed from what the user provided &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;YouFace&lt;/span&gt; when they signed up &lt;i&gt;(category: sign in, 1:1 mapping, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;reauthorization&lt;/span&gt;)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;If a user with a linked account is logged into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;Facebook&lt;/span&gt;, they should be signed into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;YouFace&lt;/span&gt; directly &lt;i&gt;(category: single sign in)&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Users who signed into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;YouFace&lt;/span&gt; with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;Facebook&lt;/span&gt; Connect should be logged out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;Facebook&lt;/span&gt; if they log out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;YouFace&lt;/span&gt; &lt;i&gt;(category: single sign out)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Users who signed into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;YouFace&lt;/span&gt; with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;Facebook&lt;/span&gt; Connect should be logged out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_68"&gt;YouFace&lt;/span&gt; if they log out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_69"&gt;Facebook&lt;/span&gt; &lt;i&gt;(category: single sign out)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Users with linked accounts who signed into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_70"&gt;YouFace&lt;/span&gt; directly (not using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_71"&gt;Facebook&lt;/span&gt; Connect) should continue to remain signed in, regardless of whether they're were originally signed into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_72"&gt;Facebook&lt;/span&gt;, when they sign out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_73"&gt;Facebook&lt;/span&gt; &lt;i&gt;(category: sign in, sign out)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Users who created their account using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_74"&gt;Facebook&lt;/span&gt; Connect should not be allowed to reset passwords or have temporary passwords sent to their email addresses &lt;i&gt;(category: account security)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;This is a kinda convoluted. Users Foo and Bar both have &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_75"&gt;YouFace&lt;/span&gt; accounts linked to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_76"&gt;Facebook&lt;/span&gt;. Bar is logged into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_77"&gt;YouFace&lt;/span&gt; with his &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_78"&gt;YouFace&lt;/span&gt; account,  and Foo is logged into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_79"&gt;Facebook&lt;/span&gt;, in the same instance of the browser (Bar logged in first). When Bar logs out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_80"&gt;YouFace&lt;/span&gt;, Foo should not get logged out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_81"&gt;Facebook&lt;/span&gt; (&lt;i&gt;category: single sign out, multiple accounts ). PS: &lt;/i&gt;&lt;i&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_82"&gt;YouFace's&lt;/span&gt; Connect library is going to pick up a valid &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_83"&gt;Facebook&lt;/span&gt; ID but it's that of Foo, not Bar. So you need to do more than just client-side detection of whether &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_84"&gt;someone's&lt;/span&gt; logged into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_85"&gt;Facebook&lt;/span&gt;.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-7582221626533192907?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/7582221626533192907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=7582221626533192907' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7582221626533192907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7582221626533192907'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2010/01/test-cases-for-basic-facebook-connect.html' title='Test cases for basic Facebook Connect integration'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-1343614753876180419</id><published>2009-12-23T12:41:00.000-08:00</published><updated>2009-12-23T12:55:02.455-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Safari'/><category scheme='http://www.blogger.com/atom/ns#' term='Chrome'/><title type='text'>Browser history navigation bug in Chrome and Safari</title><content type='html'>I've been seeing some odd behavior in Chrome - occasionally browser history would get hosed pretty badly. When I noticed the same issue navigating the website I'm working on, I ended up spending a bunch of time trying to get to the bottom of the issue. Initially I suspected it was something wrong with the site, but I was eventually able to create a stand-alone repro for Chrome (v3 and v4) as well as for Safari (v4). I suspect this might be a WebKit thing, which both browsers share, but I don't know enough to be certain.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The problem seems to occur when you spend time moving around fully ajax sites that contain one or more iframes (I've seen this on GMail as well). In my case I worked around this issue by not using iframes but I imagine that's not always possible. Anyways, this is now &lt;a href="http://code.google.com/p/chromium/issues/detail?id=30693"&gt;Chromium bug 30693&lt;/a&gt;. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-1343614753876180419?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/1343614753876180419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=1343614753876180419' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1343614753876180419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1343614753876180419'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/12/browser-history-navigation-bug-in.html' title='Browser history navigation bug in Chrome and Safari'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-2997638261383886861</id><published>2009-10-09T11:08:00.000-07:00</published><updated>2009-10-14T19:40:19.722-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><title type='text'>XSRF/CSRF Vulnerability Explained in Non-Geek Speak</title><content type='html'>I recently explained what cross-site request forgery (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;CSRF&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;XSRF&lt;/span&gt;) is to a friend who isn't a programmer/CS person and I was pretty amazed at how quickly he understood the implications of not protecting against such attacks. With the proliferation of social interactions on the web now, such attacks can be pretty damaging to consumers of new media and e-commerce sites.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The &lt;a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Wikipedia&lt;/span&gt; article about &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;CSRF&lt;/span&gt;&lt;/a&gt; does a pretty good job of explaining the issue - most people familiar with web development should be able to understand it easily. Basically, this attack lets legitimate unsuspecting users submit changes to a site they routinely interact with, but without their knowledge. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;CSRF&lt;/span&gt; attacks leverage your own browser and the trust you associate with it to perform potentially damaging actions on your behalf. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's an example of what such an attack might look like. Let's assume that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Facebook&lt;/span&gt; wasn't protected against such attacks, for the purpose of this illustration. In reality, I'm sure &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Facebook&lt;/span&gt; engineers have done a good job of making sure this can't really ever happen. That's not true of every site out there, though.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When you sign into &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Facebook&lt;/span&gt;, you have the option of remaining signed in. To do this, sites like &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Facebook&lt;/span&gt; set a browser cookie which identifies you to their servers. This is great because it lets you visit the site frequently and navigate the site without needing to enter your password every time. Browsers are good about securing your cookie - they make sure that no other site besides &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Facebook&lt;/span&gt; can see this cookie, so it's not possible for the author of www.hacker.com to steal your cookie and present it to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Facebook&lt;/span&gt; and then impersonate you. However, each time you go to any URL that contains www.facebook.com, the browser diligently sends over all cookies associated with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Facebook&lt;/span&gt;, because the receiver of those cookies is www.facebook.com.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Facebook&lt;/span&gt;, you do things like update your status or write on a friend's wall. When you do that, the browser sends your new status update to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;Facebook&lt;/span&gt; along with the cookies. By inspecting the cookie, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Facebook&lt;/span&gt; is able to validate that it is indeed you trying to update your own status, so it proceeds to allow the action. Under the covers, your browser is sending over two pieces of information - some data (your status update text, in this case) and the cookies. The browser was triggered to do this by you clicking the "Submit" button. This sounds pretty straightforward so far.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now imagine you're browsing the web and land on this page that talks about world hunger and how you can help the cause by simply clicking a "Help the Children" button. With only altruistic intentions, you click on the button. Nothing visible happens, or maybe a "Thank you!" label replaces that button. Then you simply move on to the next thing you were going to do. Suddenly, you start receiving email notifications about friends responding to your latest status update on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Facebook&lt;/span&gt;, except you never posted any update. You visit &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;Facebook&lt;/span&gt; and sure enough your status now says "I am a loser!", updated 2 minutes ago. Huh?! You didn't set that status. You panic - maybe someone hacked your account? Or someone guessed your password? What's going on?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What really happened was that the world hunger website you were on was written by a malicious attacker, and when you clicked the "Help the Children" button that website didn't really contribute 10 cents to UNICEF, but instead told your browser to send a new status update with the text "I am a loser!" to www.facebook.com. This site couldn't access your cookies directly, so the browser didn't do anything bad and stuck to its promise of not letting anyone else see cookies that shouldn't be visible to them. Remember, the attacker never looked at your cookie at all while any of this happened. However, when the attacker asked the browser to send data to www.facebook.com, the browser added the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Facebook&lt;/span&gt; cookies to the request. So now &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;Facebook&lt;/span&gt; looks at the cookies and the data, thinks that it is indeed you and goes on to update your status. Boom!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what went wrong here? The browser didn't do anything bad - it did exactly what it's supposed to. It hid your &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;Facebook&lt;/span&gt; cookies from everyone except &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;Facebook&lt;/span&gt; and it sent data that submitting the "Help the Children" button asked it to send. You didn't do anything bad - you simply clicked on a link that was meant to help needy kids. You did have cookies enabled (default for most browsers) and decided to check that "Log in automatically" option, but those seem like reasonable actions. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The flaw here is with the website you trusted - &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;Facebook&lt;/span&gt;, in this example. Sites like &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;Facebook&lt;/span&gt; that rely on cookies to identify and authorize user actions need to do more things than just validate your cookie when data is presented to the site on your behalf. They need to make sure that place from which the data was sent was 'good', or that a malicious author cannot create data the same way that www.facebook.com can. They need to make sure that when you update your status, the data contain more than just your new status text - there must be some kind of secret information in there that can only be generated by &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;Facebook&lt;/span&gt;, and this secret must be different for each &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;Facebook&lt;/span&gt; user. They can even control how long cookies and secrets remain valid, and have ways to periodically require users to sign in and generate new unique secrets for users.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course, this is just a silly example. I'm sure &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;Facebook&lt;/span&gt; is perfectly adept and handling such attacks. However, a vulnerability like this could impact everything from online review sites to banking and e-commerce sites. It's always good to be aware of things that could go wrong online - the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_26"&gt;Internet&lt;/span&gt; is definitely not as safe as you might think it is.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-2997638261383886861?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/2997638261383886861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=2997638261383886861' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2997638261383886861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2997638261383886861'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/10/xsrfcsrf-attacks-in-non-geek-speak.html' title='XSRF/CSRF Vulnerability Explained in Non-Geek Speak'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-7018974775519161084</id><published>2009-09-30T17:59:00.000-07:00</published><updated>2009-09-30T18:08:35.485-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>So, how was your date?</title><content type='html'>A funny exchange at work today...&lt;br /&gt;&lt;br /&gt;I designed this piece of &lt;a href="http://en.wikipedia.org/wiki/User_interface"&gt;UI&lt;/a&gt; putting together all my newly-acquired &lt;a href="http://www.w3schools.com/JS/default.asp"&gt;Javascript&lt;/a&gt; and &lt;a href="http://www.getpaint.net/"&gt;Paint.NET&lt;/a&gt; (a free Photoshop-like tool) skills, and it looked pretty fancy for what I thought I was going to end up with. After playing with it for a bit my co-worker responded: "Thanks for putting that together Viraj - I really like the concept. I can't wait to see what a designer can do with it".&lt;br /&gt;&lt;br /&gt;Lol... this sounds a lot like the "She's got a great personality..." line of the dating scene.&lt;br /&gt;&lt;br /&gt;Like I said &lt;a href="http://crazyviraj.blogspot.com/2009/08/to-every-webui-developer-ive-scoffed-at.html"&gt;previously&lt;/a&gt;, UI design is so much harder than I thought it was!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-7018974775519161084?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/7018974775519161084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=7018974775519161084' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7018974775519161084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7018974775519161084'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/09/so-how-was-your-date.html' title='So, how was your date?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-1888418211296576862</id><published>2009-09-18T11:43:00.000-07:00</published><updated>2009-09-18T11:51:11.159-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Fix for slow Firefox/Chrome connects to localhost</title><content type='html'>While doing some recent testing I noticed that &lt;a href="http://google.com/chrome"&gt;Chrome&lt;/a&gt;(v3) and &lt;a href="http://mozilla.org/"&gt;Firefox&lt;/a&gt;(v3.5) are both very slow to connect to http://localhost on Windows 7 - both take ~1 second just to connect.&lt;br /&gt;&lt;br /&gt;I initially suspected something was wrong with the webserver on localhost, but once I validated that wasn't it, I found some &lt;a href="http://weblogs.asp.net/dwahlin/archive/2007/06/17/fixing-firefox-slowness-with-localhost-on-vista.aspx"&gt;blog&lt;/a&gt; &lt;a href="http://codepoetry.wordpress.com/2007/03/27/firefox-very-slow-on-localhost-connections-on-vista/"&gt;posts&lt;/a&gt; about others who had noticed this in Vista and XP. Essentially, disabling ipv6 takes care of the slowness.&lt;br /&gt;&lt;br /&gt;However, to &lt;span style="font-style:italic;"&gt;fix&lt;/span&gt; the issue, have the client use http://127.0.0.1 instead of http://localhost - it bypasses ipv6 without you needing to mess with browser configuration.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-1888418211296576862?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/1888418211296576862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=1888418211296576862' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1888418211296576862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1888418211296576862'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/09/fix-for-slow-firefoxchrome-connects-to.html' title='Fix for slow Firefox/Chrome connects to localhost'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-1722622457694212472</id><published>2009-08-29T11:55:00.000-07:00</published><updated>2009-08-29T12:51:59.153-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><title type='text'>Know What you Inherit</title><content type='html'>&lt;div&gt;I ran into a couple of bugs recently that took longer than they should have to fix. Like all bugs, it seems obvious now that I know what was wrong but I think I spent a total of 5-6 hours investigating and fixing this across multiple platforms (hey, this is what makes developing software fun!). Here's hoping that those fancy search engines will help someone else find this post and save them time incase they have a similar problem.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was working on some code that launched another &lt;a href="http://en.wikipedia.org/wiki/Process_(computing)"&gt;process&lt;/a&gt;. This is a fairly mundane task. Interestingly though, the process launched went on to kill its parent and re-launch another copy of the parent. So, process A is running and launches process B, which then kills A and launches A'. Sounds kinda simple, right?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, everything seemed to work until I noticed that some resources needed by A' weren't available (ports/files). That seemed odd, given that A had been using those same resources successfully, and those should now be available since A was gone. The title of the post gives it away, but the problem is that a &lt;a href="http://en.wikipedia.org/wiki/Fork_(operating_system)"&gt;fork&lt;/a&gt; causes child processes to inherit the file descriptors/handles of the parent, so the files/ports opened by A were inherited by B and subsequently by A'. This meant that they weren't really cleaned up by the OS when A exited. Hence A' could not re-open those resources (some were locked for exclusive use).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The really interesting aspect of this bug was how it manifest itself on different OSes and the different fixes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On Windows, &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897437.aspx"&gt;TCPView&lt;/a&gt; showed the ports in use by a "&amp;lt;non-existent&amp;gt;" process. The PID of this process was that of A, which was already gone by now and didn't show up in the list of running processes.&lt;/div&gt;&lt;non-existent&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Ec26D924Y3U/SpltKsKerxI/AAAAAAAAABQ/JEiMw3UrskU/s1600-h/non-existent.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 318px; height: 149px;" src="http://4.bp.blogspot.com/_Ec26D924Y3U/SpltKsKerxI/AAAAAAAAABQ/JEiMw3UrskU/s320/non-existent.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5375447660664631058" /&gt;&lt;/a&gt;&lt;br /&gt; &lt;/non-existent&gt;&lt;div&gt;&lt;non-existent&gt;After some analytical debugging, I guessed that the handles were being inherited by the children resulting in these strange 'orphaned' ports. The solution on Windows was to use the &lt;a href="http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx"&gt;CreateProcess&lt;/a&gt; API with the 'bInheritHandles' flag to FALSE. Problem solved. By the way, the not existent process IDs attached to those ports seem to imply that the OS tracks ownership by processID, and hence cannot validate that the new owner of these is the child process now that the parent is dead - the child obviously has a different process ID. This might not be really how it's done, but seems logical.&lt;/non-existent&gt;&lt;div&gt;&lt;non-existent&gt;&lt;/non-existent&gt;&lt;br /&gt;&lt;div&gt;The Mac was much more interesting. The manifestation of the problem was simply unavailability of the resources. There isn't an equivalent of the bInheritHandles flag for the fork command on UNIX. To cut to the chase, the solution was to fork the process, close all open file descriptors that it inherits and then call &lt;a href="http://en.wikipedia.org/wiki/Exec_(operating_system)"&gt;exec&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, the Mac guys have added a nifty '&lt;a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/open.1.html"&gt;open&lt;/a&gt;' command to the system which helps launch processes as a child of the &lt;a href="http://developer.apple.com/MacOsX/launchd.html"&gt;launchd&lt;/a&gt; process, which doesn't inherit the callers file descriptors (it's parent is the launchd process). However, this open command has a couple of pretty severe limitations. It can only open &lt;a href="http://en.wikipedia.org/wiki/Application_Bundle"&gt;app bundles&lt;/a&gt;, not native binaries. And you can't pass in command line arguments to the application you open. FAIL on both counts! Mac purists will claim that command line arguments aren't the 'right thing' on the Mac, and that &lt;a href="http://developer.apple.com/legacy/mac/library/documentation/AppleScript/Conceptual/AppleEvents/intro_aepg/intro_aepg.html"&gt;Apple Events&lt;/a&gt; should be used instead. That's BS, really. For anyone writing platform independent C++ code, it's just not practical. People don't realize that not every app on the Mac is a Cocoa/Carbon app. Anyways, so on OS X I needed to be a little creative and have A launch B, but before doing anything useful in B enumerate all open file descriptors and close them (readdir() /dev/fd on &lt;a href="http://www.freebsd.org/"&gt;FreeBSD&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Darwin_(operating_system)"&gt;Darwin&lt;/a&gt; enumerates all open file descriptors). Oh and by the way, you might not want to close FDs 0, 1 and 2 - they're &lt;a href="http://www.faqs.org/docs/abs/HTML/io-redirection.html"&gt;stdin, stdout and stderr&lt;/a&gt; respectively. This post on &lt;a href="http://stackoverflow.com/questions/899038/getting-the-highest-allocated-file-descriptor/918469#918469"&gt;StackOverflow&lt;/a&gt; has some good related information incase you're curious.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-1722622457694212472?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/1722622457694212472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=1722622457694212472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1722622457694212472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1722622457694212472'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/08/know-what-you-inherit.html' title='Know What you Inherit'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Ec26D924Y3U/SpltKsKerxI/AAAAAAAAABQ/JEiMw3UrskU/s72-c/non-existent.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-4853237468936435866</id><published>2009-08-07T06:01:00.000-07:00</published><updated>2009-08-07T06:01:00.713-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><title type='text'>To Every Web/UI Developer I've Scoffed At - Apologies!</title><content type='html'>I am/was a cocky programmer. Having only worked on system and application level programming thus far, I really didn't appreciate how hard building a good, usable website or application is. I knew that an application or a system is only as good as how usable it is, but I really considered usability to be a 'simple' problem and by inference I assumed that writing the code behind what you see on a website or an application is also 'simple'. As my career matured I suspected I might be wrong, and now I know I was!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Over the last few weeks, I've been messing quite a bit with &lt;a href="http://en.wikipedia.org/wiki/HTML"&gt;Html&lt;/a&gt; and &lt;a href="http://www.w3schools.com/css/css_intro.asp"&gt;CSS&lt;/a&gt; to make stuff look non-ugly and &lt;a href="http://en.wikipedia.org/wiki/Ajax_(programming)"&gt;Javascript/Ajax&lt;/a&gt; to make stuff feel non-sluggish. And the combination of these together to make non-ugly things appear non-sluggish. Of course, this also means dealing with everything that goes on in the middle/backend to support non-sluggish, non-ugly things. Oh, and once you have something that's not ugly and not sluggish, you have to worry about the bad guys. &lt;a href="http://ha.ckers.org/xss.html"&gt;Cross-site Scripting&lt;/a&gt;, &lt;a href="http://www.cgisecurity.com/csrf-faq.html"&gt;Cross-site Request Forgery&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/HTTP_cookie"&gt;cookie&lt;/a&gt; theft and &lt;a href="http://blog.imperva.com/mt/2009/06/cookie-poisoning-web-application-attack-demonstration-video.html"&gt;poisoning&lt;/a&gt;, etc are things I didn't think much about previously. What cans of worm those are... !&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And then a couple of months ago I spent some time making an &lt;a href="http://crazyviraj.blogspot.com/2009/05/developing-for-mac-how-does-it-compare.html"&gt;mac application&lt;/a&gt; non-ugly and non-sluggish. Same deal, pretty much.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Working on these new technologies sure feels like being a kid in a candy store, but I have to confess my new found respect for good UI/Web developers (and I am not one, by a long shot). I may have snickered behind your backs previously, but it sure won't happen again!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-4853237468936435866?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/4853237468936435866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=4853237468936435866' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4853237468936435866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4853237468936435866'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/08/to-every-webui-developer-ive-scoffed-at.html' title='To Every Web/UI Developer I&apos;ve Scoffed At - Apologies!'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-1314860470520026463</id><published>2009-08-06T21:32:00.000-07:00</published><updated>2009-08-06T21:32:00.403-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random'/><title type='text'>What's your time worth?</title><content type='html'>One of the hardest questions I often find myself needing to answer is what my time is worth. Simple everyday decisions are influenced by what the answer to this question is - Should I get groceries from the store myself, or order online? Should I clean my own apartment or hire a professional? Should I contest the parking ticket by mail, in person or simply pay it? Should I go out an enjoy the weather instead of working overtime?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course, the right answer in most cases depends on more than just how you value your time. Tangible (I might pick better produce in person than online, or a professional could do a better job cleaning my apartment than I can) and non-tangible (I get to experience the judicial process at the municipal court myself if I contest a ticket in person) factors can sometimes influence these decision more than the absolute value of your time, and generally it's a combination of these factors + the value of your time which leads to the right answer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What factors influence how you derive the value of your time? Here's a quick list of things I could think of:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Your age relative to life expectancy. Generally, the older you get the more valuable your time is. Time does run out eventually, afterall.&lt;/li&gt;&lt;li&gt;Real dollar value of gains from alternate activities you could be engaged in versus the intended activity. If you're paid by the minute on your job, the dollar value of every minute your spend in the break room outside of the allowed times better be worth more than your per-minute salary.&lt;/li&gt;&lt;li&gt;The intangible value of alternate activities you could be engaged in versus the intended activity. Heh - good luck figuring this out!&lt;/li&gt;&lt;li&gt;The tangible and intangible deferred value/costs of making a decision. Not feeding the parking meter in favor of enjoying your cup of coffee by the lake will cost you $25 next week.&lt;/li&gt;&lt;li&gt;Risk associated with the decision you make. You're quite likely to hurt yourself sawing wood, and depending on how badly you're injured you could easily outspend in medical bills what you would have paid a professional instead. Again, look luck quantifying risk.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;What else do you consider when deciding one way or another?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-1314860470520026463?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/1314860470520026463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=1314860470520026463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1314860470520026463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/1314860470520026463'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/08/whats-your-time-worth.html' title='What&apos;s your time worth?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-7643142541774081769</id><published>2009-06-30T16:20:00.000-07:00</published><updated>2010-04-18T13:13:03.928-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Experiences'/><title type='text'>New Technology (for me) Roundup</title><content type='html'>Over the last almost 2 months, I've messed with several new technologies - some extensively, some briefly - that I hadn't used previously. This post is primarily a journal entry documenting my impressions of and experience with these, so far:&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.php.net/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;PHP&lt;/span&gt;&lt;/a&gt; - Exposure : Medium&lt;br /&gt;I think I really like &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;PHP&lt;/span&gt;. It seems like it's a good blend of a traditional programming language and a scripting language. I like that it allows for well designed software with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;OO&lt;/span&gt; constructs being first class citizens. I also like the flexibility that the scripting language aspect of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;PHP&lt;/span&gt; provides. I wish there were some kind of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;PHP&lt;/span&gt; compiler which helped catch silly typo-like issues before &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;runtime&lt;/span&gt;, but I guess that's the price you pay for having the conveniences of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;PHP&lt;/span&gt;. I also think I would like having a good &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;PHP&lt;/span&gt; debugger - currently I use code review and tracing as debugging aids. They've worked so far but I hope I never have to chase down something really nasty or subtle using these techniques.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html"&gt;Objective-C&lt;/a&gt;/&lt;a href="http://developer.apple.com/Carbon/"&gt;Carbon&lt;/a&gt;/&lt;a href="http://developer.apple.com/cocoa/"&gt;Cocoa&lt;/a&gt; - Exposure: Medium High&lt;br /&gt;I &lt;a href="http://crazyviraj.blogspot.com/2009/05/developing-for-mac-how-does-it-compare.html"&gt;previously wrote&lt;/a&gt; about my experience with programming for the Mac. For someone familiar with C and working with a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;runtime&lt;/span&gt; framework, this shouldn't be hard to grasp. I think I'm pretty comfortable with these technologies, but in many ways these are forced down your throat if you want to write software that runs on a Mac, and looks half decent. I dove deep into a few things related to these technologies (debugging crashes, file system events, application run loops, network support, deployment) and it was kinda fun and fulfilling to accomplish complex tasks with these technologies. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Bash"&gt;Bash&lt;/a&gt; Scripting - Exposure: Medium Low&lt;br /&gt;To be productive in a Linux development environment, mastery of scripting is key. I know just enough to get me by, and I'm sure there's so much more I could do to improve. The rule of three seems to work well... if you do the same task three times, script it. And most times, you'll discover it's already been scripted by someone else or simpler still, exists as a built in set of commands. This seems like one of those endless holes of expertise that never ends. My goal is to deal with this as needed instead of being overly enthusiastic about becoming a crazy script monkey.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;Javascript&lt;/a&gt; - Exposure: Low&lt;br /&gt;I'm actually not too bummed about not having had to mess with more Javascript. I know people who just do the craziest things with Javascript and AJAX, but I'm not creative enough (or perhaps not motivated enough) to do anything more than the minimal. Unfortunately, a minimal website only works if you're Google or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Craigslist&lt;/span&gt;. I haven't messed with Javascript for more than just a few hours, so I don't really have any strong opinions except that for someone who isn't familiar with scripting it takes some getting used to. Something like &lt;a href="http://projects.nikhilk.net/ScriptSharp/"&gt;Script#&lt;/a&gt; might be an ideal &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;transitionary&lt;/span&gt; tool though (I haven't played with it at all).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.mysql.com/"&gt;MySQL&lt;/a&gt; - Exposure: Medium Low&lt;br /&gt;MySQL seems really slick. It feels great for simple database functionality (haven't really done anything too fancy with it) and supports some &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;SQL&lt;/span&gt; syntax that comes in handy versus Microsoft &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;SQL&lt;/span&gt; Server (&lt;a href="http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html"&gt;insert ... on duplicate key update&lt;/a&gt;, &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/create-table.html"&gt;create table if not exists&lt;/a&gt;, etc). &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;PHP&lt;/span&gt; support for MySQL seems like a great integration win for both technologies. I haven't really dealt too much with administration and performance issues though, two areas which are super important to a great database solution, so I can't comment on those.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; - Exposure: Low&lt;br /&gt;I wrote a couple of python scripts to get some pretty powerful tasks done. I like that it has a bunch of libraries that enable you to write pretty fancy applications if you're so inclined (I'm not, and likely never will be). Like most scripting languages I'm amazed at how much can be accomplished in a few lines of code. Generally though, I don't like too much magic being done for me when I don't really understand what's happening and my experience with Python certainly made it seem very magical. Which is great for getting small tasks done, I guess.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt; - Exposure: Medium High&lt;br /&gt;This is a big once - even after almost two months of using this daily, I'm not nearly as comfortable with it as I was with the Visual Studio &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;IDE,&lt;/span&gt; which makes me feel like I'm not being as productive as I can be. I think I learn one or two new tricks every day that make me wonder if there's anything Vim can't do. It's another one of those 'rabbit hole' technologies where experts can tune it to crazy levels. My approach is more along the lines of 'fix it when it annoys you' which seems to be working (slower than I would like, I admit). It certainly has the potentially to make me super productive once I get better with it, and that's making me stick with it. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Others - Exposure: Low to High&lt;br /&gt;Technologies that aren't really 'new' for me but I was out of touch with for the last few years and have reconneced with recently:&lt;br /&gt;- C&lt;br /&gt;- Linux&lt;br /&gt;- Win32&lt;br /&gt;- Batch file scripting&lt;br /&gt;- &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Makefiles&lt;/span&gt;&lt;br /&gt;- &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;gdb&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So yea, as you might be able to tell, the last couple months have been insanely fun. I feel like an intern again (in more than one way ;-) )!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-7643142541774081769?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/7643142541774081769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=7643142541774081769' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7643142541774081769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/7643142541774081769'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/06/new-technology-for-me-roundup.html' title='New Technology (for me) Roundup'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3809232363591159976</id><published>2009-05-22T21:02:00.000-07:00</published><updated>2009-05-22T21:10:15.124-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><title type='text'>f.lux - I Like!</title><content type='html'>Staring at multiple computer monitors late into the night isn't as pleasant as it should be. I've noticed that the constant bright glare from the monitors causes a lot of fatigue. &lt;a href="http://stereopsis.com/flux/"&gt;f.lux&lt;/a&gt; is a very simple and yet highly effective tool that has made coding so much more pleasant. I very highly recommend this to anyone who spends long hours working at a computer. Available for Mac, PC and Linux. (PS: MacBooks already have similar functionality built-in that uses the integrated camera to detect ambient light and adjust brightness accordingly).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3809232363591159976?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3809232363591159976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3809232363591159976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3809232363591159976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3809232363591159976'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/05/flux-i-like.html' title='f.lux - I Like!'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-5603633233388319650</id><published>2009-05-17T18:15:00.000-07:00</published><updated>2009-10-02T13:36:17.166-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><title type='text'>Cocoa: What is "File's Owner" in a nib?</title><content type='html'>&lt;span class="Apple-style-span"  style=" ;font-family:'Times New Roman';"&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;One of the things I had most trouble with while writing my first Cocoa application was understanding what a File's Owner in a &lt;a href="http://developer.apple.com/documentation/developertools/Conceptual/IB_UserGuide/BuildingaNibFile/BuildingaNibFile.html#//apple_ref/doc/uid/TP40005344-CH11-SW2"&gt;nib file&lt;/a&gt; was and what role it fulfilled.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Apple's documentation seems to imply that understanding File's Owner is important (it is) but doesn't really do a good job of explaining the concept. And I'm not alone - &lt;a href="http://www.cocoabuilder.com/archive/message/cocoa/2008/5/23/207988"&gt;this email thread &lt;/a&gt;contains a pretty good summary of what Apple's documentation says and the confusion it might create. That same thread has several peoples' attempts to explain what it is. I really didn't get too much from those explanations and ended up explaining it to myself by piecing together data from a few experiments. Now that I &lt;span class="Apple-style-span" style="font-style: italic; "&gt;think&lt;/span&gt; I understand what it's for, I figured I should try and put my take out there as well &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;in case&lt;/span&gt; it ends up helping someone else in the future.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The File's Owner of your primary nib file is, by default, the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;NSApplication&lt;/span&gt; class and this comes ready-made for you when you create your Cocoa application. If your application has just the one nib file, you really don't need to worry about File's Owner. But if that's true, your application is probably really trivial or not well written.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Generally, each new window/sheet your application creates should be contained in it's own nib for faster loading of your app and smaller &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;runtime&lt;/span&gt; footprint. When adding a nib to your application in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;XCode&lt;/span&gt;, you'll noticed that the File's Owner is set to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;NSObject&lt;/span&gt; by default (select the File's Owner object in the nib and launch Tools -&gt; Identity Inspector). I recommend setting this to a derived type for two reasons:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;So that you're forced to think about who the File's Owner of the nib is.&lt;/li&gt;&lt;li&gt;So that you don't make a silly error while defining the owner of the nib - everything is an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;NSObject&lt;/span&gt;, after all.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;A nib file is loaded dynamically at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;runtime&lt;/span&gt; usually in response to some user action (clicking a button, selecting a menu option, etc). Loading the nib is done, usually, using the &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSDocumentController_Class/Reference/Reference.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;NSDocumentController&lt;/span&gt;&lt;/a&gt; or the &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSDocumentController_Class/Reference/Reference.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;NSWindowController&lt;/span&gt;&lt;/a&gt; classes. Just because these classes help load the nib doesn't mean they must 'own' the nib. &lt;span class="Apple-style-span" style="font-style: italic; "&gt;&lt;b&gt;The File's Owner of the nib is the object that makes communication possible between this new nib and other parts of the application&lt;/b&gt;&lt;/span&gt;&lt;b&gt;.&lt;/b&gt; Let's explore this further.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The document/window loaded in the nib can have one of the following purposes:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;an informative view that isn't interactive (About box, for example)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;get some more user input to feed into other parts of the application&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;#1 is the simple case - by my definition, since there is no communication to be enabled, the File's Owner for this nib is not important. But based on my previous recommendation of not using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;NSObject&lt;/span&gt; as the File's Owner, what class should be set as the File's Owner? The object (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;NSDocumentController&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;NSWindowController&lt;/span&gt;) which loaded the nib can be made owner of the nib, and the nib loaded using the &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindowController_Class/Reference/Reference.html#//apple_ref/occ/instm/NSWindowController/initWithWindowNibName:"&gt;method overload&lt;/a&gt; that doesn't need an owner specified.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;#2 is the interesting case - if this is a form that takes in some user input it is required that this information be communicated back to another part of the application. But no one on the outside really has access to controls in this form. No one, except the File's Owner. In this case, the File's Owner should be an instance of a class that you've previously created, and the type of that instance is what you set to be the File's Owner's class in the Identity Inspector. It's important here to understand that the &lt;span class="Apple-style-span" style="font-style: italic; "&gt;File's Owner isn't a 'new instance' of the class&lt;/span&gt; you specified. &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_12"&gt;In fact&lt;/span&gt;, the File's Owner is set to an instance provided when the nib was loaded (see the last parameter of &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindowController_Class/Reference/Reference.html#//apple_ref/occ/instm/NSWindowController/initWithWindowNibName:owner:"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;initWithWindowsNibName&lt;/span&gt;&lt;/a&gt;). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So your application likely had an instance of an object created previously, which is what you would pass in as the owner of the file. That instance can now expose &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;IBOutlets&lt;/span&gt; linked to fields of the form, which can then be used by other parts of your application that already have a reference to this instance. This is what Apple documentation means when it refers to the File's Owner as a &lt;span class="Apple-style-span" style="font-style: italic; "&gt;proxy.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Hopefully, this will help someone else who's learning to work with Cocoa and needs to get some clarity around the File's Owner.&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-5603633233388319650?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/5603633233388319650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=5603633233388319650' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5603633233388319650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5603633233388319650'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/05/cocoa-what-is-files-owner-in-nib.html' title='Cocoa: What is &quot;File&apos;s Owner&quot; in a nib?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-5684309895672215376</id><published>2009-05-15T19:46:00.001-07:00</published><updated>2009-05-16T01:15:45.315-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Developing for the Mac - How does it compare?</title><content type='html'>I spent most of this week developing some Mac OS X software. Having never before written a single line of Objective-C or any Mac software, I was pretty excited. Here are a few observations of developing for the Mac compared to the Windows platform (primarily .NET) from a week's worth of writing an application using Cocoa. Of course this isn't exhaustive and only includes things I had to deal with (disclaimer - opinions subject to change as time passes):&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Overall, developer reference documentation on &lt;a href="http://developer.apple.com/referencelibrary/"&gt;Apple's Developer&lt;/a&gt; site seems more current and easy to understand than that on &lt;a href="http://msdn.microsoft.com/en-us/library/default.aspx"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;MSDN&lt;/span&gt;&lt;/a&gt;. A nice touch is the reference to examples which use a particular method &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;inline&lt;/span&gt; with the documentation of the method &lt;&lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSDocumentController_Class/Reference/Reference.html"&gt;example&lt;/a&gt;&gt; (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;MSDN&lt;/span&gt; does it using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;inline&lt;/span&gt; code, so it's not too different). My favorite feature about documentation though is the logical grouping of methods and properties arranged by &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSDocumentController_Class/Reference/Reference.html"&gt;tasks&lt;/a&gt; - that makes it very easy to get stuff done. I think this is the result of being the underdog in this space.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mac OS X applications' uniform &lt;a href="http://developer.apple.com/referencelibrary/UserExperience/index.html"&gt;usability&lt;/a&gt; and consistent aesthetic isn't a fluke. Apple's documentation regarding recommended usage is precise down to &lt;a href="http://developer.apple.com/referencelibrary/UserExperience/idxCocoa-date.html"&gt;individual visual controls&lt;/a&gt; and yet comprehensive as far as &lt;a href="http://developer.apple.com/documentation/userexperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html"&gt;Human Interface Guidelines&lt;/a&gt; go.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.apple.com/TOOLS/xcode/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;XCode&lt;/span&gt;&lt;/a&gt; doesn't have anything on &lt;a href="http://www.microsoft.com/visualstudio/"&gt;Visual Studio&lt;/a&gt;. Visual Studio seems, hands down, a better integrated development environment and debugging application. VS 2008 is really pretty awesome.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.apple.com/cocoa/"&gt;Cocoa&lt;/a&gt; is nice, but still has some catching up to do with &lt;a href="http://www.microsoft.com/NET/"&gt;.NET&lt;/a&gt;. Cocoa libraries provide just enough abstractions to get stuff done, but they don't seem to be nearly as comprehensive and well thought out as the .NET libraries are. I found myself cursing some abstractions/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;APIs&lt;/span&gt; in Cocoa for their primitiveness compared to Windows pretty often. Generics give .NET an edge that Cocoa still doesn't have. Microsoft has done a great job of handling little things, such as &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc301569.aspx"&gt;boxing&lt;/a&gt;, which make development easier than it is for Cocoa. &lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;XCode&lt;/span&gt; and &lt;a href="http://developer.apple.com/tools/interfacebuilder.html"&gt;Interface Builder&lt;/a&gt; are unfortunate crutches &lt;span class="Apple-style-span" style="font-style: italic;"&gt;required&lt;/span&gt; for Mac OS X development - I would claim that it's &lt;span class="Apple-style-span" style="font-style: italic;"&gt;impossible&lt;/span&gt; to write any decent application without using both. This sounds great until you realize that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;IB&lt;/span&gt;, which really is a designer, does so much magic for you that you just cannot with code. Linking up &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;IBOutlets&lt;/span&gt;, for instance, is something I cannot imagine can be done outside of Interface Builder and has way too much magic associated with it. As a developer I often felt at the mercy of these tools, instead of being the master of it. It's fortunate that this is not true of developing for Windows - there is a lot of helpful magic that Visual Studio builds in but it's certainly not &lt;span class="Apple-style-span" style="font-style: italic;"&gt;required&lt;/span&gt; to develop a decent application.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Overall, the Mac platform (Cocoa) seems more closed than it should be. This sounds &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_9"&gt;weird&lt;/span&gt;, considering that it's all basically Unix and standard Unix libraries are provided or can be added &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;relatively&lt;/span&gt; easily. My comment here related to how accessible and complete Cocoa/&lt;a href="http://developer.apple.com/Carbon/"&gt;Carbon&lt;/a&gt; libraries are. Getting access to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_11"&gt;weird&lt;/span&gt; parts of the system is easier on Windows that on the Mac platform, I believe.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Deploying Mac applications is a snap, better than Windows. However, I think this is related to how developers are accustomed to (ab)using resources in Windows (registry, etc). Not having a lot of Windows' 'legacy' facilities on the Mac makes developers think hard about what their app really should be doing. I claim that good developers should be able to create x-copy &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;deployable&lt;/span&gt; apps even for Windows, though, so it's unfair to blame the platform here.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The fact that it's built on Unix makes the mac support a lot more languages, especially scripting languages, out of the box. Windows is catching up fast though - integration of &lt;a href="http://www.ironruby.net/"&gt;interpreted&lt;/a&gt;&lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython"&gt; languages&lt;/a&gt; with .NET and &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;PowerShell&lt;/span&gt;&lt;/a&gt; bring it at par with the Mac (I hear it might be better, but I don't have much experience).&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Testing on the Mac seems easier. The fact that there are a very finite set of configurations compared to the Windows platform makes life less complicated for developers. It's almost true that if it works on your Mac it's probably doing to work on most Macs (modulo a few exceptions).  History says this has traditionally been an advantage of the Windows platform, but I'm not so sure it's a good thing anymore. This one's probably the most controversial of my observations above and likely to change as I do more Mac work.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, who wins? I would say Windows for the overall developer friendliness. Apple has some catching up to do in several areas. That said, the Windows platform could learn more than just a few things from what Apple seems to be doing right. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's a fun time to be a software developer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-5684309895672215376?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/5684309895672215376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=5684309895672215376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5684309895672215376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5684309895672215376'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/05/developing-for-mac-how-does-it-compare.html' title='Developing for the Mac - How does it compare?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-8987653903133487386</id><published>2009-01-16T13:41:00.000-08:00</published><updated>2009-01-16T15:10:57.284-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politics'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='World'/><title type='text'>A Run on the Bank of Microsoft?</title><content type='html'>Wow... did I just predict this? Yesterday, in my &lt;a href="http://crazyviraj.blogspot.com/2009/01/problems-at-facebook.html"&gt;Problems at Facebook?&lt;/a&gt; post I referenced (somewhat jokingly) how I was kinda surprised that in the current economic conditions, the EU hadn't tapped into the Microsoft cash machine using some anti-trust excuse. Lo and behold, a few minutes ago Microsoft issued a &lt;a href="http://www.microsoft.com/presspass/press/2009/jan09/01-16statement.mspx"&gt;press release&lt;/a&gt; in response to a 'Statement of Objections' it received from the EU about - you guessed it - European anti-trust law. Obviously, I had no knowledge of this when I posted yesterday - I'm just a foot soldier. The timing is a little spooky though... maybe I should muse of some good things happening. ;)&lt;br /&gt;&lt;br /&gt;I wonder if this is the beginning of another run on the Bank of Microsoft by the EU...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update:&lt;/strong&gt; More coverage in the &lt;a href="http://online.wsj.com/article/SB123213711567091269.html?mod=testMod"&gt;Wall Street Journal&lt;/a&gt;. This thing is probably going to go on for a while. Sigh!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-8987653903133487386?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/8987653903133487386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=8987653903133487386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8987653903133487386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8987653903133487386'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/01/run-on-bank-of-microsoft.html' title='A Run on the Bank of Microsoft?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-8466219535199104859</id><published>2009-01-15T13:19:00.000-08:00</published><updated>2009-01-15T13:30:07.287-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows 7'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Win 7's glowing reviews - a case of lowered expectations?</title><content type='html'>Windows 7 was publicly released as a beta last week, and has been getting some pretty glowing reviews. I haven't yet seen a single negative review - everything I've seen compares Windows 7 much favourably over Vista and in many cases even over &lt;span id="SPELLING_ERROR_0" class="blsp-spelling-error"&gt;XP&lt;/span&gt;. &lt;a href="http://blogs.zdnet.com/hardware/?p=3223"&gt;&lt;span id="SPELLING_ERROR_1" class="blsp-spelling-error"&gt;ZDNet's&lt;/span&gt; review&lt;/a&gt; is pretty typical of most reviews I've read. Even traditional Microsoft haters (who shall go &lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;un-&lt;/span&gt;named) seem to be reacting favorably to Windows 7. Of course there are some brand new features, but I'm more concerned with the stability and snappiness of the OS.&lt;br /&gt;&lt;br /&gt;While a lot of the praise is well deserved and a lot of people have worked hard on making Windows 7 what it is, I can't help but wonder how much of it is a result of peoples' lowered expectations from Microsoft with regards to Windows. Vista wasn't nearly as good as it should have been when it released (SP1 seems to have fixed a lot of stability issues, though it is still a resource hog) and the generally negative buzz about Vista has probably reduced expectations to the point where anything that's not sluggish, bloated and resource hungry would've received good feedback.&lt;br /&gt;&lt;br /&gt;Anyways, nothing wrong with good reviews... here's hoping that Windows 7 will exceed all expectations when it's publicly released.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-8466219535199104859?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/8466219535199104859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=8466219535199104859' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8466219535199104859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8466219535199104859'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/01/win-7s-glowing-reviews-case-of-lowered.html' title='Win 7&apos;s glowing reviews - a case of lowered expectations?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3700241698811503155</id><published>2009-01-15T12:41:00.000-08:00</published><updated>2009-01-15T14:20:01.698-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><title type='text'>Problems at Facebook?</title><content type='html'>I was thinking about the whole recession thing and how it impacts Microsoft. As I worked through my train of thought, I remembered the huge &lt;a href="http://www.iht.com/articles/reuters/2008/02/27/business/OUKBS-UK-MICROSOFT-EU.php"&gt;899 million Euro fine&lt;/a&gt; that the EU slapped Microsoft with in Feb 2008. I remember thinking then that the EU was almost treating Microsoft like an ATM (probably inspired by &lt;a href="http://www.techcrunch.com/2008/02/28/microsoft-the-eus-atm-machine/comment-page-3/"&gt;this post&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;I wondered why in this time of recession the EU hasn't yet again tapped its ATM and thought I'd update my Facebook status to say "&lt;em&gt;Viraj wonders why, with this recession n all, the EU hasn't tapped its ATM (Microsoft) again using the same anti-trust excuse...&lt;/em&gt;". To my surprise, I got a little popup that said "Validation Error - A validation error occured" and nothing more informative.&lt;br /&gt;&lt;br /&gt;Interesting. What exactly is Facebook validating, and did I have some red-herring text in there? I would expect filters for expletives, racial slurs, geo-political issues... but my status message didn't seem to violate any of those. I tried the following variants, which all failed:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;"Viraj wonders why, with this recession n all, the EU hasn't tapped its ATM (MSFT) again using the same anti-trust excuse..."&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;"Viraj wonders why, with this recession n all, the EU hasn't tapped its ATM again using the same anti-trust excuse..."&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;"Viraj wonders why, with this recession n all, the EU hasn't tapped its ATM again..."&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;"Viraj wonders why, with this recession n all, the EU"&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;"wonders..."&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;Ok, so it's certainly not the text of my status message that's causing this. I started poking around, and my 'Home' page seemed OK - I had news items, status updates from friends, etc. However, when I jumped to my own profile, I was suprised to find that all data I had published was blank. No wall posts, no posted items, no recent history. However, my photo albums seemed to fine, as did my profile information.&lt;br /&gt;&lt;br /&gt;My guess is there's been some kind of data loss-ish issue at FB (a lot of their data is simply held in &lt;a href="http://www.facebook.com/notes.php?id=9445547199"&gt;caches&lt;/a&gt; so maybe a cache and replicas blew away - perhaps Wall posts are not persisted?). Anyways, I'll try to update status again and see if stuff comes back... meanwhile, I'm locked out of changing my Facebook status...&lt;br /&gt;&lt;br /&gt;Any guesses about what might be going on?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update&lt;/strong&gt;: I can't seem to be able to clear my previous status message either... the status is cleared in the webpage (local javascript clearing it, I would assume) but on refresh I see my old status again...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update2&lt;/strong&gt;: And we're back... that didn't last too long. Cool!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3700241698811503155?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3700241698811503155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3700241698811503155' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3700241698811503155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3700241698811503155'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2009/01/problems-at-facebook.html' title='Problems at Facebook?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-140319237739856811</id><published>2008-10-08T20:46:00.000-07:00</published><updated>2008-10-08T20:49:06.531-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='LiveMesh'/><title type='text'>Post on The Live Mesh Blog, PDC 2008</title><content type='html'>&lt;div&gt;I wrote a post on the &lt;a href="http://blogs.msdn.com/livemesh/"&gt;Live Mesh Blog&lt;/a&gt; earlier today that talks about what I primarily work on - the &lt;a href="http://blogs.msdn.com/livemesh/archive/2008/10/08/behind-live-mesh-the-pub-sub-system.aspx"&gt;Pub-Sub backend of Live Mesh&lt;/a&gt;. I briefly referenced that I worked in this space in a &lt;a href="http://crazyviraj.blogspot.com/2008/07/some-thoughts-on-apples-push.html"&gt;previous post&lt;/a&gt; where I commented on Apple's Push Notification announcements.&lt;br /&gt;&lt;br /&gt;I've written tons of design documents, specs and tech summaries on the job but writing this post was an interesting exercise - I tried to make it readable for both the geeks and the regular folks in the audience (hence the references to the postal system). I'm not sure how well this will work... I guess feedback from the blog comments will be a good indicator of how effective the attempt was.&lt;br /&gt;&lt;br /&gt;In addition to my &lt;a href="http://blogs.zdnet.com/microsoft/?p=349"&gt;awesomely smart teammates&lt;/a&gt; on the Live Mesh team, who I enjoy working with greatly, I wanted to send a shoutout to &lt;a href="http://www.spiteful.com/about/"&gt;Tom&lt;/a&gt; who originally helped design a lot of the stuff described in the blog post.&lt;br /&gt;&lt;br /&gt;For those who want more details about how stuff works behind the scenes, there are some &lt;a href="http://blogs.msdn.com/livemesh/archive/2008/09/26/the-live-platform-at-pdc.aspx"&gt;Live Mesh related deep-dive sessions&lt;/a&gt; scheduled at &lt;a href="https://sessions.microsoftpdc.com/public/sessions.aspx"&gt;PDC 2008&lt;/a&gt;. Sessions related to the Live Mesh backend architecture (&lt;a href="http://channel9.msdn.com/pdc2008/BB06/"&gt;"Live Services: Mesh Services Architecture and Concepts"&lt;/a&gt; by Abolade Gbadegesin) and backend communications services (&lt;a href="http://channel9.msdn.com/pdc2008/BB34/"&gt;"Live Services: Notifications, Awareness, and Communications"&lt;/a&gt; by John Macintyre) might be most interesting to those who were intrigued by my post on the Live Mesh Blog and are curious to know more. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately, I won't be attending PDC - I'll probably be busy chugging caffeine and fanning servers while thousands of new users give our new Live Mesh offerings a spin. :) &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-140319237739856811?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/140319237739856811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=140319237739856811' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/140319237739856811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/140319237739856811'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/10/post-on-live-mesh-blog-pdc-2008.html' title='Post on The Live Mesh Blog, PDC 2008'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-356205317319881779</id><published>2008-10-08T10:53:00.000-07:00</published><updated>2009-05-17T15:59:48.706-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politics'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>More Food For Thought About Google And Exit Polls</title><content type='html'>A couple of months ago I conjectured that &lt;a href="http://crazyviraj.blogspot.com/2008/08/can-google-predict-election-08-results.html"&gt;Google might be able to produce a very accurate exit poll for the '08 Election&lt;/a&gt;. Today's &lt;a href="http://googleblog.blogspot.com/2008/10/presidential-debate-expanding-town-hall.html"&gt;post&lt;/a&gt; on the Official Google Blog shows some information that's very close to what I suspected they could generate - very cool. Particularly interesting is analysis of &lt;a href="http://4.bp.blogspot.com/_Ap14FtNN91w/SOx0vun_1mI/AAAAAAAABhA/2wgfkDkSpkU/s1600-h/DEBATE2_mccain-obama-swing-in-debate-2.PNG"&gt;traffic&lt;/a&gt; from &lt;a href="http://searchvote.com/Default.aspx?q=swing+state"&gt;swing states&lt;/a&gt;. I'm sure they could do much more here - trending by counties, for instance.&lt;br /&gt;&lt;br /&gt;In that &lt;a href="http://crazyviraj.blogspot.com/2008/08/can-google-predict-election-08-results.html"&gt;previous post&lt;/a&gt; of mine, I guessed that they won't publicly release a prediction, but bits and pieces of information and trends like these are a good stand-in for a full blown exit poll.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-356205317319881779?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/356205317319881779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=356205317319881779' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/356205317319881779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/356205317319881779'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/10/more-food-for-thought-about-google-and.html' title='More Food For Thought About Google And Exit Polls'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-2366267928399613810</id><published>2008-10-07T21:31:00.000-07:00</published><updated>2008-10-07T23:01:18.610-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random'/><title type='text'>Regret - Not Reading Enough Books!</title><content type='html'>A very regretful personal trend I've noticed over the last few years is that I've been reading a lot fewer books than I used to, and I didn't used to read too many earlier either. This applies to works of fiction, self-help books, biographies, etc - the more 'traditional' books. I'm often reminded of this personal shortcoming of mine when I'm around friends and family who read a lot - I usually have much to contribute to conversations, until the topic turns to recent/popular books and I just draw blanks.&lt;br /&gt;&lt;br /&gt;This regret hits home even more on the rare occasions that I do pick up a book recommended by my wife or my friends (on average, once in 2 months) - I tend to enjoy these books more often than not. The last works of fiction I read were &lt;span id="SPELLING_ERROR_0" class="blsp-spelling-error"&gt;Jhumpa&lt;/span&gt; &lt;span id="SPELLING_ERROR_1" class="blsp-spelling-error"&gt;Lahiri's&lt;/span&gt; &lt;a href="http://www.amazon.com/Unaccustomed-Earth-Jhumpa-Lahiri/dp/0307265730/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1223444480&amp;amp;sr=8-1"&gt;Unaccustomed Earth&lt;/a&gt; and Neal Stephenson's &lt;a href="http://www.amazon.com/Snow-Crash-snowcrash/dp/B000HK4JCI/ref=sr_1_3?ie=UTF8&amp;amp;s=books&amp;amp;qid=1223444541&amp;amp;sr=1-3"&gt;Snow Crash&lt;/a&gt; - both recommendations which I enjoyed, and took about 1+ months each to read. I read much slower than most 'good' readers (my wife, who can chow down books orders of magnitude faster than I can), which means I have more breaks and more opportunities for distractions.&lt;br /&gt;&lt;br /&gt;When it comes to non-book reading though, it's a whole different story. I'm a voracious reader of blogs, news, current events, technology, opinions and trivia. I can read a newspaper cover-to-cover as fast as anyone I know, browse through several blogs a day without realizing it and read editorials/articles online pretty regularly. Maybe reality is just more entertaining than stories, or lessons from current events are more exciting than lessons in self-help books, or maybe I just do well with 'shorter' reading.&lt;br /&gt;&lt;br /&gt;Or maybe I'm just not comfortable with the form factor of traditional books, which is why I've been eyeing Amazon's phenomenally successful &lt;a href="http://www.amazon.com/kindle"&gt;Kindle&lt;/a&gt; - I wonder if that's my panacea. It's not cheap though. It would be super-awesome to be able to rent a Kindle at local libraries to check it out. I would totally buy one if it let's me get back into reading more 'traditional' books.&lt;br /&gt;&lt;br /&gt;&lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;Hmm&lt;/span&gt;, I'm really tempted now. Maybe I'll just cough up the dough and give this a shot. Anyone have good/bad experiences to share about their Kindle?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-2366267928399613810?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/2366267928399613810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=2366267928399613810' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2366267928399613810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2366267928399613810'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/10/regret-not-reading-enough-books.html' title='Regret - Not Reading Enough Books!'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-2840311035109487392</id><published>2008-09-30T19:14:00.000-07:00</published><updated>2008-10-02T15:43:47.426-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Live Search'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Surprised by Live Search</title><content type='html'>I use &lt;a href="http://live.com/"&gt;Live Search&lt;/a&gt; as my web search engine of choice, but every so often I need to use &lt;a href="http://google.com/"&gt;Google&lt;/a&gt; to find the information I'm really looking for. I was really looking for a site that gave me good side-by-side results from both engines - kind of like how dogpile.com used to work in the old days (I was surprised to find dogpile.com still alive and doing search compilation, but I really wanted a side-by-side view from only my two preferred engines).&lt;br /&gt;&lt;br /&gt;Recently, as part of an internal Microsoft initiative, I found exactly what I was looking for - a site that runs the searches in parallel and presents them side-by-side. As a bonus, you get to vote on which engine performed better. I've been using this as my default search engine on all my machines for the last few days and I'm already pretty surprised at how often Live Search comes up with far superior answers. I guess I never paid to attention to comparative relevance and quality until it was presented to me in such an 'in-your-face' manner. Of course, there are still many searches where Google trumps Live Search. Anecdotally, I'd say I prefer Live Search about 60-70% of the time, but maybe that's just me (and it could well be my inherent bias for Microsoft products).&lt;br /&gt;&lt;br /&gt;One aspect that simply blew me away was Live Search's ability to fetch answers for very specific things I was looking for. A lot of these are powered by something Live Search calls &lt;a href="http://searchvote.com/Default.aspx?q=Live+Search+Instant+Answers"&gt;'Instant Answers'&lt;/a&gt;. A few samples from queries I performed over the last week where I was really impressed by Live Search:&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://search.live.com/results.aspx?q=MSFT+GOOG+AMZN+AAPL+quote&amp;amp;form=QBLH"&gt;MSFT GOOG AMZN AAPL quote&lt;/a&gt; vs &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=MSFT+GOOG+AMZN+AAPL&amp;amp;aq=f&amp;amp;oq="&gt;MSFT GOOG AMZN AAPL&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://search.live.com/results.aspx?q=seahawks+schedule&amp;amp;form=QBRE"&gt;seahawks schedule&lt;/a&gt; vs &lt;a href="http://www.google.com/search?q=seahawks+schedule&amp;amp;rls=com.microsoft:en-us&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8&amp;amp;startIndex=&amp;amp;startPage=1"&gt;seahawks schedule&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://search.live.com/results.aspx?q=highest+peak+in+the+US"&gt;highest peak in the US&lt;/a&gt; vs &lt;a href="http://www.google.com/search?hl=en&amp;amp;rls=com.microsoft%3Aen-us&amp;amp;q=highest+peak+in+the+US"&gt;highest peak in the US&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://search.live.com/results.aspx?q=calories+in+beer+&amp;amp;form=QBRE"&gt;calories in beer&lt;/a&gt; vs &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=calories+in+beer&amp;amp;aq=f&amp;amp;oq="&gt;calories in beer&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://search.live.com/results.aspx?q=president+of+somalia&amp;amp;form=QBRE"&gt;president of somalia&lt;/a&gt; vs &lt;a href="http://www.google.com/search?q=president+of+somalia&amp;amp;rls=com.microsoft:en-us&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8&amp;amp;startIndex=&amp;amp;startPage=1"&gt;president of somalia&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://search.live.com/results.aspx?q=colt+mccoy&amp;amp;form=QBRE"&gt;Colt McCoy&lt;/a&gt; vs &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=colt+mccoy"&gt;Colt McCoy&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;These were just some of the searches I ran last week - the Instant Answers site has other query formats you can try (incidentally, I didn't know about Instant Answers or the formats until just two days ago). One place where Google still beats Live Search hands down is showing inline maps and directions. I use this fact to give a lot of sh*t to a friend of mine who works on &lt;a href="http://maps.live.com/"&gt;Live Maps&lt;/a&gt; - maybe one of these days I'll annoy him enough to make him go fix this stuff! ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-2840311035109487392?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/2840311035109487392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=2840311035109487392' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2840311035109487392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2840311035109487392'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/09/surprised-by-live-search.html' title='Surprised by Live Search'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3882974523610555141</id><published>2008-09-12T13:48:00.000-07:00</published><updated>2008-09-12T14:30:16.355-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bill Gates'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='Jerry Seinfeld'/><title type='text'>Bill &amp; Jerry, and A Lame Blog Post</title><content type='html'>You've probably seen the new &lt;a href="http://www.microsoft.com/windows/"&gt;Microsoft Windows TV ads&lt;/a&gt; featuring Jerry Seinfeld and Bill Gates. The second in the series showed up last night.&lt;br /&gt;&lt;br /&gt;When I first heard that Jerry Seinfeld was signed for the ad campaign, I wasn't really sure if he would appeal to the current generation (and I'm not sure he does). I'm a Seinfeld fan though, so I was curious what the campaign would be like. I have to be honest - the ads were completely not what I was expecting. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;FWIW&lt;/span&gt;, not many in the company had seen the ads before they were shown publicly - at least, I hadn't.&lt;br /&gt;&lt;br /&gt;Anyways, it seems like the ads &lt;a href="http://www.techcrunch.com/2008/09/12/bill-gatesjerry-seinfeld-commercial-2-i-remain-confused/"&gt;have&lt;/a&gt; &lt;a href="http://news.cnet.com/8301-17852_3-10034455-71.html"&gt;people&lt;/a&gt; &lt;a href="http://mobilitysite.com/2008/09/gates-seinfeld-and-ad-1/"&gt;talking&lt;/a&gt;. From what I've read, the reaction seems to be neutral to leaning negative - I think people were expecting a more direct retort to &lt;a href="http://www.youtube.com/results?search_query=Mac+PC+Apple&amp;amp;search_type=&amp;amp;aq=f"&gt;Apple's Mac vs PC&lt;/a&gt; ads. Personally, I found the ads pretty amusing. Subtle humor, no direct attacks and entertaining. I think Bill easily outshines Jerry in both ads so far. I had seen Bill Gates act in silly videos at company meetings before, plus in his &lt;a href="http://www.youtube.com/watch?v=3HA4lSUhlbw"&gt;last day at Microsoft&lt;/a&gt; video, so I knew he can do a decent job but I didn't think he could out-do Seinfeld. There are subtle references to Microsoft products and technologies throughout the ads - pretty funny for someone close to Microsoft but I can see how pretty much everyone else might miss it. From the coverage the campaign has gotten and the pervasiveness of the ad spots, I'm pretty impressed with how much buzz the campaign has already generated. A lot of critics have complained that the ad hardly mentioned Microsoft or Windows... does it really need to, though? Bill Gates == Microsoft == Windows. No more logos/information needed.&lt;br /&gt;&lt;br /&gt;Knowing nothing other than what I've seen on TV so far, I think this will definitely be a long-remembered ad campaign. It looks like its going to be one of those hugely successful or hugely miserable ad campaigns. Of course, given that work @ Microsoft I hope it's successful.&lt;br /&gt;&lt;br /&gt;I wonder how many &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;CEOs&lt;/span&gt; have featured in ads. I can remember a few in recent times - Chrysler, Sprint, Ford. None of those had the CEO doing comedy, though. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;CEOs&lt;/span&gt;, especially founder-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;CEOs&lt;/span&gt;, have huge brand appeal and brand recognition so they seem to be a natural fit for come-back type ads. I hope Microsoft has better success than Ford, Chrysler and Sprint are having currently, though.&lt;br /&gt;&lt;br /&gt;Given the buzz around the ads, I was kinda annoyed when David Webster from Microsoft, who's apparently running this campaign, &lt;a href="http://windowsvistablog.com/blogs/windowsvista/archive/2008/09/11/what-s-up-with-those-ads.aspx"&gt;posted&lt;/a&gt; an entry on his blog trying to justify the ads - the text of the post just reeks of defensiveness. If you're ballsy enough to sanction $300 million for an ad campaign, there's no need to put up a blog post trying to justify it even before the entire campaign has run its course. His tone sounds like he's trying to save his job already - where's the confidence, man? Super lame, Mr David Webster. I think you &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;should've&lt;/span&gt; just kept quiet and let the campaign do the talking (or not, if they don't succeed).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3882974523610555141?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3882974523610555141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3882974523610555141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3882974523610555141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3882974523610555141'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/09/bill-jerry-and-lame-blog-post.html' title='Bill &amp; Jerry, and A Lame Blog Post'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3684675059076600379</id><published>2008-08-28T17:50:00.000-07:00</published><updated>2009-05-17T16:00:02.269-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politics'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Elections'/><title type='text'>Can Google Predict Election '08 Results?</title><content type='html'>Today's post on TechCrunch about &lt;a href="http://www.techcrunch.com/2008/08/28/which-presidential-candidates-home-page-is-more-popular-and-can-it-predict-the-election/"&gt;possibly predicting election results using web traffic analysis&lt;/a&gt; reminded me of my thoughts from a few months ago.&lt;br /&gt;&lt;br /&gt;Over the course of election season, starting with the presidential primaries through Super Tuesday and going into the national conventions, Google &lt;a href="http://googleblog.blogspot.com/2008/08/bring-political-process-to-life-in-your.html"&gt;began&lt;/a&gt; &lt;a href="http://googleblog.blogspot.com/2006/10/google-earth-voter-guide.html"&gt;releasing&lt;/a&gt; &lt;a href="http://googleblog.blogspot.com/2008/06/elections-in-internet-era.html"&gt;increasing&lt;/a&gt; &lt;a href="http://googleblog.blogspot.com/2008/04/five-factors-to-look-for-in.html"&gt;amounts&lt;/a&gt; of &lt;a href="http://googleblog.blogspot.com/2008/07/more-tools-for-citizen-participation.html"&gt;election-related&lt;/a&gt; &lt;a href="http://googleblog.blogspot.com/2008/07/in-their-own-words-political-videos.html"&gt;content&lt;/a&gt; and &lt;a href="http://googleblog.blogspot.com/2008/08/election-season-in-high-gear.html"&gt;services&lt;/a&gt;. Reading the blog posts linked above and noticing the trend from Google leads to me the conclusion that the most relevant &lt;a href="http://en.wikipedia.org/wiki/Exit_poll"&gt;exit-poll&lt;/a&gt; for November's presidential election this year might actually come from Google.&lt;br /&gt;&lt;br /&gt;Google likely already &lt;a href="http://www.google.com/searchhistory/login"&gt;tracks user searches&lt;/a&gt; and &lt;a href="http://blogs.zdnet.com/micro-markets/?p=325"&gt;email data from GMail&lt;/a&gt;. Combine that with some pretty basic data mining around traffic analysis, comments on their targetted election sites and popularity of their election related content/services and you could now get a pretty good 'pulse-of-the-nation' with respect to red state-vs-blue state. My guess is that the big push around election related content and services is an attempt to not only increase pageviews, but also harness large amounts of interesting data that can be mined for various interesting purposes. Additionally, this gives them a large data set to use to refine their own data mining technologies. I strongly suspect that Google will hold on to the raw data past election time and used it as test-data to track progresses in their mining technologies. Good data to test your technologies is *very* hard to to come by, and it would be foolish to let such rich data simply fall by the wayside.&lt;br /&gt;&lt;br /&gt;Whether they publicly release their 'exit-poll' is another story altogether. I don't think Google really has much to gain by releasing the data even if they do manage to mine it. I know I wouldn't - I would mine the data, distribute predictions among team members for entertainment purposes only, see how close I got to the result, refine my algorithms and run it over the same data again to see how much closer I am now, and repeat. Releasing the data publicly, even if it turned out to be dead-on accurate, wouldn't buy me much. If it wasn't dead-on accurate, there is some amount of geek-cred that would be lost.&lt;br /&gt;&lt;br /&gt;I guess November will prove if my theory above is correct.&lt;br /&gt;&lt;br /&gt;P.S. I hope you picked up on the paradox in that last sentence above... :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3684675059076600379?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3684675059076600379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3684675059076600379' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3684675059076600379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3684675059076600379'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/08/can-google-predict-election-08-results.html' title='Can Google Predict Election &apos;08 Results?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-8151914490816853122</id><published>2008-07-30T12:04:00.000-07:00</published><updated>2009-05-17T15:59:31.233-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politics'/><category scheme='http://www.blogger.com/atom/ns#' term='World'/><title type='text'>$10,000,000,000 == $1</title><content type='html'>&lt;span &gt;I'm no economist, but it's hard to not have &lt;/span&gt;&lt;a href="http://online.wsj.com/article/SB121743031982297105.html"&gt;&lt;span &gt;seen this coming&lt;/span&gt;&lt;/a&gt;&lt;span &gt;. From the article: &lt;/span&gt;&lt;span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;Zimbabwe will drop 10 zeros from its hyper-inflated currency -- turning 10 billion dollars into one -- the country's reserve bank said Wednesday. President Robert Mugabe threatened a state of emergency if businesses profiteer from the country's economic and political unraveling. &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span &gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;Just a couple of weeks ago, Zimbabwe introduced a &lt;/span&gt;&lt;a href="http://today.reuters.com/news/articlenews.aspx?storyID=2008-07-19T094304Z_01_L19624102_RTRUKOC_0_US-ZIMBABWE-CRISIS-CBANK.xml&amp;amp;rpc=81"&gt;&lt;span &gt;100-billion dollar bill&lt;/span&gt;&lt;/a&gt;&lt;span &gt;, and it didn't buy nearly enough. People are suffering in Zimbabwe while a corrupt government mismanages the economy. I truly hope their economy recovers soon...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-8151914490816853122?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/8151914490816853122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=8151914490816853122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8151914490816853122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8151914490816853122'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/10000000000-1.html' title='$10,000,000,000 == $1'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-4711877736380716058</id><published>2008-07-28T15:05:00.000-07:00</published><updated>2008-07-28T15:29:44.919-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Engineering'/><title type='text'>Doing Something "Just Because We Can!"</title><content type='html'>Working on a distributed system like &lt;a href="http://www.mesh.com/"&gt;Live Mesh&lt;/a&gt; is a lot of fun, but finding certain types of bugs can be &lt;em&gt;interesting&lt;/em&gt;, to say the least. Going from writing code that executes locally on a workstation to writing code that is executed across several hundred machines is an extremely refreshing experience - you quickly learn to spend a good amount of your time and energy building a good logging infrastructure and leveraging it to diagnose problems. There are several other things you learn too, but that's worth a series of its own posts.&lt;br /&gt;&lt;br /&gt;With a large amount of logs comes a large amount of interesting data, and an even larger amount of &lt;em&gt;potentially&lt;/em&gt; interesting data. Good logs can go a long way in helping infer information about the scale, health, bottlenecks, usage etc of the system. Much time is spent automating such tasks so that useful reports can be generated from logs. Every so often, someone (usually a non-tecnnical person) asks for additional interesting data that would take time, effort and money (in terms of resource utilization) to extract. However, almost all such requests are missing information about what the requester hopes to conclude based on the retrieved data. My instinct is to always push back on such requests, forcing the requester to justify what questions the data will help answer or what conclusions it'll help lead to. If the data gathered does indeed help answer a crucial question, it's worth spending time and money mining the logs for it.&lt;br /&gt;&lt;br /&gt;Very often, the reason for the request is "just because we can", in which case I believe the time/money/effort spent is unwarranted unless you have people/machines sitting around doing nothing, in which case you arguably have other problems.&lt;br /&gt;&lt;br /&gt;Moral of the story - try not to ask someone else to do work (or spend your own valuable time doing work) without knowing what you intend to get out of it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-4711877736380716058?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/4711877736380716058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=4711877736380716058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4711877736380716058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4711877736380716058'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/doing-something-just-because-we-can.html' title='Doing Something &quot;Just Because We Can!&quot;'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-3254861744652239727</id><published>2008-07-23T09:47:00.001-07:00</published><updated>2008-07-23T09:58:31.830-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Movies'/><category scheme='http://www.blogger.com/atom/ns#' term='Entertainment'/><title type='text'>Blown Away by IMAX (Again)</title><content type='html'>I caught The Dark Knight at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;IMAX&lt;/span&gt;, and it was so worth the wait (waited in line for an hour, on a weeknight!). I've watched a few movie at the &lt;a href="http://www.pacsci.org/imax/"&gt;Boeing &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;IMAX&lt;/span&gt; Theater&lt;/a&gt; at the Pacific Science Center a few times now, and each time I come back amazed at the infinitely better movie-watching experience that the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;theatre&lt;/span&gt; provides. Select scenes of The Dark Knight were shot for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;IMAX&lt;/span&gt; (pretty much all &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;cityscape&lt;/span&gt; scenes in Gotham City and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Hong&lt;/span&gt; Kong) and they were just stunning. Too bad there were no real 3D scenes, like there were in &lt;a href="http://www.imax.com/ImaxWeb/filmDetail.do?type=nowPlaying&amp;amp;movieID=code__.__59177"&gt;Harry Potter and The Order of the Phoenix&lt;/a&gt;. I really need to catch more movies at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;IMAX&lt;/span&gt; - its likely the long lines that put me off, but I need to keep reminding myself that they're totally worth it.&lt;br /&gt;&lt;br /&gt;If you have a choice to watch a movie @ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;IMAX&lt;/span&gt; or at your neighborhood multiplex, do yourself a favor and pick the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;IMAX experience.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-3254861744652239727?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/3254861744652239727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=3254861744652239727' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3254861744652239727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/3254861744652239727'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/blown-away-by-imax-again.html' title='Blown Away by IMAX (Again)'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-4615269109202595725</id><published>2008-07-17T09:59:00.000-07:00</published><updated>2008-07-17T11:14:00.382-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='YouTube'/><category scheme='http://www.blogger.com/atom/ns#' term='FriendFeed'/><category scheme='http://www.blogger.com/atom/ns#' term='Facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Yahoo'/><category scheme='http://www.blogger.com/atom/ns#' term='Technology Predictions'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='Meebo'/><title type='text'>What Live Messenger, AIM and Y! Messenger Need to Remain Popular</title><content type='html'>Two things - broadcasting and aggregation.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://get.live.com/messenger/overview"&gt;Windows Live Messenger&lt;/a&gt;, &lt;a href="http://www.aim.com/"&gt;AOL Instant Messenger&lt;/a&gt;, &lt;a href="http://messenger.yahoo.com/"&gt;Y! Messenger&lt;/a&gt; and &lt;a href="http://www.google.com/talk/"&gt;Google Talk&lt;/a&gt; and several others are hugely popular &lt;a href="http://en.wikipedia.org/wiki/Instant_messaging"&gt;Instant Messaging&lt;/a&gt; applications. Almost all offer rich client experiences as well as web-based versions. I remember reading somehwere that IM apps are the most used apps on computers, and I am pretty sure they will continue to be for the near future. Demand for IM applications on the web is pretty strong too, with sites such as &lt;a href="http://www.meebo.com/"&gt;Meebo&lt;/a&gt; growing in popularity.&lt;br /&gt;&lt;br /&gt;IM clients have been very innovative over the years, starting from simple 2-person chat to having multi-party conversations, voice support, application sharing, file transfers, etc. Innovation in this space seems to be slowing down though - I haven't seen any new game changing features in any of these IM applications. They all seem to have missed the move to a more social web. In many ways, these apps &lt;em&gt;should&lt;/em&gt; have been the ones driving the social web, with their knowledge of social networks via friend-lists. However, websites like &lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt;, &lt;a href="http://www.myspace.com/"&gt;MySpace&lt;/a&gt; and &lt;a href="http://www.orkut.com/"&gt;Orkut&lt;/a&gt; have firmly established themselves as the drivers of innovation in the social space.&lt;br /&gt;&lt;br /&gt;Consumer interactions are evolving from being specifically directed to an individual or small group to being widely broadcast. Blogs, &lt;a href="http://twitter.com/"&gt;tweets&lt;/a&gt; and &lt;a href="http://www.linkedin.com/in/virajm"&gt;public profiles&lt;/a&gt; are visible to anyone and often are used as a broadcast medium. Increasingly, status messages on social websites and, more importantly, micro-blogging are encroaching on the IM space. Twitter clients such as &lt;a href="http://twitter.com/twhirl"&gt;Twhirl&lt;/a&gt; are a great example of this encroachment - users interact with it if it was an IM client but it's really just an app that allows broadcasting messages. &lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt; is another hugely successful broadcast medium.&lt;br /&gt;&lt;br /&gt;Ofcourse, users also want the ability to have personal, directed conversations along with the ability to broadcast - both to a select group (their network) as well as broadly to the world. For IM application to remain relevant and to fulfill this need, they need to include broadcasting features in addition to preserving the existing communication &amp;amp; collaboration experiences. There are multiple potential approaches to do this - use existing APIs of popular social platforms to allow users to broadcast to a specific network or to farm out to multiple social networks&lt;br /&gt;&lt;br /&gt;With the desire to broadcast comes the desire to learn about what others are boadcasting. Most (all?) social websites have news feeds and services can aggregate several such feeds to present a unified view of a users online broadcasts/activity like how &lt;a href="http://www.friendfeed.com/"&gt;FriendFeed&lt;/a&gt; does. An IM application would be an ideal home for such an aggregated feed.&lt;br /&gt;&lt;br /&gt;In many ways, Facebook is almost there with regards to being an ideal IM application. It has the advantage of being a really popular social platform, which certainly helps. Facebook recently complemented their broadcast communication feature (status messages) with IM-like functionality to enable personal communications. And of course, Facebook pioneered the news feed. Now if only they could go broadcast to and aggregate from competitor sites too... ;)&lt;br /&gt;&lt;br /&gt;The arguments above apply even to corporate IM applications - this is not just a consumer need.&lt;br /&gt;Unless traditional IM applications evolve to fill this need and compete with the Facebooks of the world, I see them dying a long, slow death.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-4615269109202595725?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/4615269109202595725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=4615269109202595725' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4615269109202595725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/4615269109202595725'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/what-live-messenger-aim-and-y-messenger.html' title='What Live Messenger, AIM and Y! Messenger Need to Remain Popular'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-9184898098084571503</id><published>2008-07-14T18:20:00.001-07:00</published><updated>2008-07-14T18:37:46.309-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='XBox'/><category scheme='http://www.blogger.com/atom/ns#' term='Netflix'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='LiveMesh'/><title type='text'>Netflix on XBox 360 == Silverlight on XBox 360?</title><content type='html'>I'm really excited about today's &lt;a href="http://www.microsoft.com/Presspass/press/2008/jul08/07-14InstantStreamPR.mspx"&gt;announcement regarding &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Netflix&lt;/span&gt; streaming on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;XBox&lt;/span&gt; 360&lt;/a&gt;. I have an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;XBox&lt;/span&gt; 360 but I wasn't really impressed with the selection of movies and shows on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;XBox&lt;/span&gt; Marketplace - I'll definitely be signing up for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Netflix&lt;/span&gt; once the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;XBox&lt;/span&gt; update rolls out. I don't care much about the &lt;a href="http://www.techcrunch.com/2008/07/14/netflix-coming-to-xbox-360-with-live-content-sharing/"&gt;content sharing&lt;/a&gt; part of the announcement though - why watch a movie together with friends when you aren't really together?&lt;br /&gt;&lt;br /&gt;I'm not sure if you remember, but &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Netflix&lt;/span&gt; showed off a &lt;a href="http://www.visitmix.com/Blogs/Joshua/netflix-uses-silverlight-for-video-on-demand/"&gt;very slick&lt;/a&gt; &lt;a href="http://www.microsoft.com/silverlight/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Silverlight&lt;/span&gt;&lt;/a&gt; based streaming video player at Mix 07, that also included sharing. I wonder if this announcement means that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Silverlight&lt;/span&gt; is coming to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;XBox&lt;/span&gt; 360. If it is, that would be very cool indeed. Can you imagine the kinds of applications that would now be possible to run on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;XBox&lt;/span&gt;? The power of &lt;a href="http://www.xna.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;XNA&lt;/span&gt;&lt;/a&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Silverlight&lt;/span&gt; could make &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;XBox&lt;/span&gt; 360 a killer platform. It could also enable your &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;XBox&lt;/span&gt; 360 to become part of your &lt;a href="http://blogs.msdn.com/livemesh/archive/2008/05/09/behind-live-mesh-what-is-moe.aspx"&gt;Live Mesh&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-9184898098084571503?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/9184898098084571503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=9184898098084571503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/9184898098084571503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/9184898098084571503'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/netflix-on-xbox-360-silverlight-on-xbox.html' title='Netflix on XBox 360 == Silverlight on XBox 360?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-5497457757805385821</id><published>2008-07-11T16:50:00.001-07:00</published><updated>2008-07-11T17:19:29.397-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Media'/><title type='text'>Losing Objective Reporting Would Suck!</title><content type='html'>Earlier today, CNN and NY Times had perfectly contradicting headlines for what was supposed to be the same news report:&lt;br /&gt;&lt;br /&gt;Times: &lt;a href="http://www.nytimes.com/2008/07/12/technology/12comcast.html?_r=1&amp;amp;oref=slogin"&gt;F.C.C. Chief Backs Sanctions Against Comcast Over Blocking&lt;/a&gt;&lt;br /&gt;CNN: &lt;a href="http://money.cnn.com/news/newsfeeds/articles/djf500/200807111314DOWJONESDJONLINE000683_FORTUNE5.htm"&gt;FCC Chairman Recommends No Fine for Comcast&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's interesting how opinion and interpretation can affect perception.&lt;br /&gt;&lt;br /&gt;With increasing globalization and the Internet becoming the primary source of news, I often notice news stories take a life of their own as they spread through different media channels. It's harder today than it was a few years ago to find objective reports - reporters/bloggers increasingly tend to state facts that are inter-twined with opinion. In many ways, blogs &lt;em&gt;need&lt;/em&gt; to be this way in order to allow conversations to continue (blog post + comments = conversation) but it is unfortunate that traditional media outlets also increasingly feel the need to add opinion and personal biases to news reports.&lt;br /&gt;&lt;br /&gt;Traditional media is still very far behind the blogosphere when it comes to mixing opinion with facts, but I think it would be unfortunate if the current converging trend here holds for long. Without objective reporting, there would only ever be a bunch of opinions floating around, and people would lose their ability to form &lt;em&gt;personal&lt;/em&gt; opinions which today derive from &lt;em&gt;facts.&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-5497457757805385821?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/5497457757805385821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=5497457757805385821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5497457757805385821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/5497457757805385821'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/losing-objective-reporting-would-suck.html' title='Losing Objective Reporting Would Suck!'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-6366807495221512864</id><published>2008-07-08T07:48:00.000-07:00</published><updated>2008-07-08T13:22:20.788-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sport'/><title type='text'>Favorites vs Underdogs</title><content type='html'>The 2008 Wimbledon final from a couple of days ago was epic. Perhaps the greatest tennis player ever against a potential future legend. &lt;a href="http://sportsillustrated.cnn.com/2008/tennis/specials/wimbledon/2008/07/06/mens.final.ap/index.html?eref=T1"&gt;Sport&lt;/a&gt; &lt;a href="http://sports.espn.go.com/sports/tennis/wimbledon08/columns/story?columnist=garber_greg&amp;amp;id=3475598"&gt;sites&lt;/a&gt; were all over the actual game coverage, but I was fascinated by the psychology of those audience watching the game.&lt;br /&gt;&lt;br /&gt;As I watched the game with friends and family, I found myself to be the sole supporter of defending champ, RFed. Everyone else was rooting for Nadal.&lt;br /&gt;&lt;br /&gt;This seems to be a theme with me - I was rooting for the Pats in &lt;a href="http://en.wikipedia.org/wiki/Super_Bowl_XLII"&gt;Super Bowl XLII&lt;/a&gt;, for Tiger Woods at the &lt;a href="http://sports.espn.go.com/golf/usopen08/news/story?id=3446435"&gt;US Open&lt;/a&gt; last month, for Australia in the &lt;a href="http://content-usa.cricinfo.com/ci/content/story/292773.html"&gt;2007 Cricket World Cup&lt;/a&gt;, etc. I seem to want the favorites to triumph. Most friends of mine and most others out these seem to always favor underdogs.&lt;br /&gt;&lt;br /&gt;I wonder what makes an individual go one way or the other when it comes to supporting the favorite vs supporting the underdog.&lt;br /&gt;&lt;br /&gt;Leaving aside the betting aspects of it all, my naive guess is that who one supports has something to do with projecting one's own life experiences. If you've struggled and played the role of underdog more often than not, you empathize with another in the same situation. If you've been on the other side more often, where you've always needed to 'defend your turf' in some way, you probably ed up rooting for the champ.&lt;br /&gt;&lt;br /&gt;Someone somewhere has probably written up a study that goes into the exact psychology of it all, but I stand by my extremely un-scientific claims above while I procrastinate trying to find said study.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-6366807495221512864?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/6366807495221512864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=6366807495221512864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6366807495221512864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/6366807495221512864'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/favorites-vs-underdogs.html' title='Favorites vs Underdogs'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-8323727601547865961</id><published>2008-07-08T00:12:00.000-07:00</published><updated>2008-07-08T00:43:44.822-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virgin America'/><category scheme='http://www.blogger.com/atom/ns#' term='Random'/><title type='text'>Virgin America FTW!</title><content type='html'>Over the 4th of July weekend, I flew Virgin America and was blown away. It's amazing how they've used technology to out-perform their competition in almost every aspect.&lt;br /&gt;&lt;br /&gt;Well, their fares were unbelievably great - $170 for a round trip ticket from SEA to LAX two weeks before the 4th of July. Their &lt;a href="http://www.virginamerica.com/"&gt;website&lt;/a&gt; is simple and slick, and they have a great model where you're charged a base price and 'frills' come extra (for instance, an exit row seats adds $15 to your ticket cost - I would totally pay for the extra leg room on a long flight). Their check-in and gate counters are Apple-slick and their brand spanking new planes are fitted with pleasant neon lighting and comfortable leather seats. Their in flight entertainment system, called Red (hip with the 'Beta' tag), is superior to any other I've seen in the US. It seemed to have just the right amount of free and for-pay options. Free lineup - live TV, music, games, soda/juice. Paid lineup - movies, food and alcohol (that's right - you order food and drink using the snazzy touchscreen and pay using your credit card). It even has this cheezy-yet-fun chat app which lets you join a chatroom (haven't seen one of those in years!) or send IM to a specific seat. Oh yea - each seat gets its own power outlet, even in economy. Their use of technology on the ground and in-flight seems to have allowed them to reduce staff and yet enhance the flying experience.&lt;br /&gt;&lt;br /&gt;By tailoring their service and catering to today's generation, they're focusing on the right things. and the primarily west-coast service seems to be a great fit for their 'attitude'. Oh, and having really pretty air-hostesses helps too. Co-incidence, or perhaps &lt;a href="http://www.mediaincanada.com/articles/mic/20051101/virgin.html"&gt;a signature Virgin move&lt;/a&gt; ;)&lt;br /&gt;&lt;br /&gt;Anyway, I would never fly another airline if a Virgin America route was available and reasonably priced. My guess is that they're losing money like every other airline (but less than others, probably). However, if they're in it for the long haul, I think they're making all the right moves.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-8323727601547865961?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/8323727601547865961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=8323727601547865961' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8323727601547865961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/8323727601547865961'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/virgin-america-ftw.html' title='Virgin America FTW!'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-139176650350975023</id><published>2008-07-02T12:29:00.000-07:00</published><updated>2008-07-03T16:37:31.886-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Interviewing'/><category scheme='http://www.blogger.com/atom/ns#' term='Career'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Viraj's Guide to Interviews - Conducting an Interview</title><content type='html'>Over the last few years, I've done a bunch of interviewing - both as the interviewer and the interviewee. However, things had slowed down on the interviewing front for the last year while I was primarily focused on getting the &lt;a href="http://www.mesh.com/"&gt;Live Mesh Tech Preview&lt;/a&gt; out the door. I conducted an interview yesterday after a long while, and thought of posting about my own list of interviewing best practices. Interviewing ranks as one of the more critical functions for the success of a team/company, so I work hard at giving it my best.&lt;br /&gt;&lt;br /&gt;I am not, by any means, an expert here but I have been interviewed by some excellent interviewers (primarily at &lt;a href="http://www.microsoft.com/careers"&gt;Microsoft&lt;/a&gt;, but in quite a few other companies too) and I made it a point to keep mental notes of things they did well so I could apply them to interviews I conduct. While all my experiences have been in computer science related interviews, the list below likely applies to other fields too.&lt;br /&gt;&lt;br /&gt;1. Spend at least 10+ minutes before an interview to plan what set of specific skills you intend to assess. It's naive to think that you can cover more than 2 skills in any sort of detail for each hour of interview time. Use part of this prep time to read the candidate's resume and understand his/her previous experience.&lt;br /&gt;&lt;br /&gt;2. Make sure the candidate is comfortable, and the environment is conducive to conversation. Conduct the interview and manage interactions the way you would want them to be if roles were reversed. There are times when you want to simulate high pressure situations, but this should be rare and I recommend avoiding it if possible.&lt;br /&gt;&lt;br /&gt;3. Ask questions that will help you assess skills needed for the job, and keep conversations relevant. Puzzles and teasers are fun to ask and often even to answer, but that don't tell you much about the candidate's skills. Problem solving, on the other hand, is a great exercise to assess the candidate's analytical skills.&lt;br /&gt;&lt;br /&gt;4. Don't let the candidate drive the meeting. Often, candidates get into a safe zone (talking about resume items, for instance) and tend to not let you proceed with your agenda. Respectfully driving the conversation back on track, even if it means cutting off the candidate, is the right thing to do.&lt;br /&gt;&lt;br /&gt;5. Don't try to prove you're smarter than the candidate. Remember that the goal is to gauge the candidate's skills and not to prove that you deserve to be interviewing them or are smarter than them. Many times you actually might not be, and that's OK!&lt;br /&gt;&lt;br /&gt;6. Pay attention when the candidate is talking. Checking email or generally being distracted shows lack of respect.&lt;br /&gt;&lt;br /&gt;7. If the candidate is struggling with something for over 4/5 minutes, help steer the candidate to a solution. Assess how the candidate reacts to hints and whether they're able to regain their composure.&lt;br /&gt;&lt;br /&gt;8. Gauge the candidate for team fit and other non technical skills. Is he/she someone you would enjoy working and interacting with? How can he/she help you grow your own certain skills? How organized and methodical is his/her approach to problems?&lt;br /&gt;&lt;br /&gt;9. Leave the last 5/7 minutes of the interview to answer the candidate's questions, and be as honest as possible. False sales pitches are often easy to detect and say a lot about your character (and that of the company). Try to determine whether the questions asked are genuine, or mundane and uninteresting. Often, what they ask says a lot about them.&lt;br /&gt;&lt;br /&gt;10. End an interview with concrete information about what the next steps are for the candidate. If you don't know, make sure you refer the candidate to someone who does.&lt;br /&gt;&lt;br /&gt;Any other interviewing best practices you've experienced that aren't covered above?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-139176650350975023?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/139176650350975023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=139176650350975023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/139176650350975023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/139176650350975023'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/virajs-guide-to-interviews-conducting.html' title='Viraj&apos;s Guide to Interviews - Conducting an Interview'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-879124542171295769</id><published>2008-07-01T19:40:00.000-07:00</published><updated>2008-07-02T09:32:44.836-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone 3G'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='WWDC 08'/><category scheme='http://www.blogger.com/atom/ns#' term='LiveMesh'/><title type='text'>Some thoughts on Apple's Push Notification Service</title><content type='html'>Last month, at &lt;a href="http://www.apple.com/quicktime/qtv/wwdc08/"&gt;WWDC&lt;/a&gt; Steve Jobs announced iPhone 3G. Very cool. I think the iPhone is a game changer. Enough &lt;a href="http://www.techcrunch.com/2008/06/10/i-am-a-member-of-the-cult-of-iphone/"&gt;people&lt;/a&gt; &lt;a href="http://www.engadget.com/2007/01/09/the-apple-iphone/"&gt;have&lt;/a&gt; &lt;a href="http://topics.nytimes.com/top/reference/timestopics/subjects/i/iphone/index.html?inline=nyt-classifier"&gt;dissected&lt;/a&gt; &lt;a href="http://www.techcrunch.com/2008/07/01/att-iphone-3g-pricing-revealed/"&gt;the iPhone 3G&lt;/a&gt; that I'll skip re-stating what everyone knows already.&lt;br /&gt;&lt;br /&gt;One of the more interesting announcements Jobs made at the WWDC Keynote was the &lt;a href="http://www.engadget.com/2008/06/09/iphone-push-notification-service-for-devs-announced/"&gt;iPhone Push Notification Service&lt;/a&gt;. In short, it's a single channel from the cloud to each iPhone, and can be used by software publishers (in addition to Apple) to send signals to apps on the iPhone without having to worry about creating their own custom channel to the cloud or using polling schemes. This sounds like a win-win for both publishers of iPhone apps and for Apple.&lt;br /&gt;&lt;br /&gt;Given that &lt;a href="http://www.mesh.com/"&gt;I work in a similar space&lt;/a&gt;, this was interesting to me. We had been thinking along similar lines and have in some ways even taken the concept even beyond what Apple announced. I'll save the details/designs of what I'm working on for another post.&lt;br /&gt;&lt;br /&gt;The technology Apple touted sounds a lot like &lt;a href="http://msexchangeteam.com/archive/2006/04/03/424028.aspx"&gt;Exchange Direct Push/Always-Up-To-Date&lt;/a&gt;, except that it opens up the channel from cloud-&gt;phone to third parties instead of the exchange model where the only publisher is Exchange and the only consumer is the Outlook Mobile client.&lt;br /&gt;&lt;br /&gt;The design challenges of opening up a channel of this sort to third parties are:&lt;br /&gt;1) Delegated authentication to allow third parties to use their notification channel&lt;br /&gt;2) Routing notifications to the correct iPhone&lt;br /&gt;3) Introduction of a single point of failure for most apps on all &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;iPhones&lt;/span&gt; (kinda similar to AT&amp;amp;T going down - if Apple's service goes down all cloud-dependent apps are 'bricked' unless they have some form of background polling, which would defeat the purpose of the single notification channel since Apple touted battery life as their primary motivation. BTW, I don’t believe that is their primary motivation – more below).&lt;br /&gt;&lt;br /&gt;One interesting feature they did &lt;em&gt;not &lt;/em&gt;talk about, and I believe that they won’t add anytime soon, is a 2-way communication channel to allow for messages &lt;em&gt;from &lt;/em&gt;the phone &lt;em&gt;to&lt;/em&gt; the publisher. The notification channel is likely 2 way inherently, but communication from the phone is only ever seen by Apple.&lt;br /&gt;&lt;br /&gt;Here are my guesses on how they deal with the above three:&lt;br /&gt;&lt;br /&gt;There is only one way to get apps on the iPhone (assume non jail-broken &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;iPhones&lt;/span&gt;) – the Apple App Store. To publish to the store, publishers share revenue with Apple. I’m certain there is some kind of certification that happens at this stage to ensure that apps are well behaved. Once certified, the publisher probably gets a ‘security token’ to communicate with Apple’s Notification Service if they want to use it. Further, my guess is that each app published by each publisher might have a unique security token. I presume that the content of Notification that publishers push through the channel would be encrypted and opaque to Apple – it would be very bad if that’s not the case. However, at least 2 pieces of information must be known to Apple – who is publishing and whom is the Notification going to.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My guess is that Apple is told what phone to send a notification to by publishers, versus figuring out itself where to route the Notification. In other words, the subscription is held by the publisher and not by Apple. The reasons I think this is how it must be is:&lt;br /&gt;- Apple would not like to be responsible for tracking subscriptions of each app on each iPhone. It would mean they have a ton of subscriptions to manage, plus they need to perform &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;lookups&lt;/span&gt; in their cloud for routing notifications to the right phone. By letting publishers deal with this, they are no longer responsible for the costs incurred of maintaining these subscriptions. Apps that create several hundred subscriptions cost the publisher, and the cost of performing &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;lookups&lt;/span&gt; are also incurred by the publisher. This makes Apple's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;SLA&lt;/span&gt; much simpler.&lt;br /&gt;- Publishers (I hope) would not want Apple knowing data about their customers.&lt;br /&gt;&lt;br /&gt;#3 is interesting – the service needs to be robust again badly behaved publishers. Their first line of defense here is probably their certification program. Apps must not do wild-card broadcasting, must not poll, must have an upper limit on Notification payload sizes, etc. Note that the announcement yesterday was only to allow 3rd parties to support 3 types of Notifications – ‘badges’, ‘audio alerts’ and ‘text alerts’. By nature, the first two should be tiny in size, the third probably has an upper limit on size of text. Their second line of defense is probably real time metering and throttling. Apps must be self metered or will be throttled by Apple. Publishers are motivated to adhere by these guidelines because Apple controls publishing their app and could impose restrictions on downloads of the app in the App Store.&lt;br /&gt;&lt;br /&gt;Regarding Apple’s stated motivation for the Notification Service – I suspect they have more interests than just “preserving battery life”. By controlling the App Store and this Notification channel, Apple now has direct insight into a ton of data that can be mined – what apps are most popular, what apps are most chatty, what app is the ‘flavor of the month’ by usage and not just by download metrics, most active users, etc. They can use this data both ways – to make special licensing deals with specific app makers they detect are 'hot' and create popular apps (popular download is different from popular usage) and also to directly target ads/other apps to consumers.&lt;br /&gt;&lt;br /&gt;Other's have &lt;a href="http://nollind.whachell.com/2008/06/apples-push-notification-service.html"&gt;posted&lt;/a&gt; on how Apple might be building something similar for the Mac. They probably are, but  the motivation for publishers to use such a channel is greatly lesser in case of Macs. There is no single channel of publishing apps for the Mac, although they do make it easier. As a publisher, the primary attraction of using something like this would be to not have to build something yourself, but I think the need to share revenue with Apple, get certified and distributed via official Apple channels only and use Apple as the middle-man for what essentially shouldn't be any of their business might act as &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;deterrents&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-879124542171295769?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/879124542171295769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=879124542171295769' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/879124542171295769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/879124542171295769'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/some-thoughts-on-apples-push.html' title='Some thoughts on Apple&apos;s Push Notification Service'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2687820185167366196.post-2685853591957748524</id><published>2008-07-01T18:18:00.000-07:00</published><updated>2008-07-01T19:25:44.499-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random'/><title type='text'>Why am I blogging?</title><content type='html'>It's kinda funny how I feel the need to justify why I'm blogging, as if every blogger must blog to serve some purpose. I think such justification is warranted, but doesn't really need to be expressed. As long as you know why you're blogging, you're good.&lt;br /&gt;&lt;br /&gt;I am a voracious reader of blogs, but never really got into blogging myself. I've tried this a couple of times before, but those were more academic exercises than real attempts to start blogging.&lt;br /&gt;&lt;br /&gt;As I read blogs, observe people and their behaviors and basically live each day I form opinions, like most other human beings, that I keep to myself and sometimes (very rarely) express them to people I interact with personally. However, I think it's time to unleash my opinions to the Intertubes - everyone else is doing it, so why shouldn't I? ;)&lt;br /&gt;&lt;br /&gt;Seriously though, there are a couple of reasons why I feel the need to blog -&lt;br /&gt;&lt;br /&gt;As an engineer, I've found myself making observations and critiquing things that others benefit from. I've been told that my opinions are often 'interesting' (whatever that means), and while I may not always be right, I seem to have built a decent track record that gives me the confidence to risk embarrassing myself in public. I'm hoping that my blog posts about Technology will be even mildly interesting to others out there. There's the personal growth angle here too - in many ways, articulating thoughts into words takes some effort and makes you reason with your opinions. Blogging seems to be a great way to cultivate this skill.&lt;br /&gt;&lt;br /&gt;The other big reason to blog is to be a participant in this new world of open communication, instead of being just a spectator. Reading interesting blogs but not blogging myself made me feel like I'm cheating, in some ways. I know I'm late to the party, but better late than never! I hope to use this platform to comment on society, trends, human behaviors and anything else that I wish to express.&lt;br /&gt;&lt;br /&gt;Lastly - and I'm ambivalent about this one - I believe blogging will somehow help my professional career. It's almost as if nowadays, the fact that you have something to say is as important (if not more) than what you have to say. I don't want this to be an explicit goal of blogging (which is why I intend to blog about more than just Technology) but as the saying goes "If you built it, they will come". Notice how nondescript 'it' and 'they' are - &lt;a href="http://en.wikipedia.org/wiki/By_design"&gt;by design&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Oh, as far as the title of my blog goes - I was looking for something witty (I envy all the bloggers-with-cool-blog-names out there) but I ended up with something more aligned with the reason I'm blogging - "&lt;a href="http://en.wikipedia.org/wiki/Mulligan"&gt;Mulligan!&lt;/a&gt;", my chance to re-do.&lt;br /&gt;&lt;br /&gt;Argh - who am I kidding - the truth is, I just played a crappy round of golf today (shot 118, lost 4 balls and broke a club) and I couldn't come up with anything better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2687820185167366196-2685853591957748524?l=crazyviraj.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://crazyviraj.blogspot.com/feeds/2685853591957748524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2687820185167366196&amp;postID=2685853591957748524' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2685853591957748524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2687820185167366196/posts/default/2685853591957748524'/><link rel='alternate' type='text/html' href='http://crazyviraj.blogspot.com/2008/07/why-am-i-blogging.html' title='Why am I blogging?'/><author><name>Viraj Mody</name><uri>http://www.blogger.com/profile/10980120071443522974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
