電腦網路與作業系統 電腦網路與作業系統

電腦網路與作業系統上課教材

電腦網路與作業系統 > 課程內容 > 第 04 章 - 學習 python - 使用雲平台

第 04 章 - 學習 python - 使用雲平台

上次更新日期 2024/03/09

程式語言的學習其實存在我們的生活當中,因為我們腦袋本來就一直在進行著選擇 (if) 與迴圈 (for) 等任務。 任何地方只要有瀏覽器就可以上網來撰寫簡單的程式碼,那就是學習 python。python 可以應用的場景非常多, 可以用在 AI 運算上面,也可以用在環工繪圖方面,因為 python 有太多的外部函數可以使用,應用面非常廣。 我們可以不用安裝 python 軟體,直接透過 google 雲端平台,就可以學習 python 了。

學習目標

  1. 建立第一隻 python 程式與執行它
  2. 設計變數功能
  3. 簡易的數值運算
  4. python 的 if 條件判斷
  5. python 的 for 與 while 迴圈學習

4.1: 使用 python 腳本與執行

傳統的程式語言,如 C, java, fortran 等,都需要透過『編譯』之後,才有辦法執行程式碼。許多新的程式語言,包括 javascript, PHP, python 等, 屬於直譯式程式語言,基本上,我們可以稱為『腳本』,將許多功能寫在一起,變成一整串人類可讀的程式碼, 透過外部程式的執行,即可進行運作!不需要重新編譯。雖然效能方面可能無法跟傳統程式語言比,但是, 可讀性、可攜性、便利性就變得很好!因此,許多的功能,漸漸都朝向這方面的語言靠近。

python 有很多可用的外掛模組,可以直接應用到樹莓派上,因此,熟悉 python 對於樹莓派來說,也是很重要的。 那我們需要樹莓派嘛?也不需要,可以使用你的 google 帳號,在瀏覽器上面登入 google 之後,連線到底下的網址, 就可以使用雲端平台來學習 python 了!

python 使用 colab

如上,登入之後,系統會提示你,是否要選用舊的程式碼 (在此平台中,稱為筆記本),如果沒有任何筆記本,那就按下上圖中的『新增筆記本』 即可。然後會出現類似底下的畫面:

python 使用 colab
  • 1 的地方是檔名,你可以將檔名取為較容易記憶的名字
  • 2 是顯示左側選單的按鈕
  • 3 是顯示目前可用檔案的按鈕
  • 4 是增加新的程式區段
  • 5 是可以直接撰寫程式碼的區段

基本上, python 撰寫時,記得你的副檔名最好都寫成 OOXX.py,檔名最好都用英文與數字加上底線的組合,不要用中文或其他特殊符號比較好。 不過,我們是使用雲端平台,這個平台當中的檔名都必須要儲存成為 .ipynb 才行!同樣的,檔名盡量也是使用英文搭配底線就好。

  • 第一隻 python 程式,印出哈囉 python

使用 print("字串") 這個程式碼功能,就可以在螢幕上列出你要輸出的字串!寫程式第一隻通常就是哈囉世界 (hello world), 讓我們來玩一玩!檔名就稱為 hello.py 好了。

# 4.1.1
# 這個 # 是註解
print("Hello Python")
python 使用 colab

程式碼撰寫完畢要執行時,如同上面的圖示,你只要點下第 2 個箭頭處,就可以得到 3 區段的顯示資訊! 在 python 程式裡面,所有在 # 後面的資料全部是註解!所以,你可以在程式腳本裡面增加一些註解,讓自己以後知道該程式的用途。 至於執行的方法,直接以『 python filename.py 』的方式來執行即可!另外,還是得要再次強調,每一行程式碼都得要對齊, 然後,如果有特殊的函數或相關的迴圈判斷式,就得要縮排!否則會出問題!

另外,如果是字串資料,則字串頭尾都需要使用雙引號來處理,否則就可能是變數名稱或者是數值型態的資料喔! 這點得要特別注意!

  • 使用變數

包括在未來我們可能會使用到的許多感測器模組,大多會使用變數的方式來提供使用者取得感測器的數值。 那什麼是變數?基本上,就是一個數學式!只是,等號的兩側中,左側永遠是未知數 (變數名稱),右側則是已知數 (變數內容)。 舉例來說,假設有公式『 y = a*x + b 』的話,那 y 這個變數可以是未知數,但是 a, b, x 就必須要先指定! 不然,式子就會發生錯誤喔!另外,我們也可以透過 print 去印出來結果!

# 4.1.2
# 開始計算 y = a*x + b
mycal = "y=a*x+b"
x = 3
a = 5
b = 10
y = a * x + b

print (mycal)
print ("嘗試計算:"+mycal)
print (y)
print ("y =", a, "*", x, "+", b, "=", y)

執行成果會有點像底下這樣的輸出:

y=a*x+b
嘗試計算:y=a*x+b
25
y = 5 * 3 + 10 = 25

如同一開始說的,等號兩邊左側是未知,右側是已知,所以左邊是變數名稱,右邊是變數值,這真的要搞清楚喔! 另外,字串也是可以相加的,如果一串相加的資料裡面有一個是字串,那整串都會變字串輸出。當然, 過程中很可能會有數值相加減的! print 是很萬用的輸出指令,在括號內的參數,可以是變數, 也可以直接用加號 (+) 將資料進行累加,也可以將每個變數用逗號 (,) 分隔來輸出,很多變化!

  • 特別的變數設定方式

變數名稱盡量使用英文與數字加上底線的組合,其他的符號都不要使用。另外,變數名稱開頭不能是數字, 這得要留意才行!此外,python 真的很人性化,它變數的設定方式還能有底下的特殊方式喔!

# 4.1.3
# 開始計算 y = a*x + b
mycal = "y=a*x+b"
print ("嘗試計算:y=a*x+b")
x, a, b = 3, 5, 10
y = a * x + b
print ("y =", a, "*", x, "+", b, "=", y)
x = a = b = 15
y = a * x + b
print ("y =", a, "*", x, "+", b, "=", y)

執行成果會有點像底下這樣的輸出:

嘗試計算:y=a*x+b
y = 5 * 3 + 10 = 25
y = 15 * 15 + 15 = 240

上面的範例中,一個等號兩邊可以同時塞多個變數與變數值,python 會主動幫你設定好!如果變數內容相同, 那可以使用第二種方式來處理!相當有趣!另外要注意,程式當中出現兩次 y=a*x+b,這是因為兩次的 a, x, b 數值有改變, 所以當然要重新計算!要注意!要注意!

再寫一小段程式碼,快速的計算一下 BMI 的數值。BMI 的計算為:『體重(公斤) / 身高2(公尺2)』。 建議你在程式碼當中輸入數個變數: myw 為體重,單位為公斤, myh 為身高,單位為公分, bmi 就是上述的計算。 最後輸出的結果會有點像:
你的身高: 176 公分
你的體重: 70 公斤
你的 BMI: 22.5

4.2: 使用 if ... else 進行條件判斷與使用 datetime 模組

寫程式碼,最需要學習的其實是邏輯概念。一般來說,邏輯就是判斷對與否 (true and false),對要做什麼,不對則要做什麼這樣。 就跟人腦一樣,會判斷是否要進行。不過,程式比較笨,大部分的時候,只會判斷『對』或『錯』而已,沒有模糊空間囉。 那如何進行對錯呢?使用 if (如果) 搭配 else (別的, 要不然) 即可。

# 4.2.1
myday = 'monday'
if myday == 'monday':
  # 是星期一的時候
  print ("感到非常 blue")
else:
  # 不是星期一的時候
  print ("就是努力工作")

執行結果會有點像:

感到非常 blue

你可以將 myday 的內容由 monday 改成 tuesday, wednesday, thursday, friday, saturday, sunday 等。但,其實只有判斷是不是星期一而已... 真是有點不太準確...無論如何,要注意的是,if 後面加的是邏輯判斷式,並不是變數給予,因此,會有兩個等號!if 的結尾 (同一行最右邊) 並不是括號,而是冒號 (:),下一行開始是 if 的子程式碼,因此需要縮排!縮幾格不是重點,有縮排就好!之後與 if 同層級的程式碼則是 else,同樣的,結尾需要有冒號,其下的程式碼則同樣是需要縮排!至於邏輯判斷經常使用的運算子則有:

  • X == Y
  • X != Y
  • X < Y
  • X <= Y
  • X > Y
  • X >= Y

運算子的比較,不是只有數值喔,字串也是可以比較的!只是,上面的案例有點怪~因為我們竟然手動輸入禮拜幾~好怪! 明明電腦就有時間啊!能不能讓系統自動帶入時間呢?可以的!只是,需要匯入額外模組才行!

  • 匯入並使用 datetime 模組

python 有非常多的外掛,其中一個重要的外掛,就是日期時間模組。要使用這個模組時,就得要先匯入模組資料才行! 使用的方法有點像這樣:

# 4.2.2
# 先匯入模組,並成為 datetime 物件
import datetime

# 設定一個變數,使用 datetime 物件,該物件內使用 datetime 函數, now 為該函數功能之一
#       物件名  .函數名  .功能之一
myday = datetime.datetime.now()

# 印出目前時間
print(myday)

# 印出目前是星期幾
print(myday.strftime("%w"))

# 印出該項目的變數類型
print(type(myday.strftime("%w")))

執行的結果有點像這樣:

2022-10-17 09:50:47.877555       <==日期與時間
1                                <==星期幾
<class 'str'>                    <==變數的類型為字串

這個日期模組挺有趣的,我們要先以 import 的方式『匯入』這個模組,如果你都沒有指定任何的別名, 那麼就直接拿這個模組名稱當成一個物件來處理。那個 now() 就是『現在這個時間點』的功能,如此, 就可以將這個日期推論出來。只是,最終並不是我們需要的禮拜幾。有興趣可以看一下文末的參考資料, 我們這邊可以直接說,我要取出星期 0~6 (星期 0 是星期天的意思),那就可以使用上面的 myday.strftime("%w") 來處理! 那個 strftime 可以解釋成『 string from time (時間轉成字串)』的概念,比較好記憶。

  • 日期結合條件判斷,自動判斷星期幾

來改變一下我們剛剛的條件判斷式吧!

# 4.2.3
import datetime                      # 匯入時間模組

myday = datetime.datetime.now()      # 取得目前的時間
wday  = int(myday.strftime("%w"))    # 由上面的變數取得星期幾

if wday == 1:                        # 調查是不是星期一
  # 是星期一的時候
  print ("感到非常 blue")
else:
  # 不是星期一的時候
  print ("就是努力工作")

執行的結果有點像這樣:

感到非常 blue

這樣看起來算是比較合理的狀態!

  • 使用 if ... elif ... else 進行多重條件判斷

再仔細想想,剛剛的範例還是不太合理~如果是星期六、日,明明就可以休息,結果竟然寫需要努力工作!不太恰當... 所以,我們應該要判斷特別的星期一,普通的星期二到星期五,假日的星期六日。因為會有複合的運算子,因此就得要有 and 以及 or 的支援! 同時,多重條件判斷,就需要 elif (else if 的縮寫) 的支援!所以,上面 if 的範例,進一步變成這樣:

# 4.2.4
import datetime

myday = datetime.datetime.now()
wday  = int(myday.strftime("%w"))

if wday == 1:
  # 是星期一的時候
  print ("感到非常 blue")
elif wday >=2 and wday <=5:
  # 星期二到五要努力
  print ("就是努力工作")
else:
  # 不是星期一到五,當然就是假日
  print("好好玩、好好休息、好好充電")

需要測試的話,可以在 wday 底下額外指定 wday = 0 之類的方式來測試!測試完畢就可以註解該行!這樣, 才有辦法處理程式碼的確認~否則,難道真要每天運作?哈哈!那是沒道理的!因此,很多時候,你會發現, 程式設計過程中,許多的『測試』得要花費心思去處理!另外,python 真的很有趣!它可以跟人類寫的判斷式一樣, 使用如下的方法來處理:

#elif wday >=2 and wday <=5:
elif 2 <= wday <=5:

不過,這種寫法畢竟好像只有特殊的腳本程式語言才支援,一般還是透過 and 或者是 or 連結兩個條件判斷處理, 建議還是不要使用這種偷懶的方式處理啦!呵呵!

請參考下面的網站,去了解 strftime() 裡面的相關意義,例如 %w 是列出星期幾的數值,不過,請找出類似 Sunday, Monday 等星期幾的名字,而不是數值。 請修改 4.2.4 的腳本,最終在上述的星期判斷中,先列出日期資料,例如;
今天是:2024-03-09 (Saturday)
好好玩、好好休息、好好充電

4.3: 使用 for 迴圈搭配數值 range() 與字串陣列

如果你要算一大堆連續的資料,總不會一筆一筆數字輸入吧!那有沒有辦法『連續輸出一串數值』呢?可以的!使用 range 即可! 這個 range 的使用方式大致上是這樣:

range(10)       # 代表 0, 1..., 9,注意,是 0 到 9 ,不含 10 喔!
range(10,16)    # 代表 10, 11..., 15,不含 16 喔!
range(0,101,5)  # 代表 0, 5, 10...100,間隔為 5 喔!

也就是說,range 預設的起始數值是 0 ,而預設的步階 (step) 是 1,除非你有額外指定,否則數值如上所示。 所以,如果你要輸出 1...9 的話,使用 for 迴圈來搭配 range 的使用即可。那麼 for 是什麼呢?基本上, for 就是指定一個變數,該變數可以進行好多次,次數由 range 來指定的意思!

# 4.3.1 開始使用 for 迴圈
for i in range(1,10):
  print(i)

執行的結果會有點像這樣:

1
2
...
9
  • 巢狀迴圈進行九九乘法表

計算九九乘法表列表,不用格式排列漂亮,很簡單的處理!

# 4.3.2
for i in range(1,10):
  for j in range(1,10):
    print( str(i) + ' x ' + str(j) + " = " + str(i*j) )

執行的結果會有點像這樣:

1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
....
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81

在 print 的輸出中,所有資料的格式需要相同,才可以使用 + 來累加!所以,我們得要將 i 與 j 純數值轉成字串,使用 str(i) 的方式來轉! 這樣就 OK 了!可以格式化輸出一堆資料哩!

  • 字串使用陣列的迴圈方式

數值可以透過 range 來提供,那文字呢?基本上,文字或數值,都可以透過陣列來處理。要注意的是, python 的陣列格式非常多樣! 我們使用單純的 list 格式處理!假設星期一到星期五學校午餐湯品要依序列出,那可以這樣處理:

# 4.3.3 了解陣列
soup = [ "牛蒡雞湯", "玉米蛋花湯", "芹菜餛飩湯", "薑絲海苗湯", "綠豆薏仁湯" ]
i = 0

for ss in soup:
    i=i+1
    print("星期 " + str(i) + " 喝的湯:" + ss)

執行的結果會有點像這樣:

星期 1 喝的湯:牛蒡雞湯
星期 2 喝的湯:玉米蛋花湯
星期 3 喝的湯:芹菜餛飩湯
星期 4 喝的湯:薑絲海苗湯
星期 5 喝的湯:綠豆薏仁湯

陣列 (list) 使用中括號包含數個字串,字串間以逗號 (,) 隔開即可!另外,如果要快速的找出第 3 號 (從 0 開始編號喔! 所以會是第四個 "薑絲海苗湯" 的顯示) 湯品,也能使用 soup[3] 來表示!

請結合前面的 timedate 日期函數功能,直接根據今天是星期幾,然後就列出該日要喝的湯品,執行結果應該有點像這樣:
今天是:2024-03-09 (Saturday)
本日湯品:隨便喝湯

4.4: 使用 while 迴圈搭配 break 與 continue 功能

相對於 for 迴圈算是固定次數的迴圈,while 迴圈則通常需要搭配判斷式來處理,亦即,只有在條件規範的環境內, 才會進行迴圈,否則就不會進行迴圈這樣的意思!我們先來做個簡單的處理,例如要算出 10! 這個 1x2x3...x10 的數值, 如果用 while 時,可以這樣計算:

# 4.4.1
i=1
j=1

while i <= 10:
  j = i*j
  i=i+1

print(j)

執行的結果會有點像這樣:

3628800
  • 使用內部 continue 與 break 進行 while 控制

除了指定限制之外,我們也可以在 while 迴圈使用兩個控制參數來處理!

  • continue:直接跑去下次迴圈,本次迴圈中止
  • break:結束 while 的迴圈運作

舉例來說,我們要輸出星期一到星期七(就是星期天),但是星期三不輸出,那可以這樣進行:

# 4.4.2
i = 0

while True:
    i=i+1
    # 星期三不要輸出
    if i == 3:
        continue
    print ("星期 " + str(i))
    # 已經 7 天了,結束輸出
    if i >= 7:
        break

print("結束輸出")

執行的結果會有點像這樣:

星期 1
星期 2
星期 4
星期 5
星期 6
星期 7
結束輸出

因為 while 後面接了 True,這代表 while 迴圈如果沒有控制的話,那就會一直跑下去.... 因此後續加上 continue 與 break 來限制,才有辦法將 while 迴圈中斷呢!

請先查看一下底下這個網站的介紹,重點在理解 input 這個程式碼的功能: 寫一個 while 迴圈,提示使用者輸入 yes 或 no。當輸入 yes 時,顯示『程式繼續其他工作』,然後結束。當輸入 no 時, 顯示『程式中斷』然後結束,如果不是 yes 或 no,就繼續要求使用者輸入 (continue)。執行結果會像這樣:
請輸入 yes, no: qq
請輸入 yes, no: hah
請輸入 yes, no: yes
程式繼續其他工作

4.5: 使用 Matplotlib 做簡易繪圖

python 可以透過 Matploblib 這個模組進行繪圖功能!繪製的圖示相當多!可以是 XY 散佈圖、折線圖、柱狀圖與圓形圖等等,功能相當龐大! 現在,就讓我們來測試一下!

  • 安裝 Matplotlib 與初次匯入模組

Matplotlib 是個非常有趣的模組,它可以讓我們透過 python 配合數據來簡易的畫出需要的圖示!常見的圖示當然是 X, Y 分佈圖。 現在,先讓我們將模組安裝起來!請在 colab 網頁上面進行如下的動作:

pip install matplotlib numpy

因為這個模組會用到其他很多額外的模組,所以安裝過程會比較冗長!請稍待一陣子。另外,因為許多圖示都會用到數值陣列, 所以最好確認一下安裝了 numpy 這個模組!安裝完畢之後,我們先來繪製一個簡單的圖示。假設有底下 5 個 (x, y) 數值:

(  5,  6 )
( 10,  9 )
( 15, 17 )
( 20, 21 )
( 25, 25 )

想要繪製出正確的圖示,你應該要這樣處理繪圖腳本:

# 4.5.1
# 匯入 matplotlib 的 pyplot ,並且取名為 plt ,方便應用
import matplotlib.pyplot as plt
import numpy as np

xps = [ 5, 10, 15, 20, 25 ]
yps = [ 6,  9, 17, 21, 25 ]
xps = np.array(xps)
yps = np.array(yps)

plt.plot(xps, yps)
plt.show()
plt.close()

執行成果會有點像底下這樣:

python 使用 colab

如果想要讓每個點都出現圓點,可以將 plt.plot 那一行改成這樣:

plt.plot(xps, yps, marker='o', markersize=5, color='b')

執行成果會有點像底下這樣:

python 使用 colab

更多的圖示可以自行找尋 matplotlib 的相關網頁來處理。

4.6: 課後練習

作業上傳時的注意事項:

  1. 伺服器的詳細資料,以及相關傳輸軟體設定,請參考第一章的 1.5 節的內容。
  2. 可以使用 MS office 的 word 或者是 libreoffice 的 writer 等軟體來撰寫你的作業,作業檔名可以使用 .doc, .docx 或者是 .odt 或者是 pdf 等格式,均可接受。
  3. 若作業中有圖檔,請將圖檔降低水平解析度到 800 像素以下再貼到文章中,檔案容量以不超過 2Mbytes 為限。
  4. 檔名請設定為: os_4XXXCYYY_unit04-2.doc (4XXXCYYY 是你的學號,請填正確,有分大小寫,請確認)
  5. 請上傳到你家目錄底下的 os 目錄中 (若不存在,請自行建立該目錄)

開始本章節題目:

  1. 參考底下這個網站的 BMI 數值依據: 撰寫程式碼,類似 4.1 之後的小節。計算出 BMI 之後,根據上述網站的說明,以 if 等方式,說明體重情況是否正常。 執行結果會有點像這樣:
    你的身高: 169 公分
    你的體重: 73 公斤
    你的 BMI: 25.559329155141626
    體重過重
    
    請將瀏覽器的程式碼與執行結果截圖貼成 os_4xxxcyyy_unit04-1.jpg 檔名後,上傳到伺服器即可。
  2. 請參考底下這幾個網站的連結: 模擬前一堂課程當中繪製圓餅圖的方式,請使用 2024 年大選的投票結果 (民國 113 年,全國不分區的得票數結果), 使用 python 繪製圓餅圖,因為 google 雲端平台不支援中文,請將 wiki 頁面轉成英文,並且複製每個政黨的英文, 然後開始繪製圓餅圖。最終圖示會有點像這樣:
    python 使用 colab 請將程式碼、圓餅圖截圖,轉存成為 os_4xxxcyyy_unit04-2.jpg 檔名後,上傳到伺服器即可。
  3. 請參考底下的連結: 使用前一堂課程的 excel 檔案內容,取出台南市的 EPA 與 M3 數據,繪製成為 XY 散佈圖,最終的圖示內容會有點像這樣:
    python 使用 colab 請將程式碼、圓餅圖截圖,轉存成為 os_4xxxcyyy_unit04-3.jpg 檔名後,上傳到伺服器即可。