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