<?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-3204586232155134420</id><updated>2012-01-29T06:06:57.174+08:00</updated><category term='Lighthearted'/><category term='codesmith'/><category term='Resharper'/><category term='WebService'/><category term='software release cycle'/><category term='google services'/><category term='software project management'/><category term='Code Maintenance'/><category term='Technorati'/><category term='firebug'/><category term='Misc'/><category term='Parody'/><category term='Test Automation'/><category term='ASP.NET'/><category term='software development'/><category term='JQuery'/><category term='Bug Reports'/><category term='netflix'/><category term='Reddit'/><category term='web 2.0'/><category term='Documentation'/><category term='Cuil'/><category term='OCR'/><category term='Advanced Installer'/><category term='StackOverflow'/><category term='PostSharp'/><category term='facebook'/><category term='LINQ'/><category term='Streamyx'/><category term='business'/><category term='MySQL'/><category term='tipjoy'/><category term='WolframAlpha'/><category term='Test Driven Development'/><category term='school'/><category term='Language Wars'/><category term='Zend'/><category term='Drupal'/><category term='Mockup'/><category term='Eclipse'/><category term='puzzles'/><category term='Intellisense'/><category term='unit testing'/><category term='testing'/><category term='Movies'/><category term='JavaScript'/><category term='Computer Problem'/><category term='TortoiseSVN'/><category term='Blog'/><category term='nhibernate'/><category term='Python'/><category term='AOP'/><category term='yahoo'/><category term='education'/><category term='Twitter'/><category term='wiki'/><category term='Reality'/><category term='Microsoft'/><category term='TestDriven.Net'/><category term='Exchange'/><category term='Google Translate'/><category term='FarPoint'/><category term='Source Control'/><category term='.Net'/><category term='Deployment'/><category term='SQL Server'/><category term='Firefox 3.0'/><category term='Clisecure'/><category term='Finance'/><category term='Code Review'/><category term='Windows Azure'/><category term='FogBugz'/><category term='Spam'/><category term='Agile Programming'/><category term='apache'/><category term='Entrepreneurs'/><category term='personal'/><category term='programming'/><category term='SharePoint'/><category term='CodePad'/><category term='Microsoft Word'/><category term='reasoning'/><category term='Google App Engine'/><category term='Open Source'/><category term='kindle'/><category term='matlab'/><category term='PHP'/><category term='Google Chrome'/><category term='TypeMock'/><category term='Digi'/><category term='Tools'/><category term='IE'/><category term='Code Sample'/><category term='Symfony'/><category term='software packaging'/><category term='SVN'/><category term='WPF'/><category term='gmail'/><category term='Books'/><title type='text'>It's common sense, stupid</title><subtitle type='html'>Common sense, programming,.Net,C#, software development, finance and anything interesting under the sun</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default?start-index=101&amp;max-results=100'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>258</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-5503693007189825235</id><published>2011-08-21T14:58:00.002+08:00</published><updated>2011-08-21T14:58:46.020+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kindle'/><title type='text'>kindlemalaysia.com</title><content type='html'>It's a long hiatus from me. I haven't been updating this blog for ages, and now I am back, just to do some shameless promotion for my new side adventure.&lt;br /&gt;&lt;br /&gt;To help my fellow Malaysians to get their hands on Kindle, I've decided to launch &lt;a href="http://kindlemalaysia.com/"&gt;kindlemalaysia.com&lt;/a&gt;. Basically this is a website that allows you to purchase kindle the&amp;nbsp;eBook&amp;nbsp;reader direct, because the &lt;a href="http://amazon.com/"&gt;Amazon.com &lt;/a&gt;just won't ship its precious&amp;nbsp;eBook&amp;nbsp;reader device to Malaysia. So, anyone who is residing in Malaysia who wishes to get their hands on the device can go to the website and order one. The purchase process is painless, just like how would normally you buy things online.&lt;br /&gt;&lt;br /&gt;If you have any questions you should read the &lt;a href="http://kindlemalaysia.com/user-resources/faq/"&gt;FAQ&lt;/a&gt;, and contact &lt;a href="mailto:admin@kindlemalaysia.com"&gt;admin@kindlemalaysia.com&lt;/a&gt; if your questions are not covered in FAQ.&lt;br /&gt;&lt;br /&gt;One would think that my main purpose to setup this&amp;nbsp;eCommerce&amp;nbsp;shop is to make money. Nothing could be further from the truth. I have a nice full time job, and don't really need any part time income, thank you very much ( Although I would be much delighted if my friends who like to engage me as their wedding MC). And from my survey I highly doubt whether Malaysians are that much into book reading that I can make a nice living selling Kindle.&lt;br /&gt;&lt;br /&gt;The reason I would do this, is to experiment with &lt;a href="http://www.google.com/AdWords"&gt;Google Adwords&lt;/a&gt; and online&amp;nbsp;eCommerce. In other words, I am doing this for fun, and experience. Or maybe gaining a few talking points on this blog; writing about software isn't that fun after all. I hope that by one year later I can educate, regale everyone about my experience and what I've learnt.&lt;br /&gt;&lt;br /&gt;We will see how it goes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5503693007189825235?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5503693007189825235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5503693007189825235' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5503693007189825235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5503693007189825235'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2011/08/kindlemalaysiacom.html' title='kindlemalaysia.com'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-854909010597459662</id><published>2010-08-07T22:53:00.002+08:00</published><updated>2010-08-08T16:42:56.664+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clisecure'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>CliSecure</title><content type='html'>&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;One of the benefits ( or drawbacks) of .NET application is that the code can be easily decompiled by tools such as Reflector. This feature is tremendously useful if you have a third party application whose methods are&amp;nbsp; behaving bizarrely and you want to know what’s under the hood so that you can work around it. It is also comes in handy when you are trying to understand the algorithms offered by .Net framework ( such as &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;LINQ&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;’s Sort()) so that you can decide whether to use the existing one or writing your own.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="Style-1" style="line-height: 115%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="Style-1" style="line-height: 115%;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="Style-1" style="line-height: 115%;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;However, for those who are in the line of selling software ( as opposed to, say &lt;/span&gt;&lt;a href="http://www.redhat.com/"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;open sourcing the software and then selling the service&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;), the danger of having the whole application decompiled and resold by the competitors is just too great to ignore. Which is why .NET developers will have to obfuscate and encrypt their code before they package it for sale. &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="Style-1" style="line-height: 115%;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="Style-1" style="line-height: 115%;"&gt;&lt;a href="http://www.secureteam.net/"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;CliSecure .NET Obfuscator&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt; is a .NET code protection and licensing solution that I have been using for past one year. To date, we are very satisfied with the product and the service. Here are a list of the features that we really love&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpFirst" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;1.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;.NET 4.0 support. &lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;We are in the process of migrating to .NET 4.0. The most important .NET 4.0 feature for us is &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd460688.aspx"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;PLINQ&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;. For computationally intensive application, parallelism is the way to go as Moore’s Law &lt;/span&gt;&lt;a href="http://www.zdnet.com/news/intel-scientists-find-wall-for-moores-law/133066"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;is going to hit the wall&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;. Instead of counting on the processor clock cycle to double up every 18 months, it is far more realistic to distribute computational loads to different cores to solve your speed issue. Which is why .NET 4.0 support is crucial for us in this matter. With CliSecure 5.2, we know that by the time we have transit to 4.0, we can release it straight to the customers without worrying about whether the protection tool is up to the task or not. &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpMiddle" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;2.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Support various .Net Applications. &lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;The&amp;nbsp; .NET ecosystem is vast; Windows Form, ASP.NET, Silverlight, WPF, WCF, Windows Phone 7 etc. Different types of application development caters to different groups of needs, but they share the same CLR and framework. It is not unlikely that your application has to run on desktops, browsers and windows smartphones at the same time. The good thing about CliSecure is that it can handle all the nuances of the types, so that you don’t have to use different protection tools for different types of applications. One caveat though, some of the nonstandard .NET applications ( such as assemblies compiled by &lt;/span&gt;&lt;a href="http://www.mathworks.com/products/netbuilder/"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Matlab .NET builder&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt; and &lt;/span&gt;&lt;a href="http://www.silverfrost.com/"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Silverfrost&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt; the fortran.Net compiler) may not be supported due to the nonstandard nature of those compiled assemblies. But in those cases, one can readily work around the limitation by editing the assemblies by hand. For me, this is not really a problem, as we seldom compile those nonstandard .NET code.&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpMiddle" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;3.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Method Call Obfuscation&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;. A lot of the protection tools keep the name of external calling method intact, because the names are needed in order to resolve the dependencies between different methods across different assemblies at runtime. This could create a security risk as hackers can determine what are the external calls your assemblies make and guess the content of your code. However, CliSecure solves this problem by replacing external calls with internal delegates so that the real, external calls are hidden from Reflector tools. With method call obfuscation, there is no problem in protecting the &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd264736.aspx"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;dynamic type objects&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;, introduced in C# 4.0. So all your dynamic language fanatics! You can now have the privilege to write &lt;/span&gt;&lt;a href="http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;duck typing code&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt; that is previously restricted to dynamic type languages. But don’t blame anyone else if you introduce silly bugs that could have been caught by C# compilers. Greater flexibility comes with greater risks, I’m warning you.&amp;nbsp; &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpMiddle" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;4.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;64 bit support.&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt; Our application is a heavy number crunching engineering application. It uses up memory a lot. So 64 bit machine is the only hope for large projects. We were using other protection tools before stumbling upon CliSecure. Amazingly at that time ( about a year ago) there was not a single .NET obfuscator tool that protected a pure 64 bit application. When contacted on how to solve this problem, those tool providers advised us to compile our application as 32 bit app and run as 32 bit app on 64 bit OS. But this is completely impractical, as the very reason why we need 64 bit OS is because we need bigger memory.&amp;nbsp; I communicated this need to CliSecure and they got it done in one month. This was the deal breaker for us to use CliSecure. &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpMiddle" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;5.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Stack Trace Translation.&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt; It’s often that when you are debugging a assembly which calls a protected assembly, you will get a gibberish stack trace when the crash happens. With the obfuscation, the real stack trace is also obfuscated and thus make debugging hard. However, with CliSecure 5.2, the stack trace is nicely preserved so that the developers won’t have to scratch his head and guess what’s going on wrong in the protected assembly. This would save us tremendous amount of time. &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpMiddle" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;6.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Encryption, not just obfuscation&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;. There is a difference between encryption and obfuscation. With obfuscation, Reflector can still see your method body and logic, with all the variables renamed, logic reshuffled ( not to the point of destroying the original code flow, of course). The weakness is that with enough determination, the hacker can still de-obfuscate the code and understand what is going on in your application. Encryption, on the other hand, completely hides the method body from hackers so there is no way of guessing what the code does beyond what is revealed from the method name.&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpMiddle" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;7.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Compatible with &lt;/span&gt;&lt;/b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms173183(VS.80).aspx"&gt;&lt;b&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;reflection&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;. One of the things I love about .NET is its rich meta data and the ability to use reflection to manipulate it. You can use reflection to dynamically infer an object’s type, create an instance of a type, access an object’s available methods, fields and properties. This is extremely useful when you are trying to&amp;nbsp; bind and display data in a declarative fashion. Unfortunately, obfuscation tools have the nasty habit of obfuscating private variables’ name, and make them inaccessible reflection, thus defeating the purpose of .NET rich metadata concept. CliSecure, on the other hand, doesn’t have problems with reflection. You can write the code in the way you want to without worrying about how the protection tool would work on it. &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="ListStyleCxSpLast" style="line-height: 115%; margin-left: .5in; mso-add-space: auto; mso-list: l0 level1 lfo1; tab-stops: list .25in .5in; text-indent: -.25in;"&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;8.&lt;span style="font: normal normal normal 7pt/normal 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;Technical Support&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;. The standard mantra of technical support in software world is “we’ll get back to you in 24 hours time”. But not everyone follows this. When we were researching for a .Net protection tool, there was one provider who got back to us only one week later, and his response was “sorry we can’t do this now, but we’ll keep you posted” and we never heard from him since. Providing good technical support is very important as we, the end users have our business to do; we can’t wait too long for our vendors to fix their problems or else our business would be affected. &lt;b&gt;Provide timely and helpful technical support is sometimes more important than features&lt;/b&gt;. And for this reason I would normally &lt;/span&gt;&lt;a href="http://itscommonsensestupid.blogspot.com/2008/08/for-developers-how-to-choose-software.html"&gt;&lt;span style="color: #000099; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt;eschew large software company with resellers&lt;/span&gt;&lt;/a&gt;&lt;span style="color: black; font-family: Arial, sans-serif; font-size: 11pt; line-height: 115%;"&gt; and prefer the ones that are small and nimble enough to answer my question quickly. CliSecure .NET Obfuscator has never failed to resolve my queries in a timely manner. When I encountered bugs in their software, they would usually give me an update that fixed the problem within a reasonable time frame. The technical support should always factor into the consideration when purchasing a component. &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="Style-1CxSpFirst" style="line-height: 115%;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="Style-1CxSpLast" style="line-height: 115%;"&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/3204586232155134420-854909010597459662?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/854909010597459662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=854909010597459662' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/854909010597459662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/854909010597459662'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2010/08/clisecure.html' title='CliSecure'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-2080145061038888785</id><published>2010-05-02T17:42:00.003+08:00</published><updated>2010-05-05T13:32:57.068+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Sample'/><category scheme='http://www.blogger.com/atom/ns#' term='Google App Engine'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>How to Use C# Client to Consume Google App Engine's rpc</title><content type='html'>&lt;div style="text-align: justify;"&gt;Google App Engine allows one to run the web apps on Google infrastructure. This is especially enticing to developers because it takes care of hardware, hosting, &amp;nbsp;scaling, authentication and deployment issues.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I'm glad to learn that one can create desktop clients in any language to take to the Google App Engine backend. The way this can be done is as thus. First, get &lt;a href="http://appengine-cookbook.appspot.com/recipe/xml-rpc-server-using-google-app-engine/"&gt;the excellent xml rpc python&lt;/a&gt; code from here, integrate it into your Google App Engine application.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The meat of your web service method is defined inside the &lt;b&gt;application&lt;/b&gt; class, assuming that we have the following method in the application class:&lt;/div&gt;&lt;pre class="brush: python"&gt;def getName(self,meta, keyInput):                                                    &lt;br /&gt;    return keyInput&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This is how you can call this service method from C# client, by making use of the &lt;a href="http://www.xml-rpc.net/"&gt;xml-rpc.net&lt;/a&gt; library: &lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;[XmlRpcUrl("http://localhost:8080/xmlrpc")]&lt;br /&gt;public interface AppTest: IXmlRpcProxy&lt;br /&gt;{&lt;br /&gt;    [XmlRpcMethod("app.getName")]&lt;br /&gt;    string GetName(string number);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public string GetName(string keyInput)&lt;br /&gt;{&lt;br /&gt;        var  appProxy = XmlRpcProxyGen.Create&amp;lt;apptest&amp;gt;();&lt;br /&gt;        appProxy.Url = "http://localhost:8080/xmlrpc/";&lt;br /&gt;        return appProxy.GetName(keyInput);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;So now your C# client can talk to Google App Engine backend with ease.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Isn't it simple? But it took me a few days to figure this out.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-2080145061038888785?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2080145061038888785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2080145061038888785' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2080145061038888785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2080145061038888785'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2010/05/how-to-use-c-client-to-consume-google.html' title='How to Use C# Client to Consume Google App Engine&apos;s rpc'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-1827635801430893300</id><published>2010-02-18T23:53:00.000+08:00</published><updated>2010-02-18T23:53:17.220+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>5A99</title><content type='html'>&lt;div style="text-align: justify;"&gt;I waited my friend at RHB bank opposite the Spring Shopping Mall, he was late, and the day was raining. This is not my exact idea of fun, I told myself. I was preparing to meet my ex-secondary schoolmates ( dubbed &lt;i&gt;5A99&lt;/i&gt;), meeting schoolmates can be fun, if the gathering can ignite the sense of kinship that bonded everyone in the first place. But it can be boring or even downright embarrassing if everyone is staring in (or past) everyone's&amp;nbsp;presence, not knowing what to say. A bad weather and a-friend-late-on-time seemed like a bad omen for the thing to come.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Finally, he came, so I followed his car to the destination. &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=kuching&amp;amp;sll=54.787715,-6.492314&amp;amp;sspn=3.370577,10.821533&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Kuching,+Sarawak,+Malaysia&amp;amp;z=11"&gt;Kuching&lt;/a&gt; was moving up a lot since the days when I moved away from it. That place was a new restaurant that didn't exist ten years ago. As we parked our car and walked into the restaurant, I took a look at my watch. 7.20pm, 10 minutes to the dinner. Standing in front of the door was a handsome young man. He was Tze Siang, after years, he still looked as boyish as before.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Suddenly, everyone seemed to appear at the same time, we enthusiastically exchanged handshakes, meeting old pals was good, but the atmosphere was a bit tense. We started to chit-chat, the conversation was a bit formal. And there were long pauses between conversation. Were we at lost of words to say to each other because of &lt;i&gt;long-time-no-see&lt;/i&gt;? I wondered.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;However, when we found a place to sit down, suddenly the atmosphere was heating up. First, a few crackers of chuckles, then, the voice volume rose, and crackers of chuckles gradually evolved into burst of laughters, from every corner of the room.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;We were exchanging our life-experience and jokes. We told one another of our experience from our walks of life, our friends listened attentively, sometimes added a few interesting remarks that set us all into laughters. The way we shouted across the table, it felt so much like the way when we shouted across the classroom. Our exaggerated facial expression when telling stories, those were the faces that we &lt;b&gt;&lt;i&gt;were&lt;/i&gt;&lt;/b&gt; when we were studying together. For a moment we&amp;nbsp;traveled&amp;nbsp;back in time, being our old gun-hoo self, resumed our innocent and carefree attitude. &amp;nbsp;There was never a moment in my life when I felt more &lt;i&gt;5A99&lt;/i&gt; then now.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The only difference was, the ladies were much more pretty and urbanized then ten years ago, and the men were more handsome, slickly dressed then before.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;To be sure, we are never the same again after started working. Our work and our commitment have taken a toll on us. We can no more make friends as heartfelt as we were ten years ago. There are times when we have to wear a mask when dealing with people. And sometimes I wonder whether earning money and recognition in exchange of&amp;nbsp;innocence&amp;nbsp;and&amp;nbsp;genuine friendship is a good bargain.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But tonight's gathering reminded me of how precious and enduring the friendship forged since young is. We may only see each other once a year, or maybe less. And the time may come when we busied ourselves with our families, but deep inside my heart, I would never forget that at one point of time I studied together with &lt;i&gt;5A99&lt;/i&gt;, and tonight shall go down as one of the most memorable days in my life. Of course, we didn't befriend with each other because we wanted to get projects or benefits, that's the point I cherish most.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Thanks, 5A99. Love you all, always.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-1827635801430893300?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1827635801430893300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1827635801430893300' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1827635801430893300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1827635801430893300'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2010/02/5a99.html' title='5A99'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5541202840960180528</id><published>2010-02-16T23:21:00.001+08:00</published><updated>2010-02-16T23:32:42.816+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><title type='text'>Face.com</title><content type='html'>&lt;div style="text-align: justify;"&gt;Ever since I joined &lt;a href="http://www.facebook.com/"&gt;facebook&lt;/a&gt; I was overwhelmed by a large number of photos and photo albums created by my friends ( you know who you are :)). With a gazillion number of photos, photo browsing, finding and tagging became an addictive activity, and a consuming one.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For a long time I wished that facebook would &amp;nbsp;just import the &lt;a href="http://picasaweb.google.com/"&gt;picasa&lt;/a&gt;'s ability to &lt;a href="http://www.readwriteweb.com/archives/picasa_web_albums_to_get_face.php"&gt;auto-recognize the faces and auto-tag them&amp;nbsp;appropriately&lt;/a&gt;. I reckon that facial recognition technology shouldn't be so difficult that only Google can do it, and should be important enough for any photo-sharing-intensive sites to have it. Or else how can the users manually identify every single one of their friends in the photos?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So, I was thrilled to learn that &lt;a href="http://face.com/"&gt;face.com&lt;/a&gt; has finally taken the challenge to autotag the faces in facebook photos. The marketing material says that face.com employs "the most advance face recognition technology on earth". Although I can't verify the claim, but from my experience it is a very useful application that actually &lt;i&gt;saves your time tremendously&lt;/i&gt;, unlike other pointless time-waster applications that suck away your time and serve absolutely no purpose at all ( I'm looking at you, &lt;a href="http://www.facebook.com/applications/SuperPoke!/2357179312"&gt;SuperPoke!&lt;/a&gt;&amp;nbsp;and &lt;a href="http://apps.facebook.com/marketplace/?cm_mmc_o=PBBLFzyLCjC_BBLFzyLCjC_BBLFzyLCjCtBFw"&gt;MarketPlace&lt;/a&gt;).&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So, if you have facebook account, why don't you just head over to &lt;a href="http://face.com/"&gt;face.com&lt;/a&gt;, and lets it tags you and your friends photos. I'm sure you will find it as useful as I do.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-5541202840960180528?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5541202840960180528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5541202840960180528' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5541202840960180528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5541202840960180528'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2010/02/facecom.html' title='Face.com'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-6388855461491587361</id><published>2010-01-22T15:03:00.001+08:00</published><updated>2010-01-22T15:19:43.063+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='education'/><title type='text'>Stupid Support Emails from Malaysia</title><content type='html'>&lt;div style="text-align: justify;"&gt;Ayende just posted the stupidest support email on &lt;a href="http://ayende.com/Blog/archive/2010/01/21/stupid-support-emails-4.aspx"&gt;his blog&lt;/a&gt;. I took a look at the email content, and had to agree with him. Really, the email lacked even basic netiquettes, was poorly written, and was asking for heavens and earths from someone he doesn't know personally.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What a shame.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What is more embarrassing to me is that the author of that email comes from Malaysia. Yes, &lt;i&gt;It is from Malaysia&lt;/i&gt;, my country.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It must be a gigantic failure for &lt;a href="http://itscommonsensestupid.blogspot.com/2009/05/open-letter-to-my-sister-and-other.html"&gt;Malaysia's education system&lt;/a&gt; to produce graduates &lt;i&gt;who don't even know how to ask questions&lt;/i&gt;. It's a bigger failure for the system to produce graduates who don't appreciate the amount of free time open source contributers have and ask for a detailed A-Z tutorial when the they can just google up the information themselves. Maybe I shouldn't be too surprised by the entire episode. I mean, what can you expect a spoonfeeding-education system to produce? An Einstein?&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Just to let you know that I was a victim of Malaysia's education system as well. I couldn't forget the time in secondary school when I had to memorize all the facts in order to pass my exams and to booked a seat in college. Even in the university I crushed through the subjects by sheer memorization. The effect of regurgitation and force memorization crippled our creativity, made us unable to think for ourselves because we were trained and told that there was only one answer in the world and unless you get that answer right you are dead and that answer is the correct one and there shall be no debate on it.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This kind of spoonfeeding system has a more&amp;nbsp;deleterious&amp;nbsp;effect on other students, I afraid. A lot of top grade students do not know anything besides their books. And it isn't clear that they really understand the knowledge taught. I mean, even for maths and physics and engineering and computer science subjects you can score an A without understanding the material, isn't it? All you have to do is to memorize everything, leave no stone unturned. So, when it comes to the time when they are expected to do their own research, or get things done without to- to-bottom command from their superior, they flounder. Or when they are asked to solve real world problem on their own, they are stumped. Even a simple act of asking help from&amp;nbsp;appropriate&amp;nbsp;person in an appropriate manner is too difficult for many of them, as demonstrated above.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What a pity.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Edit: Thanks to our broken education system, the Power Distance Index (PDI, the higher the index is, the more submissive a person is to authority) &lt;/i&gt;&lt;/b&gt;&lt;a href="http://www.clearlycultural.com/geert-hofstede-cultural-dimensions/power-distance-index/"&gt;&lt;b&gt;&lt;i&gt;for Malaysia is the highest&lt;/i&gt;&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;i&gt;.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-6388855461491587361?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6388855461491587361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6388855461491587361' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6388855461491587361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6388855461491587361'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2010/01/stupid-support-emails-from-malaysia.html' title='Stupid Support Emails from Malaysia'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-3695547529908054587</id><published>2010-01-14T17:09:00.000+08:00</published><updated>2010-01-14T17:09:49.752+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google services'/><category scheme='http://www.blogger.com/atom/ns#' term='StackOverflow'/><title type='text'>Me, At the SiteMap of StackOverflow</title><content type='html'>It's flattening to see my account at the sitemap of &lt;a href="http://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt;, &lt;a href="http://www.google.com.my/search?rlz=1C1GGLS_enMY291MY303&amp;amp;aq=f&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=stackoverflow"&gt;according to Google&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/S07fBD3OG8I/AAAAAAAAFZs/2IJ_-wUouRI/s1600-h/soflow..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="266" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/S07fBD3OG8I/AAAAAAAAFZs/2IJ_-wUouRI/s400/soflow..png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Thanks to &lt;a href="http://meta.stackoverflow.com/users/130507/chris"&gt;Chris&lt;/a&gt; who &lt;a href="http://meta.stackoverflow.com/questions/35497/tom-ritter-ngu-soon-hui-what-is-your-secret"&gt;brought this to our attention&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3695547529908054587?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3695547529908054587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3695547529908054587' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3695547529908054587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3695547529908054587'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2010/01/me-at-sitemap-of-stackoverflow.html' title='Me, At the SiteMap of StackOverflow'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/S07fBD3OG8I/AAAAAAAAFZs/2IJ_-wUouRI/s72-c/soflow..png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-2505262990064116148</id><published>2009-12-31T23:23:00.000+08:00</published><updated>2009-12-31T23:23:40.447+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Goodbye 2009, Hello 2010</title><content type='html'>&lt;div style="text-align: justify;"&gt;Time flies.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Maybe it's time for me to do some reflection. Let's see, what I have done this year?&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Probably not much. At least, nothing very interesting. Just another year.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Oh wait, maybe I &lt;i&gt;did&lt;/i&gt; do something. On SO, I achieve more than &lt;a href="http://stackoverflow.com/users/3834/ngu-soon-hui"&gt;10k of reputation&lt;/a&gt;, an achieving that is worthy of &lt;a href="http://meta.stackoverflow.com/questions/20849/thanks-to-both-stackoverflow-and-telerik-for-the-awesome-promotion"&gt;a free telerik license&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;On the blog side, I wrote 84 blog posts this year, that's a drop of 50 posts from last year.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And I planned to migrate my blog to a wordpress blog. But so far I haven't done anything on it.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;That's it. Wish everyone a happy new year!&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/3204586232155134420-2505262990064116148?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2505262990064116148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2505262990064116148' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2505262990064116148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2505262990064116148'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/12/goodbye-2009-hello-2010.html' title='Goodbye 2009, Hello 2010'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-4452372368409289382</id><published>2009-12-18T16:34:00.000+08:00</published><updated>2009-12-18T16:34:51.483+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Dude, Where's Your csproject and sln?</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Revision_control"&gt;Source control&lt;/a&gt; is&amp;nbsp;indispensable&amp;nbsp;for any team with more than two members. There is literally no way to transfer code from one developers to another with just disk swap and copy. And if you happen to work on a development project with multiple developers and your team doesn't even have a decent source control, it's not hard to guess that most of your time will be wasted on yelling at each other, arguing who's breaking the code, and demanding for latest files.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What a terrible waste of your developer's precious time, and what a waste of your stackholders' money. Sometimes it's quite a bit of irony for developers to write code so that other people's life and work can be automated and at the same time, the level of automation in development is just bare minimum. This is simply scandalous.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now, even if you already a source control, that doesn't mean that you are free from improvement, far from it. Some developers I know only check-in the source code, leaving the configuration file, csproject, solution file and all other perceived secondary files on their hard disk without proper backup. This is also not acceptable.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Think about this: when a new developer joins your team, he is expected to start working immediately. Don't expect him, &lt;i&gt;ever&lt;/i&gt; to pickup the code from source control and then create the csproject files himself just in order to do a compilation. First, the idea of constructing csproject from the source files is just plain boring. Second, it involves a fair amount of guess work; how do &lt;i&gt;you&lt;/i&gt; know which files to include and which files &lt;i&gt;not&lt;/i&gt; to include? Third, it can take a long time just to figure out what are the external references. Not to mention that every time you include a new cs file, you still have to inform him to do the same work lest the build is broken.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Let's do a simple cost benefits analysis of not adding the csproject files into the source control. The initial csproject file construction: 4 hours on average ( it can take a significantly longer time if you have a large project). Every time a new file added: 2 minutes, the frequency of this happening: 1 per week. &amp;nbsp;That's 8 minutes per month per developers. But what about the time needed for the developers to get in and out of the zone of coding thanks to this tiny distraction? Probably half an hour. Multiplying this number with the number of developers and with the length of the project duration, you can see that the whole development effort is taking a toll simply because someone decided that the csproject and solution files are not worthy of a place in source control.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So, please, for the sake of everyone, do check-in your csproject and solution, now. And make sure that your daily build can build everything automatically, without manual intervention. Starting from checking out all the files from the source, and then proceed to run a compilation, finally finishing with installer packaging, everything must happen seamlessly.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-4452372368409289382?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4452372368409289382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4452372368409289382' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4452372368409289382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4452372368409289382'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/12/dude-wheres-your-csproject-and-sln.html' title='Dude, Where&apos;s Your csproject and sln?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-4954810900289230236</id><published>2009-12-10T22:04:00.000+08:00</published><updated>2009-12-10T22:04:40.282+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='StackOverflow'/><title type='text'>SO 10K</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&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/_SDci0Pf3tzU/SyC2J8bmYMI/AAAAAAAAFVs/x0od39_-mzM/s1600-h/SO%2010k..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="170" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SyC2J8bmYMI/AAAAAAAAFVs/x0od39_-mzM/s640/SO%2010k..png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Now I am also an &lt;a href="http://stackoverflow.com/users/3834/ngu-soon-hui"&gt;SO 10k gold members&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4954810900289230236?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4954810900289230236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4954810900289230236' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4954810900289230236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4954810900289230236'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/12/so-10k.html' title='SO 10K'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SyC2J8bmYMI/AAAAAAAAFVs/x0od39_-mzM/s72-c/SO%2010k..png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-970272842223130535</id><published>2009-12-09T23:06:00.000+08:00</published><updated>2009-12-09T23:06:33.015+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google services'/><title type='text'>Google Docs Outage</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/Sx-5zTlpEZI/AAAAAAAAFUY/wYLCJX7lUY0/s1600-h/google%20docs%20outage.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="153" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/Sx-5zTlpEZI/AAAAAAAAFUY/wYLCJX7lUY0/s400/google%20docs%20outage.jpg" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt; is usually stable. But today, for four hours already, I am unable to access some of my documents.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Not all, but some. But that's enough to drive me crazy. And luckily today is not one of the days when I have to sell Google Docs to my relative ( Yes, I am Google's part time, unpaid evangelist).&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;A search in the Google Docs forum reveals that &lt;a href="http://www.google.com/support/forum/p/Google+Docs/thread?tid=5bd98477a7b1f0f7&amp;amp;hl=en"&gt;I am not alone&lt;/a&gt; &lt;a href="http://www.google.com/support/forum/p/Google+Docs/thread?tid=54649d66d81ba342&amp;amp;hl=en"&gt;in facing&lt;/a&gt; &lt;a href="http://www.google.com/support/forum/p/Google+Docs/thread?tid=6e74d7b408cfefa7&amp;amp;hl=en"&gt;the outage&lt;/a&gt;. This is unacceptable as people depends on Google Docs for their personal docs, working docs, and even &lt;a href="http://www.google.com/support/forum/p/Google+Docs/thread?tid=1467ac8c61361584&amp;amp;hl=en"&gt;their exam notes&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But, &amp;nbsp;there is still &lt;a href="http://www.google.com/support/forum/p/Google+Docs/thread?tid=1467ac8c61361584&amp;amp;hl=en"&gt;a workaround&lt;/a&gt;, hopefully those who need to access their documents would somehow get a backup version of the docs.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The moral of this outage? I afraid there is &lt;i&gt;no&lt;/i&gt; moral. You can't expect us-- I mean any mere mortal, not just yours-truly who live on the cloud-- to dutifully backup our documents to a safe space because the reason why we put our docs online in the first place is to avoid doing the backup. I think we just have to take it as it is, that such an outage is indeed regrettable, and there is nothing we can do to&amp;nbsp;forestall&amp;nbsp;it from happening, and there is nothing we can do to minimize such an unfortunate event.&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/3204586232155134420-970272842223130535?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/970272842223130535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=970272842223130535' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/970272842223130535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/970272842223130535'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/12/google-docs-outage.html' title='Google Docs Outage'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Sx-5zTlpEZI/AAAAAAAAFUY/wYLCJX7lUY0/s72-c/google%20docs%20outage.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-3795889503018425032</id><published>2009-12-08T10:07:00.000+08:00</published><updated>2009-12-08T10:07:26.944+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Test Practices at Google</title><content type='html'>&lt;div style="text-align: justify;"&gt;Here's an article on how &lt;a href="http://gojko.net/2009/12/07/improving-testing-practices-at-google/"&gt;Google conducts its automated test&lt;/a&gt;s. It gives us a glimpse of how Google manages its testing infrastructure and justifies the testing investment ( Yes, testing effort needs to be justified from time to time). We all know although writing tests are good, but tests that are poorly written will suck up development time, yield little or negative return of investment, and cost disillusion among developers. Here's how Google finds out whether a test is a "good" test (i.e., catches bugs and has a low maintenance cost) or a "bad" test. ( doesn't find bugs and is brittle):&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;The first step was to provide developers reactive feedback on tests. For example, the system suggested deleting tests that teams spent loads of time maintaining. They then collected metrics on whether the people actually acted on suggestions or not. The system also provided metrics to tech leads and managers to show how teams are doing with tests.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The second step, which is in progress at the moment, is to find patterns and indicators. As they now have identified lots of good and bad tests, the system is looking for common characteristics among them. Once these patterns are collected, algorithms will be designed to identify good and bad tests, and manually calibrated by experts.&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;It seems like they are applying pattern recognition in identifying the tests. Kudos to Google.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The software&amp;nbsp;community&amp;nbsp;would benefit as a whole if Google decides to open source &lt;i&gt;this&lt;/i&gt; portion of the code.&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/3204586232155134420-3795889503018425032?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3795889503018425032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3795889503018425032' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3795889503018425032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3795889503018425032'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/12/test-practices-at-google.html' title='Test Practices at Google'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5884748685122883116</id><published>2009-12-01T22:33:00.000+08:00</published><updated>2009-12-01T22:33:47.271+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blog'/><title type='text'>Call to Vote: Should I Get a New URL and a WordPress Blog Engine?</title><content type='html'>&lt;div style="text-align: justify;"&gt;One month ago I &lt;a href="http://itscommonsensestupid.blogspot.com/2009/10/should-i-get-new-domain-name-and-new.html"&gt;put a poll&lt;/a&gt; on thetop &amp;nbsp;right hand side of &lt;a href="http://itscommonsensestupid.blogspot.com/"&gt;my blog&lt;/a&gt;, asking everyone should I get a domain name and a new WordPress Engine. Here's the result I got so far:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;7 votes for "Get a new url and a new wordpress blog engine"&lt;/li&gt;&lt;li style="text-align: justify;"&gt;3 votes for "retaining the same blogger engine but get a new url"&lt;/li&gt;&lt;li style="text-align: justify;"&gt;4 votes for "retaining both the url and the blogger engine"&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;The rational for each choices are available &lt;a href="http://itscommonsensestupid.blogspot.com/2009/10/should-i-get-new-domain-name-and-new.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now, there are 26 days left before the poll closes. All I can say is, do vote, so that I know what to do with this blog.&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-5884748685122883116?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5884748685122883116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5884748685122883116' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5884748685122883116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5884748685122883116'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/12/call-to-vote-should-i-get-new-url-and.html' title='Call to Vote: Should I Get a New URL and a WordPress Blog Engine?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-2019206774660714326</id><published>2009-11-27T10:21:00.001+08:00</published><updated>2009-11-27T10:27:20.816+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzles'/><title type='text'>Can You Figure Out What It Is?</title><content type='html'>Here's &lt;a href="http://learn.typemock.com/its-coming/"&gt;a puzzle&lt;/a&gt; for you to crack, can you figure out what it means?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-2019206774660714326?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2019206774660714326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2019206774660714326' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2019206774660714326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2019206774660714326'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/11/can-you-figure-out-what-it-is.html' title='Can You Figure Out What It Is?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-6702817078718637688</id><published>2009-11-26T21:52:00.000+08:00</published><updated>2009-11-26T21:52:23.206+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Exchange'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Exchange 2010--New Software, Old Paradigm</title><content type='html'>&lt;div style="text-align: justify;"&gt;On Tuesday I went to &lt;a href="http://www.microsoft.com/windows/windows-7/"&gt;Windows 7&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/philpenn/archive/2008/08/19/windows-hpc-server-2008-rc2-now-available.aspx"&gt;Windows Server 2008 RC2&lt;/a&gt; and &lt;a href="http://www.itpro.co.uk/618136/microsoft-exchange-server-2010-review"&gt;Microsoft Exchange 2010&lt;/a&gt; launching at KL Convention Center. The party was great, the speakers were convincing and nice, and the food was... well, there was no food.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&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/_SDci0Pf3tzU/Sw6BP6gRxkI/AAAAAAAAFRI/feKn9z_I-qg/s1600/exchange.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: justify;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/Sw6BP6gRxkI/AAAAAAAAFRI/feKn9z_I-qg/s1600/exchange.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I was mildly impressed by Windows 7 and Server 2008, but Microsoft Exchange was a huge let down.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It wasn't that the software was poorly done. The Exchange server interface was OK, the web version of the outlook client was fully AJAX, and overall it seemed that it was quite good a tool for its purpose.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The only problem is, in my mind, the days for server-client &amp;nbsp;based Email programs are over. Back in the antediluvian days when web browser market was monopolized by the much-hated IE6 , Exchange, and &lt;a href="http://office.microsoft.xn--com%20%20home%20%20products-1w9pka/"&gt;outlook&lt;/a&gt; were the only acceptable email servers and clients existed on desktop. There was no reliable web application&amp;nbsp;substitute because&lt;a href="http://mashable.com/2009/07/16/ie6-must-die/"&gt; IE6 hindered web application so much that&amp;nbsp;&amp;nbsp;developers had no choice but to continue write for desktop application&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But no one, not even the mighty Microsoft could hold back the pace of innovation. Firefox&amp;nbsp;busted&amp;nbsp;into the scene, broke the tyranny of IE, and suddenly web development became fun again! Developers started to write applications for web, and more and more applications were shifting to the webs and consumers suddenly found that web apps are much more convenient than desktop apps and that really worried Microsoft, so it pushed out IE7 faster than scheduled. &lt;a href="http://mail.google.com/"&gt;Gmail&lt;/a&gt; is the web 2.0 app fanboy, showing us what can a web app does.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Which is what makes Exchange 2010 looked so pale in comparison. I would have to install Exchange on server, I &lt;i&gt;still&lt;/i&gt; have to do that in 2010 version. &amp;nbsp;This is completely unacceptable; what can't Microsoft make the a complete online system for email management, instead of a desktop application? &lt;a href="http://www.google.com/enterprise/"&gt;Google Enterprise&lt;/a&gt; is entirely web-based. And we can completely manage and configure our blogging platform, e-commerce platform, news platform entirely on the web ( think about CMS systems such as &lt;a href="http://www.drupal.org/"&gt;Drupal&lt;/a&gt;), it shouldn't be so difficult for Microsoft to make Exchange 2010 web-based, or is it?&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Looks like despite the rhetoric "web is the future", Microsoft thinking is still deeply,hopelessly rooted in desktop application. I can only wish them good luck, for the trend is moving towards web, not away from it.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-6702817078718637688?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6702817078718637688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6702817078718637688' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6702817078718637688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6702817078718637688'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/11/exchange-2010-new-software-old-paradigm.html' title='Exchange 2010--New Software, Old Paradigm'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Sw6BP6gRxkI/AAAAAAAAFRI/feKn9z_I-qg/s72-c/exchange.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-5090903919467414001</id><published>2009-11-25T23:46:00.000+08:00</published><updated>2009-11-25T23:46:53.213+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reddit'/><title type='text'>Is Reddit Going Nuts?</title><content type='html'>&lt;div style="text-align: justify;"&gt;Something must be deeply &lt;b&gt;&lt;i&gt;wrong&lt;/i&gt;&lt;/b&gt; with &lt;a href="http://reddit.com/"&gt;reddit.com&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It used to be a nice place to submit articles, to discuss about them and to upvote/downvote them, depending on whether you like or hate them.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But for certain reason, unknown to me, my submissions for the past few weeks were going down in the drain; they never appear in the &lt;a href="http://www.reddit.com/new/"&gt;newest link&lt;/a&gt;, which means that they didn't stand chance to be seen, upvoted/downvoted or discussed.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Sure, I can still see&amp;nbsp;&lt;a href="http://www.reddit.com/r/programming/comments/a7w1c/the_mistakes_i_made_in_my_programming_career/"&gt;my submission&lt;/a&gt;, but note that there is no upvote or downvote activity.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This is the worst way a user-driven website can break-- it means that not everyone can submit articles.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Reddit! You are no longer as fun as you were before! Now please go and fix your problem.&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/3204586232155134420-5090903919467414001?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5090903919467414001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5090903919467414001' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5090903919467414001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5090903919467414001'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/11/is-reddit-going-nuts.html' title='Is Reddit Going Nuts?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-4777690269762218653</id><published>2009-11-20T20:00:00.002+08:00</published><updated>2009-11-25T11:39:56.134+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The Mistakes I Made in My Programming Career</title><content type='html'>&lt;div style="text-align: justify;"&gt;You don't usually see people ( including me!) talk about their mistakes openly. But I think it is good to think about the mistakes we made in the past, so that we don't commit the same errors in the future.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I've been a professional programmer for about 5 years now. Like anyone else, I made mistakes along my way. Usually I didn't recognize the wrong thing I did right away; I only knew about the mistakes after being exposed to the correct ways of doing things. Hopefully after reading this post you would draw something useful from it and won't make the mistakes ( and pay the same price) as I did.&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size: x-large;"&gt;Not using a proper ORM&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Data Access Layer code is always messy, tedious and boring. I remembered when I was first doing a simple internal bookkeeping application, I was horrified at the amount of code I had to write just to get the basic plumbing done. So I started to plug away the &lt;a href="http://msdn.microsoft.com/en-us/library/h43ks021(VS.71).aspx"&gt;ADO.NET&lt;/a&gt; and manually coded up a home-brewed-with-a-very-specially-customized-to-specific-table-schema ORM to serve my purpose.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;A few months later there were some changes in the business requirements, and that cascaded into changes in table schemas, which led to a modification of my ORM, which was &lt;i&gt;so&lt;/i&gt; painful that I discarded it all together and opted for &lt;a href="http://www.wrox.com/WileyCDA/Section/Strongly-Typed-DataSets-in-ASP-NET-2-0-Pages.id-302833.html"&gt;strongly typed dataset adapter&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;For a while this thing actually worked. But still, I wished that I &lt;a href="http://itscommonsensestupid.blogspot.com/2009/04/nhibernate-multiple-databases-support.html"&gt;used a proper ORM&lt;/a&gt; ( such as &lt;a href="https://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt;) for the job. At least I don't have to worry about changing database vendor when my users grow in numbers.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: x-large;"&gt;Not learning generics soon enough.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I started my career as a programmer in .Net 1.1 days. The problem with .Net 1.1 is that it doesn't have &lt;a href="http://draft.blogger.com/msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx"&gt;generics&lt;/a&gt; support. As a result we couldn't have strongly typed list and could only be satisfied with the bland &lt;a href="http://draft.blogger.com/en.csharp-online.net/ArrayList"&gt;ArrayList&lt;/a&gt;. But using Arraylist, with casting and boxing all over your code is just painful to read and write. So we used &lt;a href="http://draft.blogger.com/www.codesmithtools.com/"&gt;CodeSmith&lt;/a&gt; to generate strongly typed collection list. But as the codebase grew those custom generated lists were becoming a monster on their own. Because I can modify the code easily, I often step in and change a method's behavior to suit my purpose, and that caused confusions and bugs later on.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I should have switched to .Net 2.0 and started to use generics as soon as it is available, instead of creating more and more custom collection lists that are simply unmaintainable.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: x-large;"&gt;Reinvent the wheel&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;New programmers always like to reinvent the wheel: "The current implementation wasn't good enough for me so I have to rewrite the whole thing from the scratch". I once thought about writing my own UI controls because Windows Forms UI controls were just too unsophisticated for my use.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As we all know there are a lot of excellent .Net UI control tools available; my GUI tools were not as good as those commercial ones, of course. I was just too naive then.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: x-large;"&gt;Too much documentation.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Code documentation is good, because it explains, in plain English, what your code is doing, right?&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Wrong.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="http://itscommonsensestupid.blogspot.com/2008/03/one-single-tip-to-comment-your-code.html"&gt;Documentation is often staled, outdated or downright wrong&lt;/a&gt;. I spent a lot of my time documenting my code ( &lt;a href="http://msdn.microsoft.com/en-us/library/b2s063f7(VS.71).aspx"&gt;XML documentation&lt;/a&gt;, remember?), only to find that I needed to update the documentation when I changed my code. Updating the code is a must, but updating the XML documentation isn't; it's a liability, it sucks time, and it serves no purpose. Eventually I ran out of patient changing the XML documentation and moved on to something else.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: x-large;"&gt;No automated build&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Application deployment and packaging are comparatively easier than programming, and so I put a very low priority on that. Soon, I was receiving complains from everyone the build wasn't working. "Prerequisites are missing, how to fix it?";"dlls are not updated, can you please send me a patch?";"Why the icons are running away?" and calls alike were reaching desk like avalanche.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;At the end of the day I was worn out, not because of programming, but because of mind-numbing re-deployment and repackaging process. I could really "save" sometime from writing the automation scripts, but the time I wasted on fixing every errors and on supporting other people was many times more than what I could "save". &lt;a href="http://ayende.com/Blog/archive/2009/11/18/reducing-friction-as-a-standard-operating-method.aspx"&gt;Your software should be built at one click, more than that is a waste.&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: x-large;"&gt;Rely on visual inspection and debugging too much&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It's so easy to come up a form and display your output. And Visual Studio is so powerful that one can easily step into the code and inspect the value on the fly. But &lt;a href="http://gilesbowkett.blogspot.com/2007/10/debugger-support-considered-harmful.html"&gt;debugger is harmful&lt;/a&gt; if you indulge into it too much. Imagine if your method will only get called after the application is up and running for 45 minutes, are you going to wait 45 minutes to reach that point and then only start debugging?&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;A better way is to break the application into sub-module that can be called independently. In this way you can just prepare the input that produces the faulty output and test it from there onwards.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: x-large;"&gt;No unit test&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I used to think that my application is trivial, that it can be easily covered by manual testing. Unit testing is for something big, and sophisticated and not for me. The outcome of this was the application grew into a monster, with no separation of concern, hard-to-refactor and completely unmaintainable code base. There was a point when I was afraid to make even the slightest modification to my code because any changes may or may no result in breaking changes. There were a few times when a mysterious problem suddenly surfaced out of nowhere, and the root cause was a breaking change I introduced a few months ago. Working with this kind of legacy code is not just boring and straining, but mentally stressing as well.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But with unit tests, life improves dramatically. I wish I could have learn &lt;a href="http://www.amazon.com/Art-Unit-Testing-Examples-NET/dp/1933988274"&gt;the art of unit testing&lt;/a&gt;, and&amp;nbsp;practicing&amp;nbsp;unit testing starting from day one. It's a shame that the school doesn't teach unit testing.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4777690269762218653?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4777690269762218653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4777690269762218653' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4777690269762218653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4777690269762218653'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/11/mistakes-i-made-in-my-programming.html' title='The Mistakes I Made in My Programming Career'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-2342994757477701181</id><published>2009-11-19T22:15:00.000+08:00</published><updated>2009-11-19T22:15:00.936+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google services'/><title type='text'>Google Wave, I Don't Get It</title><content type='html'>&lt;div style="text-align: justify;"&gt;I love&lt;a href="http://itscommonsensestupid.blogspot.com/2008/09/google-chrome.html"&gt; Google's&lt;/a&gt; &lt;a href="http://itscommonsensestupid.blogspot.com/2009/03/why-gmail-is-better-than-yahoo.html"&gt;products&lt;/a&gt;. But the &lt;a href="http://wave.google.com/"&gt;Google Wave&lt;/a&gt; is driving me nuts. Google Wave is the first Google product that I neither get it nor like.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I just can't understand Google Wave. I mean, what is it &lt;i&gt;really&lt;/i&gt; for? Upon logging into Google Wave I can see that I have, erm, a lot of entries ( sorry, I don't really know what else to call them), and all I can say is that it's a nice way to interact with a lot of people. But if I want social interaction I could have just Gchat with them, or setup a &lt;a href="http://groups.google.com/"&gt;Google groups&lt;/a&gt; to have fun together.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I can see that Google Wave has a lot of overlaps with other Google offerings. That doesn't sound very promising, I afraid.&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/3204586232155134420-2342994757477701181?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2342994757477701181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2342994757477701181' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2342994757477701181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2342994757477701181'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/11/google-wave-i-dont-get-it.html' title='Google Wave, I Don&apos;t Get It'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5957227186871266811</id><published>2009-11-10T21:25:00.001+08:00</published><updated>2009-11-11T09:15:19.844+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='matlab'/><title type='text'>Matlab: Invalid .NET Framework. Either the specified framework was not found or is not currently supported.</title><content type='html'>&lt;div style="text-align: justify;"&gt;If you are trying to compile &lt;a href="http://www.mathworks.com/"&gt;Matlab&lt;/a&gt; into .Net framework, you might encounter this message,&lt;b&gt; even though you have the .Net framework installed&lt;/b&gt;:&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;Invalid .NET Framework. Either the specified framework was not found or is not currently supported.&lt;br /&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;This error is very misleading, because most of the time, developers are smart enough to install .Net framework before trying to compile Matlab library into .Net component. The reason why-- despite that you already have .Net framework installed-- this message comes up is because of the way you specify your mcc build compilation parameter.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: bash"&gt;'mcc -d ' dnetdir ' -W ''dotnet:dotnet,dotnetclass,1.0,private'' -T link:lib ' mfile&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The above command &lt;b&gt;won't&lt;/b&gt; work if you don't have .Net framework &lt;b&gt;1.0&lt;i&gt;&lt;/i&gt;&lt;/b&gt; installed. This is because Matlab allows you to specify the .Net framework version (&lt;b&gt;1.0&lt;/b&gt;) after you specify your class name(&lt;b&gt;dotnetclass&lt;/b&gt;). And by setting the value to be 1.0 you are compiling against .Net framework 1.0 which simply doesn't exist on modern developer machine. &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/3204586232155134420-5957227186871266811?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5957227186871266811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5957227186871266811' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5957227186871266811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5957227186871266811'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/11/matlab-invalid-net-framework-either.html' title='Matlab: Invalid .NET Framework. Either the specified framework was not found or is not currently supported.'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-8005809908739973908</id><published>2009-10-20T22:40:00.000+08:00</published><updated>2009-10-20T22:40:21.499+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blog'/><title type='text'>Should I Get a New Domain Name and New Blog?</title><content type='html'>&lt;div style="text-align: justify;"&gt;I wrote my second post about &lt;a href="http://itscommonsensestupid.blogspot.com/2007/11/kick-start.html"&gt;two years ago&lt;/a&gt;, and in these two years the blog has achieve some readership ( about 250+ &lt;a href="http://www.google.com/reader"&gt;Google Reader&lt;/a&gt; subscribers, don't believe the number of subscribers reported by &lt;a href="http://feeds2.feedburner.com/ItsCommonSenseStupid"&gt;feedburner&lt;/a&gt;-- it's not accurate), hit &lt;a href="http://reddit.com/"&gt;reddit.com&lt;/a&gt;, &lt;a href="http://news.ycombinator.com/"&gt;hacker news&lt;/a&gt;, &lt;a href="http://dzone.com/"&gt;dzone&lt;/a&gt;, &lt;a href="http://dotnetkicks.com/"&gt;dotnetkicks&lt;/a&gt; and other news aggregator websites homepage a few times and help me collect my &lt;a href="http://itscommonsensestupid.blogspot.com/2009/09/my-first-google-adsense-cheque.html"&gt;first cheque&lt;/a&gt;&amp;nbsp;from Google. Not bad for a simple blog that doesn't even have a proper domain name.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But I think time has come for me to do some serious reflection on this blog. If this blog were to grow-- and if I were to continually invest in my blogging effort, mostly for the purpose of self entertainment and maybe a bit of publicity-- I would need to give the blog a proper URL, not a subdomain at &lt;a href="http://www.blogger.com/"&gt;blogspot.com&lt;/a&gt;. And also, I need a customizable backend and frontend, basically this means that I would have self-host a WordPress blog engine ( Sorry, .Net based blog engines such as &lt;a href="http://blogengine.net/"&gt;blogengine.net&lt;/a&gt; are totally out of .question because the plugins are not as many and the hosting cost is substantially more expensive).&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now, let me list down the pros and cons of getting a new domain name and a new blogging engine:&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Pro:&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;More professional&lt;/li&gt;&lt;li style="text-align: justify;"&gt;If I am not doing it now, it will be harder for me to do it next time.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;An SEO friendly URL has a greater chance of drawing in more traffic from search engines.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Easier customization&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;&lt;div style="text-align: justify;"&gt;Con&lt;/div&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;I would lose my readership. Not everyone would bother to rebookmark or resubscribe, I know&lt;/li&gt;&lt;li style="text-align: justify;"&gt;I would lose Google PageRank. I have to garden my blog from the start&lt;/li&gt;&lt;li style="text-align: justify;"&gt;I would need to setup a lot of things&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Need to shell out at least RM135 per year for the blog ( about 40 USD per year)&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Lose the remaining Google Adsense earning&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;What do you think? Leave a comment here or vote at &lt;a href="http://itscommonsensestupid.blogspot.com/"&gt;my blog&lt;/a&gt;!&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-8005809908739973908?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8005809908739973908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8005809908739973908' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8005809908739973908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8005809908739973908'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/10/should-i-get-new-domain-name-and-new.html' title='Should I Get a New Domain Name and New Blog?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-4368087715288252747</id><published>2009-10-19T23:56:00.002+08:00</published><updated>2009-10-19T23:57:59.346+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Common Misconception of The Cost of Software Development</title><content type='html'>&lt;div style="text-align: justify;"&gt;I didn't foreseen that my rant ( &lt;a href="http://itscommonsensestupid.blogspot.com/2009/10/why-software-is-expensive.html"&gt;Why Software is Expensive&lt;/a&gt;) would generate a huge response on the Internet ( over 100 comments and 89 points in &lt;a href="http://www.reddit.com/r/programming/comments/9qwlm/why_software_is_expensive/"&gt;reddit&lt;/a&gt;, &amp;nbsp;25 comments and 23 points in &lt;a href="http://news.ycombinator.com/item?id=861554"&gt;hacker news&lt;/a&gt;). Most comments agreed with the points I raised. While it is nice to find that the netizens out there agree with me, but it would be nicer if all the IT-illiterate guys wake up to the truth.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But wait! There are some dissonance that are worth addressing here:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;Software is too expensive because people want to laze off all day and getting a nice income, because REPRODUCTION costs are ZERO, yet the price is STILL high.&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Well, software is not something that you can write once and forever derive revenue from it without putting in extra effort. Anyone who believe this is grossly mistaken. Unlike a lot of products on the market that don't innovate for a decade but still able to pull in revenue just because they have something valuable to sell, software is built entirely upon innovation. Version 2 of a software application is usually a vast improvement ( and rewrite) over its predecessor. The corresponding line of code usually grows at geometrical rate but the price doesn't . &lt;a href="http://www.nytimes.com/2006/03/27/technology/27soft.html"&gt;Windows 95 has 15 million lines of code and Windows XP has 35 million&lt;/a&gt;, but the price is about the same. Without actively innovating the software applications as we know them will not be as user friendly and as powerful as they are now. All these R&amp;amp;D needs funding; to say that the developers are lazying off their days at beach while collecting cheques are simply distorting the truth.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;Not to mention, software is far more full of bugs than hardware is, and hardware development is EVEN HARDER. And yet the price of hardware is plummeting every month while the price of software is staying constant. &lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;That's because no one is ordering their own custom made hard disk and &lt;i&gt;everyone&lt;/i&gt; is trying to commission their own software. &amp;nbsp;Custom made things are always more expensive than standardize products before the latter can be mass produced but the former isn't. The reason why hard disk is so cheap is because&lt;i&gt; it comes only in a few flavors and that people all around the world are sharing the cost of developing these few flavors of hard disk&lt;/i&gt;. Software, on the other hand, doesn't enjoy this luxury and that's why the price cannot plummet. As to the accusation that software is more full of bugs than hardware, we the developers &lt;i&gt;can&lt;/i&gt; make the software bug free &lt;i&gt;provided&lt;/i&gt; that you treat software development like hardware development: rigid specs, adequate funding and time.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;Software consultants are exploiting the naive because software projects are delaying and the cost is ballooning all the time.&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;More often than not, the clients don't have a clear idea of what they want at the start of a project, so any estimation based on that are at best tentative, at worst&amp;nbsp;egregiously&amp;nbsp;inaccurate. All the estimation that software developers can provide at that stage, are only as good as the clarity of the client requirements. So later as the project understanding increases, software developers can of course provide better estimation which will often result in an increase of the amount of work needs to be done.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But really, who is to blame here? The clients who don't know what they want, or the software developers who have to provide an educated guess out of the most uncertain situation?&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style="text-align: justify;"&gt;I can't pay for your research time, and I can't pay for speculative work; I don't know what modules/design I like or need, so I need you to provide me with choices, but I can't pay for the thing I don't use.&lt;br /&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Creating design and writing code takes time &lt;i&gt;regardless&lt;/i&gt; of whether you are using them or not. So if you are not paying for them no one can do the job for you. I can understand why business owners are reluctant to pay for something that will be discarded away eventually, but without those throwaways there is no way to discover the portion that you need and want to keep.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;I don't need a website ( or the software application); it's expensive and I can see no real benefit out of it.&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;I don't know how to answer this one. This stumps me.&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/3204586232155134420-4368087715288252747?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4368087715288252747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4368087715288252747' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4368087715288252747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4368087715288252747'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/10/common-misconception-of-cost-of.html' title='Common Misconception of The Cost of Software Development'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-1610714749646580810</id><published>2009-10-11T12:06:00.000+08:00</published><updated>2009-10-11T12:06:48.513+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CodePad'/><title type='text'>Introducing CodePad-- An Online Programming Compiler</title><content type='html'>&lt;div style="text-align: justify;"&gt;I love to do my work on the cloud, and &lt;a href="http://itscommonsensestupid.blogspot.com/2009/09/apps-i-used.html"&gt;I am shifting as much work as I can, to the cloud&lt;/a&gt;. I've stopped using &lt;a href="http://office.microsoft.com/"&gt;Microsoft Office&lt;/a&gt;, in favor of &lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;. For my personal accounting use, I eschew big desktop package such as &lt;a href="http://www.intuit.com/"&gt;Intuit&lt;/a&gt;, in favor of lightweight an online alternative, &lt;a href="http://buxfer.com/"&gt;Buxfer&lt;/a&gt;. Instead of using FTPs to upload and manage the files onto my web host, I prefer to log into &lt;a href="http://www.cpanel.net/"&gt;cPanel&lt;/a&gt; and make the necessary changes. Storing and working with my data on the web applications give me the flexibility to access them from anywhere, at anytime. Having been bitten by hardware failure more than once, the idea that you would never ever lost your data because they are all stored and backup elsewhere is something I can't resist.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But it seems that compilers and debugging environment don't keep up with this trend. I don't expect to be able to compile my C# code online; there is no online version of &lt;a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx"&gt;Visual Studio&lt;/a&gt;, either. Similarly, to write and debug &lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt; requires one to setup a dedicated environment with all the &lt;a href="http://www.apache.org/"&gt;Apache&lt;/a&gt; and &lt;a href="http://www.mysql.com/"&gt;MySQL&lt;/a&gt; installed and configured. That's all well until your hardware blows up on you and you are struggling to find the backup and get back your environment.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It is in this light that I am thrilled to find &lt;a href="http://codepad.org/"&gt;CodePad&lt;/a&gt;. CodePad is an &lt;i&gt;online&lt;/i&gt;&amp;nbsp;interpreter or compiler.&amp;nbsp;&amp;nbsp;Note the &lt;i&gt;italic&lt;/i&gt; word, online. Which means you can type it your code, and presto! The code just runs!&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;CodePad,&amp;nbsp;admittedly, is not suitable for serious development work. But it's fun to play with, and it's a quick ground for us to check &lt;i&gt;and share&lt;/i&gt; our code, our ideas. The fact that we can get our code online and make it runs still get me excited. It might a sign that finally we are moving in the direction of "cloud programming".&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;To the &lt;a href="http://stackoverflow.com/"&gt;SOers&lt;/a&gt;, CodePad is an invaluable tool for you to answer and verify your response quickly, especially if you are hunting on easy questions where there are hundreds of people who also know the answer. &amp;nbsp;If you can type in the code from memory and verify it without firing up your debugger, you stand a better chance of getting the answers upvoted and accepted.&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/3204586232155134420-1610714749646580810?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1610714749646580810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1610714749646580810' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1610714749646580810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1610714749646580810'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/10/introducing-codepad-online-programming.html' title='Introducing CodePad-- An Online Programming Compiler'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-1973267637915161233</id><published>2009-10-04T23:32:00.001+08:00</published><updated>2009-10-05T22:14:07.835+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Why Software is Expensive</title><content type='html'>&lt;div style="text-align: justify;"&gt;I hate to write this post, but my recent conversation with my IT-illiterate friend prompted me to do this.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;My friend wanted to build a CMS website, "to earn a nice part time income". Given that he trusted me quite a lot, he asked me for an estimation of the cost. He mentioned that he wanted a CMS solution, with some mix-match of static-dynamic content. Also, he wanted some distinct flavors in the theme.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Given that he is quite a detailed guy ( read: loves to fuss over minor detail) and quite fickle mind, I told him that probably USD 200 is a minimum. We are living in Malaysia, so that &lt;a href="http://www.google.com.my/search?rlz=1C1GGLS_enMY327MY327&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=200+usd+in+rm"&gt;works out to RM 700&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;He was startled.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;"What? How come it costs so much? I thought the underlying CMS framework such as &lt;a href="http://drupal.org/"&gt;Drupal&lt;/a&gt; or &lt;a href="http://www.joomla.org/"&gt;Joomla&lt;/a&gt; is free and open source?! A &lt;a href="http://www.amazon.com/Microsoft-Windows-Home-Premium-Upgrade/dp/B002DHLUWK/ref=dp_cp_ob_sw_title_3"&gt;Windows Vista Home Edition is only costing RM 400&lt;/a&gt;!"&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;My friend is by no means the only one who grossly misprices the true cost and value of software. There was a client who asked us to implement a spreadsheet component because "Excel has it" at zero price. Yes, you hear it right. Zero . The reason? Because "Excel has it and so it must not be so difficult to implement".&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now, for the benefits of those who are clueless, and for the benefits of my poor developers who are stunned by those arguments, let me enumerate here why software is so expensive:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Software is expensive because there are huge overhead costs associated with software development&lt;/b&gt;. Computer equipments are expensive. And the fact that software developers need to stay on the cutting edge of the technology means that they need to always upgrade their hardware. Also, software methodologies and tools change very often, software developers need to invest a lot of time and money to just to keep up with the development so that they can provide better service to their clients next time.&lt;br /&gt;For those of you who think that hardware cost is "&lt;i&gt;just of small fraction of the total cost&lt;/i&gt;", let me tell you that hardware is &lt;i&gt;not&lt;/i&gt; cheap in third world countries; a mere &lt;a href="http://buylaptop.com.my/web/products.asp?Id=757"&gt;acer laptop&lt;/a&gt; is costing as much as a programmer's one month salary here in Malaysia.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Software is expensive because there are a lot of research going into it.&lt;/b&gt; Some express puzzle at software developer apparent "low productivity" (&lt;a href="http://www.codinghorror.com/blog/archives/000365.html"&gt;20 lines of code per day&lt;/a&gt;). Assuming that you are charging USD 50 per hour, your rate is USD 20/line. This is awfully expensive to the business owners who measure productivity in terms of quantity produced. What they miss out is that programming productivity is all about &lt;a href="http://stackoverflow.com/questions/324150/how-many-lines-of-code-do-you-write-modify-per-day/324165#324165"&gt;writing less code to get your job done&lt;/a&gt;. A programmer could spend one billable month reinventing the wheel and produce a 10 million line-of-code ORM &amp;nbsp;that is buggy, or spend &lt;a href="http://itscommonsensestupid.blogspot.com/2009/08/should-programming-work-be-billed-in.html"&gt;one non-billable month&lt;/a&gt; to look for an open source implementation that is mature and well-developed, and endure the complain of low productivity. The way business owners complain about "research time" is encouraging the wrong type of behavior.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Software is expensive because the product owners don't know what they want.&lt;/b&gt; &lt;a href="http://www.pcuf.fi/~pjt/pink/software-architecture.html"&gt;Imagine if you go to an &amp;nbsp;architect, asking him to provide a blue print, and after he comes out with that you ask him to change it according to your latest taste-- even though it is contrary to the original specification, and you repeat this process,..&amp;nbsp;&lt;/a&gt;&amp;nbsp;No one would dare to do this, but everyone seems to have no problem asking the software developers to change their code at last minute &lt;i&gt;and&lt;/i&gt; expect everything to work just fine &lt;i&gt;and&lt;/i&gt; the product ships in time&amp;nbsp;&lt;i&gt;and&lt;/i&gt;&amp;nbsp;worse of all, is not willing to pay extra.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Software is expensive because it is customized only for you&lt;/b&gt;. The reason why Microsoft Office and Windows Vista is so cheap, is because the development cost is spread over million of users. The consequence of this is that there is no competitive advantage associated with the ordinary office or Windows Vista users. Your customized application, on the other hand, is designed especially for &lt;i&gt;you&lt;/i&gt;, and you-- and no one else-- can enjoy the returns and benefits bring forth by the application. &amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-1973267637915161233?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1973267637915161233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1973267637915161233' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1973267637915161233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1973267637915161233'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/10/why-software-is-expensive.html' title='Why Software is Expensive'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-3253555243843609593</id><published>2009-09-24T22:14:00.000+08:00</published><updated>2009-09-24T22:14:30.629+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Mockup'/><title type='text'>Balsamiq Mockup FogBugz Plugin</title><content type='html'>&lt;div style="text-align: justify;"&gt;Following the &lt;a href="http://stackoverflow.com/questions/528769/best-web-app-for-creating-screen-mockups"&gt;suggestions from StackOverflow&lt;/a&gt;, I chose &lt;a href="http://www.evolus.vn/Pencil/"&gt;Pencil&lt;/a&gt; as my mockup tool, initially.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;There is nothing wrong with Pencil really. It's intuitive, it's fast and can generally get the job done.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The only problem is that it's a Firefox plugin. Well, it's not that the plugin concept troubles me. The problem with Pencil being a plugin, is that it's not a web app, which means you will have to install multiple copies of it on multiple machines, and file sharing is a big headache.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;So, when I learnt that &lt;a href="http://www.balsamiq.com/"&gt;Balsamiq&lt;/a&gt; has a &lt;a href="http://www.balsamiq.com/products/mockups/fogbugz"&gt;mockup plugin for FogBugz&lt;/a&gt;, I was thrilled-- for the longest period of time I was dreaming of doing all of my work on the web. &lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;,&lt;a href="http://www.google.com/calendar"&gt; Google Calendar&lt;/a&gt; &amp;nbsp;and &lt;a href="http://www.fogcreek.com/FogBUGZ/"&gt;FogBugz&lt;/a&gt; are &amp;nbsp;now&amp;nbsp;indispensable&amp;nbsp;part of &lt;a href="http://itscommonsensestupid.blogspot.com/2009/09/apps-i-used.html"&gt;my daily apps&lt;/a&gt; due to the fact that they are &lt;i&gt;web apps&lt;/i&gt; and thus I can access my data from anyway, anytime. Balsamiq Mockups for FogBugz can bring my mockup files online, and bring me a step closer to my dream.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Balsamiq does not&amp;nbsp;disappoint, apart from the slightly long initial loading time, it's in everyway exceeding my expectation. The UI is slick, beautiful, and such a pleasant for eyes. And it's dead easy to create a professional looking screen in no time:&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/Srt0q5evU4I/AAAAAAAAFLU/UiOxodS7dG0/s1600-h/balsamiq.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/Srt0q5evU4I/AAAAAAAAFLU/UiOxodS7dG0/s400/balsamiq.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Well, not very enlightening, I know. But that's because I am never a good artist. But I did this in 2 minutes. I am sure in the hands of skilled or half-skilled artists, Balsamiq will make their jobs easy, pleasant and professional.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In addition to slick UI, Balsamiq plugin integrated seamlessly with FogBugz, once you click "Save ", the drawing will automatically been saved as an attachment in FogBugz case, and on top of that, a screenshot:&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Srt2_NEMloI/AAAAAAAAFLk/FrUzSaXlMAw/s1600-h/balsamiqfogbugz.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Srt2_NEMloI/AAAAAAAAFLk/FrUzSaXlMAw/s400/balsamiqfogbugz.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And if you want to edit the drawing, you can just click the "Add/Edit UI Mockup" link. Since the drawing is stored on server, you don't have to scramble to find the drawing on your hard disk, that's a life saver.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The only qualm I have with Balsamiq mockup plugin, is that it's &lt;i&gt;not&lt;/i&gt; free for startup and students two person Version. They have &lt;a href="http://www.balsamiq.com/products/mockups/fogbugz#nofree"&gt;an explanation&lt;/a&gt; why this is so. But still, I think it would be better if they could give that away, just like how &lt;a href="http://www.fogcreek.com/FogBugz/StudentAndStartup.html"&gt;FogBugz on Demand is free&lt;/a&gt; for an account with two persons or less. The reasons are these:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;It is aligned with &lt;a href="http://www.balsamiq.com/blog/2009/08/13/donating/"&gt;their generous act of giving away software for a common good&lt;/a&gt;. You are helping startup and students to grow and do their job!&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Those who use FogBugz Startup Edition won't pay for a mockup tool anyway. Why should they pay for a mockup plugin, when they can get the underlying bug tracker for free, and free alternatives?&lt;/li&gt;&lt;li style="text-align: justify;"&gt;And by making the plugin free, you can expect the startups and students to continue use your products after they are the CEOs of fortune 500 companies and /or established tech workers. Giving things away free at the beginning in order to trap their loyalty is a sensible marketing strategy, no?&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3253555243843609593?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3253555243843609593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3253555243843609593' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3253555243843609593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3253555243843609593'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/09/balsamiq-mockup-fogbugz-plugin.html' title='Balsamiq Mockup FogBugz Plugin'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Srt0q5evU4I/AAAAAAAAFLU/UiOxodS7dG0/s72-c/balsamiq.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-8718674295164904433</id><published>2009-09-19T14:41:00.001+08:00</published><updated>2009-10-31T00:21:54.162+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>The Apps I Used</title><content type='html'>&lt;div style="text-align: justify;"&gt;Inspired by &lt;a href="http://www.hanselman.com/blog/ScottHanselmans2009UltimateDeveloperAndPowerUsersToolListForWindows.aspx"&gt;Scott Hanselman's 2009 Ultimate Developer and Power Users Tool List for Windows&lt;/a&gt;, I think would also like to share a list of applications ( desktop or web) that I use frequently.&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;OS and Browsers&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.microsoft.com/windows/windows-xp/default.aspx"&gt;Windows XP&lt;/a&gt;-- It's still my OS of choice after 7 years. Windows XP is stable, and faster than Windows Vista. It's a good thing that Microsoft rebranded a major Vista upgrade as &lt;a href="http://www.microsoft.com/windows/windows-7"&gt;Windows 7&lt;/a&gt;. Rebranding is a good way to get out of a colossal failure, really.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.vmware.com/"&gt;VMWare Workstation&lt;/a&gt;-- I do WAMP development sometimes, and I don't want the &lt;a href="http://www.apache.org/"&gt;Apache&lt;/a&gt; to&amp;nbsp;interfere&amp;nbsp;with &lt;a href="http://www.iis.net/"&gt;IIS&lt;/a&gt;, and I don't want to clutter my &lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt; development with my &lt;a href="http://www.microsoft.com/NET"&gt;.Net&lt;/a&gt; one. A virtualization technology is therefore a must. VMWare workstation is much more intuitive than &lt;a href="http://www.virtualbox.org/"&gt;Sun VirtualBox&lt;/a&gt;.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt;. Google Chrome&lt;a href="http://itscommonsensestupid.blogspot.com/2008/09/google-chrome.html"&gt; took away my heart the moment&lt;/a&gt; it was introduced. It's simple, and it's blazing fast! At the time when Firefox is becoming more and more bloat, Google Chrome makes browsing fun again.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.mozilla.com/firefox"&gt;Firefox&lt;/a&gt;. I &lt;i&gt;still&lt;/i&gt; have some use for Firefox-- although not for browsing. I use Firefox in conjunction with Firebug, for development purpose.&lt;/li&gt;&lt;/ol&gt;&lt;li style="text-align: justify;"&gt;Software Development&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.microsoft.com/VisualStudio/default.mspx"&gt;VS 2008&lt;/a&gt;-- If you are doing .Net development, there can be only one IDE of your choice, and that's VS 2008. Forget about &lt;a href="http://www.icsharpcode.net/OpenSource/SD/"&gt;SharpDevelop&lt;/a&gt;-- it's no match even for &lt;a href="http://www.microsoft.com/express/"&gt;VS 2008 Express&lt;/a&gt; ( which is also free). But if you are serious into development, you should always get at least a &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=83c3a1ec-ed72-4a79-8961-25635db0192b&amp;amp;displaylang=en"&gt;professional edition&lt;/a&gt;. Microsoft doesn't allow plugins for Express edition, and without plugins, the VS appeal drops instantly at least by half.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt;. Reflector is a class browser tool for .Net. Ever wonder how .Net code looks like? Get a Reflector, pull in the dll, and you can decompile the code. Sometimes the third party component you use is buggy and you can't figure out why. Looking into the source is the only way out. It gives you ammunition to curse the stupid developers who can't even get the simple things right.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;. NUnit is my choice of unit testing. It's less bloat than&lt;a href="http://www.mbunit.com/"&gt; MBUnit&lt;/a&gt;, and it has more feature that&lt;a href="http://en.wikipedia.org/wiki/MSTest"&gt; MSTest&lt;/a&gt;.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://typemock.com/"&gt;Typemock&lt;/a&gt;. Have a difficulty in isolating the dependencies? Typemock is the choice of mocking framework. You don't need to rewrite your code to make it testable. Typemock makes unit testing easy, &lt;a href="http://weblogs.asp.net/rosherove/archive/2008/10/01/unit-testing-decoupled-from-tdd-as-well-adoption.aspx"&gt;especially for&amp;nbsp;beginners&lt;/a&gt;&amp;nbsp;&lt;a href="http://weblogs.asp.net/rosherove/archive/2008/09/26/unit-testing-decoupled-from-design-adoption.aspx"&gt;who neither know anything nor bother about TDD&lt;/a&gt;.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;t&lt;a href="http://testdriven.net/"&gt;estdriven.net&lt;/a&gt;. Testdriven.net makes unit testing frictionless. From your IDE, you can execute the tests directly. One of the reasons why unit test has a hard time gaining acceptance from the developers, is because Microsoft-- through its Visual Studio offering-- doesn't make unit testing a first class citizen. With testdriven.net barrier entry to unit testing is lowered.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.fpoint.com/"&gt;FarPoint&lt;/a&gt;. That's a .Net component for spreadsheet. It's a must if you have to do heavy number crunching and presentation job.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt;. .Net's Intellisense is seriously retarded-- and Resharper is the cure! Not only that ReSharper analyzes your code, it also suggests improvements and best practices. You can seriously learn a thing or two about .Net out of the ReSharper suggestion.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.zend.com/"&gt;Zend Studio&lt;/a&gt;. Zend Studio Eclipse is, by far, the best IDE for PHP.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.secureteam.net/"&gt;CliSecure&lt;/a&gt;. .Net code is easy to decompile. CliSecure aims to stop (or at least make) the decompilation hard by obfuscation, encryption and anti-reverse-engineering technologies. Hard to comprehend? Then just take away this: CliSecure stops Reflector, and protects you from the self-righteous developers who like to&amp;nbsp;criticize.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://getfirebug.com/"&gt;FireBug&lt;/a&gt;. We all love Firebug, don't we? Without it CSS and Javascript development and debugger are just plain impossible.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.balsamiq.com/"&gt;Balsamiq&lt;/a&gt;. &lt;b&gt;The&lt;/b&gt; mockup tool, &lt;a href="http://itscommonsensestupid.blogspot.com/2009/09/balsamiq-mockup-fogbugz-plugin.html"&gt;second to none&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;li style="text-align: justify;"&gt;Software Management&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://tortoisesvn.tigris.org/"&gt;Tortoise&amp;nbsp;SVN&lt;/a&gt;. The default client application for SVN source control on Windows platform. It's free, and open source.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.relisoft.com/co_op/"&gt;Code Coop&lt;/a&gt;. A source control system. The interesting part about it is that it is distributed; there is no central server.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.automatedqa.com/products/abs/"&gt;Automated Build Studio&lt;/a&gt;. Tired of XML based build tools? Try Automated Build Studio. It's a GUI build tool. For common operations, all you need to do is to drag and drop those operations to the task panel and you can automated &amp;nbsp;your workflow.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.advancedinstaller.com/"&gt;Advanced Installer&lt;/a&gt;. An easy to use Windows Installer authoring tool. That's the tool I use to package my Windows applications.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.fogcreek.com/FogBUGZ/"&gt;FogBugz&lt;/a&gt;. The famous bug tracking tool, thanks to&lt;a href="http://www.joelonsoftware.com/"&gt; JoelOnSoftware&lt;/a&gt;. I use a self-host version of FogBugz in my day job, and the &lt;a href="http://www.fogcreek.com/FogBUGZ/IntrotoOnDemand.html"&gt;SaaS version&lt;/a&gt; for my own personal tasks.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;li style="text-align: justify;"&gt;Communication&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://mail.google.com/"&gt;Gmail&lt;/a&gt;. &lt;a href="http://itscommonsensestupid.blogspot.com/2009/03/why-gmail-is-better-than-yahoo.html"&gt;The best email system&lt;/a&gt;. Enough said.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://mail.google.com/videochat"&gt;Gmail voice and video chat&lt;/a&gt;. A serious contender to &lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt;, this is my favorite voice and video chat tool.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.google.com/calendar"&gt;Google Calendar&lt;/a&gt;. One thing I prefer Google Calendar over &lt;a href="http://www.microsoft.com/outlook/"&gt;MS Outlook&lt;/a&gt; is that it's web app; meaning nothing to install, accessible from anywhere, easy collaboration and sharing. The fact that it's tightly integrated with Gmail makes it even more appealing.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.teamviewer.com/"&gt;TeamViewer&lt;/a&gt;. This is the tool I use when I have to support my relative remote on computers issue.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt;-- Skype 4.0 has a screen sharing feature; this is the feature I like most, and this is the only reason I have not uninstall it.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.faststone.org/"&gt;FastStone&lt;/a&gt;. Screen capture tool. It was free once, but now no more.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;li style="text-align: justify;"&gt;Blogs&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.blogger.com/"&gt;Blogger&lt;/a&gt;. My blogging platform. This is where my blog posts are hosted.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AdSense"&gt;Google Adsense&lt;/a&gt;. All of the advertisements you see on this blog, are served by Google Adsense. Oh, I have just recently got my &lt;a href="http://itscommonsensestupid.blogspot.com/2009/09/my-first-google-adsense-cheque.html"&gt;first cheque&lt;/a&gt; from Google. &amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.google.com/analytics/"&gt;Google Analytics&lt;/a&gt;. A web analytics application that gives me insight into my website traffic.&lt;/li&gt;&lt;/ol&gt;&lt;li style="text-align: justify;"&gt;Information Source&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.google.com/"&gt;Google Search&lt;/a&gt;. That's the first place I hit upon when I need to find something out. And I bet it's also the choice of many as well.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt;. A clone of&amp;nbsp;&lt;a href="http://www.experts-exchange.com/"&gt;Expert Exchange&lt;/a&gt;-- minus all the annoyance. And for system admins and computer&amp;nbsp;enthusiasts, your &lt;a href="http://serverfault.com/"&gt;ServerFault&lt;/a&gt; and &lt;a href="http://superuser.com/"&gt;SuperUser&lt;/a&gt; is available as well.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://google.com/reader"&gt;Google Reader&lt;/a&gt;. The aggregator for me to keep up with latest news and blog updates from my friends, families and fellow developers.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://reddit.com/"&gt;Reddit.com&lt;/a&gt;. I like Reddit, because the comments there are usually more insightful than the links posted, and less civilized, too.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://news.ycombinator.com/"&gt;Hacker News&lt;/a&gt;. A great place to learn about tech news, startup and&amp;nbsp;entrepreneurship.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;li style="text-align: justify;"&gt;Life Organizers&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;. &lt;a href="http://itscommonsensestupid.blogspot.com/2007/11/who-needs-microsoft-word.html"&gt;Who needs Microsoft Word&lt;/a&gt;? I compose and store my documents online, on Google Docs. Although by comparison the editing capabilities are still quite primitive, but the fact that I can easily access and edit my documents, spreadsheets, slides and pdfs everywhere is enough to make up for this ( and hundreds more, if there is any) deficiency(ies). &amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.buxfer.com/"&gt;Buxfer&lt;/a&gt;.&lt;a href="http://voices.washingtonpost.com/fasterforward/2009/09/intuit_buying_mint.html?hpid=sec-tech"&gt; Mint may get the money and eyeballs recently&lt;/a&gt;, but it is this online personal financial management system, backup by &lt;a href="http://ycombinator.com/"&gt;Y Combinator&lt;/a&gt; that wins my heart. &amp;nbsp;The reason? It has &lt;a href="http://openid.net/"&gt;OpenID&lt;/a&gt; support and Mint doesn't have ( or &lt;a href="http://siteanalytics.compete.com/mint.com+buxfer.com/?metric=uv"&gt;doesn't need to have&lt;/a&gt;).&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;li style="text-align: justify;"&gt;Fun&lt;/li&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.videolan.org/vlc"&gt;VLC Media Player&lt;/a&gt;. The all-in-one, lightweight alternative to &lt;a href="http://www.microsoft.com/windows/windowsmedia/players.aspx"&gt;Windows Media Player&lt;/a&gt; and &lt;a href="http://www.real.com/realplayer"&gt;Real Player&lt;/a&gt;.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://maps.google.com/"&gt;Google Maps&lt;/a&gt;. I couldn't remember when was the last time when I looked at a &lt;i&gt;real&lt;/i&gt;, physical map. The best way for me to get from one place to another, unfamiliar place is to read the Google Maps, memorize it, and then drive there.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://picasa.google.com/"&gt;Picasa&lt;/a&gt;. Picasa comes in two edition, &lt;a href="http://picasa.google.com/"&gt;desktop one&lt;/a&gt;, and the &lt;a href="http://picasaweb.google.com/"&gt;online one&lt;/a&gt;. I use it to organize my photos and videos. And sorry, they are &lt;i&gt;not&lt;/i&gt; available for public viewing.&amp;nbsp;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt;. &lt;a href="http://mashable.com/2009/07/14/facebook-ultimate-time-waster/"&gt;The No. 1 time waster in the world&lt;/a&gt;. Thanks to Facebook, now I can reconnect back with my long-lost friends.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Wow, that's a &lt;i&gt;very&lt;/i&gt; long list. What's your favorite tool? Share with me! &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/3204586232155134420-8718674295164904433?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8718674295164904433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8718674295164904433' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8718674295164904433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8718674295164904433'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/09/apps-i-used.html' title='The Apps I Used'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-543972422302615951</id><published>2009-09-19T10:07:00.000+08:00</published><updated>2009-09-19T10:07:06.183+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><title type='text'>Unit Testing the GUI and the Database</title><content type='html'>I stumbled upon an interesting question from StackOverflow: &lt;a href="http://stackoverflow.com/questions/1447474/philisophical-questions-about-test-driven-development"&gt;Philisophical Questions about Test-Driven Development&lt;/a&gt;&lt;br /&gt;&lt;span style="border-collapse: collapse; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 18px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;ol style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-size: 14px; list-style-image: initial; list-style-position: initial; list-style-type: decimal; margin-bottom: 1em; margin-left: 30px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;br /&gt;&lt;blockquote&gt;How do you handle large changes? When it comes to testing single functions (some parameters, a result value, few side effects), TDD is a no-brainer. But what about when you need to thoroughly overhaul something large, e.g. switching from a SAX parsing library to a DOM parsing library? How do you keep to the test-code-refactor cycle when your code is in an intermediate state? Once you start making the change , you will get a bevy of failed tests until you've fully finished the overhaul (unless you maintain some kind of mongrel class that uses both DOM and SAX until you're done converting, but that's pretty weird). What happens to the small-step test-code-refactor cycle in this case? During this whole process you will no longer be moving in small, fully-tested steps. There must be some way people deal with this.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;br /&gt;&lt;blockquote&gt;When testing GUI or database code with mocks, what are you really testing? Mocks are built to return exactly the answer you want, so how do you know that your code will work with the real-world database? What is the benefit of automated tests for this kind of thing? It improves confidence somewhat, but a) it doesn't give you the same level of confidence that a complete unit test ought to, and b) to a certain extent, aren't you simply verifying that your assumptions work with your code rather than that your code works with the DB or GUI?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Here's my answer to the second part of the question:&lt;br /&gt;&lt;span style="border-collapse: collapse; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 18px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: blue;"&gt;This is my approach: For database applications, I&amp;nbsp;&lt;/span&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span style="color: blue;"&gt;don't use mock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;for my unit test. Instead, I run the tests on a real database, albeit a different one than the production database. So in this sense you can say that I don't run unit test on database. For NHibernate applications, I maintain two databases with same schema, but different database type (ORM makes this easy). I use sqlite for my automated testing, and a real MySQL or SQL server database for ad-hoc testing.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="color: blue;"&gt;Only once did I use mock for unit testing the DAL; and that's when I was using strongly typed dataset as the ORM ( a big mistake!). The way I did this was to have&amp;nbsp;&lt;/span&gt;&lt;a href="http://typemock.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="color: blue;"&gt;Typemock&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;returned me a mocked copy of the complete table so that I can perform&amp;nbsp;&lt;/span&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span style="color: blue;"&gt;select *&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;on it. Later as I looked back I wished I never do this, but that was long time ago, and I wished I used a proper ORM.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="color: blue;"&gt;As for the GUI,&amp;nbsp;&lt;/span&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="color: blue;"&gt;it is possible&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;to unit test the GUI interaction. The way I did this was to use the&amp;nbsp;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc188690.aspx" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="color: blue;"&gt;MVP pattern&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;to separate out the Model, View and Presenter. Actually for this type of application I test on the Presenter and the Model, in which I use Typemock ( or&amp;nbsp;&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Dependency_injection" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="color: blue;"&gt;dependency injection&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue;"&gt;) to isolate the different layers so that at one time I can concentrate on only one layer. I don't test the view, but I do test Presenter ( where the majority of interaction and bugs are happening) a lot .&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-543972422302615951?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/543972422302615951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=543972422302615951' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/543972422302615951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/543972422302615951'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/09/unit-testing-gui-and-database.html' title='Unit Testing the GUI and the Database'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-4483241193453575708</id><published>2009-09-12T00:25:00.000+08:00</published><updated>2009-09-12T00:25:18.759+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blog'/><title type='text'>My First Google Adsense Cheque</title><content type='html'>&lt;div style="text-align: justify;"&gt;Writing a blog is never easy. You have to spend a lot of time on it, spend some thoughts on the marketing, and most important of all, be persistent!&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I am glad to say that after operating this blog for almost 2 years, finally I got my first Google Adsense Cheque. Of course, money isn't the motivation that drives me with my blog. But nevertheless, some recognition from Google ( and some hard cash) is an additional booster.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SqnPJzG2OXI/AAAAAAAAFIY/0BgzSRt4pFk/s1600-h/googleadsense2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SqnPJzG2OXI/AAAAAAAAFIY/0BgzSRt4pFk/s400/googleadsense2.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Let's hope that I can write more, and my blog will gain in popularity, so that I can receive a second cheque sooner!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4483241193453575708?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4483241193453575708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4483241193453575708' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4483241193453575708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4483241193453575708'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/09/my-first-google-adsense-cheque.html' title='My First Google Adsense Cheque'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SqnPJzG2OXI/AAAAAAAAFIY/0BgzSRt4pFk/s72-c/googleadsense2.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-8058063700743559760</id><published>2009-09-10T20:20:00.000+08:00</published><updated>2009-09-10T20:20:00.471+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='firebug'/><title type='text'>FireSymfony-- Symfony Debugging with FireBug</title><content type='html'>&lt;div style="text-align: justify;"&gt;If you are doing &lt;a href="http://www.symfony-project.org/"&gt;Symfony&lt;/a&gt; applications, you should not miss out this one: &lt;a href="http://www.firesymfony.org/"&gt;FireSymfony&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;We all love &lt;a href="http://getfirebug.com/"&gt;firebug&lt;/a&gt;, don't we? Well, FireSymfony is an extension of firebug, that allows you to see the Symfony variables inside the much-beloved firebug:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/SqiqvjzHgsI/AAAAAAAAFII/8C9R_XH10Eg/s1600-h/firesymfony..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/SqiqvjzHgsI/AAAAAAAAFII/8C9R_XH10Eg/s400/firesymfony..png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;With all the PHP, HTML and Javascript variables in one single panel, debugging suddenly seems so much easier.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;To setup for FireSymfony, here's what &lt;a href="http://www.symfony-project.org/blog/2009/09/09/firesymfony-installing-and-configuring-the-plugin"&gt;you should do&lt;/a&gt;:&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/9096/"&gt;Install&lt;/a&gt; FireSymfony as your FireBug extension&lt;/li&gt;&lt;li&gt;Change your factories.yml by enabling the following:&lt;/li&gt;&lt;pre class="brush: bash"&gt;all:&lt;br /&gt;  logger:&lt;br /&gt;    class: sfAggregateLogger&lt;br /&gt;    param:&lt;br /&gt;      level: debug&lt;br /&gt;      loggers:&lt;br /&gt;        sf_web_debug:&lt;br /&gt;          class: sfWebDebugLogger&lt;br /&gt;          param:&lt;br /&gt;            level: debug&lt;br /&gt;            condition:       %SF_WEB_DEBUG%&lt;br /&gt;            xdebug_logging:  true&lt;br /&gt;            web_debug_class: fsWebDebugForSf12&lt;br /&gt;        sf_file_debug:&lt;br /&gt;          class: sfFileLogger&lt;br /&gt;          param:&lt;br /&gt;            level: debug&lt;br /&gt;            file: %SF_LOG_DIR%/%SF_APP%_%SF_ENVIRONMENT%.log&lt;br /&gt;&lt;/pre&gt;&lt;/ol&gt;And you are ready to go!&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Note: There is a typo at the Symfony blog (it should be &lt;b&gt;&lt;i&gt;fsWebDebugForSf12&lt;/i&gt;&lt;/b&gt;, instead of &lt;b&gt;&lt;i&gt;fsWebDebug&lt;/i&gt;&lt;/b&gt;) for Symfony 1.2.x, I've corrected the typo here. So if you follow my instruction here you will do just fine. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-8058063700743559760?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8058063700743559760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8058063700743559760' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8058063700743559760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8058063700743559760'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/09/firesymfony-symfony-debugging-with.html' title='FireSymfony-- Symfony Debugging with FireBug'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SqiqvjzHgsI/AAAAAAAAFII/8C9R_XH10Eg/s72-c/firesymfony..png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-5121643390800708866</id><published>2009-09-07T17:30:00.000+08:00</published><updated>2009-09-07T17:30:19.520+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Sample'/><category scheme='http://www.blogger.com/atom/ns#' term='Symfony'/><title type='text'>How to Retrieve database Information from databases.yml in Symfony</title><content type='html'>&lt;div style="text-align: justify;"&gt;Sometimes you need to access the database information, such as dsn, database username or password from the &lt;a href="http://www.symfony-project.org/reference/1_2/en/07-Databases"&gt;databases.yml&lt;/a&gt; in your &lt;a href="http://www.symfony-project.org/"&gt;Symfony&lt;/a&gt; application. Since databases.yml is just a yml file, you can always find the file, parse the information in the file and read the information you want.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Needless to say this is a very arduous task, even with a yml parser. Furthermore, the fact that there are multiple environments in one single databases.yml can complicated the task of obtaining the correct set of variables.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;An alternative way to do it is to use the underlying Symfony library. Suppose that you have the following databases.yml:&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;dev:&lt;br /&gt;  db3:&lt;br /&gt;    param:&lt;br /&gt;      classname: DebugPDO&lt;br /&gt;test:&lt;br /&gt;  db3:&lt;br /&gt;    param:&lt;br /&gt;      classname: DebugPDO&lt;br /&gt;      dsn: 'mysql:dbname=mydbtest;host=localhost'&lt;br /&gt;all:&lt;br /&gt;  db3:&lt;br /&gt;    class: sfPropelDatabase&lt;br /&gt;    param:&lt;br /&gt;      classname: PropelPDO&lt;br /&gt;      dsn: 'mysql:dbname=mydb;host=localhost'   #where the db is located&lt;br /&gt;      username: root&lt;br /&gt;      password: password&lt;br /&gt;      encoding: utf8&lt;br /&gt;      persistent: true&lt;br /&gt;      pooling: true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Here's how you can obtain the dsn, username and password information from the above yml:&lt;/div&gt;&lt;pre class="brush: php"&gt;$appConfig= ProjectConfiguration::getApplicationConfiguration('frontend', 'test', true);&lt;br /&gt;$dbManager= new sfDatabaseManager($AppConfig);&lt;br /&gt;$db3=$dbManager-&amp;gt;getDatabase('db3');&lt;br /&gt;$username = $db3-&amp;gt;getParameter('username');  //root&lt;br /&gt;$dsn= $db3-&amp;gt;getParameter('dsn');  //mysql:dbname=mydbtest;host=localhost because it's test config&lt;br /&gt;$password= $db3-&amp;gt;getParameter('password');  //password&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Simple, isn't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5121643390800708866?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5121643390800708866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5121643390800708866' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5121643390800708866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5121643390800708866'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/09/how-to-retrieve-database-information.html' title='How to Retrieve database Information from databases.yml in Symfony'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5598711941759543828</id><published>2009-09-03T21:03:00.010+08:00</published><updated>2009-09-04T08:27:38.925+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Computer Problem'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Apache: Only one usage of each socket address is normally permitted: make_sock could not bind to address 0.0.0.0:80 no listening sockets available, shutting down</title><content type='html'>I got this problem with my Apache server this morning:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Only one usage of each socket address * &amp;nbsp;is normally permitted. : make_sock could not bind to address 0.0.0.0:80 no listening sockets available, shutting down&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;Unable to open logs&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;Note the errors or messages, above, and press the &lt;esc&gt; key to exit.&lt;/esc&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It turned out that my newly installed &lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt; should be responsible for this debacle.So I&lt;a href="http://www.simonwhatley.co.uk/apache-installation-problems-with-skype"&gt; fixed the problem by changing the Skype configuration&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Why should Skype eavesdrop on the default 80 port and break all the other applications is a mystery to me. And although the problem is there for at least one and a half years, Skype still has no intention to fix this, even though the fix is as simple as disabling a checkbox.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5598711941759543828?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5598711941759543828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5598711941759543828' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5598711941759543828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5598711941759543828'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/09/apache-only-one-usage-of-each-socket.html' title='Apache: Only one usage of each socket address is normally permitted: make_sock could not bind to address 0.0.0.0:80 no listening sockets available, shutting down'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-8473727263731139385</id><published>2009-08-24T00:30:00.001+08:00</published><updated>2009-08-24T00:34:05.044+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='Movies'/><title type='text'>梁祝之双飞</title><content type='html'>&lt;div style="text-align: center;"&gt;不等来世再相约&lt;/div&gt;&lt;div style="text-align: center;"&gt;今生就要无恨无悔&lt;/div&gt;&lt;div style="text-align: center;"&gt;不问前缘我是谁&lt;/div&gt;&lt;div style="text-align: center;"&gt;只管今尘和你日日月月&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;我愿与你雪中泥&lt;/div&gt;&lt;div style="text-align: center;"&gt;红尘寸寸泥中血&lt;/div&gt;&lt;div style="text-align: center;"&gt;冷暖相随悲欢同泪&lt;/div&gt;&lt;div style="text-align: center;"&gt;朝朝暮暮相依偎&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;我是萍你是水&lt;/div&gt;&lt;div style="text-align: center;"&gt;相逢相爱不是罪&lt;/div&gt;&lt;div style="text-align: center;"&gt;地久苦天长泪&lt;/div&gt;&lt;div style="text-align: center;"&gt;为你染红我的血&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;我愿与你双双飞&lt;/div&gt;&lt;div style="text-align: center;"&gt;我愿与你双双飞&lt;/div&gt;&lt;div style="text-align: center;"&gt;今生有了你我梦一回&lt;/div&gt;&lt;div style="text-align: center;"&gt;来世等你将我醉&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;我愿与你双双飞&lt;/div&gt;&lt;div style="text-align: center;"&gt;飞离红尘是与非&lt;/div&gt;&lt;div style="text-align: center;"&gt;人间痴情迢迢不归路&lt;/div&gt;&lt;div style="text-align: center;"&gt;不如天上比翼蝶&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;人间痴情迢迢不归路&lt;/div&gt;&lt;div style="text-align: center;"&gt;不如天上&lt;/div&gt;&lt;div style="text-align: center;"&gt;比翼蝶&lt;/div&gt;&lt;br /&gt;今天晚上翻来覆去睡不着，脑子里面总是浮现这首《&lt;a href="http://zhidao.baidu.com/question/28668542.html"&gt;双飞&lt;/a&gt;》。所以现在就来略略谈谈。&lt;br /&gt;&lt;br /&gt;我首次听到这首歌，是在我小时候。那时应该是1993年吧。收音机常常播放这首歌。那时这首歌是&lt;a href="http://zh.wikipedia.org/wiki/%E5%B0%8F%E8%99%8E%E9%9A%8A"&gt;小虎队&lt;/a&gt;的&lt;a href="http://zh.wikipedia.org/wiki/%E5%90%B3%E5%A5%87%E9%9A%86"&gt;吴奇隆&lt;/a&gt;所演绎。如果没有记错这首歌是出自吴奇隆和杨采妮版的电影《&lt;a href="http://itscommonsensestupid.blogspot.com/2009/04/blog-post.html"&gt;梁祝&lt;/a&gt;》。梁祝的悲剧，注定了这首歌的调儿。现在的人自由恋爱，无法体会到古代人追求自由真爱的决心以及壮烈，当然也很难明白他们所付出的牺牲。想到戏中的遗憾，再看回歌词，心中不禁有一股凄凉之感。可是这也是梁祝和这首歌让人刻骨铭心的地方。大概是越有缺憾的故事，就越能打动人心。&lt;br /&gt;&lt;br /&gt;这首歌歌曲缠绵动听，没听几次就爱上了它。我还把它录起来在夜深人静的时候偷偷的播，然后一边想象戏里面的情节。我那时候都已经不信这种“来世变成蝴蝶双飞”的故事，可是想到戏里面主人翁的遭遇，又希望这是真的。我想很多的童话或神话都是这样子制造出来的吧，人们现实得不到的东西，就得编一个故事来自我陶醉一番。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;另外一点，我发现还是我儿时的流行歌词写得比较好，跟现在比起来的话。我总是觉得2000年过后的歌手不值得一提。一些天王，连咬字都不清，跟别说写好歌词，可是居然能够大红，简直是怪事。看看《双飞》的歌词，再看看周董的词句，顿时高下立判。&lt;br /&gt;&lt;br /&gt;这里就是这首歌的两个版本，一个由吴奇隆演绎，另外一个由何润东所唱，希望你会喜欢。&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/T9G4LNfBAaI&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/T9G4LNfBAaI&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/LS-IhE--I1U&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/LS-IhE--I1U&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-8473727263731139385?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8473727263731139385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8473727263731139385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8473727263731139385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8473727263731139385'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/08/blog-post.html' title='梁祝之双飞'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-2100757675057476681</id><published>2009-08-21T19:05:00.000+08:00</published><updated>2009-08-21T19:05:00.529+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tipjoy'/><title type='text'>tipjoy is dead; long live tipjoy</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://tipjoy.com/"&gt;tipjoy&lt;/a&gt; is a micropayment web service. The idea is that if you see something you like, but you are not feeling that the item deserves a paypal contribution, you can use tipjoy to send them a penny of your money.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Great concept, but sadly it doesn't work.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="http://tipjoys2cents.blogspot.com/2009/08/so-long-and-thanks-for-all-fish.html"&gt;tipjoy is closing down&lt;/a&gt;, maybe due to current economic downturn where the funds are drying up, or maybe the concept micropayment can never work on the web, we don't know.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I used tipjoy on my blog, and I didn't receive a single cent of donation. That maybe is a testament on how hard this kind of business model is.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-2100757675057476681?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2100757675057476681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2100757675057476681' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2100757675057476681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2100757675057476681'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/08/tipjoy-is-dead-long-live-tipjoy.html' title='tipjoy is dead; long live tipjoy'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-8191542187693970767</id><published>2009-08-14T23:52:00.001+08:00</published><updated>2009-08-14T23:54:15.066+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Streamyx'/><title type='text'>My Experience with Streamyx--A Lesson in Dealing Bureaucracy</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SoWHe62y7kI/AAAAAAAAFFo/bQzudNnI_VI/s1600-h/Bureaucracy_Cartoon.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SoWHe62y7kI/AAAAAAAAFFo/bQzudNnI_VI/s400/Bureaucracy_Cartoon.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Streamyx&amp;nbsp;is not exactly not the best ISP in the world; a search of "&lt;a href="http://www.google.com.my/search?hl=en&amp;amp;safe=off&amp;amp;rlz=1C1GGLS_enMY291MY303&amp;amp;ei=3nqFSq4cjYKQBd2-kbYH&amp;amp;sa=X&amp;amp;oi=spell&amp;amp;resnum=0&amp;amp;ct=result&amp;amp;cd=1&amp;amp;q=streamyx+problem&amp;amp;spell=1"&gt;Streamyx problem&lt;/a&gt;" on Google yields 82600 results, with &lt;a href="http://itscommonsensestupid.blogspot.com/2008/07/streamyx-problem.html"&gt;yours-truly's complain&lt;/a&gt; comes in the third place. Let me now share with you my recent encounter with Streamyx, and hopefully there are lessons to take away with after you finish reading it. &amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As I am going to move to a new apartment, I have to apply for a Streamyx account. I didn't do this last time because my housemate did it for me.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now,&amp;nbsp;although&amp;nbsp;Streamyx is not exactly a government body ( its parent company,&lt;a href="http://www.tm.net.my/"&gt; tmnet&lt;/a&gt; is a subsidiary of &lt;a href="http://www.tm.com.my/"&gt;Telekom&lt;/a&gt;, which is semi-private), but everyone knows that it is no less bureaucratic than Malaysia's government body. For a developer whose natural inclination is to optimize and reduce waste, dealing with bureaucracy can be a very frustrating experience.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;At first, I wanted to setup my &lt;a href="http://www.expert8.com/streamyx/registration_form.htm"&gt;Streamyx account online&lt;/a&gt;. But the problem is that I didn't have a telephone line yet. So I still had to visit the tmnet point to register the phone line. As I reached the tmnet center, I quickly filled up the form for both phone and Streamyx application. I was told that after telephone application I should allow for 3 working days for the phone activation, &amp;nbsp;and another 3-7 working days for Streamyx account activation.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now, with the&amp;nbsp;prevalence&amp;nbsp;of handphone, who really needs a home phone? The majority of the home users who hook up a telephone line do it because they want a Streamyx account. Strangely Streamyx couldn't recognize this and insisted on making the process a two step exercise, which is very inefficient and very frustrating for us the customers. This means that it could take up to 2 weeks to get a broadband account.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;That's simply ridiculous.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;After I submitted the application I went home. To my great&amp;nbsp;surprise a technician came the very next working day and installed the telephone line for me. Wow, that was surely fast. After the installation he told me to check the availability of the line that evening or the next day. He also told me that after the telephone line is submitted, the Streamyx application will be processed automatically and I should, barring all the irregularities, get the broadband service three days later.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;That meant that it would only &amp;nbsp;take four days to jump on the Information Highway. Not bad.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But knowing how efficient the government body was, I decided to take the matters into my own hand. Instead of waiting passively for the account to get activated, I would simply just call &lt;i&gt;actively&lt;/i&gt; until it was activated. I just called and called and called, all the time asking the same question-- whether my account is already activated.&amp;nbsp;You might think that this is redundant and annoying-- after all if it's already in the queue it will be processed eventually, whether I make calls or not won't make a difference. The operators were very helpful, they wanted to always get the best for me. They verified that my phone line was OK, and they asked for my Streamyx user account and I replied that I didn't have any. They were&amp;nbsp;surprised, and asked me to be patient for it.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I did. For 3 days.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;At the third day I knew I needed to do something. Instead of calling the operators to check my account status, I headed to the tmnet center to resolve the thing. I was stumped when I learnt of my account status.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;My Streamyx account was not even registered.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It was not even registered even though it should by then, or even right after my telephone line was activated--that was what I was told.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I was told that I could get my broadband service in three days time. And now, after three days,&lt;i&gt; it wasn't even been registered yet&lt;/i&gt;.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If this was not&amp;nbsp;bureaucracy&amp;nbsp;and inefficiency, I don't know what else is.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The clerk quickly entered the information into the computer ( yes, registration is just a matter of some data-entry job, and yet they made a big hassle out of it), and told me to wait for another 3 working days for the account activation.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Imagine what would happen if I just sat &amp;nbsp;idle, my application would now still be piled under a heavy stack of papers, waiting to see daylight. I could wait, wait, and wait, for days, for weeks, and my account would still remain unregistered.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Sometimes in order to deal with bureaucracy, you just have to be a bit nagging and paranoid. Also, don't believe everything they told you, you have to make sure that they really do the job.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-8191542187693970767?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8191542187693970767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8191542187693970767' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8191542187693970767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8191542187693970767'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/08/my-experience-with-streamyx-lesson-in.html' title='My Experience with Streamyx--A Lesson in Dealing Bureaucracy'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SoWHe62y7kI/AAAAAAAAFFo/bQzudNnI_VI/s72-c/Bureaucracy_Cartoon.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-4876614197019024883</id><published>2009-08-12T23:12:00.000+08:00</published><updated>2009-08-12T23:12:35.689+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>The Best Phone Model You Prefer?</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/SoLbGwUmYJI/AAAAAAAAFFc/0tomU2VVFSs/s1600-h/dopod838sc001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/SoLbGwUmYJI/AAAAAAAAFFc/0tomU2VVFSs/s320/dopod838sc001.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;My old phone, &lt;a href="http://www.mobile88.com/mobilegallery/preview.asp?prodid=862&amp;amp;cat=43&amp;amp;path=40,43"&gt;Dopod 838&lt;/a&gt; is showing the sign of aging. So I am thinking about replacing it.&lt;br /&gt;&lt;br /&gt;Here are my requirements:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Can synchronize with Microsoft Outlook on Windows&lt;/li&gt;&lt;li&gt;Has Wifi support ( if there is a built-in wifi access plan for this, even better)&lt;/li&gt;&lt;li&gt;Can access &lt;a href="http://mail.google.com/"&gt;Gmail&lt;/a&gt;, &lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;, &lt;a href="http://www.buxfer.com/"&gt;Buxfer&lt;/a&gt; and other web apps.&lt;/li&gt;&lt;li&gt;Touch screen&lt;/li&gt;&lt;/ol&gt;Anyone has any idea?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4876614197019024883?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4876614197019024883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4876614197019024883' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4876614197019024883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4876614197019024883'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/08/best-phone-model-you-prefer.html' title='The Best Phone Model You Prefer?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SoLbGwUmYJI/AAAAAAAAFFc/0tomU2VVFSs/s72-c/dopod838sc001.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-4079204254640860948</id><published>2009-08-08T15:12:00.000+08:00</published><updated>2009-08-08T15:12:22.374+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile Programming'/><title type='text'>Should Programming Work be Billed in Hours?</title><content type='html'>&lt;div style="text-align: justify;"&gt;It's a common practice that programming job is billed in hours, or its variants ( such as billed in man-months, but they are still the same, so please don't nitpick over it. ). This is exceptionally popular among agilists, who believe that the alternative,&amp;nbsp;&lt;a href="http://www.ddj.com/architect/199001126?cid=Ambysoft"&gt;fix price quote is problematic and lead to dire consequences&lt;/a&gt;, for both the software development shops and the clients.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Before I start off maybe I should summarize why fix price is bad. IT projects, as we know it, are notoriously hard, not purely because writing code is hard, but because the business requirements are always unclear, because the &lt;i&gt;commissioners often don't know what they want until they have a working software&lt;/i&gt;. &amp;nbsp;Now, business always welcome fix-price projects because the notion of fix-price seem to be able to contain the financial risk by avoiding the projects from going spirally out of control. The problem is that any IT shops who don't have infinite financial backups can't afford to do fix-price projects under never-ending requirement changes. To protect both parties, pages and pages of requirements, &amp;nbsp;violation orders and documents are written. And these are waste because they are not, strictly, a part of the delivery.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Fix-price projects often result in a lot of wastes, and because of the heavy baggage, it's not so easy to change the projects direction once they are started. This means that if the business owner finds that the business environment changes, or that the IT projects are heading into nowhere, there isn't anything they can do to the software projects except to cancel them and declare the investment as failure.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It is under this light that agile programming is born. You specify what you want, I do that, I show it to you, and you feedback your opinion, and I refine. Everything is done in a lightweight manner; I develop the most important feature early, and you get back your investment as soon as possible. The waste is kept to the minimum, the mistakes can be corrected fast because the duration of iteration is short. We don't really know how the software will look like in, say one year time; all we know is that the software is solving the clients problem from day one, gradually, instead of meeting the specifications that the clients won't like anyway.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It's clear that only bill-per-hour approach can work in this case.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But is it really a good approach? One thing for sure, it's good for software developers because it protects them from being skinned alive by never-ending changes. But the project owners do have some qualms about it.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;First, how do project owners know that the billable hours are well-spent? There is a &lt;a href="http://haacked.com/archive/2007/06/25/understanding-productivity-differences-between-developers.aspx"&gt;10 times&lt;/a&gt; ( or probably more) difference in productivity gap between good developers and bad developers, and probably no one is able to tell the &lt;a href="http://itscommonsensestupid.blogspot.com/2008/05/why-good-developers-are-not-getting-10.html"&gt;difference between who's the good developers and who's the bad&lt;/a&gt;. This is this risk, the risk that the project owners might end up paying a suboptimal developer the optimal rate, that the project owners have to take.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Second, the amount of work done can be a source of dispute. Should a developer bill for the time he spends on researching? Most project owners will&amp;nbsp;instinctively&amp;nbsp;say no, because of the belief that "the developers should already know what they are doing before they charge", if they are not then they should pick up the necessary knowledge and skills on their own. But programming is unlike other assembly job where you can know the amount of time needed for sure. There are a lot of components and libraries out there that the developers can reuse in their work. If project owners frown on the time spent on researching and testing those components, the developers could just go off their own way and reinvent the wheel and rewriting the whole framework, which will cost many times more.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But if a developer bills on research time, this means that he would charge the job cheaper if &amp;nbsp;he gets to do the same job again because he no longer needs to research. The first project owners, as shrewd as they are, would certainly feel that they are mis-fortunate just because they are the first one who venture into the uncharted &amp;nbsp;territory and thus will ask the developer to eat the research cost himself. The poor developer, who wants to save money for the project owners in the first place, are now being taken advantage of.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Third, no matter how you put it to them, business owners don't like to have liability. What's the difference between liability and cost? &amp;nbsp;If the charge is one-time, then it's cost, if it's recurring, then it's a liability. The reason why fix-price is so popular is that it's a cost, not liability. The bill-per-hour project will create the impression that a software project is&amp;nbsp;spiraling&amp;nbsp;out of control because no one knows when the investment can stop. Now, you may say that bill-as-we-go-along should be OK because the project will pay for itself along the way. But under this optimism there lies an assumption: that the projects can generate tangible benefits, or revenue in a short time. There are lot of times when the business or operation stumble even though the software behind them are perfectly done.&lt;a href="http://itscommonsensestupid.blogspot.com/2009/08/code-is-not-that-important-marketing-is.html"&gt; Code is not everything in an&amp;nbsp;endeavor&lt;/a&gt;. &amp;nbsp;Not the mention the possibility that the payback time maybe longer than the project period. Furthermore it ties the software developer to the business risk, a risk that the software developer has no inclination to share.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As a software developer, I wish every single project owner will understand the reality of software development ( and their fickleness) and adopt bill-per-hour approach. But before I can expect that, maybe the software development community should address their concern first.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4079204254640860948?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4079204254640860948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4079204254640860948' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4079204254640860948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4079204254640860948'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/08/should-programming-work-be-billed-in.html' title='Should Programming Work be Billed in Hours?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-1085033633033359595</id><published>2009-08-01T22:05:00.001+08:00</published><updated>2009-08-01T22:09:10.080+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Code is Not That Important, Marketing Is</title><content type='html'>&lt;div style="text-align: justify;"&gt;When I was in my early days as a software developer, I thought that the most important aspect for a software product organization, was software development. Code was everything and the single determiner of the success. I &lt;a href="http://www.foundersatwork.com/joel-spolksy.html"&gt;was told&lt;/a&gt;, by none other than the great &lt;a href="http://www.joelonsoftware.com/"&gt;Joel Spolksy&lt;/a&gt;, that all you have to do is to polish your code, add in features that your customers demand, and you would be doing fine.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;For a software developer and a geek, that was an assuring and comforting theory. We the geeks have seen too much injustice in the world. I mean, geeks, even though they were smarter and more hardworking than the average Joe the bond salesman, were nevertheless earning not even half of Joe's income on average. To add insult to the injury, not only there was a wide disparity between the IQ and earning power, but the world perception didn't seem to value the geek's contribution to it extend that it should. Geeks have done tremendous contribution to the world, but the society ( and the opposite sex) still treat the geeks in a polite disdain because it rather judged a man by his outward&amp;nbsp;appearance&amp;nbsp;than his inner content. This kind of injustice was very disheartening. But thanks to the internet and Information Revolution, finally, the moment of the geek has arrived. Hua haha!&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But as I grow in maturity ( meaning suffering enough bumps on head), I gradually come to the realization that the above just-improve-your-code-and-you-do-fine theory is a total nonsense. &lt;a href="http://www.fogcreek.com/FogBUGZ/"&gt;FogBugz&lt;/a&gt;, the Joel Spolsky's brain child, was &lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/SnQ_5prhDQI/AAAAAAAAFDM/z31ZLPvYnPs/s1600-h/2555237204_8c1cd1f0b5.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: justify;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/SnQ_5prhDQI/AAAAAAAAFDM/z31ZLPvYnPs/s200/2555237204_8c1cd1f0b5.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;ironically a case in point. There are hundreds, if not thousands of bug trackers out there on the Internet because they are easy to write and are ideal for programmers who don't know any other domain knowledge. And how hard a bug tracker can get? Certainly not very hard. They are many flavors, licensing schemes for bug trackers, ranging from the &lt;a href="http://www.ibm.com/software/awdtools/clearquest"&gt;very expensive&lt;/a&gt;, to the &lt;a href="http://www.bugzilla.org/"&gt;completely free and open source&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The thing that separate FogBugz from other bug tracker system, is Joel's blog.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Joel's blog is immensely popular among software developers. That blog gives him a hearing audience. One can safely say that without the blog FogBugz will be just another bug tracker that you won't even bother to look at. I am not denigrating FogBugz; I use FogBugz in my work and in my personal life; it's very pleasant use, and I will recommend it to anyone as long as they are not tight on budget. But the point is that FogBugz can get to point it is today is because it gets a head start from the blog, and the revenue that funds its continuous development up to this day.&lt;/div&gt;&lt;br /&gt;The same can be said of &lt;a href="http://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt;, &amp;nbsp;a clone of&amp;nbsp;&lt;a href="http://www.experts-exchange.com/"&gt;Expert Exchange&lt;/a&gt;-- minus all the annoyances.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And if you look around, it's not hard to find that the number of software that stands out purely because of its code are very, very few. Back in 80s Apple was the first company that introduced the modern GUI as we know it, but it was Windows that dominated the world. Microsoft Access was a complete failure when it was first introduced ( there were &lt;a href="http://www.brighthub.com/office/collaboration/articles/13190.aspx"&gt;serious bugs that caused data corruption&lt;/a&gt;), and when it came to the market there was &lt;a href="http://www.foxprohistory.org/"&gt;FoxPro&lt;/a&gt; and other desktop RDBMS that were many times more superior. In the end it was Access that flourished and FoxPro that perished, thanks to Microsoft's decision to bundle Access with other more successful office products and sold them as a suite.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Even in the ultra competitive trading world, the algorithms are often not the most important determining factors. &lt;a href="http://securitywatch.eweek.com/corporate_espionage/former_goldman_sachs_employee_arrested_for_stealing_secret_code.html"&gt;Quant shops and investment banks go to extra lengths to protect their trading algorithms&lt;/a&gt;, &amp;nbsp;in the name of protecting their trade secret. But to think that they-- or anyone else-- have a killer algorithm that no one else has is just naive. The quants are going to the same conference, reading the same journal papers and implementing the same ideas. If there was a killer algorithm, it would have been implemented by a fair share of the quant shops in a short time and thus drive down its&amp;nbsp;usefulness. The reason big sharks like Goldman Sach make money and other shops don't is because their computers are more powerful, and are nearer to the stock exchange. Of course their &lt;a href="http://www.bulldogtrust.com/trading.htm"&gt;HFT&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Statistical_arbitrage"&gt;stats arb algorithms&lt;/a&gt; do play a role, but without the underlying infrastructure it's pretty hard to make any money.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;So, my dear developer ( I am looking at the mirror here), forget the idea that if you are a good coder you are destined to be&amp;nbsp;successful. Code is not that important, marketing is.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-1085033633033359595?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1085033633033359595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1085033633033359595' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1085033633033359595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1085033633033359595'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/08/code-is-not-that-important-marketing-is.html' title='Code is Not That Important, Marketing Is'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SnQ_5prhDQI/AAAAAAAAFDM/z31ZLPvYnPs/s72-c/2555237204_8c1cd1f0b5.jpg' height='72' width='72'/><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-1903081351226691131</id><published>2009-07-27T19:58:00.000+08:00</published><updated>2009-07-27T19:58:36.374+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firefox 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Chrome'/><title type='text'>Your browser is not supported at this time</title><content type='html'>&lt;div style="text-align: justify;"&gt;I thought only &lt;a href="http://itscommonsensestupid.blogspot.com/2008/12/sorry-we-support-only-ie-and-firefox.html"&gt;a movie website&lt;/a&gt; that doesn't support Google Chrome, I was wrong.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="http://oe.quickbooks.com/"&gt;QuickBooks&lt;/a&gt; also doesn't support Google Chrome. :(&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/Sm2VHxdU1pI/AAAAAAAAFC8/Iiu4tquxqrk/s1600-h/intuit.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/Sm2VHxdU1pI/AAAAAAAAFC8/Iiu4tquxqrk/s400/intuit.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It's 2009, and Google Chrome has &lt;a href="http://www.tgdaily.com/content/view/43106/113/"&gt;2% market share&lt;/a&gt;, and the &amp;nbsp;visitors who visit my blog ( who are mostly techies) are even more inclined to use Google Chrome. I don't quite understand why they have to leave Chrome out. Hello?&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/Sm2WPkYLkfI/AAAAAAAAFDE/N29-Lpn4Mf4/s1600-h/Mymarketshare.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/Sm2WPkYLkfI/AAAAAAAAFDE/N29-Lpn4Mf4/s400/Mymarketshare.jpg" /&gt;&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/3204586232155134420-1903081351226691131?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1903081351226691131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1903081351226691131' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1903081351226691131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1903081351226691131'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/07/your-browser-is-not-supported-at-this.html' title='Your browser is not supported at this time'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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://3.bp.blogspot.com/_SDci0Pf3tzU/Sm2VHxdU1pI/AAAAAAAAFC8/Iiu4tquxqrk/s72-c/intuit.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-521435016601147110</id><published>2009-07-23T20:11:00.002+08:00</published><updated>2009-07-23T20:15:02.764+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='TypeMock'/><title type='text'>Use DoInstead for Parameter Verification in Typemock</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://blog.typemock.com/2008/08/isolator-aaa-api-basics.html"&gt;Typemock AAA syntax&lt;/a&gt; is very helpful in mocking out calls. However one of the limitation is that it's not possible to verify the correctness of method parameters.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;With the &lt;a href="http://blog.typemock.com/2009/03/typemock-isolator-53-is-out.html"&gt;DoInstead&lt;/a&gt; API, there is finally a way to verify method parameters. Here's how you can do it.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Assume that you have a word application, and you need to implement save, load file operation. For simplicity's sake you are saving it in XML. Here's your code:&lt;/div&gt;&lt;pre class="brush: csharp"&gt;public enum FileOpState&lt;br /&gt;    {&lt;br /&gt;        Saved,&lt;br /&gt;        NotSaved&lt;br /&gt;    }&lt;br /&gt;    public class FileOperationCommand&amp;lt;t&amp;gt;&lt;br /&gt;        where T: class &lt;br /&gt;    {&lt;br /&gt;        public string PrjPath&lt;br /&gt;        { get; private set; }&lt;br /&gt;      &lt;br /&gt;        public T New()&lt;br /&gt;        {&lt;br /&gt;            return Activator.CreateInstance&amp;lt;t&amp;gt;();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public T Load()&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            PrjPath = GetPrjPath(new OpenFileDialog());&lt;br /&gt;&lt;br /&gt;            if (string.IsNullOrEmpty(PrjPath))&lt;br /&gt;                return null;&lt;br /&gt;            using (FileStream fs = new FileStream(PrjPath, FileMode.Open, FileAccess.Read))&lt;br /&gt;            {&lt;br /&gt;                XmlSerializer serializer = new XmlSerializer(typeof(T));&lt;br /&gt;                return (T)serializer.Deserialize(fs);     &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public FileOpState Save(T objectToSave)&lt;br /&gt;        {&lt;br /&gt;            PrjPath = GetPrjPath(new SaveFileDialog());&lt;br /&gt;            &lt;br /&gt;            if (string.IsNullOrEmpty(PrjPath))&lt;br /&gt;                return FileOpState.NotSaved;&lt;br /&gt;            using (TextWriter writeFilStream = new StreamWriter(PrjPath))&lt;br /&gt;            {&lt;br /&gt;                XmlSerializer serializer = new XmlSerializer(typeof(T));&lt;br /&gt;                serializer.Serialize(writeFilStream, objectToSave);&lt;br /&gt;                return FileOpState.Saved;            &lt;br /&gt;            } &lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        private static string GetPrjPath(FileDialog passInDialog)&lt;br /&gt;        {&lt;br /&gt;            FileDialog fbd = passInDialog;&lt;br /&gt;&lt;br /&gt;            fbd.DefaultExt = ".xml";&lt;br /&gt;            fbd.Filter = "XML (*.xml)|*.xml";&lt;br /&gt;            if (fbd.ShowDialog() == DialogResult.OK)&lt;br /&gt;            {&lt;br /&gt;                return fbd.FileName;&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return "";&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And you want to test, for this simple application, whether when you call the Save command, the correct dialog box is called. i.e., the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.filedialog.aspx"&gt;FileDialog&lt;/a&gt; that you pass into &lt;b&gt;GetPrjPath&lt;/b&gt; is &lt;a href="http://www.jonasjohn.de/snippets/csharp/save-file-dialog-example.htm"&gt;SaveFileDialog&lt;/a&gt;, not other dialog.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This means that you have to make sure that mock away the &lt;b&gt;GetPrjPath&lt;/b&gt; by returning a predefined path, and verify that the &lt;b&gt;passInDialog&lt;/b&gt; is of the type &lt;a href="http://www.jonasjohn.de/snippets/csharp/save-file-dialog-example.htm"&gt;SaveFileDialog&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Here's how you can write the code:&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;[Test, Isolated]&lt;br /&gt;        public void Save_With_Correct_File_Dialog()&lt;br /&gt;        {&lt;br /&gt;            object fileDialogType = null;&lt;br /&gt;            Isolate.NonPublic.WhenCalled(command.GetType(), "GetPrjPath")&lt;br /&gt;            .DoInstead(context=&amp;gt;&lt;br /&gt;                           {&lt;br /&gt;                               fileDialogType = context.Parameters[0];&lt;br /&gt;                               return&lt;br /&gt;                                   @"C:\me.xml";&lt;br /&gt;                           });&lt;br /&gt;&lt;br /&gt;            UserInformation userInformation = new UserInformation()&lt;br /&gt;            {&lt;br /&gt;                Age = 10,&lt;br /&gt;                Name = "asef"&lt;br /&gt;            };&lt;br /&gt;            Assert.AreEqual(FileOpState.Saved, command.Save(userInformation));&lt;br /&gt;         Assert.IsInstanceOf&amp;lt;savefiledialog&amp;gt;(fileDialogType);&lt;br /&gt;     &lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;See what we do here. First, we use &lt;b&gt;DoInstead&lt;/b&gt; to intercept the &lt;b&gt;GetPrjPath&lt;/b&gt; method. This ensures that whenever &lt;b&gt;GetPrjPath&lt;/b&gt; is called, the code body inside &lt;b&gt;DoInstead&lt;/b&gt; steps in. When that happens, we assign the first parameter of the method to an object called &lt;b&gt;fileDialogType&lt;/b&gt;, &lt;i&gt;and&lt;/i&gt; we return a value for that method. The return value is just to make sure that the code, after exiting from the method body, can continue to run. At the assert part, we make sure that &lt;b&gt;fileDialogType&lt;/b&gt; is of the correct type. &lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;That's it! &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-521435016601147110?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/521435016601147110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=521435016601147110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/521435016601147110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/521435016601147110'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/07/use-doinstead-for-parameter.html' title='Use DoInstead for Parameter Verification in Typemock'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-3242882637031554562</id><published>2009-07-14T00:18:00.000+08:00</published><updated>2009-07-14T00:18:53.901+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Twitter'/><title type='text'>Twitter and the Web 2.0 Hype</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/SltMojO366I/AAAAAAAAFBc/yDp6Ke-1UIM/s1600-h/twitter.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/SltMojO366I/AAAAAAAAFBc/yDp6Ke-1UIM/s320/twitter.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; is the latest fan boy in the town. A free social messaging utility that allows you to broadcast to the world what you are doing under 140 characters, it enjoyed a meteoric rise after a few well known celebrities started to use it. For a simple service that can be cloned in a week ( or so &lt;a href="https://twitter.com/NetArchitect"&gt;a tweet claims&lt;/a&gt;), Twitter's success is nothing short of astounding.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But despite the role it played in the &lt;a href="http://en.wikipedia.org/wiki/2009_Iranian_election_protests"&gt;Iranian election&lt;/a&gt;, despite that it's such a huge disrupter to any authoritarian regime, despite its ability to &lt;a href="http://draft.blogger.com/goog_1247497180520"&gt;convey real time information in such a wide and spontaneous manner that no other&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="http://www.cbsnews.com/stories/2009/06/15/tech/main5090788.shtml"&gt;type of media can hope to convey&lt;/a&gt;, Twitter is really lacking of &lt;a href="http://mashable.com/2009/03/23/twitter-business-model-2/"&gt;a business model&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Well, it's not exactly a sin to have a startup that lacks a business model; I don't have a problem with that. I &lt;i&gt;do&lt;/i&gt; have a problem, however, with the kind of hype associates with it.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;For quite sometime already people has been talking about Twitter and &lt;a href="http://www.readwriteweb.com/archives/discovering_power_of_twitter_search.php"&gt;real time search&lt;/a&gt;, and why should Google worries about it. Even the venerable &lt;a href="http://www.wired.co.uk/wired-magazine/archive/2009/08/features/the-unstoppable-google.aspx"&gt;Wired magazine&lt;/a&gt;, which should really have known better, also asked Eric Schmidt whether he's worried about the threat Twitter posted to Google because of real time search.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;So, by having "real time search" Twitter is posted to be a Google killer? &lt;i&gt;C'mmon, you gotta be seriou&lt;/i&gt;s. For one, Google &lt;i&gt;does&lt;/i&gt; have a real time search-- if your article or news are important enough. For example, I can expect to get my blog post from Google minutes after it has been posted ( and I am in &lt;b&gt;&lt;i&gt;NO WAY&lt;/i&gt;&lt;/b&gt; consider my post to be important, except perhaps to myself). And if you are a venerable news agency, you can expect to see your article appears on Google news right after it appears on your website ( I searched '&lt;a href="http://www.google.com.my/search?rlz=1C1GGLS_enMY291MY303&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=obama"&gt;obam&lt;/a&gt;a' and the first item I got was &lt;a href="http://www.google.com/hostednews/afp/article/ALeqM5jL4cVaUhHt14BTCyQbcBkI4CGZww"&gt;a news item&lt;/a&gt; from AFP-- updated 39 minutes ago).&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It seems that the only strength Twitter has over Google is the " real time ability" to search for common terms, such as "&lt;a href="http://www.readwriteweb.com/archives/discovering_power_of_twitter_search.php"&gt;Gmail outage&lt;/a&gt;" that won't normally appear in Google searches because these kinds of events are quite frivolous and don't register a lasting impact. But as far as I know &lt;a href="http://technorati.com/"&gt;Technorati&lt;/a&gt;, a blog search engine also has this feature since &lt;i&gt;long time ago&lt;/i&gt;. Obviously, the ability to see "what is percolating in blogs &lt;i&gt;now"&lt;/i&gt;( Technorati motto) doesn't save Technorati at all; the last time I checked the website it's slow, and the&lt;a href="http://itscommonsensestupid.blogspot.com/2008/06/technorati-api-service.html"&gt; indexing service is unreliable&lt;/a&gt;, and according to &lt;a href="http://www.techcrunch.com/2009/04/02/technorati-lays-off-another-10-percent-of-employees/"&gt;all the metric I have&lt;/a&gt; Technorati is not exactly prospering now, even though it did started off with a big bang.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Twitter could as well turn into another Technorati, we don't know.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Which leads to the question of why all the hype? As mentioned, although Twitter is obviously a good tool, but the fact that people seems to take it too seriously has always bother me. It seems that the Internet media is always on a lookout for the next poster child to talk about, and of course the poster child will welcome all the attention ( but not the downtime that associates with the traffic spike, please). But we as the user, do we have to chase from one trend to another? From one next-hot-service to another-hot-service?&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Oh yes, one last thing. Before I forget, Twitter, &lt;a href="http://itscommonsensestupid.blogspot.com/2009/03/i-would-like-to-jump-on-twitters.html"&gt;please enable OpenID support&lt;/a&gt;. I am sure it would be useful.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Thank you for listening to my rant.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3242882637031554562?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3242882637031554562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3242882637031554562' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3242882637031554562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3242882637031554562'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/07/twitter-and-web-20-hype.html' title='Twitter and the Web 2.0 Hype'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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://3.bp.blogspot.com/_SDci0Pf3tzU/SltMojO366I/AAAAAAAAFBc/yDp6Ke-1UIM/s72-c/twitter.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-8679606707791919355</id><published>2009-07-10T19:11:00.001+08:00</published><updated>2009-07-10T19:11:01.103+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Sample'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Understanding Lambda Expression via Step By Step Debugging</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;Lambda Expression&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/bb882516.aspx"&gt;anonymous function&lt;/a&gt; and the likes can be difficult to understand for C# programmers, partly because they don't work in a strict procedural manner, and partly because the abstract level one has to raise in order to grasp the concept is comparatively high. Lambda expression is the&amp;nbsp;essence&amp;nbsp;of &lt;a href="http://en.wikipedia.org/wiki/Functional_programming"&gt;functional programming&lt;/a&gt;, and the ability to understand and master functional programming will make you a better programmer, or deliver killer products at a rate so fast that your competitors won't even stand half a chance to play catch up with you... &lt;a href="http://www.paulgraham.com/avg.html"&gt;if you believe in Paul Graham&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;No, this post is not about &lt;a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)"&gt;Lisp&lt;/a&gt;, or the superiority of another functional programming. This post is just a step by step step through over a simple lambda expression code, completed with screen captures, and debug values, so that hopefully at the end of this post, you will have a better understanding about what lambda expression is, and how it operates.&lt;/div&gt;&lt;br /&gt;Let me start off with a code snippet:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;public void RunTest2()&lt;br /&gt;        {&lt;br /&gt;            DisplayValue((b, h) =&amp;gt; b + h, 5.0, 10.0);&lt;br /&gt;            DisplayValue((b, h) =&amp;gt; b*h, 5.0, 10.0);&lt;br /&gt;            DisplayValue((b, h) =&amp;gt; b - h, 5.0, 10.0);&lt;br /&gt;            DisplayValue((b, h) =&amp;gt; b / h, 5.0, 10.0);&lt;br /&gt;       &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void DisplayValue&amp;lt;T, U&amp;gt;(Func&amp;lt;T , U, double&amp;gt; delegateReturnValue,&lt;br /&gt;            T input1, U input2)&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("The calculated value is " + delegateReturnValue(input1, input2));&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basically this is a subroutine to get the following output:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;The calculated value is 15&lt;br /&gt;The calculated value is 50&lt;br /&gt;The calculated value is -5&lt;br /&gt;The calculated value is 0.5&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If you don't understand what's going on, don't worry. Because I am going to show you how lambda expression works, in a step-by-step manner.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Launch your debugger, place a break point at the the first line:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/Slb9x7ic2BI/AAAAAAAAFAI/UB4U8CgljEc/s1600-h/firststep..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="292" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/Slb9x7ic2BI/AAAAAAAAFAI/UB4U8CgljEc/s400/firststep..png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Note that at this point, the &lt;b&gt;b&lt;/b&gt; and &lt;b&gt;h&lt;/b&gt; are not defined. There is really nothing to see at this stage.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Press F11, step into the &lt;b&gt;DisplayValue&lt;/b&gt; method. Note that we are stepping into &lt;b&gt;DisplayValue&lt;/b&gt;, the lambda expression we define above hasn't been executed, yet.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Slb-X0c6DOI/AAAAAAAAFAQ/pYoeDJeU0xA/s1600-h/displayValue..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Slb-X0c6DOI/AAAAAAAAFAQ/pYoeDJeU0xA/s400/displayValue..png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Note the function delegate &lt;b&gt;delegateReturnValue&lt;/b&gt;, the &lt;b&gt;T&lt;/b&gt; and &lt;b&gt;U&lt;/b&gt; refer to the type of the two inputs, respectively, and the &lt;b&gt;double&lt;/b&gt; is the return type. In this case, we dictate that the return type is a double. &lt;b&gt;delegateReturnValue&lt;/b&gt; is a function handler, meaning that instead of storing a variable, or a pointer to a variable, &lt;i&gt;it is storing a pointer to a method&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Think about this for a moment, the &lt;b&gt;delegateReturnValue&lt;/b&gt; is a pointer to a method, which means that we can invoke the method at anytime we want inside the&lt;b&gt; DisplayValue&lt;/b&gt;! So the break point, we can invoking the &lt;b&gt;delegateReturnValue&lt;/b&gt; and pass in two input parameters, in this case, it's &lt;b&gt;{input1=5.0, input2=10.0}&lt;/b&gt;. &lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Press F11 again, note that &lt;i&gt;only now&lt;/i&gt; the lambda expression is invoked:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/Slb_0wI7iLI/AAAAAAAAFAY/SFh7X7CAYHQ/s1600-h/delegateinvoked..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/Slb_0wI7iLI/AAAAAAAAFAY/SFh7X7CAYHQ/s400/delegateinvoked..png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;b&lt;/b&gt;, and &lt;b&gt;h&lt;/b&gt; assume the &lt;b&gt;input1&lt;/b&gt; and &lt;b&gt;input2&lt;/b&gt; values. The &lt;b&gt;delegateReturnValue&lt;/b&gt; is thus equivalent to the following function:&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;double PlusValue(double b, double h)&lt;br /&gt;{&lt;br /&gt;   return b+h;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But instead of declaring a function, we use lambda expression to reduce the amount of typing. &lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Press F11 again, this time you are back to the &lt;b&gt;DisplayValue&lt;/b&gt; function, in order to display the calculation result. &lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Slb-X0c6DOI/AAAAAAAAFAQ/pYoeDJeU0xA/s1600-h/displayValue..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Slb-X0c6DOI/AAAAAAAAFAQ/pYoeDJeU0xA/s400/displayValue..png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;So that's it! That's how you can see lambda expression in action!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-8679606707791919355?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8679606707791919355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8679606707791919355' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8679606707791919355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8679606707791919355'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/07/understanding-lambda-expression-via.html' title='Understanding Lambda Expression via Step By Step Debugging'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Slb9x7ic2BI/AAAAAAAAFAI/UB4U8CgljEc/s72-c/firststep..png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-6736379125330261858</id><published>2009-07-08T00:01:00.001+08:00</published><updated>2009-07-08T00:09:57.765+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><title type='text'>Gmail is Officially Out of Beta</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/SlNvf8hScvI/AAAAAAAAE_c/5dfEd4m-tjA/s1600-h/gmailbeta.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/SlNvf8hScvI/AAAAAAAAE_c/5dfEd4m-tjA/s400/gmailbeta.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;For those of you who still don't know, our much-beloved &lt;a href="http://mail.google.com/"&gt;Gmail&lt;/a&gt; is finally out of beta!! After staying in beta for 5 years, and long after &lt;a href="http://itscommonsensestupid.blogspot.com/.../why-gmail-is-better-than-yahoo.html"&gt;it vanquished other webmail clients to emerge as the best email system&lt;/a&gt;, not to mention twisting the &lt;a href="http://www.slate.com/id/2215622/"&gt;stretching the definition of beta&lt;/a&gt; to a point that the term "beta" no longer conveys any meaning, finally &lt;a href="http://gmailblog.blogspot.com/2009/07/gmail-leaves-beta-launches-back-to-beta.html"&gt;it decides to scrap the beta label&lt;/a&gt;, hurray!&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Also, I &amp;nbsp;note how hard it's to post to news aggregator sites such as &lt;a href="http://reddit.com/"&gt;reddit.com&lt;/a&gt;, &lt;a href="http://digg.com/"&gt;digg.com&lt;/a&gt; or &lt;a href="http://news.ycombinator.com/"&gt;hacker news&lt;/a&gt;. The moment I got the announcement from my rss, the link had already being posted on those aggregator sites. Internet has really taken the meaning of "breaking news" to a new level.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-6736379125330261858?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6736379125330261858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6736379125330261858' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6736379125330261858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6736379125330261858'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/07/gmail-is-officially-out-of-beta.html' title='Gmail is Officially Out of Beta'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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://3.bp.blogspot.com/_SDci0Pf3tzU/SlNvf8hScvI/AAAAAAAAE_c/5dfEd4m-tjA/s72-c/gmailbeta.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-7383362285239581924</id><published>2009-07-04T14:13:00.002+08:00</published><updated>2009-07-04T14:21:22.401+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>把悲伤留给自己</title><content type='html'>&lt;blockquote&gt;能不能让我　陪着你走　即然你说　留不住你&lt;br /&gt;回去的路　有些黑暗　担心让你　一个人走&lt;br /&gt;我想是因为　我不够温柔　不能分担　你的忧愁&lt;br /&gt;如果这样　说不出口　就把遗憾　放在心中&lt;br /&gt;把我的悲伤　留给自己　你的美丽　让你带走&lt;br /&gt;从此以后　我再没有　快乐起来的理由&lt;br /&gt;把我的悲伤　留给自己　你的美丽　让你带走&lt;br /&gt;我想我可以忍住悲伤　可不可以　你也会想起我&lt;br /&gt;是不是可以　牵你的手呢　从来没有　这样要求&lt;br /&gt;怕你难过　转身就走　那就这样吧　我会了解的&lt;/blockquote&gt;&lt;br /&gt;那一年，大概是五年前吧，我跟朋友去看《&lt;a href="http://ent.sina.com.cn/m/c/f/jianghu/"&gt;江湖&lt;/a&gt;》这部戏。那是一部怎样的烂戏啊！故事情节狗屁不通，导演用时光交错的方法来交错拍主角的命运，搞到观众一头雾水。戏散了之后，我和我朋友怔怔望着对方，不约而同的问彼此到底这部戏是讲什么？从那天起“江湖”就是烂戏的代名词。&lt;br /&gt;&lt;br /&gt;戏虽然烂，可是还是有一个亮点，就是&lt;a href="http://zh.wikipedia.org/wiki/%E6%9E%97%E8%8B%91"&gt;林苑&lt;/a&gt;在&lt;a href="http://www.youtube.com/watch?v=EP2oTOu60HY"&gt;戏中唱的一首歌&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;对了，就是这首：把悲伤留给自己。&lt;br /&gt;&lt;br /&gt;这其实是一首老歌，如果没记错应该是民歌年代所创。蔡琴唱过，陈升也唱过。&lt;a href="http://www.youtube.com/watch?v=Q1YbA-XmukM"&gt;蔡琴版本低沉婉约&lt;/a&gt;，听起来像在月光下，与爱侣互道别离，不知相见在何时。两人之间没有哭天喊地，没有大吵大闹，只有深深的遗憾。月有阴晴阳缺，人有悲欢离合。只是希望夜深人静的时候，你会想起我。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=NeEMBHcdkno&amp;amp;feature=related"&gt;陈升的版本&lt;/a&gt;感觉没有那么沉重。陈升的歌声激昂，转到低沉之处则流露出淡淡悲哀。这像是在火车站送走女友，想起过去的点点滴滴，一丝丝不舍。若干年后，当我们想起这一幕时，心里还会有点刺痛，偶而还会埋怨为何自己年少轻狂，不懂珍惜一段感情。&lt;br /&gt;&lt;br /&gt;林苑歌声活泼跳脱。在江湖那部戏里，余文乐认识了一个妓女，然后跟她发生了感情。余文乐跟她说他要去刺杀一个老大，然后最好笑的是他还说他爱她。杀手爱妓女，这当然不是普通的爱情。那妓女觉得他很傻，把他痛骂了一顿。看见他没有反应之后，突然牵着他的手往前跑，到了一间夜总会方停下。她就在他手上写了她的地址，凝视着他，忽然抱着他，哭着对他说如果还活着的话可以去那里找她。&lt;br /&gt;&lt;br /&gt;背景就是这一首歌。林苑的歌声带出了两个社会边沿人的爱情的无奈。一个逢场作戏，一个命不保夕，两人相识，激情过后，彼此对对方有了归宿感。可是命运却不允许他们在一起，所以只能把悲伤留给自己。那幕结束后我看看四周围，发现不少人在悄悄饮泣，这应该就是整部戏里面最感人的一幕了。&lt;br /&gt;&lt;br /&gt;下面就是这首歌不同的版本，希望你会喜欢。&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/15hb8iICbeg&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/15hb8iICbeg&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Q1YbA-XmukM&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Q1YbA-XmukM&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/NeEMBHcdkno&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/NeEMBHcdkno&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;忽然想起，其实还有一个民歌版本的，可是由于我找不到，所以就不在这里介绍了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-7383362285239581924?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/7383362285239581924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=7383362285239581924' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7383362285239581924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7383362285239581924'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/07/blog-post.html' title='把悲伤留给自己'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-118030910083405887</id><published>2009-06-27T11:29:00.000+08:00</published><updated>2009-06-27T11:29:09.832+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netflix'/><title type='text'>Celebrating the Achievement of Geeks--Netflix Price 10% Barrier is Finally Broken</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Netflix_Prize"&gt;Nexflix challenge&lt;/a&gt;, the challenge that is&amp;nbsp;offered to anyone or any team who can improve the current Netflix movie recommendation system by a margin of 10%, is finally over.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Two front runners in the contest, Team Pragmatic Theory and Team Bellkor, joined forces and&lt;a href="http://www.netflixprize.com/leaderboard"&gt; submitted an algorithm that was 10.05 percent better than the current system&lt;/a&gt;, that makes them eligible for the prize.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Machine learning and Artificial Intelligence have a sweet spot in me, and although I didn't join the challenge, but I also feel happy &amp;nbsp;for their&amp;nbsp;achievement.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The geeks have done a great contribution to the world, but the monetary reward they got was paltry at best. Nonetheless, I am happy to see that Nexflix challenge is finally broken.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-118030910083405887?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/118030910083405887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=118030910083405887' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/118030910083405887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/118030910083405887'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/celebrating-achievement-of-geeks.html' title='Celebrating the Achievement of Geeks--Netflix Price 10% Barrier is Finally Broken'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-7303810766886934119</id><published>2009-06-26T19:57:00.003+08:00</published><updated>2009-06-26T23:34:04.185+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='WebService'/><title type='text'>The Bugs in wsdl.exe</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/7h3ystb6(VS.80).aspx"&gt;wsdl.exe&lt;/a&gt; is a tool, come bundled with .Net SDK, that allows the generation of XML web services and XML web service clients from WSDL contract files, XSD schemas, and .discomap discovery documents. But unlike other excellent offerings from Microsoft, wsdl.exe is buggy, and is unable to handle a slightly complicated situation, let alone a real world wsdl file.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I've used wsdl.exe, and I spent 2 days of frustrating time to learn about it, wrestled with the bugs-- and I failed to get what I want. I have to write this, and hope that Microsoft people will notice and take action.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The first issue it fails to handle &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=470310"&gt;sequence with complex element&lt;/a&gt;. You would think that in today's webservice environment, a sequence of complex elements is a norm. But apparently Microsoft doesn't think so, and this results in inability of wsdl.exe to handle a sequence of complex elements.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What if you insist on using wsdl.exe to generate proxy class for element with a sequence of complex types? You will get a cryptic exception:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;unable to import binding * from namespace *&lt;/div&gt;&lt;div style="text-align: justify;"&gt;- unable to import operation *&lt;/div&gt;&lt;div style="text-align: justify;"&gt;- the datatype * is missing&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The second bug wsdl has is that &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=470482"&gt;it is not permissible to have two web methods that have the same return signature&lt;/a&gt;. Yes, if one method returns a type of ComplexType, the other methods &lt;b&gt;must&lt;/b&gt; have a different return type. Failing to do so will result in an &lt;b&gt;System.InvalidOperationException: The XML element * from namespace * references a references a method and a type&lt;/b&gt; exception. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Note that in both cases the messages are cryptic. You won't actually know what's going on behind the hood. And this is the most frustrating of all. You don't know whether you fail because the tool is lousy, or because you are not doing things right.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I would like to hear suggestion about alternative proxy code generation tool that can really handle a real world wsdl. Any ideas?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-7303810766886934119?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/7303810766886934119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=7303810766886934119' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7303810766886934119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7303810766886934119'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/bugs-in-wsdlexe.html' title='The Bugs in wsdl.exe'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5371757621289902770</id><published>2009-06-24T23:45:00.001+08:00</published><updated>2009-06-24T23:48:42.939+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>How to Encrypt a String in .Net and Decrypt it Using mcrypt_encrypt in PHP</title><content type='html'>&lt;div style="text-align: justify;"&gt;Sometimes you have to encrypt a string using .Net library, and decrypt it back in PHP, or vice versa, or across other languages. I have a webservice which is written in PHP and a .Net program that calls the webservice. In the exchange I would have to encrypt a string at .Net's end and decrypt it in PHP end.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The encryption and decryption in .Net is pretty straightforward; all you have to use is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aspx"&gt;Cryptography&lt;/a&gt; library in .Net. &amp;nbsp;Examples are abound on Internet, so you don't have to crack your head to find a working solution and modify them to suit your needs. Similarly, it's easy if you want to do encryption and decryption in PHP.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But to get encryption and decryption thing to work on different languages can be a bit tricky. I have spent quite a lot of time to make things to work. So here I am now posting my code, and hope that it will help other people.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Encryption in .Net. In this example I take a string, and convert it into encrypted hexadecimal string.&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;private static string CreateEncryptedString(string myString, string hexiv, string key)&lt;br /&gt;        {&lt;br /&gt;            RijndaelManaged alg = new RijndaelManaged();&lt;br /&gt;            alg.Padding = PaddingMode.Zeros;&lt;br /&gt;            alg.Mode = CipherMode.CBC;&lt;br /&gt;            alg.BlockSize = 16 * 8;&lt;br /&gt;            alg.Key = ASCIIEncoding.UTF8.GetBytes(key);&lt;br /&gt;            alg.IV = StringToByteArray(hexiv);&lt;br /&gt;            ICryptoTransform encryptor = alg.CreateEncryptor(alg.Key, alg.IV);&lt;br /&gt;&lt;br /&gt;            MemoryStream msStream = new MemoryStream();&lt;br /&gt;            CryptoStream mCSWriter = new CryptoStream(msStream, encryptor, CryptoStreamMode.Write);&lt;br /&gt;            StreamWriter mSWriter = new StreamWriter(mCSWriter);&lt;br /&gt;            mSWriter.Write(myString);&lt;br /&gt;            mSWriter.Flush();&lt;br /&gt;            mCSWriter.FlushFinalBlock();&lt;br /&gt;&lt;br /&gt;            var EncryptedByte = new byte[msStream.Length];&lt;br /&gt;            msStream.Position = 0;&lt;br /&gt;            msStream.Read(EncryptedByte, 0, (int)msStream.Length);&lt;br /&gt;&lt;br /&gt;            return ByteArrayToHexString(EncryptedByte);&lt;br /&gt;          &lt;br /&gt;        }&lt;br /&gt;        public static byte[] StringToByteArray(String hex)&lt;br /&gt;        {&lt;br /&gt;            int NumberChars = hex.Length;&lt;br /&gt;            byte[] bytes = new byte[NumberChars / 2];&lt;br /&gt;            for (int i = 0; i &amp;lt; NumberChars; i += 2)&lt;br /&gt;                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);&lt;br /&gt;            return bytes;&lt;br /&gt;        }&lt;br /&gt;        public static string ByteArrayToHexString(byte[] ba)&lt;br /&gt;        {&lt;br /&gt;            StringBuilder hex = new StringBuilder(ba.Length * 2);&lt;br /&gt;            foreach (byte b in ba)&lt;br /&gt;                hex.AppendFormat("{0:x2}", b);&lt;br /&gt;            return hex.ToString();&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;There is one thing to note. The key size must be 16. Which means that &lt;b&gt;key&lt;/b&gt; parameter must be a string with 16 characters. Or else the encryption won't work and will throw a &lt;a href="http://www.dotnet247.com/247reference/msgs/6/33674.aspx"&gt;System.Security.Cryptography.CryptographicException : Specified key is not a valid size for this algorithm exception&lt;/a&gt;. Also note that the &lt;b&gt;hexiv&lt;/b&gt; must be a hexadecimal string with 32 characters, meaning that every character inside the hexiv must be hexadecimal (0-9, a-f).&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;On the PHP end, here's how you do the decoding:&lt;/div&gt;&lt;pre class="brush: php"&gt;$cipher_alg = MCRYPT_RIJNDAEL_128;&lt;br /&gt;$decrypted_string = mcrypt_decrypt($cipher_alg, $key, &lt;br /&gt;$encrypted_string , MCRYPT_MODE_CBC, trim(hex2bin(trim($hexiv))));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Where &lt;b&gt;$encrypted_string&lt;/b&gt; is the encrypted string returned by the above function, and the &lt;b&gt;hexiv&lt;/b&gt; is the same as the &lt;b&gt;hexiv&lt;/b&gt; in the .Net code.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5371757621289902770?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5371757621289902770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5371757621289902770' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5371757621289902770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5371757621289902770'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/how-to-encrypt-string-in-net-and.html' title='How to Encrypt a String in .Net and Decrypt it Using mcrypt_encrypt in PHP'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-4466909354629222247</id><published>2009-06-22T19:26:00.000+08:00</published><updated>2009-06-22T19:26:35.297+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><title type='text'>Mocking and Stubbing in Javascript</title><content type='html'>&lt;div style="text-align: justify;"&gt;I have just stumbled across a &lt;a href="http://jquery.com/"&gt;JQuery&lt;/a&gt; unit testing and mocking framework that I would like to share: &lt;a href="http://code.google.com/p/jqunit/"&gt;jqunit&lt;/a&gt; and &lt;a href="http://code.google.com/p/jqmock/"&gt;jqmock&lt;/a&gt;. &lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Amid &lt;a href="http://stackoverflow.com/questions/1023569/jquery-mocking"&gt;a&amp;nbsp;plethora&amp;nbsp;of Javascript unit testing and mocking frameworks&lt;/a&gt; ( such as &lt;a href="http://docs.jquery.com/QUnit"&gt;qunit&lt;/a&gt;, &lt;a href="http://code.google.com/p/qmock/wiki/About_qMock"&gt;qmock&lt;/a&gt; etc), there seems to be only one mocking framework that's serious enough to implement the stubbing behavior, and that's jqmock. Incidently, a lack of mock framework support underscores how&amp;nbsp;undeserved&amp;nbsp;the Javascript community is.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Here's a quick demonstration on how to stub the annoying "alert" method call and verify that the message shown on the alert dialog box is correct. Let's say that we have the following requirement: When a link is clicked, a message box should pop up and say "Hello world new!". Here's the Javascript ( mainscript.js), using JQuery:&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: jscript"&gt;function hello2() {&lt;br /&gt;    alert("hello world new!");&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$(function(){&lt;br /&gt;$("a").click(hello2);&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And here's how we can test the code, using &lt;a href="http://itscommonsensestupid.blogspot.com/2008/09/testing-aspnet-mvc-using-typemock-aaa.html"&gt;AAA syntax&lt;/a&gt;:&lt;br /&gt;&lt;pre class="brush: jscript"&gt;with (jqUnit) {&lt;br /&gt;test("hello world test Me", function() {&lt;br /&gt;&lt;br /&gt;    //arrange&lt;br /&gt;    var alertMock = new jqMock.Mock(window, "alert");&lt;br /&gt;    alertMock.modify().args("hello world new!").returnValue();&lt;br /&gt; &lt;br /&gt;    //act&lt;br /&gt;    hello2();&lt;br /&gt;   &lt;br /&gt;    //assert&lt;br /&gt;    alertMock.verify();&lt;br /&gt;     &lt;br /&gt;     //clean up&lt;br /&gt;    alertMock.restore();&lt;br /&gt;&lt;br /&gt;});   &lt;br /&gt;}(jQuery);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In the arrange part, we just tell the code to look out for &lt;a href="http://www.devguru.com/Technologies/ecmascript/quickref/win_alert.html"&gt;window.alert&lt;/a&gt;, and if the argument to that method is "hello world new!", then we mock the call.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In the act part, we call the method under test, in this case, it's hello2().&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In the assert part, we check that the window.alert method is indeed called, and the argument is indeed as expected by calling the verify() method.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;jqUnit and jqMock is nice. But as far as I know it can't test &lt;a href="http://docs.jquery.com/Ajax/jQuery.getJSON"&gt;AJAX call&lt;/a&gt;, yet. I am looking forward to the inclusion of that feature.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4466909354629222247?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4466909354629222247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4466909354629222247' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4466909354629222247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4466909354629222247'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/mocking-and-stubbing-in-javascript.html' title='Mocking and Stubbing in Javascript'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-6889897784743295737</id><published>2009-06-21T17:53:00.000+08:00</published><updated>2009-06-21T17:53:01.175+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TypeMock'/><title type='text'>Typemock Racer</title><content type='html'>So, Typemock has an upcoming product for detecting &lt;a href="http://en.wikipedia.org/wiki/Deadlock"&gt;deadlock&lt;/a&gt; in parallel programming&lt;br /&gt;&lt;br /&gt;Here's the announcements:&lt;br /&gt;&lt;blockquote&gt;Typemock have launched a new&amp;nbsp;&lt;a href="http://www.typemock.com/"&gt;&lt;span style="color: black;"&gt;&lt;span style="text-decoration: none;"&gt;Unit testing&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;tool for easy&amp;nbsp;&lt;a href="http://www.typemock.com/learn_about_typemock_racer.php"&gt;&lt;span style="color: black;"&gt;&lt;span style="text-decoration: none;"&gt;deadlock detection&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;,&amp;nbsp;Typemock Racer, and for the launch they are offering a free license for bloggers who will review it.&lt;/blockquote&gt;&lt;blockquote&gt;Get the full details on&amp;nbsp;&lt;a href="http://blog.typemock.com/2009/06/easy-deadlock-detection-get-free.html"&gt;&lt;span style="color: black;"&gt;&lt;span style="text-decoration: none;"&gt;Typemock’s blog&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;.&amp;nbsp;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-6889897784743295737?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6889897784743295737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6889897784743295737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6889897784743295737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6889897784743295737'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/typemock-racer.html' title='Typemock Racer'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-6253051048497246645</id><published>2009-06-18T16:54:00.001+08:00</published><updated>2009-06-18T16:56:45.916+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firefox 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='JQuery'/><title type='text'>FireBug</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sjn7HjEURAI/AAAAAAAAE0Q/eWrDRAVKYB0/s1600-h/firebug.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sjn7HjEURAI/AAAAAAAAE0Q/eWrDRAVKYB0/s320/firebug.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;After &lt;a href="http://itscommonsensestupid.blogspot.com/2008/09/google-chrome.html"&gt;ditching Firefox in favor of Google Chrome&lt;/a&gt;, I am drawn towards Firefox, once again.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;No, I am not going back to use Firefox as my &lt;i&gt;browsing&lt;/i&gt; browser; I am using Firefox as my Javascript development. &lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Unlike server-side language ( whether it's a compiled or scripting language), the development for client-side language is often a pain to write. I remember I spent a lot of times sharing at the Javascript code, unable to figure out the error. Of course, the&lt;a href="http://pietschsoft.com/post/2008/02/JavaScript-Function-Tips-and-Tricks.aspx"&gt; inline function syntax&lt;/a&gt; doesn't help, too.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Javascript can be hard to write, and even harder to read. Take the below for example, see how many of you can identify the error:&lt;/div&gt;&lt;pre class="brush: jscript"&gt;module("core");  &lt;br /&gt;  test("getPersons", function() {&lt;br /&gt;            stop();&lt;br /&gt;            getPersons(&lt;br /&gt;&lt;br /&gt;            function(response) {&lt;br /&gt;&lt;br /&gt;                persons = $.evalJSON(response.d);                &lt;br /&gt;                equals(persons[0].FirstName, "Mohammad");&lt;br /&gt;    start();&lt;br /&gt;            }&lt;br /&gt;            );&lt;br /&gt; });&lt;br /&gt; &lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;function getPersons(callback) {&lt;br /&gt;&lt;br /&gt;    var persons = null;&lt;br /&gt;&lt;br /&gt;    $.ajax(&lt;br /&gt;&lt;br /&gt;    {&lt;br /&gt;        type: "POST",&lt;br /&gt;        dataType: "json",&lt;br /&gt;        data: "{}",&lt;br /&gt;        contentType: "application/json",&lt;br /&gt;        url: "ViewRecord/GetPersons",&lt;br /&gt;        success: function(response) {            &lt;br /&gt;            callback(response);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    );   &lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The answer is... you don't know until you run the code ( The answer can be &lt;a href="http://stackoverflow.com/questions/1004899/jquery-ajax-call-gives-404-resource-not-found-error-but-normal-url-call-is-fine"&gt;found here&lt;/a&gt;). And this is when FireBug comes into handy. You can view the error right in the Console window:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/Sjn_QvI7L7I/AAAAAAAAE0Y/U1GGDqyTCr4/s1600-h/firebugtest..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/Sjn_QvI7L7I/AAAAAAAAE0Y/U1GGDqyTCr4/s400/firebugtest..png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;No second guessing, no "&lt;a href="http://www.tizag.com/javascriptT/javascriptalert.php"&gt;alert&lt;/a&gt;" everywhere to find the error. The problem is exposed, right in front of you. And if you still can't find it you should change a pair of glass.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As browsers innovate at a furious pace, and as Javascript is going to play more and more roles in web application development, tools like Firebug is invaluable.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The only puzzle is, why is it so hard for IE, Google Chrome and Safari to come out with their own debugging tools?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-6253051048497246645?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6253051048497246645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6253051048497246645' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6253051048497246645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6253051048497246645'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/firebug.html' title='FireBug'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Sjn7HjEURAI/AAAAAAAAE0Q/eWrDRAVKYB0/s72-c/firebug.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-6989758623899240525</id><published>2009-06-13T11:12:00.002+08:00</published><updated>2009-06-13T11:13:00.117+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Why EU Software Liability Bill is Not Going to Work</title><content type='html'>&lt;div style="text-align: justify;"&gt;I almost fell off my chair when I learnt that &lt;a href="http://news.cnet.com/8301-1001_3-10237212-92.html"&gt;EU wants software makers held liable for the code&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;According to the gentlemen who are going to purpose the law: &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style="text-align: justify;"&gt;Licensing should guarantee consumers the same basic rights as when they purchase a good: the right to get a product that works with fair commercial conditions.... more accountability for software makers, and for companies providing digital services, would lead to greater consumer choice.&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;Talk about naivety. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It's not that I think software quality is not important, it's just that I don't think by enforcing a law software quality will magically improve over night. In fact, I afraid that such a law would have the perverse effect, it would kill the software industry in the end. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Yeah, I know, software quality &lt;a href="http://net.educause.edu/ir/library/pdf/NCP08083B.pdf"&gt;sucks in general&lt;/a&gt;.  But the reason why it sucks so much is not because software developers are incompetent, or the software companies are negligence. The reason why software sucks is because software, by definition, is the act exploring new things. Unlike manufacturing area where products are created according to a well-known process, software development is always about developing new requirements that haven't been done before ( If your developer has to develop the same thing over and over again like the guy in the assembly line, he's incompetent--- fire him!). Now when you have a well-known process it's easier to put a guarantee on it, but when you are venturing into unknowns it's counterproductive to do so.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Let's assume that the if software liability bill was passed, what would happen then? Software companies would have to expand their testing budget and effort, for sure. This is going to result in a massive increase in software cost and a very slow software release cycle. So if you are expecting your software to upgrade in every 3 months, you might have to wait for 1 year ( or longer) for the upgrade. Are you going to trade the upgrade for "less bugs"? &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Maybe the EU has NASA in mind when comes to software writing. NASA software that powers the space shuttle is known for its perfectness. &lt;a href="http://www.fastcompany.com/node/28121/print"&gt;The ratio of bugs, between NASA software and other commercial, is 1 to 294&lt;/a&gt;. But it's instructive to consider at what cost NASA pays to achieve this:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote style="text-align: justify;"&gt;At the on-board shuttle group, about one-third of the process of writing software happens before anyone writes a line of code. NASA and the Lockheed Martin group agree in the most minute detail about everything the new code is supposed to do -- and they commit that understanding to paper, with the kind of specificity and precision usually found in blueprints. Nothing in the specs is changed without agreement and understanding from both sides. And no coder changes a single line of code without specs carefully outlining the change. Take the upgrade of the software to permit the shuttle to navigate with Global Positioning Satellites, a change that involves just 1.5% of the program, or 6,366 lines of code. The specs for that one change run 2,500 pages, a volume thicker than a phone book. The specs for the current program fill 30 volumes and run 40,000 pages.&lt;/blockquote&gt;&lt;blockquote style="text-align: justify;"&gt;"Our requirements are almost pseudo-code," says William R. Pruett, who manages the software project for NASA. "They say, you must do exactly this, do it exactly this way, given this condition and this circumstance."&lt;/blockquote&gt;&lt;blockquote style="text-align: justify;"&gt;This careful design process alone is enough to put the shuttle organization in a class by itself, says John Munson of the University of Idaho. Most organizations launch into even big projects without planning what the software must do in blueprint-like detail. So after coders have already started writing a program, the customer is busily changing its design. The result is chaotic, costly programming where code is constantly being changed and infected with errors, even as it is being designed.&lt;/blockquote&gt;&lt;blockquote style="text-align: justify;"&gt;"Most people choose to spend their money at the wrong end of the process," says Munson. "In the modern software environment, 80% of the cost of the software is spent after the software is written the first time -- they don't get it right the first time, so they spend time flogging it. In shuttle, they do it right the first time. And they don't change the software without changing the blueprint. That's why their software is so perfect."&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;How many of you are willing to spend that much time writing specs? And how many customers are willing to PAY for that kind of specs? Who is going to develop something that no customers are willing to pay for?&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Furthermore, a lot of times software bugs are resulted from the &lt;a href="http://itscommonsensestupid.blogspot.com/2008/12/tale-of-hunting-down-elusive-bug.html"&gt;interaction between different applications&lt;/a&gt;. And in this case it can be extremely hard to pinpoint the culprit-- which applications that you are going to put your blame on? And how would the bill going to arbitrate on this? &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Software perfection can only achieved when there is a perfect understanding of requirements, but this is not how software development works. More often than not software is developed in &lt;a href="http://www.objectmentor.com/omSolutions/agile_what.html"&gt;iterative manner&lt;/a&gt;. The software vendors-- or the software users don't really know what they would get before the software is passed in their hands. And when the software doesn't perform in the way the users want that is considered as a bug. Now is it fair to penalize the software vendors because the users don't know their own requirements?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;If the EU bills were adopted, the cost of software would skyrocket, it would take a longer time to deliver the software, and software industry would become unprofitable, resulted in a massive deaths of software companies, large and small. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;That would be an ideal way to kill the human civilization.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&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/3204586232155134420-6989758623899240525?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6989758623899240525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6989758623899240525' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6989758623899240525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6989758623899240525'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/why-eu-software-liability-bill-is-not.html' title='Why EU Software Liability Bill is Not Going to Work'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5949527994072754928</id><published>2009-06-04T23:08:00.003+08:00</published><updated>2009-06-04T23:16:28.316+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Why Developers should always be Involved in Product Feedback</title><content type='html'>&lt;div style="text-align: justify;"&gt;Developers are no strangers to using other third party software. In a world where software development is expensive, the effects of bugs can be nasty, reusing well-tested third party components is the way to go. "Buy over Build" is now the generally &lt;a href="http://findarticles.com/p/articles/mi_m0SMG/is_n12_v18/ai_21130218/"&gt;the consensus&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What is less clear, among the developers at least, is whether they should invest their precious time into debugging and isolating the products defects, or write articulate letters to request features, or to &lt;a href="http://blog.asmartbear.com/blog/how-to-get-customers-who-love-you-even-when-you-screw-up.html"&gt;spend their energies to steer the products into the direction they want&lt;/a&gt;. Why, those cynics would ask, should they do something that bring no obvious benefits to themselves, other than a vague hope that one day the product vendors would incorporate their suggestions, fix their problems and respond to their need?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But from my experience, I can't disagree more with those cynics. In my view it's much better to be actively involved in the development of the products that you use, or at least to&lt;a href="http://itscommonsensestupid.blogspot.com/2008/07/tips-to-write-good-bug-report.html"&gt; report the bugs&lt;/a&gt; you face. Here are the whys:&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;It's good for the software vendors&lt;/b&gt;.&lt;br /&gt;Of course, the software vendors benefit the most when you report the bugs or send in feature suggestions. Any sensible companies with a long term goal can't afford to not listen to what the customers say. The more the bug reports, the better tested the software is. If the customers are passive, or silent, the software vendors have a reason to be scared, &lt;i&gt;very&lt;/i&gt; scared; the software is either so perfect and feature-complete that there is no complain, which is highly unlikely, or the customers have simply given up using the software or don't bother to report the bugs because "it won't make a difference anyway".&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;It's good for other users.&lt;/b&gt;&lt;br /&gt;The moment you post your bugs, workarounds, questions or suggestions on a public forum, it's there for other users to discover. And this can be invaluable. How many times you are frustrated by weird behaviors of a particular component, only to be enlightened when you typed in the cryptic error code in Google? If others are not sharing their tips or experience out of altruism, our developers life would be made harder. Much harder. If the vendors act on your reports, you are saving the users from having to lodge the same reports again in the future. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;It's good karma and you are feeling good&lt;/b&gt;.&lt;br /&gt;People recognize you if you are a frequent participant. You are recognized as an expert in one particular field. This kind of satisfaction can never be derived from money. You know that by your effort, the world is now a little bit better than before. Maybe you are not saving the world, but you are helping the little guy who's living half a globe away from you. For most of us, that kind of gratification sometimes is enough to keep our mood uplift for a full day. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;It's good for you, yes, YOU!&lt;/b&gt;&lt;br /&gt;In addition to Karma, you are also getting an improved version software at the next iteration. Now you can further save your time because the bugs that are hindering you are now removed or because new time-saving features are implemented. Not only that,  the experience of isolating bugs and reproducing them can&lt;a href="http://itscommonsensestupid.blogspot.com/2008/06/why-developers-should-do-testing.html"&gt; improve you as a developer&lt;/a&gt;. Oh,  programming jobs are seclusive; but if you are actively posting bugs and feature requests, then you won't feel &lt;i&gt;so&lt;/i&gt; lonely, for now you have a community to take care of and to fall back to. &lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;Software development is a complicated task, and we need as much help as we can, from our bosses, families and most importantly, our peers. If we are not going to help each other, if we are not reporting the bugs we saw under the pretense that "&lt;i&gt;we got something else more important to do&lt;/i&gt;", it's us who will suffer in the end.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5949527994072754928?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5949527994072754928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5949527994072754928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5949527994072754928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5949527994072754928'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/why-developers-should-always-involve-in.html' title='Why Developers should always be Involved in Product Feedback'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-1543003914469210656</id><published>2009-06-01T23:21:00.000+08:00</published><updated>2009-06-01T23:21:36.850+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>SPM JPA Appeals-- Who Got it and Who Didn't?</title><content type='html'>My sister, who &lt;a href="http://draft.blogger.com/itscommonsensestupid.blogspot.com/2009/05/open-letter-to-my-sister-and-other.html"&gt;failed in her bid to get JPA scholarship&lt;/a&gt;  , failed again in her appeal.&lt;br /&gt;&lt;br /&gt;She's not alone though, 5 of her friends-- who also scored 12A1-- also failed in their appeals.&lt;br /&gt;&lt;br /&gt;As far as I know, no one actually saw their fortune reversed after writing letters, filing complains and making rounds of trips to JPA buildings, &lt;a href="http://draft.blogger.com/www.mca.org.my/"&gt;MCA&lt;/a&gt; offices and &lt;a href="http://draft.blogger.com/sinchew.com.my/"&gt;Sinchew's daily&lt;/a&gt; office.&lt;br /&gt;&lt;br /&gt;But of course I could be wrong.&lt;br /&gt;&lt;br /&gt;So! If you are also an SM taker and you were, like my sister, turned down twice by the JPA commitee, do let a comment here, with your name and your results.&lt;br /&gt;&lt;br /&gt;I just want to know whether the cabinet is upholding it's word, i.e., whether it is really treating the appeal in transparent and meritocratic manner.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-1543003914469210656?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1543003914469210656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1543003914469210656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1543003914469210656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1543003914469210656'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/06/spm-jpa-appeals-who-got-it-and-who.html' title='SPM JPA Appeals-- Who Got it and Who Didn&apos;t?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-2759712501690188349</id><published>2009-05-23T22:04:00.002+08:00</published><updated>2009-05-23T22:11:05.736+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entrepreneurs'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Does RentACoder.com Work?</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://www.menekali.com/rent-a-coder-elance-going-to-the-slaughter-22-hours-of-work-500/"&gt;A lot of&lt;/a&gt; &lt;a href="http://discuss.techinterview.org/default.asp?biz.5.437299.12"&gt;people&lt;/a&gt; ranted against online consulting sites-  such as &lt;a href="http://www.elance.com/"&gt;Elance&lt;/a&gt;, &lt;a href="http://www.guru.com/"&gt;guru&lt;/a&gt;, &lt;a href="http://www.rentacoder.com/"&gt;RentACoder&lt;/a&gt; and so on. Of course, given that the bids on those websites are ridiculously low ( at least by developed world's standard), one would tend to assume that the quality would vary proportionally with the bids. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Whether you think those websites are cannibalizing the software craft, or whether online consulting sites are a force that flattens the world, one thing is certain: online consulting sites work.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Yes, they &lt;i&gt;do&lt;/i&gt; work.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Or else how do you explain the success of those sites? I mean, if the coding quality is so bad, if the solutions proposed are so buggy and so unusable, if the effort to need to manage the coders are so great that it outweighs the benefits, if a lot of projects are demanding unrealistic budget and time frame, how can those sites thrive, and earn themselves a place in the blogsphere discussion? They would have been wiped out long time ago by&lt;a href="http://en.wikipedia.org/wiki/Natural_selection"&gt; the principle of natural selection&lt;/a&gt;. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Although I have never used the freelance sites' service-- either as a buyer or a seller-- but by pure economical reason it's not hard to conclude that those sites fill a niche, that was previously unfilled. They work because they connect the high income buyers with the low income sellers. The high income buyers see that some of their works can  be outsourced to cheaper countries, and low income sellers see the opportunities to earn the kind of money they can't get in their countries. The globalization, and the internet bring them together. Both of the parties benefit.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This is a &lt;a href="http://www.thomaslfriedman.com/bookshelf/the-world-is-flat"&gt;flat world&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I guess when the blogsphere says that RentACoder.com doesn't work, it's saying that the price tag on it simply won't work on a developed country. It's saying that a lot of projects are unrealistic in terms of price and time.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But if you think that those projects are unrealistic, there are people-- maybe at the other side of the globe-- think otherwise. If you feel that  there are too many failed projects, please keep in mind that there are enough successes also, and those successes are powerful enough to cover for the failed ones and carry those sites.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And if you lament that the price tag is cannibalizing the software craft as a whole, do remember that money always go to the cheaper, better labor. The reason why others can provide the service at lower price and you can't, means that they are more competitive.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Although I am coming from a&lt;a href="http://www.tourismmalaysia.gov.my/"&gt; third world country&lt;/a&gt;, but I don't feel even the slightest glee. I always believe that when you underbid someone, one day someone else will in turn underbid you. This sort of underbidding business model is the last thing I want.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I am merely pointing out a fact. No matter what you feel about freelance sites, at the end of the day we still have to deal with it. It's here for real.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-2759712501690188349?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2759712501690188349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2759712501690188349' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2759712501690188349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2759712501690188349'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/does-rentacodercom-work.html' title='Does RentACoder.com Work?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-7997357090557333619</id><published>2009-05-19T09:30:00.000+08:00</published><updated>2009-05-19T09:30:02.152+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TypeMock'/><title type='text'>Typemock License with ASP.NEt Bundle</title><content type='html'>Typemock is a tool that I use for unit testing purpose. Now it's giving away free licenses!! Ho Ho!! Here's the &lt;a href="http://blog.typemock.com/2009/05/get-free-typemock-licenses-aspnet.html"&gt;message&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS'; font-size: 13px;"&gt;&lt;a href="http://www.typemock.com/" style="color: #006699;"&gt;Unit Testing&lt;/a&gt;&amp;nbsp;ASP.NET?&amp;nbsp;&lt;a href="http://www.typemock.com/ASP.NET_unit_testing_page.php" style="color: #006699;"&gt;ASP.NET unit testing&lt;/a&gt;&amp;nbsp;has never been this easy.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;Typemock is launching a new product for ASP.NET developers – the&amp;nbsp;ASP.NET Bundle&amp;nbsp;- and for the launch will be giving out&amp;nbsp;FREE licensesto bloggers and their readers.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both&amp;nbsp;&lt;a href="http://www.typemock.com/"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;Typemock Isolator&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;, a&amp;nbsp;&lt;a href="http://www.typemock.com/"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;unit test&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp;tool and&amp;nbsp;&lt;a href="http://sm-art.biz/Ivonna.aspx"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;Ivonna&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;, the Isolator add-on for&amp;nbsp;&lt;a href="http://sm-art.biz/Ivonna.aspx"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;ASP.NET unit testing&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;, for a bargain price.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Typemock Isolator is a leading&amp;nbsp;&lt;a href="http://www.typemock.com/"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;.NET unit testing&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp;tool (C# and VB.NET) for many ‘hard to test’ technologies such as&amp;nbsp;&lt;a href="http://typemock.com/sharepointpage.php"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;SharePoint&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;,&amp;nbsp;&lt;a href="http://www.typemock.com/ASP.NET_unit_testing_page.php"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;ASP.NET&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;,&lt;a href="http://www.typemock.com/ASP.NET_unit_testing_page.php"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;MVC&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;,&amp;nbsp;&lt;a href="http://www.typemock.com/wcfpage.php"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;WCF&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;, WPF,&amp;nbsp;&lt;a href="http://www.typemock.com/Silverlight_unit_testing_page.php"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;Silverlight&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp;and more. Note that for&amp;nbsp;&lt;a href="http://www.typemock.com/Silverlight_unit_testing_page.php"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;unit testing Silverlight&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp;there is an open source Isolator add-on called&amp;nbsp;&lt;a href="http://www.typemock.com/Silverlight_unit_testing_page.php"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;SilverUnit&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;The first 60 bloggers who will blog this text in their blog and&amp;nbsp;&lt;a href="http://blog.typemock.com/2009/05/get-free-typemock-licenses-aspnet.html"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;tell us about it&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET&amp;nbsp;dedicated&amp;nbsp;blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Also 8 bloggers will get an&amp;nbsp;additional 2 licenses&amp;nbsp;(each) to give away to their readers / friends.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Go ahead, click the following link for&amp;nbsp;&lt;a href="http://blog.typemock.com/2009/05/get-free-typemock-licenses-aspnet.html"&gt;&lt;span style="color: black;"&gt;&lt;span class="Apple-style-span" style="text-decoration: none;"&gt;more information&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;on how to get your free license.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-7997357090557333619?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/7997357090557333619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=7997357090557333619' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7997357090557333619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7997357090557333619'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/typemock-license-with-aspnet-bundle.html' title='Typemock License with ASP.NEt Bundle'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5332843277862582408</id><published>2009-05-18T20:57:00.003+08:00</published><updated>2009-05-18T21:10:33.857+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WolframAlpha'/><category scheme='http://www.blogger.com/atom/ns#' term='google services'/><category scheme='http://www.blogger.com/atom/ns#' term='Cuil'/><title type='text'>WolframAlpha is NOT Another Cuil</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/ShFaK0yG-tI/AAAAAAAAEwo/4qwVTfCbg5s/s1600-h/saupload_wolfram.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/ShFaK0yG-tI/AAAAAAAAEwo/4qwVTfCbg5s/s400/saupload_wolfram.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;When &lt;a href="http://www.wolframalpha.com/"&gt;WolframAlpha&lt;/a&gt; was first announced, there were serious concern that it would be another &lt;a href="http://www.cuil.com/"&gt;Cuil&lt;/a&gt; ( you &lt;span style="font-style: italic;"&gt;do&lt;/span&gt; remember Cuil, don't you?)-- another purported &lt;a href="http://itscommonsensestupid.blogspot.com/2008/07/cuil-google-killer.html"&gt;Google Killer&lt;/a&gt; that turned up to be a spectacular failure. For those of you who were born after Cuil came to earth, Cuil was setup by ex-Googlers and it boasts over the biggest index of webs in the world, beating even that of Google. But the first day launch was a disaster; the Cuil servers couldn't handle all the loads, the results returned were less than irrelevant, the pictures and the contents didn't match, and so on and so on.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;WolframAlpha &lt;a href="http://www.shortnews.com/start.cfm?id=78760"&gt;launched a few days ago &lt;/a&gt;, and Internet went abuzz over it. The news aggregator sites, such as &lt;a href="http://reddit.com/"&gt;reddit&lt;/a&gt; and &lt;a href="http://news.ycombinator.com/"&gt;hacker news&lt;/a&gt; , as usual, were skeptical. Users derided it because it couldn't do the things Google could do; and some who are more vociferous took this opportunities to complain about &lt;a href="http://www.stephenwolfram.com/"&gt;Stephen Wolfram&lt;/a&gt; 's characters. I spent a few hours playing with it and found that while it returned good results for certain queries, it couldn't do that for all queries and there were a few instances when WolframAlpha crashed my browser.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But despite the all shortcomings in WolframAlpha, despite whatever you want to say about Stephen Wolfram's characters, one thing is certain: WolframAlpha is &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; Cuil.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Far from it.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First of all, WolframAlpha is &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; a search engine, it's a computational engine, it's a giant calculator, it's an AI machine that can specifically ( or is supposed to  be able to) understand human query and answer it, not returning a list of links. By contrast, Cuil operates pretty much in the same way as Google, that is to return the most relevant links based on the keywords. I come to Google ( or Cuil) to go to the sites I want to, but I come to WolframAlpha to have my computational needs answered. That's a very big difference.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Cuil competes directly with Google. And here the problem lies; the moment you compare yourself to the giant, and purport that you can beat the giant at its own game, &lt;a href="http://www.businessinsider.com/2008/7/would-be-google-killer-cuil-stumbles-out-of-the-gate-long-term-looks-grim-too"&gt;people expectation is that your performance has to exceed or at least be on par with the giant&lt;/a&gt;.Cuil got crushed by this kind of expectation. Even if it could recover from the crash it  would still have to face Google as its main competitor, which was unpleasant to say the least.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;WolframAlpha, on the other hand, does not compete directly with Google. Rather it compliments Google and fill a niche where Google is absent. Want to get quick answer to your &lt;a href="http://www01.wolframalpha.com/input/?i=integrate+x"&gt;calculus problem&lt;/a&gt;? Check WolframAlpha. Want to know &lt;a href="http://www01.wolframalpha.com/input/?i=convert+pound+to+usd&amp;amp;asynchronous=false&amp;amp;equal=Submit"&gt;foreign exchange rate&lt;/a&gt;? Consult WolframAlpha.What about &lt;a href="http://www38.wolframalpha.com/input/?i=genome"&gt;genome sequence lookup&lt;/a&gt;? WolframAlpha could handle that too. WolframAlpha is like an expert system where you can get direct answers from.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Second,  Cuil is funded by angel investors, so the founders don't have 100% control over it. The investors are always impatient; the well being of the business they fund is the least of their concern, what they really care is how can they maximize their returns in the shortest time. So in addition to the competition with Google, Cuil is competing against time as well. If Cuil can't deliver in a few years time, the investors could have lost patient and could call the whole thing off.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;WolframAlpha is backed by the funds of an immensely popular symbolic software call &lt;a href="http://www.wolfram.com/mathematica/"&gt;Mathematica&lt;/a&gt;. So Stephen Wolfram and his team of scientists could have full control over it because they don't need to seek outside investment and answer to external shareholders whose interest may not be aligned with the company's long term interest. WolframAlpha could stay as long as Wolfram likes. I believe that Wolfram would stay true to the course of WolframAlpha because it's something that he personally holds dear to-&lt;a href="http://www.hplusmagazine.com/articles/ai/wolframalpha-searching-truth"&gt; to understand the universe through computation&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Third, Cuil doesn't have a viable business model other than advertising programs. Unfortunately internet advertisement is such a Winner-Take-All game that only a handful can make money out of it. If Cuil couldn't end up to be the top few dogs, it would have to find an exit strategy or go burst. The revenue stream of Cuil is extremely limited, and company with limited income channels is likely to get burst in hard times.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;On the other hand, the monetization of WolframAlpha needs not be to restricted to advertising programs. WolframAlpha could, for example, sell its service to banks, hedge funds, universities, government sectors, intelligence agencies for a hefty price. WolframAlpha could adopt a part-advertising-part-subscription model that so many successful ventures have adopted. In hard times, when advertising budget shrinks, you will find that those who have a steady subscription base can survive and thrive.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;WolframAlpha is not another Cuil, and it's not a Google Killer. It needs not to be, because it's not playing the game Google is playing.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5332843277862582408?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5332843277862582408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5332843277862582408' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5332843277862582408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5332843277862582408'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/wolframalpha-is-not-another-cuil.html' title='WolframAlpha is NOT Another Cuil'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/ShFaK0yG-tI/AAAAAAAAEwo/4qwVTfCbg5s/s72-c/saupload_wolfram.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-7136336673155543170</id><published>2009-05-15T19:58:00.000+08:00</published><updated>2009-05-15T19:58:00.836+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FogBugz'/><title type='text'>FogBugz Screenshot-- A Free Screen Capture Software</title><content type='html'>&lt;div style="text-align: justify;"&gt;It was amazingly hard to find a decent, free screen capturing software. &lt;a href="http://www.faststone.org/FSCaptureDetail.htm"&gt;FastStone Capture&lt;/a&gt; is a good piece of software, but unfortunately it turned into a paying application when it gained sufficient popularity.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But still, there are a few free screen capture software available, although it can be a bit hard to find them, as they are not&amp;nbsp;reachable&amp;nbsp;within a few Google search.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So, to save you from frustration, let me introduce you&amp;nbsp;&lt;a href="http://our.fogbugz.com/default.asp?W988"&gt;Fogbugz Screenshot tool&lt;/a&gt;, which is a screen capturing tool from the courtesy of &lt;a href="http://www.fogcreek.com/FogBUGZ/"&gt;FogBugz&lt;/a&gt;. Fogbugz screenshot tool is a windows service, it loads up when your Windows boots up and so you don't have to find it when you need it. It's right there, at the bottom right corner.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/SgvDTkB2hII/AAAAAAAAEwY/T13FgI-56DY/s1600-h/fogbugztool..png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/SgvDTkB2hII/AAAAAAAAEwY/T13FgI-56DY/s400/fogbugztool..png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&amp;nbsp;You can download it&amp;nbsp;&lt;a href="http://our.fogbugz.com/default.asp?pg=pgDownload&amp;amp;pgType=pgWikiAttachment&amp;amp;ixAttachment=3975&amp;amp;sFileName=FogBugzScreenshotSetup.zip"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;FogBugz screenshot 1.0 didn't have a "Save to File" option. But thankfully FogBugz people listened to the popular demand, so now you can use it just like any other screen capturing tool!&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://www.bugshooting.com/web/"&gt;BugShooting&lt;/a&gt;&amp;nbsp;is also one of the free screen capture software, though I haven't try it yet.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-7136336673155543170?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/7136336673155543170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=7136336673155543170' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7136336673155543170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7136336673155543170'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/fogbugz-screenshot-free-screen-capture.html' title='FogBugz Screenshot-- A Free Screen Capture Software'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SgvDTkB2hII/AAAAAAAAEwY/T13FgI-56DY/s72-c/fogbugztool..png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-4445395167573877746</id><published>2009-05-14T19:59:00.001+08:00</published><updated>2009-05-14T20:06:10.741+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spam'/><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><title type='text'>Gmail Spam Filter Says Emails from Gmail are Spam</title><content type='html'>&lt;a href="http://itscommonsensestupid.blogspot.com/2009/03/why-gmail-is-better-than-yahoo.html"&gt;Gmail is great&lt;/a&gt;, sure, and everyone who's using &lt;a href="http://mail.yahoo.com/"&gt;Yahoo&lt;/a&gt; or &lt;a href="http://www.hotmail.com/"&gt;Hotmail&lt;/a&gt; should switch to it. One area that Gmail excels is spam filtering, &lt;a href="http://itscommonsensestupid.blogspot.com/2008/05/new-kind-of-spam.html"&gt;I don't get spam nowadays&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The only thing is that sometimes the spam filter can be overzealous, see the below image for yourself.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SgwHgQ35WmI/AAAAAAAAEwg/nnl1Vv0Vqu0/s1600-h/gmail_is_spam.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="316" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SgwHgQ35WmI/AAAAAAAAEwg/nnl1Vv0Vqu0/s400/gmail_is_spam.jpg" width="400" /&gt;&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/3204586232155134420-4445395167573877746?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4445395167573877746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4445395167573877746' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4445395167573877746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4445395167573877746'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/gmail-spam-filter-says-emails-from.html' title='Gmail Spam Filter Says Emails from Gmail are Spam'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SgwHgQ35WmI/AAAAAAAAEwg/nnl1Vv0Vqu0/s72-c/gmail_is_spam.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-4000035372959571209</id><published>2009-05-13T21:55:00.001+08:00</published><updated>2009-05-13T21:57:43.764+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>An Open Letter to My Sister ( and Other Failed JPA Contenders)</title><content type='html'>&lt;div style="text-align: justify;"&gt;Dear sis,&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I am very proud of you, of your achievement in SPM ( British System O-level equivalent) . You scored 12 A1, a feat that was equaled and surpassed only by some 300 SPM candidates out  of 40000 exam takers. That placed you at the top of 0.75% of all SPM takers. Well done!&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;With such a result you aimed for &lt;a href="http://www.malaysia-scholarship.com/jpa.html"&gt;JPA scholarhsip&lt;/a&gt;, a scholarship given by Malaysian government to bright, hardworking SPM students to further their studies in local or overseas universities. According to the news source 4000 scholarships would be awarded this year, so since your result is definitely better than the median of all scholarship recipients, I felt that you had a good chance to get one. Of course, I had have some reservation, because JPA scholarship is always competitive, and there wasn't a single year whereby we didn't hear any controversies.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But I believe you put in your best effort, as you always did, when preparing for interviews. And at the end of that you seemed confident. The only thing is when the results were announced, you and I were deeply surprised, and dejected. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Despite your best effort, despite your excellent results, despite the status of our family ( JPA gives special consideration for candidates from poorer background and East Malaysia, both of which we are qualified for), you failed to secure a scholarship. On the day the news broke out, you were very angry, and puzzled by the criteria the JPA chose its candidates. You asked me why your friends, who did worse than you in the SPM exams earn a scholarship but you didn't. Although you conveyed your message in emails, but I could clearly feel the resentment, and the sense of being victimized.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I know you are angry, you are sad, you feel that this shouldn't be happening to you, that the world is unfair and the JPA people are either blind or not being impartial as they claim they are. It might disappoint you that this post is not a chorus to lambast  JPA and Malaysia government. But let me tell you something: this world, my sister, is &lt;i&gt;always&lt;/i&gt; unfair. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Yes, this is a cruel world, with no justice, with no fairness.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I can tell you thousands of injustice that were happening, or are happening right now. But let me just give you a few examples. You watch soccer? I bet your don't. But let me just cite the example anyway. There is a soccer team in England, call &lt;a href="http://www.chelseafc.com/"&gt;Chelsea&lt;/a&gt;, which is bankrolled by a billionaire named &lt;a href="http://en.wikipedia.org/wiki/Roman_Abramovich"&gt;Roman Abramovich&lt;/a&gt;. The sole purpose of Abramovich acquiring Chelsea in 2004 was to transform it from a team of debt into a team of silverware. Last year, 2008 was the year Abramovich came agonizingly close to achieving his goal. Chelsea won four runner-ups. In the EPL they were second to &lt;a href="http://www.manutd.com/"&gt;Manchester United&lt;/a&gt;. And in the European Champion's league final they were beaten by Man Utd again, this time in penalty shootout. The sad thing for Chelsea fan was, they could have won both, if only lady luck slided with them.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Before the last game of EPL, Chelsea and Man-Utd were tied in their points. So whoever won the last game won the championship. When the first half ended, Chelsea was leading 1-0 and Man Utd was lucky not to concede a penalty-- the referee erred by not awarding a penalty against Man Utd. A resilient Man Utd fought back in second half and scored two goals that effectively secured the championship, whereas Chelsea conceded a late goal after knowing that Man Utd wrapped up the game. Chelsea fans asked themselves what happened that day? They lost not because they weren't good-- they lost because someone else made a mistake and their opponent seized the chance.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As if things weren't bad enough, a week later Chelsea and Man Utd met again, this time in European Championship. The game was lackluster, with both team waiting for penalty shootout. Man Utd missed a penalty first, and if John Terry, Chelsea's captain could score the goal, Chelsea would win the championship.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But Terry stumbled; he missed the penalty and sent Chelsea to hell. Just imagine, if only John Terry could be his old, cool self, if only the goal post was a little bit wider, things could have been very different.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So, Chelsea ended up with 4 runner-ups, despite that they should really deserve better. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As if that wasn't enough, Chelsea lost out to Barcelona in the semis this year, thanks to the referee who consistently made critical mistakes in favor of Barcelona.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What I am telling you is that this life, as we experience it, is never fair. Things don't work in the way we want. We lack the luck the very moment we need it. And the even if we are the best we may not actually win! It's just a fact that we must get over, and overcome.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;You didn't get a scholarship, that's fine, and if you failed in your appeal, so be it. Just tell you yourselves this: don't ever let this kind of thing happen to your loves once, ever. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Do your best to control your destiny. Don't trust in luck, don't trust in other people, don't simply believe in the assurance of other parties because they can fail. And don't put your fate into a screwed and skewed system.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Instead, equip yourself, fight your way up and out. You don't give me a scholarship? Fine! I will find ways to complete my studies, and I will make sure that my kids don't have to go through the kind of torment I went through, and that they can go to &lt;a href="http://www.harvard.edu/"&gt;Harvard&lt;/a&gt; or &lt;a href="http://www.princeton.edu/"&gt;Princeton&lt;/a&gt; as long as they qualify without worrying about money because &lt;i&gt;I can provide them with adequate financial support&lt;/i&gt;. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Tell yourself that you will do everything to stop your kids from facing this kind of discrimination. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Tell yourself that you won't be trumped by injustice and unfairness. You are going to fight back-- &lt;i&gt;you have to!&lt;/i&gt;-- by being self-reliance.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;You can make it.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;From,&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Your bro.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4000035372959571209?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4000035372959571209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4000035372959571209' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4000035372959571209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4000035372959571209'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/open-letter-to-my-sister-and-other.html' title='An Open Letter to My Sister ( and Other Failed JPA Contenders)'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-9021876376926407366</id><published>2009-05-06T00:41:00.003+08:00</published><updated>2009-06-12T10:23:16.055+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Symfony'/><title type='text'>Move Symfony Framework Out of Sandbox Application</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://www.symfony-project.org/get/sf_sandbox_1_2.tgz"&gt;Symfony Sandbox archive&lt;/a&gt; is good for prototyping and evaluation purpose.&amp;nbsp;Although&amp;nbsp;this is not a good practice, but sometimes developers will just hack the Sandbox and turn it into a full fledge web application. And they will regret later when they find that they need to upgrade their Symfony core engines because all the Symfony core files are mixing together with the web app files and there is no way to know which files are Symfony files and which are generated files and which are application-specific files.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I ran into the same problem myself. Initially I was just thinking about playing with Symfony. So I got the Sandbox version and played with it. Little did I realize that the toy application gradually turned into a full web application. And I realized that Symfony has been upgrading the framework at a frantic pace. Not wanting to miss all the new features and bug fixes, I had to do some restructuring to keep the Symfony framework out from my core application.&lt;/div&gt;&lt;br /&gt;Here are the steps that I did:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;First, you need to have &lt;a href="http://pear.php.net/"&gt;PEAR package&lt;/a&gt; installed. If you are using PHP installer, &lt;a href="http://stackoverflow.com/questions/824050/install-pear-extension-with-php-installer"&gt;you need to turn on the PEAR extension during the Installation process&lt;/a&gt;. After that, you must &lt;a href="http://pear.php.net/manual/en/installation.getting.php"&gt;install PEAR package manager&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Now, you must install the &lt;a href="http://www.symfony-project.org/book/1_2/03-Running-Symfony"&gt;PEAR Symfony package&lt;/a&gt;. The way to do this is to:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;pear channel-discover pear.symfony-project.com&lt;br /&gt;pear install symfony/symfony&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;You can check the Symfony version by typing in the following command, make sure it's the latest, and that the Symfony file path is correct. In my case it's "C:\Program Files\PHP\PEAR\Symfony"&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;symfony -V&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;OK, so now you have the correct Symfony framework setup at the correct place. It's time to delete the Symfony framework inside your sandbox application. To do this, delete the following folders:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Sandbox_App/data/Symfony&lt;/li&gt;&lt;li&gt;Sandbox_App/doc/Symfony&lt;/li&gt;&lt;li&gt;Sandbox_Ap/lib/Symfony&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Now, go to Sanbox_App/config/ProjectConfiguration.class.php, rename &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;require_once dirname(__FILE__).'/../lib/symfony/autoload/sfCoreAutoload.class.php';&lt;br /&gt;&lt;/pre&gt;to &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;require_once 'C:\Program Files\PHP\PEAR\symfony\autoload\sfCoreAutoload.class.php';&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;cd to the Sandbox_App directory, rebuild the model, forms, fitlers, and clear the cache using the following command:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;$ php symfony propel:build-model&lt;br /&gt;php symfony propel:build-forms&lt;br /&gt;php symfony propel:build-filters&lt;br /&gt;php symfony cache:clear&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;That's it! You have successfully move Symfony framework out of Sandbox Application!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-9021876376926407366?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/9021876376926407366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=9021876376926407366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/9021876376926407366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/9021876376926407366'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/move-symfony-framework-out-of-sandbox.html' title='Move Symfony Framework Out of Sandbox Application'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-3763344312778985376</id><published>2009-05-02T22:21:00.002+08:00</published><updated>2009-06-15T21:20:29.885+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><title type='text'>Run SQL file from PHP</title><content type='html'>&lt;div style="text-align: justify;"&gt;Sometimes you will have to call a predefined .sql file in order to setup database and populate the initial database schema, instead of calling &lt;a href="http://my.php.net/function.mysql-query"&gt;mysql_query&lt;/a&gt; from the PHP script. The most straight forward way to do this is to invoke the &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/mysql.html"&gt;MySQL command line&lt;/a&gt;&amp;nbsp;and pass in the .sql file.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But this is not really preferable if you have to distribute your web applications to your customers because you can't expect them to understand all the intricacies of setting up MySQL databases. The best way is to wrap all these commands in PHP code &amp;nbsp;under install.php so that the users don't have to know what's under the hood. An amazingly, calling MySQL command line from PHP proved to be a troublesome thing for me. So I am blogging here just to help those who might need some help.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I ran across &lt;a href="http://feelitfresh.com/web20/run-or-execute-sql-file-using-php/"&gt;here&lt;/a&gt; where there is a PHP script that contains the necessary code to run .sql file. This post uses &lt;a href="http://www.php.net/function.exec"&gt;exec()&lt;/a&gt; method to call the MySQL command line. But unfortunately it doesn't work on Windows. So I actually asked around for help, and neither &lt;a href="http://stackoverflow.com/questions/814586/calling-mysql-exe-using-php-exec-doesnt-work"&gt;StackOverflow&lt;/a&gt; nor &lt;a href="http://serverfault.com/questions/3089/calling-mysql-exe-using-php-exec-doesnt-work"&gt;ServerFaul&lt;/a&gt;t users offered a correct answer. But luckily after some trying I managed to get it to work.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here's the code that is guaranteed to work... on my Windows machine.&lt;br /&gt;&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;  $dbhost = 'localhost';&lt;br /&gt;  $dbuser = 'root';&lt;br /&gt;  $dbpass = 'password';&lt;br /&gt;  $db = 'job';&lt;br /&gt;  $file =dirname(__FILE__).'\\'.'job_create.sql';&lt;br /&gt;  $mySQLDir='"C:\\Program Files\\MySQL\\MySQL Server 5.1\\bin\\mysql.exe"';&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    if ($dbpass != '') {&lt;br /&gt;        $cmd = $mySQLDir.' -h '.$dbhost.' --user='.$dbuser.' --password='.$dbpass.' &amp;lt; "'.$file.'"';&lt;br /&gt;&lt;br /&gt;    } else {&lt;br /&gt;        $cmd = $mySQLDir.' -h '.$dbhost.' --user='.$dbuser.' &amp;lt; "'.$file.'"';&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;     echo $cmd;  &lt;br /&gt;&lt;br /&gt;   exec('"'.$cmd.'"',$out ,$retval);&lt;br /&gt;   echo "\n";&lt;br /&gt;    echo ($retval);&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hopefully this code is useful to you as well!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3763344312778985376?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3763344312778985376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3763344312778985376' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3763344312778985376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3763344312778985376'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/run-sql-file-from-php.html' title='Run SQL file from PHP'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-7866585208895721248</id><published>2009-05-01T19:33:00.001+08:00</published><updated>2009-05-01T19:33:57.364+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Drupal'/><title type='text'>How Difficult It is to Find a Decent Drupal Theme?</title><content type='html'>&lt;div style="text-align: justify;"&gt;How difficult it is to find a decent and free &lt;a href="http://drupal.org/"&gt;Drupal&lt;/a&gt; theme?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Answer: very, very difficult.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I want to find a decent Drupal theme for my website, similar to &lt;a href="http://demosite.worthapost.com/?theme=endless_news"&gt;something like this&lt;/a&gt;:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SfrV36R5IoI/AAAAAAAAEtg/zKn2HkJn3eU/s1600-h/worthapost.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SfrV36R5IoI/AAAAAAAAEtg/zKn2HkJn3eU/s400/worthapost.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;My requirements are simple, all I need are:&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;the ability to put the login block, and the user information menu at the top of the screen.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;the ability to put a menu constructed using &lt;a href="http://drupal.org/project/nice_menus"&gt;nice menu&lt;/a&gt; mode, at the content top area.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;A theme that supports both 2 and 3 column layout&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Pretty simple requirements, aren't they?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So I began my quest to search for such a free template. I thought that given the popularity of Drupal, finding such a simple theme shouldn't be so difficult. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I was wrong.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;True, there are a lot of &lt;a href="http://drupal2u.com/"&gt;free&lt;/a&gt; &lt;a href="http://themegarden.org/drupal6/"&gt;themes&lt;/a&gt; out there; true, those free themes look great on demo. The only thing is, when you really apply them on your websites, they suck. Either the menus are not arranged properly, or the themes aren't compatible with &lt;a href="http://drupal.org/project/nice_menus"&gt;nice menu modules&lt;/a&gt; or other modules, or there isn't enough block space to hold my menus.  In short, there is not a single free theme that looks great on my site, and I bet there is not a single news website can have &lt;i&gt;any&lt;/i&gt; use of the available free Drupal theme. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So I am turning to premium drupal theme sites; they are quite a &lt;a href="http://fordrupal.com/"&gt;couple&lt;/a&gt; &lt;a href="http://www.themeshark.com/"&gt;of&lt;/a&gt; &lt;a href="http://www.topnotchthemes.com/"&gt;Drupal&lt;/a&gt; &lt;a href="http://www.themesnap.com/"&gt;theme&lt;/a&gt; sites, and the pricing scheme isn't cheap. The price can range from USD 70 to USD 300. For a country which per capital income &lt;a href="http://www.aseanaffairs.com/page/malaysia/economy%20malaysia%20ranks%20six%20in%20per%20capita%20gdp%20in%20asia-pacific"&gt;is just USD 7511&lt;/a&gt;, such a price tag is considered pricey, to say the least. So I need to make sure that if I buy a theme, I must be able to apply it.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Unfortunately the terms and conditions of those premium Drupal sites don't inspire confidence in me. There is no such a thing as try-before-you-buy, and there is no guarantee that they will do slight modification to the theme so that it works with your site layout. In other words it seems that the them sellers don't provide  technical support beyond installation help. How can you expect me to shell out my money for something that I have no confidence in?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So basically this post is a call for help. If anyone knows of a Drupal theme site that you are satisfied with, do let me know. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-7866585208895721248?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/7866585208895721248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=7866585208895721248' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7866585208895721248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7866585208895721248'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/05/how-difficult-it-is-to-find-decent.html' title='How Difficult It is to Find a Decent Drupal Theme?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SfrV36R5IoI/AAAAAAAAEtg/zKn2HkJn3eU/s72-c/worthapost.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-2097168127354813403</id><published>2009-04-23T11:28:00.000+08:00</published><updated>2009-04-23T11:28:34.491+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google services'/><title type='text'>Google Me ( or Google Suggest) Going Nuts</title><content type='html'>Sometimes something as mighty as Google can also make funny suggestion:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Se_fNQFHFdI/AAAAAAAAEsw/K4Ed7EkegAo/s1600-h/google+me.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Se_fNQFHFdI/AAAAAAAAEsw/K4Ed7EkegAo/s400/google+me.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I wanted to know how &lt;a href="http://googleblog.blogspot.com/2009/04/search-for-me-on-google.html"&gt;Google "Me" feature works&lt;/a&gt;&amp;nbsp;, so I typed in &lt;a href="http://www.google.com.my/search?hl=en&amp;amp;rlz=1C1GGLS_enMY291MY303&amp;amp;q=google+me&amp;amp;btnG=Search&amp;amp;meta="&gt;Google Me&lt;/a&gt; in the query box.... and that's what I got. Google seems to think that I am related to &lt;a href="http://www.google.com.my/search?hl=en&amp;amp;rlz=1C1GGLS_enMY291MY303&amp;amp;q=teyana+taylor&amp;amp;revid=1073322997&amp;amp;ei=Hd3vSejzGovq6gPL27XpAw&amp;amp;sa=X&amp;amp;oi=revisions_narrow&amp;amp;resnum=4&amp;amp;ct=revision&amp;amp;cd=1"&gt;Teyana Taylor&lt;/a&gt;.... It's just me, or everyone who types in the same query gets the same result?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-2097168127354813403?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2097168127354813403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2097168127354813403' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2097168127354813403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2097168127354813403'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/04/google-me-or-google-suggest-going-nuts.html' title='Google Me ( or Google Suggest) Going Nuts'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Se_fNQFHFdI/AAAAAAAAEsw/K4Ed7EkegAo/s72-c/google+me.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-378327317844167649</id><published>2009-04-19T23:29:00.002+08:00</published><updated>2009-04-19T23:48:06.754+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Drupal'/><title type='text'>Passing Arguments from Panel to Views in Drupal</title><content type='html'>As ridiculous as it sounds, passing arguments from panel to views in &lt;a href="http://drupal.org/drupal-6.0"&gt;Drupal 6&lt;/a&gt; is a very, very difficult job, &lt;a href="http://groups.drupal.org/node/9770"&gt;judging from the responses collected from the official Drupal Forum&lt;/a&gt;. I myself spent quite a lot of times wrestling over it. So I think it's worthwhile for me to post the solution.&lt;br /&gt;&lt;br /&gt;Here's how you can pass an argument from a panel to a view in Drupal.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;First of all, of course you need to have &lt;a href="http://drupal.org/project/views"&gt;Views Module&lt;/a&gt; and &lt;a href="http://drupal.org/project/panels"&gt;Panels Module&lt;/a&gt; installed. &lt;/li&gt;&lt;li&gt;Go to &lt;i&gt;admin/build/views&lt;/i&gt;, choose the &lt;b&gt;View&lt;/b&gt; you want to edit. Assuming that in this case, you want to define &lt;a href="http://drupal.org/node/299"&gt;Taxonomy&lt;/a&gt; Term as the argument. So you will have to define the Arguments field as follows ( here's &lt;a href="http://itscommonsensestupid.blogspot.com/2009/03/create-menu-link-to-particular-node.html"&gt;a tutorial on how to define a View&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/Ses_tvRxtqI/AAAAAAAAErg/POwe_84l4Qs/s1600-h/drupal+taxonomy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/Ses_tvRxtqI/AAAAAAAAErg/POwe_84l4Qs/s400/drupal+taxonomy.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Now, go to your &lt;b&gt;Panels&lt;/b&gt; page ( &lt;i&gt;admin/panels/panel-page&lt;/i&gt;), Set the &lt;b&gt;Path&lt;/b&gt; at the &lt;b&gt;Settings&lt;/b&gt; tab as &lt;b&gt;faculty/%&lt;/b&gt;. This means that the term after &lt;i&gt;faculty/&lt;/i&gt; will be the argument. For example, if your URL is &lt;i&gt;faculty/ab&lt;/i&gt;&lt;i&gt;c&lt;/i&gt;, then &lt;i&gt;abc&lt;/i&gt; will be the argument.&lt;/li&gt;&lt;li&gt;Go to the &lt;b&gt;Context&lt;/b&gt; tab, at the &lt;b&gt;Arguments&lt;/b&gt; section, choose &lt;b&gt;Taxonomy Term&lt;/b&gt;, and click &lt;b&gt;Add argument.&lt;/b&gt; At the Edit argument form, set the &lt;b&gt;Identifier&lt;/b&gt; as &lt;b&gt;"my term"&lt;/b&gt;, and the &lt;b&gt;keyword&lt;/b&gt; as &lt;b&gt;"term"&lt;/b&gt;. Set the &lt;b&gt;Argument type&lt;/b&gt; as &lt;b&gt;"Term name"&lt;/b&gt;, as shown below:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SetAyqHp-FI/AAAAAAAAEro/4qzqBPV14-o/s1600-h/drupal+edit+argument.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SetAyqHp-FI/AAAAAAAAEro/4qzqBPV14-o/s320/drupal+edit+argument.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Click OK.&lt;/li&gt;&lt;li&gt;Go to &lt;b&gt;Content&lt;/b&gt; tab, Select the &lt;b&gt;View&lt;/b&gt; that you defined in step 1, make sure you choose the &lt;b&gt;panel pane&lt;/b&gt; selection.&lt;/li&gt;&lt;li&gt;At the Configure Panel pane form, make sure you choose "&lt;b&gt;No context&lt;/b&gt;" as the &lt;b&gt;Taxonomy Term&lt;/b&gt;, check the&lt;b&gt; Send Arguments&lt;/b&gt; box. In the &lt;b&gt;Arguments&lt;/b&gt; field there, type in &lt;b&gt;%term&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/SetB-k6fqsI/AAAAAAAAErw/a4MhYe5iK9g/s1600-h/panel+pane+configuration.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/SetB-k6fqsI/AAAAAAAAErw/a4MhYe5iK9g/s320/panel+pane+configuration.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Note that you must set the &lt;b&gt;Taxonomy Term&lt;/b&gt; to &lt;b&gt;No Context&lt;/b&gt;, or else the view won't work. I don't know why, most &lt;b&gt;&lt;span class="Apple-style-span"  style="color:#FF0000;"&gt;&lt;a href="http://drupal.org/node/438284"&gt;probably it's a bug&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;And that's it!&lt;/li&gt;&lt;/ol&gt;That's how I got my panel and views to work together in Drupal. Do let me know whether it works on your site!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-378327317844167649?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/378327317844167649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=378327317844167649' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/378327317844167649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/378327317844167649'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/04/passing-arguments-from-panel-to-views.html' title='Passing Arguments from Panel to Views in Drupal'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Ses_tvRxtqI/AAAAAAAAErg/POwe_84l4Qs/s72-c/drupal+taxonomy.jpg' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-8103641093126065623</id><published>2009-04-11T16:24:00.000+08:00</published><updated>2009-04-11T16:24:43.284+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>梁祝</title><content type='html'>&lt;span style="font-family: arial;"&gt;&lt;a class="l" href="http://baike.baidu.com/view/16675.htm" onmousedown="return clk(this.href,'','','','10','')" style="color: #0000cc;"&gt;《梁山伯与祝英台》&lt;/a&gt;（&lt;/span&gt;梁祝）是一首华人都耳熟能详的民间传说，与白蛇传，孟姜女，牛郎织女并称为中国古代四大传说。&lt;br /&gt;&lt;br /&gt;身为流传甚广的故事，梁祝不可避免的被多次搬上舞台，其故事通过电影片，歌剧，传统戏台流传，生命力非常旺盛，到了今天这个二十一世纪还是有许多人欣赏。梁祝反映了人们对封建制度的反抗，批判了传统家长制对儿女的展控，鼓吹自由，解放，难怪受到大家的喜爱。故事结尾时祝英台哭倒在梁山泊的坟墓前，梁的坟墓裂开两半儿，祝英台跳了进去，与梁山伯双双化为蝴蝶，同飞而去，从此不再受世间礼俗所绊，逍遥自在宇宙间。虽然这一幕明显带有神话迷信色彩，可是却如实的反映出人类追逐自由理想的愿望。今世做不了夫妻，来世我们还是可以在一起。正谓《&lt;a href="http://www.etju.com/tkzl/tongkao-dxyw/dxyw-20/content.htm"&gt;但教心似金钿坚，天上人间会相见&lt;/a&gt;〉。&lt;br /&gt;&lt;br /&gt;在这么多个版本之中，我最喜欢的还是 &lt;a href="http://en.wikipedia.org/wiki/Richard_Clayderman"&gt;Richard Clayderman&lt;/a&gt; 的钢琴弹奏。传统二胡，古筝的演绎不是不好，可是我这个半二毛子就是不懂得欣赏，总是觉得气氛太闷了一点，也在严肃了一些。Richard Clayderman的演绎多了一点浪漫，少了一些的悲调，虽然有人会批评这种演绎其实乖离了故事精神，但是只要可以让故事流传下去，让更多人欣赏中国的文学瑰宝，其实也不用计较那么多。&lt;br /&gt;&lt;br /&gt;这是我从&lt;a href="http://www.youtube.com/watch?v=P2XfGfafkW4"&gt;youtube&lt;/a&gt;找来的梁祝钢琴演奏，希望你也会喜欢。&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/P2XfGfafkW4&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/P2XfGfafkW4&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-8103641093126065623?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8103641093126065623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8103641093126065623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8103641093126065623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8103641093126065623'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/04/blog-post.html' title='梁祝'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-3902462765153908594</id><published>2009-04-09T22:07:00.002+08:00</published><updated>2009-04-09T22:41:58.582+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codesmith'/><category scheme='http://www.blogger.com/atom/ns#' term='nhibernate'/><title type='text'>NHibernate Multiple Databases Support with CodeSmith</title><content type='html'>&lt;div style="text-align: justify;"&gt;I am a lazy developer, so I am always looking for tools that help me to automate my code generation. Needless to say, Data Access Layer (DAL) easily the most tedious code to write, regardless of  whether( or especially when) you have ORM to help you.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Currently I am using &lt;a href="http://www.codesmithtools.com/"&gt;CodeSmith&lt;/a&gt; to help me in my &lt;a href="http://www.nhibernate.org/"&gt;NHibernate&lt;/a&gt; DAL generation. NHibernate is a popular ORM for .Net, and it's open source. CodeSmith is a known name in code generation. So I guess going by these two tools would solve all my needs... apparently no, yet.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;You can't generate the NHibernate DAL in one touch if you are querying across multiple databases using CodeSmith tool; you have to do some manual adjustment to the code before the DAL works. So this is a post explaining how to make &lt;a href="http://mikehadlow.blogspot.com/2008/10/mapping-entities-to-multiple-databases.html"&gt;NHibernate work with multiple databases&lt;/a&gt; using CodeSmith.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I am assuming that you are accessing two different databases in the same server, if you want to access different databases in different servers than you might need to find your own help.&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;Create a CodeSmith project (*.csp), choose the correct master template, then set the SourceDatabase name to a database, let's call it &lt;b&gt;mystore&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;For all the options, you can set them to anything you want. The most important thing is BaseNamespace must be the same for both of the databases. In this case, we set the BaseNamespace to be &lt;b&gt;CodeSmithJoin.Generated.Base&lt;/b&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="text-align: justify;clear: both; "&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sd39VCpSe6I/AAAAAAAAEp0/-oRtgpP8q8c/s1600-h/basenamespace.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sd39VCpSe6I/AAAAAAAAEp0/-oRtgpP8q8c/s400/basenamespace.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Click OK&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Generate the DAL by right-clicking on csp file and Choose Generate Outputs.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;&lt;span style="color:red;"&gt;Copy the content of ManagerFactory.cs to clipboard, or a file, you will need it later&lt;/span&gt;&lt;/b&gt;&lt;span style="color:red;"&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Now you are done with the MyStore database code generation. Let's try to generate the DAL for &lt;b&gt;MyStore2&lt;/b&gt;. &lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;Create another CodeSmith project,  set the SourceDatabase to mystore2. Set the BaseNamespace to be &lt;span style="font-weight: bold;"&gt;CodeSmithJoin.Generated.Base&lt;/span&gt;. To avoid confusion, choose other namespaces for BusinessNamespace, ManagerNamespace and UnitTestNamespace. I choose MyStore.Generated.* for this purpose.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="text-align: justify;clear: both; "&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/Sd3-5IegA9I/AAAAAAAAEp8/FmdyadjH9Rg/s1600-h/morenamespace.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/Sd3-5IegA9I/AAAAAAAAEp8/FmdyadjH9Rg/s320/morenamespace.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Click OK.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Examine the *.hbm.xml from MyStore2, manually add a schema property to the hibernate-mapping tag, set the schema to be "MyStore2". &lt;span style="color:red;"&gt;&lt;b&gt;Maybe CodeSmith template can improve on this.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Create a ManagerFactory1.cs, paste the result in step 5 into it. And don't forget to put partial tag on both the IManagerFactory and ManagerFactory on both the ManagerFactory.cs and ManagerFactory1.cs. This is required because the ManagerFactory class is now splitted into two parts, one in ManagerFactory1.cs, and another in ManagerFactory.cs. &lt;span style="color:red;"&gt;&lt;b&gt;Maybe CodeSmith template can improve on this as well&lt;/b&gt;&lt;/span&gt;. &lt;/li&gt;&lt;li style="text-align: justify;"&gt; Create a &lt;a href="http://www.hibernate.org/211.html"&gt;hibernate.cfg.xml&lt;/a&gt;, add to your project, and now you can access two databases!&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;Here's how you can get NHibernate to work with multiple databases, using CodeSmith. And sure, I hope that CodeSmith can incorporate all the above suggestion so that code generation can be made easier, so that we the developers have more time browsing &lt;a href="http://reddit.com/"&gt;reddit&lt;/a&gt;.&lt;/div&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3902462765153908594?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3902462765153908594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3902462765153908594' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3902462765153908594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3902462765153908594'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/04/nhibernate-multiple-databases-support.html' title='NHibernate Multiple Databases Support with CodeSmith'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Sd39VCpSe6I/AAAAAAAAEp0/-oRtgpP8q8c/s72-c/basenamespace.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-6514450905768414667</id><published>2009-04-09T19:11:00.015+08:00</published><updated>2009-06-12T10:32:31.210+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Symfony'/><title type='text'>How to Configure Multiple Databases for Symfony</title><content type='html'>Manipulating two or more databases in a single Symfony application proved to be &lt;a href="http://stackoverflow.com/questions/733224/multiple-databases-support-in-symfony"&gt;quite a daunting challenge to me&lt;/a&gt; (&lt;span style="text-decoration: line-through;"&gt; and not to mentioned that there is &lt;/span&gt;&lt;a href="http://forum.symfony-project.org/index.php/t/20193/"&gt;&lt;span style="text-decoration: line-through;"&gt;a possibility for a Symfony bug&lt;/span&gt;&lt;/a&gt;). So the whole purpose of this post is to help those who are facing the same problem as I do; may this post saves them from unnecessary hassle.&lt;br /&gt;&lt;br /&gt;Here's how you can get multiple databases access to work in Symfony.&lt;br /&gt;&lt;br /&gt;Define the following in db1.schema.yml:&lt;br /&gt;&lt;pre class="brush: bash"&gt;db1:&lt;br /&gt;  lkp_User:&lt;br /&gt;    pk_User:                     { type: integer, required: true, primaryKey: true, autoIncrement: true }&lt;br /&gt;    UserName:                    { type: varchar(45), required: true }&lt;br /&gt;    Password:                    longvarchar&lt;br /&gt;    _uniques:&lt;br /&gt;      Unique:                    [ UserName ]&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And define the following in db2.schema.yml&lt;br /&gt;&lt;pre class="brush: bash"&gt;db2:&lt;br /&gt;  tesco:&lt;br /&gt;    Id:                  { type: integer, required: true, primaryKey: true, autoIncrement: true }&lt;br /&gt;    Name:                { type: varchar(45), required: true }&lt;br /&gt;    Description:         longvarchar&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;The schema.yml files must be of the format %dbname%.schema.yml, or else it won't work. &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now, define the following in databases.yml:&lt;br /&gt;&lt;pre class="brush: bash"&gt;dev:&lt;br /&gt;  db1:&lt;br /&gt;    param:&lt;br /&gt;      classname: DebugPDO&lt;br /&gt;test:&lt;br /&gt;  db1:&lt;br /&gt;    param:&lt;br /&gt;      classname: DebugPDO&lt;br /&gt;all:&lt;br /&gt;  db1:&lt;br /&gt;    class: sfPropelDatabase&lt;br /&gt;    param:&lt;br /&gt;      classname: PropelPDO&lt;br /&gt;      dsn: 'mysql:dbname=bpodb;host=localhost'   #where the db is located&lt;br /&gt;      username: root&lt;br /&gt;      password: #pass&lt;br /&gt;      encoding: utf8&lt;br /&gt;      persistent: true&lt;br /&gt;      pooling: true&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  db2:&lt;br /&gt;    class: sfPropelDatabase&lt;br /&gt;    param:&lt;br /&gt;      classname: PropelPDO&lt;br /&gt;      dsn: 'mysql:dbname=mystore2;host=localhost'   #where the db is located&lt;br /&gt;      username: root&lt;br /&gt;      password: #pass&lt;br /&gt;      encoding: utf8&lt;br /&gt;      persistent: true&lt;br /&gt;      pooling: true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that we define two connections in databases.yml, one for db1, another for db2. &lt;br /&gt;&lt;br /&gt;Now run the following command:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;php symfony propel-build-model&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And you are done!&lt;br /&gt;&lt;br /&gt;This is how you can workaround the deficiencies in &lt;a href="http://www.symfony-project.org/"&gt;Symfony&lt;/a&gt; documentation and configure multiple databases.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-6514450905768414667?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6514450905768414667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6514450905768414667' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6514450905768414667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6514450905768414667'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/04/how-to-configure-multiple-databases-for.html' title='How to Configure Multiple Databases for Symfony'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-1979707771628290419</id><published>2009-03-28T14:03:00.001+08:00</published><updated>2009-06-19T16:50:06.996+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Language Wars'/><title type='text'>I hate dynamic language</title><content type='html'>OK, this is a rant. No flame intentioned. But dynamic language rubs me in the wrong way and I have to complain about it.&lt;br /&gt;&lt;br /&gt;Tell me what's wrong with the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;$client = new SoapClient($wsdl); &lt;br /&gt;$dwer= $client-&amp;gt;login(array('userid'=&amp;gt;$usrname, 'password'=&amp;gt;$pass)); &lt;br /&gt;$param = array('sessionId'=&amp;gt;$sessionId, 'caseId'=&amp;gt;$caseId, 'delIndex'=&amp;gt;$delIndex);&lt;br /&gt;$result = $client-&amp;gt;derivateCase($params);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I spent an hour trying to debug this code. It turned out that I misspelled &lt;b&gt;$params&lt;/b&gt;-- it should be &lt;b&gt;$param&lt;/b&gt; ( with no &lt;b&gt;&lt;span style="color: red;"&gt;s&lt;/span&gt;&lt;/b&gt; at the back).&lt;br /&gt;&lt;br /&gt;I wouldn't get this if I were using a static type language.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-1979707771628290419?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1979707771628290419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1979707771628290419' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1979707771628290419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1979707771628290419'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/i-hate-dynamic-language.html' title='I hate dynamic language'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-5596238838987031231</id><published>2009-03-26T20:31:00.000+08:00</published><updated>2009-03-26T20:46:30.741+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Finance'/><title type='text'>Efficient Market Hypothesis-- Maybe the Market isn't So Efficient After All</title><content type='html'>&lt;div style="text-align: justify;"&gt;I am a staunch believer of &lt;a href="http://en.wikipedia.org/wiki/Efficient_market_hypothesis"&gt;Efficient Market Hypothesis&lt;/a&gt; (EMH), and my&amp;nbsp;skepticism&amp;nbsp;towards the claim that some Special Ones can time the market and make a better-than-risk-adjusted returns is &lt;a href="http://itscommonsensestupid.blogspot.com/2008/02/can-hedge-funds-time-market.html"&gt;well documented&lt;/a&gt;. &amp;nbsp;In my view no one can actually time the market and make better returns than the Index after factored in risk exposure, over the long run. Stock Market is like an ideal casino; no one can outsmart the house because all the games are just perfect probability exercises with no room for human error, no tricks that the players can exploit and the house always has a bit of unfair advantage because, err.., it's the house. In our stock market case here, each transaction will incur transaction fees, and &lt;a href="http://www.investopedia.com/terms/b/bid-askspread.asp"&gt;bid-ask spread&lt;/a&gt; and &lt;b&gt;they add up&lt;/b&gt;. Given that over the long run you can't do better than the average returns anyway, the more you trade, the more the fees will eat up on you and the more you will lose. &amp;nbsp;So as far as the investors are concerned, we have to reduce our trading costs and try to replicate the broad market returns, that's it. Forget about timing the market, forget about stock selection and forget about the trading secrets the&amp;nbsp;charlatans&amp;nbsp;sold you.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But the article "&lt;a href="http://www.marketwatch.com/news/story/top-managers-2008-pay-down/story.aspx?guid={374B1243-C237-466A-A17F-DAC5777FA5D1}&amp;amp;dist=msr_2"&gt;Top&amp;nbsp;managers'&amp;nbsp;pay&amp;nbsp;dropped&amp;nbsp;48%&amp;nbsp;last&amp;nbsp;year&lt;/a&gt;" ( thanks to&lt;a href="http://malaysiafinance.blogspot.com/2009/03/hedge-fund-top-earners.html"&gt; Dali&lt;/a&gt;) caused me to examine my long-time belief ( &lt;a href="http://www.nytimes.com/2009/03/25/business/25hedge.html"&gt;NYT also reported&lt;/a&gt; on the earning of those hedgies) .It seems that although Hedge fund top earners come and go, but there are several notable exceptions who consistently make it to the list, such as &lt;a href="http://en.wikipedia.org/wiki/James_Harris_Simons"&gt;James Simmons&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/George_Soros"&gt;George Soros&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Let's talk about Simmons, his fund uses complicated mathematical models to &lt;a href="http://en.wikipedia.org/wiki/Renaissance_Technologies"&gt;predict the price movement of easily-traded securities and derivatives&lt;/a&gt;. What he's doing is dangerously coming close to the border of &amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Technical_analysis"&gt;technical analysis&lt;/a&gt;, a field that is long derided by academics as pseudo-science. But the only difference is while technical analysts ( or the chartists) are guilty of intentionally keeping their prediction vague, lest they were proven wrong, computer models are churning out precise results ( sometimes being precise about the wrong thing, how ironic). The fact that Simmons can use computer models to beat the market consistently means that maybe-- &lt;i&gt;just maybe&lt;/i&gt; market prediction is possible, if you are smart and hardworking enough.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Or maybe not, the fact that Simmons can reproduce his stellar performance year after year may due more to the size he is, the connection he has and less to his computer models. &amp;nbsp;Because of their clouts, the hedge funds can always&amp;nbsp;negotiate&amp;nbsp;a lower transaction rate with the brokers. Because of their connections, they can always get breaking news a bit faster than the rest ( split second counts in high frequency trading). The mathematical models are just marketing tools; with or without them, the out-performers are going to get the kind of stellar returns they usually get.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Or maybe he's just plain lucky and the fact that his name pops up every year has more to do with &lt;a href="http://en.wikipedia.org/wiki/Survivorship_bias"&gt;survivor bias&lt;/a&gt; than any other thing else.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Any thoughts?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5596238838987031231?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5596238838987031231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5596238838987031231' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5596238838987031231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5596238838987031231'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/efficient-market-hypothesis-maybe.html' title='Efficient Market Hypothesis-- Maybe the Market isn&apos;t So Efficient After All'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-8516279285800378230</id><published>2009-03-24T23:35:00.003+08:00</published><updated>2009-05-14T20:00:31.200+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='yahoo'/><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><title type='text'>Why Gmail is Better than Yahoo</title><content type='html'>&lt;div class="separator" style="text-align: justify;clear: both; "&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/Scj8pGe4oFI/AAAAAAAAEn8/qSaiKyQkS0s/s1600-h/gmail.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/Scj8pGe4oFI/AAAAAAAAEn8/qSaiKyQkS0s/s320/gmail.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I posted  a short note on &lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt;, lamenting that &lt;a href="http://mail.google.com/"&gt;Gmail&lt;/a&gt; &lt;a href="http://www.webanalyticsworld.net/2007/11/gmail-vs-hotmail-vs-yahoo-mail.html"&gt;isn't the most popular web based email system&lt;/a&gt; in the universe. I thought that for those youngsters who are tech savvy enough to use Facebook, they would have the same feeling. I was wrong.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;One of my friends said that "&lt;i&gt;Yahoo is better because the interface is more advanced&lt;/i&gt;", another commented that "&lt;i&gt;yahoo is much more user friendly&lt;/i&gt;".&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;And another said that Gmail is "&lt;i&gt;arrogant&lt;/i&gt;".&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Now, just to set the record straight. Let me enumerate 8 reasons why Gmail is better than Yahoo:&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Gmail voice chat&lt;/b&gt;. You can voice chat with your friends right inside Gmail. This is something that I really like. You don't have to install a separate client program on your desktop. In a world where our desktops are suffocating in the sea of gratuitous, trivial and resource hungry apps, putting on a chatting software just for the sake of chatting is the last thing I want to do. Sure, you can voice chat with your friends... via &lt;a href="http://messenger.yahoo.com/"&gt;yahoo messenger&lt;/a&gt;. But like I said, another client program is the last thing I need. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;GUI Feeling&lt;/b&gt;. The problem with Yahoo is that it is trying too hard to emulate Outlook's Interface, &lt;i&gt;on a web platform&lt;/i&gt;. Yahoo designers seem to forget that &lt;a href="http://draft.blogger.com/goog_1237903798639"&gt;web apps are not desktop apps; they can and should do different, and even &lt;/a&gt;&lt;i&gt;&lt;a href="http://draft.blogger.com/goog_1237903798639"&gt;better&lt;/a&gt;&lt;/i&gt;&lt;a href="http://www.codinghorror.com/blog/archives/000869.html"&gt; things&lt;/a&gt;. Gmail, on the other hand, is an Exhibit A of  a Web 2.0 thing. We want web apps to evolve in terms of responsiveness, interactivity and level of fun, but we don't need them to feel like desktop apps, thank you very much.&lt;br /&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Speed.&lt;/b&gt; Gmail is fast. Yahoo is slow. Any disputes? I can get from one Gmail message to another in no time. But Yahoo mail just isn't that fast. &lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;UI customization.&lt;/b&gt; Gmail has got &lt;a href="http://gmailblog.blogspot.com/2008/06/introducing-gmail-labs.html"&gt;Gmail labs&lt;/a&gt;. That allows you to customize your Gmail looks and feel.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="text-align: justify;clear: both; "&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/Scj2Yjv67rI/AAAAAAAAEn0/_XlFgQMxuvc/s1600-h/gmail+inbox.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/Scj2Yjv67rI/AAAAAAAAEn0/_XlFgQMxuvc/s400/gmail+inbox.jpg" style="cursor: move;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;You can mold your Gmail interface to your likings. Like to customize your Gmail further? then try Mouse gestures, Title Tweaks, Google Calendar gadget, Google Docs Gadget and many more! Yahoo  mail is just too uniform, there is no taste in it. &lt;/div&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Search&lt;/b&gt;. Google is synonymous with search; the search in Gmail is simply top-notched. I never worry that my information will get lost in the sea of emails, because I know that I can retrieve anything by just typing in the relevant keywords. &lt;a href="http://www.businessinsider.com/henry-blodget-yahoo-search-streak-snapped-loses-share-in-feb-google-gains-2009-3"&gt;Who's using Yahoo for search nowadays?&lt;/a&gt; &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;AJAX&lt;/b&gt;. You don't have to refresh your inbox to get new messages. Isn't that great? And when the "Reply" button is hit a reply form comes out instantaneously. Gmail blends AJAX perfectly to give users maximum user experience. Yahoo, on the other hand, uses a lot of AJAX as well. But the problem is that the AJAX in Yahoo doesn't increase the snappiness of the pages. Although the main Yahoo Inbox page employs a lot of AJAX tricks, but the reply and email composition is still very &lt;i&gt;web 1.0&lt;/i&gt;. Oh yes, you can try to delete a Yahoo mail by right clicking on that mail and press "delete". Pretty AJAX, huh? I did try to do that, once. Only to surrender the operation when the popup menu took more than one second to load. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Threaded Conversation&lt;/b&gt;. Email conversation needs to be grouped. Or else how do you survive the onslaught of inflowing emails? Thread is a great way to organize your emails and make them accessible, readable and understandable. I don't want my main page to be dominated by just a single line of conversation, which was always happening inside my Yahoo mail box.   &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;b&gt;Spam Protection&lt;/b&gt;. I don't get spam in my Gmail inbox, even though I published my gmail address on this blog, on forums and on a lot of places. But I still get spams in my yahoo inbox even though I don't publish yahoo email address at all. &lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;So, my friend, if you are seeing this &lt;b&gt;and you still are not switching to Gmail&lt;/b&gt;, you owe me an explanation.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-8516279285800378230?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8516279285800378230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8516279285800378230' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8516279285800378230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8516279285800378230'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/why-gmail-is-better-than-yahoo.html' title='Why Gmail is Better than Yahoo'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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://3.bp.blogspot.com/_SDci0Pf3tzU/Scj8pGe4oFI/AAAAAAAAEn8/qSaiKyQkS0s/s72-c/gmail.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-3594936633593492275</id><published>2009-03-21T14:26:00.002+08:00</published><updated>2009-03-22T15:11:05.175+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Drupal'/><title type='text'>Create a menu link to a particular node type (content type)</title><content type='html'>I play with &lt;a href="http://drupal.org/"&gt;Drupal&lt;/a&gt;, an open source CMS recently. It's quite a comprehensive CMS.&lt;br /&gt;&lt;br /&gt;One thing that really bugs me is how to create a menu link to a&amp;nbsp;particular&amp;nbsp;node type. This is very useful if you allow users to submit information and display those information in your website.&lt;br /&gt;&lt;br /&gt;I found out how to do this &lt;a href="http://drupal.org/node/244281"&gt;here&lt;/a&gt;. But unfortunately I couldn't make a head or tail out of this. So I google further and this is what I found, &lt;a href="http://avpnet.org/content/video/drupal-6-and-views-module"&gt;a video tutorial&lt;/a&gt;. This tutorial is very useful if you are using Drupal 6.&lt;br /&gt;&lt;br /&gt;In order to help those who are having the same problem, I am going to list down the steps on how to create a menu link. Here you go:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download &lt;a href="http://drupal.org/project/insert_view"&gt;view module&lt;/a&gt;, install it.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Go to Administrator-&amp;gt;view, click on the link&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click Add &lt;/li&gt;&lt;li&gt;Choose a view name, and type in a description. Set the View type to be node, and click next.&lt;nr&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/ScSFPkDT5JI/AAAAAAAAEmE/oq-FYex_Kgo/s1600-h/myview.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/ScSFPkDT5JI/AAAAAAAAEmE/oq-FYex_Kgo/s400/myview.jpg" style="cursor: move;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/nr&gt;&lt;/li&gt;&lt;li&gt;You will get a page with lots of information to fill in. It's very daunting and you can get lost easily.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select the Style to be &lt;b&gt;HTML style&lt;/b&gt;, choose the &lt;b&gt;Fields&lt;/b&gt; to be Node: Title&lt;/li&gt;&lt;li&gt;Choose the Filters to be Node: Type&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/ScSF-vX91QI/AAAAAAAAEmM/vfwbHqFWsu8/s1600-h/node+title.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/ScSF-vX91QI/AAAAAAAAEmM/vfwbHqFWsu8/s400/node+title.jpg" style="cursor: move;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Go to &lt;b&gt;Filters&lt;/b&gt;, choose &lt;b&gt;Node: Type&lt;/b&gt;, At the Configure Filter &lt;i&gt;Node: Type&lt;/i&gt; there, select the operator is one of, and &lt;b&gt;node type: vehicle&lt;/b&gt;, where the vehicle is the content type you want to point to &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/ScSHAN-pLEI/AAAAAAAAEmU/bfjgC6AcSIc/s1600-h/configure+node+type.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/ScSHAN-pLEI/AAAAAAAAEmU/bfjgC6AcSIc/s320/configure+node+type.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;At the add display there, add Page and Block to it.&lt;/li&gt;&lt;li&gt;Go to Page, set Path to vehicle, and the menu to Tab: VehicleMenu, as shown below&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/ScSHadny7_I/AAAAAAAAEmc/qZLOcoYfFOU/s1600-h/path+setting.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/ScSHadny7_I/AAAAAAAAEmc/qZLOcoYfFOU/s320/path+setting.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Click Save. &lt;/li&gt;&lt;li&gt;Now, go to Administrator-&amp;gt;Site Building-Menus, click Add Item, set the path to be "vehicle", and give any description you want. Click Save.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/ScSH_fkuJzI/AAAAAAAAEmk/30_qYXiGIYg/s1600-h/add+menu+item.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/ScSH_fkuJzI/AAAAAAAAEmk/30_qYXiGIYg/s320/add+menu+item.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;You will see that the vehicle is appearing on the menu!&lt;/li&gt;&lt;li&gt;Go to Administrator-&amp;gt;site building-&amp;gt;block, put the vehicle menu on the right sidebar, and you will find that the side bar is now filled with vehicle menu!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/ScSIftfTQxI/AAAAAAAAEms/uppDcT-gqJg/s1600-h/sidebar+menu.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/ScSIftfTQxI/AAAAAAAAEms/uppDcT-gqJg/s320/sidebar+menu.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;That's it!&lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3594936633593492275?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3594936633593492275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3594936633593492275' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3594936633593492275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3594936633593492275'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/create-menu-link-to-particular-node.html' title='Create a menu link to a particular node type (content type)'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/ScSFPkDT5JI/AAAAAAAAEmE/oq-FYex_Kgo/s72-c/myview.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-1441803118782850437</id><published>2009-03-16T21:42:00.002+08:00</published><updated>2009-06-12T10:40:36.446+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Symfony'/><title type='text'>How to Deploy Symfony Application Across Multiple Servers</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://www.symfony-project.org/"&gt;Symfony&lt;/a&gt; is one of the most famous PHP MVC framework. It has been around for&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Symfony_framework"&gt;since 2005&lt;/a&gt; and is used in several high profile websites such as &lt;a href="http://delicious.com/"&gt;delicious&lt;/a&gt; and &lt;a href="http://bookmarks.yahoo.com/"&gt;Yahoo Bookmark&lt;/a&gt;&amp;nbsp;. Unlike a lot of open source frameworks, it is quite well-documented.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;It's possible to deploy a Symfony application across multiple servers. You will normally find yourself in this situation when your website takes off and is receiving hundreds of thousands of hits per hour and your high power server is stressing under the load. So you have to fork out additional dollars to buy more servers. Of course, usually you don't have to worry about multiple server deployment &lt;a href="http://www.37signals.com/svn/posts/896-optimize-for-now"&gt;unless you absolutely have to&lt;/a&gt;&amp;nbsp;. But should you have to, and you are using Symfony, here's what you might find useful.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;To deploy a single Symfony application across multiple servers, with the sessions shared among different computers, you have to use a common database for that purpose. You have to:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Define your session table in your schema.yml:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;propel:&lt;br /&gt;  session:&lt;br /&gt;    sess_id:                     { type: varchar(64), required: true }&lt;br /&gt;    sess_data:                   { type: clob, required: true }&lt;br /&gt;    sess_time:                   integer&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Define the following yml schema in your &lt;a href="http://www.symfony-project.org/book/1_2/06-Inside-the-Controller-Layer"&gt;factories.yml&lt;/a&gt;&amp;nbsp;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;all:&lt;br /&gt;  storage:&lt;br /&gt;    class: sfPDOSessionStorage &lt;br /&gt;    param:&lt;br /&gt;      db_table:    session              # Name of the table storing the sessions&lt;br /&gt;      database:    propel               # Name of the database connection to use&lt;br /&gt;      # Optional parameters&lt;br /&gt;      db_id_col:   sess_id              # Name of the column storing the session id&lt;br /&gt;      db_data_col: sess_data            # Name of the column storing the session data&lt;br /&gt;      db_time_col: sess_time            # Name of the column storing the session timestamp&lt;br /&gt;      session_name: example &lt;br /&gt;      session_cookie_domain: .example.com &lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Make sure that the table &lt;span style="font-weight: bold;"&gt;is shared across different servers&lt;/span&gt; by&amp;nbsp;assigning&amp;nbsp;the proper privileges and credentials.&amp;nbsp;&lt;/li&gt;&lt;li&gt;For your databases.yml, you have to make sure that the database connection name is set to propel.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;dev:&lt;br /&gt;  propel:&lt;br /&gt;    param:&lt;br /&gt;      classname: DebugPDO&lt;br /&gt;test:&lt;br /&gt;  propel:&lt;br /&gt;    param:&lt;br /&gt;      classname: DebugPDO&lt;br /&gt;all:&lt;br /&gt;  propel:&lt;br /&gt;    class: sfPropelDatabase&lt;br /&gt;    param:&lt;br /&gt;      classname: PropelPDO&lt;br /&gt;      dsn: 'mysql:dbname=bpodb;host=localhost'   #where the db is located&lt;br /&gt;      username: root&lt;br /&gt;      password: #ur password&lt;br /&gt;      encoding: utf8&lt;br /&gt;      persistent: true&lt;br /&gt;      pooling: true&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Build your Symfony model layer, deploy your applications on multiple servers.&lt;/li&gt;&lt;li&gt;Make sure that you access your Symfony application via a domain name, in this case, it's &lt;span style="font-style: italic;"&gt;.example.com&lt;/span&gt;. Note that if you access the application through machine name or IP address, &lt;span style="font-weight: bold;"&gt;the session sharing won't work&lt;/span&gt;.&amp;nbsp;&lt;/li&gt;&lt;li&gt;And that's it! You will find that the sessions are transfered back and forth seamlessly between different webpages.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-1441803118782850437?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/1441803118782850437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=1441803118782850437' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1441803118782850437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/1441803118782850437'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/how-to-deploy-symfony-application.html' title='How to Deploy Symfony Application Across Multiple Servers'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5218156152302823995</id><published>2009-03-12T21:42:00.022+08:00</published><updated>2009-05-14T20:01:01.798+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lighthearted'/><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><title type='text'>Nobel Prize for Gmail Engineers: For Making Time Traveling a Reality</title><content type='html'>&lt;a href="http://mail.google.com/"&gt;Gmail&lt;/a&gt; engineers did what Albert Einstein failed to do: devise a time traveling machine. Now it's possible for Gmail users to go back to the future.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/SbivjLfjYmI/AAAAAAAAElE/N1_-GA8JkCg/s1600-h/minus+3+minutes.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/SbivjLfjYmI/AAAAAAAAElE/N1_-GA8JkCg/s400/minus+3+minutes.PNG" style="cursor: move;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;But too bad, you can only go forward in time for only 3 minutes. So you can't see tomorrow's  lottery number and come back and buy the first prize number. However, this is a no small feat for Gmail engineers. As they rewrote the rules for &lt;a href="http://en.wikipedia.org/wiki/General_relativity"&gt;general relativity&lt;/a&gt; , they are definitely entitled to get a &lt;a href="http://nobelprize.org/"&gt;nobel prize&lt;/a&gt; for that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-5218156152302823995?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5218156152302823995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5218156152302823995' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5218156152302823995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5218156152302823995'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/nobel-prize-for-gmail-engineers-for.html' title='Nobel Prize for Gmail Engineers: For Making Time Traveling a Reality'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SbivjLfjYmI/AAAAAAAAElE/N1_-GA8JkCg/s72-c/minus+3+minutes.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-6354765698586946832</id><published>2009-03-10T22:12:00.001+08:00</published><updated>2009-03-10T22:12:59.320+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Twitter'/><title type='text'>I would Like to Jump on Twitter's Bandwagon, But...</title><content type='html'>&lt;div style="text-align: justify;"&gt;My friend asked me to sign up for &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; ; he said that every cool kid down the block has one. Given that it's damn hot ( and maybe the last hottest web 2.0 creature we are going to see, given the current financial meltdown), I would like to give it a try.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;However when I went to the Twitter's homepage, I was asked to sign up an account. Sorry, NO &lt;a href="http://openid.net/"&gt;Open ID &lt;/a&gt; support. Given that I have signed up so many services and accounts in the past that I am now suffering from &lt;a href="http://en.wikipedia.org/wiki/Password_fatigue"&gt;password fatigue&lt;/a&gt; , I have decided not to get another username/password, even from the hottest web 2.0 creature called Twitter.  &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So! Twitter developers! You hear me loud and clear? Just enable Open ID support. Yes, you hear me right. &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="color:red;"&gt;ENABLE OPEN ID SUPPORT, NOW&lt;/span&gt;&lt;/span&gt;. And I will get one account immediately, thank you. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-6354765698586946832?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6354765698586946832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6354765698586946832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6354765698586946832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6354765698586946832'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/i-would-like-to-jump-on-twitters.html' title='I would Like to Jump on Twitter&apos;s Bandwagon, But...'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-2507325761245843417</id><published>2009-03-03T22:09:00.000+08:00</published><updated>2009-03-04T17:53:42.303+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><title type='text'>What are the Must-Knows when Dealing with Open Source Software</title><content type='html'>&lt;div style="text-align: justify;"&gt;Open source software is good. Yeah, I agree. It saves you from &lt;a href="http://www.cio.com/article/29405/Milking_the_Mainframe_Exorbitant_Software_Licensing_Costs"&gt;exorbitant licensing cost&lt;/a&gt; . It protects you from &lt;a href="http://en.wikipedia.org/wiki/Vendor_lock-in"&gt;vendor's lock-in&lt;/a&gt; . It gives you the flexibility to modify the software as you see fit. And so on.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But open source software &lt;a href="http://itscommonsensestupid.blogspot.com/2008/02/is-open-source-software-necessarily.html"&gt;is not necessarily cheaper&lt;/a&gt; . Despite that you can obtain the source code at no charge, there are times when you find that you would rather pay a fee in exchange of the services that are normally provided by the commercial software. At the end of the day you might find that you are actually paying quite a hefty fee on training and support.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If you want to use Open Source Software instead of the commercial, proprietary counterparts.You might find the below information useful.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;A lot of open source software are &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Abandonware"&gt;&lt;span style="font-weight: bold;"&gt;abandonware&lt;/span&gt;&lt;/a&gt; . I know, I know, there are a lot of commercial software that are abandonware as well. But the likehood of a commercial software becoming an abandonware is smaller than open source applications. This is because open source software are usually sustained by contributer's enthusiasm. The usual situation is that one person starts to open source a project, and hope that other people can pick it up from there. There is a real chance that the project can die half way before it goes big. So if you bet your business on it, then I can only say good luck to you. Of course, commercial software has a real chance to die as well, the company that makes it can fold. But since the company is receiving income steadily, the risk of folding is significantly lower. &lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;Open source software support can be terrible.&lt;/span&gt; As mentioned above, a lot of contributors who contribute to open source applications are just enthusiasts. And writing documentation, answering support calls are not exactly &lt;span style="font-style: italic;"&gt;fun&lt;/span&gt;. Which is why you find that the documentation on OSS is usually &lt;a href="http://www.devx.com/opensource/Article/11839"&gt;dearth to the point of non-existent&lt;/a&gt; . It's very frustrating when you can't get the software to work and there is no one there to help you.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I have dealt with a number of software, some are open source, others are not. Usually, the commercial software vendors reply your questions ( no matter how &lt;a href="http://en.wikipedia.org/wiki/Newbie"&gt;noob&lt;/a&gt; or stupid it sounds)  within 24 hours. But I can't get this kind of luxury when I am dealing with OSS. My questions are usually left unanswered for a long period of time, and even the bugs I report are left unacknowledged. In one way it trains me to be more self-reliant. But still, I prefer to get my job done instead of learning software.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The only exception is the &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt; . But it's slowly converting to a commercial software. Hmm. There is no free lunch after all. &lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Commercial open source support can be expensive&lt;/span&gt;. Companies exist for a reason: to make money. Proprietary software companies make money by charging on the software licensing. And Open source company makes money by charging the support. And since they can't charge for the source code, they have to make it up by charging more. It's just Economics 101. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Certain level of persistence, diligence&lt;/span&gt; are needed to get the best out of the open source software. You want to get the best out of the open source? Then you better explore the software inside out. Don't try to shortcut the learning curve by consulting the documentation, because the documentation can be incomplete or downright wrong or not up-todate. There is no dedicated support line you can call, there is no support email you can email to. You can always google, out of a vast sea of data, you still have to decide which answer you want. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;The hidden switching cost&lt;/span&gt;. Finally, if you are now using a close source application and you prepare to switch to open source one, make sure you take switching cost into the account. You should allocate time and money for training and external help. And don't forget to allocate budget for software modification. You might need external consultants to change the software to better suit your needs&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-2507325761245843417?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2507325761245843417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2507325761245843417' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2507325761245843417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2507325761245843417'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/03/what-are-must-knows-when-dealing-with.html' title='What are the Must-Knows when Dealing with Open Source Software'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-3966753028296472706</id><published>2009-02-28T20:57:00.006+08:00</published><updated>2009-06-15T21:38:48.669+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Zend'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>How to Debug a PHP file as WebPage using Zend Studio for Eclipse</title><content type='html'>&lt;div style="text-align: justify;"&gt;Recently I dubbed into &lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt; development, and have chosen &lt;a href="http://www.zend.com/en/products/studio/"&gt;Zend Studio for Eclipse&lt;/a&gt; as my development platform. &amp;nbsp;Eclipse is so different than Visual Studio in terms of usability that I have to spend some time in familiarizing myself with the tool. I had some difficulties in even &lt;a href="http://itscommonsensestupid.blogspot.com/2009/01/open-existing-project-in-eclipse.html"&gt;setting up a simple Eclipse project&lt;/a&gt;&amp;nbsp;. So to help other people, I wrote &lt;a href="http://itscommonsensestupid.blogspot.com/2009/01/open-existing-project-in-eclipse.html"&gt;a post&lt;/a&gt; on how to do just that.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now, this is a post on how to debug a PHP file. It doesn't take a genius to figure out what's the latest problem I had run into.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Here are the steps on how to debug a PHP file as a webpage using Zend Studio for Eclipse&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.zend.com/en/products/studio/downloads"&gt;Download and install Zend Studio for Eclipse&lt;/a&gt;&amp;nbsp;, of course.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.zend.com/en/products/core/downloads"&gt;Download Zend Core&lt;/a&gt;&amp;nbsp;. Install it on your web server. So if you are using your own machine as the server, then install it on your machine. If you want to do remote debugging, you have to install it on the real server.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Create a new project, name it as WebPageGo, choose the default workspace for Eclipse.&lt;/li&gt;&lt;li&gt;&lt;a href="http://files.zend.com/help/Zend-Studio-Eclipse/ensuring_the_placement_of_dummy.php.htm"&gt;Put in a dummy.php&lt;/a&gt; in your &amp;nbsp;htdocs folder ("C:\Program Files\Apache Software Foundation\Apache2.2\htdocs").&amp;nbsp;&lt;/li&gt;&lt;li&gt;In the Conf\Extra folder ("C:\Program Files\Apache Software Foundation\Apache2.2\conf\extra"), &lt;a href="http://httpd.apache.org/docs/1.3/mod/core.html"&gt;Create a new configure file&lt;/a&gt; StupidWorkPlace.conf. Type in the following content:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;NameVirtualHost *:80&lt;br /&gt;  &lt;virtualhost *:80&gt;&lt;br /&gt;    DocumentRoot "C:\Documents and Settings\%YourUsername%\Zend\workspaces\DefaultWorkspace"&lt;br /&gt;    DirectoryIndex index.html index.php&lt;br /&gt;    &lt;Directory  "C:\Documents and Settings\%YourUsername%\Zend\workspaces\DefaultWorkspace"&gt;&lt;br /&gt;       AddDefaultCharset UTF-8&lt;br /&gt;       AllowOverRide none&lt;br /&gt;       Options FollowSymlinks&lt;br /&gt;       Order allow,deny&lt;br /&gt;       Allow from all&lt;br /&gt;    &lt;/Directory&gt;&lt;br /&gt;  &lt;/VirtualHost&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;In your &lt;a href="http://httpd.apache.org/docs/1.3/configuring.html"&gt;httpd.conf&lt;/a&gt; file, type in&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;Include conf/extra/StupidWorkPlace.conf;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Create a a PHP script call DoesItMatter.php ( don't ask me what's the reason behind this name). Put it under the WebPageGo workspace.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Type In the following scripts:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: php"&gt;Hello word&lt;br /&gt;&amp;lt;br/&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;echo "I want to debug";&lt;br /&gt;phpinfo();&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Choose Debug As-&amp;gt;PHP Web Page, but before that set a breakpoint at the &lt;span style="font-style: italic;"&gt;echo&lt;/span&gt; statement.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sakz7FWiYoI/AAAAAAAAEj8/EzyrbdgiF34/s1600-h/debug+as+webpage.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sakz7FWiYoI/AAAAAAAAEj8/EzyrbdgiF34/s400/debug+as+webpage.jpg" style="cursor: move;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;And voila! You can now step into the web page for debugging! &lt;/li&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sakz-PjylJI/AAAAAAAAEkE/7_cl1ys4200/s1600-h/webpage+php+step+in.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/Sakz-PjylJI/AAAAAAAAEkE/7_cl1ys4200/s400/webpage+php+step+in.jpg" style="cursor: move;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/ol&gt;Note that you must install Zend Core on your webserver, or else you can't debug,&lt;span style="font-weight: bold;"&gt; even if your webserver is located on your development machine&lt;/span&gt;. If you don't have Zend Core, you can still debug as PHP script, but &lt;span style="font-weight: bold;"&gt;&lt;span style="color: red;"&gt;you can't debug as PHP webpage, as the breakpoint won't be hit&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/3204586232155134420-3966753028296472706?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3966753028296472706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3966753028296472706' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3966753028296472706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3966753028296472706'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/02/how-to-debug-php-file-as-webpage-using.html' title='How to Debug a PHP file as WebPage using Zend Studio for Eclipse'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/Sakz7FWiYoI/AAAAAAAAEj8/EzyrbdgiF34/s72-c/debug+as+webpage.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-8959029861080106</id><published>2009-02-26T22:13:00.002+08:00</published><updated>2009-02-26T22:14:50.803+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug Reports'/><title type='text'>Microsoft Acknowledged the Bug I Report! But then Chose to Not to Fix It.</title><content type='html'>&lt;div style="text-align: justify;"&gt;So, I &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=417211"&gt;reported&lt;/a&gt; the &lt;a href="http://itscommonsensestupid.blogspot.com/2009/02/how-to-set-attribute-value-at-runtime.html"&gt;set attribute at runtime&lt;/a&gt; bug to Microsoft. But Microsoft has chosen not to fix it. Typical experience in dealing with a jaggernaut.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;A bit of background. I reported the bug two days ago. And the UIFx team reproduced and acknowledged the problem today. But two hours later the case was marked with "won't fix", &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="color:red;"&gt;with no explanation&lt;/span&gt;&lt;/span&gt;. &lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What irked me so much was not the "won't fix" decision. As &lt;a href="http://itscommonsensestupid.blogspot.com/2008/04/i-am-net-programmerand-am-proud-of-it.html"&gt;a software developer&lt;/a&gt; myself, I understand that all the software teams have their priorities, and can choose what to fix and what not to.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;What really upset me was there was no explanation of that decision. Certainly it isn't so difficult to write down why you don't fix a bug to your customer. But Microsoft fails to do that, I can only speculate the possible reasons:&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;It's not their policy to explain why bugs are not fixed&lt;/li&gt;&lt;li style="text-align: justify;"&gt;They don't like me&lt;/li&gt;&lt;li style="text-align: justify;"&gt;They don't like the bug&lt;/li&gt;&lt;li style="text-align: justify;"&gt;The bug is too trivial to justify explanation&lt;/li&gt;&lt;li style="text-align: justify;"&gt;They have so many bugs that they don't have the time to explain one by one why this is so or not so.&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;But this is also a good lesson in technical support. This incident should remind me to always explain the rational of my resolution of a case to other people. You might not care about the explanation, but other people do, and they can make noises if they are not happy.&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/3204586232155134420-8959029861080106?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8959029861080106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8959029861080106' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8959029861080106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8959029861080106'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/02/microsoft-acknowledged-bug-i-report-but.html' title='Microsoft Acknowledged the Bug I Report! But then Chose to Not to Fix It.'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-2316555030396155389</id><published>2009-02-23T21:45:00.003+08:00</published><updated>2009-06-13T11:18:41.113+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>How to Set Attribute Value at Runtime-- and How to Work around a Silly Bug</title><content type='html'>&lt;div style="text-align: justify;"&gt;Changing a property's&lt;a href="http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx"&gt; attribute&lt;/a&gt;&amp;nbsp;at runtime is generally frowned upon. After all, attributes are just metadata and should remain unchanged after the they are compiled. But sometimes you have to do it, regardless of what the "best practices" are saying.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;In my projects, there are a lot of times when I have to reuse the components that I have built. I often found that I needed to do a slight tinkering to the components to get them suit my new applications. One of the most common&amp;nbsp;scenario&amp;nbsp;I found was that I had to hide some of the properties of a class. Given that I couldn't modify the base components, the only option I had is to change the attribute values at runtime, at a different assembly.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Supposed that &amp;nbsp;we have a student class located in the base assembly:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;public class Student&lt;br /&gt;    {&lt;br /&gt;        public string Name&lt;br /&gt;        {&lt;br /&gt;            get;&lt;br /&gt;            set;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public string Address&lt;br /&gt;        {&lt;br /&gt;            get;&lt;br /&gt;            set;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and we want to make the Address property Readonly via reflection in another assembly, we can thus implement the following function to accomplish this goal:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;private void SetPropertyGrid()&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(Student))["Address"];&lt;br /&gt;            ReadOnlyAttribute attrib = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];&lt;br /&gt;            FieldInfo isReadOnly = attrib.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);&lt;br /&gt;            isReadOnly.SetValue(attrib,true);&lt;br /&gt;            propertyGrid1.SelectedObject = new Student();&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's the result:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/SaKm8dSVvyI/AAAAAAAAEi8/Xjx0wTupxM8/s1600-h/All+Readonly.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/SaKm8dSVvyI/AAAAAAAAEi8/Xjx0wTupxM8/s400/All+Readonly.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;All the properties are set to readonly, including Name. The code seems correct, but the behaviors are not.&amp;nbsp;Surprised?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;I think this is a .Net bug&lt;/span&gt;. &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=417211"&gt;Microsoft confirmed that this is indeed a bug&lt;/a&gt; . In the mean time, you have to explicitly set the ReadOnly attribute to false in order to get the code working:&lt;/div&gt;&lt;pre class="brush: csharp"&gt;public class Student&lt;br /&gt;    {&lt;br /&gt;        [ReadOnly(false)]&lt;br /&gt;        public string Name&lt;br /&gt;        {&lt;br /&gt;            get;&lt;br /&gt;            set;&lt;br /&gt;        }&lt;br /&gt;        [ReadOnly(false)]&lt;br /&gt;        public string Address&lt;br /&gt;        {&lt;br /&gt;            get;&lt;br /&gt;            set;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Yeah, you have to change the base components. But there is no choice. And this is the result after modification:&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SaKoBUrLkHI/AAAAAAAAEjE/YJIqsDCyJTU/s1600-h/Part+Readonly.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SaKoBUrLkHI/AAAAAAAAEjE/YJIqsDCyJTU/s400/Part+Readonly.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;.Net is indeed big, and&amp;nbsp;weird, don't you think so?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-2316555030396155389?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/2316555030396155389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=2316555030396155389' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2316555030396155389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/2316555030396155389'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/02/how-to-set-attribute-value-at-runtime.html' title='How to Set Attribute Value at Runtime-- and How to Work around a Silly Bug'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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://3.bp.blogspot.com/_SDci0Pf3tzU/SaKm8dSVvyI/AAAAAAAAEi8/Xjx0wTupxM8/s72-c/All+Readonly.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-6030498725207047509</id><published>2009-02-17T20:50:00.005+08:00</published><updated>2009-06-13T11:26:45.753+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>What's Wrong with Strongly Typed Dataset Designer</title><content type='html'>&lt;div style="text-align: justify;"&gt;I might be beating a dead horse here.But &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163877.aspx"&gt;strongly typed dataset&lt;/a&gt; was giving me so much hard time that I have to rant about it. Actually strongly typed dataset is quite handy if all you have to do is just need to query or update a single table. The problem is that the real world is far less ideal than that. When you apply a suboptimal tool on a complicated, messy real world situation you are going to face a lot of problems. And this was exactly what happened when I was using strongly typed dataset designer in my work.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Before you ask me why I didn't want to use a more proper ORM such as &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx"&gt;LINQ to SQL&lt;/a&gt; , or &lt;a href="http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx"&gt;Microsoft ADO.NET Entity Framework&lt;/a&gt; , let me preempt the question by offering the answer here: my project used Microsoft Access as the back end, and regretably, the two don't offer the support for MS Access, yet.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now for the rant:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;No synchronization between the actual database schema and the datasets&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Synchronization between actual database schema and the ORM layer is important, especially when your database is still early in the prototyping stage and subject to change. It is also very useful when you upgrade your database schema because you don't have to manually update the datasets. But unfortunately the strongly typed dataset designer doesn't provide this functionalities. So everything I change my column name, or I add a new column to a table, I have to reconstruct the dataset. Of course I change manually change the schema in the dataset designer, but that's not a good practice anyway because who knows what other changes I did.  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Cannot perform join table queries&lt;/span&gt;&lt;br /&gt;It is incredible that I can't preform join table queries in the designer. First the select query type is broken. To see what I mean, try the following query:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/SZqv6pDYcMI/AAAAAAAAEic/AUpfBprq6PU/s1600-h/std1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/SZqv6pDYcMI/AAAAAAAAEic/AUpfBprq6PU/s320/std1.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And the code behind is this function&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;public virtual string ScalarQuery() ;&lt;/pre&gt;&lt;br /&gt;Digging into the code, it seems that what gets return is&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;command.ExecuteScalar() ;&lt;/pre&gt;&lt;br /&gt;So I can only get the first row of the SELECT statement.. obviously the select command isn't working.&lt;br /&gt;&lt;br /&gt;What about SQL INSERT?&lt;br /&gt;&lt;br /&gt;Sadly, it isn't working as well. You &lt;span style="font-weight: bold;"&gt;can't&lt;/span&gt; insert with condition across different tables. In fact, the designer won't even allow you select different tables when configuration the INSERT command.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Non standardized  query syntax&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;SQL uses prefix '@' to denote parameter. For example, the following syntax is valid in MS Access&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;UPDATE table1 SET&lt;br /&gt;table1.nationality = @nationality&lt;/pre&gt;&lt;br /&gt;Sadly the syntax above doesn't work for dataset designer. The correct syntax would be&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;UPDATE table1 SET&lt;br /&gt;table1.nationality = ?&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The IDE will parse the '?' properly according to the order of appearance. So you can still get a nicely wrapped up function for that.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This kind of language idiosyncrasies are not hard to learn, but they can be extremely frustrating when you can't figure them out. I wonder why Microsoft has to come up with different notations&lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-6030498725207047509?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6030498725207047509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6030498725207047509' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6030498725207047509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6030498725207047509'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/02/whats-wrong-with-strongly-typed-dataset.html' title='What&apos;s Wrong with Strongly Typed Dataset Designer'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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://3.bp.blogspot.com/_SDci0Pf3tzU/SZqv6pDYcMI/AAAAAAAAEic/AUpfBprq6PU/s72-c/std1.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-3707723201380469185</id><published>2009-02-14T23:54:00.005+08:00</published><updated>2009-06-11T23:24:27.536+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Sample'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>How to use App.Config to set the Connection String for Strongly Typed Dataset</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://www.csharp-station.com/Articles/StronglyTypedDatasets.aspx"&gt;Strongly typed dataset&lt;/a&gt; is a good thing... well, sort of, if you just need a quick and dirty &lt;a href="http://en.wikipedia.org/wiki/Data_access_layer"&gt;Data Access Layer&lt;/a&gt; for your Microsoft Access backend in your .net code. What is unknown to many is that it is possible to set the the connection string of a strongly typed dataset from App.Config file. This is extremely handy if you have to deploy your application on client's computer because you can compile the application once and just change the config file when the application is installed on client's computer.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In this post I am going to demonstrate how to use the config file to set the connection string for strongly typed dataset.&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Create  a VS 2008 solution with the following c# projects. Note that I create a separate c# project for my data access layer code. This is better than lumping the datasets in the application project because it encourages better separation of concern.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SDci0Pf3tzU/SZbhVL4R6LI/AAAAAAAAEh0/UCfdxsNAkww/s1600-h/Appconfig.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_SDci0Pf3tzU/SZbhVL4R6LI/AAAAAAAAEh0/UCfdxsNAkww/s400/Appconfig.jpg" style="cursor: move;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Add a new app.config file in the AppConfigJob project by navigating to the app.config file in DAL project and choose the "Add As Link" option.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SZbjcV5f5CI/AAAAAAAAEh8/1S5McjnysHE/s1600-h/Add+app+config.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SZbjcV5f5CI/AAAAAAAAEh8/1S5McjnysHE/s400/Add+app+config.jpg" style="cursor: move;" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Note that you &lt;span style="font-weight: bold;"&gt;have to&lt;/span&gt; create the app.config file for AppConfigJob in this way-- you can't simply create a app.config file by running the C# project property option and choose setting. This is because the app.config file for AppConfigJob and DAL must have the same connection string, or else you will not be able to set the connection string from the config file later, when your application is built. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;Compile the solution in debug mode. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;In your bin\debug folder, you should see that there is an AppConfigJob.exe.config file. This is the config file that holds information to your connection string. &lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The AppConfigJob.exe.config file will have the following configuration.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&amp;lt;configSections&amp;gt;&lt;br /&gt;&amp;lt;/configSections&amp;gt;&amp;lt;connectionStrings&amp;gt;&lt;br /&gt;&amp;lt;add name="DAL.Properties.Settings.sundaybusinessConnectionString"connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\sundaybusiness.mdb;Persist Security Info=True"providerName="System.Data.OleDb" /&amp;gt;&lt;br /&gt;&amp;lt;/connectionStrings&amp;gt;&amp;lt;/configuration&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;After your application is installed on client's machine, you can always point the location of the mdb database by changing the Data Source property. To test this, create a label, put the following code into the Form1_Load method&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;AdministratorTableAdapter adapter = new AdministratorTableAdapter();&lt;br /&gt;label1.Text = adapter.Connection.ConnectionString;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;So when the Form1 is loaded, you will see the connection string information&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SZbn49IdJYI/AAAAAAAAEiM/MWqEhcbgGuc/s1600-h/loadform.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SZbn49IdJYI/AAAAAAAAEiM/MWqEhcbgGuc/s320/loadform.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Now change the data source in the AppConfigJob.exe.config to something else, maybe&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;|DataDirectory|\sundaybusiness2.mdb&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Rerun the Form1, now this is what you will see.&lt;/li&gt;&lt;li&gt;The connection string is changed, without recompiling the application.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/SZbn7lPdCfI/AAAAAAAAEiU/c2ix3RjygbM/s1600-h/loadform2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/SZbn7lPdCfI/AAAAAAAAEiU/c2ix3RjygbM/s320/loadform2.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This is how App.Config can be used to set the connection string of a database at install time. You can manually change the config file, or you can use some scripts to change it during installation time, but this is a topic for another post.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3707723201380469185?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3707723201380469185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3707723201380469185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3707723201380469185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3707723201380469185'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/02/how-to-use-appconfig-to-set-connection.html' title='How to use App.Config to set the Connection String for Strongly Typed Dataset'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SZbhVL4R6LI/AAAAAAAAEh0/UCfdxsNAkww/s72-c/Appconfig.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-635320031601568392</id><published>2009-02-12T15:34:00.001+08:00</published><updated>2009-02-12T16:11:38.017+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Misc'/><title type='text'>Holiday is Over, Now Get Back to Work</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/SZPWqbGEX8I/AAAAAAAAEhs/VCV4_kRgXSo/s1600-h/langkawi431.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/SZPWqbGEX8I/AAAAAAAAEhs/VCV4_kRgXSo/s400/langkawi431.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I have been on holiday for the past 3 weeks. It was really nice, so nice that I didn't want to ( &lt;span style="font-style: italic;"&gt;almost&lt;/span&gt;) come back to work and update my blog.&lt;/div&gt;&lt;br/&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But as great as it was, now the party is over. It's time to come back to the reality and do the following:&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;Programming&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Learning new technologies&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Blogging&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Repeat 1-4 &lt;span style="font-style: italic;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Ad_infinitum"&gt;Ad Infinitum&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;I am going to miss the magnificent beach, the shearing sunlight, the unassuming resort and the friendly people at &lt;a href="http://images.google.com.my/images?rlz=1C1GGLS_enMY291MY303&amp;amp;sourceid=chrome&amp;amp;q=langkawi&amp;amp;um=1&amp;amp;ie=UTF-8&amp;amp;sa=N&amp;amp;hl=en&amp;amp;tab=wi"&gt;Langkawi&lt;/a&gt;&amp;nbsp;. So long, and thanks for the memory.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-635320031601568392?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/635320031601568392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=635320031601568392' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/635320031601568392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/635320031601568392'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/02/holiday-is-over-now-get-back-to-work.html' title='Holiday is Over, Now Get Back to Work'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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://3.bp.blogspot.com/_SDci0Pf3tzU/SZPWqbGEX8I/AAAAAAAAEhs/VCV4_kRgXSo/s72-c/langkawi431.jpg' height='72' width='72'/><thr:total>0</thr:total><georss:featurename>Langkawi, Kedah, Malaysia</georss:featurename><georss:point>6.3233 99.854724</georss:point><georss:box>6.152683499999999 99.62126450000001 6.4939165 100.0881835</georss:box></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-7448570969065564425</id><published>2009-02-01T00:01:00.005+08:00</published><updated>2009-02-01T00:01:33.827+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google services'/><title type='text'>Google: www.google.com might harm your computer</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/SYR1GNXVcfI/AAAAAAAAEgU/LnHphvidpWQ/s1600-h/google.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/SYR1GNXVcfI/AAAAAAAAEgU/LnHphvidpWQ/s400/google.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This was what I got when I searched Google on &lt;a href="http://www.google.com/"&gt;www.google.com&lt;/a&gt;&amp;nbsp;an hour ago. Apparently Google believed that its website was going to harm the user's PC.&lt;br /&gt;&lt;br /&gt;However, Google seemed to fixed this problem now, as the below figure shown:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SDci0Pf3tzU/SYR1ylUyTuI/AAAAAAAAEgc/dicYskxWD2U/s1600-h/googlenormal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_SDci0Pf3tzU/SYR1ylUyTuI/AAAAAAAAEgc/dicYskxWD2U/s400/googlenormal.png" /&gt;&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/3204586232155134420-7448570969065564425?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/7448570969065564425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=7448570969065564425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7448570969065564425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/7448570969065564425'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/02/google-wwwgooglecom-might-harm-your.html' title='Google: www.google.com might harm your computer'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SYR1GNXVcfI/AAAAAAAAEgU/LnHphvidpWQ/s72-c/google.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-3560946417411451100</id><published>2009-01-28T21:39:00.025+08:00</published><updated>2009-01-28T22:05:05.993+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Movies'/><title type='text'>吴宇森之赤壁</title><content type='html'>去看了&lt;a href="http://ent.163.com/special/00032MPD/Red_Cliff.html"&gt;《赤壁 决战天下》&lt;/a&gt; ,真是哭笑不得.&lt;br /&gt;&lt;br /&gt;虽然说&lt;a href="http://baike.baidu.com/view/28223.htm"&gt;吴宇森&lt;/a&gt; 的三国没有必要照&lt;a href="http://www.oklink.net/gdwx/4dmz/2/index.html"&gt;&amp;lt;三国演义&amp;gt;&lt;/a&gt; 全抄,也没有必要完全根据历史事实.可是在这个演义瑰宝之前,吴大导要改编,就要改得让大家心服口服,改得表现出原著的精髓,改得大家一致赞好.可是,现实是,吴宇森的作品,虽然卡士强大,耗资巨大资金,但内容空洞,主人公作风洋派,有画虎类犬之感.&lt;br /&gt;&lt;br /&gt;先说不合理之处.我认为赵薇,林志玲这两人是这部戏的最大败笔.导演大概为了平衡一下三国阳刚过重的现象,所以硬生生加差了两个女主角的戏分,以为可以为戏加分,顺便讨好女观众.却不知道这样反而弄巧成拙.赵薇演孙权的妹妹&lt;a href="http://baike.baidu.com/view/16891.htm"&gt;孙尚香&lt;/a&gt; ,在下半集的戏中充当间谍,混入曹操的军营中,刺探军情,顺便还和一个千夫长谈恋爱,果然是虎兄无犬妹.可是赵薇也未免太神了一点吧?只身深入虎穴龙潭,以鸽子和诸葛亮通军情.怪了,诸葛亮是谁,赵薇竟然那么信任他?要联络为何不直接联络她哥哥孙权?如果跟哥哥有心病的话可以找周瑜啊!&lt;br /&gt;&lt;br /&gt;还有,曹操军纪严明,可是赵薇就是有办法来去自如,把军中的情况如实的报告给诸葛亮知道.曹操如此英明也不会对她起疑,怪哉.她最后功成身退,临走之前把曹操的军图,军队部署画在布上,披在身上,套上军衣,才返回孙营中.孙刘联军就是靠着这张总图打败曹操的.赵薇简直比现今世界最强的情报组织,&lt;a href="http://en.wikipedia.org/wiki/Mossad"&gt;以色列的情报网Mossad&lt;/a&gt; 还牛.以个人力量打败了百万大军,创造了千古不朽的佳话.&lt;br /&gt;&lt;br /&gt;再说林志玲.林大美人的演技我不愿批评.可是她戏中的小乔角色的举止简直是幼稚得可笑.话说孙权借东风,东风没到,个个急得像热窝上的蚂蚁.这个小乔,大概觉得"国家兴亡,匹女有责",就孤身一人到曹营中为东吴解忧.她也不想想曹操是何许人!皇帝都不放在眼里,跟何况是一个弱质女流!可是看到赵薇大显神威,我就觉得可能小乔也有一些特别才能,可以打退曹操丞相,来个彻底颠覆三国.可是到了曹营中,小乔就跟曹操说起一大堆道理,劝他收兵,还替周瑜下跪认输.她以为她是段誉啊?可以籍着一跪拯救天下安危,也未免太儿戏了吧.&lt;br /&gt;&lt;br /&gt;戏中还把曹操的败仗归咎于曹操贪喝小乔所泡的茶,所以误了进攻时机.殊不知东风至,曹军败乃是必然结果.曹操喝茶,能占用几多时间?就是给他多一时三刻,孙军还不是照样载着火药杀过来,曹船还是免不了火烧之厄.&lt;br /&gt;&lt;br /&gt;还有,曹操对小乔可是宽容之至.小乔三番五次顶撞讽刺他,他还不当作一回事.不用说这个跟演义历史的曹操不相符,就是再宽容的人,在这种情况下,也是绝对不会轻饶小乔的.&lt;br /&gt;&lt;br /&gt;不用说,在赤壁这种史诗战争片中穿插爱情情节是吃力不讨好的事,更何况吴大导对拍男女感情戏一点都不擅长.当赵薇在抱着她敌军的男友痛哭时,放在一片兵荒马乱,到处是死尸的场景中,显得十分可笑.小乔跟周瑜的互动,非但不能让人觉得柔情蜜意,也没有患难夫妻相,只让人觉得恶心.&lt;br /&gt;&lt;br /&gt;可能有些朋友会劝我看吴导的戏,就要是看特级效果,看大场面,这样才不会失望.但是实话一句,吴大导拍战争场面能力不出色.功力高深的导演,能把战争的场面拍得扣人心弦,令观众的脉搏不由自主得被战争节奏牵着走,呼吸由主人翁的命运所决定.可是赤壁的大战场面,即不壮观,也不扣人心弦.戏中的火烧战船,可以拍得很悲壮,可是我总是觉得怎么跟我放火烧后院野草一样轻松,这是吴大导不适合拍战争片的明证.&lt;br /&gt;&lt;br /&gt;顺便说一句话,&lt;a href="http://yule.sohu.com/20090106/n261591018.shtml"&gt;吴大导认为黄盖的苦肉计不可信&lt;/a&gt; , 因为没有人可以挨了五十大板之后还有力气带兵打仗,所以他让小乔献茶来取而代之.小乔献茶这个情节的可信度如何, 上面已经有了评论.至于吴导认为苦肉计不可信,那是因为他不知道打板可以打死或打活.高明的打手,可以早上打你一百大板,打得你皮破血流,晚上你就可以健步如飞.这曰"打活".当然,他也可以照着打,打你皮不破,血不流,没打几下你就得见阎罗王.这曰"打死".&lt;br /&gt;&lt;br /&gt;如此这样恶搞三国的电影,本来不应该在戏院上映.可是奈何人家是荷里活大导,所以他的戏可以横行华人世界,票房满座.倒是那些真正懂三国的导演,因为名气不足,所以不能拍三国的戏.人生之讽刺,莫过于此.&lt;br /&gt;&lt;br /&gt;我哭三国!我哭赤壁!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3560946417411451100?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3560946417411451100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3560946417411451100' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3560946417411451100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3560946417411451100'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/blog-post.html' title='吴宇森之赤壁'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-6118642518083154112</id><published>2009-01-27T23:56:00.031+08:00</published><updated>2009-06-12T11:06:38.784+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Computer Problem'/><title type='text'>Cannot Login into Desktop in Windows XP</title><content type='html'>&lt;div style="text-align: justify;"&gt;I have encountered a very weird problem in my mom's notebook. Her notebook has two account. However, when I clicked on the administrator account at the login screen, I couldn't go to the desktop as usual; instead, I was redirected to the login screen.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I believed that this is a problem of virus. A Google search revealed a lot of hints, but only one solution worked for me. Basically what happened was the registries were corrupted and you have to be able fix those registries without login into Windows XP&amp;gt; This was what I &lt;a href="http://support.microsoft.com/?kbid=307545"&gt;did to get the computer working again&lt;/a&gt;&amp;nbsp;.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Log into the Recovery Console&lt;/li&gt;&lt;li&gt;Type the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;md tmp&lt;br /&gt;copy c:\windows\system32\config\system c:\windows\tmp\system.bak&lt;br /&gt;copy c:\windows\system32\config\software c:\windows\tmp\software.bak&lt;br /&gt;copy c:\windows\system32\config\sam c:\windows\tmp\sam.bak&lt;br /&gt;copy c:\windows\system32\config\security c:\windows\tmp\security.bak&lt;br /&gt;copy c:\windows\system32\config\default c:\windows\tmp\default.bak&lt;br /&gt;&lt;br /&gt;delete c:\windows\system32\config\system&lt;br /&gt;delete c:\windows\system32\config\software&lt;br /&gt;delete c:\windows\system32\config\sam&lt;br /&gt;delete c:\windows\system32\config\security&lt;br /&gt;delete c:\windows\system32\config\default&lt;br /&gt;&lt;br /&gt;copy c:\windows\repair\system c:\windows\system32\config\system&lt;br /&gt;copy c:\windows\repair\software c:\windows\system32\config\software&lt;br /&gt;copy c:\windows\repair\sam c:\windows\system32\config\sam&lt;br /&gt;copy c:\windows\repair\security c:\windows\system32\config\security&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Restart the computer&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If this doesn't solve your problem, you may want to &lt;a href="http://articles.techrepublic.com.com/5100-10878_11-6031733.html"&gt;restore the original Windows XP boot setting&lt;/a&gt;&amp;nbsp;, or you may want to consult the &lt;a href="http://www.experts-exchange.com/Operating_Systems/WinXP/Q_21138228.html"&gt;Expert-Exchange for answers&lt;/a&gt; ( remember to scroll to the bottom to get the answers!)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-6118642518083154112?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/6118642518083154112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=6118642518083154112' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6118642518083154112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/6118642518083154112'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/cannot-login-into-desktop-in-windows-xp.html' title='Cannot Login into Desktop in Windows XP'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-8343247364359336049</id><published>2009-01-23T02:02:00.005+08:00</published><updated>2009-01-23T02:14:25.030+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entrepreneurs'/><title type='text'>Why 99% of Entrepreneurs Fail</title><content type='html'>&lt;div style="text-align: justify;"&gt;I came across a very interesting post &lt;a href="http://jessicamah.com/blog/?p=641"&gt;Why 99% of Entrepreneurs Fail: Because they don’t do anything&lt;/a&gt; . The post gives 3 types of entrepreneurs that are set for failure:&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;All ideas, no implementation type of entrepreneurs&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Lots of ideas, half baked implementation type of entrepreneurs&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Lots of ideas, lots of implementation, but no focus type of entrepreneurs&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;If you are falling in any one of the categories then you better watch out! It's likely that your venture will fail.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Having said this, it doesn't mean that if you are a man with a great idea and lots of wonderful implementation and you are laser focused on your goal you &lt;span class="Apple-style-span" style="font-style: italic;"&gt;will&lt;/span&gt; succeed. The sad truth is even though you do everything right, you might still fail. In fact, it is very likely that you will fail despite your best effort.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Why is this so? This is because the success of a venture depends more on timing and market condition rather than human's will. So, if you are starting your own business and are falling every time, don't be too harsh on yourself. Great people fail, and they fail despite doing no wrong. This is just a part of life.&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/3204586232155134420-8343247364359336049?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/8343247364359336049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=8343247364359336049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8343247364359336049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/8343247364359336049'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/why-99-of-entrepreneurs-fail.html' title='Why 99% of Entrepreneurs Fail'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-399401867895382876</id><published>2009-01-20T18:44:00.007+08:00</published><updated>2009-01-20T21:47:23.510+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google services'/><title type='text'>Google Adsense for Feeds is Not Working-- and How to Fix it</title><content type='html'>&lt;div style="text-align: justify;"&gt;When &lt;a href="http://googlesystem.blogspot.com/2008/08/google-tests-adsense-for-feeds.html"&gt;Google Adsense for Feeds&lt;/a&gt; first came out &lt;a href="http://itscommonsensestupid.blogspot.com/2008/08/google-adsense-with-feeds.html"&gt;I took a look at it&lt;/a&gt;  and tried to get it working. &lt;a href="http://itscommonsensestupid.blogspot.com/2008/08/google-adsense-for-feeds-is-not-working.html"&gt;I did not succeed&lt;/a&gt; . But now, I am happy to report that it is finally working. Here are the steps that you can try should you run into the same problem as mine.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First of all, you have to &lt;a href="https://www.google.com/adsense/support/bin/answer.py?answer=99647"&gt;add Google Adsense to your feeds&lt;/a&gt; . If everything works after that, then congratulation, you need to read no further.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But if you are like me, still struggling to find the appearance of the advertisement after doing everything. Then proceed with the following steps:&lt;/div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;Log into your feedburner account at &lt;a href="http://feedburner.google.com/"&gt;http://feedburner.google.com&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;Select the feed title, choose publicize tab.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/SXWtNUajT9I/AAAAAAAAEfc/96b-wvyiec0/s1600-h/feedburner.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/SXWtNUajT9I/AAAAAAAAEfc/96b-wvyiec0/s400/feedburner.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;Select the FeedCount, get a chicklet that displays the number of current subscribers. &lt;span style="font-weight: bold;"&gt;&lt;span style="color:red;"&gt;Only the readers who subscribe through this chicklet will be able to see the advertisement&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/SXWtznp2CHI/AAAAAAAAEfk/wH7PP_MbLRY/s1600-h/chicklet.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="129" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/SXWtznp2CHI/AAAAAAAAEfk/wH7PP_MbLRY/s400/chicklet.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Paste the chicklet on your blog. The problem with not using feedburner to manage subscription is that now I have 0 readers, according to the stats. So you have to rebuild your reader count. But don't worry, you have not lost those who subscribe to your blog via other widget such as &lt;a href="http://www.addthis.com/"&gt;AddThis&lt;/a&gt; .&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Now, unsubscribe your own blog. Yes, do it. &lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;Resubscribe to your blog by clicking on the Chicklet. Now you are subscribing to your own blog via FeedBurner and you should be able to see the advertisement in your feed.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SXWvQNmVSrI/AAAAAAAAEf0/0JV4PeWXDjM/s1600-h/google+adsense+advertisement.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SXWvQNmVSrI/AAAAAAAAEf0/0JV4PeWXDjM/s400/google+adsense+advertisement.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Wait for a few hours.&lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;Log in to your &lt;a href="https://www.google.com/adsense/"&gt;Google Adsense&lt;/a&gt; account, you should see that there are page impressions. This indicates that the Google Adsense for Feeds are successfully setup!&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/SXWvDhYCX2I/AAAAAAAAEfs/lELcpU2fcnM/s1600-h/addimpression.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/SXWvDhYCX2I/AAAAAAAAEfs/lELcpU2fcnM/s400/addimpression.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;Note that, you &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="color:red;"&gt;need to be a feedburner subscriber&lt;/span&gt;&lt;/span&gt; in order to see the advertisement.Those who already subscribe to your blog, but not via feedburner won't see the advertisement. You will ask whether it's possible for Google to migrate its spartan "Subscribe to" link to feedburner so that those who subscribe via that link can get the advertisement.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Maybe it is possible, just maybe. But Google needs to do some work on that, I guess. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-399401867895382876?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/399401867895382876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=399401867895382876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/399401867895382876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/399401867895382876'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/google-adsense-for-feeds-is-not-working.html' title='Google Adsense for Feeds is Not Working-- and How to Fix it'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SXWtNUajT9I/AAAAAAAAEfc/96b-wvyiec0/s72-c/feedburner.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-3433987059191479303</id><published>2009-01-16T18:07:00.006+08:00</published><updated>2009-06-11T23:50:42.048+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Sample'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Is LINQ Becoming a Monster?</title><content type='html'>&lt;div style="text-align: justify;"&gt;I love &lt;a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx"&gt;LINQ&lt;/a&gt; . It gives the developers the power to query databases and lists in a manner far more succint, readable and elegant than that could otherwise be obtained via traditional looping methods ( you know, the combination kinds of &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;for&lt;/span&gt;&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;if&lt;/span&gt;&lt;/span&gt; ) that normally result in lines and lines of code, methods and sub-methods calling. LINQ combines the succintness of &lt;a href="http://www.w3schools.com/sql/default.asp"&gt;SQL queries&lt;/a&gt; with the compile-time type checking advantage offered by C#, and produces code that is far more intuitive and readable than SQL or C# custom tailored filtering functions.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But after using it for quite sometime, I found that LINQ could be a bit prohibitive. Prohibitive in the sense that you always have to write LINQ expressions that are big, complicated, ugly and undecipherable at times. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Take a look at the below queries, see how much you can understand out of it?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;     public DateTime MyDateTime(IEnumerable&amp;lt;timedb.timerecordrow&amp;gt; relatedForm,&lt;br /&gt;         DateTime lastDateTime)&lt;br /&gt;     {&lt;br /&gt;         DateTime dt1 = relatedForm.OrderBy(record =&amp;gt; record.EnterTime).FirstOrDefault(record =&amp;gt;&lt;br /&gt;                                                                              record.EnterTime &amp;gt; lastDateTime).&lt;br /&gt;             EnterTime;&lt;br /&gt;         DateTime dt2 = relatedForm&lt;br /&gt;             .Where(record =&amp;gt; !record.IsLeaveTimeNull())&lt;br /&gt;             .OrderBy(record =&amp;gt; record.LeaveTime)&lt;br /&gt;             .FirstOrDefault(record =&amp;gt;record.LeaveTime &amp;gt; lastDateTime).&lt;br /&gt;             LeaveTime;&lt;br /&gt;&lt;br /&gt;         if (dt1 &amp;gt;= dt2)&lt;br /&gt;             return dt2;&lt;br /&gt;         else&lt;br /&gt;         {&lt;br /&gt;             return dt1;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;     }&lt;br /&gt;     public List&amp;lt;actioninfo&amp;gt; PullLogRecord()&lt;br /&gt;     {&lt;br /&gt;     &lt;br /&gt;         var descriptionDB = ActionDescriptionAdapter.GetData();&lt;br /&gt;         var timeDB = TimeRecordAdapter.GetData();&lt;br /&gt;&lt;br /&gt;         var groupByAction = timeDB.GroupBy(e =&amp;gt; e.UserActionReference);&lt;br /&gt;         var groupByActionAndCurrElement = groupByAction.Select&lt;br /&gt;             (&lt;br /&gt;             group=&gt;new {Key = descriptionDB&lt;br /&gt;                 .Where(record=&amp;gt;record.UserAction==group.Key)&lt;br /&gt;                 .Select(record=&amp;gt;record.Description).Single(),&lt;br /&gt;                 NestedGroup= group.ToLookup&lt;br /&gt;                 (&lt;br /&gt;                 result=&amp;gt;result.CurrElement,&lt;br /&gt;                 result=&amp;gt;new TimerInformation()&lt;br /&gt;                             {&lt;br /&gt;                                 EnterTime = result.EnterTime,&lt;br /&gt;                                 LeaveTime = result.IsLeaveTimeNull() ?&lt;br /&gt;                                  MyDateTime(timeDB.ToList(), result.EnterTime) :&lt;br /&gt;                                  result.LeaveTime&lt;br /&gt;                             }&lt;br /&gt;                  &lt;br /&gt;                 )}&lt;br /&gt;             );&lt;br /&gt;         var dictionary = groupByActionAndCurrElement.ToDictionary&lt;br /&gt;             (&lt;br /&gt;             result =&amp;gt; result.Key,&lt;br /&gt;             result =&amp;gt; result.NestedGroup&lt;br /&gt;             );&lt;br /&gt;&lt;br /&gt;         List&amp;lt;actioninfo&amp;gt; actionInfos=new List&amp;lt;actioninfo&amp;gt;();&lt;br /&gt;         foreach (string key in dictionary.Keys)&lt;br /&gt;         {&lt;br /&gt;             ActionInfo ai = new ActionInfo(){ActionName = key};&lt;br /&gt;          &lt;br /&gt;          &lt;br /&gt;             foreach (var pair in dictionary[key])&lt;br /&gt;             {&lt;br /&gt;                 ai.ElementInfo.Add(new ElementInfo()&lt;br /&gt;                 {&lt;br /&gt;                     ElementName = pair.Key,TimingInfo = pair.ToList()&lt;br /&gt;                 });&lt;br /&gt;             }&lt;br /&gt;             actionInfos.Add(ai);&lt;br /&gt;          &lt;br /&gt;         }&lt;br /&gt;         return actionInfos;&lt;br /&gt;     }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It's awfully long. But what it does is relatively simple:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li style="text-align: justify;"&gt;Pull records from a data table&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Group the data in terms of &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;description&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;CurrElement&lt;/span&gt; tables. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;After the grouping,  get each of the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;EnterTime&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;LeaveTime&lt;/span&gt; for each record and put them in a list, and put the list into an &lt;span class="Apple-style-span" style="font-style: italic;"&gt;ElementInfo&lt;/span&gt; object,  and so on. If the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;LeaveTime&lt;/span&gt; is a &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 255);"&gt;null&lt;/span&gt;&lt;/span&gt;, then it will find the first record that immediately after the corresponding &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;EnterTime&lt;/span&gt;. &lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;With such a long query, debugging it becomes very difficult. I have tried to break it into smaller methods, but so far only succeeded in spinning off one method. The whole query is still can't fit into a page. It's still a pain to read.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;If I were to write my own C# code, although I might need more lines to do it, but at least I could write sub-functions to make things easier to understand. But with LINQ... that's the best I could produce, given my limited time and relatively low exposure in it.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Is there a way to improve on this?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-3433987059191479303?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/3433987059191479303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=3433987059191479303' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3433987059191479303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/3433987059191479303'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/is-linq-becoming-monster.html' title='Is LINQ Becoming a Monster?'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-474687507698276161</id><published>2009-01-14T18:01:00.000+08:00</published><updated>2009-01-14T18:03:49.986+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TypeMock'/><title type='text'>Typemock 5.2 is here, with VB.Net Support!</title><content type='html'>&lt;a href="http://blog.typemock.com/2009/01/get-free-isolator-licnese-for-helping.html"&gt;Typemock 5.2 is here&lt;/a&gt;&amp;nbsp;, with VB.Net support!&lt;br /&gt;&lt;br /&gt;If you don't know about Typemock, you should really have a look.&lt;br /&gt;&lt;br /&gt;The 5.2 version is released. Here's the information from their website:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS'; font-size: 13px;"&gt;&lt;div align="left"&gt;&lt;strong style="color: black; font-weight: bold;"&gt;&lt;span style="color: #cc0000;"&gt;*Begin*&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/div&gt;&lt;begin&gt;&lt;div align="left"&gt;&lt;span style="color: red;"&gt;&lt;strong style="color: black; font-weight: bold;"&gt;&lt;begin&gt;&lt;/begin&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;a href="http://www.typemock.com/vbpage.php" style="color: #006699;"&gt;Programming Visual Basic&lt;/a&gt;&amp;nbsp;applications?&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;Typemock have released a new version of their&amp;nbsp;&lt;a href="http://www.typemock.com/?utm_source=hp&amp;amp;utm_medium=typeblog&amp;amp;utm_campaign=isolatorvb" style="color: #006699;"&gt;unit testing&lt;/a&gt;&amp;nbsp;tool, Typemock Isolator 5.2.&lt;br /&gt;This version includes a new friendly&amp;nbsp;&lt;a href="http://www.typemock.com/vbpage.php?utm_source=vbp&amp;amp;utm_medium=typeblog&amp;amp;utm_campaign=isolatorvb" style="color: #006699;"&gt;VB.NET&amp;nbsp;&lt;/a&gt;API which makes Isolator the best Isolation tool for&amp;nbsp;&lt;a href="http://www.typemock.com/vbpage.php?utm_source=vbp&amp;amp;utm_medium=typeblog&amp;amp;utm_campaign=isolatorvb" style="color: #006699;"&gt;unit testing A Visual Basic (VB) .NET application&lt;/a&gt;.&lt;/div&gt;&lt;div align="left"&gt;Isolator now allows unit testing in VB or C# for many ‘hard to test’ technologies such as&amp;nbsp;&lt;a href="http://typemock.com/sharepointpage.php?utm_source=spp&amp;amp;utm_medium=typeblog&amp;amp;utm_campaign=isolatorvb" style="color: #006699;"&gt;SharePoint&lt;/a&gt;, ASP.NET MVC, partial support for Silverlight, WPF, LINQ, WF, Entity Framework,&amp;nbsp;&lt;a href="http://www.typemock.com/wcfpage.php?utm_source=wcfp&amp;amp;utm_medium=typeblog&amp;amp;utm_campaign=isolatorvb" style="color: #006699;"&gt;WCF unit testing&lt;/a&gt;&amp;nbsp;and more.&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;Note that the first 25 bloggers who blog this text in their blog and tell us about it, will get a&amp;nbsp;&lt;span style="color: #006600;"&gt;&lt;strong style="color: black; font-weight: bold;"&gt;Free Full Isolator license&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;(C#, VB, and Sharepoint included - worth $139 !!!). If you post this in a&amp;nbsp;&lt;strong style="color: black; font-weight: bold;"&gt;&lt;span style="color: #330099;"&gt;VB.NET dedicated blog&lt;/span&gt;&lt;/strong&gt;, you'll get a license automatically (even if more than 25 submit) during the first week of this announcement.&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;Go ahead, click the following link for&amp;nbsp;&lt;a href="http://blog.typemock.com/2009/01/get-free-isolator-licnese-for-helping.html?utm_source=vb_blog&amp;amp;utm_medium=typeblog&amp;amp;utm_campaign=isolatorvbblog" style="color: #006699;"&gt;more information&amp;nbsp;&lt;/a&gt;on how to get your free license.&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: white;"&gt;_&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;strong style="color: black; font-weight: bold;"&gt;&lt;span style="color: red;"&gt;*End*&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;/begin&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-474687507698276161?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/474687507698276161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=474687507698276161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/474687507698276161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/474687507698276161'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/typemock-52-is-here-with-vbnet-support.html' title='Typemock 5.2 is here, with VB.Net Support!'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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-3204586232155134420.post-5735440337750796423</id><published>2009-01-13T18:30:00.013+08:00</published><updated>2009-06-11T23:56:34.891+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Sample'/><category scheme='http://www.blogger.com/atom/ns#' term='FarPoint'/><title type='text'>How to use CustomTypeDescriptor to show Custom Object's Properties in FarPoint</title><content type='html'>&lt;div style="text-align: justify;"&gt;The binding and the displaying of data is a task that is best handled separately from your normal logic code. Microsoft understands this and allows the use of attributes and other decorative thing to make the code more readable. One of the example is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.propertygrid.aspx"&gt;PropertyGrid&lt;/a&gt; example in .Net, where one can set the display name of a property not by writing imperative code, but by putting on a declarative attribute ( &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.displaynameattribute.aspx"&gt;DisplayName&lt;/a&gt; ("My Name")) in order to dictate the run time appearance of the property grid.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;This is one step forward from the good old days when the logic code is cluttered up with trivial appearance information, and there was no delineation between the logic and the markup.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But I am not here to talk about how this &lt;a href="http://www.csharphelp.com/archives/archive119.html"&gt;attribute&lt;/a&gt; thing  is making my code clearer in terms of separation of concern. I am here to show you how to use attributes to use CustomTypeDescriptor to show Custom Object's Properties in &lt;a href="http://www.fpoint.com/"&gt;FarPoint &lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;FarPoint is a spreadsheet-like component. It is a vast improvement over its .Net controls. For example, it can bind to an object with a list as its child property, but we can't do the same thing for .Net's &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.aspx"&gt;DataGridView&lt;/a&gt; . The only downside is, you gonna pay for it. :(&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Assume that we need to display the students' result in data grid. We have the following class definition:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;public class Score&lt;br /&gt;{&lt;br /&gt;[DisplayName("Subject")]&lt;br /&gt;public string SubjectName{get; set;}&lt;br /&gt;[DisplayName("Result")]&lt;br /&gt;public string Grade{get; set;}}&lt;br /&gt;&lt;br /&gt;public class StudentInformation&lt;br /&gt;{&lt;br /&gt;public string Name{get;set;}&lt;br /&gt;public string Id{get;set;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]&lt;br /&gt;public class Student&lt;br /&gt;{&lt;br /&gt;public StudentInformation StudentInfo{ get; set; }&lt;br /&gt;public List&amp;lt;Score&amp;gt; Score{get; set;}&lt;br /&gt;public Student()&lt;br /&gt;{&lt;br /&gt;StudentInfo=new StudentInformation();&lt;br /&gt;Score=new List&amp;lt;Score&amp;gt;();&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;When the information is displayed, we want to show only the "Name" property in StudentInformation; we are not interested in the ID property field however. To accomplish this, we then can define a new type of TypeDescriptionProvider, called MyTypeDescriptionProvider that manipulates how the hierarchical data should be displayed.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;This MyTypeDescriptionProvider needs to be applied on top of the student class in order to take effect. Here's the code:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;public class MyTypeDescriptionProvider : TypeDescriptionProvider&lt;br /&gt;{&lt;br /&gt;private ICustomTypeDescriptor td;&lt;br /&gt;public MyTypeDescriptionProvider(): this(TypeDescriptor.GetProvider(typeof(Student)))&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public MyTypeDescriptionProvider(TypeDescriptionProvider parent): base(parent)&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)&lt;br /&gt;{&lt;br /&gt;if (td == null)&lt;br /&gt;{&lt;br /&gt;td = base.GetTypeDescriptor(objectType, instance);&lt;br /&gt;td = new MyCustomTypeDescriptor(td);&lt;br /&gt;}&lt;br /&gt;return td;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class MyCustomTypeDescriptor : CustomTypeDescriptor&lt;br /&gt;{&lt;br /&gt;public MyCustomTypeDescriptor(ICustomTypeDescriptor parent): base(parent)&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;public override PropertyDescriptorCollection GetProperties()&lt;br /&gt;{&lt;br /&gt;var cols = base.GetProperties();&lt;br /&gt;var studentPD = cols["StudentInfo"];&lt;br /&gt;var studentPDChildProperties = studentPD.GetChildProperties();&lt;br /&gt;PropertyDescriptor[] array = new PropertyDescriptor[2];&lt;br /&gt;array[0] = new SubPropertyDescriptor(studentPD, studentPDChildProperties["Name"], "Student Name");&lt;br /&gt;array[1] = cols["Score"];&lt;br /&gt;var newcols = new PropertyDescriptorCollection(array);&lt;br /&gt;return newcols;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class SubPropertyDescriptor : PropertyDescriptor&lt;br /&gt;{&lt;br /&gt;private PropertyDescriptor _subPD;&lt;br /&gt;private PropertyDescriptor _parentPD;&lt;br /&gt;public SubPropertyDescriptor(PropertyDescriptor parentPD, PropertyDescriptor subPD, string pdname): base(pdname, null)&lt;br /&gt;{&lt;br /&gt;_subPD = subPD;&lt;br /&gt;_parentPD = parentPD;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public override bool IsReadOnly&lt;br /&gt; {&lt;br /&gt; get { return false; }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;public override void ResetValue(object component) { }&lt;br /&gt;&lt;br /&gt;public override bool CanResetValue(object component) { return false; }&lt;br /&gt;public override bool ShouldSerializeValue(object component)&lt;br /&gt;{return true;}&lt;br /&gt;public override Type ComponentType{get { return _parentPD.ComponentType; }}&lt;br /&gt;public override Type PropertyType { get { return _subPD.PropertyType; } }&lt;br /&gt;&lt;br /&gt;public override object GetValue(object component)&lt;br /&gt;{return _subPD.GetValue(_parentPD.GetValue(component));&lt;br /&gt;}&lt;br /&gt;public override void SetValue(object component, object value)&lt;br /&gt;{&lt;br /&gt;_subPD.SetValue(_parentPD.GetValue(component), value);&lt;br /&gt;OnValueChanged(component, EventArgs.Empty);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;To understand the above code I suggest you to step through it in debugger and see how the values changed. In a nutshell, this code, upon execution, will take the a StudentInfo object, rip it apart and get the "Name" property of it and rebind it to the FarPoint Spreadsheet.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;And now you can just bind the Student object to the FarPoint object!&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;public static List&amp;lt;student&amp;gt; StudentList()   &lt;br /&gt;     {          &lt;br /&gt;        List&amp;lt;student&amp;gt; list = new List&amp;lt;student&amp;gt;(); &lt;br /&gt;        Student s = new Student();    &lt;br /&gt;        s.StudentInfo.Name = "John Smith";  &lt;br /&gt;        s.StudentInfo.Id = "100001";     &lt;br /&gt;        Score sc = new Score();    &lt;br /&gt;        sc.SubjectName = "math"; &lt;br /&gt;        sc.Grade = "A";    &lt;br /&gt;        s.Score.Add(sc);      &lt;br /&gt;        sc = new Score();       &lt;br /&gt;        sc.SubjectName = "English"; &lt;br /&gt;        sc.Grade = "A";       &lt;br /&gt;        s.Score.Add(sc);        &lt;br /&gt;        list.Add(s);      &lt;br /&gt;        s = new Student();  &lt;br /&gt;        s.StudentInfo.Name = "David Black";      &lt;br /&gt;        s.StudentInfo.Id = "100002";   &lt;br /&gt;        sc = new Score();      &lt;br /&gt;        sc.SubjectName = "math";         &lt;br /&gt;        sc.Grade = "B";       &lt;br /&gt;        s.Score.Add(sc);     &lt;br /&gt;        sc = new Score();      &lt;br /&gt;        sc.SubjectName = "English";   &lt;br /&gt;        sc.Grade = "A";         &lt;br /&gt;        s.Score.Add(sc);       &lt;br /&gt;        list.Add(s);        &lt;br /&gt;        return list;    &lt;br /&gt;    }  &lt;br /&gt;     &lt;br /&gt; private void Form1_Load(object sender, EventArgs e)   &lt;br /&gt;   {         &lt;br /&gt;     fpSpread1.DataSource = StudentList();       &lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here's the end result:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SDci0Pf3tzU/SWxSbIWRzmI/AAAAAAAAEd4/4DVj5XL1OJo/s1600-h/FarPointResult.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_SDci0Pf3tzU/SWxSbIWRzmI/AAAAAAAAEd4/4DVj5XL1OJo/s320/FarPointResult.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Note also that by using the DisplayName attribute, we can set whatever name we like in the column header. For example, I bind "Subject" to the Score.SubjectName.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;You may ask whether you can do the same for DataGridView control? The answer is part of it. You can slice and dice the sub properties and display only the data you want, but you can't display list inside an object.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Isn't this databinding thing an improvement over imperactive code, whereby you get to loop over the collection ( and the sub collection), set the column header manually and other boring coding in order to display data?&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/3204586232155134420-5735440337750796423?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/5735440337750796423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=5735440337750796423' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5735440337750796423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/5735440337750796423'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/how-to-use-customtypedescriptor-to-show.html' title='How to use CustomTypeDescriptor to show Custom Object&apos;s Properties in FarPoint'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</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/_SDci0Pf3tzU/SWxSbIWRzmI/AAAAAAAAEd4/4DVj5XL1OJo/s72-c/FarPointResult.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3204586232155134420.post-4616150876310472509</id><published>2009-01-08T18:20:00.018+08:00</published><updated>2009-06-22T19:40:43.681+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blog'/><title type='text'>Code Syntax Highlighter on Blogger</title><content type='html'>If you are a programming blogger and you need to post code on your blog, you will definitely find this&lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt; code highlighter tool&lt;/a&gt; handy. Thanks to &lt;a href="http://yacoding.blogspot.com/2008/05/how-to-add-syntax-highlight-to-blogger.html"&gt;Fabio Gomes&lt;/a&gt; , now this blog's code snippets have been upgraded with syntax highlights, and it's now more pleasing to the eyes.&lt;br /&gt;&lt;br /&gt;Here are the steps to install code syntax highlighter on your Blogger's blog. Basically I ripped the procedures from &lt;a href="http://yacoding.blogspot.com/2008/05/how-to-add-syntax-highlight-to-blogger.html"&gt;Fabio Gomes&lt;/a&gt; , but with an update so that &lt;span style="font-weight: bold;"&gt;you don't have to install the Javascript&lt;/span&gt; yourself at somewhere. All you have to do is to edit your template and put on the proper tags, include the proper js libraries, and you are ready to go!&lt;br /&gt;&lt;br /&gt;Here are the steps in order to install the Python language support, you can easily add other languages by finding the corresponding tag mapping &lt;a href="http://code.google.com/p/syntaxhighlighter/w/list"&gt;here&lt;/a&gt; :&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to &lt;a href="http://www.articlealley.com/article_13060_13.html"&gt;your Blogger template&lt;/a&gt; ,  add the following code after the &amp;lt;!-- end outer-wrapper --&amp;gt; tag:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: jscript"&gt;&amp;lt;link href="http://8296241635750553491-a-1802744773732722657-s-sites.googlegroups.com/site/syntaxhighlightersite/Home/SyntaxHighlighter.css&amp;amp;attredirects=0&amp;amp;auth=ANoY7cpVJlNd7vAn3sSqyL9XdtPsh_q-LmvwjhFIpi50UdV12NY3RpR-pJ20wpDYH9TS8n0cNE65iU8f7pVb_J-QK80oqgeFu9Wiks3c0cAhjrPxnT4UQj0-wxH-ZSLCUHlXhdkmDXI9aLISxEH0o4A0A4_KDfS1BoTyL_KiZyrgNo0OT3zm-1bQ8G2zTes9oClbSKuc_VpeDedb8Nmv6RkHOMonZCQ0H8aSEUxlu8j68ghwEDyVOL0%3D" rel="stylesheet" type="text/css"/&amp;gt;&lt;br /&gt;&amp;lt;script language="javascript" src="http://syntaxhighlighter.googlecode.com/svn-history/r57/trunk/Scripts/shCore.js"/&amp;gt;&lt;br /&gt;&amp;lt;script language="javascript" src="http://syntaxhighlighter.googlecode.com/svn-history/r57/trunk/Scripts/shBrushPython.js"/&amp;gt;&lt;br /&gt;&amp;lt;script language="javascript"&amp;gt;&lt;br /&gt;dp.SyntaxHighlighter.BloggerMode();&lt;br /&gt;dp.SyntaxHighlighter.HighlightAll('code');&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Add the tag to surround your code snippet:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: jscript"&gt;&amp;lt;pre name="code" class="py"&amp;gt;&amp;lt;/pre&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;And it should work, just like below:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SDci0Pf3tzU/SWXVGezEKiI/AAAAAAAAEdw/c0ApE_bheyA/s1600-h/code+syntax+highlighter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_SDci0Pf3tzU/SWXVGezEKiI/AAAAAAAAEdw/c0ApE_bheyA/s400/code+syntax+highlighter.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;As pointed out by Ronald, the previous solution doesn't work because Google code doesn't render css/text properly in Firefox. So I have decided to host the css file elsewhere( and resulted in much lengther url!). The above code snippet has been updated with the latest css hosting. Hopefully Firefox team will fix this problem! &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note: &lt;/b&gt;&lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;&lt;b&gt;Code Syntax Highlighter 2.0&lt;/b&gt;&lt;/a&gt;&lt;b&gt; is already available. For instruction on how to use it, refer &lt;/b&gt;&lt;a href="http://dirkdev.blogspot.com/2009/02/moved-to-syntaxhighlighter-20.html"&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;&lt;b&gt; and &lt;/b&gt;&lt;a href="http://blog.webunusual.com/2009/02/enlight-your-blogger-with.html"&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;&lt;b&gt;.&amp;nbsp;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3204586232155134420-4616150876310472509?l=itscommonsensestupid.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itscommonsensestupid.blogspot.com/feeds/4616150876310472509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3204586232155134420&amp;postID=4616150876310472509' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4616150876310472509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3204586232155134420/posts/default/4616150876310472509'/><link rel='alternate' type='text/html' href='http://itscommonsensestupid.blogspot.com/2009/01/code-syntax-highlighter-on-blogger.html' title='Code Syntax Highlighter on Blogger'/><author><name>Soon Hui</name><uri>http://www.blogger.com/profile/12990238997406388445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http:/
