Ruby on Rails 網站程式設計基礎班
第二課: Ruby 語言基礎

公告
補交門禁卡押金
公告
Office Hour (課後輔導):
時間:星期三晚上 8:00 - 9:00
地點:承德路三段98號三樓
公告
課程內容會錄影
*不過別太過依賴它
Mac vs. Ubuntu
各有好壞
Mac 開發介面比較人性化
Linux 和雲端伺服器比較接近

心理建設
卡關,程式出錯是常態
工程師很大一部分的時間都是在 debug
基本的 Unix 指令
# 以後講義上出現前面有 '$' 符號的程式碼代表終端機指令
# 請不要把 '$' 複製貼上到終端機
# mkdir 是創出一個新的路徑(也就是資料夾)
$mkdir ntu_ror_266
# cd 是改變路徑到某個地方
$cd ntu_ror_266
# ls 是把目前這個目錄下的所有檔案都列出來
$ls
# => ntu_ror_266
# touch 是創造一個新的檔案
$touch hello_world.rb
# code 是開啟 code
$code hello_world.rb
$code .
# ruby 是執行副檔名為 .rb 的檔案
$ruby hello_world.rb
更多 Unix 指令教學
git 版本管理工具

github 註冊

markdown 語法
用簡單易讀的語法把純文字檔案轉成易於網頁顯示的 html 程式碼
注意副檔名是 .md
教學:
https://wastemobile.gitbooks.io/gitbook-chinese/content/format/markdown.html
http://markdown.tw/
markdown 與 git demo
# 建立一個空的資料夾
$mkdir folder_name
# 進入資料夾
$cd folder_name
# 建立一個 md 檔
$touch my_file_name.md
# 在 md 檔裡寫入:
##Hello World!
```ruby
puts "Hello world!"
```
# 接下來用 git 做版本控制並推上 github
markdown 與 git demo
# 先在 github 建立一個帳號
# 在終端機輸入
$git init
$git remote add origin 你的 github 專案連結
$git add my_file_name.md
$git commit -m "first commit"
$git push origin master
# 就可把 md 檔上傳到 github
Comparisons (邏輯運算)
if 4 >= 4 #若這樣比
puts "5 大於等於 4" #這行也會被印出
end
# A <= B 則是比較 A 是否小於等於 B
if 5 <= 6
puts "5 小於等於 6"
end
if 6 <= 6 #若這樣比
puts "5 小於等於 6" #這行也會被印出
end
Comparisons (邏輯運算)
# A && B 則是指 A 必須成立而且 B 也必須成立,我才會回傳 true
if (4 < 5) && (5 < 6)
puts "兩者都成立"
end
if (4 < 5) && (5 > 6) #這樣就不會印出任何東西,因為( 5 > 6 )不成立
puts "兩者都成立"
end
# A || B 則是指只要 A 或 B 其中一方成立,我就會回傳 true
if (4 < 5) && (5 < 6) #這樣會印出東西,因為兩者皆成立
puts "兩者都成立"
end
if (4 < 5) || (5 > 6) #這樣也會印出東西,因為兩者其中一方成立
puts "兩者都成立"
end
Comparisons (邏輯運算)
# !A 則是取身為布林值 A 的反值,所以
!(4 < 5) # 放入 irb 裡會回傳 false
# (4 < 5) 會回傳 true, 但前面加的 ! 會取 true 的相反值,也就是 false
# 在 ruby 裡,變數前面有兩個驚歎號代表會把判斷這個變數是否有值
!!5
# =>true 5並非空值
str = "p"
!!str
# =>true str, 也就是"p",並非空值
# ruby 語言裡唯二會被判斷成 false 的值分別是 false 和 nil
!!false
# => false
!!nil
# => false
Condition(判斷式)
input = 6
if input < 5 # 如果 if 後面判斷式成立
puts "#{input} is less than 5" # 就執行這邊
else # 不成立的話
puts "#{input} is greater than or equal to 5" # 只好執行這邊
end
# => 6 is greater than or equal to 5
Condition(判斷式)
operation = 3
if operation == 1 #判斷式不成立,會接下去看下一個 elsif
result = num1 + num2
puts "your answer is: #{result}"
elsif operation == 2 #判斷式還是不成立,會接下去看下一個 elsif
result = num1 - num2
puts "your answer is: #{result}"
elsif operation == 3 # 成立!,印出 num1 x num2 的結果
result = num1 * num2
puts "your answer is: #{result}"
else
result = num1.to_f / num2.to_f
puts "your answer is: #{result}"
end
Condition(判斷式)
# ternary operator 簡單來說,就是讓你用更簡潔的方法來寫 if...else 判斷式
# 語法是 判斷式 ? 成立要執行或回傳的程式碼 : 不成立要執行或回傳的程式碼
puts true ? "this is true" : "this is false"
# => "this is true"
puts false ? "this is true" : "this is false"
# => "this is false"
Condition(判斷式)
# case...when,用敘述來測試一連串條件
operation = 5
case operation #case 關鍵字後面要加上被判斷的變數
when 1 # 到這裡,ruby 會去判斷 when 後面的參數是否等於 case 後面的變數
# 就等同於執行 operation == 1 (但請不要把判斷式寫在這裡喔)
puts "operation is equal to 1" # 若 operation 等於 when 後面的結果,執行這段程式碼
when 2 # 到這裡,ruby 會去執行 operation == 2
puts "operation is equal to 2" # 若 operation 等於 when 後面的結果,執行這段程式碼,以此類推
when 3 # 以此類推...
puts "operation is equal to 3"
when 4 # 以此類推...
puts "operation is equal to 4"
else # 預設項目,若上面所有的 case 都不成立時,就執行預設項目裡的程式碼
puts "operation is equal to 5"
end
Condition(判斷式)
# when 後面要被比較的結果也可以是字串
operation = "3"
case operation #case 關鍵字後面要加上被判斷的變數
when "1" # 到這裡,ruby 會去執行 operation == 1 (請不要把判斷式寫在這裡喔)
puts "operation is equal to 1" # 若 operation 等於 when 後面的結果,執行這段程式碼
when "2" # 到這裡,ruby 會去執行 operation == 2
puts "operation is equal to 2" # 若 operation 等於 when 後面的結果,執行這段程式碼,以此類推
when "3"
puts "operation is equal to 3"
when "4"
puts "operation is equal to 4"
end
Condition(判斷式)
# 當然,Ruby 是講求程式碼精簡的語言,所以我們可以把 case when 的程式碼變得更簡潔一點:
operation = 3
case operation
when 1 then puts "operation is equal to 1" # 加上 then 關鍵字,可直接把要執行的程式碼寫在 then 後面
when 2 then puts "operation is equal to 2"
when 3 then puts "operation is equal to 3"
when 4 then puts "operation is equal to 4"
end
Loop(迴圈)
3.times do
puts "Hello World!"
end
#代表這個會印出三次 "Hello World!"
# while loop 則是會根據 while 後面的判斷式決定是否要繼續執行迴圈
# 可以想成 '只要' 條件式還成立,我就繼續執行
# 要先給 i 個起始值
i = 10
while i > 0 #判斷式是只要 i 大於 0,我就繼續執行
puts "while loop to #{i}"
i -= 1 #每執行一次,i 就會減一,這就是所謂的"遞減"
#若這邊比較難看懂,可以把 i -= 1 想像成 i = i - 1
end
Loop(迴圈)
# begin...end while 和 loop do 一樣,主要是用於一些我不知道起始值的狀況
begin #告訴電腦先執行以下程式碼,而不是先判斷
puts "輸入 5 才能退出喔" #讓電腦印出問題
input = gets.chomp.to_i #讀取使用者的輸入,用 to_i 轉成整數
end while input != 5 #判斷式寫在最下面,只要 input 不等於 5,我就回到上面繼續執行
Symbol (符號)
# 宣告時在前面加 : 符號,可以想像成識別符號
:name
# symbol vs string
#string 可以被改變,但 symbol 不能被改變
"hello" + " world"
# =>"hello world"
:hello + :world
# => NoMethodError: undefined method '+'
Array (陣列)
# 陣列(array)是一種資料結構,可以把它想像成儲存許多值的清單,你可以:
arr = [1,2,3,4,5,6,7,8,9] # 把 1 到 9 存在 arr 這個陣列裡
# 也可以在裡面塞很多不同型別的資料:
arr2 = [0.3, "ntu rails", 4]
# 你也可以在 array 裡面塞另一個 array:
arr3 = [1, 2, [3,4]]
Array (陣列)
# 今天我若要把 array 的最後一個值刪掉:
arr = [1,2,3,4,5,6,7,8,9]
arr.pop
# 就會把 9 移除
# 若要把 9 加回 array 最後面:
arr.push(9)
# 也可以這樣寫:
arr << 9 # 非常簡潔易懂
Array (陣列)
# 我想檢查一個 arr 裡是否存在 5:
# 可以用 include? method
arr = [1,2,3,4,5,6,7,8,9]
arr.include?(5)
# 5 存在,所以會回傳 true,相對的
arr.include?(18)
# 會回傳 false
Array (陣列)
# 今天我要取得Array裡面儲存的值時,就需要他的索引值(index)
arr = [1,2,3,4]
arr[1]
# =>2
# 注意索引值是從 0 開始算起
arr = [1,2,3,4,5,6,7,8,9]
#索引值: 0 1 2 3 4 5 6 7 8
#所以我要是希望在 arr 裡面取得 1:
arr[0] = 1
#就需要去index 為 0 的地方取得
#若是要刪掉 index 為 2 的值
arr.delete_at(2)
#然後 arr 裡面的 3 就被刪掉了
[1,2,4,5,6,7,8,9]
Array (陣列)
#今天我若要改變 array 裡面所有的值,像是把所有值加上 2
arr.map {|x| x + 2} #使用 map 方法,x 代表每一個值
# 執行後,就會得到:
[3, 4, 5, 6, 7, 8, 9, 10, 11]
# 但這不會改變 arr 裡面原本的值,但若我們用 map!
arr.map! {|x| x + 2}
# 再查看一次 arr,此時 arr 就被改變了
arr = [3, 4, 5, 6, 7, 8, 9, 10, 11]
# 任何加 ! 的方法代表呼叫該方法的物件最後會被改變
Array (陣列)
# 今天我想過濾出一部分的值
arr = [1,2,3,4,5,6,7,8,9]
arr.select {|x| x > 5}
# 會把所有大於 5 的值找出來
[6, 7, 8, 9]
# 也有另一個方法,reject 會把不需要的值排除掉
arr.reject {|x| x < 6 }
?與!的慣例
# Ruby 的 method 名稱可以用?或!結尾,前者表示會回傳Boolean值,
# 後者暗示會有某種副作用(side-effect),通常是指會改變 caller 原本的值:
arr = [1,2,3,3,4,5,5]
arr.uniq
=> [1, 2, 3, 4, 5]
arr
=> [1, 2, 3, 3, 4, 5, 5]
# 使用非 ! 的 uniq,原本呼叫他的 arr 並沒有變動
arr.uniq!
=> [1, 2, 3, 4, 5]
arr
=> [1, 2, 3, 4, 5]
# 如果使用 uniq!,arr 得值則會被被改變
Block (區塊)
# 之前我們在 array 裡的範例:
arr = [1,2,3,4]
arr.map {|x| x + 2}
# 這邊特別注意,包在大括號 { ... } 以及 do ... end 裡面的程式碼,
# 在 Ruby 語言裡稱為一個程式碼區塊 (Block)
# 簡單來說 block 像是一小段可以被丟到方法裡執行的 code
# 但是它並不是參數、也不能單獨存在...
{ puts "Hello, Ruby" } # 這樣會產生語法錯誤
action = { puts "Hello, Ruby" } # 這樣也會產生語法錯誤
# 必須依附在其他的方法或物件下
5.times { puts "Hello, Ruby" }
取得使用者輸入
# 取得使用者在 command line 上面輸入的值
input = gets.chomp
Debugging
# 使用一個叫做 pry 的套件
gem install pry
# 在每一個 .rb 檔最上面加上
require 'pry'
練習題:計算機
用 Ruby 寫出一個簡單的計算機程式
Hash (雜湊)
# 另一種資料結構,可以把他想像成置物箱,每一個值(value)會對應到一個鑰匙(key)
person = {
:name => "Bob",
:age => 30,
:occupation => "Engineer"
}
# 在上面的範例,:name, :age, :occupation 是 key,"Bob", 30, "Engineer" 是 value
# 因為 symbol 是 immutable (不能被改變的),所以很適合用來當做 key
# 若我要取得某個 value,我需要它的 key
person[:name]
# => "BOb"
Hash (雜湊)
# ‘=>' 符號叫做 hashrocket,是 hash 用來 assign 值所使用的符號
# 但是 Matz 老大認為 hashrocket 讓 hash 看起來太醜了...
# 所以出現了一種新的 hash 宣告方式
person = {
name: "Bob",
age: 30,
occupation: "Engineer"
}
# 目前 Ruby 是兩種寫法都支援
Range (範圍)
# range 可以聯想成範圍
1..10 #代表 1 到 10
# 另一種 range
1...10 #(中間有三個 ...) 代表 1 到 9
# 放進 irb 執行:
# irb(main):003:0> (1..10).to_a #把它轉成 array 比較容易看懂
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 1 到 10
# irb(main):004:0> (1...10).to_a
# => [1, 2, 3, 4, 5, 6, 7, 8, 9] # 三個 . 的範圍只從 1 到 9
Random(隨機)
# 我們有些時候會需要電腦幫忙產出隨機數(可以想像成骰子),ruby 就有提供一個這樣的一個功能:
rand(1..100) #會產生出一個介於1到100之間的隨機數,記住裡面要放入的是一個 range
# => 33
# => 87
# ...
# array 也有類似的功能, .shuffle (洗牌)
arr = [1,2,3]
arr.shuffle!
# => [1, 2, 3]
arr.shuffle!
# => [3, 2, 1]
arr.shuffle!
# => [1, 3, 2]
arr.shuffle!
# => [3, 2, 1]
# 記住 shuffle! 和 shuffle 的差別在於只有 shuffle! 會改變 arr 的資料
Random(隨機)
# 另外一個用 Array 產生隨機樹的方法: .sample
arr = [1,2,3]
arr.sample
#=> 1
arr.sample
#=> 3
arr.sample
#=> 2
arr.sample
#=> 1
Homework 2
剪刀石頭布
NTU ROR 第二課
By Eugene Chang
NTU ROR 第二課
- 2,122