爬蟲系列文 - Ruby爬蟲初探

前言

說到網路爬蟲,比較常聽得到的可能是利用Python來實作
那Ruby能不能做到呢?
其實是可以的,只是相較於Python的資源來說沒那麼豐富


環境安裝

首先當然你要先安裝Ruby
這邊會需要Ruby 2.1.0 以上的版本

接著需要安裝 Nokogiri 這個 gem
我們會透過它來達到parse HTML的功能

#先檢查我們有沒有安裝 nokogiri 這個gem
gem list nokogiri 

#假如結果出現類似下方這樣,就是有安裝
#這邊需要的是 Nokogiri 1.6.0 以上版本
*** LOCAL GEMS ***
nokogiri (1.6.7.2)

假如沒有安裝
你會需要執行

gem install nokogiri

假如安裝過程有問題
Then please start troubleshooting with the link


實作開始

  1. 會需要建立一個 crawler.rb 檔 (當然檔名想取其他名字也是可以的)
  2. 這邊會用到 nokogiri 跟 open-uri
  3. 拿博客來的每日六六折來舉例 (http://www.books.com.tw/activity/gold66_day/?loc=activity_BK_001)
crawler.rb
require 'nokogiri'
require 'open-uri'

# Let's try to fetch and parse HTML document

books = Nokogiri::HTML(open('http://www.books.com.tw/activity/gold66_day/?loc=activity_BK_001'))

puts "### Search for nodes by css with Bookstore"
books.css('div h1 a').each do |link|
  puts link.content
end

從網頁原始碼來解析

我們實際上要看的是這裡

詳細說明


實際執行

下面爬出來的書名就是執行結果


參考資源:

Nokogiri
Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser with XPath and CSS selector support.
Nokogiri Tutorials

open-uri
open-uri: Ruby Standard Library Documentation

Blog reference
用 Ruby 做網頁爬蟲
第十一篇 - 第一次自幹爬蟲就上手 - 使用 Ruby

Rails Pacific 2016 - 關於Adam Cuppy 介紹的 RSpec - Part 2

Part 1 提到了 M.V.O. Workflow
接著要來講一下 Permutation Tables


P.T. Workflow

1. Define sets of data (定義你的 Data sets)
2. Define the output of each set (定義每個 Output)
3. Assert the method creates the output from the data (input/output) (驗證 input 和 output)

一樣是用 User modal 來舉例
這次要看的是 fullname 這個 method


這個 method 裡面有個 Array
包括了 firstname, middlename, lastname


這個 Array 加上了 compact 用意
是會把array成員是 nil 的去掉
Ruby 官方 API Array compact


這邊的 join 則是說
會把這個 Array 組成一個字串
而且每個array成員之間會有一個空格隔開
Ruby 官方 API Array join


假如用之前的 M.V.O workflow 來寫
我們的測試大概是會長成這樣


這邊是說我們現在要測的東西是
User modal 裡面的 fullname method
因為每個子測項都會需要做一次
所以用subject 把它抽出來


這邊的 user.fullname 對應 #fullname
會加上 # 用意是代表 instance method
Better Specs - How to describe your methods


這邊可以看到第一個測項是
firstname 的值為 nil 的情況


這邊則是加上了 lastname 的值為 nil 的情況


陸續加了幾個測項之後
我們還少了什麼情況的測項呢?!


這樣的寫法其實是不好的
不好看出我們寫了哪些測項
抑或是少了哪些測項


如果要改寫成 P.T. workflow
我們先從基本結構來看


我們要驗證的是 firstname 的 nil值


剛剛的測項
可以改寫成這樣
Array nil 的部分是 firstname


Array 的 James 的部分是 middlename


Array 的 Johnson 的部分是 lastname


合起來的 新字串 就是 fullname


稍微列幾個測項


我們還少了什麼測項呢?


這邊很明確的可以比較看出我們少了這些


測項用 P.T workflow 完整寫起來會是這個結構


我們把每次要做的部分抽出來
用 each 來跑
也利用 Shared Examples 的方式抽到前面來
讓 test code 達到 Dry
Better Specs - Shared Examples


這樣整個就是會是 P.T. Workflow 的正確寫法
是不是乾淨清楚多了呢!?


Rails Pacific 2016 - 關於Adam Cuppy 介紹的 RSpec - Part 1


Rails Pacific 2016 - 關於Adam Cuppy 介紹的 RSpec - Part 1

先講結論,你可以學到什麼 ?

1. RSpec 基本寫法
2. 幾個化繁為簡的 RSpec Design Patterns

Taming Chaotic Specs: RSpec Design Patterns - 投影片

在此之前,我對於 Adam Cuppy 的印象僅止於
地表最強 RSpec 這句形容他的話


直到聽了 Taming Chaotic Specs: RSpec Design Patterns
今年 Rails Pacific Day 1 的 Workshop 之後
深深體會到他在RSpec的強大
這強大在於你光看投影片也可以感覺出這些 Patterns 的好用之處


接下來就略為介紹一下他投影片所帶到我有理解的部分
因為只寫過其他語言的測試,對於 RSpec 僅止於理解
還未實做過,講錯的部分還請不吝指正


關於寫測試

常常聽人講寫測試,你是否也是對測試一知半解呢?
剛開始寫測試,你可能會處於東寫一點西漏一點
把測試寫得很亂的情況

As Adam Cuppy says :

Don’t you hate when testing takes 3x as long because your specs are hard to understand? 
Following a few simple patterns, you can easily take a bloated spec and make it DRY and simple to extend. 
We will take a bloated sample spec and refactor it to something manageable, readable and concise.

Minimum Valid Object

M.V.O. Workflow...
1. Start with a “valid” object (先定義 valid 的物件應該是怎麼樣的)
2. Make one specific change    (就你需要測試得部分做修改)
3. Assert the “valid” object is now “invalid”  (驗證 invalid 情況的測試)

這邊用 User modal 來舉例,
假設我們有個 User modal 有以下這些設定


基本的 RSpec 格式可能是會這樣寫的
這邊是在寫應該要 invalid 的測項
因為 User modal 的 firstname 長度定義在 4~20個字
所以長度 小於 4 或是 超過20 都屬於 invalid 的範圍


你可能會想說這樣寫是合理的


那實際執行結果呢?!


拿這部分來看好了
這邊是長度超過 20 的部分


對於 User modal 我們其實只給了 firstname 的值


其他的部分,因為沒有給值
所以造成了驗證錯誤


我們實際上想驗證的是 Should be invalid 這個測項
expect(user.valid?).to_not eq true (這邊是說 我們預期 user 不會等於 true)


一個基本的 RSpec scope 應該會長這樣
describe "你要測的class" do 開頭
然後end 結束這個 scope


這邊可以看到我們每次驗證之前
都需要執行 User.new 的動作


每次跑測項的時候都要做的事情就可以抽出來
Subject 可以看作每個子測項都要做的 setup動作
described_class 其實就是代表我們要測的 User modal 這個 class


本來的寫法可以整理成這樣


這邊是長度超過20的測項


這邊是長度小於4的測項


加上我們要的 firstname 參數
和測項需要的值


firstname 參數會對應到的部分


對照改寫前的寫法
我們還缺少驗證的部分


我們可以把驗證的寫法單獨抽出來看一下
expect(user.valid?).to_not eq true (我們預期 user 不會 等於 true)
這邊會不會覺得 to_not 然後又是 true 很奇怪呢?!
到底是 true 還是 not true


很明顯的
這寫法不太好


RSpec Predicate Magic Methods

這邊要講一下 RSpec 斷言的特別用法

當我們在驗證 user 是不是 valid 的時候
user.valid? 的 valid?
可以寫成 be_valid


依樣畫葫蘆
我們要做其他驗證也可以這樣寫


改寫成這樣之後
還是有 to_not 跟 be_valid
其實語意還是不清楚


可以再改寫成這樣
把 to_not 跟 be_valid
整合成 be_invalid
這樣就只需要看 be_invalid


是不是清楚多了
這樣的寫法才是語意正確的


把剛剛改寫完的驗證的部分加進去


雖然修正了寫法
但我們還是只驗證了否定的測項


只有預期錯誤的否定測項
那肯定測項應該是什麼樣的呢?!


加上預期會正確的肯定測項
fisrtname 長度的範圍是 4~20
所以長度 4 是正確的


這樣我們的測項就比較比較完整了


現在的驗證部分


可以改寫成這樣


前面都是只講 firstname 參數
其實整個完整的寫法應該是這樣的
可以拆解成幾步來看


1. 建立 Subject 物件,User modal 有這些參數


2. 設定 default 正確的情況,這些參數可以怎麼塞值


3. 驗證正確的情況


4. 接著依照我們想測的參數來改變他的值


這樣是不是完整多了呢?!
這樣的寫法就是符合了 M.V.O. Workflow


Rails Pacific 2016 - 關於Adam Cuppy 介紹的 RSpec - Part 2

未完待續...

Rails 實戰春季二班心得

先講結論

斯斯有兩種

1.真的想學Rails
並且想快速入門
學費也負擔得起
也願意花大量時間練習
有時間參加Meetup
非常推薦

2.只是想沾點邊
學費對你是很重的負擔
沒有時間練習
沒有時間參加Meetup
這種就非常不推薦


補習班

補習上課來說有幾種情況
就我自身參加過巨匠,恆逸資訊,Xdite Rails實戰班這些經驗來講
應該還算有點說服力

1.花了自己的錢沒學到東西
這種情況通常最幹
不過也有分成課程不能吸收
老師教不好
或是下了課自己也沒練習
課程也不會push你
也可能是課程教的你其實都會了
我在巨匠補習曾經有過這種感覺
老師好壞參差不齊

2.花了自己的錢有學到東西
這種情況通常是因為花了自己的錢
自然會認真一點
可能是課程服務完善
或是程度能吸收
Rails 實戰班對我來說屬於這種

3.花了別人的錢沒學到東西
這種情況通常發生在家裡幫忙出錢
唸書的時候補習應該很多會屬於這種
或是公司出錢
因為不是花到自己的錢
也不一定真的想上課
自然也不會感覺到痛

4.花了別人的錢有學到東西
這種情況也可能是家裡
或公司/政府補助
老師教得好可能是其一
自己也能吸收
我在恆逸資訊有過這種體驗
當時是用青年就業補助


回到正題

扯了一堆
回到本來的主線

會刷下這課程是因為平常吃飯都會看Logdown explore
看看別人的筆記或技術心得吸收新知很不錯
偶然間看到Rails實戰班的心得
後來也追蹤了Xdite的FB
交叉洗腦下開始有了想上課的念頭

去年的冬季班大概就有想上課的想法
但因為覺得沒有大量時間寫作業而作罷
年底的時候在FB上看到春季班的訊息
那時距離開課還有兩個月
仔細想了一下
覺得應該有充足時間預習完Rails101
便一頭熱地從皮包掏出信用卡刷下去了

一方面也是想看看這課程是不是這麼神
許多學員的心得都寫得栩栩如生


課前預習

刷完課程不久
就收到了要我加入課程Slack的通知
上面也提醒說一定要先預習 前導教材
前導教材一
這是Railsbridge提供的免費教材
前導教材二
這是Growth school提供的免費教材

前導教材都是免費的
如果想沾點邊的
可以考慮這些大概就可以稍微體驗了

在上課前自己大概完整練習了兩次Rails 101
兩次是202 (雖然不是200 OK 但也是成功了)
不一定要做到4遍變成404 Not Found

兩次都是自己打字
自己打字有個好處
一邊打可以一邊理解程式邏輯
就算不能馬上理解也會有點印象
經過思考理解之後才算真的懂

打字過程也難免會經歷打錯字的情況
這時候就可以嘗試著自己排除錯誤
在開發過程中
debug是常常會做的事
差別只是時間長短
經驗多少罷了

第二遍大概就開始試著看題目需求
自己試著產生對應的東西
有些地方也是沒法產生完全
還是可以偷看答案來加深印象
這在平常開發也是會發生的
主管或PM開出需求
你理解跟釐清需求之後
想辦法實作功能出來

在做Rails 101的過程中
也遇到過幾次教材有錯字
順序不對
或是有些地方照著教材做會有bug出現的情形
在經過自己檢查跟看底下留言
有參考slack頻道同學提問
也嘗試Google排除之下
大致上是還算順利

這邊也建議在做Rails101有成功debug的朋友
可以在課程留言提醒一下
前人踩雷
後人被炸才有得參考


卡關求助管道

通知信裡面也提供了卡關求助管道
不管是課程問題
或是自己想做點小東西
繳了錢就是該問問題

實體管道:
每週二與四都有 Rails 新手帶練與指導 (晚上 19:00 - 22:00 )
在 Deroot 台北市中正區新生南路一段60號B1
線上管道:
Slack Rails 頻道

時間允許的話
建議是兩種管道都花時間參與
實體管道是有人當場幫你障礙排除
也可以準備好問題過去轟炸助教

線上管道則是適合時間或地點
不方便過去參加實體管道的


環境安裝

如果有參照前導教材的
應該會經歷安裝環境這一環
要開發免不了要經歷一次
一開始是照著Railsbridge 安裝趴下去安裝
RailsBridge 裝機趴 Installfest

距離上課前兩週再次收到 Call to Action 通知
上面提供了更仔細地環境安裝和工具設定


課前作業檢查表

這邊是利用 Quip 這個多人協作軟體
其實有點像Google Doc 但是又更方便
小團隊或小公司很適合使用

藉著課前作業檢查表
可以逐項勾選確認自己有沒有完成
一項一項去除也多少會有點成就感

檢查表上除了基礎項目
也有一些加分項目
加分項目 可想而知是不做沒關係
有做會更好
但有些小功能可能要有 Review 機制
不然加分項目做完沒有反饋有時不免顯得自嗨


正式上課

正式上課是在台大的集思會議中心
環境還算舒適
小缺憾是有便當但卻沒有喝的
這算是個小bug

上課整體流程是架構在實作出一個購物網站
一開始是講 User Story 使用者故事
這算是我蠻感興趣的部分
以往都是當RD
比較少參與設計功能的部分
User Story 是從使用者角度去思考
實際會產生什麼行為
把行為轉換為需要開發的功能
比起冷冰冰的 Spec 規格 來說
多了一份親切感

如果有仔細做過Rails101至少兩次
會發現第一週其實是很親切的
後台功能和Bootstrap套版
大多是基於Rails101的基礎上加點東西

上完第一週
作業大致也先跑完一次
比較有趣的部分是利用carrierwave來做圖片上傳的部分
利用git pull request來繳交作業
第二次就是一邊理解
一邊嘗試實作

藉著 Quip 的共筆系統
除了完成自己的筆記部分
也可以參考同學的
這部分也是有小bug
筆記雖然可以參考其他人的
但是寫錯不一定會發現
如果有筆記糾錯的服務會是更加分的

第二週算是進入重點了
開始實作購物車跟訂單的部分
這邊開始就跟Rails101產生分歧點
往外延伸到其他部分

其中 State machine 狀態機 蠻重要的
如果是非本科應該不太會接觸到這部分
狀態機 顧名思義就是用來幫你切換狀態的
按照他的規則
寫出 state狀態, transitions切換條件, event切換動作
訂好之後就會照你訂的規則下去跑

也因為跟Rails101重疊部分不多
開始有點吸收不順的情況
一邊要理解一邊想打code會有點跟不上
發現跟不上的時候用貼的是比較快的
但只貼不思考大概就會產生有些人說的貼code班的效果

第二週作業則是要補上上課沒做的一些部分
添加清空功能
處理數量計算邏輯
前後台訂單檢視
後台狀態切換

第二週和第三週中間空了一週
應該是讓我們有更多時間去準備消化前面的部分
不過人總是有惰性
做完第一遍就開始有點偷懶
好在也是藉著兩次禮拜天自發性的作業讀書會彌補了一點

第三週則是寄信,金流,整理Code
寄信是利用 letter_opener 來做
有先帶到了以往 Xdite是教他公司裡的新進員工用 Gmail測試套件
那課程為什麼不用呢?
因為預覽每次要打開gmail很麻煩
然後一天寄超過50封信
會跳出 被Gmail ban掉 成就 Get

金流的部分
這邊是教我們用智付寶
也不免俗先帶到了歐付寶
有在關注Logdown或是Xdite FB的應該對 歐付寶事變 有印象
就不贅述了

透過教學
申請智付寶測試站拿到需要的 API Key
也裝了Pay2go
做完相關設定之後
就嘗試著刷卡了
能在自己實作的網站上刷卡其實是很有成就感的

整理Code的部分
Controller
講到用繼承去抽出不同Controller的相同部分
同一個Controller內
則是可以利用Filter來抽出重複action code

Model
用Module來抽出不同Model的相同部分

View
這邊是講到什麼時候你該用Helper
什麼時候你該用Partial

當View裡面出現 邏輯判斷,邏輯計算的時候
這時候你應該用Helper

當View裡面有整塊元件可以複用
當View超過兩三頁
或是特殊元件應該抽出來另外看的
這時候你應該用Partial

最後是ServiceObject
這邊可以把它理解成功能元件化
把同性質的功能整個拆出來

用大賣場來比喻
可以講說是什麼都有什麼都賣什麼都不奇怪
但是如果把相同性質的商品分區處理結帳
這樣就很方便的可以去找你要的東西
ServiceObject大概就是在做這樣的事
把同性質的東西封裝成一個物件來處理
你想要做相關的事就要透過ServiceObject去做

因為上課時間關係
也偷講了一些第四週有關的內容
前後端調教對使用者體驗來說蠻重要的


前三週總結

整體來說
上課節奏蠻緊湊的
雖然每段講解跟實作時間都是分開
但聽完講解後接著就是馬上實作
其實是沒辦法在上課時間理解完全的
上課是在腦袋大致上畫上一個輪廓
透過實作走過一遍加深印象
如果下課就不練習其實效果有限

可以透過課前預習
或是課後練習來補上細節理解不足的部分
當然也是會有很多地方自己不好理解
這邊也需要自己做筆記整理起來
Meetup/slack/上課QA時間大概就是可以處理掉這部分
很多時候也是自己偷懶或是時間不夠沒整理完全

大量練習是必須的
一邊做一邊理解
透過debug找原因去了解為什麼

雖然課程費用不便宜
只要投入夠多心力
你就會發現這錢花得並不冤枉
在這幾個月可以學到的實際上你自己要花很久去摸索
更別說可以認識有相同企圖心的同學
從助教跟老師身上透過提問去挖到更多的東西..等等

Rails Controller - Filters

Filter 是什麼?

有些東西直接講也講不明白
我們看看官方文件是怎麼說的

Filters enable controllers to run shared pre- and post-processing code for its actions. These filters can be used to do authentication, caching, or auditing before the intended action is performed. Or to do localization or output compression after the action has been performed. Filters have access to the request, response, and all the instance variables set by other filters in the chain or by the action (in the case of after filters).

Filter 有哪些 ?

斯斯有三種
before_action, after_action, around_action (Rails 4 開始的寫法)
before_filter, after_filter, around_filter (Rails 4 之前的寫法)

為什麼我們要用 Filter 而 Filter 又是怎麼用呢?

一般而言有幾種情況會用到
一是做 Code refactor 的時候
比如說在不同 action 裡面都會做同樣的事
這時候就可以用一個自訂 action 抽出來放在 filter 觸發時執行

二是做使用者驗證
像是有些功能是要登入才能做的
這時候就可以用 before_action 來做動作前的驗證是否登入

三是做異常處理
做某些動作時可能在不同階段會遇到不同的異常狀況
這時候就可以用 around_action 來做動作過程中的異常處理

四是做 log 紀錄
我們可能會想在執行每個動作之後紀錄執行狀況
這時候可以用 after_action 來把結果寫進log檔裡

References :

ActionController::Filters::ClassMethods In: actionpack/lib/action_controller/filters.rb
_filter vs _action
Rails Filters: Before, After, and Around Filters
使用 Filters 整理 controller
Ruby on Rails 實戰聖經 Action Controller - 控制 HTTP 流程 - Filters
Rails 102 Filters : before_action, after_action, around_action

Rails Controller - Strong Parameter

Strong Parameter 是什麼呢 ?

Strong Parameter 主要是用來限制 parameter 寫入 db 的
假如送出的 parameter 沒有被 permit
就無法透過 create method 新增資料
或用 update method 對資料做更新

為什麼要用 Strong Parameter 呢 ?

話若是講透枝, 目屎是撥未離

主要是 Rails 在設計 Form 的欄位是直接對應到 Model
這會造成關鍵欄位很容易被猜中的情況
Hacker可以經由測試欄位來入侵

所以 Rails 4 維護團隊就利用 Strong Parameter 來解決這個問題

若要細說從頭
就要從 Github 被 hack 事件說起
可以參閱
從 Github 被 hack,談 Rails 的安全性( mass-assignment )

Strong Parameter 要怎麼用呢 ?

對照下面的 sample code
可以看到只有 title 和 description 這兩個欄位有被 permit
當我們執行 create method 的時候
除了這兩個欄位以外的參數都會被濾掉
不會存到 db 裡

products_controller.rb
class Admin::ProductsController < ApplicationController

def create
    @product = Product.create(product_params)
end

private
def product_params
    params.require(:product).permit(:title, :description)
end

References :

Rails 102 Strong Parameters

Rails Routing - Namespace

Namespace 是什麼 ?

Namespcae 是 scope 的一種特定應用
特別適合應用於後台介面
寫在 Namespace 裡的都會被影響到
簡單來說就是用來改變 routing path的

為什麼我們要用 Namespace 呢?

通常是用來區分 controller 底下的 routing
在專案裡有同名 controller 的需求時可以有效把整組 routing 分開

Namespace 該怎麼用呢?

比如說我們現在要做一個購物網站
而網站會有前後台
前後台有需要同名的 controller, view
這時候使用 Namespace 就可以把同名的 routing 整組區分開

routes.rb
resources :products

namespcae :admin do 
    resources :products
end
resources :products

這裡表示 controller 是 ProductsController
而網址會是 /products
URL Helper 會是 products_path

namespcae :admin do 
    resources :products
end

這邊的 controller 則是 Admin::ProductsController
網址會是 /admin/products
URL Helper 會是 admin_products_path

References :

Ruby on Rails 實戰聖經
Rails Routing from the Outside In

User Story

User stroy 是什麼?

  • 使用者故事
  • 敏捷專案常用技巧
  • 可以用來取代規格的東西
  • 透過「角色」來表達在什麼「場景」該做什麼事

為什麼我們要用 User stroy ?

  • 只有規格和功能會不知道如何下手,或是容易做東缺西
  • 以使用者的觀點下去寫出實際會遇到的狀況,藉此寫下有價值的功能與需求
  • 好處是可以專注在必要功能,避免浪費時間在有附加價值但卻不必要的功能
  • 團隊跑敏捷專案會用到
    • 需要把使用者故事切成細項
    • 用細項去劃分可能需要的時間
    • 藉此來控管專案時程

如何使用 user story ?

  • 比如說實作一個購物網站
  • 由使用者和管理者兩個方面去做延伸
  • 寫出使用者會可能想看到的功能和過程中應該會遭遇到的功能
  • 寫出管理者應該要有的功能和實際管理上應該會遭遇到的功能

Time to go through Rails 101

Rails 101 是一個免費線上課程

Rails 101
rails101s

起初是由Xdite開始寫的
後來的再版交由Sdlong改寫與維護

這邊是使用 Rails 4.2.0 和 Ruby 2.2.0的環境
使用的環境是比較推薦用Mac 或是Linux
不可諱言的只要用過Mac 相信就回不去了
Mac無論對一般使用者或是程式開發者來說
都有更好的使用者體驗

裡面由Scaffold開始體驗
接著教你套用好用的前端套件Bootstrap

完成了體驗版本
後續大致上是用做一個討論板為目標
教你如何自己動手做出有CRUD的功能

接續的豆知識也會告訴你
什麼是MVC
什麼是RESTful

也用了devise這個gem
來做使用者機制

同時也有簡易的後台機制

寫到這邊應該覺得Code有點亂了
所以也有帶到一些實用的Refactor技巧

最後是教你如何把網站Deploy上Heroku

Meetup

裡面也有提到假如卡關了或是有任何問題
你都可以在這些時間到這些地方求助
Taipei Rails Meetup 台北市新生南路一段 60 號 Deroot。週二:19:00 - 22:00
Ruby on Rails 新手村 台北市新生南路一段 60 號 Deroot。週四:19:00 - 22:00
Kaohsiung Rails Meetup 週三 19:00-22:00

First Step on Rails

工欲善其事,必先利其器

第一篇就從環境設定開始吧
可以參考
RailsBridge 裝機趴 Installfest

裡面有提供 Mac OS, Windows, Linux的安裝程序
不過我只安裝過Mac OS的
因為硬碟出問題的關係安裝過10.10.5
和現在的 10.11.3
如果安裝有問題可以留言交流一下

同時也有Git的安裝教學
對寫程式而言
版本控管是很重要的一環
無論是多人協作
或只是一個人自幹
Git就是在做版控的部分

另外是設定SSH key
很多時候遠端會需要帳號密碼
SSH key可以用來取代每次輸入帳密的這個步驟
也有不少的線上服務是可以利用SSH key來做認證
這邊需要安裝的 Git 跟 Heroku 都有用到

接下來是Heroku
什麼是Heroku呢?!
寫網站總會需要一個地方可以放
平常測試可能是在本機端
不過實際上線總會需要個Server
假設還沒有餘力自己用Linux架設的話
Heroku就是很方便可以完成這個需求
而且有五個App的空間免費