<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Zan's Collection of anything useful &#187; Software</title>
	<atom:link href="http://liangzan.net/index.php/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://liangzan.net</link>
	<description></description>
	<lastBuildDate>Mon, 26 Jul 2010 10:27:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Adding rvm to zsh prompt</title>
		<link>http://liangzan.net/index.php/2010/07/26/adding-rvm-to-zsh-prompt/</link>
		<comments>http://liangzan.net/index.php/2010/07/26/adding-rvm-to-zsh-prompt/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 10:23:23 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[zsh]]></category>
		<category><![CDATA[rvm]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=72</guid>
		<description><![CDATA[Here&#8217;s a simple way to add rvm to your zsh prompt. I think it should work for bash too. It&#8217;ll only show when rvm is in use. And here&#8217;s how it looks. [URL=http://img252.imageshack.us/i/rvmzshprompt.png/][IMG]http://img252.imageshack.us/img252/1047/rvmzshprompt.png[/IMG][/URL]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a simple way to add <a href="http://rvm.beginrescueend.com/">rvm</a> to your <a href="http://www.zsh.org/">zsh</a> prompt. I think it should work for <a href="http://www.gnu.org/software/bash/">bash</a> too.</p>
<p><script src="http://gist.github.com/490372.js"></script></p>
<p>It&#8217;ll only show when rvm is in use. And here&#8217;s how it looks.</p>
<p><script src='http://img252.imageshack.us/shareable/?i=rvmzshprompt.png&#038;p=tl' type='text/javascript'></script><noscript>[URL=http://img252.imageshack.us/i/rvmzshprompt.png/][IMG]http://img252.imageshack.us/img252/1047/rvmzshprompt.png[/IMG][/URL]</noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2010/07/26/adding-rvm-to-zsh-prompt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test for blank elements with Culerity-Cucumber</title>
		<link>http://liangzan.net/index.php/2010/04/07/test-for-blank-elements-with-culerity-cucumber/</link>
		<comments>http://liangzan.net/index.php/2010/04/07/test-for-blank-elements-with-culerity-cucumber/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 07:13:30 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[cucumber culerity rails]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=69</guid>
		<description><![CDATA[How to test for blank elements when using culerity]]></description>
			<content:encoded><![CDATA[<p>When you need to test for blank elements on Culerity, it is better to parse the html. Using Celerity helper methods such as $browser.button will return a Culerity::RemoteObjectProxy object. It does not tell you if it found an element or not. It is a limitation of Culerity. To work around it try this:</p>
<p><script src="http://gist.github.com/358616.js"></script></p>
<p>You can use the above code in the step definitions. </p>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2010/04/07/test-for-blank-elements-with-culerity-cucumber/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to shoot yourself in the foot using a functional programming language</title>
		<link>http://liangzan.net/index.php/2010/03/09/how-to-shoot-yourself-in-the-foot-using-a-functional-programming-language/</link>
		<comments>http://liangzan.net/index.php/2010/03/09/how-to-shoot-yourself-in-the-foot-using-a-functional-programming-language/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:46:31 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=64</guid>
		<description><![CDATA[While preparing for a presentation on Scala, I added some jokes on the functional languages. Here&#8217;s the original version and the new editions Erlang You create a dozen clones of youself, pass the gun to one another in turn to shoot at each other&#8217;s foot Python You have to align your foot 10 steps below [...]]]></description>
			<content:encoded><![CDATA[<p>While preparing for a presentation on Scala, I added some jokes on the functional languages. Here&#8217;s the <a href="http://www.thealmightyguru.com/Humor/Docs/ShootYourselfInTheFoot.html">original</a> version and the new editions</p>
<p><strong>Erlang</strong><br />
You create a dozen clones of youself, pass the gun to one another in turn to shoot at each other&#8217;s foot</p>
<p><strong>Python</strong><br />
You have to align your foot 10 steps below the gun for it to work</p>
<p><strong>Ruby</strong><br />
You pull the trigger to find popcorns popping out of the gun. Someone somewhere has just made all guns shoot popcorns.</p>
<p><strong>Haskell</strong><br />
Close your eyes and picture a gun in your mind. Think about the foot being shot. Open your eyes. You found your foot shot. No sound. No smell. No one else even noticed.</p>
<p><strong>Scala</strong><br />
You pull the trigger and you got shot. You stab your foot with the gun and you got shot.</p>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2010/03/09/how-to-shoot-yourself-in-the-foot-using-a-functional-programming-language/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Cucumber to test Paperclip file attachments</title>
		<link>http://liangzan.net/index.php/2009/08/31/using-cucumber-to-test-paperclip-file-attachments/</link>
		<comments>http://liangzan.net/index.php/2009/08/31/using-cucumber-to-test-paperclip-file-attachments/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 15:23:45 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=51</guid>
		<description><![CDATA[I was using thoughtbot&#8217;s paperclip to attach files. I realised that paperclip only provide shoulda macros for test::unit. No cucumber macros? In the end, I got to write it. Its very simple. The feature is shown here: Define your steps: As celerity does not have an attach_file method, I got to write my own. You [...]]]></description>
			<content:encoded><![CDATA[<p>I was using thoughtbot&#8217;s <a href="http://github.com/thoughtbot/paperclip/tree/master">paperclip</a> to attach files. I realised that paperclip only provide <a href="http://github.com/thoughtbot/shoulda/tree/master">shoulda</a> macros for test::unit. No <a href="https://github.com/aslakhellesoy/cucumber/tree">cucumber</a> macros? In the end, I got to write it. Its very simple.</p>
<p>The feature is shown here: <script src="http://gist.github.com/178507.js"></script></p>
<p>Define your steps:  <script src="http://gist.github.com/178505.js"></script></p>
<p>As <a href="https://github.com/jarib/celerity/tree">celerity</a> does not have an <strong>attach_file</strong> method, I got to write my own. You could see it&#8217;s not hard at all. Remember to define the <strong>browser</strong> variable.</p>
<p>Last, we have some hooks to clean up the test upload files. Remember to place an <strong>@upload</strong> tag in your scenario.</p>
<p><script src="http://gist.github.com/178501.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2009/08/31/using-cucumber-to-test-paperclip-file-attachments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Email_Spec Integrated with Action_Mailer_Cache_Delivery</title>
		<link>http://liangzan.net/index.php/2009/08/20/email_spec-integrated-with-action_mailer_cache_delivery/</link>
		<comments>http://liangzan.net/index.php/2009/08/20/email_spec-integrated-with-action_mailer_cache_delivery/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 06:47:41 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=49</guid>
		<description><![CDATA[For people using the action mailer cache delivery plugin, you can now add the email_spec plugin. The email_spec plugin provides many wonderful helpers to test your emails. Both plugins are now integrated. To use them you need to install both my forks of the plugins: action_mailer_cache_delivery email_spec Install them as plugins following the same instructions [...]]]></description>
			<content:encoded><![CDATA[<p>For people using the action mailer cache delivery plugin, you can now add the email_spec plugin. The email_spec plugin provides many wonderful helpers to test your emails. Both plugins are now integrated. To use them you need to install both my forks of the plugins:</p>
<ul>
<li><a href="http://github.com/liangzan/action_mailer_cache_delivery/tree/master">action_mailer_cache_delivery</a></li>
<li> <a href="http://github.com/liangzan/email-spec/tree/master">email_spec</a></li>
</ul>
<p>Install them as plugins following the same instructions from the README. Don&#8217;t forget to change the git url!</p>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2009/08/20/email_spec-integrated-with-action_mailer_cache_delivery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Troubleshooting an Eclipse PDE Build</title>
		<link>http://liangzan.net/index.php/2009/06/10/troubleshooting-an-eclipse-pde-build/</link>
		<comments>http://liangzan.net/index.php/2009/06/10/troubleshooting-an-eclipse-pde-build/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 06:45:21 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=47</guid>
		<description><![CDATA[In this post, I&#8217;ll share what I&#8217;ve learnt trying to run an Eclipse PDE build. The specific version is Eclipse 3.2. This took me a while to get right(a few months in fact!). The key to getting it right is getting The Dependencies right. So let&#8217;s dive in! Setting up I&#8217;m following the example by [...]]]></description>
			<content:encoded><![CDATA[<p>
  In this post, I&#8217;ll share what I&#8217;ve learnt trying to run an Eclipse PDE build. The specific version is Eclipse 3.2. This took me a while to get right(a few months in fact!). The key to getting it right is getting The Dependencies right. So let&#8217;s dive in!
</p>
<h2>Setting up</h2>
<p>
  I&#8217;m following <a href="http://cubiclemuses.com/cm/blog/2007/pdebuild.html">the example</a> by J Aaron Farr. His example works and is simple enough.
</p>
<p>
  The example code and screencast can be downloaded <a href="http://sourceforge.net/project/showfiles.php?group_id=81506&#038;package_id=231281">here</a>.
</p>
<p>
  If you are following Farr&#8217;s steps, you should end up with 3 directories: builder, features, plugins. You should place all your plugins in the plugins folder, and the features in the features folder. The builder folder can be copied from Farr&#8217;s example. One thing to note is inside the builder folder is a target folder. That contains a copy of Eclipse which is used to build. Make sure that copy has the dependencies(plugins/features) you need.
</p>
<h2>The checklist</h2>
<p>
There&#8217;re lots of things that can go wrong in an Eclipse PDE build. Most times the error messags don&#8217;t tell you clearly what&#8217;s wrong. In my experience, the problems are usually found in the configuration. And it always is a dependency problem.
</p>
<h3>Product</h3>
<p>
The product file is found from your launching plugin.
</p>
<ul>
<li>Does the product contain all of your plugins and their dependencies? Only those plugins/features listed in the product are packaged. So make sure all the things you need are there</li>
<li>Does the build.properties file point to the correct product file?</li>
<li>Does the product contain the features necessary for testing? You need these 2 features org.eclipse.rcp(for launching eclipse) and org.eclipse.test(for testing). Add them as one of the features in the product.</li>
<li>Does the product configuration correct? There&#8217;s the fields like name, id, application, useFeatures found in the attriute line of the product declaration. Make sure these are correct.</li>
</ul>
<h3>build.properties</h3>
<p>
This is one of the configuration files found under builder directory. It is meant for build.xml.
</p>
<ul>
<li>Are the paths correct? Use the full path to make sure everything works first. Switch to relative paths after which.</li>
<li>Is it forward slash or back slash? Ans: its &#8220;/&#8221;</li>
<li>What if I have spaces in the path? Ans: Use double quotes &#8220;&#8221;</li>
</ul>
<p>
For a better explanation, you can try the <a href="http://wiki.eclipse.org/index.php/PDEBuild">eclipse wiki</a>
</p>
<h3>customTarget.xml</h3>
<p>
This is one of the configuration files found under builder directory. It is meant for adding your own ant targets to the build process.
</p>
<ul>
<li>Are u running junit tests? If you do, have you added an ant target task? Is the path correct?</li>
</ul>
<h3>allElements.xml</h3>
<p>
This is one of the configuration files found under builder directory.
</p>
<ul>
<li>Is the name of your feature correct?</li>
</ul>
<h3>Deployment target</h3>
<p>
This is the eclipse that you usually use to build against.
</p>
<ul>
<li>Does it have all the plugins features necessary for the build?</li>
<li>Does it contain only 1 copy of the plugin/feature?(eclipse will always take the newest version of the same plugin. it&#8217;ll cause problems if your build needs the older version)</li>
</ul>
<h3>Build target</h3>
<p>
This is the eclipse target found under builder > target.
</p>
<ul>
<li>Does it have all the plugins features necessary for the build?</li>
<li>Does it contain only 1 copy of the plugin/feature?(eclipse will always take the newest version of the same plugin. it&#8217;ll cause problems if your build needs the older version)</li>
</ul>
<h3>feature.xml for the plugins</h3>
<p>
This is the feature.xml for the feature that contains your plugins.
</p>
<ul>
<li>Is the id correct?</li>
<li>Does it contain all the plugins of your project</li>
<li>Does it have the dependencies listed?</li>
</ul>
<h3>feature.xml for the test plugins</h3>
<p>
This is the feature.xml for the feature that contains your test plugins.
</p>
<ul>
<li>Does it have the required dependency org.apache.ant?</li>
<li>Does it contain the test plugins?</li>
<li>Does it contain org.apache.ant and org.eclipse.core.runtime.compatibility?</li>
</ul>
<h3>General</h3>
<ul>
<li>Is the compiler version correct?</li>
<li>Is Ant and Java configured correctly?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2009/06/10/troubleshooting-an-eclipse-pde-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up a basic project infrastructure with Redmine, Hudson, VSFTP</title>
		<link>http://liangzan.net/index.php/2008/10/23/setting-up-a-basic-project-infrastructure-with-redmine-hudson-vsftp/</link>
		<comments>http://liangzan.net/index.php/2008/10/23/setting-up-a-basic-project-infrastructure-with-redmine-hudson-vsftp/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 09:15:58 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=45</guid>
		<description><![CDATA[Here I would like to share with you the steps to set up the basic project infrastructure. For a project, there&#8217;re a few tools which are absolutely necessary to function File Server Project Wiki Continuous Integration Server Bug/Issue Tracking Source Control With these features in mind, I have identified the software necessary to provide all [...]]]></description>
			<content:encoded><![CDATA[<p>Here I would like to share with you the steps to set up the basic project infrastructure.</p>
<p>For a project, there&#8217;re a few tools which are absolutely necessary to function</p>
<ul>
<li>File Server</li>
<li>Project Wiki</li>
<li>Continuous Integration Server</li>
<li>Bug/Issue Tracking</li>
<li>Source Control</li>
</ul>
<p>With these features in mind, I have identified the software necessary to provide all these functionality.</p>
<ul>
<li>Subversion &#8211; Source Control</li>
<li>Redmine &#8211; wiki, issue tracking, forums, repository viewing</li>
<li>Hudson &#8211; continuous integration</li>
<li>VSFTP &#8211; FTP file server</li>
</ul>
<p>Ubuntu is chosen cos Linux is more stable, its free, its much easier to install stuff in it. But the real reason is cos I&#8217;m a Linux geek.</p>
<h2>What do you need to learn?</h2>
<p>All the work is done on the command line. So you need to be familiar with UNIX shell commands. Another thing is you&#8217;ll be editing text files most of the time. Therefore you have to learn one of the UNIX text editors.</p>
<p><a href="http://cb.vu/unixtoolbox.xhtml">Basic UNIX commands</a></p>
<h2>Unix text editors</h2>
<ul>
<li><a href="http://www.gnu.org/software/emacs/emacs.html">Emacs</a></li>
<li><a href="http://www.vim.org/">Vim</a></li>
<li><a href="http://www.udel.edu/topics/software/general/editors/unix/pico/">Pico</a></li>
<li><a href="http://www.nano-editor.org/">nano</a></li>
</ul>
<h2>What tools do you need?</h2>
<ul>
<li><a href="www.chiark.greenend.org.uk/~sgtatham/putty/">Putty SSH client</a></li>
<li>Hardware &#8211; any old computer will do</li>
<li>OS &#8211; <a href="www.ubuntu.com/products/whatisubuntu/serveredition">Ubuntu Linux Server Edition</a></li>
</ul>
<h2>Setting up the server OS</h2>
<ul>
<li><a href="http://www.cyberciti.biz/tips/howot-install-ubuntu-linux-ssh-server.html">OpenSSH Server</a></li>
<li><a href="http://articles.slicehost.com/2008/4/25/ubuntu-hardy-setup-page-1">Ubuntu Initial Setup</a></li>
<li><a href="http://ubuntuforums.org/showthread.php?t=400693">Fix your IP</a></li>
</ul>
<h2>Redmine Issue Tracking Server</h2>
<ul>
<li><a href="http://articles.slicehost.com/2008/4/30/ubuntu-hardy-ruby-on-rails">Ruby on Rails</a></li>
<li><a href="http://articles.slicehost.com/2008/7/8/ubuntu-hardy-installing-mysql-with-rails-and-php-options">MySQL</a></li>
<li>MySQL Ruby Gems</li>
<li><a href="http://articles.slicehost.com/2008/5/6/ubuntu-hardy-thin-web-server-for-ruby">Thin Web App Server</a></li>
<li><a href="http://www.redmine.org/wiki/1/RedmineInstall">Redmine</a></li>
</ul>
<h2><a href="http://articles.slicehost.com/subversion">Subversion</a></h2>
<h2><a href="http://www.cyberciti.biz/faq/ubuntu-vsftpd-ftp-service-server/">VSFTP FTP Server</a></h2>
<h2>Hudson Continuous Integration Server</h2>
<ul>
<li><a href="http://java.sun.com/javase/downloads/index.jsp">Java JDK</a></li>
<li><a href="https://hudson.dev.java.net/servlets/ProjectDocumentList">Hudson</a></li>
</ul>
<h2><a href="http://maven.apache.org/download.html">Maven</a></h2>
<h2>Static Code Analysis Tools</h2>
<ul>
<li><a href="http://pmd.sourceforge.net">PMD</a></li>
<li><a href="http://findbugs.sourceforge.net">findbugs</a></li>
<li><a href="http://cobertura.sourceforge.net">Cobertura</a></li>
</ul>
<h2>Continuous feedback devices</h2>
<ul>
<li><a href="http://www.x10.com/automation/firecracker.htm">X10 firecracker</a></li>
<li><a href="http://www.arduino.cc/">Arduino</a></li>
</ul>
<h2>How-Tos</h2>
<ul>
<li><a href="http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Devices/BubbleBubbleBuildsInTrouble.rdoc">Pragmatic Automation</a></li>
<li><a href="http://hudson.gotdns.com/wiki/display/HUDSON/Hudson+Build+Status+Lava+Lamps">Hudson Lava Lamps</a></li>
<li><a href="http://www.aboutdebian.com/x10.htm">Debian X10 package</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-ap11146/index.html">IBM Continuous Integration</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2008/10/23/setting-up-a-basic-project-infrastructure-with-redmine-hudson-vsftp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comparing payment gateways for an e-commerce store in Singapore</title>
		<link>http://liangzan.net/index.php/2008/09/18/comparing-payment-gateways-for-an-e-commerce-store-in-singapore/</link>
		<comments>http://liangzan.net/index.php/2008/09/18/comparing-payment-gateways-for-an-e-commerce-store-in-singapore/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 03:11:41 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=42</guid>
		<description><![CDATA[Comparing the various payment gateway options in Singapore]]></description>
			<content:encoded><![CDATA[<p>In this post I hope to share the nuts and bolts of setting up an <a href="http://en.wikipedia.org/wiki/Electronic_commerce">e-commerce</a> website from scratch. The topic of e-commerce is too broad to broach upon in 1 post. So let&#8217;s focus on the <a href="http://en.wikipedia.org/wiki/Payment_gateway">payment gateway</a>. What is a <a href="http://en.wikipedia.org/wiki/Payment_gateway">payment gateway</a>? Why do I need it?  And the more important question: Where to find a <a href="http://en.wikipedia.org/wiki/Payment_gateway">payment gateway</a> in Singapore?</p>
<h2>What is a payment gateway? Why do I need it?</h2>
<p>The <a href="http://en.wikipedia.org/wiki/Payment_gateway">payment gateway</a> is that magic link between your website and the banks. It is how people pay you from the Internet. Without it, you can&#8217;t make any monetary transactions. No transactions means you can&#8217;t sell. Simply put, you must have a <a href="http://en.wikipedia.org/wiki/Payment_gateway">payment gateway</a> if you were to sell things online.</p>
<h2>E-Commerce Features</h2>
<p>Amongst payment gateways, they offer many different pricing plans and different features. Here&#8217;re some of the major features that you should take into consideration.</p>
<ol>
<li><strong>Virtual terminal</strong></li>
<p>Virtual terminal is a virtual credit card swipe machine. It means you can make purchases manually by keying in the credit card details through the virtual terminal. It is helpful in cases when you sell your goods in person. The customer can still pay you by credit card though you don&#8217;t have a swipe machine. But from a customer&#8217;s perspective, I don&#8217;t feel comfortable letting a stranger know my credit card number. Besides, isn&#8217;t your website supposed to be up 24/7? Well, I feel that this feature is helpful but largely non essential.</p>
<li><strong>Support</strong></li>
<p>Support is that helping hand when things don&#8217;t work. For example, you have problems integrating. Or the payment gateway is down, and you don&#8217;t know why. Different plans have different support arrangements. It can range from email support to phone to 24/7 phone support. Though the terms may say 24/7 phone support, it may be an empty promise. If support is important to you, do seek out current customers and find out how&#8217;s their customer service experience.</p>
<li><strong>Hosted/Non hosted</strong></li>
<p>Hosted solutions is when your customers is transferred to the payment gateway&#8217;s website to make payment. While non-hosted solutions means the entire payment process is completed on your website. The main difference is the question of user interface. When your customers are redirected to another website, they&#8217;re facing a completely different user interface. It may make them uncomfortable. Some people feel that it looks unprofessional. Is this a turn off significant enough? Well, it is subjective. If a simple redirect is enough to turn off your customers, doesn&#8217;t that reveal how much they want to buy your product? Rather than working on your interface, why not spend your energy on things that matter?</p>
<li><strong>Credit card</strong></li>
<p>Visa, Mastercard, Discover, etc There&#8217;re a multitude of credit cards available. Not all cards are supported by the gateways. Do check with them. In essence think which credit cards do your customers use. As long as you support the cards they have, you&#8217;re fine.</p>
<li><strong>Need a merchant account?</strong></li>
<p>Usually, non-hosted solutions would require you to have a merchant account. A merchant account is a bank account that is electronically linked to the payment gateway. It means when someone makes payment, the money goes into this merchant account. You will need to pay fees for it. Banks usually impose a setup fee, plus transaction fees plus monthly fees. Don&#8217;t forget you still need to pay the payment gateways.</p>
<li><strong>E-Commerce Technology</strong></li>
<p>Payment gateways offer different ways to integrate with their servers. Some may let you integrate via <a href="http://en.wikipedia.org/wiki/Web_services">web services</a>. While some may force you to use <a href="http://en.wikipedia.org/wiki/JavaServer_Pages">JSP</a>(they told they&#8217;ve never heard of <a href="http://www.rubyonrails.org">Rails</a> before). So ask your programmer to check  out the technologies available before you commit to a payment gateway</ol>
<h2>What are the payments gateways available in Singapore?</h2>
<p>It is at times like this that you realise that the Internet is very US centric. Many of the well known payment gateways like <a href="http://www.authorize.net">Authorize.net</a>, <a href="http://www.braintreepaymentsolutions.com">Braintree</a>, <a href="http://checkout.google.com">Google Checkout</a> operate exclusively in the United States. The choices are pretty limited if you&#8217;re not in US.</p>
<p><strong>Available Options in Singapore</strong></p>
<ul>
<li><a href="https://www.paypal.com/us/cgi-bin/webscr?cmd=_wp-standard-overview-outside">Paypal Website Payment Standard</a></li>
<li><a href="https://www.paypal.com/us/cgi-bin/webscr?cmd=_payflow-gateway-overview-outside">Paypal Payflow Gateway</a></li>
<li><a href="http://www.nets.com.sg/enets/home.htm">E-Nets</a></li>
<li><a href="http://www.e-clearing.com/index.jsp">E-Clearing</a></li>
<li><a href="http://www.worldpay.com">World Pay</a></li>
<li><a href="http://www.dps.co.nz">Payment Express</a></li>
<li>Cybersource(See updates below)</li>
<li>2c2p(Mar 2010)</li>
<li><a href="http://www.payvision.com/">Payvision</a></li>
</ul>
<p>For <a href="https://www.paypal.com/us/cgi-bin/webscr?cmd=_payflow-gateway-overview-outside">Paypal Payflow Gateway</a>, the condition is you need to have a volume of S$5 million a year. If you qualify, congratulations! Visit a <a href="http://www.citibank.com.sg">Citibank</a> branch to open a merchant account and link it to the Payflow Gateway. It took me 2 months, a wasted trip to <a href="http://www.paypal.com">Paypal</a> office in Singapore(where I got chased away), over 10 emails, almost 20 calls to <a href="http://www.paypal.com">Paypal</a>(including overseas calls to UK and US) just to find this out.</p>
<p>Banks do have e-commerce services. But Singapore banks are geared towards servicing <a href="http://en.wikipedia.org/wiki/Bricks_and_mortar_business">brick and mortar companies</a> aiming to build an internet store. They&#8217;re not start-up friendly. What do I mean by that? It is required that you go through an application process, where you fill up many forms, and wait. And in fact, their e-commerce service providers are either <a href="http://www.nets.com.sg/enets/home.htm">E-Nets</a> or <a href="http://www.e-clearing.com/index.jsp">E-Clearing</a>. So please save yourself trouble and possible middleman fees by approaching the payment gateways directly. For overseas payment gateways, they usually offer their services through <a href="http://www.nets.com.sg/enets/home.htm">E-Nets</a>. That is the case for <a href="http://www.dps.co.nz">Payment Express</a> which is based in New Zealand.</p>
<h2>Cost Comparison</h2>
<table>
<tbody>
<tr>
<td></td>
<td>World Pay</td>
<td>Enets</td>
<td>Paypal</td>
<td>Payment express</td>
</tr>
<tr>
<td>Set up fees</td>
<td>S$250</td>
<td>S$200</td>
<td>Free</td>
<td>S$150</td>
</tr>
<tr>
<td>Annual fees</td>
<td>S$650</td>
<td>S$450</td>
<td>Free</td>
<td>S$600</td>
</tr>
<tr>
<td>Transaction fees</td>
<td>4.50%</td>
<td>4.50%</td>
<td>3.4% + S$0.50</td>
<td>100 free transactions, S$0.50 per transaction thereafter</td>
</tr>
</tbody>
</table>
<h2>Final Decision?</h2>
<p>Eventually, we decided to use <a href="https://www.paypal.com/us/cgi-bin/webscr?cmd=_wp-standard-overview-outside">Paypal Website Payment Standard</a>. Why? First, the cost is the lowest. There&#8217;re no set up fees or monthly fees. You only pay when there&#8217;re purchases. Second, the process is easy to set up. All I needed is a credit card. Applying for a merchant account at the banks is a hassle in comparison. There is processing time, and added charges for the set up can be quite hefty.</p>
<h2>How to build an e-commerce cart?</h2>
<p>There&#8217;re all sorts of technologies available. It depends on the person coding it.</p>
<p>If you&#8217;re using <a href="http://www.rubyonrails.org">Rails</a>, I highly recommend the following <a href="http://www.fortytwo.gr/blog/14/Using-Paypal-with-Rails">blog post</a> from <a href="http://www.fortytwo.gr">fortytwo</a>.</p>
<p>Good luck on your e-commerce endeavours!</p>
<h2>Update &#8211; Jan 2010</h2>
<p>I&#8217;ve found out that <a href="http://www.cybersource.com/">Cybersource</a> offers an API for direct integration on your website. Their prices is reasonable too. They have a <a href="http://www.cybersource.com/cgi-bin/pages/prep.cgi?page=/contact_us/sales.html">Singapore office</a>. It&#8217;s best to call them directly. Their emails keep bouncing.</p>
<p>Another option that is coming is <a href="http://www.2c2p.com/">2C2P</a>. They will link to local banks on March 1st 2010. They also have an API.</p>
<h2>Update &#8211; Apr 2010</h2>
<p>Another option is Payvision. They have a local office. Their sales staff can be annoying. They want to see your website before further discussion. With Payvision, you can use <a href="https://cheddargetter.com/">CheddarGetter</a> for recurring payments</p>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2008/09/18/comparing-payment-gateways-for-an-e-commerce-store-in-singapore/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to set up Dual Monitors on Ubuntu Gutsy with Nvidia graphic cards</title>
		<link>http://liangzan.net/index.php/2008/03/12/how-to-set-up-dual-monitors-on-ubuntu-gutsy-with-nvidia-graphic-cards/</link>
		<comments>http://liangzan.net/index.php/2008/03/12/how-to-set-up-dual-monitors-on-ubuntu-gutsy-with-nvidia-graphic-cards/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 10:59:57 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=19</guid>
		<description><![CDATA[I had always wanted a dual monitor setup. It helps you get more things done. Especially in cases when you have to read the manual and configure something at the same time. If you don&#8217;t believe me, Slashdot has some research to prove it. So how do you get it to work? At the moment, [...]]]></description>
			<content:encoded><![CDATA[<p>I had always wanted a dual monitor setup. It helps you get more things done. Especially in cases when you have to read the manual and configure something at the same time. If you don&#8217;t believe me, <a href="http://developers.slashdot.org/article.pl?sid=03/10/09/137232&amp;mode=thread&amp;tid=137&amp;tid=196">Slashdot</a> has some research to prove it. So how do you get it to work?</p>
<p>At the moment, Ubuntu doesn&#8217;t come pre-installed with a wizard(like Windows) where you can configure your screen. You have to install the drivers by yourself. To do that just follow the tutorial from this <a href="http://www.lockergnome.com/linux/2007/06/18/dual-monitors-with-ubuntu/">Linux Fanatics</a>. It demonstrates you how to get <a href="http://www.albertomilone.com/nvidia_scripts1.html">Envy</a>, which sets up the drivers for you automatically.</p>
<p>After that, you got the wizard to help you configure your monitors. Well, that should work for some. But not for me. In the end, I had to configure my xorg.conf. So here&#8217;s my xorg.conf</p>
<p><code><br />
Section "ServerLayout"<br />
Identifier      "Default Layout"<br />
screen "Default Screen" 0 0<br />
Inputdevice     "Generic Keyboard"<br />
Inputdevice     "Configured Mouse"<br />
EndSection</code></p>
<p>Section &#8220;Files&#8221;<br />
EndSection</p>
<p>Section &#8220;Module&#8221;<br />
Load            &#8220;glx&#8221;<br />
Load            &#8220;v4l&#8221;<br />
EndSection</p>
<p>Section &#8220;InputDevice&#8221;<br />
Identifier      &#8220;Generic Keyboard&#8221;<br />
Driver          &#8220;kbd&#8221;<br />
Option          &#8220;CoreKeyboard&#8221;<br />
Option          &#8220;XkbRules&#8221;      &#8220;xorg&#8221;<br />
Option          &#8220;XkbModel&#8221;      &#8220;pc101&#8243;<br />
Option          &#8220;XkbLayout&#8221;     &#8220;us&#8221;<br />
EndSection</p>
<p>Section &#8220;InputDevice&#8221;<br />
Identifier      &#8220;Configured Mouse&#8221;<br />
Driver          &#8220;mouse&#8221;<br />
Option          &#8220;CorePointer&#8221;<br />
Option          &#8220;Device&#8221;        &#8220;/dev/input/mice&#8221;<br />
Option          &#8220;Protocol&#8221;      &#8220;ImPS/2&#8243;<br />
Option          &#8220;ZAxisMapping&#8221;  &#8220;4 5&#8243;<br />
Option          &#8220;Emulate3Buttons&#8221;       &#8220;true&#8221;<br />
EndSection</p>
<p>Section &#8220;Monitor&#8221;<br />
Identifier      &#8220;Digital Panel&#8221;<br />
Gamma   1<br />
EndSection</p>
<p>Section &#8220;Monitor&#8221;<br />
Identifier      &#8220;Analog Panel&#8221;<br />
Gamma   1<br />
Option          &#8220;RightOf&#8221;       &#8220;Digital Panel&#8221;<br />
EndSection</p>
<p>Section &#8220;Device&#8221;<br />
Identifier      &#8220;Failsafe Device&#8221;<br />
Driver          &#8220;nvidia&#8221;<br />
Boardname       &#8220;vesa&#8221;<br />
Option          &#8220;AddARGBVisuals&#8221;        &#8220;True&#8221;<br />
Option          &#8220;AddARGBGLXVisuals&#8221;     &#8220;True&#8221;<br />
Option          &#8220;NoLogo&#8221;        &#8220;True&#8221;<br />
EndSection</p>
<p>Section &#8220;Screen&#8221;<br />
Identifier      &#8220;Default Screen&#8221;<br />
Device          &#8220;Failsafe Device&#8221;<br />
Monitor         &#8220;Digital Panel&#8221;<br />
Defaultdepth    24<br />
Option          &#8220;Monitor-DVI0&#8243;  &#8220;Digital Panel&#8221;<br />
Option          &#8220;Monitor-VGA0&#8243;  &#8220;Analog Panel&#8221;<br />
Option          &#8220;AddARGBVisuals&#8221;        &#8220;True&#8221;<br />
Option          &#8220;AddARGBGLXVisuals&#8221;     &#8220;True&#8221;<br />
Option          &#8220;NoLogo&#8221;        &#8220;True&#8221;<br />
Option          &#8220;TwinView&#8221;      &#8220;true&#8221;<br />
Option          &#8220;TwinViewOrientation&#8221;   &#8220;RightOf&#8221;# &#8220;LeftOf&#8221; &#8220;Above&#8221; &#8220;Below&#8221; &#8220;Clone&#8221;<br />
Option          &#8220;UseEdidFreqs&#8221;  &#8220;True&#8221;<br />
Option          &#8220;MetaModes&#8221;     &#8220;1280&#215;1024,1280&#215;1024&#8243;<br />
SubSection &#8220;Display&#8221;<br />
Depth   24<br />
EndSubSection<br />
Most of the times, xorg.conf is found under /etc/X11/xorg.conf Edit it as a super user, then press Ctrl-Alt-Backspace to restart X windows. And your dual monitors should be up!</p>
<p>My hardware setup</p>
<ul>
<li>Nvidia 8400GS 256mb</li>
<li>1 Acer 17 inch monitor for VGA</li>
<li>1 Samsung 19 inch monitor for DVI</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2008/03/12/how-to-set-up-dual-monitors-on-ubuntu-gutsy-with-nvidia-graphic-cards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Complete Summary</title>
		<link>http://liangzan.net/index.php/2007/11/12/code-complete-summary/</link>
		<comments>http://liangzan.net/index.php/2007/11/12/code-complete-summary/#comments</comments>
		<pubDate>Mon, 12 Nov 2007 05:32:22 +0000</pubDate>
		<dc:creator>zan</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://liangzan.net/?p=12</guid>
		<description><![CDATA[This is the best book I&#8217;ve read on software best practices: Steve McConnell&#8217;s Code Complete. It is full of gems. It is so good that I decided to summarise it and placed it on my desktop so I could look over it whenever I have the time. So here&#8217;s the summary. It&#8217;s far better to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=pd_bbs_sr_1/105-3821572-2612463?ie=UTF8&amp;s=books&amp;qid=1194845416&amp;sr=8-1"></a></p>
<p style="text-align: center"><a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=pd_bbs_sr_1/105-3821572-2612463?ie=UTF8&amp;s=books&amp;qid=1194845416&amp;sr=8-1"><img src="http://liangzan.net/wp-content/uploads/2007/11/code_complete.jpg" title="Code Complete" alt="Code Complete" /></a></p>
<p>This is the best book I&#8217;ve read on software best practices: Steve McConnell&#8217;s Code Complete. It is full of gems. It is so good that I decided to summarise it and placed it on my desktop so I could look over it whenever I have the time. So here&#8217;s the summary. It&#8217;s far better to read the actual book.</p>
<h2>Control Structures Issues</h2>
<ul>
<li>Do expressions use true and false rather than 1 and 0?</li>
<li>Are boolean values compared to true and false implicitly?</li>
<li>Are numeric values compared to their test values explicitly?</li>
<li>Have expressions been simplified by the addition of new boolean variables and the use of boolean functions and decision tables?</li>
<li>Are boolean expressions stated positively?</li>
<li>Do pairs of braces balance?</li>
<li>Are braces used everywhere they&#8217;re needed for clarity?</li>
<li>Are logical expressions fully parenthesized?</li>
<li>Have tests been written in number-line order?</li>
<li>Do Java tests uses cases a.equals(b) style instead of a==b when appropriate?</li>
<li>Are null statements obvious?</li>
<li>Have nested statements been simplified by retesting part of the conditional, converting to if-then-else or case statements, moving nested code into its own routine, converting to a more object oriented design, or have they been improved in some other way?</li>
<li>If a routine has a decision count of more than 10, is there a good reason for not designing it?</li>
</ul>
<h2>Loops</h2>
<h3>Loop selection and creation</h3>
<ul>
<li>Is a while loop used instead of a for loop if appropriate?</li>
<li>Was the loop created from the inside out?</li>
</ul>
<h3>Entering the loop</h3>
<ul>
<li>Is the loop entered from the top?</li>
<li>Is initialisation code directly before the loop?</li>
<li>If the loop is an infinite loop or an event loop, is it constructed cleanly rather than using a kludge such as for i = 1 to 9999?</li>
<li>If the loop is a C++, C, or Java for loop, is the loop header reserved for loop control code?</li>
</ul>
<h3>Inside the loop</h3>
<ul>
<li>Does the loop use {and} or their equivalent to enclose the loop body and prevent problems arising from improper modifications?</li>
<li>Does the loop body have something in it? is it nonempty?</li>
<li>Are housekeeping chores grouped, at the beginning or at the end of the loop?</li>
<li>Does the loop perform one and only one function, as a well defined routine does?</li>
<li>Is the loop short enough to view all at once?</li>
<li>Is the loop nested to 3 levels or less?</li>
<li>Have long loops contents been moved into their own routine?</li>
<li>If the loop is long, is it especially clear?</li>
</ul>
<h3>Loop indexes</h3>
<ul>
<li>If the loop is a for loop, does the code inside it avoid monkeying with the loop index?</li>
<li>Is a variable used to save important loop-index values rather than using the loop index outside the loop?</li>
<li>Is the loop index an ordinal type or an enumerated type &#8211; not floating point?</li>
<li>Does the loop index have a meaningful name?</li>
<li>Does the loop avoid index cross talk?</li>
</ul>
<h3>Exiting the loop</h3>
<ul>
<li>Does the loop end under all possible conditions?</li>
<li>Does the loop use safety counters &#8211; if you instituted a safety-counter standard?</li>
<li>Is the loop&#8217;s termination condition obvious?</li>
<li>If break or continue are used, are they correct?</li>
</ul>
<h2>Defensive Programming</h2>
<h3>General</h3>
<ul>
<li>Does the routine protect itself from bad data?</li>
<li>Have you used assertions to document assumptions, including preconditions and post conditions?</li>
<li>Have assertions been used only to document conditions that should never occur?</li>
<li>Does the architecture or high-level design specify a specific set of error handling techniques?</li>
<li>Does the architecture or high level design specify whether error handling should favour robustness or correctness?</li>
<li>Have barricades been created to contain the damaging effects of errors and reduce the amount of code that has to be concerned about error processing?</li>
<li>Have debugging aids been used in the code?</li>
<li>Have debugging aids been installed in such a way that they can be activated or deactivated without a great deal of fuss?</li>
<li>Is the amount of defensive programming code appropriate &#8211; neither too much or too little?</li>
<li>Have you used offensive programing techniques to make errors difficult to overlook during development?</li>
</ul>
<h2>Exceptions</h2>
<ul>
<li>Has your project defined a standardized approach to exception handling?</li>
<li>Have you considered alternatives to using an exception?</li>
<li>Is the error handled locally rather rather than throwing a nonlocal exception, if possible?</li>
<li>Does the code avoid throwing exceptions in constructors and destructors?</li>
<li>Are all exceptions at the appropriate levels of abstraction for the routines that throw them?</li>
<li>Does each exception include all relevant exception background information?</li>
<li>Is the code free of empty catch blocks?(Or if an empty catch block truly is appropriate, is it documented?)</li>
</ul>
<h2>Security Issues</h2>
<ul>
<li>Does the code that checks for bad data input data check for attempted buffer overflows, SQL injection, HTML injection, integer overflows, and other malicious inputs?</li>
<li>Are all error-return codes checked?</li>
<li>Are all exceptions caught?</li>
<li>Do error messages avoid providing information that would help an attacker break into the system?</li>
</ul>
<h2>Design in Construction</h2>
<h3>Design Practices</h3>
<ul>
<li>Have you iterated, selecting the best of several attempts rather than the first attempt?</li>
<li>Have you tried decomposing the system in several different ways to see which way will work best?</li>
<li>Have you approached the design problem both from the top down and from the bottom up?</li>
<li>Have you prototyped risky or unfamiliar parts of the system, creating the absolute minimum amount of throwaway code needed to answer specific questions</li>
<li>Have your design been reviewed, formally or informally by others?</li>
<li>Have you driven the design to the point that its implementation seems obvious?</li>
<li>Have you captured your design work using an appropriate technique such as a Wiki, email, flip charts, digital photography, UML, CRC cards, or comments in the code itself?</li>
</ul>
<h3>Design Goals</h3>
<ul>
<li>Does the design adequately address issues that were identified and deferred at the architectural level?</li>
<li>Is the design stratified into layers?</li>
<li>Are you satisfied with the way the program has been decomposed into subsystems, packages and classes?</li>
<li>Are you satisfied with the ways the classes have been decomposed into routines?</li>
<li>Are classes designed for minimal interaction with each other?</li>
<li>Are classes and subsystems designed so that you can use them in other systems?</li>
<li>Will the program be easy to maintain?</li>
<li>Is the design lean? Are all its parts strictly necessary?</li>
<li>Does the design use standard techniques and avoid exotic, hard-to-understand elements?</li>
<li>Overall, does the design help minimise both accidental and essential complexity?</li>
</ul>
<h2>Fundamental Data Types</h2>
<h3>Numbers in General</h3>
<ul>
<li>Does the code avoid magic numbers?</li>
<li>Does the code anticipate divide by zero errors?</li>
<li>Are type conversions obvious?</li>
<li>If variables with 2 different types are used in the same expression, will the expression be evaluated as you intend it to be? you know a float with an int, you know what will happen right?</li>
<li>Does the code avoid mixed-type comparisons?</li>
<li>Does the program compile with no warnings?</li>
</ul>
<h3>Integers</h3>
<ul>
<li>Do expressions that use integer division work the way they&#8217;re meant to?</li>
<li>Do integer expressions avoid integer-overflow problems?</li>
</ul>
<h3>Floating-point numbers</h3>
<ul>
<li>Does the code avoid additions and subtractions on numbers with greatly different magnitudes?</li>
<li>Does the code systematically prevent rounding errors?</li>
<li>Does the code avoid comparing floating point numbers for equality?</li>
</ul>
<h3>Characters and Strings</h3>
<ul>
<li>Does the code avoid magic characters and strings?</li>
<li>Are references to strings free of off-by-one errors?</li>
<li>Does C code treat string pointers and character arrays differently?</li>
<li>Does C code follow the convention of declaring strings to be length CONSTANT + 1?</li>
<li>Does C code use arrays of characters rather than pointers, when appropriate?</li>
<li>Does C code initialise strings to NULLs to avoid endless strings?</li>
<li>Does C code use strncpy() rather than strcpy()? And strncat() and strncmp()?</li>
</ul>
<h3>Boolean Variables</h3>
<ul>
<li>Does the program use additional boolean variables to document conditional tests?</li>
<li>Does the program use additional boolean variables to simplify conditional tests?</li>
</ul>
<h3>Enumerated Types</h3>
<ul>
<li>Does the program use enumerated types instead of named constants for their improved readability, reliability, and modifiability?</li>
<li>Does the program use enumerated types instead of boolean variables when a variable&#8217;s use cannot be completely be captured with true and false?</li>
<li>Do tests using enumerated type reserved for invalid values?</li>
<li>Is the first entry in an enumerated type reserved for invalid?</li>
</ul>
<h3>Named Constants</h3>
<ul>
<li>Does the program use named constants for data declarations and loop limits rather than magic numbers?</li>
<li>Have named constants been used consistently? &#8211; meaning its not used as named constants in some places and as literals in others?</li>
</ul>
<h3>Arrays</h3>
<ul>
<li>Are all array indexes within the bonds of the array?</li>
<li>Are all array references free of off-by-one errors?</li>
<li>Are all subscripts on multidimensional arrays in the correct order?</li>
<li>In nested loops, is the correct variable used as the array subscript, avoiding loop index cross talk?</li>
</ul>
<h3>Creating Types</h3>
<ul>
<li>Does the program use a different type for each kind of data that might change?</li>
<li>Are type names oriented toward the real-world entities the types represent rather than toward programming language types?</li>
<li>Are the types names descriptive enough to help document data declarations?</li>
<li>Have you avoided redefining predefined types?</li>
<li>Have you considered creating a new class rather than simply redefining a type?</li>
</ul>
<h2>General Issues in using variables</h2>
<h3>Initialising variables</h3>
<ul>
<li>Does each routine check input parameters for validity?</li>
<li>Does the code declare variables close to where they&#8217;re first used?</li>
<li>Does the code initialise variables as they&#8217;re declared, if possible?</li>
<li>Does the code initialise variables close to where they&#8217;re first used, if it isn&#8217;t possible to declare and initialise them at the same time?</li>
<li>Are counters and accumulators initialised properly and, if necessary, reintialised each time they are used?</li>
<li>Are variables reinitialised properly in code that&#8217;s being executed repeatedly?</li>
<li>Does the code compile with no warnings from the compiler?</li>
<li>If your language uses implicit declarations, have you compensated for the problems they cause?</li>
</ul>
<h3>Other general issues in using data</h3>
<ul>
<li>Do all variables have the smallest possible scope possible?</li>
<li>Are all references to variables as close together as possible, both from each reference to a variable to the next reference and in total live time?</li>
<li>Do control structures correspond to the data types?</li>
<li>Are all declared variables being used?</li>
<li>Are all variables bound at appropriate times &#8211; that is, are you striking a conscious balance between the flexibility of late binding and the increased complexity associated with late binding?</li>
<li>Does each variable have one and only one purpose?</li>
<li>Is each variable&#8217;s meaning explicit, with no hidden meanings?</li>
</ul>
<h2>High Quality Routines</h2>
<h3>Big Picture Issues</h3>
<ul>
<li>Is the reason for creating the routine sufficient?</li>
<li>Have all parts of the routine that would benefit from being put into routines of their own been put into routines of their own?</li>
<li>Is the routine&#8217;s name a strong, clear verb-plus-object name for a procedure or a description of the return value for a function?</li>
<li>Does the routine&#8217;s name describe everything the routine does?</li>
<li>Have you established naming conventions for common operations?</li>
<li>Does the routine have strong, functional cohesion &#8211; doing one and only one thing and doing it well?</li>
<li>Do the routines have loose coupling &#8211; are the routine&#8217;s connections to other routines small, intimate, visible, and flexible?</li>
<li>Is the length of the routine determined naturally by its function and logic, rather than by an artificial coding standard</li>
</ul>
<h3>Parameter- Passing issues</h3>
<ul>
<li>Does the routine&#8217;s parameter list, taken as a whole, present a consistent interface abstraction?</li>
<li> Are the routine&#8217;s parameters in a sensible order, including matching the order of parameters in similar routines?</li>
<li> Are interface assumptions documented?</li>
<li> Does the routine have 7 or fewer parameters?</li>
<li> Is each input parameter used?</li>
<li> Is each output parameter used?</li>
<li> Does the routine avoid using input parameters as working variables?</li>
<li> If the routine is a function, does it return a valid value under all possible circumstances?</li>
</ul>
<h2>Naming Variables</h2>
<h3>General Naming Considerations</h3>
<ul>
<li> Does the name fully and accurately describe what the variable represents?</li>
<li> Does the name refer to the real world problem rather than to the programming language solution?</li>
<li> Is the name long enough that you don&#8217;t have to puzzle it out?</li>
<li> Are computed value qualifiers, if any, at the end of the name?</li>
<li> Does the name use Count or Index instead of Num?</li>
</ul>
<h3>Naming specific kinds of Data</h3>
<ul>
<li> Are loop index names meaningful (something other than i, j, or k if the loop is more than one or two lines long or is nested)?</li>
<li> Have all &#8216;temporary variables&#8217; been renamed to something more meaningful?</li>
<li> Are boolean variables names so that their meanings when they&#8217;re true are clear?</li>
<li> Do enumerated-type names include a prefix or suffix that indicates the category-for example, Color_ for Color_red, color_green, color_blue and so on</li>
<li> Are named constants named for the abstract entities they represent rather than the numbers they refer to?</li>
</ul>
<h3>Naming Conventions</h3>
<ul>
<li> Does the convention distinguish among local, class, and global data?</li>
<li> Does the convention distinguish among type names, named constants, enumerated types and variables?</li>
<li> Does the convention identify input-only parameters to routines in languages that don&#8217;t enforce them?</li>
<li> Is the convention as comparable as possible with standard conventions for the language?</li>
<li> Are names formatted for readability?</li>
</ul>
<h3>Short Names</h3>
<ul>
<li> Does the code use long names(unless it&#8217;s necessary to use short ones?)?</li>
<li> Does the code avoid abbreviations that only save one character?</li>
<li> Are all words abbreviated consistently?</li>
<li> Are the names pronounceable?</li>
<li> Are names that could be misread or mispronounced avoided?</li>
<li> Are short names documented in translation tables?</li>
</ul>
<h3>Common Naming Problems: Have you avoided&#8230;.</h3>
<ul>
<li> Names that are misleading?</li>
<li> Names with similar meaning?</li>
<li> Names that are different by one or two characters?</li>
<li> Names that sound familiar?</li>
<li> Names that use numerals?</li>
<li> Names intentionally mispelled to make them shorter?</li>
<li> Names that are commonly misspelled in English?</li>
<li> Names that conflict with standard library routines names or with predefined variable names?</li>
<li> Totally arbitrary names?</li>
<li>Hard to read characters?</li>
</ul>
<h2>Checklist: Summary of Refactoring</h2>
<h3>Data Level Refactoring</h3>
<ul>
<li>Replace a magic number with a named constant</li>
<li>Rename a variable with a clearer or more informative name</li>
<li>Move an expression inline</li>
<li>Replace an expression with a routine</li>
<li>Introduce an intermediate variable</li>
<li>Convert a multiuse variable to a multiple single-use variables</li>
<li>Use a local variable for local purposes rather than a parameter</li>
<li>Convert a data primitive to a class</li>
<li>Convert a set of type codes to a class or an enumeration</li>
<li>Convert a set of type codes to a class with subclasses</li>
<li>Change an array to an object</li>
<li>Encapsulate a collection</li>
<li> Replace a traditional record with a data class</li>
</ul>
<h3>Statement Level Refactoring</h3>
<ul>
<li>Decompose a boolean expression</li>
<li>Move a complex boolean expression into a well-named boolean function</li>
<li>Consolidate fragments that are duplicated within different parts of a conditional</li>
<li>Use break or return instead of a loop control variable</li>
<li>Return as soon as you know the answer instead of assigning a return value within nested if-then-else statements</li>
<li>Replace conditionals(especially repeated case statements) with polymorphism</li>
<li> Create and use null objects instead of testing for null values</li>
</ul>
<h3>Routine Level refactoring</h3>
<ul>
<li>Extract a routine</li>
<li>Move a routine&#8217;s code inline</li>
<li>Convert a long routine to a class</li>
<li>Substitute a simple algorithm for a complex algorithm</li>
<li>Add a parameter</li>
<li>Remove a parameter</li>
<li>Separate query operations from modification operations</li>
<li>Combine similar routines by parameterising them</li>
<li>Separate routines whose behaviour depends on parameters passed in</li>
<li>Pass a whole object rather than specific fields</li>
<li>Pass specific fields rather than a whole object</li>
<li>Encapsulate downcasting</li>
</ul>
<h3>Class Implementation Refactoring</h3>
<ul>
<li>Change value objects to reference objects</li>
<li>Change reference objects to value objects</li>
<li>Replace virtual routines with data initializations</li>
<li>Change member routine or data placement</li>
<li>Extract specialised code into a subclass</li>
<li> Combine similar code into a superclass</li>
</ul>
<h3>Class Interface refactorings</h3>
<ul>
<li>Move a routine to another class</li>
<li>Convert one class to two</li>
<li>Eliminate a class</li>
<li>Hide a delegate</li>
<li>Remove a middleman</li>
<li>Replace inheritance with delegation</li>
<li>Replace delegation with inheritance</li>
<li>Introduce a foreign routine</li>
<li>Introduce an extension class</li>
<li>Encapsulate an exposed member variable</li>
<li>Remove Set() routines for fields that cannot be changed</li>
<li>Hide routines that are not intended to be used outside the class</li>
<li>Encapsulate unused routines</li>
<li> Collapse a superclass and subclass if their implementations are very similar</li>
</ul>
<h3>System  Level Refactorings</h3>
<ul>
<li>Create a definitive reference source for data you can&#8217;t control</li>
<li>Change unidirectional class association to bidirectional class association</li>
<li>Change bidirectional class association to unidirectional class association</li>
<li>Provide a factory routine rather than a simple constructor</li>
<li> Replace error codes with exceptions or vice versa</li>
</ul>
<h2>Organising Straight line code</h2>
<ul>
<li>Does the code make dependencies among statements obvious?</li>
<li> Do the names of routines make dependencies obvious?</li>
<li> Do parameters to routines make dependencies obvious?</li>
<li> Do comments describe any dependencies that would otherwise be unclear?</li>
<li> Have housekeeping variables been used to check for sequential dependencies in critical sections of the code?</li>
<li> Does the code read from top to bottom?</li>
<li> Are related statements grouped together?</li>
<li> Have relatively independent groups of statements been moved into their own routines?</li>
</ul>
<h2>Table driven Methods</h2>
<ul>
<li>Have you considered table-driven methods as an alternative to complicated logic?</li>
<li> Have you considered table driven methods as an alternative to complicated inheritance structures?</li>
<li> Have you considered storing the table&#8217;s data externally and reading it at run time so that the data can be modified without changing code?</li>
<li> If the table cannot be accessed directly via a straightforward array index, have you put the access-key calculation into a routine rather than duplicating the index calculation in the code?</li>
</ul>
<h2>Unusual Control Structures</h2>
<h3>return</h3>
<ul>
<li> Does each routine use return only when necessary?</li>
<li> Do returns enhance readability?</li>
</ul>
<h3>Recursion</h3>
<ul>
<li> Does the recursion routine include code to stop the recursion?</li>
<li> Does the routine use a safety counter to guarantee that the routine stops?</li>
<li> Is recursion limited to one routine?</li>
<li> Is the routine&#8217;s depth of recursion within the limits imposed by the size of the program&#8217;s stack?</li>
<li> Is recursion the best way to implement the routine? Is it better than simple iteration?</li>
</ul>
<h3>goto</h3>
<ul>
<li> Are gotos used only as a last resort, and then only to make code more readable and maintanable?</li>
<li> If a goto is used for the sake of efficiency, has the gain in efficiency been measured and documented?</li>
<li> Are gotos limited to one label per routine?</li>
<li> Do all gotos go forward, not backward?</li>
<li> Are all goto labels used?</li>
</ul>
<h2>Unusual Data Types</h2>
<h3>Structures</h3>
<ul>
<li> Have you used structures instead of naked variables to organise and manipulate groups of related data?</li>
<li> Have you considered creating a class as an alternative to using structure?</li>
</ul>
<h3>Global data</h3>
<ul>
<li> Are all variables local or of class scope unless they absolutely need to be global?</li>
<li> Do variable naming convention differentiate among local, class and global data?</li>
<li> Are all variables documented?</li>
<li> Is the code free of pseudo-global data &#8211; mammoth objects containing a mishmash of data that&#8217;s passed to every routine?</li>
<li> Are access routines  used instead of global data?</li>
<li> Do access routines provide a level of abstraction beyond the underlying data type implementations?</li>
<li> Are all related access routines at the same level of abstraction?</li>
</ul>
<h3>Pointers</h3>
<ul>
<li> Are pointer operations isolated in routines?</li>
<li> Are pointer references valid, or could the pointer be dangling?</li>
<li> Does the code check pointers for validity before using them?</li>
<li> Is the variable that the pointer references checked for validity before it&#8217;s used?</li>
<li> Are pointers set to null after they&#8217;re freed?</li>
<li> Does the code use all the pointer variables needed for the sake of readability?</li>
<li> Are pointers in linked list freed in the right order?</li>
<li> Does the program allocate a reserve parachute of memory so that it can shut down gracefully if it runs out of memory?</li>
<li> Are pointers used only as a last resort, when no other method is available?</li>
</ul>
<h2>Using Conditionals</h2>
<h3>if-then Statements</h3>
<ul>
<li> Is the nominal path through the code clear?</li>
<li> Do if-then tests branch correctly on equality?</li>
<li> Is the else clause present and documented?</li>
<li> Is the else clause correct?</li>
<li> Are the if and else clauses used correctly &#8211; not reversed?</li>
<li> Does the normal case follow the if rather than the else?</li>
</ul>
<h3>if-then-else-if chains</h3>
<ul>
<li> Are complicated tests encapsulated in boolean function calls?</li>
<li> Are the most common cases tested first?</li>
<li> Are all cases covered?</li>
<li> Is the if-then else-if chain the best implementation &#8211; better than a case statement?</li>
</ul>
<h3>Case statements</h3>
<ul>
<li> Are cases ordered meaningfully?</li>
<li> Are the actions for each case simple &#8211; calling other routines if necessary?</li>
<li> Does the case statement test a real variable, not a phony one that&#8217;s made up solely to use and abuse the case statement?</li>
<li> Is the use of the default clause legitimate?</li>
<li> Is the default clause used to detect and report unexpected cases?</li>
<li> In C, C++, Java, does the end of each case have a break?</li>
<li>Use retesting to refactor nested if-else</li>
</ul>
<h2>Abstract Data Types</h2>
<ul>
<li> Have you thought of the classes in your program as abstract data types and evaluated their interfaces from that point of view?</li>
</ul>
<h3>Abstraction</h3>
<ul>
<li> Does the class have a central purpose?</li>
<li> Is the class well named, and does its name describe its central purpose?</li>
<li> Does the class&#8217;s interface present a consistent abstraction?</li>
<li> Does the class&#8217;s interface make obvious how you should use the class?</li>
<li> Is the class&#8217;s interface abstract enough that you don&#8217;t have to think about how its services are implemented? Can you treat the class as a black box?</li>
<li> Are the class&#8217;s services complete enough that other classes don&#8217;t have to meddle with its internal data?</li>
<li> Has unrelated information been moved out of the class?</li>
<li> Have you thought about subdividing the class into component classes, and have you subdivided it as much as you can?</li>
<li> Are you preserving the integrity of the class&#8217;s interface as you modify the class?</li>
</ul>
<h3>Encapsulation</h3>
<ul>
<li> Does the class minimize accessibility to its members?</li>
<li> Does the class avoid exposing member data?</li>
<li> Dos the class hide its implementation details from other classes as much as the programming language permits?</li>
<li> Does the class avoid making assumptions about its users, including its derived classes?</li>
<li> Is the class independent of other classes? iS it loosely coupled?</li>
</ul>
<h3>Inheritance</h3>
<ul>
<li> Is inheritance used only to model &#8216;is a&#8217; relationships &#8211; that is, do derived classes adhere to the Liskov Substitution Principle?</li>
<li> Does the class documentation describe the inheritance strategy?</li>
<li> Do derived classes avoid overidding non-overridable routines?</li>
<li> Are common interfaces, data, and behaviour as high as possible in the inheritance tree?</li>
<li> Are inheritance trees fairly shallow?</li>
<li> Are all data members in the base class private rather than protected?</li>
</ul>
<h3>Other Implementation issues</h3>
<ul>
<li> Does the class contain about 7 data members or fewer?</li>
<li> Does the class minimise direct and indirect routine calls to other classes?</li>
<li> Does the class collaborate with other classes only to the extent absolutely necessary?</li>
<li> Is all member data initialised in the constructor?</li>
<li> Is the class designed to be used as deep copies rather than shallow copies unless there&#8217;s a measured reason to create shallow copies?</li>
</ul>
<h3>Language-Specific Issues</h3>
<ul>
<li> Have you investigated the language-specific issues for classes in your specific programming language?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://liangzan.net/index.php/2007/11/12/code-complete-summary/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
