tag:blogger.com,1999:blog-52716793382521641752024-03-13T08:32:50.808+05:30A Techie's NotebookMy learnings while programming ...Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.comBlogger32125tag:blogger.com,1999:blog-5271679338252164175.post-59748271620954721542015-11-15T12:32:00.000+05:302015-11-15T12:32:05.862+05:30I have MOVED my blog to life-lessons.inI have moved my blog site to <a href="http://life-lessons.in/">http://life-lessons.in</a><br />
<br />
<b>Please follow my new posts there. Thank you! </b><br />
<b><br /></b>
<div style="text-align: left;">
<a href="http://life-lessons.in/" target="_blank"><img alt="Blog moved to http://life-lessons.in" border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkPs_QN_3-In6gjnK_qj7xCE8tAmjV9-xhxo1OLDDwxyg37PBuUZ4gsmKrPtXWsPIU7nbTbiVRnnzfn3U6PJHSVSFCijIBIKiO7P5eHQOQ-vcXMIU5wlFtHcOQo4wywdl4Z32MJI0uI9o/s400/Blog+moved+to+Life-Lessons.in.png" title="" width="400" /></a></div>
<b><br /></b>Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.comtag:blogger.com,1999:blog-5271679338252164175.post-90524047107432740892015-10-03T12:28:00.002+05:302015-10-03T12:28:52.895+05:30Understanding Vagrant boxes & VMs -- clearing the confusionVagrant is an awesome tool for developers to get their own sandboxed environments to play with. To understand more about "Why Vagrant", you could read my earlier blog post: <a href="http://techie-notebook.blogspot.in/2012/12/vagrant-interesting-approach-to-setup.html">Vagrant: An interesting approach to setup development environments FAST</a>. But, because Vagrant does a lot of things auto-magically under the hoods, most of the times people are left confused when they want to delete / add boxes or VMs. I will try and explain the relationships between Base Boxes, VMs, Virtual Box Instances, etc in this post.<br />
<br />
<b>Note:</b> The term <i>box</i> is loosely used by many people, and hence the confusion has risen even further.<br />
<br />
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
There are 3 different entities involved in running a Vagrant <i>box</i>: </div>
<div>
<ol>
<li><span style="font-family: Helvetica Neue;"><span style="font-size: 14px;"><b>Base Boxes:</b> The .box file is a packaged vagrant box for distribution. You can get boxes from <a href="http://www.vagrantbox.es/">http://www.vagrantbox.es/</a> or people may provide boxes via FTP, Dropbox, or via any other file distribution system on the internet. The base box file path is mentioned in the Vagrantfile using the variable <a href="http://docs.vagrantup.com/v2/vagrantfile/machine_settings.html" target="_blank">config.vm.box_url</a>. This may point to a local file on your machine, or a URL from where vagrant should download the box. The base box is your starting point (FIRST TIME). The base box may be a fresh OS, or may be an OS with certain softwares pre-installed; depending on what the person, distributing the box, wanted to package into it. Read more here: <a href="http://docs.vagrantup.com/v2/boxes/base.html" target="_blank">Base Boxes</a></span></span></li>
<li><span style="font-family: Helvetica Neue;"><span style="font-size: 14px;"><b>Installed Boxes:</b> This is the list of Vagrant boxes installed on your machine. You can see this list by executing the command <a href="http://docs.vagrantup.com/v2/cli/box.html" target="_blank">vagrant box list</a>. You can think of them as vagrant templates available to you for creating machines to work with. These boxes can only be created from base boxes. Usually, you would download a base box, then install it using the <b><i>vagrant</i></b> <b><i>box add</i></b> command, and from then on you don't need the base box, and you can freely delete the base box (to free space on your hard disk). Any new machine you create, only needs one of the installed boxes to create itself from it. The installed boxes are usually placed by Vagrant in the <i><user-home-dir>/.vagrant.d/boxes</user-home-dir></i> folder. Any project on your machine, can use these boxes as base templates to spin off machines. </span></span><b style="font-family: 'Helvetica Neue'; font-size: 14px;">Note:</b><span style="font-family: 'Helvetica Neue'; font-size: 14px;"> When you fire a </span><b style="font-family: 'Helvetica Neue'; font-size: 14px;"><i>vagrant box remove</i></b><span style="font-family: 'Helvetica Neue'; font-size: 14px;"> command, you are in effect removing the box template from your machine. After that you can only add it back using a base box (.box file). </span></li>
<li><span style="font-family: Helvetica Neue;"><span style="font-size: 14px;"><b>Machines: </b>When you fire the <a href="http://docs.vagrantup.com/v2/cli/up.html" target="_blank"><i>vagrant up</i></a> command, you are asking for a VM to be started (based on the <i>Vagrantfile</i> specification in the current directory). This is the Virtual Box Machine Instance that you are spinning off to work with. When you fire the <a href="http://docs.vagrantup.com/v2/cli/halt.html" target="_blank"><i>vagrant halt</i></a> command, you are shutting down the current VM (based on the Vagrantfile specification in the current directory). You can also confirm this if you launch your Virtual Box GUI -- it will show you a running machine when you say <b><i>vagrant up</i></b>, and a shut down machine when you say <b><i>vagrant halt</i></b>. These machines are usually stored in a hidden <b><i>.vagrant</i></b> folder in the same directory from where you fired the <b><i>vagrant up</i></b> command. <b>Note: </b>When you perform a <a href="http://docs.vagrantup.com/v2/cli/destroy.html" target="_blank">vagrant destroy</a>, you are destroying the VM (and not the template box from which you created this machine). Usually this VM is called "<i>default</i>".</span></span></li>
</ol>
<div>
<br /></div>
</div>
<div>
The confusion actually occurs because of the way <b style="font-style: italic;">vagrant up</b> command behaves. When you do a <i><b>vagrant up</b>, </i>Vagrant will bring up the VM which was halted earlier. But, if the VM was destroyed (using vagrant destroy), or was never created in the first place, then Vagrant will <b>create</b> the VM from the installed box template. Hence, when you do <b><i>vagrant destroy</i></b>, followed by <b><i>vagrant up</i></b>, you are in fact creating a new VM from the installed template boxes. Therefore, its common for people to only do a <i><b>vagrant halt</b> (or suspend) </i>so that they can start off from where they left. You will choose to <i><b>destroy</b> </i>only if you don't care about any changes in the VM, and want to free the space occupied by the VM on your disk. </div>
<div>
<br /></div>
<div>
In development mode, since most code changes are done on your local file-system, and developers use Vagrant just to "run" the code, it is OK if they destroy the VM, at the end of your work day. The next time you perform a <b><i>vagrant up</i></b>, it will recreate the VM, <a href="http://docs.vagrantup.com/v2/provisioning/index.html" target="_blank">provision</a> it, and run with the latest code (think of them like <a href="http://martinfowler.com/bliki/PhoenixServer.html" target="_blank">Phoenix boxes</a>).</div>
<div>
<br /></div>
<div>
Note that, the <b style="font-style: italic;">vagrant up</b> command will also download the base box and install it as a box template if it detects that this is the first time this box is being brought up. After this, you can choose to delete the downloaded .box file (or store it on some long-term disk store), since its not being used in your vagrant workflow. Vagrant required the .box file only to install and create a box template in your machine. All further VM creations will use the installed boxes.</div>
<div>
<br /></div>
<div>
Hopefully this explanation clears up any doubts you have about the relationship between .box files, vagrant boxes, Virtual Box Machines, etc. </div>
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-17801618554478470932015-08-16T16:05:00.001+05:302015-08-16T16:10:41.169+05:30Installing ThoughtWorks Go Server & Agent on a Digital Ocean dropletToday I experimented with installing <a href="http://www.go.cd/" target="_blank">ThoughtWorks Go</a> CD Server and agent on a Digital Ocean droplet. Here are the steps (pretty simple!):<br />
<br />
<b>Step 1:</b> Create a <b>CentOS</b> 6.7x64 droplet. Give it some name, e.g: "centos-droplet". Ensure that you choose a minimum of 1GB RAM, and enable <i>Private Networking</i> option while creating the droplet.<br />
<br />
<b>Step 2:</b> Login as root to your new droplet.<br />
<pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; font-family: monospace, monospace; font-size: 14px; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><code langs="" style="background-color: transparent; border-radius: 2px; color: #333333; font-family: monospace, monospace; margin: 0px; padding: 0px;">ssh root@<ip-address-of-your-droplet></ip-address-of-your-droplet></code></pre><b>Step 3:</b> Add host entry for your droplet name. For instance, if your droplet is called "centos-droplet":<br />
<pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; font-family: monospace, monospace; font-size: 14px; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><code langs="" style="background-color: transparent; border-radius: 2px; color: #333333; font-family: monospace, monospace; margin: 0px; padding: 0px;">vi /etc/hosts</code></pre><pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; font-family: monospace, monospace; font-size: 14px; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><code langs="" style="background-color: transparent; border-radius: 2px; color: #333333; font-family: monospace, monospace; margin: 0px; padding: 0px;">centos-droplet localhost <ip_of_droplet></ip_of_droplet></code></pre><b>Step 4:</b> Install Open JDK7 (you can also install just the JRE)<br />
<pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; font-family: monospace, monospace; font-size: 14px; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><code langs="" style="background-color: transparent; border-radius: 2px; color: #333333; font-family: monospace, monospace; margin: 0px; padding: 0px;">sudo yum install <b>java-1.7.0-openjdk-devel</b></code></pre><b>Step 5:</b> Ensure that java is installed<br />
<pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; font-family: monospace, monospace; font-size: 14px; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><code langs="" style="background-color: transparent; border-radius: 2px; color: #333333; font-family: monospace, monospace; margin: 0px; padding: 0px;">java -version</code></pre><b>Step 6:</b> Now register ThoughtWorks Go YUM repo by executing the following command:<br />
<pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; font-family: monospace, monospace; font-size: 14px; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><pre style="-webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; background-color: #f7f7f7; border-radius: 3px; border: 0px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; line-height: 1.45; margin-bottom: 16px; overflow: auto; padding: 16px; white-space: pre-wrap; word-wrap: normal;"><code class="lang-bash" style="-webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; line-height: inherit; margin: 0px; max-width: initial; overflow: initial; padding: 0px; white-space: pre; word-wrap: normal;"><span class="hljs-built_in" style="-webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; box-sizing: border-box; color: #f5871f;">echo</span> <span class="hljs-string" style="-webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; box-sizing: border-box; color: #718c00;">"
[gocd]
name = GoCD YUM Repository
baseurl = http://dl.bintray.com/gocd/gocd-rpm
enabled = 1
gpgcheck = 0
"</span> > /etc/yum.repos.d/thoughtworks-go.repo</code></pre></pre><b>Step 7:</b> Install the Go Server<br />
<pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><span style="color: #333333; font-family: monospace, monospace;"><span style="font-size: 14px;">yum install -y <b>go-server</b></span></span></pre><div><code langs="" style="background-color: transparent; border-radius: 2px; margin: 0px; padding: 0px;"></code><br />
<div style="color: black; font-family: Times;"><code langs="" style="background-color: transparent; border-radius: 2px; margin: 0px; padding: 0px;"><b>Step 8:</b> Check if Go Server service is running. If not, start the service. </code></div><code langs="" style="background-color: transparent; border-radius: 2px; margin: 0px; padding: 0px;"> <pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><span style="color: #333333; font-family: monospace, monospace;"><span style="font-size: 14px;">service go-server <b>status</b> </span></span></pre><pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><span style="color: #333333; font-family: monospace, monospace;"><span style="font-size: 14px;">service go-server <b>start</b> </span></span></pre><div style="color: #333333; font-family: monospace, monospace;"><div style="color: black; font-family: Times;"><b>Step 9: </b> The server should now be running on port 8153. You should be able to open a browser on your laptop, and connect to the remote Digital Ocean droplet Go server UI on <a href="http://ip-of-your-droplet:8153/go" target="_blank">http://ip-of-your-droplet:8153/go</ip-of-your-droplet></a></div><div style="color: black; font-family: Times;"><b><br />
</b></div><div style="color: black; font-family: Times;"><b>Step 10:</b> Install the Go Agent (on the same droplet)</div><div style="color: black; font-family: Times;"><code langs="" style="border-radius: 2px; margin: 0px; padding: 0px;"></code></div><pre class="code-pre " style="-webkit-text-stroke-width: 0px; background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; color: black; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; margin: 0px 0px 28px; orphans: auto; overflow: auto !important; padding: 13px 17px; text-align: start; text-indent: 0px; text-transform: none; widows: 1; word-spacing: 0px; word-wrap: normal;"><span style="color: #333333; font-family: monospace, monospace;"><span style="font-size: 14px;">yum install -y <b>go-agent</b></span></span></pre><div style="color: black; font-family: Times;"><b>Step 11:</b> Check if Go Agent service is running. If not, start the service. </div><pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; color: black; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><span style="color: #333333; font-family: monospace, monospace;"><span style="font-size: 14px;">service go-agent <b>status</b> </span></span></pre><pre class="code-pre " style="background-color: rgba(0, 0, 0, 0.0470588); border-radius: 3px; box-sizing: border-box; color: black; margin-bottom: 28px; overflow: auto !important; padding: 13px 17px; word-wrap: normal;"><span style="color: #333333; font-family: monospace, monospace;"><span style="font-size: 14px;">service go-agent <b>start</b> </span></span></pre></div></code></div>On the droplet you can run '<b>ps -ef | grep java'</b> to see the server, and agent processes.<br />
<br />
At this point, both your Go server and agent should be up and running. If you go to the "<a href="http://www.go.cd/documentation/user/current/navigation/agents_page.html" target="_blank">Agents</a>" tab in your Go Server UI, you should be able to see this agent registered (with the same name as your droplet machine name). <br />
<br />
That's it. You should be good to Go! If there are any issues, you can check server logs at <b>/var/log/go-server</b> and agent logs at <b>/var/log/go-agent</b> folder.<br />
<br />
<h4>Related Links</h4><div><ol><li>https://www.digitalocean.com/community/tutorials/how-to-install-java-on-centos-and-fedora</li>
<li>http://www.go.cd/documentation/user/current/installation/install/server/linux.html</li>
<li>http://www.go.cd/documentation/user/current/installation/install/agent/linux.html</li>
</ol></div>Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-71453103774052819352015-02-14T15:19:00.002+05:302015-02-14T15:19:09.229+05:30i18n: Building Applications for Multiple Countries and Languages<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
Nowadays, many softwares and websites are i18n enabled. If you don't yet understand what is meant by Internationalisation, Globalisation and Localisation in software, then this <a href="http://en.wikipedia.org/wiki/Internationalization_and_localization" target="_blank">Wikipedia link</a> is your friend.</div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
I have worked on a couple of projects where we had to make the application multi-country savvy, and I think it would be good to pen down various areas we considered, and the tools we used. Note that, these practices are from the perspective of a Java/Scala project, but can easily be adapted to other platforms too -- since the basic requirements are similar.</div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
1) <b>External Files for String: </b>Maintain all user visible strings in properties files (not log messages though!). We maintain the English version (messages.properties), and the translation teams maintain translations for other languages (messages_fr_FR.properties, etc). Read about locales <a href="http://tutorials.jenkov.com/java-internationalization/locale.html" target="_blank">here</a>. </div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
2) <b>No Automated Translations:</b> Having automated translations does not really work in practice, because the "context" is important, which can't be figured out by just looking at the string. For instance, on one of our projects we had provided a feature in our website (internal version), which allowed translators to hit a url with a key name so that they can see the page where the key will be used -- and get a context of what we are looking at, and how their translation will look on screen. Automated translations usually target tourists wanting to communicate or researchers wanting to understand a particular sentence, and hence are devoid of the subtleties you want in a website / application. Poor translation is also a put-off for the users of the application. Therefore, I'd recommend staying away from Automated Translation tools / websites. </div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
3) <b>Simple Scripted Tests for Errors: </b>On one project we wrote a tool for performing basic checks for received translation files against our reference properties file. These error are usually not easy to catch by "humans", and can slip through. For instance: </div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<ol>
<li>Check if a key has not been translated</li>
<li>Check if a key is missing in a file</li>
<li>Check if a key is "extra" in a file</li>
<li>Check for UTF-8 encoding issues</li>
<li>Check if a key is duplicate </li>
<li>Check if a key doesn't have a value</li>
</ol>
</div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
These checks are very easy to code via a script, and can be run by the translation teams themselves. This concept is called "<a href="http://techie-notebook.blogspot.in/2012/07/poka-yoke-applying-mistake-proofing-to.html" target="_blank">Poka Yoke</a>".</div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
4) <b>Grammatical considerations: </b>Also, many UI messages cannot be concatenated, because grammatically nouns/adjectives/verbs come in different positions in different languages. So a message: "Your owe Rs 100" has to be externalized in YAML/properties file as "You owe {0}" (where {0} will be replaced by price+currency), and this context needs to be informed to the translators.</div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
5) <b>Singular/Plural: </b>Also singular / plural word construction needs to be different in different languages. So messages change based on whether you are displaying "1" or "more". </div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
6) <b>Numbers/Dates/UoM: </b>Besides UI strings, we also need to look out for currencies, dates, time-zones, units-of-measures, etc since they vary by country, and hence need to use formatters appropriately. Same goes for <a href="http://en.wikipedia.org/wiki/Decimal_mark#Examples_of_use" style="color: #1155cc;">Numbers</a>, where decimal separators are different by country (dot in some, and comma in others). For instance, use "Number" fields to store numbers in DB / Models, and use UTC to store Date/Time values, and then format them appropriately on screen depending on the locale.</div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
7) <b>Case-insensitive checks: </b>Case-insensitive code also needs to be written properly, because for instance in Turkish there are 4 'i', and your code may not do the correct comparison for case-insensitive strings, if it doesn't have a "locale". (<a href="http://www.i18nguy.com/unicode/turkish-i18n.html" style="color: #1155cc;">Why languages fail with the Turkish I</a>). For this reason, in Java/Scala, the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#toUpperCase(java.util.Locale)" style="color: #1155cc;">toUpperCase API</a> takes a "locale" as a parameter (and mentions the Turkish I case in documentation).</div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
8) <b>UTF-8:</b> Of course, you use <b>Unicode</b> character set and <b>UTF-8</b> encoding everywhere. For more details read: <a href="http://www.joelonsoftware.com/articles/Unicode.html" target="_blank">The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)</a>. For Java/Scala programs on Windows, don't forget to set JAVA_OPTS="-Dfile.encoding=UTF-8". </div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
<br /></div>
<div style="color: #222222; font-family: arial, sans-serif; font-size: small;">
These are all the points I could think of right now. If more areas strike me, I will post updates to this blog. Meanwhile, if you have practical tips to share in this regard, I'd love to hear. </div>
<div>
<br /></div>
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com1tag:blogger.com,1999:blog-5271679338252164175.post-40567827041538692332015-02-01T00:23:00.000+05:302015-02-01T00:23:58.608+05:30(Comic) Addicted to Programming<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwVNb1RBld_cATCwkoV_ODR5aINYoNTICwZMY_5jlZpua3-MeQTKJVMKDOY5fyo1X81Ub1RKSOvc7ibxAaPL6w-m8sMXmjgv6JE9gpWJy44nM3qA3Q2A2KL34PimPASUhSabTjrbQI-Hk/s1600/Screen+Shot+2015-01-31+at+8.47.27+pm.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwVNb1RBld_cATCwkoV_ODR5aINYoNTICwZMY_5jlZpua3-MeQTKJVMKDOY5fyo1X81Ub1RKSOvc7ibxAaPL6w-m8sMXmjgv6JE9gpWJy44nM3qA3Q2A2KL34PimPASUhSabTjrbQI-Hk/s1600/Screen+Shot+2015-01-31+at+8.47.27+pm.png" height="571" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<a href="http://www.pixton.com/comic/omvuay8h" target="_blank">Link to Comic on Pixton</a>Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-57918604443063263302015-01-25T14:06:00.001+05:302015-02-02T01:18:30.755+05:30(Comic) Git Push Keys<a href="http://www.pixton.com/comic/h1vdckci" target="_blank">Link to this comic on Pixton</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXJgAyU-9OKjesox-wqhMRxsePzwJoOPUkRk5PSVdBUH14TBYO34cg_-RFm81kXy1PliUyKmffcNogu82Df_R4BDNcDNLkZJkEycZyoYgMjk2y7ijiGOFUwvdhQJwC35nYLMS_JrMBs28/s1600/Screen+Shot+2015-01-25+at+10.28.35+am.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br />
</a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXJgAyU-9OKjesox-wqhMRxsePzwJoOPUkRk5PSVdBUH14TBYO34cg_-RFm81kXy1PliUyKmffcNogu82Df_R4BDNcDNLkZJkEycZyoYgMjk2y7ijiGOFUwvdhQJwC35nYLMS_JrMBs28/s1600/Screen+Shot+2015-01-25+at+10.28.35+am.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXJgAyU-9OKjesox-wqhMRxsePzwJoOPUkRk5PSVdBUH14TBYO34cg_-RFm81kXy1PliUyKmffcNogu82Df_R4BDNcDNLkZJkEycZyoYgMjk2y7ijiGOFUwvdhQJwC35nYLMS_JrMBs28/s1600/Screen+Shot+2015-01-25+at+10.28.35+am.png" height="302" width="640" /></a></div>
<br />
<br />
A very interesting blog related to a real life incident where a developer accidentally pushed his Amazon EC2 keys onto github: <a href="http://www.devfactor.net/2014/12/30/2375-amazon-mistake/" target="_blank">My $2375 Amazon EC2 Mistake</a><br />
<br />
<b>[Update: 1/Feb/2015]</b><br />
GITRob: A ruby tool to scan Github Projects for Sensitive Information:<br />
<a href="http://michenriksen.com/blog/gitrob-putting-the-open-source-in-osint/">http://michenriksen.com/blog/gitrob-putting-the-open-source-in-osint/</a>Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-20432976232896792042015-01-22T01:12:00.000+05:302015-02-01T00:24:08.697+05:30(Comic) Defensive Programming<a href="http://www.pixton.com/comic/d2yrnf2h" target="_blank">Link to Comic</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilLOT7kKdeyqmtMeD6Sbia8oZeO6-EvJyX6AgwLrE3KYstwq4rTMq-G3drxWAvaqmr_p-6FHac2HTNp9KxG6ag1aiLv1lUFWwoM-c2xZpXGEJ55gOk-KPaBge8SXCGi85KG-MAyTydFqc/s1600/Screen+Shot+2015-01-21+at+9.35.28+pm.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilLOT7kKdeyqmtMeD6Sbia8oZeO6-EvJyX6AgwLrE3KYstwq4rTMq-G3drxWAvaqmr_p-6FHac2HTNp9KxG6ag1aiLv1lUFWwoM-c2xZpXGEJ55gOk-KPaBge8SXCGi85KG-MAyTydFqc/s1600/Screen+Shot+2015-01-21+at+9.35.28+pm.png" height="312" width="640" /></a></div>
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-10719606296798079472015-01-21T02:12:00.000+05:302015-02-01T00:24:21.487+05:30(Comic) The Standup Cycle -- in Agile TeamsIf you have daily stand ups, then you should be familiar with this standup ritual that occurs few times each year.<br />
<br />
<a href="http://www.pixton.com/comic/um0w65cm" target="_blank">Link to comic on Pixton</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL3LBg7_AHBE75qrLklTrF9_ZyfCcFwV5Mp8NySpg6hzQuVAVBHlNaEXZ_kl7LJGRKQFmBrKdLv_HReQbopgZ4DvnF8HjYSBl9_Aa0iVsurVBFBTwfvYFeiozbNXg8BqkscTWhaNbce9s/s1600/Screen+Shot+2015-01-20+at+10.39.41+pm.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL3LBg7_AHBE75qrLklTrF9_ZyfCcFwV5Mp8NySpg6hzQuVAVBHlNaEXZ_kl7LJGRKQFmBrKdLv_HReQbopgZ4DvnF8HjYSBl9_Aa0iVsurVBFBTwfvYFeiozbNXg8BqkscTWhaNbce9s/s1600/Screen+Shot+2015-01-20+at+10.39.41+pm.png" height="492" width="640" /></a></div>
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-84533738264843810182015-01-20T01:38:00.002+05:302015-02-01T00:24:34.516+05:30(Comic) Programming Language or the Algorithm -- The choices we sometimes make<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisEedVvGumeJe3x2pGBXCR8UTWKpZlSXYBcAFnHAuv0fgkDLaiYcQTgRSWpflojcVva2CpM1CDeRREwFU18HBK-Yl63q-fp9rkVCpJVjn4Y6SRq4dtB29cnOZ19ZOSDAcE0Zg70SpsSXg/s1600/Screen+Shot+2015-01-19+at+10.03.31+pm.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisEedVvGumeJe3x2pGBXCR8UTWKpZlSXYBcAFnHAuv0fgkDLaiYcQTgRSWpflojcVva2CpM1CDeRREwFU18HBK-Yl63q-fp9rkVCpJVjn4Y6SRq4dtB29cnOZ19ZOSDAcE0Zg70SpsSXg/s1600/Screen+Shot+2015-01-19+at+10.03.31+pm.png" height="480" width="640" /></a></div>
<br />
<br />
<a href="http://www.pixton.com/comic/9y8th4di" target="_blank">Link to Comic</a> <br />
<i><br /></i>
<i>This comic was inspired by the Levenshtein algorithm I was reading about yesterday. </i><br />
<br />
Sometimes we love the tools so much, that we forget the technology. Try and solve problems too. Its fun.<br />
<br />
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-81656525173143942632015-01-20T00:20:00.000+05:302015-02-01T00:24:52.211+05:30(Comic) Comfortable in RedA second attempt at making a comic on <a href="http://www.pixton.com/" target="_blank">Pixton</a>. People on teams need to ensure they practice what they preach, and not get comfortable with status-quo.<br />
<br />
<a href="http://www.pixton.com/comic/ykrflbcd" target="_blank">Link to Comic</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk7CAXTlg2cKYm1JXU7ZuvbY2EV35lkatEVHuBqkXO_Sv_dNIZbh7w1yDI9qMe2ACPtKf3N5sCMC-P9vC5raUu2KJi7F2A1BYsggvIRfH8vI8zIASICzzsV7PwpdjBqXyoJxY2JiEQNzs/s1600/Screen+Shot+2015-01-21+at+12.24.36+pm.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk7CAXTlg2cKYm1JXU7ZuvbY2EV35lkatEVHuBqkXO_Sv_dNIZbh7w1yDI9qMe2ACPtKf3N5sCMC-P9vC5raUu2KJi7F2A1BYsggvIRfH8vI8zIASICzzsV7PwpdjBqXyoJxY2JiEQNzs/s1600/Screen+Shot+2015-01-21+at+12.24.36+pm.png" height="490" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-88033237686128071332015-01-20T00:16:00.000+05:302015-02-01T00:25:00.090+05:30(Comic) Collaboration vs Coding -- A developer's challengeI decided to try out <a href="http://pixton.com/" target="_blank">Pixton</a> to create some comics. Here is my first attempt:<br />
<br />
<a href="http://www.pixton.com/comic/xihmxkwa">LINK TO COMIC</a><br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU_h8oieI9Xf3dPyicLqLom0PAlnjzrUauxdQmqfKQlaVyqqvJZw39aCdo4cYhYS2yyiESG9lfh0doB62I9-u5MZqc94crU_qtVRHFe-GhxEb-LAnraAKV3mtzKGd7WL8aWdRGCbgH9DE/s1600/Screen+Shot+2015-01-19+at+8.42.40+pm.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU_h8oieI9Xf3dPyicLqLom0PAlnjzrUauxdQmqfKQlaVyqqvJZw39aCdo4cYhYS2yyiESG9lfh0doB62I9-u5MZqc94crU_qtVRHFe-GhxEb-LAnraAKV3mtzKGd7WL8aWdRGCbgH9DE/s1600/Screen+Shot+2015-01-19+at+8.42.40+pm.png" height="440" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Collaboration vs Coding</td></tr>
</tbody></table>
<br />
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-75388014874013627092014-11-28T22:23:00.001+05:302014-11-29T12:25:32.134+05:30The Way To A New Project --- Becoming EffectiveYou move to a new project. Its exciting. It holds promise of something awesome (usually). You are ready to dive. You want to learn things fast. You want to contribute. You want to become effective. You want to be welcomed. And then maybe, become invaluable.<br />
<br />
There are some tips I have learnt on how to navigate new projects effectively. I would look forward to hearing what you have to say about yours. And, I suspect there will be more.<br />
<br />
<br />
<ol>
<li>The more experience you get on multiple tools and technologies, the easier it is to move to newer projects with newer tech stacks. </li>
<li>The more you master one programming language, the more difficult you find adopting another language. Especially if you are a perfectionist.</li>
<li>The more you expose yourself to various languages, the better you program in all previous languages.</li>
<li>The quicker you understand the domain of the project, the quicker you understand the code of your project (unless people in your team like naming everything as “data” or “temp” or “value” or “count”, in which case you are doomed, and you should quit).</li>
<li>Understand the database of your project. The database brings insights into relationships between entities. These relationships will remain permanent for a very long time, while the code on top that manipulates the data, will keep getting refactored. Once you get a handle on the data, the code becomes much easier to understand. </li>
<li>Pair with QAs. Perform testing. You will understand the domain, and the interdependencies very fast.</li>
<li>Ask questions, write notes, and volunteer to take sessions on project topics / technologies. Nothing teaches us faster, than the pressure to not look foolish. </li>
<li>Try and understand the reasoning behind why features are being built, because 60% of the features in all software products are built for the same purpose — each using a different technology or tool. For instance, every corporate website has Search, Page Analytics, Splunk Style Logging, Meta-Tagging for SEO, JS/CSS optimizations for performance, Device & Browser Detection and Cookie Manipulations for Personalization, Responsive design, REST based integration, SSL, etc. </li>
<li>Follow a user journey in code — to understand all the layers involved, and how they interact. A decent codebase, usually has a few patterns that are repetitively used. </li>
<li>Use a good IDE for navigating code. They will help you understand code paths, callers, implementors, etc very quickly. I use IntelliJ (Cmd+Alt+F7), and Sublime. </li>
<li>Read the unit test to understand the class. Of course, I work at ThoughtWorks, and therefore have the luxury of seeing self documenting unit tests. And this means, I am indebted to ensure that readers of my code also get a good unit test.</li>
<li>Hunt out for project documentation — especially those which pertain to large scale features, architecture, etc — as they summarize information quite well.</li>
<li>Sign up for devops tasks. They will help you understand the interdependencies between systems very quickly.</li>
<li>Find out who's who on the project (customer side), so that you know whom to reach out to, for what insight. </li>
<li>Have patience. It takes a minimum of 3 months to “feel” effective. And then another 3 to be “one-with-the-project”.</li>
</ol>
<br />
<br />
I know. It’s not a shortcut. It’s a path.<br />
<div>
<br /></div>
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-26093770292590525862014-07-26T12:13:00.003+05:302015-11-15T12:23:37.354+05:30Difference between sorted, sortWith and sortBy in ScalaScala collections provide you three options for sorting: <b>sorted</b>( ), <b>sortWith</b>( ) and <b>sortBy</b>( ). Here is a <i>simplified</i> explanation:<br />
<br />
<b>sorted</b><br />
Will sort the list using the natural ordering (based on the implicit Ordering passed)<br />
<br />
<b>sortBy (an attribute)</b><br />
Sort by a given attribute using the attribute's type.<br />
e.g. given a list of Person objects, if you want to sort them in ascending order of their age (which is an Int), you could simply say: <span style="font-family: "courier new" , "courier" , monospace;">personList.sortBy(_.age)</span><br />
<br />
<span style="font-family: inherit;"><b>sortWith (a function)</b></span><br />
<span style="font-family: inherit;">Takes a comparator function. Useful when you want to specify a custom sorting logic. </span><br />
<span style="font-family: inherit;">e.g. if you want to sort by age descending, you could write this as: </span><br />
<span style="font-family: inherit;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">personList.sortWith{(leftE,rightE) => </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> leftE.age > rightE.age</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: inherit;">Or, more simply: </span><span style="font-family: "courier new" , "courier" , monospace;">personList.sortWith(_.age > _.age)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: inherit;">Checkout this gist for a full example: </span><br />
<span style="font-family: inherit;"><a href="https://gist.github.com/gsluthra/80555ed4af24bea244b5">https://gist.github.com/gsluthra/80555ed4af24bea244b5</a></span><br />
<script src="https://gist.github.com/gsluthra/80555ed4af24bea244b5.js"></script><br />
<span style="font-family: inherit;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-22887395638274545122014-05-04T17:33:00.000+05:302014-05-04T17:34:32.192+05:30Using Puppet to open port 80 through the iptables commandPuppet provides an add-on module called <a href="https://forge.puppetlabs.com/puppetlabs/firewall" target="_blank">firewall</a> to manage firewall configuration on your system. I tried it out, and ended up locking myself out of my Vagrant box. All I needed to do was open port 80 on my VM, and the steps mentioned in the Puppet Firewall module setup page seemed like an overkill for something so simple.<br />
<br />
So, I decided to understand the iptables command better. This <a href="http://wiki.centos.org/HowTos/Network/IPTables" target="_blank">writeup on centos website</a> is an excellent introduction to understanding iptables. Armed with this knowledge, I realized all I needed was:<br />
<ol>
<li>Make a single rule entry on my Centos VM for allowing incoming traffic on port 80.</li>
<li>Save the state of the iptables rule, so that on restart of the iptables service, this new rule is not lost.</li>
</ol>
<b><i>Note</i>:</b> <i>I am working on puppet v3.2.3 and Cento v6.4 Minimal Version.</i><br />
<br />
If you google, most places you will find this command for opening port 80 (<i>didn't work!</i>):<br />
<br />
<b style="background-color: #fff2cc;"> sudo iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT</b><br />
<br />
What this command essentially says is append (<b>-A</b>) a new rule to <b>INPUT</b> traffic chain, where for <b>NEW</b> connections of type <b>tcp</b>, and destination port (<b>-dport</b>) <b>80</b>, perform <b>ACCEPT</b> connections.<br />
<br />
This command did not actually open the port for me because this command "APPENDS" the rule right at the end of the iptable chain. By default, Centos already came with a rule:<br />
<br />
<b style="background-color: #fff2cc;">-A INPUT -j REJECT --reject-with icmp-host-prohibited</b><br />
<br />
The line I added, got appended <b>AFTER</b> this rule. Meaning, all requests were getting blocked anyways, and hence my rule to allow incoming traffic to port 80 was never evaluated.<br />
<br />
Therefore, what we need to do is to insert our rule <b><u>before</u></b> the REJECT rule. To do that, we use the -I (insert) switch, instead of the -A (Append) switch. The -I switch needs to know the line number of the rule to insert at. To see the line numbers of various, use the following command:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC_ILf02jA7CwRbX_oa2wLsDvmN4LY6JC8qzoz4eBockRhNsBq-9FuU6lUv92DHn1mDelL1BDrxnD46UyS-AUj0U831rfdvW1P7G0pZpv6K1Vuigk-6WTypn72j9Mu7iPKZnzF0NMCigs/s1600/ipTables_List_Line_NUmbers_Command.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC_ILf02jA7CwRbX_oa2wLsDvmN4LY6JC8qzoz4eBockRhNsBq-9FuU6lUv92DHn1mDelL1BDrxnD46UyS-AUj0U831rfdvW1P7G0pZpv6K1Vuigk-6WTypn72j9Mu7iPKZnzF0NMCigs/s1600/ipTables_List_Line_NUmbers_Command.png" height="220" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ipTables with Line Number (Notice Line 5 Has the Reject Rule)</td></tr>
</tbody></table>
<span style="background-color: #cccccc;"><br />
</span> Using the "<b style="background-color: #fff2cc;">sudo iptables -L -n -v --line-numbers</b>" you can see that by default line number 5 has the REJECT rule for all traffic.<br />
<br />
Hence the command that we need to allow incoming traffic to port 80 is (<i>works!</i>):<br />
<b><br />
</b> <b style="background-color: #fff2cc;">sudo iptables -I INPUT 5 -m state --state NEW -p tcp --dport 80 -j ACCEPT</b><br />
<b><br />
</b>Now, our rules gets inserted at line 5, and everything works. Based on this knowledge, our puppet script now looks like this (using two execs):<br />
<br />
<script src="https://gist.github.com/gsluthra/ae547a28e646408130e6.js"></script><br />
<br />
The <b>first <i>exec</i></b> fires the command only if it does not detect a port 80 entry (using the <i>unless</i> attribute). The <i>unless </i>attribute tests that a grep on <i>iptables-save</i> command contains port 80 entry. The <i>iptables-save</i> command allows us to see the current iptables rule configuration in a parseable format.<br />
<br />
The <b>second <i>exec</i></b><b style="font-style: italic;"> </b>fires the <i>service iptables save</i> command to save the configuration to disk. This command needs to be fired only if the first exec actually makes an entry. Hence we specify <i>notify</i> attribute in <i>exec</i> and also mark this <i>exec</i> with <i>refreshonly => true</i> so that it is executed only as part of the notify process, and should not be executed otherwise.<br />
<br />
That's it! You should be good to go now! You can do the same thing if you also want to make an entry for port 443 (SSL) or anything similar. <br />
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-54959479979121488012014-04-13T20:45:00.000+05:302014-04-13T21:24:51.941+05:30Reading Environment Variables in PuppetPuppet uses a tool called <a href="http://docs.puppetlabs.com/learning/variables.html#facts" target="_blank">Facter</a> to discover <i>facts</i> about the system it is going to provision. Some examples of these facts are: <i>$operatingsystem</i>, <i>$hostname</i>, <i>$processorcount</i>, etc. These facts are available as variables in puppet to use in manifests. You can see the full list here: <a href="http://docs.puppetlabs.com/facter/latest/core_facts.html" target="_blank">Factor 2.0 Core Facts</a>.<br />
<br />
If you want an environment variable, or a bash script parameter to be available to puppet, you need to make it available as a Facter <i>fact</i><b style="font-style: italic;">. </b>You can do that by simply setting a variable whose name is prefixed with the "<b>FACTER_"</b> string.<br />
<br />
So for instance, if you wanted to make a variable called say <b><i>$my_module_name</i></b> available within puppet, and wanted its value to be equal to environment variable PRODUCT_MODULE_NAME, you could do the following in a bash script that invokes puppet:<br />
<br />
<blockquote class="tr_bq">
export FACTER_my_module_name=$PRODUCT_MODULE_NAME</blockquote>
<br />
Now, <b><i>$my_module_name</i></b> variable will be available within your puppet manifests.<br />
<br />
<br />
<h4>
Setting a Default if Environment Variable is not set</h4>
<br />
To take this further, if you wanted your puppet variable to have a default value, if no environment variable was set, you could specify it in puppet manifest (.pp) file like this:<br />
<br />
<blockquote class="tr_bq">
$module_name = $my_module_name ? {<br />
undef<span class="Apple-tab-span" style="white-space: pre;"> </span>=> "Admin_Module",<br />
default => $my_module_name <span class="Apple-tab-span" style="white-space: pre;"> </span><br />
}</blockquote>
<br />
Note that the above code uses a different variable name called "<b><i>module_name</i></b>", whose value will be set to "Admin_Module" if <i>$my_module_name</i> is un-defined, else it will be set to value of "<i>my_module_name</i>" variable.<br />
Now you can use <b><i>$module_name</i></b> in all your puppet manifests (instead of using <i>$my_module_name</i>).<br />
<br />
To see a sample code where I did this in Bahmni Hospital Management System provisioning scripts, check out this Github commit: <a href="https://github.com/Bhamni/bahmni-environment/commit/2fb5377a47eb0baec553609a81e0c0ba604a79e2" target="_blank">Example</a>.<br />
<br />
<b>Tip:</b> If you wish to debug what <i>facts</i> are being set in your system, you can use this snippet to print all facts to a file: <a href="http://www.puppetcookbook.com/posts/see-all-client-variables.html" target="_blank">Printing all puppet facts</a>.<br />
<br />
<b>Tip: </b>If your puppet script is running with "sudo", then the environment variables set in current environment won't be passed to the sudo environment. If you want that, then use "-E" switch with sudo to pass environment variables forward.<br />
<br />
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-76132657310456416902014-03-01T12:59:00.001+05:302014-03-01T13:00:16.030+05:30Autojump: A neat command line utility that saves me tons of time<a href="https://github.com/joelthelion/autojump" target="_blank">Autojump</a> is a really neat utility that complements the <b>cd</b> command very nicely. For instance if I have a folder called "my_project", I can just say "<b><span style="font-family: Courier New, Courier, monospace;">j project</span></b>", and the auto jump command will directly jump to this directory (wherever it is in my filesystem).<br />
<br />
How does it work?<br />
<br />
Autojump tracks how much time you spend in your command line on a specific folder. And builds a weight chart. So, if you have spent enough some time in your <b>my_project</b> directory on command line, and you say "<b><span style="font-family: Courier New, Courier, monospace;">j project</span>"</b>, it will check its registry and jump to the highest match. And, the best thing is you don't even need to specify the full name. Partial names work!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkk8vv88oD46WSRRUcD1GmmBA1vuy8UnES1g8WBB-p84vOywwqJjc_R0Xa9eGJxUbOfZfxej6q9FfDi1f6nFvsJXbl0GjG9i2r2dwqeJhGeLiFpsMr5uTHMA-hRKzuRTQx_Q0h8eLwp4g/s1600/Screen+Shot+2014-03-01+at+12.53.03+pm.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkk8vv88oD46WSRRUcD1GmmBA1vuy8UnES1g8WBB-p84vOywwqJjc_R0Xa9eGJxUbOfZfxej6q9FfDi1f6nFvsJXbl0GjG9i2r2dwqeJhGeLiFpsMr5uTHMA-hRKzuRTQx_Q0h8eLwp4g/s1600/Screen+Shot+2014-03-01+at+12.53.03+pm.png" height="241" title="" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Autojump in action</td></tr>
</tbody></table>
<br />
Install zsh. And install autojump. You will see a super productivity increase on command line.<br />
<br />
<b>Platforms Supported:</b> Linux and Mac.<br />
<br />
<b>To install on Mac:</b><br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">brew install autojump</span></blockquote>
And then copy the single line printed by brew install into your .bashrc or .zshrc file. After that go to command line, cd into a directory. Then cd to some other directory. And type "j <first_dir>". You will see it work! </first_dir><br />
<br />
Thanks to my colleague Ankit Dhingra for introducing me to auto jump. Goodbye to cd aliases.<br />
<br />
<b>Related Links:</b><br />
<a href="https://github.com/robbyrussell/oh-my-zsh">https://github.com/robbyrussell/oh-my-zsh</a><br />
<a href="https://github.com/joelthelion/autojump">https://github.com/joelthelion/autojump</a><br />
<br />
<br />
<br />
<br />Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-75588433047897605342014-02-01T21:54:00.000+05:302014-02-01T21:54:40.925+05:30Displaying a Bootstrap Modal in Rails with an AJAX call I am in the process of building a simple Learning Management Solution. I wanted to display a Bootstrap modal pop-up on click of the <b>Add Capsules</b> button. The idea was that on click of this button, an AJAX call should be made to the server, with the current Learning Path ID, so that it can query the DB, and find the potential capsules to be returned for the learning path. I would return an HTML snippet as response, which I wanted to insert into the <b>body</b> of the modal.<br />
<br />
See screenshot below of how it looks:<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuuOBImZc11p13SWkHy_cova3NEq645-AKQAK7AGfVRW1COcaqrtSamQAAK1mwL1QQZPAaJ9SVzMGONE_UncwAYkq1mzKLvfRmDz-B9AzzCxnwDtLNvNZkyC4vYQFH_FntFl7f5GWCzhE/s1600/Screen+Shot+2014-02-01+at+9.25.30+PM.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuuOBImZc11p13SWkHy_cova3NEq645-AKQAK7AGfVRW1COcaqrtSamQAAK1mwL1QQZPAaJ9SVzMGONE_UncwAYkq1mzKLvfRmDz-B9AzzCxnwDtLNvNZkyC4vYQFH_FntFl7f5GWCzhE/s1600/Screen+Shot+2014-02-01+at+9.25.30+PM.png" height="364" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bootstrap Modal Pop up on click of Add Capsules button (with Ajax response body)</td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Check out this commit on Github to see the work that was needed: <a href="https://github.com/gsluthra/dakshina/commit/ecc5642f519544a55e534e1766fef7889bc9382d" target="_blank">Bootstrap Modal Commit</a>. The comment on the Github explains the details. It was actually quite easy once you know how.<br />
<br />
I believe instead of sending an HTML snippet from the backend, a better practice is to send JSON data, and then construct the HTML at the browser via javascript. I guess, I could do that too, but this was really simple to do. I might modify it to return JSON some time in the recent future.<br />
<br />
Reference:<br />
<br />
<ul>
<li><a href="http://getbootstrap.com/javascript/#modals-examples">http://getbootstrap.com/javascript/#modals-examples</a></li>
<li><a href="http://stackoverflow.com/questions/20026132/using-bootstrap-3-0-modals-to-load-dynamic-remote-content-within-an-iframe">http://stackoverflow.com/questions/20026132/using-bootstrap-3-0-modals-to-load-dynamic-remote-content-within-an-iframe</a></li>
</ul>
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-36635538635397996672014-01-10T20:50:00.000+05:302015-11-15T12:23:22.020+05:30Using Capybara and RSpec assertions in Page ObjectsOn my Rails project, I am using RSpec and Capybara to write functional tests. I did not want to specify any HTML elements in my Capybara feature files, since that makes the feature files brittle to HTML / CSS changes. It also violates the DRY principle and basic code hygiene.<br />
<br />
So, I decided to refactor out my HTML centric Capybara code into separate Page Objects. If you are unfamiliar with Page Objects, then read the following:<br />
<br />
<ul>
<li><a href="http://martinfowler.com/bliki/PageObject.html" target="_blank">Page Objects by Martin Fowler</a></li>
<li><a href="http://robots.thoughtbot.com/better-acceptance-tests-with-page-objects" target="_blank">Better Acceptance Tests with Page Objects</a></li>
</ul>
<br />
<br />
The Page Object pattern for encapsulating HTML centric DSL is a common pattern followed while writing UI level functional tests in ThoughtWorks.<br />
<br />
The problem I was facing when I refactored my code into Page objects was that I was unable to use the RSpec '<b>expect</b>' syntax in Page Objects. Turns out all I had to do in my page objects was:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">include RSpec::Matchers</span></blockquote>
<br />
Here is the full code from my project on Github.<br />
<a href="https://github.com/gsluthra/dakshina/tree/master/spec/features">https://github.com/gsluthra/dakshina/tree/master/spec/features</a><br />
<br />
The appropriate feature files and page objects in a GIST:<br />
<a href="https://gist.github.com/gsluthra/8356015">https://gist.github.com/gsluthra/8356015</a><br />
<script src="https://gist.github.com/gsluthra/8356015.js"></script>Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com2tag:blogger.com,1999:blog-5271679338252164175.post-65447137430694740272013-09-21T09:59:00.000+05:302013-09-21T09:59:18.645+05:30Transferring all contacts from BlackBerry to Android Galaxy PhoneYesterday, I was attempting to switch over from my Blackberry, to a Samsung Galaxy S, and spent quite some time figuring out.<br />
<br />
There are many links on the internet. Finally here is what I did:<br />
<br />
1. <b>Bluetooth Option</b>: I tried pairing my galaxy with blackberry in bluetooth. The pairing was successful. Then in bluetooth menu of Blackberry itself, when you select a bluetooth device, you will find an option saying "Transfer Contacts". I did that, and BB said -- 400 Contacts Transferred, but the Galaxy only added the FIRST contact! So basically, this method did not work for me :(<br />
<br />
2. <b>Using BlackBerry Desktop Software (for Mac)</b>:<br />
<br />
<ul>
<li>I chose to "Sync Contacts" with Computer. There it gave me a warning, that this is the first time you are syncing contacts what should it do. I chose "MERGE", since I didn't anyways have any contacts on my Mac. </li>
<li>After this, when I typed "Address Book" in my SpotLight, I saw all my Contacts had been successfully imported into my Local Address Book of Mac.</li>
<li>In Address Book preferences, if you select "Local On My Mac", there was an option for syncing Address book with Google Account. I gave it credentials of a new Gmail account I have created solely for Contact syncing with my android. Once I did that, all my contacts were sent to GMAIL. Then I unchecked the Gmail sync option from AddressBook since I didn't want any more sync to happen. </li>
<li>I registered that particular GMAIL account in my Android (in Settings -> Account), and chose to sync only the CONTACTS. </li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrjZINcr2WuicQBz8gN5Kw8e4KL_J52n8YHNUawRkqGYeQzkFEUTAFepNKgXqZoQHUNIVvvd6IHSeYTK1VcIlpW3IzqQmcTeZva0zqu6IczwKHfkBX9txLorEVLu3TH3ZCQRbJ6zGCSEA/s1600/Screen+Shot+2013-09-21+at+9.52.16+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrjZINcr2WuicQBz8gN5Kw8e4KL_J52n8YHNUawRkqGYeQzkFEUTAFepNKgXqZoQHUNIVvvd6IHSeYTK1VcIlpW3IzqQmcTeZva0zqu6IczwKHfkBX9txLorEVLu3TH3ZCQRbJ6zGCSEA/s320/Screen+Shot+2013-09-21+at+9.52.16+AM.png" width="320" /></a></div>
<br />
<br />
<br />
That's it. The contacts are now in my phone.. and they will stay 2 way synch with my Android-only GMAIL account, which is kinda neat.<br />
<br />
Bye Bye Blackberry. I will miss the tiny red blinking light of my Blackberry.<br />
<div>
<br /></div>
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com4tag:blogger.com,1999:blog-5271679338252164175.post-37017383558634334002013-06-21T08:15:00.000+05:302013-06-21T08:15:00.974+05:30Tata Photon & Reliance USB Dongle Connection Settings<b>TATA PHOTON</b><br />
<br />
In India, if you want to manually enter your TATA Photon connection settings (on a Mac or Linux or Windows), here is what you need to do: <br />
<br />
Telephone Number: #777<br />
Account Name: 9XXXXXXXXX@photon.ttsl.in (prefix your tata photon phone number which usually starts with a 9)<br />
Password: internet<br />
<br />
<br />
<b>RELIANCE NON-3G DONGLE</b><br />
<br />
In India, if you want to manually enter your Reliance USB dongle connection settings (on a Mac or Linux or Windows), here is what you need to do: <br />
<br />
Telephone Number: #777<br />
Account Name: 9XXXXXXXXX (your reliance phone number which usually starts with a 9)<br />
Password: Same as your reliance phone number which you entered above as account name<br />
<br />
This should do the trick, since this is what worked for me on my Mac. <br />
<br />
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.comtag:blogger.com,1999:blog-5271679338252164175.post-78390977039423429282012-12-31T11:52:00.000+05:302012-12-31T11:54:57.256+05:30Debugging code in IntelliJ for OpenMRS JettyYesterday, while working on <a href="http://openmrs.org/" target="_blank">OpenMRS</a> I needed to debug some Java code. I could not easily find steps for debugging OpenMRS with IntelliJ on Google, so I decided to write down my findings.<br />
<br />
I used IntelliJ's <b>Remote JVM</b> option to connect to OpenMRS Jetty server.<br />
<br />
<b>Step1: Configure Jetty to open a remote debugging port:</b><br />
<br />
One needs to set the following in MAVEN_OPTS so that Jetty opens a remote debugging port for IntelliJ to connect to:<br />
<br />
<script src="https://gist.github.com/4417799.js"></script><br />
<br />
I updated the MAVEN_OPTS in my home directory's .zshrc file (since i use ZSH shell on Mac). You may need to set the MAVEN_OPTS variable appropriately for your environment (Windows/Linux/etc) so that it is correctly set, before starting Jetty on command line.<br />
<br />
The value "51696" that I have mentioned above is the port where I want the debugger to run. The memory options have been set because Jetty gives an OutOfMemoryException with OpenMRS if the memory is insufficient (and by default, it seems to be insufficient - so you are better off setting the memory values too).<br />
<br />
Now, start Jetty normally using "mvn jetty:run". You will notice the following line being printed by Jetty to indicate that debug port has been opened.<br />
<br />
<blockquote class="tr_bq"><span style="font-family: Courier New, Courier, monospace;">Listening for transport dt_socket at address: 51696</span></blockquote><br />
<b>Step2: Configure IntelliJ to connect to the remote debugging port of Jetty:</b><br />
<b><br />
</b> In IntelliJ, go to "Run" menu, and select "Edit Configurations". Select the "Defaults" option on the left menu, and click on the "+" on the Right side, to create a new configuration. In that Select "Remote" option, and enter options as "localhost" and port as "51696" (same as the port number in step 1 above). Put "Name" as anything you like. I have set it as "OpenMRS Jetty".<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHnIKWLNdYMgC1-zsRwV368yYEm56yFNs6lwzmhzionI6KEcPeEa9kHtbaFKCarbw2nDfXWMsqPCOYfxTvuc4Zx9hxzRecbNmtD4ftaMFv398IS1wk25jTpY1pMq2eTJuSFefSclK51CI/s1600/Screen+Shot+2012-12-31+at+11.29.33+AM.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="368" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHnIKWLNdYMgC1-zsRwV368yYEm56yFNs6lwzmhzionI6KEcPeEa9kHtbaFKCarbw2nDfXWMsqPCOYfxTvuc4Zx9hxzRecbNmtD4ftaMFv398IS1wk25jTpY1pMq2eTJuSFefSclK51CI/s640/Screen+Shot+2012-12-31+at+11.29.33+AM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">OpenMRS Jetty Remote Debugger in IntelliJ IDE</td></tr>
</tbody></table><br />
<br />
That's it! Now you can debug using this "OpenMRS Jetty" configuration. On clicking "Debug" you should see the debugger connected to Jetty, and breakpoints will start working. <br />
<br />
<b>Note: </b><i>If you want to perform Debugging on Eclipse, then basic process would be the same. Step1: No change. Step2: In Eclipse choose Remote JVM Debugging option (similar to IntelliJ).</i><br />
<br />
There are other ways of debugging OpenMRS too, especially if you run Jetty from inside the IDE. But, for me, this method was simpler. <br />
<br />
<br />
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com3tag:blogger.com,1999:blog-5271679338252164175.post-80811532298194826982012-12-16T20:13:00.002+05:302012-12-18T20:12:54.295+05:30Vagrant -- An interesting approach to setup development environments FAST!<br />
<br />
If you have never heard of <a href="http://vagrantup.com/" target="_blank">Vagrant</a>, or are interested in understanding what is Vagrant, then this blog should be useful to you.<br />
<br />
<h2>
The Need for Vagrant</h2>
Recently, I was involved in organizing the <a href="http://gracehopper.org.in/2012/conference/hackathon/">GraceHopper Hackathon</a> in Bangalore where we expected about 50+ women developers to come and contribute to Humanitarian software projects like <a href="http://openmrs.org/" target="_blank">OpenMRS</a>, <a href="http://rapidftr.com/" target="_blank">RapidFTR</a>, and others. Since all participants would mostly be new to the projects, and we had a single day to get them going, and contribute -- we wanted to ensure that people spend as less a time on setup of their dev environment as possible.<br />
<br />
I got introduced to Vagrant, because at the GraceHopper Hackathon, one of the projects - RapidFTR, provides people with the ability to <a href="https://github.com/rapidftr/RapidFTR/wiki/Using-a-VM-for-development" target="_blank">setup their environment using a Vagrant box</a> -- and that's when I realized -- this is interesting!<br />
<br />
Setting up a development environment for many projects now-a-days isn't a matter of simply running a script or downloading a piece of software. On most projects, the average setup time to get all up and running is usually a day, and sometimes more. Most often, time is spent on setting environment variables, handling software version conflicts, or general configuration. Not to mention, that once you are done, doing this for the next project would be even more challenging.<br />
<h2>
</h2>
<h2>
Vagrant: The Solution</h2>
Vagrant provides an elegant solution to this whole mess. <br />
<br />
In simple terms, Vagrant allows you to provides a "box" which has everything pre-installed and setup for you -- and all you do is "start" the box on your machine and you are set. This box is essentially a Virtual Box VM, which is running in invisible mode (background mode) on your machine, and has the whole development environment for your software setup inside it. But, instead of coding inside the Vagrant VM, you code on your laptop -- and do your builds, compilations and server startups, etc inside the Vagrant VM. <br />
<br />
Vagrant essentially shares a folder on the "box" which is also available on your laptop, and this is the folder that contains the code of your project. Any modifications to that folder by your laptop (host), or the box (guest), will be reflected to each other. <br />
<br />
Basically this means that your laptop owns the code, so you use your favorite powerful IDE and laptop environment to modify code, and you use the vagrant environment to "run" the code.<br />
<br />
<b>The advantages you get when using a Vagrant box are:</b><br />
<br />
<ol>
<li>You don't install stuff on your machine, and mess your machine up with all the weird libraries and settings. All you have on your machine is the "code". Rest is inside the VM.</li>
<li>You have exactly the same development environment as everyone else in your team.</li>
<li>The development environment is created once (Vagrant box), and used everywhere on all Operating Systems. This is because the Box is essentially a VM, which is running on top of Virtual Box. And Virtual Box VMs can be run on any host operating system.</li>
</ol>
<br />
<b><br /></b>
<b>Is it different from using a VM?</b><br />
<br />
Some people ask the question -- why Vagrant Box? Why don't I just setup a Virtual Box VM and everyone can work on that VM. That is also the same -- isn't it?<br />
<br />
Well the answer is -- "Almost". <br />
<br />
If you create a VM, and then ask people to work on that VM on their machines -- you are in for trouble most of the time! In most cases a VM on your machine is slow. It is especially painful when you have to do things like editing, coding, etc. Plus that also means you have to learn the shortcuts of the VM to make you productive on that VM. <br />
<br />
When using a Vagrant box, you aren't working in the VM. You are working on your own laptop, and only connecting to the VM in "ssh" (command-line) mode. In effect, you are actually just firing a few commands to VM -- like build, start server, etc and the rest of the work is being done on your own machine. For you, the Vagrant box is just like a "server" to which you connect and tell what to do. <br />
<br />
<br />
A Vagrant VM is usually viewed as a light-weight command-line only VM which usually runs a Linux OS (Lucid32 by default, but you can use Ubuntu or anything else).<br />
<div>
<br /></div>
<br />
Vagrant also allows you to configure port forwarding, so that when you type a URL in your browser like http://localhost:3000, you get connected to your server application running inside vagrant -- just as-if the server was running directly on your laptop.<br />
<br />
<b>Steps to setup a Vagrant Box on your machine:</b><br />
<b><br /></b>
When you have a Vagrant Box based Development environment setup (like RapidFTR did), here is all you do to get yourself setup: <br />
<br />
<br />
<ol>
<li>Install Virtual Box for your laptop. If you have a Mac, then you install Virtual Box for Mac (and so on). This will act as the environment inside which Vagrant box will run.</li>
<li>Install Vagrant for your laptop. Once you install vagrant, you will see that on command line "vagrant" command will become available.</li>
<li>You download the code into a folder on your machine (say from Github or your network code repository).</li>
<li>You "add" a vagrant box to you laptop using the "vagrant box add" command. This command will need the path to your vagrant box VM. Alternatively, the box can be downloaded and added automatically from the internet as part of the vagrant up command (in next step).</li>
<li>You then do a "vagrant up" to start your box. This vagrant "up" command is done from your code directory, and the code directory will contain a "Vagrant" configuration file with configuration details on the Vagrant box to run. If the box isn't found on your local machine, vagrant will attempt to download the box from the URL provided in the vagrant configuration file. (This means you didn't use the box add command to add the box locally - as was mentioned in the previous step).</li>
<li>Once the vagrant box is up and running, then you ssh into the Vagrant box using the "vagrant ssh" command (or putty on windows) -- to build/start/stop your project application.</li>
</ol>
<br />
<br />
That's it. Now you are free to modify code on your local machine, and see it working via the vagrant box VM environment.<br />
<br />
<b>Chef your Vagrant</b><br />
<br />
Vagrant also allows you to run <a href="http://vagrantup.com/v1/docs/provisioners/chef_solo.html" target="_blank">chef</a> scripts as part of your vagrant up command. The chef scripts will perform the installation and setup of software inside your Vagrant box. This way -- the power of infrastructure automation and provisioning provided by chef, can be combined with the power of a decoupled development environment provided by Vagrant. Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com5tag:blogger.com,1999:blog-5271679338252164175.post-7590796822536704822012-08-20T17:27:00.001+05:302012-08-20T17:27:33.634+05:30Pretty Fractal Trees using HTML-5 Canvas & Random NumbersLast week I sat down to see how I can generate a fractal tree on a web page. It turned out to be a very interesting exercise using HTML5 Canvas and simple Math trigonometric functions. Using random numbers for changing the length of the tree branch, and the angle of branch split -- I was quite successful in generating very realistic looking trees! <br />
<br />
Each time you render the HTML, the trees look quite different. I can see how Game creators can create interesting looking forests for "heroes" to travel in using such techniques.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTQ0hd2cnhoPHFXVoS3fJzdeZG6RQZxPJgE1zoxF5K63dvLR8hWCRzbun3Qd4A2wRV9EpiBMQpCEqJY-mRJ66gfutL_QnukHnApGvESMDHLP5ELuV1siAI0dKtxZ4MjHDVG0Jibl30yTs/s1600/Screen+Shot+2012-08-12+at+1.37.54+PM.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="287" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTQ0hd2cnhoPHFXVoS3fJzdeZG6RQZxPJgE1zoxF5K63dvLR8hWCRzbun3Qd4A2wRV9EpiBMQpCEqJY-mRJ66gfutL_QnukHnApGvESMDHLP5ELuV1siAI0dKtxZ4MjHDVG0Jibl30yTs/s400/Screen+Shot+2012-08-12+at+1.37.54+PM.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">HTML 5 Canvas with a Fractal Tree<br />
</td></tr>
</tbody></table><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Here is the code (also posted on github):<br />
<br />
<script src="https://gist.github.com/3401766.js?file=tree_html5.html"></script><br />
<br />
Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com0tag:blogger.com,1999:blog-5271679338252164175.post-43748872207962936242012-07-29T11:05:00.000+05:302013-11-24T16:36:56.996+05:30Recommended Readings for Lateral Dev Hires at ThoughtWorks -- An Unofficial Opinion<i><span style="color: red;">All thoughts mentioned in this post are in no way endorsed or validated by ThoughtWorks. These are solely my opinions (and a few co-workers). You are still the best judge of your capabilities, and needs.</span> </i><br />
<br />
Quite often experienced folks joining <a href="http://www.thoughtworks.com/" target="_blank">ThoughtWorks</a> have a common set of questions: What should I read to prepare myself for ThoughtWorks? What kind of technologies does ThoughtWorks work on? Will I go on a Ruby or Java or Mobile project?<br />
<br />
I doubt there is any good and precise answer to these questions. But, there certainly are some practices that I feel our in the DNA of ThoughtWorks. Agile & Extreme Programming practices drive most of this. <span style="background-color: white;">Unfortunately, Agile means totally different things to different people outside ThoughtWorks. And, quite often, nothing will prepare you for the radical changes that are going to come to your <i>way of working</i> at ThoughtWorks. </span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">So, I thought, why not try come up with some recommended readings for Dev Lateral hires (experience range of 3 - 10 years), to introduce them to some of our development practices, coding styles, unit testing beliefs, etc. I asked a few of my colleagues - namely <a href="http://in.linkedin.com/pub/unmesh-joshi/5/763/948" target="_blank">Unmesh</a>, <a href="http://twitter.com/chiragsdoshi/" target="_blank">Chirag</a>, <a href="http://sunitspace.blogspot.in/" target="_blank">Sunit</a> and <a href="http://www.wikyblog.com/AmanKing/ThoughtWorks" target="_blank">Aman</a> on what they felt should be the minimum recommended reading list for Lateral ThoughtWorkers. This is what we all came up with. </span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">I may have used my discretion to sanitize the final list, therefore if you don't like the list -- blame me! :) </span><br />
<span style="background-color: white;"><br /></span>
<h3>
<span style="background-color: white;"><b>Highly Recommended Book Reading</b></span></h3>
<span style="background-color: white;"><b><a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672" target="_blank">Refactoring, Improving the Design of Existing Code (Martin Fowler)</a></b></span><br />
This book introduces you to <a href="http://en.wikipedia.org/wiki/Code_refactoring" target="_blank">refactoring</a>, code smells and patterns to help you refactor your code into something much more readable, maintainable and extensible. If you are new to refactoring, this will be an eye-opener. Note that examples in this book are targeted towards Java developers, but core concepts are valid in almost any serious programming language. Couple this reading with <a href="http://www.jetbrains.com/idea/features/refactoring.html" target="_blank">IntelliJ Refactoring shortcuts</a> to realize how easy it is to perform useful re-factorings by Java programmers. At ThoughtWorks, the most popular Java IDE is <a href="http://www.jetbrains.com/idea/" target="_blank">IntelliJ</a>. Its refactoring capabilities are beautiful. <br />
<span style="background-color: white;"><b><br /></b></span>
<span style="background-color: white;"><b><a href="http://www.amazon.com/Test-Driven-Development-By-Example/dp/0321146530/ref=pd_sim_b_7" target="_blank">Test Driven Development (TDD) By Example (Kent Beck)</a></b></span><br />
<span style="background-color: white;">TDD - A fundamental practice that has been very highly suggested by proponents of Extreme Programming (XP). This book (again in Java) helps developers in understanding how to think Test-First, and how unit testing affects the design and development of your code. It is a simple, tiny and very nicely written book that gets-to-the-point. Warning: You are not supposed to "read" the book, but follow it as-if <a href="http://en.wikipedia.org/wiki/Kent_Beck" target="_blank">Kent Beck</a> <span id="goog_1325110834"></span><span id="goog_1325110835"></span><a href="http://www.blogger.com/"></a>himself is pairing with you. If you do not code along with this book, you may as well not read this book. If you are joining ThoughtWorks, you will benefit tremendously by understanding TDD.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;"><b><a href="http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0201616416" target="_blank">Extreme Programming Explained (Kent Beck)</a></b></span><br />
<span style="background-color: white;">An excellent introduction to the values and practices of Extreme Programming, and our preferred <i>flavour</i> of Agile. It will give you an insight into how we work, and why we do things the way we do. A must read -- whether you are a developer, QA, BA, PM or any technically connected person who is joining ThoughtWorks. The book is deceptively simple. Understanding this book will explain to you the meaning of "<i>being</i>" Agile, versus "<i>doing</i>" Agile.</span><br />
<br />
<b><a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank">Clean Code: A Handbook of Agile Software Craftsmanship (Robert C Martin a.k.a Uncle Bob)</a></b><br />
Coding is our bread and butter. Well, we prefer it nice and clean! Clean Code is taken very seriously at ThoughtWorks, and the techniques, tips and recommendations mentioned in this book are invaluable. This book is packed with code examples (in Java), and isn't something you read over a plane journey, but something you couple with an IDE, coffee and a leave-me-alone-to-do-as-I-please environment.<br />
<br />
<h3>
<span style="background-color: white;"><b>Other Recommended Book Reading</b></span></h3>
Even though I have mentioned the <i>highly</i> recommended ones, there are still some other books, that I just <i>had</i><b> </b>to let people know they should consider reading. Each of these books are as much a gem as the ones above, except that if you think like an economist, who wishes to maximise his returns at ThoughtWorks, then maybe you will start with the list above, and later digest the ones in this section.<br />
<br />
<b><a href="http://www.amazon.com/The-Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ref=pd_sim_b_4" target="_blank">The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt, David Thomas)</a></b><br />
A collection of very practical & solid advice on many many aspects of Software Development. Reading this book will make you feel you are being handed out information and knowledge developed by the authors through years of hard labour, failures, learnings and successes. Quite a collection!<br />
<br />
<b><a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445" target="_blank">Agile Software Development, Principles, Patterns and Practices (Robert C Martin a.k.a Uncle Bob)</a></b><br />
Uncle Bob introduces Agile practices, and shows how teams need to design and develop code so that Agility can be attained. Even if you didn't work in a team that followed the Agile methodology, you definitely need to know these design principles. Most of them are fundamental to how good software should be created.<br />
<br />
<b><a href="http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683/ref=pd_sim_b_1" target="_blank">Effective Java [2nd Edition] (Joshua Bloch)</a></b><br />
If you are a Java programmer, then you have to read this book. This book is filled with pearls of wisdom on how to use the Java programming language way more effectively than you thought possible. I still pick it up this book time to time, to refresh my Java knowledge. Please read it.<br />
<br />
<b><a href="http://martinfowler.com/books/continuousDelivery.html" target="_blank">Continuous Delivery: Reliable Software Releases Through Build, Test and Deployment Automation (Jez Humble, David Farley)</a></b><br />
How does one make software delivery and releases -- painless and a non-event. What processes, practices and tools should teams follow so that one-click delivery is possible. Turns out, it isn't so easy - but then it isn't rocket science either. All ThoughtWorks projects aim towards providing Continuous Delivery, and this book will give an insight into our methods of achieving those.<br />
<br />
<b><a href="http://www.amazon.com/Implementation-Patterns-Kent-Beck/dp/0321413091" target="_blank">Implementation Patterns (Kent Beck)</a></b><br />
Kent Beck takes the sum total of all his experience in programming, Smalltalk & Java, and categorizes it into a set of Values, Principles and Patterns (with lots of good examples) for us to realize. This book will make you a much better programmer -- one that others will be able to appreciate.<br />
<br />
<h3>
<span style="background-color: white;"><b>Recommended Reference Links on the Internet</b></span></h3>
<div>
There is a wealth of information on the Internet, undoubtedly. Although I do feel that books seem to deliver a more "complete" experience and understanding -- since they take you through a complete story line with a full narrative and total context. The articles on the internet seem to provide a window to possibilities - and there are few folks who publish the "complete picture". Although, the situation has been remarkably improving in the last two or three years. One has to be very judicious and thorough when reading / learning stuff on the internet. As a reference guide - the internet is priceless. There are always exceptions to the rule. Always.</div>
<div>
<br /></div>
<div>
<span style="background-color: white;">Some recommended reference links on the internet that will help the new ThoughtWorker: </span></div>
<div>
</div>
<div>
<ul>
<li><span style="background-color: white;"><a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" target="_blank">Uncle Bob: Principles of OOD</a></span></li>
<li><a href="http://www.refactoring.com/catalog/index.html" target="_blank">Refactoring Catalog</a></li>
<li><a href="http://martinfowler.com/" target="_blank">Martin Fowler's Blogs</a></li>
<ul>
<li><a href="http://martinfowler.com/bliki/RoysSocialExperiment.html" target="_blank">ThoughtWorks is Roy's Social Experiment</a></li>
<li><a href="http://martinfowler.com/articles/newMethodology.html" target="_blank">The New Methodology</a></li>
<li><a href="http://martinfowler.com/articles/itsNotJustStandingUp.html" target="_blank">Patterns for Daily Standup Meetings</a></li>
<li><a href="http://martinfowler.com/articles/continuousIntegration.html" target="_blank">Continuous Integration</a></li>
<li><a href="http://martinfowler.com/articles/mocksArentStubs.html" target="_blank">Mocks aren't Stubs</a></li>
<li><a href="http://martinfowler.com/articles/rubyAtThoughtWorks.html" target="_blank">Ruby At ThoughtWorks</a></li>
<li><a href="http://martinfowler.com/articles/designDead.html" target="_blank">Is Design Dead?</a></li>
</ul>
<li><a href="http://javascript.crockford.com/" target="_blank">Douglas Crockford on Javascript</a></li>
<li><a href="http://xunitpatterns.com/" target="_blank">xUnit Patterns</a></li>
<li><a href="http://www.systemswemake.com/" target="_blank">Systems We Make</a></li>
<li><a href="http://programmers.stackexchange.com/questions/46716/what-should-every-programmer-know-about-web-development" target="_blank">What should every programmer know about Web Development?</a></li>
<li><a href="http://rmurphey.com/blog/2012/04/12/a-baseline-for-front-end-developers/" target="_blank">A baseline for Front-End Developers</a></li>
</ul>
</div>
<span style="background-color: white;"><br /></span>
I would use these links as a starting point, or a seed, to lead me into further research, based on what I find interesting and parts where I feel I need a better understanding.<br />
<br />
Welcome to ThoughtWorks!<br />
<span style="background-color: white;"><br /></span>Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com13tag:blogger.com,1999:blog-5271679338252164175.post-30028627729977201502012-07-22T21:14:00.000+05:302012-08-05T21:26:30.826+05:30POKA YOKE - Applying Mistake Proofing to Software<br />
For years, automobile companies have utilized "Mistake Proofing" as a technique for ensuring high quality, high speed manufacturing -- especially in cases of mass scale production. <span style="background-color: white;">This is also known as <a href="http://en.wikipedia.org/wiki/Poka-yoke" target="_blank">Poka-Yoke</a> (in Japanese) and was adopted and formalized as part of the Toyota Production System. This blog attempts to raise awareness (with examples) for the need of Poka Yoke in Software Design and within the Software Development process.</span><br />
<div>
<br /></div>
<h3>
<b>What is Poka Yoke?</b></h3>
<div>
<br /></div>
<div>
<div>
The essential idea of Poka Yoke is to Mistake Proof the manufacturing process so that workers in a plant cannot make mistakes easily, or if a mistake is made, it is detected and <span style="background-color: white;">corrected quickly. </span></div>
<div>
<span style="background-color: white;"><br />
</span></div>
<div>
<span style="background-color: white;">There are two types of Poka Yokes:</span></div>
<div>
<span style="background-color: white;"><br />
</span></div>
<div>
<span style="background-color: white;"><b>Control Poka Yoke: </b></span><span style="background-color: white;">A Control Poka Yoke is one where the process is designed in such a manner that one cannot make a mistake.</span></div>
<div>
<span style="background-color: white;"><br />
</span></div>
<div>
<span style="background-color: white;">For instance, a car manufacturer might want to put special heat resistant bolts in the engine assembly. For this, the bolts can be made to be of a certain dimension such that it only fits the engine assembly, and nowhere else. Therefore, one cannot use the special bolts in any place except the engine assembly, and one can also not inadvertently put the wrong (non-heat resistant) bolt in the engine assembly</span></div>
<div>
<span style="background-color: white;"><br />
</span></div>
<div>
<span style="background-color: white;">This is a form of control poka yoke, where one cannot go wrong, or make a mistake.</span></div>
<div>
<span style="background-color: white;"><br />
</span></div>
<div>
<span style="background-color: white;">Another interesting example of a control poka yoke are the Gas connections in an Emergency Room at the hospital. To ensure that someone doesn’t connect the wrong gas pipes to the wrong outlets, the Pin configuration of the connections are designed to be unique for each Gas outlet (a standard called the <i>Pin Index Safety System</i>).</span></div>
<div>
<span style="background-color: white;"><br />
</span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwjJ83MPwpvYmHrnlqFv_zgi6W5AZsHRt5l7FM4jFEZBYKrmYvB1hyphenhyphenDc_3pDd10TZSfXmZRfQ066MSNa03UCJf-L0xLAE4ht55W7mCMobIja1xLIsKcwqnjZLctm2U8axCCSnr2DByq9U/s1600/Medical+Gas+Valves+Poka+Yoke.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwjJ83MPwpvYmHrnlqFv_zgi6W5AZsHRt5l7FM4jFEZBYKrmYvB1hyphenhyphenDc_3pDd10TZSfXmZRfQ066MSNa03UCJf-L0xLAE4ht55W7mCMobIja1xLIsKcwqnjZLctm2U8axCCSnr2DByq9U/s320/Medical+Gas+Valves+Poka+Yoke.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Mistake Proofing via different Pin Configurations</td></tr>
</tbody></table>
<div>
<span style="background-color: white;"><b>Warning Poka Yoke: </b></span><span style="background-color: white;">A warning Poka Yoke is one where the moment someone makes a mistake, the person is quickly notified of the mistake, so that corrective action can be taken.</span></div>
<div>
<span style="background-color: white;"><b><br />
</b></span></div>
<div>
<span style="background-color: white;">An example of a Warning Poka yoke is the Car Seatbelt Warning indicator. If one forgets to put on the Seat Belt, then it will beep to warn you of the fact that you forgot to put it on.</span></div>
<div>
<span style="background-color: white;"><br />
</span></div>
<div>
<span style="background-color: white;">Check out the following catalog of Poka Yoke examples from John Grout’s website:</span></div>
<div>
<a href="http://www.mistakeproofing.com/">http://www.mistakeproofing.com/</a></div>
</div>
<div>
<br /></div>
<h3>
The Need For Poka Yoke in Software</h3>
<div>
There are very compelling reasons to use Poka Yokes in Software Design for the benefit of end users, and also in Software Development Teams for creating high quality software in shorter time-frames. </div>
<div>
<br /></div>
<div>
<b>In Software Design</b></div>
<div>
<b><br />
</b></div>
<div>
<i>Beautiful software</i> is designed in a manner that it is intuitive and transparent to the user. It meets the need in a fluid manner, assisting the user to do just what he/she would like to do with it, without making the user jump through hoops and millions of clicks. It should be like an extension of the body, which one uses sub-consciously. </div>
<div>
<br /></div>
<div>
To create such Beautiful software, it is imperative that it is designed with the user behavior, psychology and needs at the core of all thought. When the user naturally moves through the software with ease, we can perceive it as a form of Control Poke Yoke, that ensures that one doesn’t make costly mistakes while using the software. For instance, a simple control Poka Yoke feature is the “Auto Save” feature of Gmail, which ensures that a user’s email is auto-saved every few minutes, so that loss of the internet connection doesn’t make the user lose his/her data. This is an indication of detailed thought gone into understanding the users behavior and needs.</div>
<div>
<br /></div>
<div>
We will look at few more examples of Poka Yoke in software design in the following sections.</div>
<div>
<br /></div>
<div>
<b>In Software Development Teams</b></div>
<div>
<b><br />
</b></div>
<div>
The need for Poka Yoke in Software Development teams is higher than ever before. It is quite well established in the industry that the cost of fixing a defect amplifies 10 to 100 times depending on how far the defect has gone unnoticed in the development process. Couple that with the need for integrating with tens of systems nowadays, and the problem gets compounded manifold. Delegating software development to large number of mediocre or inexperienced developers, isn’t helping the cause. Introducing a poka yoke, that catches defects early, makes Discovery and Diagnosis of a defect ridiculously easy. Of course, to design a Poka Yoke, one needs to be aware of possible mistakes that could potentially occur -- and that comes from feedback, retrospectives and burnt fingers across a project or multiple projects.</div>
<div>
<br /></div>
<div>
The point of a Poka Yoke is: <i>Making mistakes is OK, just don’t make the same mistake again and again</i>.</div>
<div>
<br /></div>
<div>
Quite frequently on large projects, or long running projects, or on projects with multiple and remote teams -- communication becomes a severe issue. In such projects it is very difficult to keep all folks “on the same page”. One finds people sending emails in BOLD, or writing and maintaining huge Wiki pages with FAQ and ToDos on how to perform a certain task. Unfortunately, no one has the time to read or maintain these documents, and errors slip through the cracks.</div>
<div>
<br /></div>
<div>
For instance, on one of my Travel projects, to perform test bookings, we had to use live GDS inventory. So we were given instructions on attributes of a test booking. These went something like: Make bookings at least 6 months in advance, and don’t book during Christmas, or New Year season, don’t book ABC and XYZ airlines, cancel the ticket within 20 minutes of doing the bookings, etc.</div>
<div>
<br /></div>
<div>
Now, even though people followed these rules, quite a few folks would forget to follow at least one or more of these rules. As a result, one time a large airline sent our Travel booking agency a huge bill for messing up with their ticket prices because apparently some test program did a huge number of bookings & cancellations for their flights -- and caused their ticket prices to go up, resulting in shooing away of “real” customers. Now, this can be easily avoided by putting a Poka yoke that would reject any bookings sent via our service that didn’t meet the criteria. And -- that’s really quite easy in software!</div>
<div>
<br /></div>
<div>
In today’s world, the array of tools and techniques available to us are immense. We must use these tools smartly, so that we concentrate on more pressing issues, and let poka yokes, automation scripts and smart checks catch common, and well understood project issues.</div>
<div>
<br /></div>
<div>
Instead of sending multiple BOLD font emails, create a Poka Yoke -- to ensure things don’t break again, and mistakes and errors don’t slip through.</div>
<div>
<br /></div>
<h3>
Qualities of a Good Poka Yoke</h3>
<div>
A good Poka Yoke must meet the following qualities:</div>
<div>
<br /></div>
<div>
<ul>
<li><b>Early:</b> A good poka yoke must be early in the process, so that it can provide quick feedback -- and help in detecting mistakes the moment they occur.</li>
<li><b>Precise: </b>It should be precise, so that it is easy to diagnose and identify what mistake occurred.</li>
<li><b>Simple: </b>The poka yoke should be simple -- to develop and maintain. This is quite important since one doesn’t want to spend time and effort in maintaining poka yokes, and complex poka yokes will have a fairly high chance of becoming erroneous. Having a buggy poka yoke is worse than having no poka yoke at all.</li>
<li><b>Light: </b>The poka yoke needs to be unobtrusive and transparent. If a poka yoke itself becomes an overhead to the process, then it will drive the developers/users crazy, and they will find ingenious ways to avoid it all together. For instance, think about how a developer will feel if he/she has to run a 70 minute pre-commit script before each and every check-in!</li>
</ul>
</div>
<h3>
Examples of Poka Yoke in Software Design (for End Users)</h3>
<div>
<ol>
<li><a href="http://npxp.com/gmail-please-find-the-attached-file" target="_blank">Gmail Attachment Check</a>: If one uses the words "I have attached", but does not attach any document to the email, Gmail will give a warning saying you used the words I have attached, but didn't really attach any document. Are you sure this isn't a mistake?</li>
<li><a href="http://gmailblog.blogspot.in/2011/04/dont-forget-bob-and-got-wrong-bob.html" target="_blank">Wrong Bob/ Missed Bob Check in Gmail:</a> Depending on which set of people you commonly email together, Gmail will warn you (or offer suggestions) to include the folks you may have missed. This will ensure you don't mistakingly leave out someone, or add someone you didn't want to email.</li>
<li><a href="http://googleenterprise.blogspot.in/2009/01/new-layer-of-data-access-security-for.html" target="_blank">Password Strength Indicators:</a> When you sign up for an account on most websites, you are nowadays displayed a password strength indicator - which gives you feedback on the quality and strength of your chosen password. You may think that "Passw0rd" is an awesome password, but that's a mistake you are making! Websites have data collected over millions of users which can tell them things like what are common and easy to break passwords. They utilize this data, along with sophisticated software to create Password Strength indicators so that naive users don't mistakingly set simple, easy to guess passwords.</li>
<li><a href="http://www.macstories.net/news/prevent-accidental-quit-in-google-chrome/" target="_blank">Cmd-Q Warning In Chrome:</a> Quite often Mac users make a mistake of pressing Cmd+Q to close a TAB instead of Cmd+W. Google Chrome on Mac can warn users when they press Cmd+Q, to help them from inadvertently closing all their windows.</li>
<li><a href="http://www.designvsart.com/blog/2009/10/29/poka-yoke-design/" target="_blank">Spelling suggestions in Google suggest:</a> Google will auto-suggest spelling corrections depending on what you might be searching. Helps users from making inadvertent mistakes.</li>
<li><b>Undo Feature</b> is nowadays present in most production quality successful software. Undo as a way of quickly "fixing" mistakes has become second-nature for most software users, that without this feature, most of us operate with a Save-paranoia. Gmail provided an <a href="http://mashable.com/2010/08/22/how-to-undo-send-in-gmail/" target="_blank">Undo Send</a> feature to provide a safety net for times when someone clicks Send by mistake.</li>
<li><b>Double Entry Box</b>: Most websites & software where one needs to enter a critical bank account number, or a password create option, users will notice that they are asked to enter the same value twice (with paste option disabled). This is to ensure people haven't made a mistake while entering the value, and that both boxes hold the same value.</li>
</ol>
<br />
<ol>
</ol>
</div>
<h3>
Examples of Poke Yoke in Software Development</h3>
<div>
<ol>
<li><a href="http://soyouthinkyouneedtorewrite.com/build-radiators-love-them-long-time/" target="_blank">Unit Tests + Pre-commit + CI + Build Radiators</a>: Unit Tests are one of the strongest and most effective means of Mistake Proofing software development. They are precise and early in the development stage. They catch regression mistakes during refactoring, or bug fixing immediately. Unit Tests, coupled with a Continuous Integration Server (like <a href="http://www.thoughtworks-studios.com/go-agile-release-management" target="_blank">Go</a>, <a href="http://jenkins-ci.org/" target="_blank">Jenkins</a>, etc), a pre-commit script, and a Build Radiator are an excellent poka yoke mechanism to inform developers quickly about a mistake having occurred.</li>
<li><b>IDEs and Compilers</b>: IDE's indicate issues in code while you code. They will catch mistakes around incorrect type casting, generics, exception handling and provide you with possible fix options. Compilers will act as strict control mechanisms and will disallow any code that doesn't meet the syntax requirements (especially in case of Statically typed languages).</li>
<li><b>Architectural Controls [ACs]</b>: Some architectural poka yoke control examples in software:</li>
<ol>
<li><b>[AC] Hiding HttpSession</b>: In some web projects folks would create a custom framework for development teams where a potential-to-misuse object like an HttpSession would be made unavailable. Instead, a custom "Session" object would be available which only has specific methods exposed like the getSessionID( ) method, so that application code could use the Session for its original purpose -- which was to identify the user's session, and not to act as a bag of data for passing around to pages and methods. It also ensures that there isn't much overhead in keeping session data synchronized across multiple machines in a cluster - since the ability of developers to stuff anything they like in the session object has been taken away. This will force the developers to look for data structures appropriate to their need for storing user specific application data. </li>
<li><b>[AC] Context aware injections</b>: Custom frameworks can also be written to explicitly ensure that people don't perform an operation which is incorrect / invalid in the current application context. For instance, we would not like to perform updates during a GET Request (remember <a href="http://en.wikipedia.org/wiki/Representational_state_transfer" target="_blank">REST</a>?). In such cases, the framework can inject appropriate implementations which do not support update method calls, so that a developer doesn't make a modifying call in the GET context.</li>
<li><b>[AC] Running Under Least Privilege (RUPL)</b>: The paradigm of Running Under Least Privilege is popular at many levels in Software Development. Operating Systems now create processes which operate at Lowest Level of Privilege, so that processes cannot inadvertently wipe out a memory area which doesn't belong to them, or they do not mistakingly come under a virus attack and wipe out system secure space. Database connections at application level are given only read/update/delete row access on tables, rather than dba / admin access to ensure that the application cannot overwrite/drop tables by mistake. RUPL ensures that a process or a program is given only as much control as they need to avoid costly screw-ups.</li>
<li><b>[AC] Circuit Breaker</b>: Michael T. Nygard introduces this concept as a programming pattern in his masterpiece book <a href="http://pragprog.com/book/mnee/release-it" target="_blank">ReleaseIt!</a> The essential idea is similar to an electric current circuit breaker which trips open whenever the current load is high. The Circuit Breaker trips open whenever it detects that the call to an external web-service, database, etc took too long to respond, or timed-out. Once a circuit breaker is in Open State, it will immediately return an exception to any caller that attempts to connect to the external service. This has the advantage of protecting the external service from an overload of requests while it is attempting to recover, and also prevents the caller application threads from getting blocked. For more details read the <a href="http://www.dalnefre.com/wp/2011/06/circuit-breaker-stability-pattern/" target="_blank">concept</a> and a sample Java AOP based <a href="http://code.google.com/p/jianwikis/wiki/CircuitBreakerDesignPattern" target="_blank">implementation</a> here. Circuit breaker acts as a poka yoke by preventing both the callee and the caller from unknowingly blowing up in case of a failure. </li>
<li><b>[AC] Types with Immutability: </b>Passing a type (like a Money object), instead of passing primitives (like numbers) gives developers control over what can happen to the data as its passed along the various software layers, and what kind of operations can be performed on the data. Adding immutability to these types also ensures that an intermediate layer cannot inadvertently modify an internal data element while it is passing the type around.</li>
</ol>
<li><b>Password Log Check: </b>To ensure that someone has not mistakingly logged sensitive user information like Credit Card Number, CVV or user password to a log file one can write a script to scan log files on the automation test machines. In automation tests, teams usually use only a small set of username/password/accounts/test-data, and hence checking for these accounts in log files, can help uncover if someone has mistakingly left a debug statement in code that prints sensitive data to the log. This would be a Warning Poka Yoke. A control poka yoke would be one where somehow the log API would disallow logging any variable/string which contained the words "credit card number" or "password" or "pwd", etc.</li>
<li><b>Localization Test for Menu-Keyboard Shortcuts:</b> Quite a few desktop softwares have menu options with Keyboard Shortcut keys (accelerators) which are shown underlined. The idea being that when someone presses "Alt+Character<character>", then that menu option will get pressed. There are 2 requirements of these shortcut characters: First, the character must be present in the menu item, and Second, it must be unique in the menu. This is all fine when its designed, but quite often the keyboard shortcuts get messed up when they go through a localization process for other languages. Quite often translators will assign shortcuts which will clash with other menu options, since they don't fully understand which all menu options are shown together (especially in the case where menu changes dynamically based on roles). The solution in such cases is to write a poka yoke script that will check all menu options in a particular language to ensure there isn't a clash. This kind of bug detection is very cumbersome manually.</character></li>
<li><b>Localization Message Bundle Checks:</b> Localization in Java for instance is done through message bundlers (or properties file). Quite often translated files can have errors like translation of a specific line missed, or key misspelled, or key missing, etc. Such errors cannot be quickly caught through language testing. Instead a simple script that compares English Locale properties file against each Language property file can easily catch most of these errors through simple comparisons, and save precious heart aches later. These scripts can be run as part of the localization check-in to catch translation file errors immediately. Use of good translation tools can also eliminate these problems quite effectively, acting therefore as control poka yokes.</li>
<li><b>Hiring the Right People:</b> A very effective poka yoke to mistake proof your software. Something only few companies like <a href="http://www.thoughtworks.com/" target="_blank">ThoughtWorks</a> get right :) </li>
</ol>
</div>
<h3>
Pragmatic Mistake Proofing</h3>
<div>
One needs to be pragmatic about mistake proofing to ensure it is effective, and doesn't irritate the hell out of its users. The guideline to deciding whether a Poka Yoke is needed is to look at feedback from the field. If an issue occurs quite frequently, and people seem to stumble upon it too often, then its most likely a candidate to apply a Poka Yoke. Also, if the blast radius of an issue going out in the field is very high, like logging passwords in clear text, then too, it makes sense to mistake proof the issue.</div>
<h3>
<span style="background-color: white;"><br /></span></h3>
<h3>
<span style="background-color: white;">Conclusion</span></h3>
<div>
Poka Yoke techniques have been in software for sometime. The point to keep in mind, is to be aware of the fact that whenever there is something to warn to people -- instead of writing long emails, and bold font Wiki documents, one should pause and introspect. Ask the question: Can I re-design the system/ component/process such that mistakes cannot be made. Or, can I put in a check in software, such that if mistakes occur, then they can be caught quickly. If yes, then consider the Poka Yoke. </div>
<div>
<br /></div>
<div>
<i><b>Note:</b> The idea of Poka Yoke in Software was presented by <a href="http://blog.doshi.info/?tag=thoughtworks" target="_blank">Dhaval Doshi</a> and me in ThoughtWorks Bangalore xConf (July 2012) <a href="http://www.slideshare.net/gsluthra/poka-yoke-the-science-of-mistake-proofing-for-slideshare" target="_blank">Slideshare Link</a>. Based on positive reviews at the xConf we decided to write a blog on this topic since we could not find good enough resources on the Internet that spoke of Poka Yoke in Software. Thanks to fellow ThoughtWorkers <a href="http://in.linkedin.com/pub/unmesh-joshi/5/763/948" target="_blank">Unmesh Joshi </a>and <a href="http://in.linkedin.com/in/chiragdoshi" target="_blank">Chirag Doshi</a> for providing feedback and few suggestions on this topic. </i></div>Gurpreethttp://www.blogger.com/profile/15595965206631257990noreply@blogger.com8