以下為此單元簡報。
https://drive.google.com/file/d/1x4yvJs3MlaLFsLkKfSAC8iGOEr7fyxJY/view?usp=sharing
以下為本單元的教學影片(放置於YouTube上),以下兩種方式擇一。
(A)以YouTube播放清單方式觀看影片,如下。
https://www.youtube.com/playlist?list=PLOk9WKoJdjHZ-ARc1E3cx01fexp-UCdpj
(B)以超連結方式觀看個別影片,如下。
Python 4-5-迴圈結構的流程控制break continue else
電腦每秒鐘可執行幾億次的指令,擁有強大的計算能力,程式中迴圈結構可以重複執行某個程式區塊許多次,如此才能善用電腦的計算能力。迴圈結構利用指定迴圈變數的初始條件、迴圈變數的終止條件與迴圈變數的增減值來控制迴圈執行次數。許多問題的解決都涉及迴圈結構的使用,例如:加總、排序、找最大值…等,善用迴圈結構才能有效利用電腦的運算能力與簡化程式碼。
假設要撰寫程式產生1000個「Hello」,若不使用迴圈結構需寫1000個「print('Hello')」,如下。
print('Hello')
print('Hello')
…
print('Hello')
需要1000個print('Hello')
使用迴圈結構可以簡化程式碼達成相同功能,如下。
for i in range(1000):
print('Hello')
充電時間
函式range為Python的內建函式,回傳一個數字串列,使用方式如下表。
(A)迴圈結構 — 使用for
for迴圈結構通常用於已知重複次數的程式,迴圈結構中指定迴圈變數的初始值、終止值與遞增(減)值,迴圈變數將由初始值變化到終止值的前一個數字,每次依照遞增(減)的值進行數值遞增或遞減。
(A-1)產生ASCII碼(ch5\5-1-1-ascii.py)
電腦中所有資料皆以二進位方式儲存,大小寫英文字母、數字都有國際標準的二進位編碼,這樣的編碼稱為ASCII碼,如A的ASCII碼以二進位表示為01000001,十進位表示為65;B 的ASCII碼以二進位表示為01000010,十進位表示為66、C的ASCII碼以二進位表示為01000011,十進位表示為67,依此類推。請寫一個程式利用迴圈與「chr」函式,「chr」函式將整數轉換成對應的ASCII字元。
(a)解題想法
可以使用迴圈結構撰寫程式,迴圈變數起始值為輸入的起始值,迴圈變數中止值為輸入的中止值,迴圈每執行一次迴圈變數就會遞增1,迴圈內使用函式chr將整數轉換成對應的ASCII字元顯示在螢幕上。
(b)程式碼與解說
行號
1
2
3
4
程式碼
s = int(input('請輸入ASCII的啟始值?'))
e = int(input('請輸入ASCII的終止值?'))
for i in range(s, e):
print(chr(i))
執行結果
ASCII起始值輸入「65」,ASCII終止值輸入「70」,本程式就會顯示ASCII介於65到69的字元。
請輸入ASCII的啟始值?65
請輸入ASCII的終止值?70
A
B
C
D
E
解說
第1行:於螢幕輸出「請輸入ASCII的啟始值?」,經由input與int函式,將輸入的值轉換成整數,指定給變數s。
第2行:於螢幕輸出「請輸入ASCII的終止值?」,經由input與int函式,將輸入的值轉換成整數,指定給變數e。
第3到4行:使用for迴圈,其中i值變化由使用者輸入的ASCII起始值(s)到ASCII終止值(e)減1,每次遞增1,利用chr函式,將ASCII值轉成所對應的字元,並顯示於螢幕。
(A-2) 加總
寫一個程式允許使用者輸入加總的開始值、結束值與遞增值,計算數值加總的結果,例如要計算3+6+9+12的結果,就輸入3為開始值,13為結束值,3為遞增值。
(a)解題想法
可以使用迴圈結構撰寫程式,迴圈變數起始值為輸入的加總起始值,迴圈變數終止值為輸入的加總終止值,迴圈每執行一次迴圈變數就會依照輸入的遞增(減)值進行遞增(減),迴圈內使用「sum=sum+迴圈變數」進行數值的加總,顯示加總的過程。
(b)程式碼與解說
行數
1
2
3
4
5
6
7
程式碼
s = int(input('請輸入加總開始值?'))
e = int(input('請輸入加總終止值?'))
inc = int(input('請輸入遞增減值?'))
sum = 0
for i in range(s, e, inc):
sum = sum + i
print('i為', i, '加總結果為', sum)
執行結果
加總開始值輸入「3」,加總結束值輸入「13」,加總遞增值輸入「3」,結果如下。
請輸入加總開始值?3
請輸入加總終止值?13
請輸入遞增減值?3
i為 3 加總結果為 3
i為 6 加總結果為 9
i為 9 加總結果為 18
i為 12 加總結果為 30
解說
第1行:於螢幕輸出「請輸入加總開始值?」,經由input與int函式,將輸入的值轉換成整數,指定給變數s。
第2行:於螢幕輸出「請輸入加總終止值?」,經由input與int函式,將輸入的值轉換成整數,指定給變數e。
第3行:於螢幕輸出「請輸入遞增減值?」,經由input與int函式,將輸入的值轉換成整數,指定給變數inc。
第4行:初始化變數sum為0。
第5到6行:使用for迴圈,其中i值變化由使用者輸入的「加總開始值(s)」到「加總終止值(e)」的前一個數字,每次依所輸入的「遞增減值(inc)」進行遞增減,利用「sum=sum+i」計算加總(第6行),將i值與sum值顯示於螢幕(第7行)。
(B)while迴圈結構
while迴圈結構與for迴圈結構
while迴圈結構與for迴圈結構十分類似,while迴圈結構常用於不固定次數的迴圈,由迴圈中測試條件成立與否,決定是否跳出迴圈,測試條件為真時繼續迴圈,當測試條件為假時結束迴圈。例如:猜數字遊戲,兩人(A與B)玩猜數字遊戲,一人(A)心中想一個數,另一人(B)去猜,A就B所猜數字回答「猜大一點」或「猜小一點」,直到B猜到A所想數字,這樣的猜測就屬於不固定次數的迴圈,適合使用while而不適合使用for。
while指令後面所接測試條件,若為真時會不斷做迴圈內動作,直到測試條件的結果為假時跳出while迴圈。
(B-1) 階乘計算
請計算N為多少時,其階乘值大於等於M。N階乘表示為N!,其值為「1*2*3*…*(n-1)*n」,使用while迴圈計算,N!超過M的最小N值為何?
(a)解題想法
可以使用迴圈結構撰寫程式,迴圈變數i起始值為1,進入迴圈之前,測試迴圈變數i的階乘值是否小於M,迴圈每執行一次迴圈變數i就會遞增1,迴圈內計算迴圈變數i的階乘值,最後顯示「多少階乘會大於等於M」。
(b)程式碼與解說
行數
1
2
3
4
5
6
7
程式碼
M = int(input('請輸入M?'))
fac = 1
i = 1
while(fac < M):
i = i + 1
fac = fac * i
print(i,'階乘為', fac,'大於', M)
執行結果
輸入M值為「1000」,結果如下。
請輸入M?1000
7 階乘為 5040 大於 1000
解說
第1行:於螢幕輸出「請輸入M?」,經由函式input與函式int,將輸入的值轉換成整數,儲存到變數M。
第2行:初始化fac等於1。
第3行:初始化i等於1。
第4到6行:使用while迴圈,測試fac是否小於M,i值每次遞增1,利用「fac=fac*i」求fac,fac為i的階乘(第6行)。
第7行:顯示階乘超過M的i值。
(B-2) 猜數字
大家是否玩過一個遊戲,兩人(A與B)一起玩,A心中想一個數字,B猜A心中所想的數字,B每猜一次,A就回答「猜大一點」、「猜小一點」與「猜中了」,當B猜到A所想的數字遊戲就結束,我們可以將此遊戲寫成程式,所猜數字介於1到100。
(a)解題想法
利用Python語言內建模組random中的隨機函式randint,產生介於1到99的目標值,使用while迴圈結構不斷允許使用者輸入數字進行猜測,測試猜測值與目標值是否相等,若相等則終止迴圈,否則根據猜測值與目標值的大小關係,顯示「猜大一點」、「猜小一點」與「猜中了」等提示。
(b)程式碼與解說
行數
1
2
3
4
5
6
7
8
9
10
11
程式碼
import random
target = random.randint(1,99)
guess = 0
while target != guess:
guess = int(input('請輸入1到99的數字?'))
if target < guess:
print('猜小一點')
elif target > guess:
print('猜大一點')
else:
print('猜中了')
執行結果
不斷輸入數字進行猜測,結果如下。
請輸入1到99的數字?50
猜大一點
請輸入1到99的數字?75
猜小一點
請輸入1到99的數字?62
猜小一點
請輸入1到99的數字?57
猜中了
解說
第1行:包含模組random,為了隨機產生數字。
第2行:使用模組random的函式randint產生1到99的隨機數值,指定給變數target。
第3行:初始化變數guess為0。
第4到11行:執行while迴圈,當guess與target不同時繼續做。
第5行:於螢幕輸出「請輸入1到99的數字?」,經由函式input與函式int,將輸入的值轉換成整數,指定給變數guess。
第6到11行:若target小於guess,會輸出「猜小一點」(第6到7行),否則若target大於guess,會輸出「猜大一點」(第8到9行),否則輸出「猜中了」(第10到11行)。
充電時間 隨機函式
Python語言包含亂數功能,首先「import random」讓程式有隨機產生數字的功能,接著呼叫random.randint(a, b),就會產生介於a到b(包含a與b)的隨機整數值。
亂數產生介於1到99的數值,公式如下。
import random
target = random.randint(1,99)
(C)巢狀迴圈
巢狀迴圈並不是新的程式結構,只是迴圈範圍內又有迴圈,巢狀迴圈可以有好幾層,巢狀迴圈與單層迴圈運作原理相同,從外層迴圈來看,內層迴圈只是外層迴圈內的動作,因此外層迴圈作用一次,內層迴圈需要執行完畢。以輸出九九乘法表為例,當外層迴圈作用一次,內層迴圈要執行九次,當外層迴圈作用九次,內層迴圈總共執行八十一次。
(C-1) 九九乘法表
寫一個程式印出九九乘法表。
(a)解題想法
巢狀迴圈的外層迴圈使用迴圈變數i,內層迴圈使用迴圈變數j,外層迴圈i等於1,內層迴圈j由1變化到9,印出「1*1=1,1*2=2,1*3=3,…,1*9=9」,i遞增1,外層迴圈i等於2,內層迴圈j由1變化到9,印出「2*1=2,2*2=4,2*3=6,…,2*9=18」,依此類推,直到外層迴圈i等於9,內層迴圈j由1變化到9,印出「9*1=9,9*2=18,9*3=27,…,9*9=81」。
(b)程式碼與解說
行數
1
2
3
4
程式碼
for i in range(1,10):
for j in range(1,10):
print(i, '*', j, '=', i*j, '\t', sep='',end='')
print()
執行結果
1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9
2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18
3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27
4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
解說
第1到4行:變數i為外層迴圈,其變化值由1到9,其範圍包含內層迴圈。
第2到3行:變數j為內層迴圈,其變化值由1到9,當外層迴圈執行一次,內層迴圈執行九次,依序將「變數i*變數j=變數i與j相乘結果」顯示在螢幕(第3行),接著串接tab字元「'\t'」,且設定sep為空字串「''」取代原本的空白字元,與設定end為空字串「''」取代原本的換行字元「'\n'」。
第4行:print()表示換行,內層迴圈執行完畢後進行換行。
執行結果如下。
巢狀迴圈印出九九乘法表原理,如下表,在Python語言中外層迴圈包含內層迴圈,外層迴圈執行一次,內層迴圈要執行完畢,九九乘法表外層迴圈執行九次,內層迴圈執行八十一次。
(C-2) 列出2到1000所有質數
可以參考前一節質數判斷程式,某數的因數只有1與自己,沒有其他因數,稱為質數。程式中要判斷一個數字是否是質數,就要判斷他的因數是否只有1與自己,要列出2到1000所有質數,除了需要質數判斷程式外,外層需要一個迴圈從2變化到1000,對每一個數進行質數判斷,若是質數就顯示出來。
(a)解題想法
使用巢狀迴圈,外層迴圈變數i列舉從2變化到1000的所有整數,判斷是否為質數。外層迴圈變數i的值為從2到1000,每次遞增1,內層迴圈內先設定旗標變數prime為True,內層迴圈變數j依序找出從2到i^(1/2)(開根號i,不須列舉到i-1)的每個整數,判斷由2到i^(1/2)的每個整數是否整除n,若j可以整除i,則旗標變數prime設定為False,跳出迴圈,最後根據旗標變數prime決定i是否為質數。
(b)程式碼與解說
行數
1
2
3
4
5
6
7
8
9
10
11
程式碼
import math
for i in range(2,1000):
j = 2
prime = True
while j <= math.sqrt(i):
if (i%j == 0):
prime = False
break
j += 1
if prime:
print(i,'是質數')
執行結果
列出最後5個質數。
971 為質數
977 為質數
983 為質數
991為質數
997 為質數
解說
第1行:包含數學(math)函式庫,為了開根號sqrt函式。
第2行:使用for迴圈,迴圈變數i由2遞增到999。
第3行:初始化j為2
第4行:初始化prime為True。
第5到9行:為while迴圈,當j小於時,繼續做。
第6到8行:當j整除i,prime為False,使用break中斷迴圈。
第9行:j遞增1。
第10到11行:若prime等於True,使用函式print輸出該數且顯示「是質數」。
(D)迴圈結構特殊指令的使用—break、continue與else
迴圈在特殊需求下可以使用break、continue與else指令,當要跳出迴圈時可以使用break跳出迴圈。當要跳過迴圈內之後的程式碼,迴圈變數值直接遞增或遞減,繼續迴圈的執行,則使用continue,也就是跳過continue後的程式繼續執行迴圈程式。若迴圈正常結束,就會執行else程式區塊,若迴圈經由break中斷,就不會執行else程式區塊。
針對不同的迴圈結構執行break,如下表。
針對不同的迴圈結構執行continue,如下表。
針對不同的迴圈結構執行else,如下表。
將break、continue與else可以使用在迴圈中,產生想要的結果,如質數判斷,當確定有一個因數就不是質數,就可以跳出迴圈(break),求質數程式,當找不到因數就會執行else程式區塊。使用else進行質數判斷,程式碼如下。
行數
1
2
3
4
5
6
7
8
9
10
程式碼
import math
num = int(input('請輸入一個整數?'))
j = 2
while j < math.sqrt(num):
if (num%j == 0):
print(num, '不是質數')
break
j += 1
else:
print(num, '是質數')
執行結果
輸入一個數字「37」,顯示判斷質數結果如下。
請輸入一個整數?37
37 是質數
解說
第1行:包含數學(math)函式庫,為了開根號sqrt函式。
第2行:於螢幕輸出「請輸入一個整數?」,經由函式input與函式int,將輸入的值轉換成整數,指定給變數num。
第3行:數字2指定給變數j
第4到10行:為while迴圈,當j小於√num時,繼續做。
第5到7行:當j整除num,會輸出該數且顯示「不是質數」,使用break中斷迴圈。
第8行:j遞增1。
第9到10行:若沒有使用break跳出迴圈,會執行else程式區塊,使用函式print顯示該數且顯示「是質數」。
(D-1)登入系統
請寫一個程式模擬帳號與密碼登入,使用者輸入帳號與密碼,若帳號密碼一致,則輸出「帳號與密碼正確」,否則輸出「登入失敗」。
(a)解題想法
使用while迴圈,迴圈內允許使用者輸入帳號與密碼,若帳號與密碼正確,則顯示「帳號與密碼正確」,接著使用break中斷while迴圈,否則顯示「登入失敗」。使用「while True:」無窮迴圈結構,表示永遠測試條件都成立,允許使用者不斷輸入帳號與密碼直到執行break才中斷「while True:」無窮迴圈。
(b)程式碼與解說
行數
1
2
3
4
5
6
7
8
程式碼
while True:
acc = input('請輸入帳號?')
pwd = input('請輸入密碼?')
if (acc == 'abc' and pwd == '123'):
print('帳號與密碼正確')
break
else:
print('登入失敗')
執行結果
預設登入帳號為「abc」,密碼為「123」,帳號輸入「abc」與密碼輸入「12」,顯示「登入失敗」,接著帳號輸入「abc」與密碼輸入「123」,顯示「帳號與密碼正確」。
請輸入帳號?abc
請輸入密碼?12
登入失敗
請輸入帳號?abc
請輸入密碼?123
帳號與密碼正確
解說
第1行到第8行:while迴圈中測試條件為True,表示測試永遠為真,表示無窮迴圈(第1行),登入成功後使用break跳出迴圈,中斷無窮迴圈執行(第6行)。
第2行:於螢幕輸出「請輸入帳號?」,經由函式input,將輸入的字串指定給變數acc。
第3行:於螢幕輸出「請輸入密碼?」,經由函式input,將輸入的字串指定給變數pwd。
第4行到第8行:判斷帳號是否等於帳號「abc」,密碼是否等於密碼「123」(第4行),若是則顯示「帳號與密碼正確」訊息(第5行),使用break跳出迴圈(第6行),否則顯示「登入失敗」訊息,繼續while迴圈(第7行到第8行)。