條件式&迴圈整理 === **作者 - 彭彥菱 編輯 - BESTCI跨域人才程式能力培育計畫 / NTU BESA** **項目** ==for loop (basic & nested & advanced )== ==while loop (basic & advanced & sentinel)== ==Conditions (if / else & Cascading if )== **共筆內容** **課程重點** * for loops (basic) * while loops (basic) * coditionals * advanced loop (while True) * for loop - range * nested for loop **課程範例** * 終極密碼 * 找到最大值 --- ## 課程重點 在程式語言的世界裡重複咒語有兩種,for 跟 while loop,那這兩者到底有甚麼不同呢? ### 1. for loop (definite loop) 需要執行的次數:**已知** 依據問的問題,得知需要執行迴圈的次數。 **Basic For Loop** ```python= for i in range(99): # 括號內的數字表示迴圈執行的次數 | | 重複區間 | | ``` **Nested Loops 巢狀迴圈** (Lecture5) ### 2. while(Indefine loop) 需要執行的次數:**未知** 依據問的問題,來判斷要執行的動作,但不知道實際要執行的次數。 **Basic while loop** ```python= while condition(): | | Yes 區間 | | |No 區間| ``` **Bugs for while loop (Fencepost Bug)** * Infinite loop 需注意無限循環迴圈的情況 * 執行大於檢查 * OBOB (Off-By-One Bug) :::info 在做while for loop時,最常出現缺頭或缺尾的bug 解決方案: 在執行loop前或後,多執行一次。 ::: 舉例說明: 一個fence posts 的組成,會需要一個panel,兩個fenceposts,而fenceposts的數量會比panel多一個。 ![](https://i.imgur.com/XuEoVhw.png) 這就像是Karel要從(1,1)移動到盡頭(1,7),並放置一整排的beeper,會遇到的狀況是,當Karel走到最後一格時,是面對牆壁(`front_is_not_clear`),並不會放一顆beeper,所以我們要在while loop的No區間,多一行`put_beeper()`,才會放滿第一行的beeper,達成任務。 ![](https://i.imgur.com/C4z5jN5.png) ### 3. Conditions (Yes / No) 條件式的基本架構會從問題出發。 **Basic Conditionals** ```python= if condition(): | | Yes區間   | | else: | | No區間   | | ``` **if statement 擇一執行** 因為if跟else會共用一個condition,所以else就不用在加condition,而if的Yes區間一定要有code,No區間就不一定要有code,若進入no區間則會直接結束這個條件式,若不執行任何動作,直接輸入`pass`。 **如何判斷 if / while 使用時機?** if-else跟while loop不同的是,while會執行很多次,不斷地詢問,直到跳出loop,移到No區間為止,而if-else只會執行一次。 * nested if: 若是if內縮排再使用if,則是「滿足兩個條件的交集」才會執行。 * 2 if in arow: 若在if相同縮排處變成會「一定檢查」 **Advanced if statement** 這裡舉個例子來說明Advanced if statement的觀念,假設我們希望Keral可以移動到beeper上,並且撿取beeper,應該要用哪個if statement做會比較適合呢? ![](https://i.imgur.com/wB9CtME.png) * **nested if**: 取兩個if條件的交集 > Karel撿取beeper需要同時滿足兩個條件,1. 前方是空的 2. 人需站在beeper上面,才會執行`pick_beeper` ,`move()`這些動作。 ```python= if front_is_clear(): if on_beeper(): pick_beeper() move() ``` * **2 if in arow** 兩個if的條件都會被檢查到,會執行符合的條件 > Karel的前方只要是空的,就會往前移動一格,只要是站在beeper上面,就會撿取beeper。 ```python= if front_is_clear(): move() if on_beeper(): pick_beeper() ``` ### 4. advanced loop (while True) while True不會擋任何迴圈,不管如何一定會進入這個迴圈。 若在執行迴圈時,遇到某些狀況需要停止,會使用`break`來跳出迴圈。 > 可以參考後面的課程範例: 終極密碼 (while True) ```python= while True: break ``` 若在執行迴圈時,遇到某些狀況想要略過特定狀況,會使用`continue`。 ```python= while True: continue ``` ### 5. for loop - range - 要如何判斷迴圈會跑幾次? - *i* 是variable(迴圈編號),存了甚麼? - zero-index: 程式通常從[0]開始編號 **range(start,stop,step)** > start是起始值,stop是終止值,step是間隔值 先來看幾個例子: * one argument ```python= end = 5 #上限不包含 for i in range(end): # 0,1,2,3,4 ``` * two arguments ```python= start = 1 #下限包含 end = 5 for i in range(start,end): # default step = 1 # 1,2,3,4 ``` * three arguments ```python= start = 1 end = 11 step = 2 for i in range(start,end,step): # 0,1,3,5,7,9 ``` ![](https://i.imgur.com/P82Eki0.png) (ref from https://www.pythonclassroom.com/loops/for-loop-range-one-argument) ### 6. Nested for loop double variable要注意變數不重複 使用Nested loop印出以下圖形: ``` #### #### #### ``` ```python= ROWS = 3 COLS = 4 for i in range(ROWS): # 總共列數 for j in range(COLS): # 總共欄數 print('#', end ="") #印出4個連續的# print("") # 印出空字元=換行 ``` 那來試試看階梯變形版的圖形 ``` # ## ### ``` 這裡需要思考的是,當每次進入loop時,印出的`#`需要遞增1個,所以會使用`for j in range(i+1)`。 當跑第一圈時,`i = 0`代入,會得到`for j in range(1)`,第一列會印出`#`,跑第二圈時,第二列會印出`##`,以此類推。 ```python= for i in range(3): #總共三列 for j in range(i+1): #每印下一列增加1 print('#', end ="") print("") #換行 ``` 如果`for j in range(i+1)`改成`for j in range(3)` 或 `for j in range(1,4)`會印出滿版的九宮格的#圖樣。 ``` ### ### ### ``` 來試試看用Nested loop印出checkboard吧! ``` # # # # # # # # ``` 建議可以先觀察`#`所在位置,剛好都是在ROW與COL相加除以2的位置,取餘數為0的位置。 ```python= ROWS = 4 COLS = 4 for i in range(ROWS): for j in range(COLS): if (i+j)/2 == 0: print("#", end = "") else print("", end = "") print("") ``` ## 課程範例 ### 1. 終極密碼 Basic while loop ```python= # This number controls when to stop the game SECRET = 45 # Basic while loop def main(): print("Guess a number from 0-99: ") guess = int(input("guess: ")) while guess != SECRET: if guess > SECRET: print("Too high") else: print("Too small") guess = int(input("guess: ")) print("Congrat!!!") ``` 用進階loop迴圈`while True`的寫法,並使用`break`。 ```python= # advanced while True loop def main(): print("Guess a number from 0-99: ") guess = int(input("guess: ")) while True: if guess > SECRET: print("Too high") elif guess == SECRET: break else: print("Too small") guess = int(input("guess: ")) print("Congrat!!!") ``` ### 2. 找到最大值 ```python= # This constant controls when to stop EXIT = -1 def main(): """ This program find the maximum among user inputs """ print('This program finds the maximum!') data = int(input('Your Data: ')) if data == EXIT: print("No number!") else: maximum = data while True: data = int(input('Your Data: ')) if data > maximum: maximum = data elif data == EXIT: print(maximum) break ```