<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title><![CDATA[Michael Hsu.tw]]></title>
  <subtitle><![CDATA[Try to Keep everything in Mind]]></subtitle>
  <link href="http://michaelhsu.tw/atom.xml" rel="self"/>
  <link href="http://michaelhsu.tw"/>
  <updated>2014-11-05T13:39:52.367Z</updated>
  <id>http://michaelhsu.tw/</id>
  <author>
    <name><![CDATA[Michael Hsu]]></name>
    <email><![CDATA[evenchange4@gmail.com]]></email>
  </author>
  <generator uri="http://zespia.tw/hexo">Hexo</generator>
  <entry>
    <title type="html"><![CDATA[React Flux 導讀]]></title>
    <link href="http://michaelhsu.tw/2014/11/05/react-flux/"/>
    <id>http://michaelhsu.tw/2014/11/05/react-flux/</id>
    <published>2014-11-05T13:32:10.000Z</published>
    <updated>2014-11-05T13:38:31.000Z</updated>
    <content type="html"><![CDATA[<h2 id="簡介">簡介</h2>
<p>最近看到社群很活躍討論的新的前端話題，花了一些時間看了文件，有機會在 <strong>椒鹽分享小聚</strong> 中跟大家分享我的讀書心得。</p>
<h2 id="Slides">Slides</h2>
<iframe src="//slides.com/evenchange4/react-flux-intro/embed" width="576" height="420" scrolling="no" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen></iframe>

<a id="more"></a>

<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://www.slideshare.net/AndrewHull/react-js-and-why-its-awesome?qid=cc3c82e2-7cee-4bed-9eb9-c341e06698c6&amp;v=qf1&amp;b=&amp;from_search=1" target="_blank" rel="external">http://www.slideshare.net/AndrewHull/react-js-and-why-its-awesome?qid=cc3c82e2-7cee-4bed-9eb9-c341e06698c6&amp;v=qf1&amp;b=&amp;from_search=1</a></li>
<li><a href="http://www.slideshare.net/floydophone/react-preso-v2" target="_blank" rel="external">http://www.slideshare.net/floydophone/react-preso-v2</a></li>
<li><a href="http://ithelp.ithome.com.tw/question/10157402" target="_blank" rel="external">http://ithelp.ithome.com.tw/question/10157402</a></li>
<li><a href="https://www.youtube.com/watch?v=fHLqSWdDrpA" target="_blank" rel="external">https://www.youtube.com/watch?v=fHLqSWdDrpA</a></li>
<li><a href="http://2014.jsdc.tw/talks/jeremy.pdf" target="_blank" rel="external">http://2014.jsdc.tw/talks/jeremy.pdf</a></li>
<li><a href="https://docs.angularjs.org/guide/scope" target="_blank" rel="external">https://docs.angularjs.org/guide/scope</a></li>
<li><a href="http://andyyou.logdown.com/posts/234130-reactjs-reactjs-decrypt" target="_blank" rel="external">http://andyyou.logdown.com/posts/234130-reactjs-reactjs-decrypt</a></li>
<li><a href="https://gist.github.com/coodoo/61e517afb1cd08b08574" target="_blank" rel="external">https://gist.github.com/coodoo/61e517afb1cd08b08574</a></li>
<li><a href="http://blog.andrewray.me/reactjs-for-stupid-people/" target="_blank" rel="external">http://blog.andrewray.me/reactjs-for-stupid-people/</a></li>
<li><a href="http://fluxxor.com/what-is-flux.html" target="_blank" rel="external">http://fluxxor.com/what-is-flux.html</a></li>
<li><a href="http://facebook.github.io/flux/docs/overview.html#content" target="_blank" rel="external">http://facebook.github.io/flux/docs/overview.html#content</a></li>
<li><a href="http://blog.andrewray.me/reactjs-for-stupid-people/" target="_blank" rel="external">http://blog.andrewray.me/reactjs-for-stupid-people/</a></li>
<li><a href="http://code.tutsplus.com/tutorials/intro-to-the-react-framework--net-35660" target="_blank" rel="external">http://code.tutsplus.com/tutorials/intro-to-the-react-framework--net-35660</a></li>
<li><a href="http://scotch.io/tutorials/javascript/getting-to-know-flux-the-react-js-architecture" target="_blank" rel="external">http://scotch.io/tutorials/javascript/getting-to-know-flux-the-react-js-architecture</a></li>
</ul>
<h2 id="Image_Reference">Image Reference</h2>
<ul>
<li><a href="http://wiredcraft.com/posts/2014/08/20/why-we-may-ditch-angularjs-for-react.html" target="_blank" rel="external">http://wiredcraft.com/posts/2014/08/20/why-we-may-ditch-angularjs-for-react.html</a></li>
<li><a href="http://blog.stevepond.io/" target="_blank" rel="external">http://blog.stevepond.io/</a></li>
<li><a href="http://www.slideshare.net/rmsguhan/react-meetup-mailonreact" target="_blank" rel="external">http://www.slideshare.net/rmsguhan/react-meetup-mailonreact</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/spa/" term="SPA"/>
    <category scheme="http://michaelhsu.tw/tags/f2e/" term="F2E"/>
    <category scheme="http://michaelhsu.tw/tags/react/" term="React"/>
    <category scheme="http://michaelhsu.tw/tags/flux/" term="Flux"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[SPA – 使用 Angular.js 實現前後端分離開發應用]]></title>
    <link href="http://michaelhsu.tw/2014/10/20/SPA/"/>
    <id>http://michaelhsu.tw/2014/10/20/SPA/</id>
    <published>2014-10-20T06:53:26.000Z</published>
    <updated>2014-10-20T07:17:43.000Z</updated>
    <content type="html"><![CDATA[<h2 id="簡介">簡介</h2>
<p>這是一個在台大資管人對於網站開發的心得議程。從我們一年級計算機概論課程就第一次學習簡易的 HTML、CSS 網頁，到大三資料庫系統架設 PHP 以及資料庫環境，接著或許會有些更熱血的同學會在大四接觸到用 Rails 或 Express 開發，才開始有了 MVC 的概念，每個階段對於網站開發又有不同的心得。而這次我想分享今年暑假在實習時接觸的前端框架 Angular.js，以及過程是怎麼將網站做前後端分離的應用開發。不會談論過於細節的實作程式碼，希望給大家一個概觀的架構以及怎麼開始使用 Angular.js。<a href="http://www.im.ntu.edu.tw/~b100027/" target="_blank" rel="external">http://www.im.ntu.edu.tw/~b100027/</a></p>
<h2 id="Slides">Slides</h2>
<iframe src="//slides.com/evenchange4/2014-ntuim-prepconf/embed" width="576" height="420" scrolling="no" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen></iframe>

<a id="more"></a>


<h2 id="[延伸閱讀]_Gulp-js_簡介">[延伸閱讀] Gulp.js 簡介</h2>
<iframe src="//slides.com/evenchange4/gulp-js/embed" width="576" height="420" scrolling="no" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen></iframe>



<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://2014.jsconf.cn/slides/herman-taobaoweb/index.html" target="_blank" rel="external">http://2014.jsconf.cn/slides/herman-taobaoweb/index.html</a></li>
<li><a href="http://ihower.tw/rails3/intro.html" target="_blank" rel="external">http://ihower.tw/rails3/intro.html</a></li>
<li><a href="http://www.humasolutions.com/single-page-app-spa-with-angularjs/" target="_blank" rel="external">http://www.humasolutions.com/single-page-app-spa-with-angularjs/</a></li>
<li><a href="http://ithelp.ithome.com.tw/question/10132196" target="_blank" rel="external">http://ithelp.ithome.com.tw/question/10132196</a></li>
<li><a href="http://blog.miniasp.com/post/2013/04/24/Front-end-Engineering-Fineart-An-Introduction-to-AngularJS.aspx" target="_blank" rel="external">http://blog.miniasp.com/post/2013/04/24/Front-end-Engineering-Fineart-An-Introduction-to-AngularJS.aspx</a></li>
<li>ng-book</li>
<li>帥哥 iamblue</li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/angular-js/" term="angular.js"/>
    <category scheme="http://michaelhsu.tw/tags/spa/" term="SPA"/>
    <category scheme="http://michaelhsu.tw/tags/f2e/" term="F2E"/>
    <category scheme="http://michaelhsu.tw/tags/gulp-js/" term="gulp.js"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[GitHub Pages Custom Domains]]></title>
    <link href="http://michaelhsu.tw/2014/06/20/github-pages-custom-domains/"/>
    <id>http://michaelhsu.tw/2014/06/20/github-pages-custom-domains/</id>
    <published>2014-06-19T17:49:59.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>這邊為一個記錄將 Github Page 自定義到你所擁有的 Domain 下的一個流程。當然這些流程在 Goolge 搜尋 Github Page 就可以直接找到英文的說明文件，非常的詳細，此處就當做漢化的以及我自己碰到情境的過程記錄。</p>
<ul>
<li>CASE I:  <code>http://evenchange4.github.io</code> -&gt; <code>http://michaelhsu.tw</code></li>
<li>CASE II: <code>http://about.michaelhsu.tw</code> -&gt; <code>http://evenchange4.github.io/about</code></li>
</ul>
<a id="more"></a>

<h2 id="Basic_預備知識與情境說明">Basic 預備知識與情境說明</h2>
<p>GitHub Pages 分為兩種：</p>
<ol>
<li>User Pages: 例如 <a href="http://evenchange4.github.io" target="_blank" rel="external">http://evenchange4.github.io</a>，每個帳號都只有一個，必須命名為 <code>evenchange4.github.io</code>，且在 <code>master</code> branch。</li>
<li>Project Pages: 例如 <a href="http://evenchange4.github.io/about" target="_blank" rel="external">http://evenchange4.github.io/about</a>，也就是你的 GitHub 每一個 repository 都可以有一個 Page，必須在 <code>gh-pages</code> branch。</li>
</ol>
<p>你可以注意到上面兩個例子可以分別導到我所擁有的 Domain name <code>michaelhsu.tw</code>，這是怎麼做到的呢？以下兩個情境依序帶你做設定。我這邊使用的 DNS provider 是 <code>Godaddy</code>。</p>
<h2 id="CASE_I:_A_record_to_User_Pages">CASE I: A record to User Pages</h2>
<p>也就是例子中的將 <a href="http://evenchange4.github.io" target="_blank" rel="external">http://evenchange4.github.io</a> 導到 <a href="http://michaelhsu.tw" target="_blank" rel="external">http://michaelhsu.tw</a>。</p>
<ol>
<li>在 <a href="https://github.com/evenchange4/evenchange4.github.com" target="_blank" rel="external">repository 中的 evenchange4.github.com</a> <code>master</code> branch 新增 <code>CNAME</code> 檔案，內容為一行 <code>michaelhsu.tw</code></li>
<li>將 Godaddy 新增 A record to 以下兩個 IP (兩個都要)<ul>
<li><code>192.30.252.153</code></li>
<li><code>192.30.252.154</code></li>
</ul>
</li>
</ol>
<p><img src="http://media-cache-ec0.pinimg.com/originals/c8/60/5e/c8605ef5757a8e5b33fdb1f41df4a806.jpg" alt="▲ Figure: A record to User Pages"></p>
<p><em>需跳別注意 <code>207.97.227.245</code> or <code>204.232.175.78</code> 是舊的。</em></p>
<h2 id="CASE_II:_ALIAS_to_Project_Pages">CASE II: ALIAS to Project Pages</h2>
<p>大致上 CASE I 兩步驟設定完畢就可以直接由 <code>http://about.michaelhsu.tw</code> 導到 <code>http://evenchange4.github.io/about</code>，但是如果我想要自定義到  該怎麼做？</p>
<ol>
<li>在 <a href="https://github.com/evenchange4/about" target="_blank" rel="external">repository 中的 about</a> <code>gh-pages</code> branch 新增 <code>CNAME</code> 檔案，內容為一行 <code>about.michaelhsu.tw</code> </li>
<li>將 Godaddy 新增 CNAME record to <code>evenchange4.github.io</code>。</li>
</ol>
<p><img src="http://media-cache-ec0.pinimg.com/736x/bb/61/5d/bb615d925996f0401c5e2ec00bce6e64.jpg" alt="▲ Figure: ALIAS to Project Pages"></p>
<p>最後可以用 <code>dig</code> 來檢查：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">$ dig about<span class="built_in">.</span>michaelhsu<span class="built_in">.</span>tw <span class="subst">+</span>nostats <span class="subst">+</span>nocomments <span class="subst">+</span>nocmd <span class="subst">+</span>multiline</div><div class="line"><span class="subst">=&gt;</span></div><div class="line">; <span class="subst">&lt;&lt;&gt;&gt;</span> DiG <span class="number">9.8</span><span class="number">.3</span><span class="attribute">-P1</span> <span class="subst">&lt;&lt;&gt;&gt;</span> about<span class="built_in">.</span>michaelhsu<span class="built_in">.</span>tw <span class="subst">+</span>nostats <span class="subst">+</span>nocomments <span class="subst">+</span>nocmd <span class="subst">+</span>multiline</div><div class="line">;; <span class="built_in">global</span> options: <span class="subst">+</span>cmd</div><div class="line">;about<span class="built_in">.</span>michaelhsu<span class="built_in">.</span>tw<span class="built_in">.</span>	<span class="keyword">IN</span> A</div><div class="line">about<span class="built_in">.</span>michaelhsu<span class="built_in">.</span>tw<span class="built_in">.</span>	<span class="number">3600</span> <span class="keyword">IN</span>	CNAME evenchange4<span class="built_in">.</span>github<span class="built_in">.</span>io<span class="built_in">.</span></div><div class="line">evenchange4<span class="built_in">.</span>github<span class="built_in">.</span>io<span class="built_in">.</span>	<span class="number">3600</span> <span class="keyword">IN</span>	CNAME github<span class="built_in">.</span><span class="built_in">map</span><span class="built_in">.</span>fastly<span class="built_in">.</span>net<span class="built_in">.</span></div><div class="line">github<span class="built_in">.</span><span class="built_in">map</span><span class="built_in">.</span>fastly<span class="built_in">.</span>net<span class="built_in">.</span>	<span class="number">19</span> <span class="keyword">IN</span> A	<span class="number">199.27</span><span class="number">.79</span><span class="number">.133</span></div></pre></td></tr></table></figure>

<h2 id="Reference">Reference</h2>
<ul>
<li><a href="https://help.github.com/articles/tips-for-configuring-an-a-record-with-your-dns-provider" target="_blank" rel="external">Tips for configuring an A record with your DNS provider</a></li>
<li><a href="https://help.github.com/articles/adding-a-cname-file-to-your-repository" target="_blank" rel="external">Adding a CNAME file to your repository</a></li>
<li><a href="https://help.github.com/articles/my-custom-domain-isn-t-working" target="_blank" rel="external">My custom domain isn’t working</a></li>
<li><a href="https://help.github.com/articles/user-organization-and-project-pages" target="_blank" rel="external">User, Organization, and Project Pages</a></li>
<li><a href="https://help.github.com/articles/about-custom-domains-for-github-pages-sites#subdomains" target="_blank" rel="external">About custom domains for GitHub Pages sites</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/github/" term="github"/>
    <category scheme="http://michaelhsu.tw/tags/page/" term="page"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Gulp.js-LiveReload 自動刷新頁面]]></title>
    <link href="http://michaelhsu.tw/2014/06/11/gulp-livereload/"/>
    <id>http://michaelhsu.tw/2014/06/11/gulp-livereload/</id>
    <published>2014-06-11T15:52:54.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>最近又重回學習前端的懷抱，在看<a href="https://egghead.io/" target="_blank" rel="external">蛋頭兄的 Angular.js</a> 的影片邊操作的同時，不斷的 Refresh 網頁真的不是辦法，以前我的想法是就不停的按 <code>CMD+R</code> 就算了，懶得做那麼多自動刷新得設定，但這樣下去真的不是辦法，原來還是會累的，所以就依照目前最潮的方式來學習設置「自動刷新頁面」的功能。於是乎挑選了 <code>Gulp.js + LiveReload</code> with <code>http-server</code> ，或是考慮使用 <code>gulp-connect</code>。</p>
<ul>
<li>Source Code: <a href="https://github.com/evenchange4/gulp-livereload" target="_blank" rel="external">https://github.com/evenchange4/gulp-livereload</a></li>
</ul>
<a id="more"></a>

<h1 id="Knowledge_前置小作業">Knowledge 前置小作業</h1>
<p>對於使用的工具名稱至少要有一認識，所以查了一下資料。</p>
<ul>
<li><a href="http://gulpjs.com/" target="_blank" rel="external">Gulp.js</a>: 看影片念做 <code>告Ｐ</code>，是一個自動化構建的工具。</li>
<li><a href="http://gulpjs.com/" target="_blank" rel="external">Gulp.js</a> vs <a href="http://gruntjs.com/" target="_blank" rel="external">Grunt</a>: 最主要差在 Gulp 使用 node.js 的 Streams 來加速。</li>
<li><a href="http://livereload.com/" target="_blank" rel="external">LiveReload 2</a>: Client 端的整合自動刷新利器。</li>
<li>靜態網頁可以嗎？：不行，所以這裡使用 node 簡易的 http server “<a href="https://github.com/nodeapps/http-server" target="_blank" rel="external">http-server</a>“，後面會一併教大家如何使用。</li>
<li><a href="https://github.com/avevlad/gulp-connect" target="_blank" rel="external">gulp-connent</a>: 把 webserver 跟 livereload 弄在一起的套件。</li>
</ul>
<h1 id="選擇使用_gulp-livereload_with_http-server">選擇使用 gulp-livereload with http-server</h1>
<h2 id="第一步：Install_安裝">第一步：Install 安裝</h2>
<p>Install Node Package， 這邊用 <code>npm</code> 來下載管理使用到的套件：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ sudo npm <span class="operator"><span class="keyword">install</span> gulp -g</span></div><div class="line">$ sudo npm <span class="keyword">install</span> http-<span class="keyword">server</span> -g</div></pre></td></tr></table></figure>

<p>Install Chrome Extension，安裝 <a href="https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei" target="_blank" rel="external">Chrome Extension: LiveReload</a>，作為 client 端監控的插件。</p>
<p><img src="http://media-cache-ak0.pinimg.com/originals/68/1d/3b/681d3be7a8e194b1b99f29c5eb98ec2a.jpg" alt="▲ Figure: Goolge Chrome Extension: LiveReload"></p>
<h2 id="第二步：Config_前置作業與設定">第二步：Config 前置作業與設定</h2>
<p>Managing module dependencies，讓後人執行可以一目了然：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>npm init</div><div class="line"><span class="variable">$ </span>sudo npm install gulp gulp-livereload --save-dev</div></pre></td></tr></table></figure>

<p>Gulp Config，配置設定 Gulp，新增且編輯 <code>gulpfile.js</code>：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">'gulp'</span>),</div><div class="line">	livereload = <span class="built_in">require</span>(<span class="string">'gulp-livereload'</span>);</div><div class="line"></div><div class="line">gulp.task(<span class="string">'watch'</span>, <span class="function"><span class="keyword">function</span> <span class="params">()</span> </span>{  <span class="comment">// 'watch' 是 task 的名稱，可以任意定義名稱  </span></div><div class="line">	<span class="keyword">var</span> server = livereload();</div><div class="line"></div><div class="line">	</div><div class="line">    gulp.watch(<span class="string">'*.*'</span>, <span class="function"><span class="keyword">function</span> <span class="params">(file)</span> </span>{	<span class="comment">// 監控的檔案，在這裏 '*.*' 我監控所有檔案</span></div><div class="line">        server.changed(file.path);</div><div class="line">    });</div><div class="line">});</div></pre></td></tr></table></figure>

<h2 id="第三步：Quick_Start_執行">第三步：Quick Start 執行</h2>
<p>運行 Run http-server，因為前面提到的，直接用瀏覽器開啟的檔案靜態網頁不支援，因此一定要有一個 http server，所以這邊用非常簡單 node 的 <code>http-server</code> 來運作：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ http-server</div><div class="line">Starting up http-server, serving ./ on port: <span class="number">8080</span></div><div class="line">Hit CTRL-C to <span class="keyword">stop</span> the server</div><div class="line"><span class="keyword">...</span></div></pre></td></tr></table></figure>

<p>運行 Run gulp-livereload 執行 Gulp 監聽的 Task: </p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">$ gulp watch</div><div class="line">[<span class="number">00</span>:<span class="number">22</span>:<span class="number">57</span>] Using gulpfile ~/code/node/livereload/gulpfile.js</div><div class="line">[<span class="number">00</span>:<span class="number">22</span>:<span class="number">57</span>] Starting <span class="string">'watch'</span><span class="keyword">...</span></div><div class="line">[<span class="number">00</span>:<span class="number">22</span>:<span class="number">57</span>] Finished <span class="string">'watch'</span> after <span class="number">7.41</span> ms</div><div class="line">[<span class="number">00</span>:<span class="number">23</span>:<span class="number">23</span>] index.html was reloaded.</div><div class="line">[<span class="number">00</span>:<span class="number">23</span>:<span class="number">23</span>] Live reload server listening on: <span class="number">35729</span></div></pre></td></tr></table></figure>

<p>連接 Chrome-livereload，在 Chrome 瀏覽器連接起來，這邊第一次連可能會沒反應，多點幾次就好了，使得<code>圈圈變為實心</code>的：</p>
<p><img src="http://media-cache-cd0.pinimg.com/originals/c6/84/7f/c6847f0f85412e6229563f5c556baf7d.jpg" alt="▲ Figure: Goolge Chrome Extension：必須要為實心圈圈"></p>
<h1 id="選擇使用_gulp-connect">選擇使用 gulp-connect</h1>
<p>因為 <code>gulp-connect</code> 這個 node 的套件已經將 webserver 整合在一起，所以不需要特別執行 http-server。程序同前面，我快速帶過。</p>
<h2 id="第一步：Install_安裝-1">第一步：Install 安裝</h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ sudo npm <span class="operator"><span class="keyword">install</span> gulp-<span class="keyword">connect</span> <span class="comment">--save-dev</span></span></div></pre></td></tr></table></figure>

<h2 id="第二步：Config_前置作業與設定-1">第二步：Config 前置作業與設定</h2>
<p>將  <code>gulpfile.js</code> 編輯：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">'gulp'</span>),</div><div class="line">  connect = <span class="built_in">require</span>(<span class="string">'gulp-connect'</span>);</div><div class="line"></div><div class="line">gulp.task(<span class="string">'connect'</span>, <span class="function"><span class="keyword">function</span><span class="params">()</span> </span>{</div><div class="line">  connect.server({</div><div class="line">    root: <span class="string">''</span>,</div><div class="line">    livereload: <span class="literal">true</span></div><div class="line">  });</div><div class="line">});</div><div class="line"></div><div class="line">gulp.task(<span class="string">'html'</span>, <span class="function"><span class="keyword">function</span> <span class="params">()</span> </span>{</div><div class="line">  gulp.src(<span class="string">'*.html'</span>)</div><div class="line">    .pipe(connect.reload());</div><div class="line">});</div><div class="line"></div><div class="line">gulp.task(<span class="string">'watch'</span>, <span class="function"><span class="keyword">function</span> <span class="params">()</span> </span>{</div><div class="line">  gulp.watch([<span class="string">'*.*'</span>], [<span class="string">'html'</span>]);</div><div class="line">});</div><div class="line"></div><div class="line">gulp.task(<span class="string">'default'</span>, [<span class="string">'connect'</span>, <span class="string">'watch'</span>]);</div></pre></td></tr></table></figure>

<h2 id="第三步：Quick_Start_執行-1">第三步：Quick Start 執行</h2>
<p>再來執行 <code>gulp</code> 即可：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">$ gulp                                                          </div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Using gulpfile ~/code/node/livereload/gulpfile.js</div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Starting <span class="string">'connect'</span><span class="keyword">...</span></div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Server started http://localhost:<span class="number">8080</span></div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] LiveReload started on port <span class="number">35729</span></div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Finished <span class="string">'connect'</span> after <span class="number">18</span> ms</div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Starting <span class="string">'watch'</span><span class="keyword">...</span></div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Finished <span class="string">'watch'</span> after <span class="number">7.29</span> ms</div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Starting <span class="string">'default'</span><span class="keyword">...</span></div><div class="line">[<span class="number">03</span>:<span class="number">08</span>:<span class="number">42</span>] Finished <span class="string">'default'</span> after <span class="number">7.06</span> μs</div></pre></td></tr></table></figure>

<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://www.36ria.com/6373" target="_blank" rel="external">Gulp.js—比Grunt更易用的前端构建工具</a></li>
<li><a href="https://www.youtube.com/watch?v=OKVE6wE9CW4" target="_blank" rel="external">使用gulp及livereload实时更新页面</a></li>
<li><a href="http://angularjs.cn/A0xJ" target="_blank" rel="external">Gulp.js-livereload 不用F5了，实时自动刷新页面来开发</a></li>
<li><a href="http://blog.wu-boy.com/2013/12/streaming-build-system-gulp/" target="_blank" rel="external">The streaming build system Gulp 比較</a></li>
<li><a href="https://github.com/avevlad/gulp-connect#livereload" target="_blank" rel="external">gulp-connect config</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/gulp/" term="gulp"/>
    <category scheme="http://michaelhsu.tw/tags/node-js/" term="node.js"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Run R script from command line on Ubuntu]]></title>
    <link href="http://michaelhsu.tw/2014/05/06/R-on-Linux/"/>
    <id>http://michaelhsu.tw/2014/05/06/R-on-Linux/</id>
    <published>2014-05-06T15:19:57.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>目的：希望能透過 cmd 的方式執行 <code>./script.r</code> 的檔案，並且讀進 <code>Arguments</code>。</p>
<h2 id="Install_R_on_Ubuntu">Install R on Ubuntu</h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ sudo apt-<span class="keyword">get</span> update</div><div class="line">$ sudo apt-<span class="keyword">get</span> install r-<span class="keyword">base</span></div><div class="line"><span class="preprocessor"># installing packages</span></div><div class="line">$ sudo apt-<span class="keyword">get</span> install r-<span class="keyword">base</span>-dev</div></pre></td></tr></table></figure>

<a id="more"></a>

<h2 id="Run_R_script_from_command_line">Run R script from command line</h2>
<h3 id="方法一：use_Rscipt">方法一：use <code>Rscipt</code></h3>
<h3 id="方法二：第一行加入_#!/usr/bin/Rscript_如下範例程式：">方法二：第一行加入 <code>#!/usr/bin/Rscript</code> 如下範例程式：</h3>
<ul>
<li>Sample code <code>test.r</code>:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="shebang">#!/usr/bin/Rscript</span></div><div class="line">print(<span class="string">"HelloR"</span>)</div></pre></td></tr></table></figure>

<ul>
<li>Reminding: You can use <code>$ which Rscript</code> to search your path to Rscript.</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>which <span class="constant">Rscript</span></div><div class="line">/usr/bin/<span class="constant">Rscript</span></div></pre></td></tr></table></figure>

<ul>
<li>Run sample code <code>test.r</code> from command line:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 方法一執行方式</span></div><div class="line"><span class="variable">$ </span><span class="constant">Rscipt</span> test.r</div><div class="line"><span class="comment"># 方法二執行方式</span></div><div class="line"><span class="variable">$ </span>./test.r</div></pre></td></tr></table></figure>

<h3 id="If_you_get_^M_Problem">If you get ^M Problem</h3>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ ./<span class="filename">test.r   </span></div><div class="line">zsh: ./<span class="filename">test.r</span>: bad interpreter: /usr/bin/Rscript^M: 沒有此一檔案或目錄</div></pre></td></tr></table></figure>

<p>This is an encoding problem at the end of line, your can use <code>Line endings</code> setting of Sublime: <em><code>View &gt; Line Endings &gt; Unix</code></em></p>
<p><img src="http://media-cache-ak0.pinimg.com/originals/fe/ee/e7/feeee7f4dd2f325f28547d32a69807fe.jpg" alt="▲ Figure: Line endings setting of Sublime"></p>
<h2 id="Read_Command_line_Argument">Read Command line Argument</h2>
<ul>
<li>Sample code <code>test.r</code>:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="shebang">#!/usr/bin/Rscript</span></div><div class="line">args&lt;-commandArgs(TRUE)</div><div class="line">print(args[<span class="number">1</span>])</div></pre></td></tr></table></figure>

<ul>
<li>Run sample code <code>test.r</code> from command line:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>./test.r <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span> </div><div class="line">[<span class="number">1</span>] <span class="string">"1"</span></div></pre></td></tr></table></figure>

<ul>
<li>Reminding: Arguments list start from index <code>1</code>.</li>
</ul>
<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://cran.r-project.org/bin/linux/ubuntu/README" target="_blank" rel="external">UBUNTU PACKAGES FOR R</a></li>
<li><a href="http://stackoverflow.com/questions/18306362/run-r-script-from-command-line" target="_blank" rel="external">Run R script from command line</a></li>
<li><a href="http://stackoverflow.com/questions/2151212/how-can-i-read-command-line-parameters-from-an-r-script" target="_blank" rel="external">How can I read command line parameters from an R script?</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/r/" term="R"/>
    <category scheme="http://michaelhsu.tw/tags/ubuntu/" term="ubuntu"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[C++ Tutorial for the Mac User, Include self-defined header files]]></title>
    <link href="http://michaelhsu.tw/2014/03/17/2014-03-17-cpp-tutorial-for-the-mac/"/>
    <id>http://michaelhsu.tw/2014/03/17/2014-03-17-cpp-tutorial-for-the-mac/</id>
    <published>2014-03-17T00:11:26.000Z</published>
    <updated>2014-09-18T14:24:17.000Z</updated>
    <content type="html"><![CDATA[<p>For the course of NTU <a href="http://www.im.ntu.edu.tw/~lckung/courses/PDSp14/" target="_blank" rel="external">Programming Design, Spring 2014</a></p>
<p>If you want to compile a C++ program that includes self-defined header files on Mac or other Linux environment. We suggest you the following two ways to do that. One way is using g++ to compile and run programs in terminal (Recommended). Another way is using Xcode to new a project (i.e., a file with filename extension <em>.xcodeproj</em>).<br>Here, we provide two <em>cpp</em> files, and one <em>header</em> file to you for demonstrating how you can run it on Mac. Just the same as windows’ Dev-C++. Download <a href="https://github.com/evenchange4/102-2_PD_Cpp-Tutorial-for-the-Mac/archive/master.zip" target="_blank" rel="external">example code</a> that was mentioned in the class.</p>
<a id="more"></a>

<h2 id="Using_Commands_in_Terminal_(Recommended)">Using Commands in Terminal (Recommended)</h2>
<p>In Figure 1, find terminal in the Spotlight results, and then click it to open a new Terminal windows (Figure 2).</p>
<p><img src="http://media-cache-ec0.pinimg.com/736x/a2/ce/2c/a2ce2ca0ce15d4723e114adcdf4782c3.jpg" alt="▲ Figure 1: Search your Terminal on Mac."></p>
<p><img src="http://media-cache-ec0.pinimg.com/originals/31/ae/31/31ae31f1aaeb260267263faee8a433b2.jpg" alt="▲ Figure 2: Terminal windows view."></p>
<p>Before starting, some basic knowledge you need to know is about unix-like system command-line commands. Here we list some useful commands.<br>First, we need to change directory <code>cd path</code> to the right one which your code is available under this folder. We assume that the codes are under the path</p>
<p><strong> <em>~/Downloads/project</em> </strong></p>
<p>And then we need to to switch our path to the destination path of project.</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> Downloads/project</div></pre></td></tr></table></figure>

<p>Then we type the command below to list <code>li</code> what files are under the folder project.</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ <span class="keyword">ls</span></div></pre></td></tr></table></figure>

<p>And, we can compile our C++ codes as below. The two cpp files will be linked together automatically (i.e., It links all the object files that are separated by a white space.).  Here we will get one executable file (e.g., run). <code>-o filename</code> is an argument of output file name.</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="comment">$</span> <span class="comment">g</span><span class="literal">+</span><span class="literal">+</span> <span class="comment">main</span><span class="string">.</span><span class="comment">cpp</span> <span class="comment">myMax</span><span class="string">.</span><span class="comment">cpp</span> <span class="literal">-</span><span class="comment">o</span> <span class="comment">run</span></div></pre></td></tr></table></figure>

<p>Finally, execute <code>./program</code> the program, and the results will be printed on the Terminal windows. The above steps are shown in Figure 3.</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>./run</div></pre></td></tr></table></figure>

<p><img src="http://media-cache-ec0.pinimg.com/originals/0c/ce/39/0cce398d637b44bc189ef32d8d6b2f33.jpg" alt="▲ Figure 3: Screenshot of final results."></p>
<h2 id="Using_Xcode">Using Xcode</h2>
<p>We use the Xcode in Mac which is almost the same as windows’ Dev-C++. In Figure 4, we create a new Xcode project, and then select the <strong> <em>OSX &gt; Application &gt; Command Line Tool</em> </strong> option (Figure 5).</p>
<p><img src="http://media-cache-ak0.pinimg.com/originals/4e/99/11/4e9911c6a8f276155b9076785ec407b5.jpg" alt="▲ Figure 4: Create a new Xcode project."></p>
<p><img src="http://media-cache-ec0.pinimg.com/736x/85/aa/1b/85aa1b5598a9008a7ae5a4a66aec2f0b.jpg" alt="▲ Figure 5: OSX &gt; Application &gt; Command Line Tool"></p>
<p>In Figure 6, you need to name the product first, and keep the product type as C++ (of course).  Then, we put all of the downloaded source codes in the project, but we need some tips to do that. Now, create two empty files manually (<strong><em>File &gt; new &gt; File</em></strong>), and those will be your <em>cpp</em> file and <em>header</em> file (Figure 7 and Figure 8).</p>
<p><img src="http://media-cache-cd0.pinimg.com/originals/67/7d/75/677d75783e85548b6b3995235da870f8.jpg" alt="▲ Figure 6: Name the Product."></p>
<p><img src="http://media-cache-ec0.pinimg.com/originals/c7/03/36/c70336e5b0bc319cac47cf053948b02a.jpg" alt="▲ Figure 7: Create two empty files manually."></p>
<p><img src="http://media-cache-ak0.pinimg.com/originals/38/7c/87/387c8791e7deb2c373f9e082eb6e5efd.jpg" alt="▲ Figure 8: Those are your cpp file and header file."></p>
<p>Finally, we can execute your project, and we will get the results in the console window in the bottom of Xcode (Figure 9).</p>
<p><img src="http://media-cache-ak0.pinimg.com/originals/0b/65/78/0b6578094de1329f9eb5ff60bdf06d67.jpg" alt="▲ Figure 9: Execute Project."></p>
<h2 id="後記">後記</h2>
<p>第一次用英文打這種 Tutorial，因為當了 全英文授課的 PD 助教所以需要全英文的文件，希望一學期過後破爛的英文可以稍微有些長進ＱＱ 特別感謝 Lynn 從旁協助。</p>
<h2 id="Reference">Reference</h2>
<ul>
<li><a href="https://github.com/evenchange4/102-1_DS_TA_Sample-code/tree/master/ADT%20List%20code" target="_blank" rel="external">ADT List implement sample code</a></li>
<li><a href="https://docs.google.com/viewer?a=v&amp;pid=sites&amp;srcid=ZGVmYXVsdGRvbWFpbnxudHVjc2llYzIwMTJ8Z3g6MWE1NzkzNzMxNzI0ODVmZQ" target="_blank" rel="external">2012.09.11 程式編輯與編譯環境安裝 Summary</a></li>
<li><a href="https://gist.github.com/evenchange4/52ba298788b23bda9ac3" target="_blank" rel="external">Class 範例程式</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/linux/" term="linux"/>
    <category scheme="http://michaelhsu.tw/tags/c/" term="c++"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Using SSH Connect to Windows Vmware Ubuntu]]></title>
    <link href="http://michaelhsu.tw/2014/03/15/vmware-port-forwarding/"/>
    <id>http://michaelhsu.tw/2014/03/15/vmware-port-forwarding/</id>
    <published>2014-03-15T13:24:55.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>當你的電腦是 Windows 系統，卻需要 Linux (Ubuntu) 環境的話，選擇架設 Virtual maching 是一個不錯的選擇。或許有許多環境有 For windows 的版本，但是很難避免一些小問題，畢竟 Linux 的資源比較多。</p>
<p>最近的一個需求情境是這樣的，LAB 的電腦是 Windows 系統，但是我想要 Ruby 去做資料的 Preprocess，但是本身使用 Mac 的我，實在不習慣 Windows 的 CMD ，所以選擇使用 Vmware 架設一個 <code>Ubuntu 12.04.4 LTS</code> 環境，但是離開實驗室後，要怎麼使用 LAB 電腦撰寫程式呢？</p>
<!-- 1. Port forwarding
2. Folder Sharing -->

<a id="more"></a>

<blockquote>
<p>使用 SSH 登入你遠端電腦的 Vmware Ubuntu</p>
</blockquote>
<p>但是要怎麼透過 Windows 的固定 IP 連進你的 Virtual machine 呢？透過 Port Forwarding 的設定將 Vmware Ubuntu 的 Port 對應到 Windows 的 Port。</p>
<h2 id="Configuration_Environment">Configuration Environment</h2>
<ol>
<li>Windows 7 Enterprise, 64-bit 6.1.7601, Service Pack 1, With Memory 16GB</li>
<li>Licensed VMware® Workstation 10 </li>
<li>Setup Virtual Machine with Ubuntu 12.04.4 LTS</li>
<li>Use a NTU fixed IP </li>
<li>Want to make the SSH/FTP (22/TCP) available to the network</li>
</ol>
<h2 id="Port_forwarding">Port forwarding</h2>
<ol>
<li><p>Vmware NAT Setting: 首先將 Vmware 新增設定，開啓 <code>Edit</code> &gt; <code>Virtual Network Editor</code> ，選擇使用 <code>NAT</code>（基本上就是 Vmnet8） 的網路連線形態，點選 <code>NAT Setting...</code>，然後 <code>Add</code> 新增一筆。</p>
<p> <img src="http://media-cache-ec0.pinimg.com/736x/58/09/a8/5809a8710536ecb65a7894e7288dd994.jpg" alt="VMware Port forwardind - NAT setting"></p>
<p> <em>上束這個例子就是將 Windows 的實體 IP port 5555 對應到 VM 中的 Ubuntu port 22。</em></p>
</li>
<li><p>Setup custom Firewall for Port: <code>Windows 防火牆</code> &gt; <code>進階</code> &gt; <code>輸入規則</code> &gt; <code>新增規則</code> ，接者選擇 TCP 以及欲開啟的 Port number （上述例子 55555），就完成開啟 Windows Port 的設定了。</p>
<p> <img src="http://media-cache-ec0.pinimg.com/736x/21/d5/75/21d575df4c43fbee3c4e928d5c8ef8a6.jpg" alt="Open port for Windows"></p>
</li>
</ol>
<h2 id="How_to_Start_Connecting">How to Start Connecting</h2>
<p>當然你需要將你的 Ubuntu 安裝好 SSH (參考 Reference)， 然後直接在 terminal 輸入以下指令，或是使用 Putty 等軟體登入。</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ ssh <span class="variable">&lt;userid&gt;</span><span class="comment">@&lt;IP&gt; -p &lt;port_number&gt;</span></div><div class="line"><span class="comment"># example: </span></div><div class="line"><span class="comment"># ssh michaelhsu@140.112.117.123 -p 55555</span></div></pre></td></tr></table></figure>

<blockquote>
<p>恭喜你可以在任意地方使用 SSH 登入你的 VM 工作了！，當然 FTP 也是可以。</p>
</blockquote>
<h2 id="Folder_Sharing">Folder Sharing</h2>
<p>當然你也可以直接操作 LAB 電腦來使用 Windows Putty SSH 登入你的 VM Ubuntu，但是問題來了，原本存在 Windows 實體硬碟中欲處理的 Dataset 該怎麼搬移進去 Virtual Machine 呢？你可以想說用拖曳的（VMware 小檔案的確可以！），或是使用 FTP 連線上傳，但是當資料量大到無法這樣做呢？例如我最近在處理 Twitter 7 month raw Dataset 將近 25GM 的檔案，該怎麼辦呢！？頭疼了。</p>
<blockquote>
<p>直接與你的 Virtual Machine Share Folder 是一個很不錯的選擇。</p>
</blockquote>
<p>a. Install Vmware Tools: 安裝 Vmware 共享資料夾所需要的工具：透過設定 <code>VM</code> &gt; <code>Install Vmware Toola</code> 接者會跳出下載下來的目錄資料夾，將 <code>VMwareTools-8.4.5-324285.tar.gz</code>（版本號可能不同） 複製到 <code>/tmp</code> 底下接者解壓縮</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>cd /tmp</div><div class="line"><span class="variable">$ </span>tar zxvf <span class="constant">VMwareTools</span>-<span class="number">8.4</span>.<span class="number">5</span>-<span class="number">324285</span>.tar.gz</div></pre></td></tr></table></figure>

<p>並且進行安裝：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">$ cd vmware-tools-distrib</div><div class="line">$ sudo ./vmware-install.pl</div><div class="line"></div><div class="line"><span class="preprocessor"># 隨者指示安裝完畢後出現</span></div><div class="line"><span class="preprocessor">#</span></div><div class="line"><span class="preprocessor"># Enjoy,</span></div><div class="line"><span class="preprocessor"># 　　--the VMware team</span></div></pre></td></tr></table></figure>

<p>b. Setup Shared Folders: 透過 Vmware 設定 <code>Virtual Machine Setting</code> &gt; <code>Options</code> ，在 VM Power Off 的情況下可以新增一筆欲共用的資料夾。</p>
<p><img src="http://media-cache-ec0.pinimg.com/736x/e0/0a/79/e00a7913afa6c5d590984e1304c898b4.jpg" alt="Folder Sharing"></p>
<p>於是乎你的資料就來去自如，你可能會覺得這樣很像 Dropbox 的功能，他是真正的不透過網路共用資料，也是無時差的同步，不過必須額外小心處理！</p>
<p><img src="http://media-cache-ak0.pinimg.com/736x/48/37/71/483771d3e05ed978d2bf6bf2ef044ab2.jpg" alt="Working with Vmware Ubuntu in Windows 7"></p>
<p><em>上述應用為使用 Windows 的 Sublime3 寫完程式後並儲存在分享的資料夾中，直接使用 Putty 登入的 VM Ubuntu 的環境執行該程式</em></p>
<h2 id="延伸應用與後記">延伸應用與後記</h2>
<p>突然想起來之前在 TMI (台灣創意工場)  intern 的時候，曾經使用 Vmware Centos 架設 PHP Server ，原來我很早就接觸過這種連線的設定，只是一直沒有沒有機會使用到。這邊我另外做了一個嘗試多開一個 Port 給 VM Ubuntu run <code>Rails</code> project ，並透過上面教學的步驟設定，成功可以將外面的連線導到 Virtual Machine 架設的 Server 中，如此以來就可以打在一個最佳的架設環境了！感到熱血沸騰啊。</p>
<p>最後感謝坐我隔壁的 LAB 同學，一起討論學到蠻多東西的，我覺得未來一年半應該也會常常提到他，應此以後就稱他為 <del>陽光宅男</del> <code>Mr. Sunshine</code> 好了。</p>
<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://windows.microsoft.com/zh-tw/windows/open-port-windows-firewall#1TC=windows-7" target="_blank" rel="external">在 Windows 防火牆中開啟連接埠</a></li>
<li><a href="https://www.virten.net/2013/03/how-to-setup-port-forwarding-in-vmware-workstation-9/" target="_blank" rel="external">How to Setup Port Forwarding in VMware Workstation 9</a></li>
<li><a href="http://compositecode.com/2013/11/10/using-ssh-locally-to-work-with-ubuntu-vm-vmware-tools-installation-via-shell/" target="_blank" rel="external">Using SSH Locally to Work With Ubuntu VM + VMware Tools Installation via Shell</a></li>
<li><a href="http://www.cnblogs.com/RealOnlyme/archive/2012/04/08/2437811.html" target="_blank" rel="external">[转载]VMware 虚拟机安装Ubuntu 11.10使用share folders共享目录</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/linux/" term="linux"/>
    <category scheme="http://michaelhsu.tw/tags/vmware/" term="vmware"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[為什麼你該使用 Linux Screen]]></title>
    <link href="http://michaelhsu.tw/2013/12/21/use-linux-screen/"/>
    <id>http://michaelhsu.tw/2013/12/21/use-linux-screen/</id>
    <published>2013-12-21T04:35:27.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>對於 Linux 系統幾乎都是內建的工具，可以讓你真正的遠端工作，最適合有使用遠端主機透過 ssh 或是其他連線方式進行工作的人，讓你下次回到工作模式時，立即進入狀況！</p>
<blockquote>
<p>讓你下次回到工作模式時，立即進入狀況！</p>
</blockquote>
<a id="more"></a>


<h2 id="常用指令">常用指令</h2>
<ul>
<li>Out of screen</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>screen -r</div><div class="line"><span class="variable">$ </span>screen -ls</div></pre></td></tr></table></figure>

<ul>
<li>In screen <code>ctrl+a</code> 之後鍵入：<ul>
<li><code>c</code>: create a window</li>
<li><code>d</code>: 離開 (detach)</li>
<li><code>A</code>: rename the window</li>
<li><code>k</code>: kill</li>
<li><code>?</code>: 熱鍵查詢</li>
<li><code>數字</code>: 換頁</li>
</ul>
</li>
</ul>
<h2 id="配置設定_Screen_畫面_vim_~/-screenrc">配置設定 Screen 畫面 <code>vim ~/.screenrc</code></h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">hardstatus on</div><div class="line">hardstatus alwayslastline</div><div class="line">hardstatus string <span class="string">"%{.bW}<span class="variable">%-</span>w%{.rY}<span class="variable">%n</span> <span class="variable">%t</span>%{-}<span class="variable">%+</span>w <span class="variable">%=</span>%{..G} <span class="variable">%H</span>(<span class="variable">%l</span>) %{..Y} <span class="variable">%Y</span>/<span class="variable">%m</span>/<span class="variable">%d</span> <span class="variable">%c</span>:<span class="variable">%s</span> "</span></div><div class="line"><span class="comment"># 設定視窗回捲時可看到的行數</span></div><div class="line">defscrollback <span class="number">2048</span></div></pre></td></tr></table></figure>

<ul>
<li><img src="http://media-cache-ak0.pinimg.com/originals/36/73/42/3673423624133dff9416119ed50d2853.jpg" alt="linux screen "></li>
</ul>
<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://napmas.blogspot.tw/2011/09/screenrc.html" target="_blank" rel="external">沒事做，弄點小設定。把常用的screen 再弄得看起來厲害一點</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/linux/" term="linux"/>
    <category scheme="http://michaelhsu.tw/tags/ssh/" term="ssh"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[HTTP Server 大小事]]></title>
    <link href="http://michaelhsu.tw/2013/07/04/server/"/>
    <id>http://michaelhsu.tw/2013/07/04/server/</id>
    <published>2013-07-04T05:54:21.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<h1 id="Web_server_/_Application_server_傻傻分不清楚_？">Web server / Application server 傻傻分不清楚 ？</h1>
<p>都通稱是 server，但確有些許微妙的不同，小時候一直很不懂之間的差別，直到最近才搞得比較清楚一點。<br><a id="more"></a></p>
<h1 id="Web_server">Web server</h1>
<p>Apache、Nginx 都是 <code>web server</code> ，主要可以拿來 serve static files、serve dynamic web apps （ex: PHP 寫的）。注意！但是他們都不能夠直接拿來 serve <code>Ruby web apps</code>，必須要透過額外的 add-on 才行。<br>其中 Apache 應該是比較常聽到的架設選項，但是近年大家都偏好使用 Nginx 是因為他比較沒那麼肥大，而且速度比 Apache 快，所以變成了架設 server 的首選。<br>另外他們除了做 proxy server 外，也可以拿來做 Reverse Proxy Server ，因為彼此的特性不同，也常常混合者使用，例如拿 Nginx 來做 Reverse Proxy Server ，拿 Apache 來當做後面的 Web Server。</p>
<p><img src="http://media-cache-ec2.pinimg.com/originals/c8/42/c5/c842c5e2cbe2e7e3a726d8589c9c219c.jpg" alt="Nginx vs Apache 比較圖表"></p>
<h1 id="什麼是_Proxy_Server_、_Reverse_Proxy_Server？">什麼是 Proxy Server 、 Reverse Proxy Server？</h1>
<h2 id="Proxy_Server（代理伺服器）">Proxy Server（代理伺服器）</h2>
<p>他的工作是去各個 Web Server 抓取資料回來放在伺服器上來供用戶讀取下載，如此一來可以大幅減少到各個 Web server 抓取資料的時間。</p>
<p><img src="http://media-cache-ak1.pinimg.com/originals/58/f7/d1/58f7d140cf1a22a37bcc46efe292375d.jpg" alt="proxy server"></p>
<h2 id="Reverse_Proxy_Server（反向代理伺服器）">Reverse Proxy Server（反向代理伺服器）</h2>
<p>他做的事情恰好相反，負責將用戶端的資料傳送（HTTP）給藏在 Reverse Proxy Server 後面的 Web Server，這些躲在後面的 Web Server 不會、也不能直接被用戶直接連結，只能經由 Reverse Proxy Server 代理傳送和接收資料，如此不僅可以保護後方 Web Server 被攻擊，同時還可提供負載平衡、快取以及資料加密的功能。</p>
<blockquote>
<p>When that server responds with an HTTP response, Apache/Nginx will forward the response back to the client. You will learn later why this is relevant.</p>
</blockquote>
<p><img src="http://media-cache-ak0.pinimg.com/originals/5e/5f/d7/5e5fd7a0f14c6f1edc7de6b67fc3c6a2.jpg" alt="Reverse Proxy Server"></p>
<h1 id="Application_server">Application server</h1>
<p>可以是很多語言寫的 app server，這邊拿 ROR 的 app server 來比較，通常你在 <code>rails new project</code> 的時候所預設 server 是 <code>WEBrick</code>，這就是一個 <code>app server</code>，所以你在 run <code>$ rails s</code> 的時候就會看到 <code>=&gt; Booting WEBrick</code>，這是因為 rails 內建的 app server 是 WEBrick，但是我們通常在部署的時候就不會使用 WEBrick 這樣的 app server，因為 <code>慢！</code>。</p>
<p><img src="http://media-cache-ak1.pinimg.com/originals/d8/d9/85/d8d985f9bb711421bd18a7e87d49d15e.jpg" alt="rails default app server"></p>
<p>所以我們通常會把 Rails 的 App server 給換掉，但是你可能會懷疑會什麼可以這樣直接換 app server 勒？答案是強大的 <code>Rack</code> 設計。</p>
<h2 id="什麼是_Rack？">什麼是 <a href="https://github.com/rack/rack" target="_blank" rel="external">Rack</a>？</h2>
<blockquote>
<p>Rack: a Ruby Webserver Interface.<br>provides a minimal interface between webservers supporting Ruby and Ruby frameworks.</p>
</blockquote>
<p>Rack 是各種 web framework 與各種 app server 的橋梁（middleware），其中必須制定好規則也就是 <code>Rack SPEC</code>，簡單用圖來表示就是像這樣：</p>
<p><img src="http://media-cache-ec2.pinimg.com/originals/29/37/15/29371534a2f8f37492976a983fa8e710.jpg" alt="Rack: app servers / web frameworks"></p>
<h2 id="比較_Rails_各種_App_server">比較 Rails 各種 App server</h2>
<p>很抱歉因為志志實在太熱愛寫 ROR 了，這邊就只能做 Rail 的 app server 比較了。</p>
<ol>
<li>Mongrel: <ul>
<li>過時的 <code>雜種</code>。</li>
<li>written in part Ruby part C</li>
<li>no process monitoring，當調需要手動重啓。</li>
</ul>
</li>
<li>WEBrick: <ul>
<li>not fit for production</li>
<li>written entirely in Ruby (慢)</li>
<li>但是因為他是純 ruby 寫的，所以被設為預設（heroku 也是），不需額外安裝。</li>
</ul>
</li>
<li>Unicorn:<ul>
<li>fork of Mongrel，加上 process monitoring</li>
<li>因為 make all processes listen on a single shared socket, instead of a separate socket for each process. 所以簡化了 reverse proxy 的設定。</li>
</ul>
</li>
<li>Thin:<ul>
<li>no process monitoring</li>
<li>evented I/O</li>
</ul>
</li>
<li>Puma:<ul>
<li>forked from Mongrel</li>
<li>purely multi-threaded</li>
</ul>
</li>
<li>Phusion Passenger:<ul>
<li>Dynamically adjusting the number of processes based on traffic</li>
<li>written in C++, making it very fast.</li>
</ul>
</li>
<li>Rainbows:</li>
</ol>
<h2 id="現實世界的_App_server_怎麼運作">現實世界的 App server 怎麼運作</h2>
<p>在這多的 app servers 中，像是 <code>Phusion Passenger</code>, <code>Rainbows</code> 就可以直接透過 port 開在 80 來達到 directly exposed to the Internet。但是有些 app server 卻不建議這麼做，例如 <code>Mongrel</code>, <code>Unicorn</code>, <code>Thin</code>, <code>Puma</code>。他們需要放在 reverse proxy server 後面比較恰當。</p>
<h2 id="為什麼需要_Apache/Nginx_reverse_proxy_server？">為什麼需要 Apache/Nginx reverse proxy server？</h2>
<ol>
<li>因為這些 app server 一次只能 handle 1 request concurrently，如果有兩個以上的 request，就必須要 run multiple app server instances（<code>app server cluster</code>），而這正是 Apache/Nginx 可以透過 reverse proxy，幫助你適當 <code>distributing requests between the instances in the cluster</code>，而且可以 buffer requests and responses 避免發生 <code>slow clients</code> 的情況發生。<blockquote>
<p>Apache and Nginx are very good at doing many things at the same time because they’re either multithreaded or evented. </p>
</blockquote>
</li>
<li>Web server 比起 App server 更適合來 serve static files。</li>
<li>安全，避免 corrupted requests。</li>
</ol>
<p>那為什麼 <code>Phusion Passenger</code> 可以不需要 Apache/Nginx reverse proxy server？ 因為它在設計上具有獨特的特性：integrates directly into Apache or Nginx （Web server）所以你在架設的時候也相當簡易，可以參考 <a href="http://michaelhsu.tw/2013/06/26/nginx-passenger-rails-setup-on-ubuntu/" target="_blank" rel="external">Nginx + Passenger + Rails4 Setup on Ubuntu12.04</a>。</p>
<h2 id="現實中的_Requests">現實中的 Requests</h2>
<p>如果你只是需要做 Prototype demo 用，一般的開個 App server 當然沒問題，但是真的搬到台面上運作呢？當然不行，面對龐大的使用者你的 Server 必須要能夠應付得了。來看看實際上的 Web Request 是怎麼處理的。</p>
<p><img src="http://media-cache-ec3.pinimg.com/originals/b6/e1/be/b6e1be1319facc07a91f9c5d9c1909df.jpg" alt="面對大量 requests"></p>
<h1 id="OS_課程回顧：">OS 課程回顧：</h1>
<ul>
<li><code>Program</code>：程式碼（ OOP Class）。</li>
<li><code>Process</code>：Program 所產生的執行個體（ OOP Object ）。因此一個 Program 可以同時執行多次產生多個 Process。每個proecess 包含：<ul>
<li>一個 Memory Space（ OOP variable ），因此不同 Process 的 Memory Space 也不同,彼此看不到對方的 Memory Space。</li>
<li>一個以上的Thread。Thread：CPU執行的最小單位。</li>
</ul>
</li>
</ul>
<h3 id="Process_去取得_CPU_資源，很多_Process_去運用資源的方式有兩種">Process 去取得 CPU 資源，很多 Process 去運用資源的方式有兩種</h3>
<ol>
<li>multiprogramming 一次執行一個 Process，等到 I/O 再換下一個，剩餘的放在 memory。</li>
<li>time sharing 來快速切換 process。</li>
</ol>
<p>釐清：multi-tasking 利用 CPU 多核來同使處理 tasks</p>
<h3 id="取得_process_的方法就得使用_Process_scheduler：">取得 process 的方法就得使用 Process scheduler：</h3>
<ol>
<li>short-term scheduler（CPU scheduler ），來決定哪下一個被處理的 Process。</li>
<li>long-term scheduler （Job scheduler ）來決定哪些 process 來放到 ready queue</li>
</ol>
<h3 id="至於_multi-thread_的使用_CPU_資源又是另一個_Thread_Scheduling_的事情了">至於 multi-thread 的使用 CPU 資源又是另一個 Thread Scheduling 的事情了</h3>
<p><img src="http://media-cache-ak3.pinimg.com/originals/23/6b/81/236b8188125600d8d845ceb78594681a.jpg" alt="Thread Scheduling"></p>
<p><img src="http://media-cache-ec2.pinimg.com/originals/8e/d2/a2/8ed2a27ed9dbed0f503eb2df6217dfc1.jpg" alt="multi-thread"></p>
<p>我們可以將處理大量的 Requests （<code>I/O concurrency models</code>）方式分為四種：</p>
<ol>
<li>Single-threaded multi-process<ul>
<li>最傳統的做法，因為早期 Ruby 的生態系對於 multithreading 支援度不高。</li>
<li>因此需要 web server load balances between processes</li>
<li>適合 for fast, short-running workloads</li>
<li>不適合 for slow, long-running blocking I/O workload</li>
<li>而且如果每個 Request 都沒有 I/O blocking，利用的 CPU 效率就是最好的。</li>
<li><code>同時</code>連線線就等於能用的Process數量（例如最基本512 mb的主機上，通常可以開 3 個 Rails process，但是因為每個連線都控制在 20ms 以下，所以每秒鐘能處理的 requests 數量還是十分驚人，足以應用絕大部分的應用場景。</li>
<li><code>Mongrel</code>、<code>Unicorn</code></li>
</ul>
</li>
<li>Purely multi-threaded<ul>
<li>因為現今 Ruby 生態系的發展，multithreading 支援度高，所以有些 App server 採取這個方式，</li>
<li>Multithreading allows high I/O concurrency</li>
<li>第一點提到的兩種情況都適合。</li>
<li>因為採用 Global Interpreter Lock (GIL) 所以不能夠 leverage multiple CPU cores</li>
<li>no builtin cluster support. 所以 You need to take special care to ensure that you can utilize multiple cores</li>
<li><code>Puma</code></li>
</ul>
</li>
<li>Hybrid multi-threaded multi-process<ul>
<li>implemented by Phusion Passenger Enterprise 4 </li>
<li>因為 hybrid 的設計，就算 Global Interpreter Lock (GIL) 也可以 fully utilize all CPU cores。</li>
<li>任意切換組合： single-threaded multi-process, purely multithreaded, or perhaps even multiple processes each with multiple threads</li>
<li>Puma, the hybrid mode is called “clustered”</li>
</ul>
</li>
<li>Evented-driven<ul>
<li>完全不同的設計概念，無論有多少連線，只有在有事件發生時，才會讓CPU做事。</li>
<li>allows very high I/O concurrency</li>
<li>excellent for long-running blocking I/O workloads</li>
<li>但是 Framework 的設計概念必須一致，例如 Rails、Sinatra 這樣的 Framework 就不行。ex: 雖然 <code>Thin</code> 在設計上是這樣，但是搭配 rails 就仍舊只能 single-threaded multi-process</li>
<li><code>thin</code></li>
</ul>
</li>
</ol>
<h3 id="總結：">總結：</h3>
<p>我們可以把網路真實的情況分為三個層級來做適當的處理：</p>
<ul>
<li>Situation 1：天真的想法，但是其實堪用。</li>
</ul>
<p>面對大量的 Client Request，<code>multi-proecess</code> （這邊講的是 single-thread）是最原始的做法，讓每一個 Request 都產生一個完整的 Rails app Process，而每個 Process 去取得 CPU core 得到運算資源來作處理，當然 Process 取得 CPU 資源應該在 OS 課程上學到，也許會透過一些排程來作 CPU 資源分配，但是切換 Process 需要 Context switch 是一種負擔。multi-proecess 這樣的做法好處是，除了撰寫容易外，面對只需要運算而不需要做 I/O blocking 的程式就能達到最好的 CPU 資源利用。</p>
<ul>
<li>Situation 2：中等的想法，但也是堪用。</li>
</ul>
<p>但是一旦碰到很多 I/O blocking ，能夠同時處理的 Request 就會受到限制，不過其實 <code>multi-proecess</code> 對於一般的服務，負載量是沒問題的。<br>但是當面對非常大量的或連續的 HTTP request，例如聊天室，每個使用者連線持續佔用 Process，或是 Process 需要的 Context switch 總成本量太高，就會出現等待問題了。這時候想到的解決方案是 <code>Multi-threaded</code>，因為利用 Thread 來取代 process 得以降低 context switching 負擔，因為 Thread 共用 Memory Space 的特性。這樣的解法是沒問題的，雖然程式設計撰寫上比較沒這麼容易，但是因為 Ruby 對於 Multi-threaded 的支援度越來越高，所以也算是一個很好地解決方案。</p>
<ul>
<li>Situation 3：天人的想法，好還要更好。</li>
</ul>
<p>現階段正在發展，最好的做法還是應該採用 Evented-driven 的 <code>Actor model</code>。就算是 Thread 很廉價，但是數量一多還是會成為 Server 負擔。Actor model 是個無窮的迴圈，無論有多少連線，只有在有事件發生時，才會讓CPU做事。<br>所以要如何達到 Evented-driven 呢？在 Rails 架構下，除了把 App server 改成有 evented 特性的 <code>thin</code> server 外，要把 rails 本身的 I/O 操作都改成 evented 版本，不然只要有一個部分被 blocking ，等於做了白功。事實上， Rails 這個 web framework 本來就並非 Evented-driven 的設計概念，所以最的方法是會選令其他 web frameworks ，例如 ruby 的 <code>Cramp</code>、<code>Goliath</code>（base on <code>EventMachine</code> ruby library)，或是其他語言的 Evented 框架如 <code>node.js</code>。</p>
<h1 id="實作自己_Host_HTTP_server">實作自己 Host HTTP server</h1>
<p>參考 <a href="http://michaelhsu.tw/2013/06/26/nginx-passenger-rails-setup-on-ubuntu/" target="_blank" rel="external">Nginx + Passenger + Rails4 Setup on Ubuntu12.04</a>，有簡易的步驟教學。</p>
<h1 id="Reference">Reference</h1>
<ul>
<li><a href="http://stackoverflow.com/questions/4113299/ruby-on-rails-server-options/4113570#4113570" target="_blank" rel="external">Ruby on Rails Server options [closed]</a></li>
<li><a href="https://github.com/FooBarWidget/passenger/wiki/Puma-vs-Phusion-Passenger?utm_source=rubyweekly&amp;utm_medium=email" target="_blank" rel="external">Puma vs Phusion Passenger</a></li>
<li><a href="http://140.131.86.2/Ftp/240914500/q018/q018.htm" target="_blank" rel="external">Proxy server 簡介</a></li>
<li><a href="http://www.arthurtoday.com/2010/01/reverse-proxy-server.html" target="_blank" rel="external">Reverse Proxy Server ( 反向代理伺服器 ) 是什麼 ?</a></li>
<li><a href="http://neverealize.tumblr.com/post/32388841062/web-server-compare" target="_blank" rel="external">第一話 WEB SERVER COMPARE</a></li>
<li><a href="http://wp.xdite.net/?p=1557" target="_blank" rel="external">Rack 與 Rack middleware</a></li>
<li><a href="http://rack.github.io/" target="_blank" rel="external">Rack: a Ruby Webserver Interface</a></li>
<li><a href="http://ihower.tw/rails3/deployment.html" target="_blank" rel="external">Ruby on Rails 實戰聖經 佈署</a></li>
<li><a href="http://210-70-179-219.cjcu.edu.tw/CourseOS/homework/Ch4_Homework_Ans.htm" target="_blank" rel="external">Chapter 4 Homework- Threads 參考答案 </a></li>
<li><a href="http://programming.im.ncnu.edu.tw/J_Chapter9.htm" target="_blank" rel="external">Program,Process,Thread</a></li>
<li><a href="http://www.csie.ntnu.edu.tw/~swanky/os/chap4.htm" target="_blank" rel="external">Context Switching(內文切換)</a></li>
<li><a href="http://answers.yahoo.com/question/index?qid=20101031182605AAczoHe" target="_blank" rel="external">What is the difference between time-sharing and multitasking?</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/rails/" term="rails"/>
    <category scheme="http://michaelhsu.tw/tags/ruby/" term="ruby"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[如何愛上開發 Ruby2 on Rails4]]></title>
    <link href="http://michaelhsu.tw/2013/07/03/ror/"/>
    <id>http://michaelhsu.tw/2013/07/03/ror/</id>
    <published>2013-07-03T14:15:13.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>因為對於很多新鮮技術感興趣的我，接觸了不少開發的語言，包括 <code>ios(objective-C)</code>、 <code>android(java)</code>、<code>web(ROR)</code>，雖然接觸的都不算深，但是我最後發現 web 才是最對我胃口的開發應用。</p>
<blockquote>
<p>寫網頁吧，比較有成就感！<br>Ruby on Rails</p>
</blockquote>
<a id="more"></a>

<p><img src="http://blog.vinova.sg/wp-content/uploads/2011/09/ruby_rails_is_love.png" alt="rails lover"></p>
<h1 id="開發準備工作">開發準備工作</h1>
<ul>
<li>最佳環境： <code>Mac</code> &gt;&gt; <code>linxu Ubuntu 12.04</code> &gt;&gt;&gt;&gt; <code>windows</code></li>
<li>什麼是 HTML CSS Javascript？<ul>
<li><a href="http://mrorz.github.io/webdev/#/" target="_blank" rel="external">HTML5, CSS/Sass, jQuery, Bootstrap<br>新一代網頁設計</a></li>
<li><a href="http://homepage.ntu.edu.tw/~b98705034/" target="_blank" rel="external">第一次寫網頁就上手</a></li>
<li>HTML 標記語言</li>
<li>CSS 長什麼樣子</li>
<li>javascript 動畫或功能</li>
</ul>
</li>
<li>其他<ul>
<li>孫媽 網路應用課</li>
<li>Tony 資料庫管理</li>
<li>小盧 SA</li>
<li>資料結構</li>
</ul>
</li>
</ul>
<h2 id="靜態網頁，需不需要架設伺服器呢？">靜態網頁，需不需要架設伺服器呢？</h2>
<p>答案不需要。因為不需要資料庫，也不需要運算能力。</p>
<p>那靜態網頁可以放在哪裡？自己電腦桌面上、學校空間、dropbox、<code>github page!</code><br>ex: 計概作業放到學校空間上。</p>
<p><a href="http://code.kpman.cc/2013/05/18/%E5%BB%BA%E7%AB%8B%E8%87%AA%E5%B7%B1%E7%9A%84github-project-pages/" target="_blank" rel="external">建立自己的GitHub Project Pages</a></p>
<h2 id="Ruby_on_Rails_可以做到什麼事情？">Ruby on Rails 可以做到什麼事情？</h2>
<p><a href="http://im102timeline.herokuapp.com/" target="_blank" rel="external">http://im102timeline.herokuapp.com/</a></p>
<p>你可以把設計網頁分為兩個部分</p>
<ol>
<li>存取資料（新增資料那些）</li>
<li>網頁美觀度</li>
</ol>
<p>而為什麼1.的部分可縮短成10分鐘呢？因為 ROR 就是要推薦你們的好東西。</p>
<ol>
<li>開發快速</li>
<li>好維護</li>
</ol>
<h1 id="Ruby_關於_Ruby">Ruby <a href="http://www.ruby-lang.org/zh_tw/about/" target="_blank" rel="external">關於 Ruby</a></h1>
<p>跟 C、C++、java、PHP、Ruby、Python 一樣就是程式語言，但是是比較特別的高階的程式語言。</p>
<blockquote>
<p> 試著讓 Ruby 更為自然，而不是簡單。</p>
</blockquote>
<ul>
<li>scripting language。</li>
<li>純物件導向的語言。</li>
<li>區塊(Blocks)：<code>{}</code>、<code>do ... end</code></li>
<li>動態語言<ul>
<li>動態語言(Ruby、Python、PHP、Perl等)比起靜態語言(Java、C++等)</li>
<li>靜態語言和動態語言的差別在於，前者的變數型別需要事前宣告，後者則是執行期才動態決定。實務上，就看程式需不需要事前編譯這個動作了。</li>
<li><ol>
<li>執行效能是絕對比不上靜態語言的 </li>
</ol>
</li>
<li><ol>
<li>沒有編譯期可以檢查型別錯誤</li>
</ol>
</li>
<li>不需要編譯</li>
</ul>
</li>
</ul>
<h2 id="安裝_Ruby_2-0-0-p195">安裝 <code>Ruby 2.0.0-p195</code></h2>
<ol>
<li>請先更新電腦再開始</li>
<li>text editor: <a href="http://www.sublimetext.com/" target="_blank" rel="external">sublime 2</a></li>
<li>chrome</li>
<li><a href="https://rvm.io/" target="_blank" rel="external">rvm</a></li>
</ol>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">$ sudo apt-<span class="built_in">get</span> <span class="keyword">update</span></div><div class="line">$ sudo apt-<span class="built_in">get</span> install curl</div><div class="line">$ \curl -L http<span class="variable">s:</span>//<span class="built_in">get</span>.rvm.io | bash -<span class="keyword">s</span> stable</div><div class="line">$ <span class="keyword">source</span> /home/michaelhsu/.rvm/scripts/rvm #!!注意不同！</div><div class="line">$ rvm <span class="keyword">list</span></div><div class="line">$ rvm install <span class="number">2.0</span>.<span class="number">0</span>-p195</div></pre></td></tr></table></figure>

<ul>
<li><code>$ irb</code> 玩玩看<ul>
<li><a href="http://tryruby.org/" target="_blank" rel="external">http://tryruby.org/</a></li>
<li><a href="http://www.ruby-doc.org/core-2.0/String.html" target="_blank" rel="external">http://www.ruby-doc.org/core-2.0/String.html</a></li>
<li><a href="http://www.ruby-doc.org/core-2.0/Array.html" target="_blank" rel="external">http://www.ruby-doc.org/core-2.0/Array.html</a></li>
<li><a href="http://www.ruby-doc.org/core-2.0/Hash.html" target="_blank" rel="external">http://www.ruby-doc.org/core-2.0/Hash.html</a></li>
</ul>
</li>
<li>ruby gem: <a href="http://rubygems.org/" target="_blank" rel="external">http://rubygems.org/</a></li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ gem <span class="keyword">list</span></div></pre></td></tr></table></figure>

<h2 id="ruby_可以寫什麼？">ruby 可以寫什麼？</h2>
<p>什麼都可以寫，像程式作業，舉例：<a href="http://michaelhsu.tw/2013/06/25/%E6%8D%B7%E9%81%8B%E7%AB%99%E7%B6%93%E7%B7%AF%E5%BA%A6%E5%9D%90%E6%A8%99-open-data/" target="_blank" rel="external">捷運站經緯度坐標 Open data</a></p>
<h1 id="為什麼需要網站開發框架？_Web_framework">為什麼需要<code>網站開發框架</code>？ Web framework</h1>
<p>程式語言與 HTML 標記語言太過於混雜，用 <code>&lt;?php ... ?&gt;</code> 括起來的部份參雜在 html file 裡面，雖然是可以進行開發，但是維護性非常低，也許自己可能也看不懂，至於所謂框架看起來就是長這樣：</p>
<ul>
<li><img src="http://media-cache-ak3.pinimg.com/originals/fe/5a/a3/fe5aa320c1890829e87473194c1269a3.jpg" alt="一層層的資料夾加上一些概念"></li>
</ul>
<h1 id="MVC_架構">MVC 架構</h1>
<ul>
<li>MVC 是一個設計概念，包括<ul>
<li>Model: 操作資料庫</li>
<li>View: 表示使用者介面</li>
<li>Controller: HTTP Request，與其他部分溝通</li>
</ul>
</li>
<li>很多地方都有提倡 MVC 架構，Rails 是其中之一</li>
<li>分離邏輯和使用者介面。</li>
<li><img src="http://media-cache-ak1.pinimg.com/originals/90/25/28/902528e5769a3115621abc41533a02bd.jpg" alt=""></li>
<li>其它語言開發框架？</li>
<li><img src="http://media-cache-ak3.pinimg.com/originals/9d/5c/4f/9d5c4f06860c413a4df3a41fe01ea02e.jpg" alt="language vs web frameworks -- wiki"></li>
</ul>
<h1 id="Rails_哲學說">Rails 哲學說</h1>
<ul>
<li>MVC<ul>
<li>VIEW: <code>html.erb</code>、<code>&lt;%= %&gt;</code></li>
<li>Controller: 主軸核心運算</li>
<li>Model: 操作資料庫</li>
</ul>
</li>
<li>DRY: Don’t Repeat Yourself</li>
<li>RESTful (最佳實踐規則) -&gt; controller 提到</li>
<li>ORM (Object-relational mapping) -&gt; model</li>
</ul>
<h2 id="安裝_rails_4-0-0">安裝 <code>rails 4.0.0</code></h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>gem install rails</div></pre></td></tr></table></figure>

<h1 id="實作">實作</h1>
<ul>
<li>rails new 建立一個 Rails Project，</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>rails new <span class="string">"myfirstror"</span></div><div class="line"><span class="variable">$ </span>cd myfirstror</div><div class="line"><span class="variable">$ </span>sudo apt-get install nodejs <span class="comment"># for ubuntu error</span></div><div class="line"><span class="variable">$ </span>rails server</div></pre></td></tr></table></figure>

<ul>
<li>利用 Scaffold 來快速打造一個 CRUD 的功能。</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ <span class="tag">rails</span> <span class="tag">generate</span> <span class="tag">scaffold</span> <span class="tag">food</span> <span class="tag">name</span><span class="pseudo">:string</span> <span class="tag">count</span><span class="pseudo">:integer</span> <span class="tag">descript</span><span class="pseudo">:text</span> <span class="tag">due</span><span class="pseudo">:datetime</span> <span class="tag">eatable</span><span class="pseudo">:boolean</span></div><div class="line"></div><div class="line">$ <span class="tag">rake</span> <span class="tag">db</span><span class="pseudo">:migrate</span></div></pre></td></tr></table></figure>

<ul>
<li><img src="http://media-cache-ak3.pinimg.com/originals/4c/53/f6/4c53f6e4114738835ee229966235412d.jpg" alt="attributes SQL types"></li>
<li>CRUD</li>
<li>Restful</li>
<li>rails gem 可以自己寫，但是記得 DRY，有人寫好就拿來用。</li>
</ul>
<h1 id="版本控制_git">版本控制 <code>git</code></h1>
<p>你的程式碼應該放在哪裡呢？</p>
<ol>
<li><del>你的電腦裡</del></li>
<li><del>你的隨身碟裡</del></li>
<li><del>dropbox</del></li>
<li>github!</li>
</ol>
<h2 id="安裝">安裝</h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">sudo</span> apt-get install git</div></pre></td></tr></table></figure>

<p>create github account<br>git 教學 <a href="http://try.github.io/" target="_blank" rel="external">try git</a></p>
<h1 id="Deploy_部署">Deploy 部署</h1>
<ul>
<li>RAILS_ENV: development/test/production</li>
<li>PaaS: Herku</li>
</ul>
<h2 id="安裝_heroku">安裝 heroku</h2>
<ul>
<li><a href="https://toolbelt.heroku.com/" target="_blank" rel="external">toolbelt</a></li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ wget -qO- http<span class="variable">s:</span>//toolbelt.heroku.<span class="keyword">com</span>/install-ubuntu.<span class="keyword">sh</span> | <span class="keyword">sh</span></div><div class="line">$ heroku login</div></pre></td></tr></table></figure>

<h3 id="heroku_push_設定_gemfile">heroku push 設定 <code>gemfile</code></h3>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">group <span class="symbol">:development</span> <span class="keyword">do</span></div><div class="line">  gem <span class="string">'sqlite3'</span></div><div class="line"><span class="keyword">end</span></div><div class="line">group <span class="symbol">:production</span> <span class="keyword">do</span></div><div class="line">  gem <span class="string">'pg'</span></div><div class="line"><span class="keyword">end</span></div><div class="line"></div><div class="line">gem <span class="string">'rails_12factor'</span>, <span class="symbol">group:</span> <span class="symbol">:production</span></div></pre></td></tr></table></figure>

<p>安裝 PostgreSQL</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">sudo</span> apt-get install libpq-dev</div></pre></td></tr></table></figure>

<hr>
<h1 id="延伸">延伸</h1>
<ul>
<li>IaaS / VPS / Self hosting: <a href="http://michaelhsu.tw/2013/06/26/nginx-passenger-rails-setup-on-ubuntu/" target="_blank" rel="external">Nginx + Passenger + Rails4 Setup on Ubuntu12.04</a>，有簡易的步驟教學。<ul>
<li>Web server / Application server 傻傻分不清楚 ？<a href="http://michaelhsu.tw/2013/07/04/server/" target="_blank" rel="external">HTTP Server 大小事</a></li>
</ul>
</li>
</ul>
<p>雲端運算概念：</p>
<ol>
<li>IaaS (Infrastructure as a Service）: AWS EC2</li>
<li>PaaS（Platform as a Service）: Heroku、GAE</li>
<li>SaaS（Software as a Service）: Gmail、google doc</li>
</ol>
<p>切換資料庫：<a href="http://michaelhsu.tw/2013/07/03/rails-on-postgresql/" target="_blank" rel="external">Rails on PostgreSQL</a></p>
<h1 id="學習資源">學習資源</h1>
<ul>
<li><a href="http://ihower.tw/rails3/index.html" target="_blank" rel="external">Ruby on Rails 實戰聖經</a> 必看！</li>
<li><a href="http://tryruby.org" target="_blank" rel="external">http://tryruby.org</a></li>
</ul>
<h1 id="Reference">Reference</h1>
<ul>
<li><a href="http://mrorz.github.io/webdev/#/" target="_blank" rel="external">HTML5, CSS/Sass, jQuery, Bootstrap<br>新一代網頁設計</a></li>
<li><a href="http://homepage.ntu.edu.tw/~b98705034/" target="_blank" rel="external">第一次寫網頁就上手</a></li>
<li><a href="https://www.digitalocean.com/community/articles/how-to-install-ruby-on-rails-on-ubuntu-12-04-lts-precise-pangolin-with-rvm" target="_blank" rel="external">How to Install Ruby on Rails on Ubuntu 12.04 LTS (Precise Pangolin) with RVM</a></li>
<li><a href="https://www.digitalocean.com/community/articles/how-to-install-git-on-ubuntu-12-04" target="_blank" rel="external">How to Install Git on Ubuntu 12.04</a></li>
<li><a href="http://stackoverflow.com/questions/3260345/list-of-rails-model-types" target="_blank" rel="external">attributes SQL types</a></li>
<li><a href="https://devcenter.heroku.com/articles/rails4-getting-started" target="_blank" rel="external">Getting Started with Rails 4.x on Heroku</a></li>
<li><a href="http://stackoverflow.com/questions/3116015/how-to-install-gem-pg-on-ubuntu" target="_blank" rel="external">How to install gem pg on Ubuntu</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/ruby/" term="ruby"/>
    <category scheme="http://michaelhsu.tw/tags/rails/" term="rails"/>
    <category scheme="http://michaelhsu.tw/tags/heroku/" term="Heroku"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Rails on PostgreSQL]]></title>
    <link href="http://michaelhsu.tw/2013/07/03/rails-on-postgresql/"/>
    <id>http://michaelhsu.tw/2013/07/03/rails-on-postgresql/</id>
    <published>2013-07-03T08:28:30.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p><img src="http://jangmt.com/wiki/images/b/b5/PostgreSQL-9.gif" alt="又是隻大象"><br>最近看到老師都在玩 PostgreSQl ，看看我之前都是用 MySQL 當做資料庫的，感覺應該也來跟進下，雖然不前太知道他有什麼優缺點，但是學長聽說 MySQL 之後會閉源了，沒有人維護的確是很大的問題，總之就先來玩玩看吧。</p>
<h2 id="Install_postgresql">Install postgresql</h2>
<ul>
<li>Mac: 請 100% 跟者 ”<a href="http://www.moncefbelyamani.com/how-to-install-postgresql-on-a-mac-with-homebrew-and-lunchy/" target="_blank" rel="external">How to Install PostgreSQL on a Mac With Homebrew and Lunchy</a>“ 動一動。</li>
</ul>
<a id="more"></a>

<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>brew update</div><div class="line"><span class="variable">$ </span>brew doctor</div><div class="line"><span class="variable">$ </span>brew install postgresql</div><div class="line"><span class="variable">$ </span>initdb /usr/local/var/postgres -<span class="constant">E</span> utf8</div><div class="line"><span class="variable">$ </span>gem install lunchy</div><div class="line"><span class="variable">$ </span>mkdir -p ~<span class="regexp">/Library/</span><span class="constant">LaunchAgents</span></div><div class="line"><span class="variable">$ </span>cp /usr/local/<span class="constant">Cellar</span>/postgresql/<span class="number">9.2</span>.<span class="number">1</span>/homebrew.mxcl.postgresql.plist ~<span class="regexp">/Library/</span><span class="constant">LaunchAgents</span>/</div></pre></td></tr></table></figure>

<ul>
<li>Ubuntu</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">sudo</span> apt-get install postgresql</div></pre></td></tr></table></figure>

<ul>
<li>check &amp; start</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>postgres -<span class="constant">V</span></div><div class="line"><span class="variable">$ </span>lunchy start postgres</div><div class="line"></div><div class="line"><span class="comment"># for ubuntu</span></div><div class="line"><span class="variable">$ </span>sudo /etc/init.d/postgresql start</div><div class="line"></div><div class="line"><span class="variable">$ </span>brew info postgres</div></pre></td></tr></table></figure>

<h2 id="Setup_postgresql">Setup postgresql</h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>lunchy start postgres</div><div class="line"><span class="variable">$ </span>lunchy stop postgres</div><div class="line"></div><div class="line"><span class="comment"># for ubuntu</span></div><div class="line"><span class="variable">$ </span>sudo /etc/init.d/postgresql start</div></pre></td></tr></table></figure>

<ul>
<li>add user</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>sudo su - postgres <span class="comment"># for ubuntu error</span></div><div class="line"></div><div class="line"><span class="variable">$ </span>createuser --createdb --pwprompt username</div><div class="line"><span class="variable">$ </span>dropuser root</div></pre></td></tr></table></figure>

<h2 id="Rails_on_PostgreSQL">Rails on PostgreSQL</h2>
<ul>
<li>Gemfile</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="title">gem</span> <span class="string">'pg'</span></div></pre></td></tr></table></figure>



<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>sudo aptitude install libpq-dev <span class="comment"># error for ubuntu</span></div><div class="line"></div><div class="line"><span class="variable">$ </span>bundel install</div></pre></td></tr></table></figure>

<ul>
<li>config/database.yml</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">development:</div><div class="line">  adapter: postgresql</div><div class="line">  encoding: utf8</div><div class="line">  database: ass_development</div><div class="line">  pool: <span class="number">5</span></div><div class="line">  username: root</div><div class="line">  password: <span class="number">1234</span></div><div class="line">  host: localhost</div><div class="line"></div><div class="line"><span class="keyword">...</span></div></pre></td></tr></table></figure>

<ul>
<li>Rake </li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ <span class="tag">rake</span> <span class="tag">db</span><span class="pseudo">:create</span><span class="pseudo">:all</span></div><div class="line">$ <span class="tag">rake</span> <span class="tag">db</span><span class="pseudo">:migration</span></div><div class="line">$ <span class="tag">rake</span> <span class="tag">db</span><span class="pseudo">:seed</span></div></pre></td></tr></table></figure>

<ul>
<li>for production</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ rake <span class="keyword">d</span><span class="variable">b:drop</span> RAILS_ENV=production</div><div class="line">$ rake <span class="keyword">d</span><span class="variable">b:create</span> RAILS_ENV=production</div><div class="line">$ rake <span class="keyword">d</span><span class="variable">b:migrate</span> RAILS_ENV=production</div><div class="line">$ rake <span class="keyword">d</span><span class="variable">b:seed</span> RAILS_ENV=production</div></pre></td></tr></table></figure>

<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://mikewilliamson.wordpress.com/2010/12/21/creating-rails-users-in-postgres-on-ubuntu/" target="_blank" rel="external">Creating Rails users in Postgres on Ubuntu</a></li>
<li><a href="http://robdodson.me/blog/2012/04/27/how-to-setup-postgresql-for-rails-and-heroku/" target="_blank" rel="external">How to Setup PostgreSQL for Rails and Heroku</a></li>
<li><a href="http://cat-son.blogspot.tw/2012/11/ubuntupostgresql.html#sthash.Dpjq9Kt8.MsdA7rZr.dpbs" target="_blank" rel="external">[宅] 在Ubuntu安裝PostgreSQL</a></li>
<li><a href="http://stackoverflow.com/questions/11919391/postgresql-error-fatal-role-username-does-not-exist" target="_blank" rel="external">PostgreSQL error: Fatal: role “username” does not exist</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/ruby/" term="ruby"/>
    <category scheme="http://michaelhsu.tw/tags/postgresql/" term="PostgreSQL"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Nginx + Passenger + Rails4 Setup on Ubuntu12.04]]></title>
    <link href="http://michaelhsu.tw/2013/06/26/nginx-passenger-rails-setup-on-ubuntu/"/>
    <id>http://michaelhsu.tw/2013/06/26/nginx-passenger-rails-setup-on-ubuntu/</id>
    <published>2013-06-26T09:48:41.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>因為最近要架一個系統，想說從來沒有自己 host server ，就把流程都記錄一下吧。</p>
<p><img src="http://www.maesr.com/wp-content/uploads/2012/05/nginx_passenger_eyecatcher.png" alt="據說比 Apache 快 數十倍的利器"></p>
<h2 id="目錄">目錄</h2>
<ul>
<li>一、環境設定 Linux + Rails</li>
<li>二、環境設定 Nginx (via passenger RubyGems)</li>
<li>三、環境設定 mysql（for Mac Hombrew）</li>
<li>四、部署設定 mina</li>
<li>五、資安處理</li>
</ul>
<a id="more"></a>

<h2 id="一、環境設定_Linux_+_Rails">一、環境設定 Linux + Rails</h2>
<ul>
<li>SSH 登入: </li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>ssh evenchange4<span class="variable">@hostip</span></div></pre></td></tr></table></figure>

<ul>
<li>os: Ubuntu 12.04.2 LTS (GNU/Linux 3.2.0-23-generic x86_64)</li>
<li><a href="https://rvm.io/" target="_blank" rel="external">rvm</a> install: </li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ \curl -L http<span class="variable">s:</span>//<span class="built_in">get</span>.rvm.io | bash -<span class="keyword">s</span> stable --rails # Or, --<span class="keyword">ruby</span>=<span class="number">1.9</span>.<span class="number">3</span></div></pre></td></tr></table></figure>

<ul>
<li>檢查環境</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">$ rails -<span class="keyword">v</span></div><div class="line">Rails <span class="number">4.0</span>.<span class="number">0</span></div><div class="line"></div><div class="line">$ <span class="keyword">ruby</span> -<span class="keyword">v</span></div><div class="line"><span class="keyword">ruby</span> <span class="number">2.0</span>.<span class="number">0</span>p195 (<span class="number">2013</span>-<span class="number">05</span>-<span class="number">14</span> revision <span class="number">40734</span>) [x86_64-linux]</div><div class="line"></div><div class="line">$ rvm <span class="keyword">list</span></div><div class="line">rvm rubies</div><div class="line">=* <span class="keyword">ruby</span>-<span class="number">2.0</span>.<span class="number">0</span>-p195 [ x86_64 ]</div></pre></td></tr></table></figure>

<ul>
<li>install <a href="https://www.digitalocean.com/community/articles/how-to-install-git-on-ubuntu-12-04" target="_blank" rel="external">git</a>:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">sudo</span> apt-get install git</div></pre></td></tr></table></figure>

<ul>
<li>rails server <a href="http://stackoverflow.com/questions/15515180/execjsruntimeunavailable-error-when-i-starts-rails-server" target="_blank" rel="external">ExecJS::RuntimeUnavailable error</a>:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ gem <span class="operator"><span class="keyword">install</span> therubyracer</span></div><div class="line">$ sudo apt-<span class="keyword">get</span> <span class="keyword">install</span> nodejs</div></pre></td></tr></table></figure>

<h2 id="二、環境設定_Nginx_(via_passenger_RubyGems)">二、環境設定 Nginx (via passenger RubyGems)</h2>
<blockquote>
<blockquote>
<p>Nginx (pronounced engine-x) is a free, open-source, high-performance HTTP server and reverse proxy.</p>
</blockquote>
</blockquote>
<p>-<img src="http://ihower.tw/rails3/images/deployment-proxy-diagram.jpg" alt="反向代理概念"></p>
<ul>
<li><p>其中 Web 伺服器可以是 Apache、Nginx，但是它除了提供靜態檔案之外，其餘的任務就只是做 reverse proxy 將 request 分發到應用程式伺服器。</p>
</li>
<li><p>安裝 nginx proxy server <a href="http://www.modrails.com/documentation/Users%20guide%20Nginx.html#_supported_operating_systems" target="_blank" rel="external">配置：2.2 (via passenger RubyGems)</a> </p>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>gem install passenger</div><div class="line"></div><div class="line"><span class="variable">$ </span>chmod o+x /home/evenchange4/.rvm/gems/ruby-<span class="number">2.0</span>.<span class="number">0</span>-p195/gems/passenger-<span class="number">4.0</span>.<span class="number">5</span>/</div><div class="line"><span class="variable">$ </span>chmod o+x /home/evenchange4/.rvm/gems/ruby-<span class="number">2.0</span>.<span class="number">0</span>-p195/gems</div><div class="line"><span class="variable">$ </span>chmod o+x /home/evenchange4/.rvm/gems/ruby-<span class="number">2.0</span>.<span class="number">0</span>-p195</div><div class="line"><span class="variable">$ </span>chmod o+x /home/evenchange4/.rvm/gems</div><div class="line"><span class="variable">$ </span>chmod o+x /home/evenchange4/.rvm</div><div class="line"><span class="variable">$ </span>chmod o+x /home/evenchange4</div><div class="line"></div><div class="line"><span class="variable">$ </span>sudo apt-get install libcurl4-openssl-dev</div><div class="line"><span class="variable">$ </span>rvmsudo passenger-install-nginx-<span class="class"><span class="keyword">module</span></span></div></pre></td></tr></table></figure>

<ul>
<li>設定 <a href="http://ruby-china.org/wiki/mac-nginx-passenger-rails" target="_blank" rel="external">Nginx</a>: <code>$ sudo vi /opt/nginx/conf/nginx.conf</code> ，Add a server block inside <code>http</code> block</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">...</span></div><div class="line">   server {</div><div class="line">      listen <span class="number">80</span>;</div><div class="line">      server_name <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span>;</div><div class="line">      root /home/evenchange4/test123/public;</div><div class="line">      passenger_enabled on;</div><div class="line">      rails_env development; <span class="comment"># 切換</span></div><div class="line">      <span class="comment">#rails_env production;</span></div><div class="line">   }</div><div class="line"><span class="keyword">...</span></div></pre></td></tr></table></figure>

<ul>
<li><p>上方 block 可以透過 <a href="http://www.modrails.com/documentation/Users%20guide%20Nginx.html" target="_blank" rel="external">rails_env</a> 來轉換環境。</p>
</li>
<li><p>Create an Init Script to Manage nginx: <a href="https://library.linode.com/web-servers/nginx/installation/ubuntu-12.04-precise-pangolin#sph_create-an-init-script-to-manage-nginx" target="_blank" rel="external">Init script for Ubuntu 12.04</a></p>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ wget -<span class="type">O</span> <span class="keyword">init</span>-deb.sh http:<span class="comment">//library.linode.com/assets/1139-init-deb.sh</span></div><div class="line">$ sudo mv <span class="keyword">init</span>-deb.sh /etc/<span class="keyword">init</span>.d/nginx</div><div class="line">$ chmod +x /etc/<span class="keyword">init</span>.d/nginx</div><div class="line">$ sudo /usr/sbin/update-rc.d -f nginx defaults</div></pre></td></tr></table></figure>

<ul>
<li>start/stop/restart nginx </li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ sudo /etc/init.d/nginx <span class="operator"><span class="keyword">start</span>/<span class="keyword">stop</span>/restart</span></div></pre></td></tr></table></figure>

<ul>
<li>nginx status</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>passenger-memory-stats</div></pre></td></tr></table></figure>

<h2 id="三、環境設定_mysql">三、環境設定 mysql</h2>
<ul>
<li>Install（Mac Hombrew）:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>brew install mysql</div></pre></td></tr></table></figure>

<ul>
<li>Install（Ubuntu）:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ sudo apt-get install mysql-<span class="keyword">server</span> mysql-<span class="keyword">common</span> mysql-<span class="keyword">client</span> libmysqlclient-dev</div></pre></td></tr></table></figure>

<ul>
<li>run mysql server</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># mac</span></div><div class="line"><span class="variable">$ </span>mysql.server start/stop</div><div class="line"></div><div class="line"><span class="comment"># ubuntu</span></div><div class="line"><span class="variable">$ </span>sudo service mysql start</div></pre></td></tr></table></figure>

<ul>
<li>login </li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$mysql</span> -u root -p</div></pre></td></tr></table></figure>

<ul>
<li>create database</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="input"><span class="prompt">mysql&gt;</span> <span class="constant">CREATE</span> <span class="constant">DATABASE</span> ass_development;</span></div><div class="line">mysql&gt; show databases;</div></pre></td></tr></table></figure>

<ul>
<li><p>檢查 mysql 是否支援中文 utf8</p>
<ol>
<li>更改 /etc/mysql/my.cnf <a href="http://blog.sina.com.cn/s/blog_4bc179a80100hmjc.html" target="_blank" rel="external">詳細教學</a></li>
<li><a href="http://stackoverflow.com/questions/16350310/mysql-mysql2error-incorrect-string-value" target="_blank" rel="external">砍掉 db</a></li>
</ol>
</li>
<li><p>匯入 (必須需要有database name)</p>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>mysql -uroot -pmcc2012 <span class="constant">NTUMB_development</span> &lt; code/<span class="number">2013</span>-<span class="number">04</span>-<span class="number">24_10_45</span>.<span class="constant">NTUMB_development</span></div></pre></td></tr></table></figure>

<ul>
<li><p>new <a href="https://github.com/RailsApps/rails3-bootstrap-devise-cancan" target="_blank" rel="external">RailsApps</a> project，選擇 <code>I want to build my own application</code> 來作設定。</p>
</li>
<li><p>production</p>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>rake <span class="symbol">db:</span>drop <span class="constant">RAILS_ENV</span>=production</div><div class="line"><span class="variable">$ </span>rake <span class="symbol">db:</span>create <span class="constant">RAILS_ENV</span>=production</div><div class="line"><span class="variable">$ </span>rake <span class="symbol">db:</span>migrate <span class="constant">RAILS_ENV</span>=production</div><div class="line"><span class="variable">$ </span>rake <span class="symbol">db:</span>seed <span class="constant">RAILS_ENV</span>=production</div><div class="line"><span class="variable">$ </span>sudo /etc/init.d/nginx restart</div></pre></td></tr></table></figure>

<h2 id="四、部署設定_mina">四、部署設定 <a href="http://nadarei.co/mina/" target="_blank" rel="external">mina</a></h2>
<ul>
<li>因為 <a href="https://github.com/capistrano/capistrano" target="_blank" rel="external">capistrano</a> 非常缺乏文檔資料，加上不太支援 Rails4 ，所以挑選 mina 來幫助部署。</li>
<li>透過 mina 的輔助，可以將 source code（須先 commit 到 github上） 透過 ssh 連線自動部署到 hosting server 上。並且可以直接寫 <code>rake</code> <a href="https://github.com/evenchange4/ass/blob/master/config/deploy.rb" target="_blank" rel="external">script</a> 的指令來隨心所欲的執行指令。</li>
<li><img src="http://nadarei.co/mina/images/logo.png?1344377458" alt="mina"></li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>mina init</div></pre></td></tr></table></figure>

<ul>
<li>如果 <a href="https://github.com/nadarei/mina/issues/99" target="_blank" rel="external">ssh 無反應</a>，<code>vi config/depoy.rb</code> 加入:</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># Password prompt in mina doesn't work</span></div><div class="line"><span class="type">set</span> :term_mode, <span class="keyword">nil</span></div></pre></td></tr></table></figure>



<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>mina setup</div></pre></td></tr></table></figure>

<ul>
<li>自行到 server 編輯 <code>database.yml</code></li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>git commit -a -m <span class="string">"deploy"</span></div><div class="line"><span class="variable">$ </span>git push</div><div class="line"><span class="variable">$ </span>mina deploy</div></pre></td></tr></table></figure>

<h2 id="五、資安處理">五、資安處理</h2>
<ul>
<li>安裝 <a href="https://www.digitalocean.com/community/articles/how-to-install-denyhosts-on-ubuntu-12-04" target="_blank" rel="external">denyhosts</a> 防止 ssh 帳號被連續 try，並且加入白名單</li>
<li><a href="https://github.com/thoughtbot/paperclip/wiki/Interpolations" target="_blank" rel="external">paperclip generate access_token and interpolate it</a></li>
</ul>
<h2 id="Reference">Reference</h2>
<ol>
<li><a href="http://askubuntu.com/questions/169551/why-cant-i-install-phusion-passenger-for-nginx" target="_blank" rel="external">rvmsudo passenger-install-nginx-module</a></li>
<li><a href="https://github.com/ludicast/yaml_db" target="_blank" rel="external">YamlDb</a></li>
</ol>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/ruby/" term="ruby"/>
    <category scheme="http://michaelhsu.tw/tags/nginx/" term="nginx"/>
    <category scheme="http://michaelhsu.tw/tags/passenger/" term="passenger"/>
    <category scheme="http://michaelhsu.tw/tags/rails/" term="rails"/>
    <category scheme="http://michaelhsu.tw/tags/linux/" term="linux"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[捷運站經緯度坐標 Open data]]></title>
    <link href="http://michaelhsu.tw/2013/06/25/捷運站經緯度坐標-open-data/"/>
    <id>http://michaelhsu.tw/2013/06/25/捷運站經緯度坐標-open-data/</id>
    <published>2013-06-25T03:50:13.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<h2 id="資料說明">資料說明</h2>
<ul>
<li>2013 夏，取得的站數為 <code>96</code> 站。</li>
<li>download rawdata on github: <a href="https://raw.github.com/evenchange4/mrt_opendata/master/mrt.json" target="_blank" rel="external">mrt.json</a> </li>
<li>source code: <a href="https://github.com/evenchange4/mrt_opendata" target="_blank" rel="external">github.com/evenchange4/mrt_opendata</a></li>
</ul>
<a id="more"></a>

<h2 id="步驟做法">步驟做法</h2>
<ol>
<li>爬取捷運站的<a href="http://web.trtc.com.tw/c/stationdetail2010.asp?ID=19" target="_blank" rel="external">官方網站</a>來取得每一個捷運站的地址。<ul>
<li>各站的 ID 可以從 <a href="http://www.trtc.com.tw/ct.asp?CtNode=24569&amp;mp=122031&amp;xItem=1015926" target="_blank" rel="external">www.trtc.com.tw</a> html <code>option</code>‘s attribute <code>value</code> 取得。</li>
</ul>
</li>
<li>再使用 ruby gem <code>&quot;geocoder&quot;</code> 將地址來取得經緯度。<ul>
<li>example: “10576臺北市松山區敦化北路338號” -&gt; “25.063718, 121.549643”</li>
<li><img src="http://media-cache-ec3.pinimg.com/originals/e3/04/37/e30437b99265e324397a1477f7afce8b.jpg" alt="geocoder demo"></li>
</ul>
</li>
</ol>
<h2 id="捷運站坐標:_mrt-json">捷運站坐標: <code>mrt.json</code></h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line">[</div><div class="line">  {</div><div class="line">    "<span class="attribute">id</span>": <span class="value"><span class="number">1</span></span>,</div><div class="line">    "<span class="attribute">name</span>": <span class="value"><span class="string">"松山機場"</span></span>,</div><div class="line">    "<span class="attribute">number</span>": <span class="value"><span class="string">"7"</span></span>,</div><div class="line">    "<span class="attribute">address</span>": <span class="value"><span class="string">"10576臺北市松山區敦化北路338號"</span></span>,</div><div class="line">    "<span class="attribute">latitude</span>": <span class="value"><span class="number">25.063718</span></span>,</div><div class="line">    "<span class="attribute">longitude</span>": <span class="value"><span class="number">121.549643</span></span></div><div class="line">  },</div><div class="line">  {</div><div class="line">    "<span class="attribute">id</span>": <span class="value"><span class="number">2</span></span>,</div><div class="line">    "<span class="attribute">name</span>": <span class="value"><span class="string">"中山國中"</span></span>,</div><div class="line">    "<span class="attribute">number</span>": <span class="value"><span class="string">"8"</span></span>,</div><div class="line">    "<span class="attribute">address</span>": <span class="value"><span class="string">"10476臺北市中山區復興北路376號"</span></span>,</div><div class="line">    "<span class="attribute">latitude</span>": <span class="value"><span class="number">25.0607843</span></span>,</div><div class="line">    "<span class="attribute">longitude</span>": <span class="value"><span class="number">121.5439248</span></span></div><div class="line">  },</div><div class="line">  ...</div></pre></td></tr></table></figure>

<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://www.trtc.com.tw/ct.asp?CtNode=24569&amp;mp=122031&amp;xItem=1015926" target="_blank" rel="external">www.trtc.com.tw</a></li>
<li>ruby gem <a href="http://www.rubygeocoder.com/" target="_blank" rel="external">geocoder</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/ruby/" term="ruby"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[RHadoop 實作推薦系統]]></title>
    <link href="http://michaelhsu.tw/2013/06/21/rhadoop-實作推薦系統/"/>
    <id>http://michaelhsu.tw/2013/06/21/rhadoop-實作推薦系統/</id>
    <published>2013-06-21T04:37:11.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<h2 id="簡介">簡介</h2>
<ul>
<li>課程： <a href="https://sites.google.com/site/cloudcomputingspecialproject/101-2-progress-report" target="_blank" rel="external">101-2 NTU cloud computing special project</a></li>
<li>Proposal title: <a href="https://docs.google.com/viewer?a=v&amp;pid=sites&amp;srcid=ZGVmYXVsdGRvbWFpbnxjbG91ZGNvbXB1dGluZ3NwZWNpYWxwcm9qZWN0fGd4OjQxMzkxMWI2YmI2NTI4NjM" target="_blank" rel="external">Large-scale big data mining in cloud system</a> </li>
<li><a href="https://docs.google.com/document/d/1RHhWToolQXbNJhZx61RizXGwNfkccZS6ZmqvoLiGe4I/edit#" target="_blank" rel="external">Progress Report</a></li>
<li>source code: <a href="https://github.com/evenchange4/CCSP" target="_blank" rel="external">github.com/evenchange4/CCSP</a></li>
<li>datasets: <a href="https://drive.google.com/folderview?id=0B41WBNgHd5hjTE5KcmN0b0F5SjA&amp;usp=sharing" target="_blank" rel="external">movielen_dataset.csv (123Mb, preprocessed) </a></li>
<li>使用整合 R 與 Hadoop 的 package RHadoop (rmr2) 來實作 item-base 的推薦系統。</li>
<li><img src="http://oytunyuksel.com/wp-content/uploads/post-02-01.jpg" alt="讓小丸子來教你 from oytunyuksel"></li>
</ul>
<a id="more"></a>

<h2 id="工具">工具</h2>
<ul>
<li>RHadoop rmr2</li>
<li>演算法: Collaborative Filtering 協同過濾 (item-based)</li>
<li>安裝 Haddop 參考: <a href="http://michaelhsu.tw/2013/04/21/hadoop-%E7%AC%AC%E4%B8%80%E6%AC%A1%E5%AE%89%E8%A3%9D%E5%B0%B1%E4%B8%8A%E6%89%8B-cdh3/" target="_blank" rel="external">Hadoop 第一次安裝就上手 CDH3</a></li>
<li>使用 Rhadoop 參考: <a href="http://michaelhsu.tw/2013/05/01/r-and-hadoop-%E5%88%9D%E9%AB%94%E9%A9%97/" target="_blank" rel="external">R and Hadoop 整合初體驗</a></li>
</ul>
<h2 id="演算法與實作">演算法與實作</h2>
<ul>
<li>本演算法參考 <a href="http://blog.fens.me/rhadoop-mapreduce-rmr/" target="_blank" rel="external">粉丝日志 RHadoop实践系列</a> 來實作，特別感謝有這種中文的教學文章。</li>
<li>推薦結果 = 伴隨矩陣 (co-occurrence matrix) * 評分矩陣（score matrix）</li>
<li><img src="http://cos.name/wp-content/uploads/2013/04/alogrithm_1.jpg" alt="演算法概念 from Mahout In Action"></li>
<li>map-reduce 實作步驟：<ol>
<li>建立 item’s co-occurrence matrix，然後算出 frequence</li>
</ol>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">train.mr&lt;-mapreduce(</div><div class="line">	train.hdfs, </div><div class="line">	map = function(k, v) {</div><div class="line">		keyval(k,v$item)</div><div class="line">	},</div><div class="line">	reduce = function(k,v){</div><div class="line">		m&lt;-merge(v,v)</div><div class="line">		keyval(m$x,m$y)</div><div class="line">	}</div><div class="line">)</div><div class="line">step2.mr&lt;-mapreduce(</div><div class="line">	train.mr,</div><div class="line">	map = function(k, v) {</div><div class="line">		d&lt;-data.frame(k,v)</div><div class="line">		d2&lt;-ddply(d,.(k,v),count)</div><div class="line"></div><div class="line">		key&lt;-d2$k</div><div class="line">		val&lt;-d2</div><div class="line">		keyval(key,val)</div><div class="line">	}</div><div class="line">)</div></pre></td></tr></table></figure>

<pre><code><span class="number">2</span>. 建立 <span class="literal">user</span>'s 評分矩陣
</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">train2.mr&lt;-mapreduce(</div><div class="line">	train.hdfs, </div><div class="line">	map = <span class="function"><span class="keyword">function</span><span class="params">(k, v)</span> </span>{</div><div class="line">		<span class="comment">#df&lt;-v[which(v$user==3),]</span></div><div class="line">		df&lt;-v</div><div class="line">		key&lt;-df<span class="variable">$item</span></div><div class="line">		val&lt;-data.frame(item=df<span class="variable">$item</span>,user=df<span class="variable">$user</span>,pref=df<span class="variable">$pref</span>)</div><div class="line">		keyval(key,val)</div><div class="line">	}</div><div class="line">)</div></pre></td></tr></table></figure>

<pre><code><span class="number">3.</span> equijoin co-occurrence <span class="built_in">matrix</span> <span class="built_in">and</span> score <span class="built_in">matrix</span>
</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">eq.hdfs&lt;-equijoin(</div><div class="line">	<span class="keyword">left</span>.<span class="built_in">input</span>=step2.mr, </div><div class="line">	<span class="keyword">right</span>.<span class="built_in">input</span>=train2.mr,</div><div class="line"></div><div class="line">	<span class="built_in">map</span>.<span class="keyword">left</span>=<span class="function"><span class="keyword">function</span><span class="params">(k,v)</span>{</span></div><div class="line">		keyval(<span class="keyword">k</span>,<span class="keyword">v</span>)</div><div class="line">	},</div><div class="line">	<span class="built_in">map</span>.<span class="keyword">right</span>=<span class="function"><span class="keyword">function</span><span class="params">(k,v)</span>{</span></div><div class="line">		keyval(<span class="keyword">k</span>,<span class="keyword">v</span>)</div><div class="line">	},</div><div class="line">	outer = <span class="keyword">c</span>(<span class="string">"left"</span>)</div><div class="line">)</div></pre></td></tr></table></figure>

<pre><code><span class="bullet">4. </span>計算推薦的結果
</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">cal.mr&lt;-mapreduce(</div><div class="line">	input=eq.hdfs,</div><div class="line">	map=<span class="function"><span class="keyword">function</span><span class="params">(k,v)</span></span>{</div><div class="line">		val&lt;-v</div><div class="line">		na&lt;-is.na(v<span class="variable">$user</span>.r)</div><div class="line">		<span class="keyword">if</span>(length(which(na))&gt;<span class="number">0</span>) val&lt;-v[-which(is.na(v<span class="variable">$user</span>.r)),]</div><div class="line">		keyval(val<span class="variable">$k</span>.l,val)</div><div class="line">	},</div><div class="line">	reduce=<span class="function"><span class="keyword">function</span><span class="params">(k,v)</span></span>{</div><div class="line">		val&lt;-ddply(v,.(k.l,v.l,user.r),summarize,v=freq.l*pref.r)</div><div class="line">		keyval(val<span class="variable">$k</span>.l,val)</div><div class="line">	}</div><div class="line">)</div></pre></td></tr></table></figure>

<pre><code><span class="number">5</span>. output <span class="keyword">list</span> <span class="built_in">and</span> score
</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="literal">result</span>.mr&lt;-mapreduce(</div><div class="line">	input=cal.mr,</div><div class="line">	map=function(k,v){</div><div class="line">		keyval(v$user.r,v)</div><div class="line">	},</div><div class="line">	reduce=function(k,v){</div><div class="line">		val&lt;-ddply(v,.(user.r,v.l),summarize,v=sum(v))</div><div class="line">		val2&lt;-val[order(val$v,decreasing=<span class="type">TRUE</span>),]</div><div class="line">		names(val2)&lt;-c(<span class="string">"user"</span>,<span class="string">"item"</span>,<span class="string">"pref"</span>)</div><div class="line">		keyval(val2$user,val2)</div><div class="line">	}</div><div class="line">)</div></pre></td></tr></table></figure>

<pre><code><span class="number">6</span>. <span class="literal">result</span>
</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">from</span>.dfs(<span class="literal">result</span>.mr)</div></pre></td></tr></table></figure>

<h2 id="Data_preprocess">Data preprocess</h2>
<ul>
<li>input: csv file (user,item,rating ex: <code>1,101,5.0</code>)</li>
<li>實際資料：<a href="http://www.grouplens.org/node/12" target="_blank" rel="external">MovieLens Data Sets</a><ul>
<li>GroupLens Research has collected and made available rating data sets from the MovieLens web site (<a href="http://movielens.umn.edu" target="_blank" rel="external">http://movielens.umn.edu</a>). The data sets were collected over various periods of time, depending on the size of the set.</li>
<li><a href="http://www.grouplens.org/sites/www.grouplens.org/external_files/data/ml-10m.zip" target="_blank" rel="external">origin data sets MovieLens 10M</a> - Consists of 10 million ratings and 100,000 tag applications applied to 10,000 movies by 72,000 users.</li>
<li>MovieID index file</li>
</ul>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="number">1</span><span class="symbol">:</span><span class="symbol">:Toy</span> <span class="constant">Story </span>(<span class="number">1995</span>)<span class="symbol">:</span><span class="symbol">:Adventure|Animation|Children|Comedy|Fantasy</span></div><div class="line"><span class="number">2</span><span class="symbol">:</span><span class="symbol">:Jumanji</span> (<span class="number">1995</span>)<span class="symbol">:</span><span class="symbol">:Adventure|Children|Fantasy</span></div><div class="line"><span class="number">3</span><span class="symbol">:</span><span class="symbol">:Grumpier</span> <span class="constant">Old Men </span>(<span class="number">1995</span>)<span class="symbol">:</span><span class="symbol">:Comedy|Romance</span></div><div class="line"><span class="number">4</span><span class="symbol">:</span><span class="symbol">:Waiting</span> to <span class="constant">Exhale </span>(<span class="number">1995</span>)<span class="symbol">:</span><span class="symbol">:Comedy|Drama|Romance</span></div><div class="line">...</div></pre></td></tr></table></figure>

<ul>
<li>format convert: <ul>
<li>原始格式：<code>UserID::MovieID::Rating::Timestamp</code></li>
</ul>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">1<span class="pseudo">::122</span><span class="pseudo">::5</span><span class="pseudo">::838985046</span></div><div class="line">1<span class="pseudo">::185</span><span class="pseudo">::5</span><span class="pseudo">::838983525</span></div><div class="line">1<span class="pseudo">::231</span><span class="pseudo">::5</span><span class="pseudo">::838983392</span></div><div class="line">1<span class="pseudo">::292</span><span class="pseudo">::5</span><span class="pseudo">::838983421</span></div><div class="line">...</div></pre></td></tr></table></figure>

<pre><code><span class="bullet">- </span>轉換格式：<span class="code">`UserID,MovieID,Rating`</span> save as <span class="code">`movielen_dataset.csv`</span>
</code></pre><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">f = File.<span class="built_in">open</span>(<span class="string">"movielen_dataset.csv"</span>, <span class="string">"w"</span>)</div><div class="line">File.<span class="built_in">open</span>(<span class="string">"ratings.dat"</span>).<span class="keyword">each</span> <span class="built_in">do</span> |l|</div><div class="line">	temp = l.<span class="built_in">split</span>(<span class="string">"::"</span>)</div><div class="line">	userID  = temp[<span class="number">0</span>]</div><div class="line">	movieID = temp[<span class="number">1</span>]</div><div class="line">	rating  = temp[<span class="number">2</span>]</div><div class="line">	f &lt;&lt; <span class="string">"#{userID},#{movieID},#{rating}\n"</span></div><div class="line"><span class="function"><span class="keyword">end</span></span></div><div class="line">f.<span class="built_in">close</span></div></pre></td></tr></table></figure>



<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="number">1</span>,<span class="number">122</span>,<span class="number">5</span></div><div class="line"><span class="number">1</span>,<span class="number">185</span>,<span class="number">5</span></div><div class="line"><span class="number">1</span>,<span class="number">231</span>,<span class="number">5</span></div><div class="line"><span class="number">1</span>,<span class="number">292</span>,<span class="number">5</span></div><div class="line"><span class="keyword">...</span></div></pre></td></tr></table></figure>

<h2 id="Result">Result</h2>
<p>…待補，vm localhost hdfs 跑好久</p>
<p><code>failed Reduce Tasks exceeded allowed limit</code></p>
<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://blog.fens.me/rhadoop-mapreduce-rmr/" target="_blank" rel="external">粉丝日志 RHadoop实践系列</a></li>
<li><a href="http://manning.com/owen/" target="_blank" rel="external">Mahout In Action</a></li>
<li><a href="http://michaelhsu.tw/2013/04/21/hadoop-%E7%AC%AC%E4%B8%80%E6%AC%A1%E5%AE%89%E8%A3%9D%E5%B0%B1%E4%B8%8A%E6%89%8B-cdh3/" target="_blank" rel="external">Hadoop 第一次安裝就上手 CDH3</a></li>
<li><a href="http://michaelhsu.tw/2013/05/01/r-and-hadoop-%E5%88%9D%E9%AB%94%E9%A9%97/" target="_blank" rel="external">R and Hadoop 整合初體驗</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/r/" term="R"/>
    <category scheme="http://michaelhsu.tw/tags/hadoop/" term="hadoop"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Open Source list]]></title>
    <link href="http://michaelhsu.tw/2013/05/14/open-source-list/"/>
    <id>http://michaelhsu.tw/2013/05/14/open-source-list/</id>
    <published>2013-05-14T06:16:12.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>簡單記錄一下</p>
<a id="more"></a>

<h2 id="CSS_framework">CSS framework</h2>
<ul>
<li><a href="http://www.kule.tw/" target="_blank" rel="external">Kule CSS Lazy 2</a></li>
<li><a href="http://foundation.zurb.com/" target="_blank" rel="external">Foundation 4</a></li>
<li><a href="http://gumbyframework.com/" target="_blank" rel="external">Gumby 2</a></li>
<li><a href="http://twitter.github.io/bootstrap/" target="_blank" rel="external">Bootstrap</a></li>
<li><a href="http://aozora.github.io/bootmetro/" target="_blank" rel="external">BootMetro</a></li>
<li><a href="http://jquerymobile.com/" target="_blank" rel="external">jQuery mobile</a></li>
<li><a href="http://masonry.desandro.com/" target="_blank" rel="external">jQuery Masonry</a></li>
<li><a href="http://designmodo.github.io/Flat-UI/" target="_blank" rel="external">Flat UI</a></li>
<li><a href="http://maker.github.io/ratchet/" target="_blank" rel="external">Ratchet</a>: Prototype iPhone apps with simple HTML, CSS, and JS components</li>
</ul>
<h2 id="CSS">CSS</h2>
<ul>
<li>icon <a href="http://fortawesome.github.io/Font-Awesome/" target="_blank" rel="external">Font Awesome</a> </li>
<li>配色 <a href="http://kuler.adobe.com/" target="_blank" rel="external">Kuler</a> </li>
<li>背景 <a href="http://subtlepatterns.com/" target="_blank" rel="external">Subtle patterns</a></li>
</ul>
<h2 id="Javascript">Javascript</h2>
<ul>
<li>RequireJS <ul>
<li>管理Script tag </li>
<li>TonyQ <a href="http://ithelp.ithome.com.tw/question/10120521" target="_blank" rel="external">實用 JavaScript 工具庫：RequireJS</a> </li>
</ul>
</li>
<li><a href="http://tympanus.net/Development/Arctext/" target="_blank" rel="external">Arctext.JS</a><ul>
<li>彎曲文字</li>
</ul>
</li>
</ul>
<h2 id="Ruby_gem">Ruby gem</h2>
<ul>
<li><a href="https://github.com/pluskid/rmmseg-cpp" target="_blank" rel="external">rmmseg-cpp</a><ul>
<li>an re-implementation of rmmseg (Chinese word segmentation library for Ruby) in C++</li>
<li>demo: <a href="https://sentiminer.herokuapp.com/" target="_blank" rel="external">sentiminer</a></li>
</ul>
</li>
<li><a href="https://github.com/tcocca/acts_as_follower" target="_blank" rel="external">acts_as_follower</a><ul>
<li>Follow functionality</li>
<li>demo: <a href="https://sentiminer.herokuapp.com/" target="_blank" rel="external">sentiminer</a></li>
</ul>
</li>
<li><a href="https://github.com/helios-framework/helios/" target="_blank" rel="external">helios</a><ul>
<li>An extensible open-source mobile backend framework</li>
<li><a href="http://helios.io/" target="_blank" rel="external">http://helios.io/</a></li>
</ul>
</li>
<li><a href="https://github.com/mkdynamic/omniauth-facebook" target="_blank" rel="external">omniauth-facebook</a><ul>
<li>Facebook OAuth2 Strategy for OmniAuth 1.0</li>
<li>demo: <a href="http://emo-song.herokuapp.com/" target="_blank" rel="external">emo-song</a></li>
</ul>
</li>
<li><a href="https://github.com/arsduo/koala" target="_blank" rel="external">koala</a><ul>
<li>A lightweight, flexible library for Facebook with support for OAuth authentication, the Graph and REST APIs, realtime updates, and test users.</li>
<li>demo: <a href="http://emo-song.herokuapp.com/" target="_blank" rel="external">emo-song</a></li>
</ul>
</li>
</ul>
<h2 id="ios">ios</h2>
<ul>
<li><a href="http://iosdevelopersnote.blogspot.tw/2012/09/ios-html-socketio.html" target="_blank" rel="external">聊天廣播 - iOS 與 HTML 利用 Socket.io</a><ul>
<li><a href="https://github.com/Scentsome/Developer-s-Note/tree/master/chatRoom" target="_blank" rel="external">Developer-s-Note</a></li>
</ul>
</li>
</ul>
<h2 id="R">R</h2>
<ul>
<li><a href="http://tryr.codeschool.com/" target="_blank" rel="external">try R</a></li>
<li><a href="http://statlab.nchc.org.tw/rnotes/?page_id=2" target="_blank" rel="external">R 學習筆記</a></li>
</ul>
<h2 id="node-js">node.js</h2>
<ul>
<li><a href="http://timdream.org/wordfreq/" target="_blank" rel="external">wordfreq</a></li>
</ul>
<h2 id="Blog">Blog</h2>
<ul>
<li><a href="http://cofounderinc.com/" target="_blank" rel="external">http://cofounderinc.com/</a></li>
<li><a href="http://kytu800.github.io/" target="_blank" rel="external">http://kytu800.github.io/</a></li>
<li><a href="http://lucienlee.github.io/" target="_blank" rel="external">http://lucienlee.github.io/</a></li>
<li><a href="http://rosaniline.github.io/" target="_blank" rel="external">http://rosaniline.github.io/</a></li>
<li><a href="http://cytms.github.io/" target="_blank" rel="external">http://cytms.github.io/</a></li>
<li><a href="http://lovemew67.github.io/" target="_blank" rel="external">http://lovemew67.github.io/</a></li>
<li><a href="http://eva0919.github.io/" target="_blank" rel="external">http://eva0919.github.io/</a></li>
<li><a href="http://michaelhsu.tw/" target="_blank" rel="external">http://michaelhsu.tw/</a></li>
<li><a href="http://code.kpman.cc/" target="_blank" rel="external">http://code.kpman.cc/</a></li>
<li><a href="http://andikan.github.io/" target="_blank" rel="external">http://andikan.github.io/</a></li>
<li><a href="http://kytu.cc/blog" target="_blank" rel="external">http://kytu.cc/blog</a></li>
<li><a href="http://abc123634.github.io/" target="_blank" rel="external">http://abc123634.github.io/</a></li>
<li><a href="http://mnicnc404.github.io" target="_blank" rel="external">http://mnicnc404.github.io</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/ruby/" term="ruby"/>
    <category scheme="http://michaelhsu.tw/tags/js/" term="js"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Host self RSS reader - Stringer]]></title>
    <link href="http://michaelhsu.tw/2013/05/10/2013-05-10-private-rss-reader-stringer/"/>
    <id>http://michaelhsu.tw/2013/05/10/2013-05-10-private-rss-reader-stringer/</id>
    <published>2013-05-09T21:01:05.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>剛剛在 <a href="http://rubyweekly.com/" target="_blank" rel="external">ruby weekly</a> 看到這個玩具，看標題就感覺十分的有趣馬上來玩玩看！</p>
<blockquote>
<h1 id="Stringer_-">Stringer -</h1>
<p>A [work-in-progress] self-hosted, anti-social RSS reader. </p>
</blockquote>
<p>是一個私人的 RSS reader 然後可以 host 在 heroku 上！蠻好奇他是怎麼設計的。</p>
<a id="more"></a>

<h2 id="下載安裝使用">下載安裝使用</h2>
<ul>
<li><p>stringer 在 <a href="https://github.com/swanson/stringer" target="_blank" rel="external">https://github.com/swanson/stringer</a> 有完整的步驟。</p>
</li>
<li><p>demo: <a href="http://mreader.herokuapp.com/" target="_blank" rel="external">http://mreader.herokuapp.com/</a></p>
</li>
</ul>
<p>呃，都說是私人的了，就沒辦法 demo 給你看囉 XD，不過可以看看截圖或是自己實際玩玩看：</p>
<p><img src="https://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-ash4/262472_606814032665116_1927512106_n.jpg" alt="stringer demo"></p>
<h2 id="學習的地方">學習的地方</h2>
<ul>
<li>RSS(xml) parser：<a href="https://github.com/pauldix/feedzirra" target="_blank" rel="external">Feedzirra</a>。<br>後來發現原來我有玩過，勉為其難看一下以前的 <a href="http://evenchange4.tumblr.com/post/32658941295/code-google-news" target="_blank" rel="external">blog</a> 吧。<del>懶得轉了</del></li>
<li>UI：Twitter Bootstrap and Flat UI.</li>
<li><a href="https://addons.heroku.com/scheduler" target="_blank" rel="external">heroku addons:add scheduler</a>：因為 RSS 需要不停地去更新，但是等到使用者要看才再去 refresh 就慢了，所以 heroku 上有一個可以定期的執行 cmd 指令的套件可以使用，每隔一段時間就去執行一次。<blockquote>
<h2 id="Scheduler:_clock_Run_Jobs_with_Ease">Scheduler: clock Run Jobs with Ease</h2>
<p>Scheduler is an add-on for running jobs on your app at scheduled time intervals, much like cron in a traditional server environment.</p>
</blockquote>
</li>
</ul>
<p><img src="http://i.imgur.com/LMIMnil.png" alt="heroku addons:add scheduler"></p>
<p>然後到 heroku 上的 <a href="https://heroku-scheduler.herokuapp.com/dashboard" target="_blank" rel="external">scheduler dashboard</a> 作設定：</p>
<p><img src="http://i.imgur.com/gPQ4j8d.png" alt="Heroku Scheduler"></p>
<ul>
<li>Rake：<a href="http://rake.rubyforge.org/" target="_blank" rel="external">Ruby make</a>：如此可以直接使用 cmd 指令來執行。<ul>
<li>Rakefile：發佈和打包的 rake tasks</li>
</ul>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">desc <span class="string">"Fetch all feeds."</span></div><div class="line">task :fetch_feeds <span class="built_in">do</span></div><div class="line">   FetchFeeds.<span class="built_in">new</span>(Feed.all).fetch_all</div><div class="line"><span class="function"><span class="keyword">end</span></span></div></pre></td></tr></table></figure>

<pre><code><span class="bullet">- 
</span>![<span class="link_label">rack</span>](<span class="link_url">http://farm3.staticflickr.com/2793/4373500414_017aabf744_o.png</span>)
</code></pre><ul>
<li><p>use subDomain CNANE：如此一來真的可以變成自己的 RSS reader 阿！（教學一樣在作者的 github 步驟上） </p>
</li>
<li><p>幽默：他在 github 上面有句話，<del>看來有人臉很腫啊</del>。</p>
<blockquote>
<p>When <code>BIG_FREE_READER</code> shuts down, your instance of Stringer will still be kicking. </p>
</blockquote>
</li>
</ul>
<h2 id="Reference">Reference</h2>
<ul>
<li>github <a href="https://github.com/swanson/stringer" target="_blank" rel="external">https://github.com/swanson/stringer</a></li>
<li>[Ruby][教學] 如何打包一個 Gem <a href="http://blog.xdite.net/posts/2012/01/04/how-to-pack-a-gem/" target="_blank" rel="external">Blog</a></li>
<li><a href="http://railscasts-china.com/episodes/the-rails-initialization-process-by-kenshin54" target="_blank" rel="external">通过分析Rack和Rails的源代码, 讲解Rails的启动流程。</a></li>
<li><a href="http://wp.xdite.net/?p=1557" target="_blank" rel="external">Rack 與 Rack middleware</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/ruby/" term="ruby"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[oh-my-zsh 設定]]></title>
    <link href="http://michaelhsu.tw/2013/05/07/喔-我的-zsh-/"/>
    <id>http://michaelhsu.tw/2013/05/07/喔-我的-zsh-/</id>
    <published>2013-05-07T09:11:46.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<p>前陣子介紹了 <a href="http://michaelhsu.tw/2013/04/21/colorful-terminal/" target="_blank" rel="external">漂漂終端機懶人包</a>，把終端機變得美美的方法，但是其實有一個更強大的 framework 叫做 oh-my-zsh，它是一個大家可以一起編輯的 zsh framework，擁有 120+ plugins、120+ themes，所以可以跟大家分享自己的主題，或是拿別人的來用。除了主題之外，他的 plugin 強大的功能也是令大眾喜愛的原因，譬如你想要 <code>簡寫</code> 或 <del>偷懶</del> 的做某件事，如果不想要要靠 batch 檔來執行，可以用 oh-my-zsh 的 custom plugin，然後可以分享給其他人。</p>
<blockquote>
<p>你應該開始使用 “OH MY ZSHELL!”</p>
</blockquote>
<p><img src="https://github-camo.global.ssl.fastly.net/5c385f15f3eaedb72cfcfbbaf75355b700ac0757/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6f686d797a73682f6f682d6d792d7a73682d6c6f676f2e706e67" alt="▲ oh-my-zsh"></p>
<p><a id="more"></a></p>
<h2 id="Shell?_bash_v-s-_zsh">Shell? bash v.s. zsh</h2>
<p>至於兩個 Shell 差別在哪？來看看官方 <a href="http://zsh.sourceforge.net/FAQ/zshfaq02.html#l14" target="_blank" rel="external">FAQ</a> 說法：</p>
<p>2.5: Similarities with bash</p>
<p>The Bourne-Again Shell, <code>bash</code>, is another enhanced Bourne-like shell; the most obvious difference from <code>zsh</code> is that it does not attempt to emulate the Korn shell. Since both shells are under active development it is probably not sensible to be too specific here. Broadly, <code>bash</code> has paid more attention to standards compliancy (i.e. POSIX) for longer, and has so far avoided the more abstruse interactive features (programmable completion, etc.) that <code>zsh</code> has.</p>
<p>但我覺得差別最大的應該是 <code>tab</code> 鍵的應用。</p>
<h2 id="Configuration_Environment">Configuration Environment</h2>
<ol>
<li>Unix-like system: OSX</li>
<li>Linux: Ubuntu</li>
</ol>
<h2 id="Install_oh-my-zsh">Install oh-my-zsh</h2>
<h3 id="Step_1:_github_下載_oh-my-zsh">Step 1: github 下載 <a href="https://github.com/robbyrussell/oh-my-zsh" target="_blank" rel="external">oh-my-zsh</a></h3>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">curl -L http<span class="variable">s:</span>//github.<span class="keyword">com</span>/robbyrussell/oh-my-zsh/raw/master/tools/install.<span class="keyword">sh</span> | <span class="keyword">sh</span></div></pre></td></tr></table></figure>

<h3 id="Step_2:_設定_PATH，railscasts_Oh_My_ZSH">Step 2: 設定 PATH，<a href="http://railscasts.com/episodes/308-oh-my-zsh?view=comments" target="_blank" rel="external">railscasts Oh My ZSH</a></h3>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">cat</span> ~/.bash_profile &gt;&gt; ~/.zshrc</div></pre></td></tr></table></figure>

<h3 id="Step_3:_設定_zsh_vi_~/-zshrc，下面是我目前的設定檔範例">Step 3: 設定 zsh <code>vi ~/.zshrc</code>，下面是我目前的設定檔範例</h3>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div></pre></td><td class="code"><pre><div class="line"><span class="preprocessor"># Path to your oh-my-zsh configuration.</span></div><div class="line">ZSH=$HOME/.oh-my-zsh</div><div class="line"></div><div class="line"><span class="preprocessor"># Set name of the theme to load.</span></div><div class="line"><span class="preprocessor"># Look in ~/.oh-my-zsh/themes/</span></div><div class="line"><span class="preprocessor"># Optionally, if you set this to "random", it'll load a random theme each</span></div><div class="line"><span class="preprocessor"># time that oh-my-zsh is loaded.</span></div><div class="line">ZSH_THEME=<span class="string">"kennethreitz"</span></div><div class="line"><span class="preprocessor">#ZSH_THEME="eastwood"</span></div><div class="line"><span class="preprocessor"># Example aliases</span></div><div class="line"><span class="preprocessor"># alias zshconfig="mate ~/.zshrc"</span></div><div class="line"><span class="preprocessor"># alias ohmyzsh="mate ~/.oh-my-zsh"</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Set to this to use case-sensitive completion</span></div><div class="line"><span class="preprocessor"># CASE_SENSITIVE="true"</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Comment this out to disable bi-weekly auto-update checks</span></div><div class="line"><span class="preprocessor"># DISABLE_AUTO_UPDATE="true"</span></div><div class="line">DISABLE_UPDATE_PROMPT=<span class="string">"true"</span></div><div class="line"><span class="preprocessor"># Uncomment to change how often before auto-updates occur? (in days)</span></div><div class="line"><span class="preprocessor"># export UPDATE_ZSH_DAYS=13</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Uncomment following line if you want to disable colors in ls</span></div><div class="line"> DISABLE_LS_COLORS=<span class="string">"true"</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Uncomment following line if you want to disable autosetting terminal title.</span></div><div class="line"><span class="preprocessor"># DISABLE_AUTO_TITLE="true"</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Uncomment following line if you want to disable command autocorrection</span></div><div class="line"> DISABLE_CORRECTION=<span class="string">"true"</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Uncomment following line if you want red dots to be displayed while waiting for completion</span></div><div class="line"><span class="preprocessor"># COMPLETION_WAITING_DOTS="true"</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Uncomment following line if you want to disable marking untracked files under</span></div><div class="line"><span class="preprocessor"># VCS as dirty. This makes repository status check for large repositories much,</span></div><div class="line"><span class="preprocessor"># much faster.</span></div><div class="line"><span class="preprocessor"># DISABLE_UNTRACKED_FILES_DIRTY="true"</span></div><div class="line"></div><div class="line"><span class="preprocessor"># Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)</span></div><div class="line"><span class="preprocessor"># Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/</span></div><div class="line"><span class="preprocessor"># Example format: plugins=(rails git textmate ruby lighthouse)</span></div><div class="line">plugins=(sublime)</div><div class="line"></div><div class="line">source $ZSH/oh-my-zsh.sh</div><div class="line"></div><div class="line"><span class="preprocessor"># Customize to your needs...</span></div><div class="line"></div><div class="line">[[ -s <span class="string">"$HOME/.rvm/scripts/rvm"</span> ]] && source <span class="string">"$HOME/.rvm/scripts/rvm"</span></div><div class="line"><span class="preprocessor"># Load RVM into a shell session *as a function*</span></div></pre></td></tr></table></figure>

<h3 id="Step_4:_mac_iterm2_設定_default_zsh">Step 4: mac iterm2 設定 default zsh</h3>
<p><img src="http://i.imgur.com/ZC7hTtO.png" alt="▲ mac iterm2"></p>
<h2 id="自定義主題">自定義主題</h2>
<p>主題除了在 github <a href="https://github.com/robbyrussell/oh-my-zsh/wiki/Themes" target="_blank" rel="external">wiki</a> 上挑選外，還可以查看圖示列表 <a href="http://zshthem.es/all/" target="_blank" rel="external">http://zshthem.es/all/</a>。而我最後挑選了 <code>kennethreitz</code> 作為我的主題，並且做了一些更動，以下是我的主題設定檔:</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">vim</span> ~/.oh-my-zsh/themes/kennethreitz.zsh-theme</div></pre></td></tr></table></figure>



<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="title">local</span> return_code=<span class="string">"%(?..%{<span class="variable">$fg</span>[red]%}%? ↵%{<span class="variable">$reset_color</span>%})"</span></div><div class="line"></div><div class="line">PROMPT=<span class="string">'</span></div><div class="line">[%{<span class="variable">$fg</span>[blue]%}%~%{<span class="variable">$reset_color</span>%} <span class="variable">${return_code}</span>]</div><div class="line">%{<span class="variable">$fg</span>[green]%}%(!.#.$)%{<span class="variable">$reset_color</span>%} '</div><div class="line">PROMPT2=<span class="string">'%{<span class="variable">$fg</span>[red]%}\ %{<span class="variable">$reset_color</span>%}'</span></div><div class="line">RPS1=<span class="string">'$(git_prompt_info)'</span></div><div class="line"></div><div class="line">ZSH_THEME_GIT_PROMPT_PREFIX=<span class="string">"%{<span class="variable">$reset_color</span>%}%{<span class="variable">$fg</span>[yellow]%}["</span></div><div class="line">ZSH_THEME_GIT_PROMPT_SUFFIX=<span class="string">"]%{<span class="variable">$reset_color</span>%} "</span></div><div class="line">ZSH_THEME_GIT_PROMPT_CLEAN=<span class="string">""</span></div><div class="line">ZSH_THEME_GIT_PROMPT_DIRTY=<span class="string">"%{<span class="variable">$fg</span>[red]%}*%{<span class="variable">$fg</span>[yellow]%}"</span></div></pre></td></tr></table></figure>

<p><img src="http://media-cache-ec0.pinimg.com/736x/b9/41/fd/b941fdd237c0707c91a3bc6d0c23ffad.jpg" alt="▲ Self-config theme"></p>
<h2 id="Plugin">Plugin</h2>
<p><a href="https://github.com/robbyrussell/oh-my-zsh/blob/master/plugins/sublime/sublime.plugin.zsh" target="_blank" rel="external">sublime.plugin.zsh</a></p>
<p>舉一個例子我有 <code>plugins=(sublime)</code> ，然後來看看他的 <a href="https://github.com/robbyrussell/oh-my-zsh/blob/master/plugins/sublime/sublime.plugin.zsh" target="_blank" rel="external">zsh code</a> 是怎麼寫的，然後讓我們加入幾行 code 使得可以使用 <code>st3</code> 來開啟最新版本的 sublime 3:</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">vim ~<span class="regexp">/.oh-my-zsh/plugins</span><span class="regexp">/sublime/sublime</span>.plugin.zsh</div></pre></td></tr></table></figure>



<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="input"><span class="prompt"># Sublime Text 2 Aliases</span></span></div><div class="line"></div><div class="line">local _sublime_darwin_paths &gt; /dev/null <span class="number">2</span>&gt;&<span class="number">1</span></div><div class="line">_sublime_darwin_paths=(</div><div class="line">    <span class="string">"/usr/local/bin/subl"</span></div><div class="line">    <span class="string">"$HOME/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"</span></div><div class="line">    <span class="string">"$HOME/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl"</span></div><div class="line">    <span class="string">"$HOME/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"</span></div><div class="line">    <span class="string">"/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"</span></div><div class="line">    <span class="string">"/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl"</span></div><div class="line">    <span class="string">"/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"</span></div><div class="line">)</div><div class="line"></div><div class="line"><span class="keyword">if</span> [[ <span class="variable">$(</span><span class="string">'uname'</span>) == <span class="string">'Linux'</span> ]]; <span class="keyword">then</span></div><div class="line">    <span class="keyword">if</span> [ -f <span class="string">'/usr/bin/sublime_text'</span> ]; <span class="keyword">then</span></div><div class="line">        st_run() { nohup /usr/bin/sublime_text <span class="variable">$@</span> &gt; <span class="regexp">/dev/null</span> & }</div><div class="line">    <span class="keyword">else</span></div><div class="line">        st_run() { nohup /usr/bin/sublime-text <span class="variable">$@</span> &gt; <span class="regexp">/dev/null</span> & }</div><div class="line">    fi</div><div class="line">    <span class="keyword">alias</span> st=st_run</div><div class="line"></div><div class="line">elif  [[ <span class="variable">$(</span><span class="string">'uname'</span>) == <span class="string">'Darwin'</span> ]]; <span class="keyword">then</span></div><div class="line"></div><div class="line">    <span class="keyword">for</span> _sublime_path <span class="keyword">in</span> <span class="variable">$_sublime_darwin_paths</span>; <span class="keyword">do</span></div><div class="line">        <span class="keyword">if</span> [[ -a <span class="variable">$_sublime_path</span> ]]; <span class="keyword">then</span></div><div class="line">            <span class="keyword">alias</span> subl=<span class="string">"'$_sublime_path'"</span></div><div class="line">            <span class="keyword">alias</span> st=subl</div><div class="line">            <span class="keyword">break</span></div><div class="line">        fi</div><div class="line">    done</div><div class="line">fi</div><div class="line"></div><div class="line"><span class="keyword">alias</span> stt=<span class="string">'st .'</span></div><div class="line"></div><div class="line"></div><div class="line">local _sublime_darwin_subl3=<span class="regexp">/Applications/</span><span class="constant">Sublime</span>\ <span class="constant">Text</span>.app/<span class="constant">Contents</span>/<span class="constant">SharedSupport</span>/bin/subl</div><div class="line"></div><div class="line"><span class="keyword">if</span>  [[ <span class="variable">$(</span><span class="string">'uname'</span>) == <span class="string">'Darwin'</span> ]]; <span class="keyword">then</span></div><div class="line">  <span class="comment"># Check if Sublime is installed in user's home application directory</span></div><div class="line">  <span class="keyword">if</span> [[ -a <span class="variable">$HOME</span>/<span class="variable">${</span>_sublime_darwin_subl3} ]]; <span class="keyword">then</span></div><div class="line">    <span class="keyword">alias</span> st3=<span class="string">'$HOME/${_sublime_darwin_subl3}'</span></div><div class="line">  <span class="keyword">else</span></div><div class="line">    <span class="keyword">alias</span> st3=<span class="string">'${_sublime_darwin_subl3}'</span></div><div class="line">  fi</div><div class="line">fi</div><div class="line"><span class="keyword">alias</span> stt3=<span class="string">'st3 .'</span></div></pre></td></tr></table></figure>

<p>如此一來就可以透過指令來啓動 sublime囉，超級方便。</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>st .</div><div class="line"><span class="comment"># or</span></div><div class="line"><span class="variable">$ </span>st3 .</div></pre></td></tr></table></figure>

]]></content>
    <category scheme="http://michaelhsu.tw/tags/linux/" term="linux"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[RSS/Atom、Sitemap for SEO]]></title>
    <link href="http://michaelhsu.tw/2013/05/05/rssatom-sitemap-for-seo/"/>
    <id>http://michaelhsu.tw/2013/05/05/rssatom-sitemap-for-seo/</id>
    <published>2013-05-05T09:51:30.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<blockquote>
<p>不會動的，編成 sitemap.xml，會動的，用 rss 提交。 </p>
<p><img src="http://3.bp.blogspot.com/-x-lZtfOu5rU/Tokfsiby51I/AAAAAAAAEPc/4ixGhkOKwDQ/s1600/sitemap.jpg" alt="sitemap"></p>
</blockquote>
<h2 id="一、首先瞭解_RSS_跟_Atom_差別在哪？">一、首先瞭解 RSS 跟 Atom 差別在哪？</h2>
<ol>
<li>ATOM is an IETF standard while RSS is not</li>
<li>ATOM feeds explicitly indicates the content while the browser is left to figure out whether the RSS feed contains plain text or escaped HTML</li>
<li>ATOM code is modular and reusable while RSS code is not</li>
<li>RSS still holds dominance in the syndication format due to its head start and popularity</li>
</ol>
<a id="more"></a>

<h2 id="二、他們怎麼知道我網頁的_RSS/Atom_link?">二、他們怎麼知道我網頁的 RSS/Atom link?</h2>
<p>像是通常你要訂閱 blog ，可能在 RSS reader 輸入你的網址就會自動搜尋，他是怎麼做到的？</p>
<p><img src="http://i.imgur.com/j3LIruF.png" alt="Feedly"></p>
<p>其實偷看一下 <code>&lt;head&gt;</code> ，其中的 type 是 <code>&quot;application/rss+xml&quot;</code> 或 <code>&quot;application/atom+xml&quot;</code></p>
<ul>
<li>new blog demo: <a href="http://evenchange4.github.io/atom" target="_blank" rel="external">http://evenchange4.github.io/atom</a></li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">&lt;head&gt;</div><div class="line"><span class="keyword">...</span></div><div class="line">  &lt;link rel=<span class="string">"alternate"</span> href=<span class="string">"/atom.xml"</span> title=<span class="string">"Michael Hsu.tw"</span> type=<span class="string">"application/atom+xml"</span>&gt;</div><div class="line"><span class="keyword">...</span></div><div class="line">&lt;/head&gt;</div></pre></td></tr></table></figure>

<ul>
<li>old blog demo: <a href="http://evenchange4.tumblr.com/rss" target="_blank" rel="external">http://evenchange4.tumblr.com/rss</a></li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">&lt;head&gt;</div><div class="line"><span class="keyword">...</span></div><div class="line">  &lt;link rel=<span class="string">"alternate"</span> type=<span class="string">"application/rss+xml"</span> href=<span class="string">"http://evenchange4.tumblr.com/rss"</span>&gt;</div><div class="line"><span class="keyword">...</span></div><div class="line">&lt;/head&gt;</div></pre></td></tr></table></figure>

<h2 id="三、那_Sitemap_呢？">三、那 Sitemap 呢？</h2>
<blockquote>
<p>Sitemap 的提交主要的目的，是要避免搜索引擎的爬蟲沒有完整的收錄整個網頁的內容，所以提交 Sitemap 是能夠補足搜索引擎的不足，進而加速網頁的收錄速度，達到搜尋引擎友好的目的。</p>
</blockquote>
<ul>
<li>demo: <a href="http://michaelhsu.tw/sitemap" target="_blank" rel="external">http://michaelhsu.tw/sitemap</a></li>
</ul>
<h2 id="四、我碰到的問題，&lt;head&gt;_內的_link_type_RSS/Atom_錯亂？">四、我碰到的問題，<code>&lt;head&gt;</code> 內的 link type RSS/Atom 錯亂？</h2>
<p>當 RSS reader 自動搜尋 <a href="http://michaelhsu.tw/" target="_blank" rel="external">http://michaelhsu.tw/</a> 會偵測到 <code>/rss</code> 而不是 <code>/atom</code>，我覺得原因是我這個 domain name 之前是 DNS A(host) 到舊的 blog 那時候是用 rss，而現在新的 blog 是用 atom。<br>所以我覺得並不是因為 head 內寫錯了，而是有 CDN 的原因？<del>待解決…</del><br>已解決，改成 feedburner 一勞永逸</p>
<figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;link rel=<span class="string">"alternate"</span> href=<span class="string">"http://feeds.feedburner.com/michael-hsu-tw"</span> title=<span class="string">"Michael Hsu.tw"</span> type=<span class="string">"application/atom+xml"</span>&gt;</div></pre></td></tr></table></figure>

<h2 id="五、怎麼產生_RSS/Atom-XML">五、怎麼產生 RSS/Atom.XML</h2>
<p>我的 blog 是 hexo node.js base 的，npm 有一個相當簡單的 package <code>hexo-generator-feed</code>，設定教學文可以參考 kpman | code 的<a href="http://code.kpman.cc/2013/05/08/%E5%9C%A8hexo%E8%87%AA%E8%A8%82rss/" target="_blank" rel="external">在hexo自訂rss</a>。</p>
<h2 id="Reference">Reference</h2>
<ul>
<li>What is the difference between RSS and ATOM feeds? <a href="http://stackoverflow.com/questions/6619717/what-is-the-difference-between-rss-and-atom-feeds" target="_blank" rel="external">stackoverflow</a></li>
<li>Sitemap / RSS / Atom, SEO <a href="http://stackoverflow.com/questions/11006823/sitemap-rss-atom-seo" target="_blank" rel="external">stackoverflow</a></li>
<li><a href="http://niucp03.blogspot.tw/2010/09/rss.html" target="_blank" rel="external">瀏覽器自動偵測網站是否具有RSS訂閱</a></li>
<li><a href="http://blog.seo-tw.org/2011/10/sitemap.html" target="_blank" rel="external">如何有效正確的提交Sitemap給搜索引擎</a></li>
</ul>
]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[R and Hadoop 整合初體驗]]></title>
    <link href="http://michaelhsu.tw/2013/05/01/r-and-hadoop-初體驗/"/>
    <id>http://michaelhsu.tw/2013/05/01/r-and-hadoop-初體驗/</id>
    <published>2013-05-01T15:08:17.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<blockquote>
<p><img src="http://i.imgur.com/IVgmGSJ.jpg" alt="R &amp; Hadoop"><br>當 R 尬上 Hadoop，到底會激盪出什麼樣的火花呢？下面實際跑過書上的範例來為您介紹，三種不一樣的整合方式任君挑選。</p>
</blockquote>
<h2 id="目錄">目錄</h2>
<ol>
<li>Hadoop &amp; R</li>
<li>R and Streaming</li>
<li>Rhipe</li>
<li>RHadoop</li>
</ol>
<a id="more"></a>

<h2 id="安裝_R">安裝 R</h2>
<p>想知道它是 Fedora, Debian, 還是Ubuntu 等等的 Linux distribution version：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ cat /<span class="keyword">proc</span>/version</div><div class="line"><span class="comment"># =&gt;</span></div><div class="line"><span class="type">Linux</span> version <span class="number">2</span>.<span class="number">6</span>.<span class="number">32</span>-<span class="number">358</span>.<span class="number">0</span>.<span class="number">1</span>.el6.x86_64 (mockbuild@c6b10.bsys.dev.centos.org) (gcc version <span class="number">4</span>.<span class="number">4</span>.<span class="number">7</span> <span class="number">20120313</span> (<span class="type">Red</span> <span class="type">Hat</span> <span class="number">4</span>.<span class="number">4</span>.<span class="number">7</span>-<span class="number">3</span>) (<span class="type">GCC</span>) ) <span class="comment">#1 SMP Wed Feb 27 06:06:45 UTC 2013</span></div></pre></td></tr></table></figure>

<p>所以選擇安裝 Red Hat el6 =&gt; <a href="http://cran.rstudio.com/" target="_blank" rel="external">官網</a>竟然沒有，只好自己谷歌<br>安裝 <a href="http://pkgs.org/centos-6-rhel-6/epel-x86_64/R-2.15.2-1.el6.x86_64.rpm/download/" target="_blank" rel="external">R-2.15.2-1.el6.x86_64.rpm</a>。</p>
<h2 id="安裝_Hadoop">安裝 Hadoop</h2>
<p>參考 <a href="http://michaelhsu.tw/2013/04/21/hadoop-%E7%AC%AC%E4%B8%80%E6%AC%A1%E5%AE%89%E8%A3%9D%E5%B0%B1%E4%B8%8A%E6%89%8B-cdh3/" target="_blank" rel="external">Hadoop 第一次安裝就上手 CDH3</a>。</p>
<h2 id="範例資料來源">範例資料來源</h2>
<p>下載 hadoop book example: <a href="https://github.com/alexholmes/hadoop-book" target="_blank" rel="external">https://github.com/alexholmes/hadoop-book</a>：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>git clone git<span class="variable">@github</span>.<span class="symbol">com:</span>alexholmes/hadoop-book.git</div></pre></td></tr></table></figure>

<blockquote>
<h2 id="整合一：R_and_Streaming">整合一：R and Streaming</h2>
<p><em>可以使用任何程式語言來實作 map/reduce，只要規定好標準的input/output。<br>好處：在本機端就可以很簡單的做測試，不需要真正去涉及 MapReduce 就能 test，並且透過 cmd 來執行 hadoop job。<br>這邊透過兩個例子（map-only、Full MapReduce）來演示。</em></p>
</blockquote>
<h2 id="一、map-only_job，_problem:_計算_stocks_每日的平均">一、map-only job， problem: 計算 stocks 每日的平均</h2>
<ul>
<li>不 care join or group data in reducer。 </li>
<li>其中 input csv file 的 element 為 <code>Symbol,Date,Open,High,Low,Close,Volume,Adj Close</code></li>
<li>日平均算法：開盤(open)跟收盤(close)的平均。</li>
</ul>
<p>step1: 首先先在本機端（Mac）上跑看看：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># cat ｜ 表示 把前一次運行的結果往後面丟。</span></div><div class="line">$ cat test-data/stocks.txt | src/main/R/ch8/stock_day_avg.R</div><div class="line"><span class="comment"># =&gt; </span></div><div class="line">AAPL	<span class="number">2009</span>-<span class="number">01</span>-<span class="number">02</span>	<span class="number">88.315</span></div><div class="line">AAPL	<span class="number">2008</span>-<span class="number">01</span>-<span class="number">02</span>	<span class="number">197.055</span></div><div class="line">AAPL	<span class="number">2007</span>-<span class="number">01</span>-<span class="number">03</span>	<span class="number">85.045</span></div><div class="line"><span class="keyword">...</span></div></pre></td></tr></table></figure>

<p>step2: 接著丟上 hadoop 來看看：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 首先，先新增一個環境變數，設定hadoop 的路徑</span></div><div class="line"><span class="variable">$ </span>export <span class="constant">HADOOP_HOME</span>=<span class="regexp">/usr/java</span><span class="regexp">/hadoop-1.0.4/</span></div><div class="line"></div><div class="line"><span class="comment"># 移除 output file 內的資料</span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -rmr output</div><div class="line"></div><div class="line"><span class="comment"># 複製到 hadoop file system</span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -put test-data/stocks.txt \stocks.txt</div><div class="line"><span class="comment"># check </span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -ls</div><div class="line"></div><div class="line"><span class="comment"># run hadoop mamp/reduce， -file: copy 到 distributed cache</span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop \</div><div class="line">  jar <span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/contrib/streaming/*.jar \</div><div class="line">  -<span class="constant">D</span> mapreduce.job.reduces=<span class="number">0</span> \</div><div class="line">  -inputformat org.apache.hadoop.mapred.<span class="constant">TextInputFormat</span> \</div><div class="line">  -input stocks.txt \</div><div class="line">  -output output \</div><div class="line">  -mapper `路徑要設`/src/main/<span class="constant">R</span>/ch8/stock_day_avg.<span class="constant">R</span> \</div><div class="line">  -file `路徑要設`/src/main/<span class="constant">R</span>/ch8/stock_day_avg.<span class="constant">R</span></div><div class="line"><span class="comment"># 我的路徑範例</span></div><div class="line"><span class="variable">$ </span>/usr/java/hadoop-<span class="number">1.0</span>.<span class="number">4</span>/bin/hadoop   jar /usr/java/hadoop-<span class="number">1.0</span>.<span class="number">4</span>/contrib/streaming/hadoop-streaming-<span class="number">1.0</span>.<span class="number">4</span>.jar   -<span class="constant">D</span> mapreduce.job.reduces=<span class="number">0</span>   -inputformat org.apache.hadoop.mapred.<span class="constant">TextInputFormat</span>   -input stocks.txt   -output output   -mapper src/main/<span class="constant">R</span>/ch8/stock_day_avg.<span class="constant">R</span>   -file src/main/<span class="constant">R</span>/ch8/stock_day_avg.<span class="constant">R</span></div><div class="line"></div><div class="line"><span class="comment"># check ouput 從網頁看，或是 fs</span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -cat output/part*</div><div class="line"><span class="comment"># =&gt;</span></div><div class="line"><span class="constant">AAPL</span>	<span class="number">2008</span>-<span class="number">01</span>-<span class="number">02</span>	<span class="number">197.055</span>	</div><div class="line"><span class="constant">AAPL</span>	<span class="number">2009</span>-<span class="number">01</span>-<span class="number">02</span>	<span class="number">88.315</span>	</div><div class="line"><span class="constant">AAPL</span>	<span class="number">2007</span>-<span class="number">01</span>-<span class="number">03</span>	<span class="number">85.045</span>	</div><div class="line"><span class="constant">AAPL</span>	<span class="number">2006</span>-<span class="number">01</span>-<span class="number">03</span>	<span class="number">73.565</span>	</div><div class="line"><span class="constant">AAPL</span>	<span class="number">2005</span>-<span class="number">01</span>-<span class="number">03</span>	<span class="number">64.035</span>	</div><div class="line">...</div></pre></td></tr></table></figure>

<p><em>結果與本機端相同。</em></p>
<p>step3: 來看看 R 的 code on <a href="https://github.com/alexholmes/hadoop-book/blob/master/src/main/R/ch8/stock_day_avg.R" target="_blank" rel="external">github</a> ：</p>
<figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># R process name</span></div><div class="line"><span class="comment">#! /usr/bin/env Rscript </span></div><div class="line"></div><div class="line"><span class="comment"># 關掉 warnings</span></div><div class="line">options(warn=-<span class="number">1</span>)</div><div class="line"></div><div class="line"><span class="comment"># 切換 output 到 path</span></div><div class="line">sink(<span class="string">"/dev/null"</span>)</div><div class="line"></div><div class="line"><span class="comment"># standard input.</span></div><div class="line">input &lt;- file(<span class="string">"stdin"</span>, <span class="string">"r"</span>)</div><div class="line"></div><div class="line"><span class="comment"># read n line，false 結尾為 empty，不需要是EOF</span></div><div class="line"><span class="keyword">while</span>(length(currentLine &lt;- readLines(input, n=<span class="number">1</span>, warn=<span class="literal">FALSE</span>)) &gt; <span class="number">0</span>) {</div><div class="line">   <span class="comment"># split 後，unlist 把 list 轉換成 vector</span></div><div class="line">   fields &lt;- unlist(strsplit(currentLine, <span class="string">","</span>))</div><div class="line"></div><div class="line">   lowHigh &lt;- c(as.double(fields[<span class="number">3</span>]), as.double(fields[<span class="number">6</span>]))</div><div class="line">   stock_mean &lt;- mean(lowHigh)</div><div class="line"></div><div class="line">   <span class="comment"># 切換回來 output 到 terminal</span></div><div class="line">   sink()</div><div class="line"></div><div class="line">   <span class="comment"># concatenate 和 ouput</span></div><div class="line">   cat(fields[<span class="number">1</span>], fields[<span class="number">2</span>], stock_mean, <span class="string">"\n"</span>, sep=<span class="string">"\t"</span>)</div><div class="line">   </div><div class="line">   <span class="comment"># 切換回去</span></div><div class="line">   sink(<span class="string">"/dev/null"</span>)</div><div class="line">}</div><div class="line">close(input)</div></pre></td></tr></table></figure>

<h2 id="二、Full_MapReduce_job，_problem:_計算_stocks_累積移動平均（CMA）">二、Full MapReduce job， problem: 計算 stocks <a href="http://zh.wikipedia.org/wiki/%E7%A7%BB%E5%8B%95%E5%B9%B3%E5%9D%87" target="_blank" rel="external">累積移動平均（CMA）</a></h2>
<ul>
<li>CMA 算法為：同樣的公司不同日期的平均。</li>
</ul>
<p>step1: 同樣地先在本機端（Mac）上跑看看：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"># <span class="keyword">cat</span> ｜ 表示 把前一次運行的結果往後面丟。</div><div class="line"># <span class="built_in">map</span> | <span class="keyword">runtime</span> <span class="built_in">sort</span>（用 linux cmd 指令模仿的） | reduce</div><div class="line">$ <span class="keyword">cat</span> test-data/stocks.txt | src/main/R/ch8/stock_day_avg.R | <span class="built_in">sort</span> --key <span class="number">1</span>,<span class="number">1</span> | src/main/R/ch8/stock_cma.R</div><div class="line"># =&gt; </div><div class="line">AAPL  <span class="number">68.997</span></div><div class="line">CSCO  <span class="number">30.8985</span></div><div class="line">GOOG  <span class="number">419.943</span></div><div class="line">MSFT  <span class="number">44.6725</span></div><div class="line">YHOO  <span class="number">70.971</span></div></pre></td></tr></table></figure>

<p>step2: 接著丟上 hadoop 來看看：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line">$ export HADOOP_HOME=/usr/java/hadoop-1.0.4/</div><div class="line">$ ${HADOOP_HOME}/bin/hadoop fs -rmr output</div><div class="line">$ ${HADOOP_HOME}/bin/hadoop fs -put test-data/stocks.txt \stocks.txt</div><div class="line">$ ${HADOOP_HOME}/bin/hadoop \</div><div class="line">  jar ${HADOOP_HOME}/contrib/streaming/*.jar \</div><div class="line">  -<span class="ruby">inputformat org.apache.hadoop.mapred.<span class="constant">TextInputFormat</span> \</span></div><div class="line">  -<span class="ruby">input stocks.txt \</span></div><div class="line">  -<span class="ruby">output output \</span></div><div class="line">  -<span class="ruby">mapper src/main/<span class="constant">R</span>/ch8/stock_day_avg.<span class="constant">R</span> \</span></div><div class="line">  -<span class="ruby">reducer src/main/<span class="constant">R</span>/ch8/stock_cma.<span class="constant">R</span> \</span></div><div class="line">  -<span class="ruby">file src/main/<span class="constant">R</span>/ch8/stock_day_avg.<span class="constant">R</span> \</span></div><div class="line">  -<span class="ruby">file src/main/<span class="constant">R</span>/ch8/stock_cma.<span class="constant">R</span></span></div><div class="line">$ ${HADOOP_HOME}/bin/hadoop fs -cat output/part*</div><div class="line"># =&gt;</div><div class="line">AAPL  68.997  </div><div class="line">CSCO  49.94775  </div><div class="line">GOOG  123.9468  </div><div class="line">MSFT  101.297 </div><div class="line">YHOO  94.55789</div></pre></td></tr></table></figure>

<p><img src="http://i.imgur.com/zJWwuXF.png" alt="最後結果截圖"><br><strong> 但其實，答案跟預期不同，似乎算錯了！</strong></p>
<p>step3: mapper 的 code 同 problem 1 的 mapper，所以我們來看看 R <code>reducer</code> 的 code on <a href="https://github.com/alexholmes/hadoop-book/blob/master/src/main/R/ch8/stock_cma.R" target="_blank" rel="external">github</a>：</p>
<figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#! /usr/bin/env Rscript</span></div><div class="line">options(warn=-<span class="number">1</span>)</div><div class="line">sink(<span class="string">"/dev/null"</span>)</div><div class="line"></div><div class="line"><span class="comment"># R 定義 function，input means：vector</span></div><div class="line">outputMean &lt;- <span class="keyword">function</span>(stock, means) {</div><div class="line">  stock_mean &lt;- mean(means)</div><div class="line">  sink()</div><div class="line">  cat(stock, stock_mean, <span class="string">"\n"</span>, sep=<span class="string">"\t"</span>)</div><div class="line">  sink(<span class="string">"/dev/null"</span>)</div><div class="line">}</div><div class="line"></div><div class="line">input &lt;- file(<span class="string">"stdin"</span>, <span class="string">"r"</span>)</div><div class="line"></div><div class="line">prevKey &lt;- <span class="string">""</span></div><div class="line">means &lt;- numeric(<span class="number">0</span>)</div><div class="line"></div><div class="line"><span class="keyword">while</span>(length(currentLine &lt;- readLines(input, n=<span class="number">1</span>, warn=<span class="literal">FALSE</span>)) &gt; <span class="number">0</span>) {</div><div class="line"></div><div class="line">  fields &lt;- unlist(strsplit(currentLine, <span class="string">"\t"</span>))</div><div class="line"></div><div class="line">  key &lt;- fields[<span class="number">1</span>]</div><div class="line">  mean &lt;- as.double(fields[<span class="number">3</span>])</div><div class="line"></div><div class="line">  <span class="keyword">if</span>( identical(prevKey, <span class="string">""</span>) || identical(prevKey, key)) {</div><div class="line">    prevKey &lt;- key</div><div class="line">    means &lt;- c(means, mean)</div><div class="line">  } <span class="keyword">else</span> {</div><div class="line">    outputMean(prevKey, means)</div><div class="line">    prevKey &lt;- key</div><div class="line">    </div><div class="line">    <span class="comment"># 這邊 sample code 寫錯，發現新的 key 應該要用新的 </span></div><div class="line">    means &lt;- numeric(<span class="number">0</span>) vector</div><div class="line"></div><div class="line">    means &lt;- c(means, mean)</div><div class="line">  }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">if</span>(!identical(prevKey, <span class="string">""</span>)) {</div><div class="line">  outputMean(prevKey, means)</div><div class="line">}</div><div class="line"></div><div class="line">close(input)</div></pre></td></tr></table></figure>

<p><strong> 注意 line 33，更改後才會得到正確的答案。 </strong></p>
<p><img src="http://i.imgur.com/IUo5fqg.png" alt="正確的答案"></p>
<blockquote>
<h2 id="整合二：Rhipe">整合二：Rhipe</h2>
<p>Client-side R and Hadoop working together。<br>「R and Hadoop Integrated Processing Envirnment」的縮寫，在 R 裡面運行 Hadoop job。</p>
</blockquote>
<h2 id="一、安裝_Rhipe">一、安裝 <a href="http://saptarshiguha.github.io/RHIPE/installation.html" target="_blank" rel="external">Rhipe</a></h2>
<p>先安裝 <a href="https://code.google.com/p/protobuf/" target="_blank" rel="external">Protocol Buffers</a>，下載<code>protobuf-2.4.1.tar.gz</code>，一定要這個版本，記得看 readme 安裝方法。</p>
<blockquote>
<p>Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. Google uses Protocol Buffers for almost all of its internal RPC protocols and file formats.<br>think XML, but smaller, faster, and simpler.</p>
</blockquote>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>cd protobuf-<span class="number">2.4</span>.<span class="number">1</span></div><div class="line"><span class="variable">$ </span>./configure</div><div class="line"><span class="variable">$ </span>make</div><div class="line"><span class="variable">$ </span>make check</div><div class="line"><span class="variable">$ </span>make install</div></pre></td></tr></table></figure>

<p>挑一個最多人下載的版本 <a href="https://github.com/saptarshiguha/RHIPE/downloads" target="_blank" rel="external">Rhipe_0.69.tar.gz</a>。</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>export <span class="constant">PKG_CONFIG_PATH=</span>/usr/local/lib/pkgconfig</div><div class="line"><span class="variable">$ </span>export <span class="constant">HADOOP=</span>/usr/java/hadoop-<span class="number">1.0</span>.<span class="number">4</span></div><div class="line"><span class="variable">$ </span>export <span class="constant">HADOOP_LIB=</span><span class="variable">$HADOOP</span>/lib</div><div class="line"><span class="variable">$ </span>export <span class="constant">HADOOP_CONF_DIR=</span><span class="variable">$HADOOP</span>/conf</div><div class="line"><span class="variable">$ </span>/sbin/ldconfig</div><div class="line"><span class="variable">$ </span><span class="constant">R CMD INSTALL </span>/root/<span class="constant">Downloads/Rhipe_0.</span><span class="number">69</span>.tar.gz</div><div class="line"></div><div class="line"><span class="comment"># check install</span></div><div class="line"><span class="variable">$ </span><span class="constant">R</span></div><div class="line">&gt; library(<span class="constant">Rhipe)</span></div></pre></td></tr></table></figure>

<h2 id="二、同_problem_2_計算_stocks_累積移動平均（CMA）">二、同 problem 2 計算 stocks 累積移動平均（CMA）</h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>export <span class="constant">HADOOP_HOME</span>=<span class="regexp">/usr/java</span><span class="regexp">/hadoop-1.0.4/</span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -rmr output</div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -put test-data/stocks.txt /tmp/stocks.txt</div><div class="line"><span class="variable">$ </span>export <span class="constant">HADOOP_BIN</span>=<span class="regexp">/usr/java</span><span class="regexp">/hadoop-1.0.4/bin</span></div><div class="line"><span class="variable">$ </span>hadoop-book-master/src/main/<span class="constant">R</span>/ch8/stock_cma_rhipe.<span class="constant">R</span></div></pre></td></tr></table></figure>

<p><img src="http://i.imgur.com/mJ66DfS.png" alt="結果截圖"></p>
<p><del>接著看一下 整合 rhipe 的 R code on <a href="https://github.com/alexholmes/hadoop-book/blob/master/src/main/R/ch8/stock_cma_rhipe.R" target="_blank" rel="external">github</a></del></p>
<h2 id="三、問題討論">三、問題討論</h2>
<ol>
<li>亂碼？</li>
<li><del>結果數據與第一個整合不一樣</del>：已解決，問題出在整合一的 sample code 算錯。</li>
</ol>
<blockquote>
<h2 id="整合三：RHadoop">整合三：RHadoop</h2>
<p>相較簡單的整合 Client-side R and Hadoop，同Rhipe可在 R 裡面運行 Hadoop job。</p>
</blockquote>
<p>RHadoop其中包含了三個元件</p>
<ol>
<li>rmr (整合 R、Hadoop) ，範例只專注在 rmr 上。</li>
<li>rdfs（R 的 HDFS 界面）</li>
<li>rhbase（R 的 Hbase 界面）</li>
</ol>
<h2 id="一、安裝">一、安裝</h2>
<p>前置套件安裝</p>
<figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">$ R</div><div class="line">&gt; install.packages(<span class="string">"RJSONIO"</span>)</div><div class="line">&gt; install.packages(<span class="string">"itertools"</span>) </div><div class="line">&gt; install.packages(<span class="string">"digest"</span>)</div><div class="line">&gt; q()</div><div class="line"></div><div class="line">$ R CMD javareconf</div><div class="line">$ R</div><div class="line">&gt; install.packages(<span class="string">"rJava"</span>)</div><div class="line">&gt; install.packages(<span class="string">"Rcpp"</span>)</div><div class="line">&gt; install.packages(<span class="string">"functional"</span>)</div><div class="line">&gt; install.packages(<span class="string">"stringr"</span>)</div><div class="line">&gt; install.packages(<span class="string">"reshape2"</span>)</div></pre></td></tr></table></figure>

<p>安裝 rmr2，下載 <a href="https://github.com/RevolutionAnalytics/RHadoop/wiki/Downloads" target="_blank" rel="external">rmr2-2.2.0</a>，中途可能會需要你安裝 R 套件。</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span><span class="constant">R</span> <span class="constant">CMD</span> <span class="constant">INSTALL</span> rmr2_2.<span class="number">2.0</span>.tar.gz</div></pre></td></tr></table></figure>

<h2 id="二、同_problem_2_再來計算一次_stocks_累積移動平均（CMA）">二、同 problem 2 再來計算一次 stocks 累積移動平均（CMA）</h2>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="variable">$ </span>export <span class="constant">HADOOP_HOME</span>=<span class="regexp">/usr/java</span><span class="regexp">/hadoop-1.0.4/</span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -rmr output</div><div class="line"><span class="variable">$ </span><span class="variable">$HADOOP_HOME</span>/bin/hadoop fs -put test-data/stocks.txt stocks.txt</div><div class="line"><span class="variable">$ </span>hadoop-book-master/src/main/<span class="constant">R</span>/ch8/stock_cma_rmr.<span class="constant">R</span></div></pre></td></tr></table></figure>

<p>遇到 argument ERROR：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">Error <span class="keyword">in</span> mapreduce(<span class="variable">input =</span> <span class="string">"stocks.txt"</span>, <span class="variable">output =</span> <span class="string">"output"</span>, <span class="variable">textinputformat =</span> rawtextinputformat,  : </div><div class="line">  unused argument(s) (<span class="variable">textinputformat =</span> rawtextinputformat, <span class="variable">textoutputformat =</span> kvtextoutputformat)</div><div class="line">Execution halted</div></pre></td></tr></table></figure>

<p>因為<a href="https://github.com/RevolutionAnalytics/rmr2/blob/master/docs/getting-data-in-and-out.md" target="_blank" rel="external">新版 rmr2</a> format參數 改了，請改成 <code>vi src/main/R/ch8/stock_cma_rmr.R</code> on <a href="https://github.com/alexholmes/hadoop-book/blob/master/src/main/R/ch8/stock_cma_rmr.R" target="_blank" rel="external">github</a>:</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#! /usr/bin/env Rscript</span></div><div class="line"><span class="keyword">library</span>(rmr2)</div><div class="line"><span class="keyword">...</span></div><div class="line">mapreduce(</div><div class="line">  input = <span class="string">"stocks.txt"</span>,</div><div class="line">  output = <span class="string">"output"</span>,</div><div class="line">  input.format = <span class="string">"text"</span>,</div><div class="line">  output.format = <span class="string">"text"</span>,</div><div class="line">  map = map,</div><div class="line">  reduce = reduce</div><div class="line">)</div></pre></td></tr></table></figure>

<p>最後，</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># check output</span></div><div class="line"><span class="variable">$ </span><span class="variable">${</span><span class="constant">HADOOP_HOME</span>}/bin/hadoop fs -cat output/part*</div><div class="line"><span class="comment"># =&gt; </span></div><div class="line"><span class="constant">AAPL</span>	<span class="number">88.315</span></div><div class="line"><span class="constant">GOOG</span>	<span class="number">428.875</span></div></pre></td></tr></table></figure>

<p><img src="http://i.imgur.com/JN1SV1c.png" alt="有問題的結果截圖"></p>
<p>發現是 map 的 input 格式出錯，更改 sample code：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">#! /usr/bin/env Rscript</div><div class="line">library(rmr2)</div><div class="line"></div><div class="line"><span class="built_in">map</span> &lt;- <span class="function"><span class="keyword">function</span><span class="params">(k,v)</span> {</span></div><div class="line">  fields &lt;- unlist(strsplit(<span class="keyword">v</span>, <span class="string">","</span>))</div><div class="line">  keyval(fields[<span class="number">1</span>], mean(<span class="keyword">as</span>.double(<span class="keyword">c</span>(fields[<span class="number">3</span>], fields[<span class="number">6</span>]))))</div><div class="line">}</div><div class="line"></div><div class="line">reduce &lt;- <span class="function"><span class="keyword">function</span><span class="params">(k,vv)</span> {</span></div><div class="line">  keyval(<span class="keyword">k</span>, mean(<span class="keyword">as</span>.numeric(unlist(vv))))</div><div class="line">}</div><div class="line"></div><div class="line">mapreduce(</div><div class="line">  <span class="built_in">input</span> = <span class="string">"stocks.txt"</span>,</div><div class="line">  output = <span class="string">"output"</span>,</div><div class="line">  <span class="built_in">input</span>.format = <span class="string">"text"</span>,</div><div class="line">  output.format = <span class="string">"text"</span>,</div><div class="line">  <span class="built_in">map</span> = <span class="built_in">map</span>,</div><div class="line">  reduce = reduce</div><div class="line">)</div></pre></td></tr></table></figure>

<h2 id="問題討論">問題討論</h2>
<ol>
<li>為什麼只有兩筆資料？ 是 input format 錯誤??</li>
</ol>
<h2 id="Reference">Reference</h2>
<ul>
<li><a href="http://www.manning.com/holmes/" target="_blank" rel="external">Hadoop.in.Practice.Oct.2012.pdf</a> ch8</li>
<li>R <a href="http://rfunction.com/archives/2238" target="_blank" rel="external">unlist</a></li>
<li>R <a href="http://www.statmethods.net/interface/io.html" target="_blank" rel="external">Input/Output</a> </li>
<li>R <a href="http://stat.ethz.ch/R-manual/R-devel/library/base/html/cat.html" target="_blank" rel="external">cat</a></li>
<li>Nick Hsu <a href="https://docs.google.com/document/d/14StHO_kcYGstR6YQU8QujTi1-pSeWx1CjCIxT7n7aW4/edit" target="_blank" rel="external">101-2 Progress Report</a></li>
<li>rhadoop3-rhadoop-mapreduce <a href="http://cos.name/2013/04/rhadoop3-rhadoop-mapreduce/" target="_blank" rel="external">blog</a></li>
</ul>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/r/" term="R"/>
    <category scheme="http://michaelhsu.tw/tags/hadoop/" term="hadoop"/>
  </entry>
  <entry>
    <title type="html"><![CDATA[Real Time Web]]></title>
    <link href="http://michaelhsu.tw/2013/04/25/real-time-web/"/>
    <id>http://michaelhsu.tw/2013/04/25/real-time-web/</id>
    <published>2013-04-24T21:46:09.000Z</published>
    <updated>2014-09-18T14:00:09.000Z</updated>
    <content type="html"><![CDATA[<h2 id="Node-js">Node.js</h2>
<h3 id="是什麼：">是什麼：</h3>
<ol>
<li>build scalable network applications using JavaScript on the server-side.</li>
<li>據 JavaScript Runtime 寫成，因為大部份都是 C code ，所以很快。</li>
</ol>
<h3 id="可以做什麼：">可以做什麼：</h3>
<ol>
<li>Websocket Server （像聊天室）</li>
<li>Fast File Upload Client</li>
<li>Any Real-Time Data Apps</li>
</ol>
<a id="more"></a>

<h3 id="不是什麼：">不是什麼：</h3>
<ol>
<li>A Web Framework</li>
<li>Multi-threaded（可視為 single threaded server ）</li>
</ol>
<h2 id="Blocking_Code_vs_Non-Blocking_Code（callback）">Blocking Code vs Non-Blocking Code（callback）</h2>
<ul>
<li>Blocking</li>
</ul>
<p>一般為了做:</p>
<ol>
<li>Calls out to web services</li>
<li>Reads/Writes on the Database </li>
<li>Calls to extensions</li>
</ol>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> contents = fs.readFileSync(<span class="string">'/etc/hosts'</span>);</div><div class="line"><span class="built_in">console</span>.log(contents);</div><div class="line"><span class="built_in">console</span>.log(<span class="string">'Doing something else'</span>);</div></pre></td></tr></table></figure>

<ul>
<li>Non-Blocking（callback）</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">fs.readFile(<span class="string">'/etc/hosts'</span>, <span class="function"><span class="keyword">function</span><span class="params">(err, contents)</span> </span>{</div><div class="line">  <span class="built_in">console</span>.log(contents);</div><div class="line">});</div><div class="line"><span class="built_in">console</span>.log(<span class="string">'Doing something else'</span>);</div></pre></td></tr></table></figure>

<h3 id="語法">語法</h3>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">fs.readFile(<span class="string">'/etc/hosts'</span>, <span class="function"><span class="keyword">function</span><span class="params">(err, contents)</span> </span>{</div><div class="line">  <span class="built_in">console</span>.log(contents);</div><div class="line">});</div></pre></td></tr></table></figure>

<ul>
<li>￼￼￼Same as</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> <span class="keyword">callback</span> = <span class="function"><span class="keyword">function</span><span class="params">(err, contents)</span> </span>{</div><div class="line">  console.log(contents);</div><div class="line">}</div><div class="line">fs.readFile(<span class="string">'/etc/hosts'</span>, <span class="keyword">callback</span>);</div></pre></td></tr></table></figure>

<h3 id="Event">Event</h3>
<p>將 Event 附加在 DOM 上。</p>
<h2 id="Websocket_101"><a href="http://lucumr.pocoo.org/2012/9/24/websockets-101/" target="_blank" rel="external">Websocket 101</a></h2>
<h3 id="What">What</h3>
<ol>
<li>因為 bidirectional communication 的需求。</li>
<li>如果兩邊終端（endpoints）非瀏覽器則不一定需要使用 Websocket 這個 protocol。</li>
<li>work with existing HTTP infrastructure，所以受到很多限制。</li>
<li>不同於單純的 raw TCP connection，因為命名的關係常常聯想成傳統的 socket。事實上他在於訊息的傳輸是根據 UDP，但卻有 TCP 的 reliable， </li>
</ol>
<p>websocket adds on top of that:</p>
<ol>
<li>upgrades from HTTP 1.1</li>
<li>Through the HTTP handshake</li>
</ol>
<h3 id="data_structure">data structure</h3>
<p>為了要存放 non-blocking message，使用 <a href="https://github.com/antirez/redis" target="_blank" rel="external">Redis</a>。</p>
<blockquote>
<p>Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes </p>
</blockquote>
]]></content>
    <category scheme="http://michaelhsu.tw/tags/node-js/" term="node.js"/>
  </entry>
</feed>
