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

<channel>
	<title>Continuous Learning</title>
	<atom:link href="http://yinsochen.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://yinsochen.com</link>
	<description>My journey in life, technology, entrepreneurship, and learning</description>
	<lastBuildDate>Mon, 05 Mar 2012 01:44:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Remove Submodule from GIT Repo</title>
		<link>http://yinsochen.com/remove-submodule-from-git-repo/</link>
		<comments>http://yinsochen.com/remove-submodule-from-git-repo/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 01:31:50 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=943</guid>
		<description><![CDATA[There is no git submodule rm command, so it takes a bit of manual work to remove a submodule reference in your git repo From (https://git.wiki.kernel.org/articles/g/i/t/GitSubmoduleTutorial_c489.html) Delete the relevant line from the .gitmodules file. Delete the relevant section from .git/config. Run git rm --cached &#8230; <a href="http://yinsochen.com/remove-submodule-from-git-repo/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There is no <code>git submodule rm</code> command, so it takes a bit of manual work to remove a submodule reference in your git repo</p>
<p>From (<a href="https://git.wiki.kernel.org/articles/g/i/t/GitSubmoduleTutorial_c489.html">https://git.wiki.kernel.org/articles/g/i/t/GitSubmoduleTutorial_c489.html</a>)</p>
<ol>
<li>Delete the relevant line from the <code><em>.gitmodules</em></code> file.</li>
<li>Delete the relevant section from <code><em>.git/config</em></code>.</li>
<li>Run <code><em>git rm --cached path_to_submodule</em></code> (no trailing slash).</li>
<li>Commit the superproject.</li>
<li>Delete the now untracked submodule files.</li>
</ol>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fremove-submodule-from-git-repo%2F&amp;title=Remove%20Submodule%20from%20GIT%20Repo"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/remove-submodule-from-git-repo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Git Submodules</title>
		<link>http://yinsochen.com/using-git-submodules/</link>
		<comments>http://yinsochen.com/using-git-submodules/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 04:30:37 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=939</guid>
		<description><![CDATA[If you want to reference code from external repositories within your own repository in GIT &#8211; you&#8217;ll have to use GIT submodules. Let&#8217;s say that we have a repo called sandbox, and inside sandbox, we have a lib sub directory &#8230; <a href="http://yinsochen.com/using-git-submodules/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you want to reference code from external repositories within your own repository in GIT &#8211; you&#8217;ll have to use <a href="http://book.git-scm.com/5_submodules.html">GIT submodules</a>.</p>
<p>Let&#8217;s say that we have a repo called <code>sandbox</code>, and inside <code>sandbox</code>, we have a <code>lib</code> sub directory that refers to multiple libraries from other repos, looking like the following</p>
<pre>/sandbox # your repo
 |
 +-&gt; /lib
      |
      +-&gt; /subA # submodule A
      +-&gt; /subB # submodule B
      ...</pre>
<p>To add the submodules, you need to use the <code>git submodule add</code> command at the root of your repo as follows</p>
<pre>$ cd ~/sandbox
$ git submodule add &lt;git_repo_path_of_submodule_A&gt; lib/subA
$ git submodule add &lt;git_repo_path_of_submodule_B&gt; lib/subB
$ ...</pre>
<p>Each <code>git submodule add</code> will create a clone of the external git repo into your existing repo and manage them as a submodule.</p>
<p>Because each submodule is also a git repo clone, you <a href="http://stackoverflow.com/questions/5814319/git-submodule-push">can modify/change source code inside submodule</a> and then push it back to the origin.</p>
<pre>$ cd ~/sandbox/lib/subA
&lt;make changes and edits&gt;
$ git commit -a -m "reason of change..."
$ git push
$ cd ~/sandbox
$ git add lib/subA
$ git commit -m "updated submodule"</pre>
<p>Submodule changes has to be pushed back out to the origin before the rest of the code, otherwise it will break the dependency.</p>
<p>Also submodules are &#8220;fixed&#8221; to a particular version of the original repo &#8211; so if you want to keep up the latest version, remember to issue the following</p>
<pre># at the root of the repo
$ git submodule update</pre>
<p>You can put the above into a cronjob to refresh it automatically, or <a href="http://stackoverflow.com/questions/4611512/is-there-a-way-to-make-git-pull-automatically-update-submodules/4611550#4611550">use <code>git config alias</code> as described in this link</a>.</p>
<p>That&#8217;s it &#8211; enjoy git submodules.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fusing-git-submodules%2F&amp;title=Using%20Git%20Submodules"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/using-git-submodules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTPS with GITHUB</title>
		<link>http://yinsochen.com/https-with-github/</link>
		<comments>http://yinsochen.com/https-with-github/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 18:35:09 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=932</guid>
		<description><![CDATA[SSH port is blocked at many company firewalls &#8211; for no good technical reasons of course, but probably driven by security policies, and that means one cannot use github without either a weird proxy hack or via HTTPS, which github &#8230; <a href="http://yinsochen.com/https-with-github/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>SSH port is blocked at many company firewalls &#8211; for no good technical reasons of course, but probably driven by security policies, and that means one cannot use github without either a weird proxy hack or <a href="https://github.com/blog/642-smart-http-support">via HTTPS, which github now supports</a>.</p>
<p>For cloning an existing repro &#8211; just use the https path.</p>
<pre># public repro
git clone https://github.com/username/repro.git
# private repro - will prompt for password
git clone https://username@github.com/username/repro.git</pre>
<p>&nbsp;</p>
<p>If you are creating a new repro, then you want to add the http path as the origin server.</p>
<pre># will prompt password upon push
git remote add origin https://username@github.com/username/repro.git</pre>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fhttps-with-github%2F&amp;title=HTTPS%20with%20GITHUB"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/https-with-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working with HTML Canvas</title>
		<link>http://yinsochen.com/working-with-html-canvas/</link>
		<comments>http://yinsochen.com/working-with-html-canvas/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 22:07:38 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=918</guid>
		<description><![CDATA[Canvas is central to HTML5 for 2D graphics.  It is supported to various degree by the modern browsers, which of course means IE lags behind until version 9. The following creates a canvas element in an HTML page &#60;canvas id="example" &#8230; <a href="http://yinsochen.com/working-with-html-canvas/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Canvas_element">Canvas</a> is central to HTML5 for 2D graphics.  It is supported to various degree by the modern browsers, which of course means IE lags behind until version 9.</p>
<p>The following creates a canvas element in an HTML page</p>
<pre>&lt;canvas id="example" width="200" height="200"&gt;
Your browser does not support Canvas. 
&lt;/canvas&gt;</pre>
<p>To make the above work in IE &#8211; you will need to use the <a href="http://code.google.com/p/explorercanvas/">ExploreCanvas project</a> (there are others but won&#8217;t look at them in this post), which provides a javascript implementation of the canvas element.</p>
<pre>&lt;head&gt;
&lt;!--[if IE]&gt;&lt;script src="excanvas.js"&gt;&lt;/script&gt;&lt;![endif]--&gt;
&lt;/head&gt;</pre>
<p>Although ExploreCanvas provides quite a bit of coverage, it currently does not implement all canvas capabilities, one of which is the text capability, which fortunately can be decently patched with <a href="http://code.google.com/p/canvas-text/">the canvas-text project</a>.</p>
<p>Between the two of them we now have 90% of canvas capability, enough for us to play with canvas in a cross-browser fashion.</p>
<p>To use canvas-text, add the following line to <code>&lt;head&gt;&lt;/head&gt;</code> as well.</p>
<pre>&lt;script type="text/javascript" src="canvas.text.js"&gt;&lt;/script&gt;</pre>
<p>You&#8217;ll also need to pick a particular font, which is also implemented in javascript as part of the canvas-text project. I have only tried &#8230;</p>
<p>Time to start drawing on the canvas&#8230;</p>
<h2>Rectangle</h2>
<p>The following draws a rectangle.</p>
<pre>var example = document.getElementById('example');
var context = example.getContext('2d');
context.fillStyle = 'red';
context.fillRect(30, 30, 50, 50);</pre>
<p>The first two line basically returns a drawing context from the particular canvas, so you can use it for drawing. It&#8217;s best to put that into an initiation routine, since you&#8217;ll likely to reuse the context over and over again.  We won&#8217;t see these line repeated going forward.</p>
<p>The 3rd line (fillStyle) sets the color of the fill function. Besides colors it can also be a gradient object, and there are two types of gradients (linear and radial), but with IE only linear works at this moment (IE for now also cannot handle every common color names; for example &#8211; magenta).</p>
<p>The last line creates a rectangle filled with the color specified in the 3rd line.  The parameters are top, left, width, and height.</p>
<h2>Circle</h2>
<p>Drawing a circle looks like the following</p>
<pre>context.beginPath();
context.arc(x, y, radius, 0 , Math.PI * 2, true);
context.closePath();
context.fill();</pre>
<p>Basically, draw an arc of a circle with the <code>arc()</code> function, with <code>beginPath()</code>/<code>closePath()</code> pair perform the drawing, and <code>fill()</code> to color the circle.</p>
<h2>Polygon</h2>
<p>Both circles and polygons are drawn with a path, so they both make use of the <code>beginPath()</code>, <code>closePath()</code> and <code>fill()</code>. The difference is that circle uses arc, whereas polygon uses straight lines via <code>moveTo()</code>/<code>lineTo()</code> as follows:</p>
<pre>context.beginPath();
context.moveTo(x, y);
for (i = 0; i &lt; points.length; ++i) {
    context.lineTo(points[i][0], points[i][1]);
}
context.closePath();
context.fill();</pre>
<h2>Text</h2>
<p>Finally &#8211; text is done as follows</p>
<pre>context.font = '20pt Arial';
context.fillText('hello world', 20, 50);</pre>
<p>Keep in mind that not every font is available for IE &#8211; so trial and error is inevitable.</p>
<h2>Gradient</h2>
<p>Gradient is created by setting <code>context.fillStyle</code> to a gradient object, which is created via one of the following methods</p>
<pre>var linearG = context.createLinearGradient(startX, startY, endX, endY);
var radialG = context.createRadialGradient(startX, startY, startRadius, endX, endY, endRadius);</pre>
<p>Currently radial gradient does not work in IE.</p>
<p>To create additional &#8220;stops&#8221; (additional points between the start and end points), use <code>addColorStop()</code>.</p>
<pre>gradient.addColorStop(color, offset); // offset is between 0 and 1</pre>
<p>The above is a quick tour of the canvas API. It&#8217;s fairly low level as you are working with a context object. It would be much nicer to work at the shapes level, or even above. Libraries such as Processing is supposed to offer such capability. We&#8217;ll revisit canvas in the future.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fworking-with-html-canvas%2F&amp;title=Working%20with%20HTML%20Canvas"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/working-with-html-canvas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NodeJS Serving Static Files</title>
		<link>http://yinsochen.com/nodejs-serving-static-files/</link>
		<comments>http://yinsochen.com/nodejs-serving-static-files/#comments</comments>
		<pubDate>Sat, 25 Feb 2012 08:29:57 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=908</guid>
		<description><![CDATA[We have previously generated dynamic hello world in NodeJS &#8211; let&#8217;s now try to do so via serving a static file instead. The hello.html contains the following &#60;html&#62; &#60;head&#62;&#60;title&#62;hello world&#60;/title&#62;&#60;/head&#62; &#60;body&#62; &#60;p&#62;Hello world&#60;/p&#62; &#60;/body&#62; &#60;/html&#62; To serve this file we &#8230; <a href="http://yinsochen.com/nodejs-serving-static-files/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We have previously generated <a href="http://yinsochen.com/nodejs-hello-world/">dynamic hello world in NodeJS</a> &#8211; let&#8217;s now try to do so via serving a static file instead.</p>
<p>The <code>hello.html</code> contains the following</p>
<pre>&lt;html&gt;
&lt;head&gt;&lt;title&gt;hello world&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;Hello world&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>To serve this file we can quickly hack our handler to just load this file whenever we are pointing to root.</p>
<p>The <a href="http://nodejs.org/docs/latest/api/fs.html">fs module provides file I/O for NodeJS</a>.  The simplest approach is probably to read the whole file into memory and write it out at once, via <a href="http://nodejs.org/docs/latest/api/fs.html#fs.readFile"><code>readFile</code></a>:</p>
<pre>var fs = require('fs');
...
fs.readFile('hello.html', function (err, data) {
    if (err) {
	res.writeHead(500, {'Content-Type':'text/plain'});
	res.end('internal error: ' + err);
    } else {
	res.writeHead(200, {'Content-Type':'text/html'});
	res.end(data, 'utf-8');
    }
});</pre>
<p><code>fs.readFile</code> isn&#8217;t the most efficient method, especially for large files, but for now it suffices, and we&#8217;ll revisit how to handle large files in the future.</p>
<p>The above will serve <code>hello.html</code> with every request, since it&#8217;s embedded into the code. What we want is to be able to serve any file based on the incoming path.</p>
<p>For that &#8211; we&#8217;ll need the following</p>
<ul>
<li>A mapping between the virtual path to physical path on disk</li>
<li>A content type map between the file extension to the content type</li>
</ul>
<p>To map the physical path, we&#8217;ll need to start with a root path, say /tmp/node, and we&#8217;ll at this moment simply append the path to the root path.</p>
<pre>function virtualToPhysical(path) {
    return '/tmp/node' + path;
}
...
fs.readFile(<strong>virtualToPhysical(req.url)</strong>, function (err, data) {</pre>
<p>Since <code>req.url</code> always starts with <code>/</code>, the virtualToPhysical function will not have issue with missing <code>/</code> if used within the context of NodeJS.</p>
<p>The above change allows you to serve file from anywhere (assuming NodeJS has the proper permission) on the filesystem. However, we still need to deal with the mime types of different types of file.</p>
<p>Traditionally web servers such as Apache uses a <code>mime.types</code> file that holds the mapping between extensions and the content type. Although parsing mime.types isn&#8217;t all that difficult (just split on lines and split again on spaces, and then remove comments), it&#8217;s simpler to just use a <a href="https://github.com/bentomas/node-mime">pre-written module here, specifically node-mime</a>.</p>
<p>Installing node-mime is simple, just issue the following command</p>
<pre>$ npm install mime</pre>
<p>Then add the following code</p>
<pre><strong>var mime = require('mime');</strong>
...
// on fileRead success
res.writeHead(200, {'Content-Type': <strong>mime.lookup(req.url) }</strong>);</pre>
<p>With the above &#8211; we can now serve arbitrary static files!</p>
<p>&nbsp;</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fnodejs-serving-static-files%2F&amp;title=NodeJS%20Serving%20Static%20Files"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/nodejs-serving-static-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NodeJS Hello World</title>
		<link>http://yinsochen.com/nodejs-hello-world/</link>
		<comments>http://yinsochen.com/nodejs-hello-world/#comments</comments>
		<pubDate>Sat, 25 Feb 2012 06:21:48 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=902</guid>
		<description><![CDATA[NodeJS hello world is pretty straight forward Download NodeJS &#38; install it Verify via running node on command line Type up the following hello.js in your favorite editor var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello &#8230; <a href="http://yinsochen.com/nodejs-hello-world/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>NodeJS hello world is pretty straight forward</p>
<ol>
<li><a href="http://nodejs.org/#download">Download NodeJS</a> &amp; install it</li>
<ul>
<li>Verify via running <span style="font-family: courier new,courier;">node</span> on command line</li>
</ul>
<li>Type up the following hello.js in your favorite editor
<pre>var http = require('http');

http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8080);

console.log('Server running at http://127.0.0.1:8080/');</pre>
</li>
<li>Run
<pre>node hello.js</pre>
</li>
<li>You&#8217;ll see Hello World printed when you visit http://localhost:8080</li>
</ol>
<h2>Counting Hello World</h2>
<p>A counting hello world is also pretty straight forward, as Javascript has closure, so we just need to setup a variable to store the counter.</p>
<ol>
<li>Change <code>hello.js</code>and add a count variable as follows
<pre>var http = require('http');
<strong>var count = 0;</strong>
http.createServer(function (req, res) {
            res.writeHead(200, {'Content-Type': 'text/plain'});
            <strong>count += 1;</strong>
            res.end('Hello World ' + <strong>count</strong> + '\n');
    }).listen(8080, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8080/');</pre>
</li>
<li>Refresh the page and you&#8217;ll see the counter being updated.</li>
<li>You might find the counter being updated in increments of 2 &#8211; this is due to your browser issue an &#8220;invisible request&#8221; (because we are not logging it) for the non-existent <code>/favicon.ico</code> file as well as for the root. To see it in action, we&#8217;ll add a logging line to see the request url via <code>req.url</code>, as follows
<pre>var http = require('http');
var count = 0;
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    count += 1;
    <strong>console.log('count: ' + count + ': ' + req.url); </strong>
    res.end('Hello World ' + count + '\n');
    }).listen(8080, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8080/');</pre>
<p>You can then verify the log at the console</p>
<pre>$ node http.js
Server running at http://127.0.0.1:8080/
count: 1: /
count: 2: /favicon.ico
count: 3: /
count: 4: /favicon.ico
count: 5: /
count: 6: /favicon.ico</pre>
</li>
<li>To not count the favicon request &#8211; we can add a conditional test to the http handler function against the <code>req.url</code>and return 404 for favicon.
<pre>var http = require('http');
var count = 0;
http.createServer(function (req, res) {
    <strong>if (req.url == '/favicon.ico') {</strong>
	<strong>res.writeHead(404, {'Content-type' : 'text/plain'});</strong>
	<strong>res.end('not found'); </strong>
    <strong>} else {</strong>
	res.writeHead(200, {'Content-Type': 'text/plain'});
	count += 1;
	console.log('count: ' + count + ': ' + req.url);
	res.end('Hello World ' + count + '\n');
    <strong>}</strong>
    }).listen(8080, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8080/');</pre>
</li>
</ol>
<p>That&#8217;s it &#8211; your counting NodeJS hello world program.</p>
<p>&nbsp;</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fnodejs-hello-world%2F&amp;title=NodeJS%20Hello%20World"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/nodejs-hello-world/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ignore That RFP When&#8230;</title>
		<link>http://yinsochen.com/ignore-that-rfp-when/</link>
		<comments>http://yinsochen.com/ignore-that-rfp-when/#comments</comments>
		<pubDate>Fri, 11 Mar 2011 04:07:10 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[rfp]]></category>
		<category><![CDATA[sales]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=372</guid>
		<description><![CDATA[It is often difficult to ignore the RFP that just lands on your desk.  There lies the untold riches and glory that awaits you. But just like the gold rush, most people come home empty handed with RFPs.  In each &#8230; <a href="http://yinsochen.com/ignore-that-rfp-when/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It is often difficult to ignore the RFP that just lands on your desk.  There lies the untold riches and glory that awaits you.</p>
<p>But just like the gold rush, most people come home empty handed with RFPs.  In each RFP, there is exactly one winner (there are RFPs with zero winner &#8211; yes, these are just market surveys in disguise), and everyone else go home for the next time.</p>
<p>Furthermore, RFPs generally favors the participants differently.  It&#8217;s similar to a playoff seeding, where there usually is a already clear favorite, and they get to play the lower seed first before facing tougher competitions.</p>
<p>Nevertheless, vendors who want to get into the buyer&#8217;s door will keep playing the game.  So it&#8217;s prudent to know how to play this game well.</p>
<p>To win any RFP, you will have to put a lot of effort into it, in order to convince the buyer that your solution is the best choice. <span id="more-372"></span></p>
<p>To do that &#8211; you&#8217;ll have to invest a lot of resources.  If you are a big company that can throw armies of people on all the RFPs that comes across your desk, great.  You can stop reading now.</p>
<p>If not &#8211; you will need to be selective about the RFPs you answer.  Yes that means you need to <strong>concentrate on the likely winners, and ignore the rest</strong>.</p>
<p>It&#8217;s always scary to limit the opportunities.  But focus will give you greater penetration power, which is exactly what you need to win an RFP.</p>
<p>1 out of 10 is much better than 0 out of 100.</p>
<p>So what RFP you should go for?  And what to ignore?</p>
<p>The surest RFPs to go for are the ones that buyers told you &#8220;this is yours to lose.&#8221;</p>
<p>Okay &#8211; no buyer will say that, so this needs to be implied, whether it&#8217;s because you have strong relationship with the buyers, or that you are the incumbent vendor.  The point is &#8211; <strong>you already know you are likely to win before you bid</strong> (not that you know you can win). <strong> </strong></p>
<p>Conversely &#8211; if you do not know whether you are likely to win, then you are not likely to win.  And broadly speaking &#8211; all such RFPs should be ignored.</p>
<p>But what if your job is to get new buyers to bite?  In that case you cannot just ignore all of the RFPs from new buyers.</p>
<p>In that case, you&#8217;ll need to know which ones you actually have a chance, and which ones you really don&#8217;t:</p>
<ul>
<li>When the existing incumbent is getting kicked out of the door &#8211; there is a vacuum, so someone new gets to fill it</li>
<li>When you get to directly work with the buying manager and not the procurement &#8211; there is a chance that you can build working relationship</li>
<li>When you only have a very short amount of time to turn around RFP &#8211; either you are late to the party, or the buyer doesn&#8217;t have its act together; in either case, the chance is not there</li>
<li>When you have to follow a very rigid RFP structure &#8211; this means buyer is not looking for people to &#8220;innovate&#8221; on RFP, and chance is that buyer is not looking for innovation period &#8211; this is not likely to be a good fit either</li>
<li>The RFP is likely stretching your company&#8217;s resource if you win &#8211; the size discrepancy will likely disqualify you &#8211; don&#8217;t waste the time</li>
</ul>
<p>The truth is that RFP is often not the best way to get into a new buyer&#8217;s door except under drastic situations.  Look for the compelling reason(s) for the buyer to search for a new vendor, if you can&#8217;t find that reason, it&#8217;s best to look elsewhere for now, and wait for the compelling opportunity to present itself to you (this likely will occur on a &#8220;side door&#8221;) down the road.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fignore-that-rfp-when%2F&amp;title=Ignore%20That%20RFP%20When%26%238230%3B"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/ignore-that-rfp-when/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Increase Upload Quota in WordPress</title>
		<link>http://yinsochen.com/increase-upload-quota-in-wordpress/</link>
		<comments>http://yinsochen.com/increase-upload-quota-in-wordpress/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 18:10:36 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Setup]]></category>
		<category><![CDATA[quota]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=152</guid>
		<description><![CDATA[In WordPress Network, there is a upload size quota limitation, defaulted to 10MB.  Which works for ISP selling their spaces at premium, but not if you already buy the space: Administration -&#62; Super Admin -&#62; Sites Choose the site that &#8230; <a href="http://yinsochen.com/increase-upload-quota-in-wordpress/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In WordPress Network, there is a upload size quota limitation, defaulted to 10MB.  Which works for ISP selling their spaces at premium, but not if you already buy the space:</p>
<ul>
<li>Administration -&gt; Super Admin -&gt; Sites</li>
<li>Choose the site that you want to update the quota, click Edit</li>
<li>Update the field that says <a href="http://wordpress.org/support/topic/edit-site-upload-quota">Site Upload Space Quota</a>, or Blog Upload Space in 3.1</li>
</ul>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fincrease-upload-quota-in-wordpress%2F&amp;title=Increase%20Upload%20Quota%20in%20WordPress"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/increase-upload-quota-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flapjax &#8211; Functional Reactive Programming in Javascript</title>
		<link>http://yinsochen.com/flapjax-functional-reactive-programming-in-javascrip/</link>
		<comments>http://yinsochen.com/flapjax-functional-reactive-programming-in-javascrip/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 19:40:05 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[flapjax]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[plt]]></category>
		<category><![CDATA[scheme]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=294</guid>
		<description><![CDATA[What if programming can be as simple as writing spreadsheet formulas? Now &#8211; there are some complex spreadsheets out there for sure, but the power of spreadsheet comes from that the values are self-updating, i.e. changing value in one cell &#8230; <a href="http://yinsochen.com/flapjax-functional-reactive-programming-in-javascrip/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>What if programming can be as simple as writing spreadsheet formulas?</p>
<p>Now &#8211; there are some complex spreadsheets out there for sure, but the power of spreadsheet comes from that the values are self-updating, i.e. changing value in one cell will automatically cause all its dependent cells to reflect the change.  If spreadsheets cannot do the auto-propagation, even the simplest spredsheet will be much more complex.</p>
<p>Most programming languages do not have the auto-propagating capability, but the ones that do are called <a href="http://en.wikipedia.org/wiki/Reactive_programming">reactive programming languages</a>.  And if the language is also functional, then it&#8217;s called a <a href="http://en.wikipedia.org/wiki/Functional_reactive_programming">functional reactive programming language</a>.</p>
<p>Since most of the mainstream languages did not have reactive features built-in, the feature need to be &#8220;bolted on&#8221;, as a library or a transformer.  The one for Javascript is called <a href="http://flapjax-lang.org/">Flapjax</a>.</p>
<p>Let&#8217;s do a quick example to demonstrate the power of functional reactive programming.  We&#8217;ll use timer as an example, where the timer should refresh its value (in total milliseconds) every tenth of a second.</p>
<p>If we were to write this in conventional Javascript, it will be something like this:<span id="more-294"></span></p>
<pre>var d = new Date();
setTimeout(function () { node.innerHTML = d.getMilliseconds(); } , 100);</pre>
<p>But if Flapjax it&#8217;s as follows (<a href="http://flapjax-lang.org/demos/time1.html">you can see the demo here</a>):</p>
<pre> {! timerB(100); !}</pre>
<p>Cool huh?  The timerB &#8220;function&#8221; automatically handles the refresh that we have to manually handle with setTimeout in conventional Javascript.</p>
<p>What if we want to have two timers, the first gets updated every tenth of a second, and the second gets updated whenever the first is updated ten times?</p>
<p>In conventional Javascript we will write:</p>
<pre>var d = new Date();
var i = 0;
setTimeout(function () { node.innerHTML = d.getMilliseconds();
   i++;
   if (i == 10) {
      node2.innerHTML = Math.floor(d.getMilliseconds());
   } else {
      i = 0;
   }
} , 100);</pre>
<p>In Flapjax we can write (<a href="http://flapjax-lang.org/demos/time2.html">see a more extensive demo that includes the last digit of the timer</a>):</p>
<pre>var tenthB = timerB(100);
var secondB = Math.floor(tenthB / 1000);
{! tenthB !} {! secondB !}</pre>
<p>It now looks like we have created two variables, and as the value of the first variable changes, the second variable changes along with it.  In comparison, the conventional event-driven approach of Javascript has too much code, and also obscures the relationship between the two timers.</p>
<p>This is only the tip of the iceberg of what functional reactive programming can do &#8211; for more details, see the <a href="http://flapjax-lang.org/tutorial/">Flapjax tutorial</a>.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fflapjax-functional-reactive-programming-in-javascrip%2F&amp;title=Flapjax%20%26%238211%3B%20Functional%20Reactive%20Programming%20in%20Javascript"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/flapjax-functional-reactive-programming-in-javascrip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Should You Have Faith in Lean Startups (or In Your Startup)?</title>
		<link>http://yinsochen.com/should-you-have-faith-in-lean-startups/</link>
		<comments>http://yinsochen.com/should-you-have-faith-in-lean-startups/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 07:51:22 +0000</pubDate>
		<dc:creator>yc</dc:creator>
				<category><![CDATA[Startup]]></category>
		<category><![CDATA[faith]]></category>
		<category><![CDATA[lean startup]]></category>

		<guid isPermaLink="false">http://173.230.157.124/yinsochen/?p=279</guid>
		<description><![CDATA[Ash Maurya is asking a very good question: Do you have faith in lean startups? He goes on to digest the &#8220;faith&#8221; in lean startups and cautions the practitioners to have a healthy dose of skeptism: Observe the Stockdale Paradox &#8230; <a href="http://yinsochen.com/should-you-have-faith-in-lean-startups/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ashmaurya.com/">Ash Maurya</a> is asking a very good question:</p>
<p style="padding-left: 30px;"><a href="http://www.ashmaurya.com/2011/02/do-you-have-faith-in-lean-startups/">Do you have faith in lean startups?</a></p>
<p>He goes on to digest the &#8220;faith&#8221; in lean startups and cautions the practitioners to have a healthy dose of skeptism:</p>
<ul>
<li>Observe the <a href="http://en.wikipedia.org/wiki/James_Stockdale#Prisoner_of_war">Stockdale Paradox</a> at play &#8211; faith of ultimate result must be compartmentalized from the brutal confrontation of the current reality</li>
<li>The lean startup movement itself <a href="http://en.wikipedia.org/wiki/Crossing_the_Chasm">need to cross the chasm</a></li>
<li>Do not confuse the tactical techniques with the methodology</li>
<li>Focus on learning, validating, and iterating, instead of just believing</li>
</ul>
<p>What Ash said are all valid &#8211; he then further made a point that he believes fundamentally that the <a href="http://groups.google.com/group/lean-startup-circle/browse_frm/thread/71e7a5bc9ecf4ef5">lean startup methodology is fundamentally different from other well-intentioned agile methodology that has gone astray</a>.</p>
<p>This is where I beg to differ.</p>
<p>While I cannot predict how the lean startup movement will end up, the matter of fact is that when a methodology/ideology movement gone astray, <span style="text-decoration: underline;">it is not the methodology/ideology itself, but the people who participate in the movements</span>.</p>
<p>The famed <a href="http://groups.google.com/group/lean-startup-circle/browse_frm/thread/71e7a5bc9ecf4ef5">Technology Adoption Lifecycle</a> has captured the people&#8217;s behaviors in a nutshell:</p>
<div id="attachment_282" class="wp-caption alignnone" style="width: 1034px"><a href="http://commons.wikimedia.org/wiki/File:Technology-Adoption-Lifecycle.png"><img class="size-full wp-image-282" title="Technology Adoption Lifecycle" src="http://yinsochen.com/files/2011/03/Technology-Adoption-Lifecycle.png" alt="Technology Adoption Lifecycle" width="1024" height="408" /></a><p class="wp-caption-text">Technology Adoption Lifecycle</p></div>
<p><span id="more-279"></span></p>
<p>Whether you factor into the Chasm or not, the following categories of people are defined:</p>
<ul>
<li>Innovators &#8211; people who are constantly seeking to push the boundary</li>
<li>Early adopters &#8211; people who quickly sees the vision for the new ideas and can relate to how it will help them</li>
<li>Early majority &#8211; people are conservative, but will still open to new ideas, but will wait for early adopters to adopt the ideas</li>
<li>Late majority &#8211; people who are conservative, and will not adopt new ideas until others have adopted the ideas</li>
<li>Laggards &#8211; people who will never adopt the ideas</li>
</ul>
<p>Just based on the above information alone, we immediately know that not all potential adoptees are equally invested in trying out new ideas.  We can count on the innovators and the early adopters to try out the ideas and potentially help shape it, but late majority and laggards are not going to be invested in the ideas until it becomes inevitable (maybe not even then), and certainly they are not going to waste energies to figure out how to &#8220;make the idea work&#8221;.</p>
<p>In other words, lean startups will encounter more of people who will try to make the ideas work for them during the innovator and early adopter phase, but will encounter more of people who want the ideas to work for them during the later phases of adoption cycle.</p>
<p>Unfortunately, startups will require people who will make the ideas work, instead of the other way around.</p>
<p>So &#8211; if lean startup movement is ever successful enough to cross that chasm, it will encounter such the late majority and laggards, and will be met with the same market force that have subjected other technology/ideas/methodologies.</p>
<p>But that&#8217;s okay &#8211; because that does not impact your startup.</p>
<p>For your startup &#8211; you are looking for the best ideas to help it to become successful, but you know that it is prudent to prove that</p>
<ul>
<li>the idea can help you, and</li>
<li>you can make the idea work</li>
</ul>
<p>prior you go all-in, because you know your startup is a venture, not a speculation.</p>
<p>That &#8220;best idea&#8221; might be lean startup today, but it might be something different tomorrow.  You might want to stick with an idea long enough to realize its value, but you are certainly not going to be married to an idea just for &#8220;faith&#8221;.  But if it works, it will stay in your toolkit for further applications.  Why not?</p>
<p>All these ideas are means to an end &#8211; for your startup and your success.  Use your tools wisely.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fyinsochen.com%2Fshould-you-have-faith-in-lean-startups%2F&amp;title=Should%20You%20Have%20Faith%20in%20Lean%20Startups%20%28or%20In%20Your%20Startup%29%3F"><img src="http://173.230.157.124/yinsochen/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://yinsochen.com/should-you-have-faith-in-lean-startups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

