Se ha denunciado esta presentación.
Se está descargando tu SlideShare. ×
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Cargando en…3
×

Eche un vistazo a continuación

1 de 100 Anuncio

Python函式

Descargar para leer sin conexión

內建數值函式, 使用math套件, 使用random套件, 使用time套件, 自訂函式, 參數預設值與引數傳遞, 全域變數與區域變數, lambda函式, 使用函式裝飾器, 遞迴函式與應用, 應用實例:輪流取物遊戲、猜數字遊戲

內建數值函式, 使用math套件, 使用random套件, 使用time套件, 自訂函式, 參數預設值與引數傳遞, 全域變數與區域變數, lambda函式, 使用函式裝飾器, 遞迴函式與應用, 應用實例:輪流取物遊戲、猜數字遊戲

Anuncio
Anuncio

Más Contenido Relacionado

Más de 吳錫修 (ShyiShiou Wu) (20)

Anuncio

Python函式

  1. 1. Python函式 Revised on August 24, 2021  內建數值函式  使用math套件  使用random套件  使用time套件  自訂函式  參數預設值與引數傳 遞  全域變數與區域變數  lambda函式  函式裝飾器  遞迴函式與應用  應用實例:  輪流取物遊戲  猜數字遊戲
  2. 2.  設計程式時,會發現經常用到⼀些特定功能的程式片段,若將這樣的 程式片段獨立出來,必要時加以參數化,使其轉化成⼀個單獨的程式 單元,這樣就能重複呼叫執行使用,這種程式單元稱為函式 (Function)  系統內建函式是內含在程式語言開發環境,可直接呼叫使用的函式庫, 例如:輸出入函式、串列函式、字串函式等  使用者自定函式 (簡稱自定函式) 則是程式設計者在軟體開發過程中, 因應功能需求自己定義出來的函式 內建函式與自定函式 1/3 2
  3. 3. 內建函式與自定函式 2/3  內建函式就好像黑盒子,只要了解函式介面,知道給予什麼參數就可 得到所要的結果,不必瞭解函式的內部是如何設計,也無法更改函式 功能  自定函式是程式設計者依需求自行設計出來的,隨時可以修改維護  自定函式具有下列好處  可將較大程式軟體,依功能切割成多個程式單元,再交由多人共同設計。 如此不但可縮短程式開發的時間,也可以達到程式模組化的目的  將相同功能的程式片段寫成函式,只需做⼀次,提⾼程式的再利用性及可 讀性,也讓程式的除錯及維護更加容易  強化系統架構,主框架程式專注在系統流程管控,功能性或主題性的工作 交給函式處理,程式碼可較精簡 3
  4. 4.  Python語言的編譯器提供⼀個已定義好的函式集合稱為標準函式庫 (Standard library),包括:  輸出入函式  數值函式  字串函式  檔案輸出入函式  時間函式  亂數函式  ... 內建函式與自定函式 3/3 4
  5. 5. 內建數值函式 1/4 函式 說明 範例 abs(n) 取得n的絕對值 num = abs(-8) #8 round(n) 取得n四捨六入五成雙的整數值 當小數為5時,若個位數為偶數則捨去;若 個位數為奇數則進位 num = round(12.6) #13 num = round(12.4) #12 num = round(12.5) #12 num = round(11.5) #12 int(n) 將n轉換為整數(小數部份直接捨去) num = int(12.6) #12 float(n) 將n轉換為浮點數 num = float(12) #12.0 hex(n) 將n轉換為十六進位數字 num = hex(254) #0xfe oct(n) 將n轉換為八進位數字 num = oct(254) #0376 divmod(n, m) 取得n除以m的商跟餘數 ret = divmod(23, 5) #(4, 3) pow(n, m) 取得n的m次方 num = pow(5, 3) #125 chr(n) 取得Unicode編碼為n的字元 num = chr(0x5357) #南 ord(n) 取得字元n的Unicode編碼 num = ord('南') #21335 5
  6. 6.  round() 函式也可以指定要轉換的小數位數  round(n, m) 以四捨六入五成雙方式,計算 n 到小數點第 m 位之近似值 num = round(12.34, 1) #12.3 num = round(12.36, 1) #12.4 num = round(12.35, 1) #12.3 num = round(12.35001, 1) #12.4 註:即使是浮點數也可能因為尾數換算成二進位表示法後,超過有效位數而存在截斷 誤差;12.35實際儲存值可能為12.3499999999... 內建數值函式 2/4 6
  7. 7.  pow()函式也可以用來計算餘數  pow(n, m, k) 計算 n 的 m 次方,再取得除以 k 的餘數 (𝑛 % 𝑘) num = pow(12, 1, 5) #2 num = pow(3, 2, 5) #4 內建數值函式 3/4 7
  8. 8.  學年結束,將結餘的班費 5346 元平均退還 31 位學生,則每位學生可退還 多少錢,仍剩多少錢 classFund = 5346 students = 31 print('班費剩餘 %d元, 學生有% d人' %(classFund,students)) (div, mod) = divmod(classFund, students) print ('每人退還 %d元' %div) print ('班費仍剩餘 %d元' %mod) 測試: 班費剩餘 5346元, 學生有 31人 每人退還 172元 班費仍剩餘 14元 內建數值函式 4/4 8
  9. 9.  有些內建函式是定義在各別套件中,要使用這些內建函式時,必須先 使用import指令引用套件  import 套件名稱 import math #匯入math套件,並可使用math套件內的任何函式  程式中必須以「套件名稱.函式名稱」呼叫套件內的函式 print(math.sqrt(100))  匯入套件時可指定別名,程式中要呼叫套件內的函式時,要在函式前 要加上別名名稱 import math as M print(M.sqrt(100)) import指令 1/2 9
  10. 10.  若覺得以「套件名稱.函式名稱」呼叫套件內的函式有些麻煩,可改用 from .. import指令  from 套件名稱 import * from math import * #匯入math套件,並可使用math套件所有函式 print(sqrt(100))  若只要匯入套件中的特定函式,如 sqrt(),其匯入時敘述為 from math import sqrt #只匯入math.sqrt函式,不可使用math套件的其它函式 print(sqrt(100))  匯入套件指定函式時,也可以設定函式別名 from math import sqrt as squareRoot print(squareRoot(100)) #匯入math套件中的sqrt函式,並指定函式別名 #squareRoot(100)與sqrt(100)是⼀樣的效果 import指令 2/2 10
  11. 11.  數值的內建函式還有定義在 math 套件中的數值函式,例如 sin()、 exp()、log() 等  要使用 math 套件內的函式,必須在使用前匯入 math 套件  import math math套件函式 1/2 函式 說明 範例 pi 圖週率常數 (3.141592653589793) num = math.pi #3.14... e 數學常數 (2.718281828459045) num = math.e #2.71... ceil(n) 取得大於n的最小整數 num = math.ceil(12.3) #13 floor(n) 取得小於n的最大整數 num = math.floor(12.3) #12 fabs(n) 取得浮點數n的絕對值 num = math.fabs(-12.3) #12.3 sqrt(n) 取得n的平方根 num = math.sqrt(169) #13.0 11
  12. 12. math套件函式 2/2 函式 說明 範例 exp(n) 取得n自然指數值(𝑒 ) num = math.exp(1) #2.71... log(n) 取得n自然對數值(𝑙𝑜𝑔 𝑛) num = math.log(math.e) #1.0 sin(n) 取得弳度為n的正弦函式值 num = math.sin(math.pi/6) #0.5 cos(n) 取得弳度為n的餘弦函式值 num = math.cos(math.pi/3) #0.5 tan(n) 取得弳度為n的正切函式值 num = math.tan(math.pi/4) #1 asin(n) 取得反正弦函式的弳度值 num = math.asin(0.5) #π/6 acos(n) 取得反餘弦函式的弳度值 num = math.acos(0.5) #π/3 atan(n) 取得反正切函式的弳度值 num = math.atan(1) #π/4 12
  13. 13.  亂數函式多用於電腦、統計學、模擬、離散數學、抽樣、作業研究、 數值分析、決策等各領域,函式定義在 random 套件中  import random random套件函式 1/2 函式 說明 範例 randint(n1, n2) 產生一個整數 n,𝑛1 𝑛 𝑛2 random.randint(1, 10) randrange(n1,n2,n3) 產生⼀個 n1 到 (n2-1) 之間每隔 n3 的 整數 random.randrange(1, 10, 2) random() 產生一個浮點數 n,0.0 𝑛 1.0 random.random() uniform(n1, n2) 產生一個浮點數 n,𝑛1 𝑛 𝑛2 random.uniform(1, 10) choice(s) 從字串 s 中隨機取得⼀個字元 random.choice('python') sample(s, n) 從字串或串列 s 中隨機取得不重複 n 個 字元,回傳串列 random.sample('python', 2) shuffle(s) 將串列 s 隨機重新排列 random.shuffle([1,2,3,4]) 13
  14. 14.  隨機產生4個不重複的數字 from random import * numStr = '0123456789' randNum = sample(numStr, 4) #randNum為字元串列 answer = ''.join(randNum) #將字元串列合併為數字字串 print(answer) random套件函式 2/2 14
  15. 15.  time 套件提供許多與時間相關函式,例如 clock()、sleep()、time() 等  time() 取得電腦目前的時間,即自 1970-01-01 00:00:00 起到目前為止,所經過的 秒數  Python 最小時間單位為 tick,tick 時間為 us (百萬分之⼀秒),因此 time()傳回值是精確到小數點 6 位的浮點數 from time import * num = time() print(num) #1629348277.5953765 (執行時的時間值) time套件函式 1/5 15
  16. 16.  ctime() 取得電腦目前所在時區的日期、時間資料,資料型別為字串  傳回資料是英文字串,傳回值的格式為'星期 月份 日 時:分:秒 ⻄元年' import time as T st = T.ctime() print(st) #Thu Aug 19 13:34:14 2021 (執行時的時間值) time套件函式 2/5 16
  17. 17.  localctime() 傳回目前電腦所在時區資訊 (time.struct_time類別),包括以下資料欄 time套件函式 3/5 資料欄 說明 tm_year 時區資料的⻄元年份 tm_mon 時區資料的月份值(1~12) tm_mday 時區資料的日期值(1~31) tm_hour 時區資料的時(0~23) tm_min 時區資料的分(0~59) tm_sec 時區資料的秒(0~59) tm_wday 時區資料的星期值(0~6),0表示星期⼀ tm_yday 時區資料的該年的第幾天(0~366) tm_isdst 0:非日光節約時間,1:日光節約時間 17
  18. 18. time套件函式 4/5 from time import * curtime = localtime() print(type(curtime)) print(curtime) year = curtime.tm_year moon = curtime.tm_mon day = curtime.tm_mday hour = curtime.tm_hour min = curtime.tm_min sec = curtime.tm_sec print('%s:%s:%s %s-%s-%s' %(hour,min,sec,year,moon,day)) 測試結果: <class 'time.struct_time'> time.struct_time(tm_year=2021, tm_mon=8, tm_mday=19, tm_hour=15, tm_min=1, tm_sec=38, tm_wday=3, tm_yday=231, tm_isdst=0) 15:1:38 2021-8-19 18
  19. 19.  sleep() 使程式暫停⼀段時間,單位為秒 from time import * t1 = time() print('暫停前電腦時間:', t1) sleep(5) t2 = time() print('暫停後電腦時間:', t2) print('程式暫停了%f秒' %(t2 - t1)) 測試結果: 暫停前電腦時間: 1629357313.1758947 暫停後電腦時間: 1629357318.185649 程式暫停了5.009754秒 time套件函式 5/5 19
  20. 20.  設計程式隨機產生兩題四則運算(+,-,*,/)測驗  第⼀個運算值介於 11 到 20 間整數,第二個運算值介於 1 到 10 間整數  除法結果四捨五入到小數點第1位  作答完成顯示得分及所花費時間 提示: 四捨五入到小數點第1位可採用以下程式碼 result = math.floor(value * 10 + 0.5) / 10.0 實作練習 1/3 20
  21. 21. from random import randint import time import math total, score = 2, 0 t1 = time.time() #開始作答時間 for i in range(total): print('第%d題' %(i + 1)) num1 = randint(11, 20) #隨機產生第⼀個運算值 num2 = randint(1, 10) #隨機產生第二個運算值 op = randint(1, 4) #隨機選擇四則運算 if (op == 1): operator = '+' result = num1 + num2 if (op == 2): operator = '-' result = num1 - num2 if (op == 3): operator = '*' result = num1 * num2 實作練習 2/3 21
  22. 22. if (op == 4): operator = '/' result = math.floor(num1 / num2 * 10 + 0.5) / 10.0 print('%d %s %d = ' %(num1, operator, num2), end = '') ans = eval(input()) #考生輸入答案 if (ans == result): print('答對了!') score += 100 / total else: print('答錯了!') print('正確答案 : %f' %(result)) print() t2 = time.time() #完成作答時間 print('答題得分 : %d 分' %score) print('花費時間 : %0.2f 秒' %(t2 - t1)) 實作練習 3/3 22
  23. 23.  Python 使用 def 命令建立自定函式,不但可以傳送多個引數給函式, 也允許返回多個回傳值,語法如下  def 函式名稱([參數1, 參數2...]): 程式區塊 [return 回傳值1, 回傳值2...]  函式名稱:命名方式比照識別字命名規則。同程式中,自定函式的名稱 不可以重複,也不可以和內建函式相同名稱  參數 (Parameter)  在函式宣告中的參數也稱為虛引數 (Formal Argument),用來接收來自呼叫 端的程式敘述所傳遞過來的資料。呼叫函式時傳入的資料稱為引數 (Argument) 或實引數 (Actual Argument)  若有多個參數,參數間要用逗點 (,) 隔間開。若函式不需要參數,函式名稱後 的 () 仍須保留 自訂函式 1/8 23
  24. 24.  傳回值:函式執行完成後,可以傳回⼀個或多個結果  傳回值可以是資料、可以是變數、也可以是運算式,但回傳值最終會是 資料結果  使用 return 敘述就可以傳回結果資料,若函式的任務是沒有傳回值時, 則return敘述可省略  若有多個回傳值,主程式也要有多個變數來接收回傳值;如果用單⼀變 數接收回傳值,則全部回傳值會封裝為元組資料 (後續單元介紹) 自訂函式 2/8 24
  25. 25.  有傳回值的函式呼叫  變數1, 變數2, ... = 函式名稱(引數1, 引數2, ...)  使用指定運算子「=」,將函式回傳值指定給等號左邊的變數  被呼叫函式的回傳值數量、資料型別,必須和呼叫敘述端的變數⼀致  自訂 ctof 函式,傳入攝氏溫度,回傳華氏溫度 def ctof(c): f = c * 1.8 + 32 return f tempc = float(input("請輸入攝氏溫度:")) tempf = ctof(tempc) print("華氏溫度為:%5.1f 度" % tempf) 測試結果: 請輸入攝氏溫度:26.5 華氏溫度為: 79.7 度 自訂函式 3/8 25
  26. 26.  自訂 progression 函式,傳入等差級數首項、公差及項數,回傳級數末項 及總和 def progression(a1, d, n): an = a1 + (n - 1) * d #末項 sn = n * (a1 + an) / 2 #和 return an, sn a1 = eval(input('輸入數列的首項:')) d = eval(input('輸入數列的公差:')) n = eval(input('輸入數列的項數:')) dd = progression(a1, d, n) print(dd) an, sn = progression(a1, d, n) print('等差數列的末項為 %d,和為 %d' %(an, sn), end = '') 測試結果: 輸入數列的首項:1 輸入數列的公差:2 輸入數列的項數:6 (11, 36.0) 等差數列的末項為 11,和為 36 自訂函式 4/8 26
  27. 27.  無傳回值的函式呼叫  函式名稱(引數1, 引數2, ...)  將呼叫敘述端的實引數傳給被呼叫函式端的虛引數。虛引數將所得到的 資料帶入函式內經過運算處理後,不回傳結果到原來的呼叫敘述 def printChar(ch, n): for i in range(n): print ('%s' %ch, end = '') print() ch1 = 'A' n1 = 12 printChar(ch1, n1) #以變數作為實引數 printChar('-', 15) #以常值作為實引數 printChar('B', n1) #以常值與變數作為實引數 測試結果: AAAAAAAAAAAA --------------- BBBBBBBBBBBB 自訂函式 5/8 27
  28. 28.  撰寫函式使用說明  在函式開頭使用「'''」撰寫函式的說明文件,說明文件可以跨行,直到 找到下⼀個「'''」  可用以下指令讀取函式的說明文件  help (函式名稱)  print (函式名稱.__doc__) 自訂函式 6/8 28
  29. 29.  為 progression 函式加入說明 def progression(a1, d, n): ''' progression(a1, d, n)函式用來計算等差級數 Args: a1: 等差級數首項 d: 等差級數公差 n: 等差級數項數 Returns: 回等差級數未項值及總和 ''' an = a1 + (n - 1) * d #末項 sn = n * (a1 + an) / 2 #和 return an, sn help(progression) 自訂函式 7/8 29
  30. 30. 測試結果: Help on function progression in module __main__: progression(a1, d, n) progression(a1, d, n)函式用來計算等差級數 Args: a1: 等差級數首項 d: 等差級數公差 n: 等差級數項數 Returns: 回等差級數未項值及總和 自訂函式 8/8 30
  31. 31.  設計程式計算二正整數之最大公因數與最小公倍數  歐幾里得演算法 (Euclidean Algorithm),也稱為輾轉相除法,用來計算兩 個整數的最大公因數(GCD,Greatest Common Divisor) gcd 𝑚, 𝑛 gcd 𝑛, 𝑚 , 𝑚 𝑛 𝑚, 𝑛 0 gcd 𝑛, 𝑚%𝑛 , 𝑒𝑙𝑠𝑒  最小公倍數(LCM,Least Common Multiple) 𝑙𝑐𝑚 𝑛 𝑚 𝑔𝑐𝑑 lcm(32, 12) = 32 * 12 / 4 = 96 實作練習 1/2 2 32 12 1 24 8 2 8 4 8 0 2 32 12 24 8 2 32 12 1 24 8 8 4 被除數 除數 被除數 除數 除數即為最 大公因數 被除數 31 整除
  32. 32. def gcd(x, y): while ( x > 0 and y > 0 ): if(x > y): x = x % y else: y = y % x return y if (x == 0) else x while True: a = eval(input('輸入第⼀個正整數a:')) b = eval(input('輸入第二個正整數b:')) if a > 0 and b > 0: break else: print('無效輸入, 請重新輸入...') gcd = gcd(a, b) print('%d, %d 兩整數的GCD為 %d' %(a, b, gcd)) print('%d, %d 兩整數的LCM為 %d' %(a, b, (a * b)/gcd)) 測試結果: 輸入第⼀個正整數a:234 輸入第二個正整數b:36 234, 36 兩整數的GCD為 18 234, 36 兩整數的LCM為 468 實作練習 2/2 32
  33. 33.  設計解⼀元二次方程式的兩個根的函式,由使用者輸入方程式的平方 項係數 a、⼀次項係數 b、及常數項 c,先判斷所輸入的⼀元二次方程 式係數是否有實數解,再呼叫自訂函式求解  ⼀元二次方程式:𝑎𝑥 𝑏𝑥 𝑐 0  實數解條件:𝑏 4𝑎𝑐 0  實數解𝑥 實作練習 1/2 33
  34. 34. import math def equation(a, b, c): d = math.sqrt(b ** 2 – 4 * a * c) return (-b + d)/(2 * a), (-b - d)/(2 * a) while (1): a = eval(input('請輸入平方項係數a:')) b = eval(input('請輸入⼀次項係數b:')) c = eval(input('請輸入常數項c:')) if ((b ** 2 – 4 * a * c) >= 0): break else: print('無解, 請重新輸入係數...') ret = equation(a, b, c) print('⼀元二次方程式的根為 %0.2f, %0.2f' %(ret[0], ret[1])) 測試結果: 請輸入平方項係數a:2 請輸入⼀次項係數b:3 請輸入常數項c:1 ⼀元二次方程式的根為 -0.50, -1.00 實作練習 2/2 34
  35. 35.  呼叫函式時,若引數數量與參數數量不相符,在這種情況下⼀般是會 產生錯誤的  要避免上述錯誤情形,在定義函式時,可指定參數預設值。如此⼀來, 若呼叫該函式時沒有傳遞引數,或傳遞的實引數數量少於參數數量時, 參數的預設值就派上用場了  當某⼀參數定義了預設值,其右側的所有參數都必須定義預設值 def greeting(name, msg = 'Good morning!', msg2 = ''): print('Hello', name + ', ' + msg) greet('Kate') greet('Bruce', 'How do you do?') 測試: Hello Kate, Good morning! Hello Bruce, How do you do? 參數的預設值 35
  36. 36.  呼叫函式時引數資料的傳遞方式有傳值呼叫 (call by value) 和參考呼 叫 (call by reference) 兩種  傳值呼叫  虛引數的資料異動時,會另外建立新的資料物件,不會影響到實引數的資 料內容  以下資料型別之引數採用傳值呼叫 boolean, int, float, long, str, unicode, tuple 引數的傳遞方式 1/9 36
  37. 37. def inc(x): print('id of x = %d' %id(x), end = ', ') print('x = %d' %(x)) x += 1 print('id of x = %d' %id(x), end = ', ') print('x = %d' %(x)) a = 10 print('id of a = %d' %id(a), end = ', ') print('a = %d' %(a)) inc(a) print('id of a = %d' %id(a), end = ', ') print('a = %d' %(a)) 測試結果: id of a = 140729614147616, a = 10 id of x = 140729614147616, x = 10 id of x = 140729614147648, x = 11 id of a = 140729614147616, a = 10 引數的傳遞方式 2/9 37
  38. 38. 引數的傳遞方式 3/9  參考呼叫  實引數和虛引數共用相同資料物件,如此引數間的資料傳遞是雙向互通  在函式中更新虛引數的內容,則原呼叫敘述實引數的內容也跟著變動  以下資料型別之引數採用參考呼叫 list, dict, set 38
  39. 39. def additem(x): print('id of x = %d' %id(x), end = ' ,') print('x = ', x) x.append(5) print('id of x = %d' %id(x), end = ' ,') print('x = ', x) a = [1, 2, 3, 4] print('id of a = %d' %id(a), end = ' ,') print('a = ', a) additem(a) print('id of a = %d' %id(a), end = ' ,') print('a = ', a) 測試結果: id of a = 2398559902016 ,a = [1, 2, 3, 4] id of x = 2398559902016 ,x = [1, 2, 3, 4] id of x = 2398559902016 ,x = [1, 2, 3, 4, 5] id of a = 2398559902016 ,a = [1, 2, 3, 4, 5] 引數的傳遞方式 4/9 39
  40. 40.  在定義函式時,允許不限定傳送過來的實引數數量  def 函式名稱(*參數): 程式區塊 [return 回傳值1, 回傳值2…]  呼叫函式時,不限定實引數個數,實引數間以逗號分隔  全部的實引數全被封裝成⼀個元組資料 (tuple) 傳給參數  元組資料的取用方式與串列資料相同 引數的傳遞方式 5/9 40
  41. 41. def calsum(*data): total = 0 for x in data: total += x return total print("不定數目引數範例:") print("2個引數:calsum(4, 5) = %d" % calsum(4, 5)) print("3個引數:calsum(4, 5, 12) = %d" % calsum(4, 5, 12)) print("4個引數:calsum(4, 5, 12, 8) = %d" % calsum(4, 5, 12, 8)) 測試結果: 不定數目引數範例: 2個引數:calsum(4, 5) = 9 3個引數:calsum(4, 5, 12) = 21 4個引數:calsum(4, 5, 12, 8) = 29 引數的傳遞方式 6/9 41
  42. 42.  使用字典參數  def 函式名稱(**參數): 程式區塊 [return 回傳值1, 回傳值2…]  呼叫函式時,不限定實引數個數,實引數間以逗號分隔  每個實引數使用「引數名稱 = 引數值」形式  全部的實引數全被封裝為成⼀個字典資料 (dictionary) 傳給參數 引數的傳遞方式 7/9 42
  43. 43. def resume(**data): print(data) print('字典引數範例:') resume(name = 'Justin', age = 23, tel = '1234567') 測試結果: 字典引數範例: {'name': 'Justin', 'age': 23, 'tel': '1234567'} 引數的傳遞方式 8/9 43
  44. 44.  同時使用不定數目引數及字典參數  def 函式名稱(*參數1, **參數2): 程式區塊 [return 回傳值1, 回傳值2…] def resume(*index, **data): print(index) print(data) for key in index: print(data[key]) print('同時使用不定數目引數及字典引數範例:') resume('name', 'age', 'tel', name = 'Justin', age = 23, tel = '1234567') 測試結果: 同時使用不定數目引數及字典引數範例: ('name', 'age', 'tel') {'name': 'Justin', 'age': 23, 'tel': '1234567'} Justin 23 1234567 引數的傳遞方式 9/9 44
  45. 45.  定義在函式外的變數可供多個函式共同使用,稱為「全域變數」 (Global variable),在程式結束前會⼀直存在  在函式內建立的變數,稱為區域變數 (Local Variable)  區域變數僅限在所屬函式中使用,離開該函式時此類變數的記憶體會立即 被釋放掉。每次函式被呼叫時,系統會重新配置記憶體給此類變數使用  由於 Python 會自動建立變數,當函式內的區域變數名稱與全域變數 名稱相同,在函式內會產生「變數覆蓋」的現象  兩個同名稱的變數,在記憶體內是佔用不同的位址,互不影響  當程式流程執行到函式時,就使用這個區域所建立的區域變數,全域變數 會保留其值,等程式流程離開這個函式時,這個區域變數便會消失  待程式流程回到主程式時,全域變數會仍用原保留的值繼續運作 全域變數與區域變數 1/3 45
  46. 46. def mysub(): v2, v3 = 200, 300 #Python自動建立v2,v3區域變數 print('--in mysub--') print('v1=%d, v2=%d, v3=%d' %(v1, v2, v3)) #v1是全域變數,v2與v3是區域變數 print('--in main program--') v1, v2 = 10, 20 print('v1=%d, v2=%d' %(v1, v2)) mysub() print('--in main program--') print('v1=%d, v2=%d' %(v1, v2)) print('v1=%d, v2=%d, v3=%d' %(v1, v2, v3)) #錯誤 測試結果: --in main program-- v1=10, v2=20 --in mysub-- v1=10, v2=200, v3=300 --in main program-- v1=10, v2=20 全域變數與區域變數 2/3 46 NameError: name 'v3' is not defined
  47. 47.  若函式內須要更新全域變數內容,則函式須用 global 來宣告該全域變數 def mysub(): global v2 v2, v3 = 200, 300 #v2為全域變數,並自動建立v3區域變數 print('--in mysub--') print('v1=%d, v2=%d, v3=%d' %(v1, v2, v3)) print('--in main program--') v1, v2 = 10, 20 print('v1=%d, v2=%d' %(v1, v2)) mysub() print('--in main program--') print('v1=%d, v2=%d' %(v1, v2)) 測試結果: --in main program-- v1=10, v2=20 --in mysub-- v1=10, v2=200, v3=300 --in main program-- v1=10, v2=200 全域變數與區域變數 3/3 47
  48. 48.  Lambda函式是⼀種特別的函式  它是匿名函式,不需要定義名稱,且函式程式碼只能有⼀行指令敘述。語 法如下: lambda 參數1, 參數2, ...:程式碼  下列max()函式會回傳二數中較大者 def max(m, n): if m > n: return m else: return n 可改寫如下 def max(m, n): return m if m > n else n lambda函式 1/5 48
  49. 49.  若將max()函式轉換成lambda函式,程式如下 max = lambda m, n : m if m > n else n print(max(10, 3))  Lambda函式支援IIFE (immediately invoked function expression) 語 法,意思是利用 function expression 的方式來建立函式,並且立即執 行它,語法如下:  (lambda 函式參數:指令敘述)(實引數) print((lambda m, n:m if m > n else n)(10, 3)) lambda函式 2/5 49
  50. 50.  Lambda函式通常應用在以下情境  function使用頻率偏低,不易命名,或是命名會干擾整個命名規則,採用 隨用隨扔的lambda函式,可節省記憶體  filter()函式在可疊代的物件中,依據條件運算式,篩選特定的元素。 語法如下:  filter(篩選函式, 可疊代的物件)  下列程式會篩選串列中的偶數資料 def even_fn(x): return (x % 2 == 0) data = [-5, 1, 3, 2, 5, -9, 20, 21] result = list(filter(even_fn, data))  當需要許多不同的篩選條件時 (奇數、偶數、正數、負數…),我們就要定 義各種篩選函式 lambda函式 3/5 50
  51. 51. def even_fn(x): return (x % 2 == 0) def odd_fn(x): return (x % 2 != 0) def positive_fn(x): return (x > 0) data = [-5, 1, 3, 2, 5, -9, 20, 21] result = list(filter(even_fn, data)) print(result) result = list(filter(odd_fn, data)) print(result) result = list(filter(positive_fn, data)) print(result) 測試結果: [2, 20] [-5, 1, 3, 5, -9, 21] [1, 3, 2, 5, 20, 21] lambda函式 4/5 51
  52. 52.  每個篩選運算式其實都很簡單,要為不同篩選條件定義函式並命名也會有 點困擾,此時就很適合改用lambda函式 data = [-5, 1, 3, 2, 5, -9, 20, 21] result = list(filter(lambda x: x % 2 == 0, data)) print(result) result = list(filter(lambda x: x % 2 != 0, data)) print(result) result = list(filter(lambda x: x > 0, data)) print(result) 測試結果: [2, 20] [-5, 1, 3, 5, -9, 21] [1, 3, 2, 5, 20, 21] lambda函式 5/5 52
  53. 53.  Python的函式本⾝就是⼀個物件,因此具備物件的性質  可以將函式設定給⼀個變數 def ctof(c): return c * 1.8 + 32 fahrenheit = ctof print(fahrenheit(25)) 測試結果: 77.0  可以在函式裡再定義另⼀個函式 def fahrenheit(c): def ctof(c): return c * 1.8 + 32 print('華氏溫度為:%5.1f 度' % ctof(c)) fahrenheit(25) 測試結果: 華氏溫度為: 77.0 度 Python函式的其它特性 1/4 53
  54. 54.  函式可以當做參數傳給另⼀個函式 def jap(): print('こんにちは, ', end = '') def eng(): print('Hello, ', end = '') def cht(): print('你好, ', end = '') def vietnam(): print('xin chào, ', end = '') def sayhello(name, nationality): nationality() print(name) funcs = [cht, eng, jap, vietnam] name = input('Name: ') i = int(input('Nationality 1-Chinese, 2-English, 3-Japanese, 4-Vietnam:')) sayhello(name, funcs[i - 1]) 測試結果: Name: Tony Nationality 1-Chinese, 2-English, 3-Japanese, 4-Vietnam:1 你好, Tony Python函式的其它特性 2/4 54
  55. 55.  函式可以回傳另⼀個函式 def nationality(i): def jap(): print('こんにちは, ', end = '') def eng(): print('Hello, ', end = '') def cht(): print('你好, ', end = '') def vietnam(): print('xin chào, ', end = '') funcs = [cht, eng, jap, vietnam] return funcs[i - 1] def sayhello(name, greeting): greeting() print(name) name = input('Name: ') i = int(input('Nationality 1-Chinese, 2-English, 3-Japanese, 4-Vietnam:')) sayhello(name, nationality(i)) Python函式的其它特性 3/4 55
  56. 56.  內部函式可以取得包含函式的區域變數 def greeting(name, i): def jap(): print('こんにちは! ', name) def eng(): print('Hello! ', name) def cht(): print('你好! ', name) def vietnam(): print('xin chào, ', end = '') funcs = [cht, eng, jap, vietnam] funcs[i - 1]() name = input('Name: ') i = int(input('Nationality 1-Chinese, 2-English, 3-Japanese, 4-Vietnam:')) greeting(name, i) 測試結果: Name: Tony Nationality 1-Chinese, 2-English, 3-Japanese, 4-Vietnam:1 你好, Tony Python函式的其它特性 4/4 56
  57. 57.  函式裝飾器 (decorator) 功能是將⼀個函式的結果,再以另⼀個函式包 裝處理,使原函式呈現另⼀種功能面貌 def sayHello(name): return 'Hello, ' + name def htmlText(func): def wrapper(name): return '<p>' + func(name) + '</p>' return wrapper mysayHello = htmlText(sayHello) print(mysayHello('John')) 測試結果: <p>Hello, John</p>  sayHello函式被當作參數傳入htmlText函式,htmlText函式以內部函式 wrapper來增加sayHello函式的功能,因此htmlText函式裝飾了sayHello 函式,所以htmlText函式就是⼀個裝飾器 函式裝飾器 1/3 57
  58. 58.  如要將裝飾器B永遠附加在函式A,需要將執行裝飾函式敘述修改如下: A = B(A),先前程式可修改如下 def sayHello(name): return 'Hello, ' + name def htmlText(func): def wrapper(name): return '<p>' + func(name) + '</p>' return wrapper mysayHello = htmlText(sayHello) print(mysayHello('John')) 測試結果: <p>Hello, John</p> 函式裝飾器 2/3 58
  59. 59.  Python 提供更簡潔的裝飾器語法,在被裝飾的函式前,加上@符號及 裝飾器名稱,就不需要執行附加裝飾器 A = B(A) 的指令  @裝飾器 def 被裝飾函式(): def htmlText(func): def wrapper(name): return '<p>' + func(name) + '</p>' return wrapper @htmlText def sayHello(name): return 'Hello, ' + name print(sayHello('John')) 測試結果: <p>Hello, John</p> 函式裝飾器 3/3 59
  60. 60.  函式間可以相互呼叫,除了呼叫別的函式外,也可呼叫自己本⾝,這 種函式呼叫自己的方式稱為「遞迴」  遞迴是⼀種應用極廣的程式設計技術,在函式執行的過程不斷地的呼 叫函式自⾝,但每⼀次呼叫,會完成整體之部份作業,直到遇到終止 再呼叫函式自⾝的條件時,才會停止遞迴逐層返回  如果⼀個問題能拆成同形式且較小範圍時,就非常適合使用遞迴函式 來設計  例如要計算1 + 2 … + 10的總和時,可以拆成1和2 + 3 … +10;2 + 3 … + 10 又可以拆成2和3 + 4 … + 10,其餘類推,此時就可以設計成遞迴函式  數列、階乘、費氏級數、輾轉相除法、排列、組合、堆疊、河內塔、八個 皇后、樹的走訪、老鼠走迷宮…等問題都具備這種特性  如果遞迴的函式內沒有設定終止呼叫的條件,則這樣的函式會形成無 窮遞迴,造成程式無法正常結束 何謂遞迴 60
  61. 61.  計算 sum = 1 + 2 + 3 + ... + (n-1) + n 數列總和  sum(n) = 1 for n == 1  sum(n) = n + sum(n-1) for n > 1 def f(n): if n == 1: return 1 else : #n > 0 return n + f(n - 1) n = eval(input('n = ')) sum = f(n) print('1 + 2 + ... + %d = %d' %(n, sum)) 測試結果: n = 5 1 + 2 + ... + 5 = 15 遞迴應用實例 1/12 遞迴公式 61
  62. 62.  sum(5)執行流程 遞迴應用實例 2/12 sum(5) 5 + sum(4) 4 + sum(3) 3 + sum(2) 2 + sum(1) 1 1 3 6 10 15 62
  63. 63.  計算 sum = 1 – 4 + 7 – 10 + ... – (n-3) + n 數列總和  sum(n) = 1 for n == 1  sum(n) = (1 + 3(n-1)) + sum(n-1) for n == 奇數  sum(n) = -(1 + 3(n-1)) + sum(n-1) for n == 偶數 def g(n): if (n == 1): return 1 elif (n % 2 == 0): #n > 0,為偶數 return -(1 + 3 * (n - 1)) + g(n - 1) else: #n > 0,為奇數 return 1 + 3 * (n - 1) + g(n - 1) n = eval(input('n = ')) sum = g(n) if (n % 2 == 1): #n輸入值為奇數 print('1 – 4 + 7 – ... + %d = %d' %(1 + 3 * (n - 1), sum)) else: #n輸入值為偶數 print('1 – 4 + 7 – ... - %d = %d' %(1 + 3 * (n - 1), sum)) 遞迴應用實例 3/12 63
  64. 64.  計算 n! = n * (n-1) * (n-2) * ... * 1 乘積  n! = 1 for n <= 1  n! = n + (n-1)! for n > 1 def factorial(n): if n <= 1: return 1 else : #n > 1 return n * factorial(n - 1) while True: n = eval(input('n = ')) if (n >= 1): break else: print('輸入資料不符, 請重新輸入...') print('%d! = %d' %(n, factorial(n))) 測試結果: n = 4 4! = 24 遞迴應用實例 4/12 64
  65. 65.  輾轉相除法就是將兩數相除,能整除則除數為最大公因數;不能整除, 則除數變為被除數,餘數變為除數,再將兩數相除,以此類推 def GCD(p, q): if (p % q == 0): return q else : return GCD(q, p % q) x = eval(input('x = ')) y = eval(input('y = ')) if (x < y): x, y = y, x gcd = GCD(x, y) print('GCD(%d, %d) = %d' %(x, y, gcd)) 測試結果: x = 234 y = 48 GCD(234, 48) = 6 遞迴應用實例 5/12 gcd p, 𝑞 𝑞 𝑝%𝑞 0 gcd 𝑞, 𝑝%𝑞 𝑝%𝑞 0 65
  66. 66.  ⻄元1200年代的歐洲數學家Fibonacci提出假說:  若有⼀對免子每個月生⼀對小免子,兩個月後小免子也開始生產。前兩個 月都只有⼀對免子,第三個月就有兩對免子,第四個月有三對免子,第五 個月有五對免子…  假設免子都沒有死亡,則每個月免子的總對數就形成了⼀種數列,即為 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...  這種數列被稱為「費氏數列」 遞迴應用實例 6/12 𝑓 0 𝑛 0 1 𝑛 1 𝑓 𝑓 𝑛 2 66
  67. 67. def fib(n): if (n == 0): return 0 elif (n == 1): return 1 else: #n >= 2 return fib(n - 1) + fib(n - 2) n = eval(input('n = ')) print('費氏數列第 %d 項為 %d' %(n, fib(n))) 測試結果: n = 10 費氏數列第 10 項為 55 遞迴應用實例 7/12 67
  68. 68.  有n個不同的物品,要挑出 k 個的方法數有幾個?這是數學上「組合」 的題目,我們用 C(n, k) 來表示。若有針對某個特定物品,會分成兩種 互斥情況: 1. 選到這個特定物品,就再從剩下的n-1個物品中挑出k-1個物品,則會有 C(n-1, k-1)個方法數 2. 沒有選到這個特定物品,就再從剩下的n-1個物品中挑出k個物品,則會有 C(n-1, k)個方法數  所以,當 n = k 或 k = 0 時,則 C(n, k) = 1; 當 n > k 時,則 C(n, k) = C(n-1, k-1) + C(n-1, k) 遞迴應用實例 8/12 68
  69. 69. def C(n, k): if n == k or k == 0: return 1 else : return C(n - 1, k - 1) + C(n - 1, k) while True: n = eval(input('n = ')) k = eval(input('k = ')) if n >= 0 and k >= 0 and n > k: break else: print('輸入資料不符, 請重新輸入...') ans = C(n, k) print('組合 C(%d, %d) = %d' %(n, k, ans)) 測試結果: n = 5 k = 2 組合 C(5, 2) = 10 遞迴應用實例 9/12 69
  70. 70.  河內塔問題 有三根杆子A,B,C。A杆上有 N 個 (N>1) 穿孔圓盤,盤的尺寸由下到上依 次變小。要求按下列規則將所有圓盤移至 C 杆:  每次只能移動⼀個圓盤  大盤不能疊在小盤上面  提示:可將圓盤臨時置於 B 杆,也可將從 A 杆移出的圓盤重新移回 A 杆, 但都必須遵循上述兩條規則 遞迴應用實例 10/12 70 A B C A B C
  71. 71.  將⼀個 N 層河內塔由 A 桿移到 C 桿。依照上面的解法  先將前 N-1 層的圓盤先移到 B 桿  再將第 N 層的圓盤移到 C 桿  將 B 桿上的圓盤全部移到 C 桿 遞迴應用實例 11/12 71
  72. 72. def Hanoi(n, a, b, c): if n == 1: print('move %d %s --> %s' %(n, a, c)) return Hanoi(n - 1, a, c, b) print('move %d %s --> %s' %(n, a, c)) Hanoi(n - 1, b, a, c) n = int(input('Number of rings on A: ')) Hanoi(n, 'A', 'B', 'C') 測試結果: Number of rings on A: 3 move 1 A --> C move 2 A --> B move 1 C --> B move 3 A --> C move 1 B --> A move 2 B --> C move 1 A --> C 遞迴應用實例 12/12 72
  73. 73.  在執行遞迴的過程中,系統必須使用堆疊記錄每⼀層的中間值,然後 去下⼀層繼續進行計算,直到終止條件被滿⾜。然而,萬⼀計算量太 大、或設計不良使得終止條件⼀直沒有被滿⾜,就會造成系統資源被 recursion 耗盡  為了避免這件事情的發生,Python 對於遞迴次數 (深度) 有所限制, 也就是說,它透過限制呼叫遞迴函式的次數,來杜絕你的遞迴無止盡 地跑下去這個可能性。透過 sys 模組中的 getrecursionlimit() 函式, 可取得遞迴函式的次數限制, setrecursionlimit()函式可重設遞迴函式 的次數限制 import sys sys.getrecursionlimit() 測試結果: 3000 遞迴限制 73
  74. 74.  遊戲規則  桌面有⼀堆⽯子  遊戲⼀開始隨機決定該回遊戲之⽯子總數 (18~23之間)  玩家與電腦輪流拿取⽯子,每回至少要拿⼀顆,最多可拿N顆  遊戲⼀開始隨機決定該回遊戲之每回合拿取⽯子上限值 (3~5)  拿到最後⼀顆⽯子者落敗  隨機決定誰先拿取⽯子 應用實例:輪流取物遊戲 1/7 74
  75. 75.  拿取策略分析  以最多拿3個為例  max_take = 3之決策樹  max_take + 1為⼀個完整回合可控制的拿取總數 應用實例:輪流取物遊戲 2/7 玩家 1 2 3 電腦 1~3 1~3 1~3 合計拿取數 2, 3, 4 3, 4, 5 4, 5, 6 75 n-1 n n-2 n-3 n-4 n-3 n-2 n-5 n-6 1 2 3 1 2 3 1 2 3 1 2 3 對手可能拿取數量 自已可以拿取數量
  76. 76.  1 + (max_take+1) * N組成的節點為關鍵路徑節點  take = (total-1) % (max_take + 1)  如果計算結果為 0 表示對手佔據關鍵節點,則隨機取 1~max_take  max_take = 3之決策樹  先佔據關鍵節點者,就能掌控遊戲 應用實例:輪流取物遊戲 3/7 76 1 3 4 5 11 7 9 6 8 3 2 1 1 2 3 10 12 1 2 3 2 3 2 1 1 2 3 對手可能拿取數量 對手可能拿取數量
  77. 77.  亂數決定⽯子總數 import random total = random.randint(18, 23) #隨機產生18~23的⽯子數  亂數決定每回合可拿取的⽯子上限 max_take = random.randint(3, 5) #隨機產生3~5間的拿取上限值  顯示遊戲訊息 print('共有%d個⽯子,每回只能拿取1~%d個,拿到最後⼀個⽯子者落敗' %(total, max_take))  回合制處理作業 turn = random.randint(0, 9) % 2 #隨機決定誰先,0電腦, 1玩家 if (turn == 1): print('玩家先') else: print('電腦先') 應用實例:輪流取物遊戲 4/7 77
  78. 78.  玩家回合作業 def player_turn(): global total run = True while (run): try: take = int(input('要取走幾個⽯子頭(1~%d):' %max_take)) if (take >= 1 and take <= max_take): run = False total = total - take print('玩家取走%d個⽯子,剩下%d個' %(take, total)) else: print('只能取走1~%d個⽯子' %max_take) except: print('必須輸入數值') 應用實例:輪流取物遊戲 5/7 78
  79. 79.  電腦回合作業 def computer_turn(): global total take = (total - 1) % (max_take + 1) if (take == 0): take = random.randint(1, max_take) total = total - take; print('電腦取走%d個⽯子,剩下%d個' %(take, total)) 應用實例:輪流取物遊戲 6/7 79
  80. 80.  主程式 while(True): if (turn): player_turn() turn = 1 - turn #換手 if (total == 1): print('玩家獲勝') break else: computer_turn() turn = 1 - turn #換手 if (total == 1): print('電腦獲勝') break 應用實例:輪流取物遊戲 7/7 80
  81. 81.  遊戲規則  電腦與玩家各自設定⼀組4位數不重複的數值為謎底  玩家與電腦輸流猜對手數值,對家必須依據自已的答案提供正確提示  玩家先猜  A代表數字正確位置也正確,B代表數字正確但位置錯誤  例如正確答案為 5234,而對手猜 5346時,其中 5 的位置對了,記為1A; 3 和 4 這兩個數字對了,而位置不對,記為2B;因此要提示1A2B  先猜中對手答案者獲勝 應用實例:猜數字遊戲 1/11 81 5 2 3 4 5 3 4 6 結果為1A2B 答案值 猜測值
  82. 82.  電腦猜數字策略 1. 前二次固定猜 1357 及 8642 收集答案提示 2. 之後由 9876 開始遞減,搜尋符合下列條件的可能答案 1) 4 個位數之數字不重複 2) 與之前記錄中的猜測值比對,必須得到與記錄中相同的答案題示 3. 如果答錯則增加⼀組猜測值與答案提示記錄,回到步驟 2 應用實例:猜數字遊戲 2/11 82
  83. 83. from random import sample count = 0 #局數 randNum = sample('0123456789', 4) #隨機取出4個數字 answer = ''.join(randNum) #轉換為數字字串 guess = 9876 #電腦猜測值 playerNums = [] #用來記錄玩家每⼀回合的猜測值 playerHints = [] #用來記錄玩家每⼀回合的猜測結果 computerNums = [] #用來記錄電腦每⼀回合的猜測值 computerHints = [] #用來記錄電腦每⼀回合的猜測結果 應用實例:猜數字遊戲 3/11 83
  84. 84. #顯示所有回合猜測值及結果 def show_detail(guesslist, resultlist): for i in range(len(guesslist)) : print ('(%d) %s/%s' % (i + 1, guesslist[i], resultlist[i])) #比對guess與answer數值字串內容,回傳?A?B之a, b值 def check(guess, answer): a = b = 0 for i in range(4): if guess[i] in answer: if i == answer.find(guess[i]) : a += 1 else: b += 1 return a, b 應用實例:猜數字遊戲 4/11 84
  85. 85. #找下⼀組數值不重複的4位數數值字串 def next_guess(): global guess if (guess < 123): print('提示有誤,請重新檢查') sys.exit() while (True): temp = guess tempguess = ['0', '0', '0', '0'] for i in range(3, -1, -1): tempguess[i] = chr(temp % 10 + 48) temp //= 10 computer_guess = ''.join(tempguess) for ch in computer_guess: #檢查數字字串是否有重複的數字 if (computer_guess.count(ch) > 1): guess -= 1 #換下⼀個數字 break; else: return computer_guess #回傳猜測值 應用實例:猜數字遊戲 5/11 85
  86. 86. #驗證猜測值的合理性,假設猜測值為正確答案,那麼與先前所有猜測值應得到同樣的比對結果 def is_reasonable(numstr): for c in range(len(computerNums)): a, b = check(numstr, computerNums[c]) if ((chr(a + 48) != computerHints[c][0]) or (chr(b + 48) != computerHints[c][2])): return False #與先前比對結果不吻合 return True 應用實例:猜數字遊戲 6/11 86
  87. 87. #玩家回合處理作業 def player_turn(): wellform = False while (wellform == False): user_guess = input('輸入四個不重複數字:') if (user_guess.isdigit() == False) : print ('***錯誤:只能輸入數字,請重新輸入') continue if (len(user_guess) != 4) : print ('***錯誤:必須輸入四個數字,請重新輸入') continue for ch in user_guess: #檢查是否有重複的數字 if (user_guess.count(ch) > 1): print ('***錯誤:數字不可重複,請重新輸入') break else: wellform = True 應用實例:猜數字遊戲 7/11 87
  88. 88. a, b = check(user_guess, answer) #檢查猜測結果 result = '%dA%dB' %(a, b) print(result) playerNums.append(user_guess) #記錄猜測值 playerHints.append(result) #記錄答案提示 return (a == 4) 應用實例:猜數字遊戲 8/11 88
  89. 89. #電腦回合處理作業 def computer_turn(): global guess if (count == 0): computer_guess = '1357' elif (count == 1): computer_guess = '8642' else: validate = False while (validate == False): computer_guess = next_guess() if (is_reasonable(computer_guess)): validate = True else: guess -= 1 #換下⼀組數值 print('電腦猜%s' %computer_guess) 應用實例:猜數字遊戲 9/11 89
  90. 90. a = int(input('有幾個數字及位置都正確?')) b = int(input('有幾個數字正確,但位置不正確?')) result = '%dA%dB' %(a, b) print(result) if (a == 4): return True else: computerHints.append(result) #記錄猜測提示 computerNums.append(computer_guess) #記錄猜測結果 guess -= 1 return False 應用實例:猜數字遊戲 10/11 90
  91. 91. #主程式 while (True): print ('-' * 20) print('player's turn') show_detail(playerNums, playerHints) if (player_turn()): print ('Congratulations! Your are winner !!') break; print ('-' * 20) print('computer's turn') show_detail(computerNums, computerHints) if (computer_turn()): print ('Computer wins this game !!') break; count += 1 應用實例:猜數字遊戲 11/11 91
  92. 92.  程式中若要使用math套件的sqrt函式,又要使用squareRoot別名,則 下列匯入敘述何者正確? A. from math.sqrt as squareRoot B. from math import sqrt as squareRoot C. import math.sqrt as squareRoot D. import sqrt from math as squareRoot 自我評量 1/9 92
  93. 93.  在程式中要從10~20之間隨機產生⼀整數,下列何者正確? A. random.randint(10, 20) B. random.randrange(10, 20, 1) C. random.randint(10, 21) D. random.randrange(11, 21, 1) 自我評量 2/9 93
  94. 94.  在程式中要從0.0~1.0之間隨機產生⼀浮點數,下列何者正確? A. random.randint(0, 1) B. random.randrange(0.0, 1.0) C. random.random(0, 1) D. random.random() 自我評量 3/9 94
  95. 95.  要隨機產生⼀個整數,但這個整數必須符合下列條件  數字是3的倍數  最小數是9  最大數是99 A. import random as R print(R.randint(3, 33) * 3) B. from random import * print(randint(3, 32) * 3) C. from random import randrange print(randrange(3, 99, 3)) D. from random import randrange as rnd print(rnd(3, 99, 3)) 自我評量 4/9 95
  96. 96. 自我評量 5/9  設計⼀函式,傳入引數n為浮點數,回傳值為正整數值,則函式會使用 到下列那些敘述? A. math.abs(n) B. math.fabs(n) C. math.round(n) D. math.float(n) E. math.floor(n) F. math.ceil(n) G. math.fmod(n) H. math.int(n) 96
  97. 97.  串列 A = [1,3,9,2,5,8,4,9,6,7],呼叫 f(A, 10) 後,回傳值為何? def f(A, n): index = 0 for i in range(n): if A[i] >= A[index]: index = i return index 1. 1 2. 2 3. 7 4. 9 自我評量 6/9 97
  98. 98.  給定 g(x) 函式如下,則 g(13) 傳回值為何? def g(x): if (x > 1): return g(x - 2) + 3 return x 1. 16 2. 18 3. 19 4. 22 自我評量 7/9 98
  99. 99. 自我評量 8/9  下列程式碼是⼀個計算n階層的函式,請問要如何修改才能到正確旳結 果? 1. def f(n): 2. fac = 1 3. if (n >= 0): 4. fac = n * f(n - 1) 5. return fac 1. 第2行改為fac = n 2. 第4行改為fac = n * f(n + 1) 3. 第3行改為if (n > 0): 4. 第4行改為fac = fac * f(n - 1) 99
  100. 100. 自我評量 9/9  給定下列g()函式及k()函式,執行g(3)後的傳回值為何? def k(a, n): if (n >= 0): return (k(a, n - 1) + a[n]) else: return 0 def g(n): a = [5, 4, 3, 2, 1] return k(a, n) 1. 5 2. 12 3. 14 4. 15 100

×