# 控制程式流程:迴圈 ## 電腦的存在是為了幫人類解決繁雜工作 電腦的存在是為了為人類解決繁雜工作,所謂的重複工作,在這裡我們定義成: - 有特定的變數 - 有既定的流程 其中既定流程又包括有預定的事件執行次數與條件,如下圖。 ![](https://i.imgur.com/BF3vDEz.png =400x250) 這一章要談的就是,如何讓程式按照你指定的次數被執行。 ## 迴圈 先從一個生活例子開始談,想像你在一間的學校操場跑步,每天都要跑五圈。 ![](https://i.imgur.com/NuLxeq8.png =350x300) 如果把這件事規格化,那麼就可以拆成跑步的順序跟次數,所以就寫成: - 執行動作:從某點移動至某點 - 執行順序:A-B-C - 執行次數:5個回合 接著我們用Python程式語法來表示這件事,在Python,定義了兩種跟程式執行次數有關的語法,分別是`for loop`和`while loop`。 ### For 迴圈(For Loop) #### 定義次數 如果你知道要執行幾次,可以使用以下語法 ```python= for 變數 in range(start, end, step): ``` 例如 ```` python= for i in range (0, 5, 1): #執行A行為 #執行B行為 #執行C行為 ```` 這段程式碼,是讓A,B,C這三個行為依序被執行,並且執行五次。 在`for`後面的變數`i`,在這裡被宣告。 接著變數`i`會根據後面的`(0, 5, 1)`進行值的變化,依序是**起始參數(start)**、**終止條件參數(end)**、**Step參數**。 以這個例子來說,起始參數0將i的初始值設為0;終止條件參數5是這個迴圈的終止條件,當變數`i`>=5時,離開此迴圈;Step參數1是變數`i`每個回合加上的值。 根據以上定義,這樣的迴圈寫法,會讓這個迴圈執行5次,也就是分別是i=0,1,2,3,4這五個回合。 #### 掃描資料結構 for迴圈語法還有一個很常見的用法 ```python= for i in 資料結構: ``` 資料結構包括前面介紹的`List`, `Tuple`, `Set`, `Dictionary` 如此一來,i就會走遍資料結構中的元素,並且儲存起來 例如 ```python= student_list = ["Chaoyen", "Joanne", "Manchester"] for student in student_list: print(f"{student}") ``` 將list中的元素,一一讀取出來並輸出結果。 ### 隨堂練習 全班的成績如下表所示,請設計一個程式來計算全班**數學科平均成績**,並使用以下設計原則 - 使用`Dictionary`跟`list`儲存全班資料 - 使用`for loop`讀取全班數學科成績 | 姓名 | 國文科 | 英文科 | 數學科 | | -------- | -------- | -------- | -------- | | Chaoyen | 80 | 87 | 67 | | Joanne | 76 | 80 | 95 | | Manchster | 85 | 70 | 90 | :::spoiler 參考程式碼 ```python= student_score = { "Chaoyen":[80, 87, 67], "Joanne":[76, 80, 95], "Manchster":[85, 70, 90], } math_sum = 0 #儲存全班數學成績的累計 for score in student_score.values(): math_sum += score[2] print(math_sum/len(student_score)) ``` ::: ### While 迴圈(While Loop) ```` python= i = 0 while i < 5: #執行A #執行B #執行C i+=1 ```` 這段程式碼,也是讓A,B,C這三個行為依序被執行,並且執行五次。 但`while`,並不像`for`具備宣告效果,所以我們在前一行宣告變數`i`,並初始化為0。 `while`語法後面連接的,是這個迴圈的執行條件,只要符合執行條件,這個迴圈會一直被執行下去。 以這個例子來說,只要變數`i`小於5,就會依序執行行為A、行為B、行為C。 但我們希望這個迴圈執行五次就結束,所以我們在最後面加入`i+=1`也就是累加的動作,這樣經過五個回合後,也就是分別是i=0,1,2,3,4這五個回合,程式就會跳離這個while迴圈,繼續往下執行。 > i += 1 是 i = i + 1的縮寫 ### 隨堂練習 請分別使用`For Loop` ,`While`設計程式,達成以下需求: a. 依序印出10, 9, 8, 7, 6, 5, 4, 3, 2, 1 :::spoiler 參考程式碼 ```python= x = 10 y = 10 #使用for Loop for i in range(0, 10, 1): print(f"{x} ", end="") x -= 1 i = 0 print("") #使用while Loop while i < 10: print(f"{y} ", end="") y -= 1 i+=1 ``` ::: b. 依序印出2, 4, 6, 8, 10 :::spoiler 參考程式碼 ```python= x = 2 y = 2 #使用for Loop for i in range(0, 5, 1): print(f"{x} ", end="") x += 2 i = 0 print("") #使用while Loop while i < 5: print(f"{y} ", end="") y += 2 i += 1 ``` ::: ### 迴圈應用:優化LED專題 在之前的專題中,我們讓左邊第一行的LED,依序點亮第一到第五顆,然後熄滅,再重來一次。 接著需求變更,改成讓左邊第二行的LED,依序點亮第一到第五顆,然後熄滅,再重來一次 ```python= from microbit import * while True: display.set_pixel(0, 0, 9) sleep(1000) display.set_pixel(0, 1, 9) sleep(1000) display.set_pixel(0, 2, 9) sleep(1000) display.set_pixel(0, 3, 9) sleep(1000) display.set_pixel(0, 4, 9) sleep(1000) ``` 讓我們來看看,使用巢狀迴圈來改寫程式碼,是否可以更快速面對程式功能變更需求? ```python= from microbit import * while True: x = 0 y = 0 for i in range(0, 5, 1): display.set_pixel(x, y, 9) y += 1 sleep(1000) display.clear() sleep(1000) ``` 改寫結果如上,我們只需要改第四行,將x=0改為x=1,就可以滿足需求,更棒的是,不管未來要點幾顆燈,我們都可以用第七到第九行,來改寫點燈的範圍。 ## 巢狀迴圈 很多時候,我們在許多任務中,又可以在每個大任務中細分成許多小任務,所以在這裡我們介紹巢狀迴圈的觀念。 ![](https://i.imgur.com/Rxm0Kef.png =350x300) 回到我們一開始舉的生活例子開始談,想像你在一間的學校操場跑步,每天都要跑五圈,但跑到B點時,要做完3個回合B的子任務,才可以繼續往C點前進。 如果把這件事規格化,那麼就可以拆成跑步的順序跟次數,所以就寫成: - 執行動作:從某點移動至某點 - 執行順序:A-B(執行3個回合)-C - 執行次數:5個回合 用Python程式語法來表示,請參考以下範例: ```` python= for i in range (0, 5, 1): #執行A行為 for j in range (0, 2, 1): #執行B行為 #執行C行為 ```` 請注意執行A,B,C三個行為,程式碼其實是被分成三個區塊來看待,你必須非常了解每一個區塊,是怎麼透過你寫的for語法來決定執行次數,以及正確地被縮排,電腦才會幫你正確地執行程式。 ```` python= for i in range (0, 5, 1): #執行A行為 ```` ```` python= for j in range (0, 2, 1): #執行B行為 ```` ```` python= #執行C行為 ```` 當你無法掌握迴圈的控制時,請善用`print()`,掌握迴圈執行情況,例如 ```` python= for i in range (0, 5, 1): #執行A行為 print(i) for j in range (0, 2, 1): #執行B行為 print(j) #執行C行為 ```` 透過i,j值的輸出變化,你應該就會很清楚程式執行的順序,是否如你預期發生。 ### 巢狀迴圈的應用:電腦動畫 在程式設計中,是使用一個不斷執行的迴圈來更換一張又一張的圖,也就是`Frame`,來進行動畫繪製,一個典型的動畫迴圈如下所示: ``` while(true) { 繪製Frame 暫停指定秒數 改變動畫狀態 } ``` 其中改變動畫狀態視不同的程式而有所不同,也許只是單純的載入下一張影像,也許是由於使用者的操作而改變狀態。 請使用List宣告管理所有micro:bit LED,並且利用迴圈,畫出一個笑臉,如下圖所示 ![](https://i.imgur.com/133yI7Z.png) > 解決方案解析: > 1. 宣告List來管理所有LED的亮度,注意每個LED座標對應List的位置, > 2. 使用迴圈,根據宣告的LED亮度,點亮所有LED 參考程式碼如下: ```python= from microbit import * led_brightness = [ [0, 9, 0, 9, 0], [0, 0, 0, 0, 0], [9, 0, 0, 0, 9], [0, 9, 9, 9, 0], [0, 0, 0, 0, 0], ] x = 0 y = 0 for i in range(0, 5, 1): for j in range(0, 5, 1): display.set_pixel(x, y ,led_brightness[y][x]) y += 1 sleep(1000) x += 1 y = 0 ``` ## 未來持續學習 請充分理解語法,迴圈是程式設計中不可或缺的一環,因為電腦的主要工作,就是幫助人類進行重複性的工作。 很多人學習程式語言,遇到這個單元會陷入瓶頸,請多熟練迴圈次數的控制,分清楚**計數用**跟真正要**處理**的變數。 多看別人的程式,並且動手練習,是最好的方法。 ## 參考資料 Python官方文件 https://www.python.org/ ###### tags: `Python程式設計入門`