2021年1月19日 星期二

Python 3 重點筆記

內建函式庫 library,模組化程式設計 Modular Programming

使用之前需要先 import,有兩種方式:

一、非 FQNs (Fully Qualified Names),使用時只寫函式名
1 from random import randint # 注意 import 方式
2 secret = randint ( 1 , 10 ) # 包含 1 和 10,直接用函式名 randint

二、 FQNs (Fully Qualified Names),使用時須加函式庫名,可避免函式名相同
1 import random # 注意 import 方式
2 random_list = random.sample ( range(start, end, step) , list_len ) # 包含 start,不含 end,list_len 是取多少組數字,必須用函式庫名 . 函式名 random.sample,這是非重置性抽樣,抽過的不會再抽到

random

1 import random
2 seq = [1, 2, 3, 4, 5]
3 random.shuffle( seq ) # 以亂數打亂 seq list 內元素的排列順序

decimal

1 from decimal import Decimal

2 n=round(Decimal(0.115), 2)

3 m=round(float("0.115"), 2)

4 print(n, m)

urllib

1 import urllib.request
2 page = urllib.request.urlopen ( "http://beans-r-us.appspot.com/prices.html" )
3 text = page.read().decode( "utf8" )

time

import time
time . clock ( ) # 以秒呈現的現在時間,是一個 float
time . daylight ( ) # 非日光節約時間傳回 0 ,日光節約時間傳回 1
time . gmtime ( ) # 傳回不受時區影響的現在 UTC 日期和時間
time . localtime ( ) # 傳回受時區影響的現在當地時間
time . sleep ( secs ) # 等待秒數
time . time ( ) # 傳回 1970 1月 1日至今的秒數
time . timezone ( ) # 傳回 UTC 倫敦時區與你所在時區相差的小時

operator

import operator # 傳回 True or False
operator.gt ( m, n ) # 意思是 m greater than n
operator.ge ( m, n ) #意思是 m greater and equal n
operator.eq ( m, n ) #意思是 m equal n
operator.le ( m, n ) #意思是 m less and equal n
operator.lt ( m, n ) #意思是 m less than n

sqlite3

1 import sqlite3 # 資料庫 sqlite3 函式庫
2 db = sqlite3.connect ("surfer.sdb")
3 db.row_factory = sqlite3.Row
4 cursor = db.cursor ( )
5 cursor.execute ("select * from surfer")
6 rows = cursor.fetchall ( )
7 for each_row in rows:

itertools

1 items = ['a', 'a', 'c']
2 from itertools import permutations
3 for p in permutations(items,3): # 任 3 個排列,重順序,不是重複
4     print(p) # print(list(p))
 
output:
('a', 'a', 'c')
('a', 'c', 'a')
('a', 'a', 'c')
('a', 'c', 'a')
('c', 'a', 'a')
('c', 'a', 'a')

output:(任 2 個排列)
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')

1 from itertools import combinations
2 for c in combinations(items, 3): # 任 3 個組合
3     print(c)
 
output:
('a', 'b', 'c')
 
output:(任 2 個排列)
('a', 'b')
('a', 'c')
('b', 'c')

第三方函式庫(package,須額外安裝)

pygame

1. import pygame.mixer
2. sounds = pygame.mixer
3. sounds . init ( )
4. sounds . music . load ( " heartbeat.mp3 " ) # 播放 music 和 Sound 各支援不同音訊格式
    # s = sounds . Sound ( " heartbeat.mp3 " )
5. sounds . music . play ( )
    # channel = s . play ( )
6. while sounds . music . get_busy ( ) : # 形成一個 loop 等歌播完
    # while channel . get_busy ( ) :
7.     pass # 什麼都不做

tkinter

1. from tkinter import * # 使用 tkinter 的程式,副檔名要用 . pyw
2. app = Tk ( )
3. app . title ( " 測試視窗  " )
4. app . geometry ( " 450 x 100 + 200 + 100 " ) # ( 寬 x 長 + x 座標 + y 座標 )
5. b1 = Button ( app, text =  " 正確 ! ", width = 10, command = action )
    # action 可以是運算式或沒有引數的函式,如有引數則可以這樣寫:
       lambda arg1, arg2 : action ( arg1, arg2 )
6. b1 . pack ( side = " left ", padx = 10 ) # 左、右邊的按鈕只有 padx,上、下只有 pady
7. app . mainloop ( ) # 有返回值

布局管理的三種方式(在同一個視窗裡不能混用):
pack ( side = "left" ):較不精確的布局適用
grid ( row = 0, column = 1 ):用行列布局,多數時候是最佳的布局方式
place ( x = 10, y = 20 ):用 x, y 精確標示布局位置

widgets:
Label:單行或多行文字,不可編輯
Entry:單行文字,可編輯
Text:單行或多行文字,可編輯
checkbutton:核取方塊
askokcancel:ok cancel 確認視窗

label01 = Label ( app, textvariable = IntVar) :
IntVar ( )
DoubleVar ( )
StringVar ( )
BooleanVar ( )

check_b = Checkbutton ( app, variable = IntVar, command = start_music, text = "核取方塊" )
askokcancel ( title = "確認視窗",  message = "你確認要關閉視窗?" )

Window Manager Protocal Event:
WM_TAKE_FOCUS:
WM_SAVE_YOURSELF:
WM_DELETE_WINDOW:app.protocol ( "WM_DELETE_WINDOW", shutdown )

內建函式 built-in functionality

函式變數 . 方法(不用 import)

字串
1 s = "Where is John?"
2 print( s [ 0 ] ) #W
3 print( s [ 9 : 13 ] ) #John

array = list ( s ) # 將字串 s 轉成 list
s.count ( "sub" ) # 傳回 s 字串中 sub 出現幾次
s . endswith ( ".jpg" ) # 傳回 True 如果 s 字串的結尾是 .jpg
s . lower ( ) # 將全部小寫後的字串傳回 ,但不改變 s 字串
s . upper ( ) # 將全部大寫後的字串傳回 ,但不改變 s 字串
s . isupper( ) # s 字串是否大寫
s . islower( ) # s 字串是否小寫
s . replace ( "tomorrow" , "today" ) # 將字串中全部 tomorrow 取代為 today 後傳回 ,但不改變 s 字串
s . strip ( ) # 移除 s 字串頭尾指定字元(預設是空白),不包含 s 字串中間字元
s . find ( "python" ) # 傳回 s 字串中 python 所在的第一位索引值
s . startswith ( "$$" ) # 傳回 True 如果 s 字串的開頭是 $$
s . split ( ) # 將 s 字串依指定字元剪開(預設是空白),傳回數個子字串
"_" . join ( s ) # 將 s 字串內每個字元以 _ 隔開後傳回
print ( s [ : : -1 ] ) # 將 s 字串從後面印到前面
sorted ( s ) # 將 s 字串由小到大排列,以陣列形式傳回 ,但不改變 s 字串
len ( s ) # 字串 s 的長度
ord( "A" ) # 傳回 A 的 ASCII 碼
chr ( 65 ) # 傳回 ASCII 碼所代表的字母 A

多重變數指派 multiple assignment
( rhythm , lead , vocals , bass ) = s . split ( )

函式 functions,程式碼的再利用

1 def get_price ( price ) : # 函式宣告要在使用之前
2     return ( price )
3 print ( get_price ( price ) ) # 主程式變數 price(全域變數)與函式變數 price(區域變數) 不是同一變數

1 def send_to_twitter ( msg ) :
2     password_manager = urllib . request . HTTPPasswordMgr ( )
3     password_manager . add_password ( "Twitter API" , "http://twitter.com/statuses" , "帳號" , "密碼" )
4     http_handler = urllib . request . HTTPBasicAuthHandler ( password_manager )
5     page_opener = urllib . request . build_opener ( http_handler )
6     urllib . request . install_opener ( page_opener )
7     params = urllib . parse . urlencode ( { ' status ' : msg } )
8     resp = urllib . request . urlopen ( "http://twitter.com/statuses/update.json" , params )
9     resp . read ( )

資料結構(Data Structure)

陣列(list, array)

scores = [ 89 , 60 ]

1 scores = [ ]
2 scores . append ( "john" )

scores . count ( ) # 在 scores list 中出現幾次
scores . extend ( list ) # 一次性在 scores 後方增加一整個 list(一維陣列)
scores . append ( obj ) # 在 scores list 最後方,插入一個新項目
scores . index ( ) # 找出 scores list 中某個項目的索引值,如果找不到,會傳回異常
s in(not in) scores # 項目 s 在(不在) scores list 中
scores . insert ( index, obj ) # 在 scores list 某個索引值的後方,插入一個新項目
scores . pop ( ) # pop(0)移除並傳回 scores 第一個項目,pop( )移除並傳回 scores 最後一個項目
scores . remove ( "Marry" ) # 移除選定內容的第一個,後面項目會自動往前移動,沒有傳回值
"_" . join ( scores ) # 將陣列元素以 _ 隔開後,以字串形式傳回
del scores [0] # 移除選定 index 項目,後面項目會自動往前移動,沒有傳回值
scores . reverse ( ) # 反轉 scores list 中項目的排列順序
scores . sort ( ) # 將 scores list 中項目的排列順序由小到大排列
scores . sort ( reverse = True ) # 將 scores list 中項目的排列順序由大到小排列
len ( scores ) # scores list 長度


二維陣列(Multi-dimensional array)

1 list_row = [ ] # 一整列加入成為二維陣列
2 list_column =  [ 89, 60, 23, 56 ]
3 list_row.append ( list_column )
4 list_column =  [ 98, 46, 32, 40 ]
5 list_row.append ( list_column )
6 print ( list_row [ 0 ] [ 2 ] ) # 23

1 def creat_table(size): # 一項一項加入成為二維陣列
2     table_list = []
3     for row in range(0, size, 1):
4         table_list.append([])
5         for column in range(0, size, 1):
6             table_list[row].append(row * size + column + 1) # 內容是數學式計算產生
7     return(table_list)

Linked list

佇列(Queue)

Hash, Dictionary

1 scores = { } # 宣告 hash scores
2 scores [ 8.45 ] = "Joseph" # 8.45 是 key,Joseph 是 value
3 scores [ 7.21 ] = "Zack"
4 scores [ 9.12 ] = "Juan"
5 for each_score in scores.keys ( ) : # method keys ( ) 傳回 key list
6     print ( each_score, scores [ each_score ] )
7 for each_name in scores.values ( ) : # method values ( ) 傳回 value list
8     print ( each_score ) # value 不能反查 key
9 for each_score, each_name in scores.items ( ) : # method items ( ) 傳回 key-value pair list
10   print ( each_score, each_name )

1 line = " 101 ; Johnny ; USA "
2 s = { }
3 ( s ["id"], s ["name"], s ["country"] ) = line.split ( " ; " ) # key 也可以是文字

key不能重複,否則後面會取代前面
1 test = { "a" : 100, "b" : 200, "b" : 300 }
2 print ( test ) # { "a" : 100, "b" : 300 }

hash 沒有 sort ( ) 方法,但可用內建函數 sorted ( )
1 for each_score in sorted ( scores.keys ( ) ) : # 小到大
2 for each_score in sorted ( scores.keys ( ) , reverse = True ) : # 大到小

dict.clear ( ) # 剩下空 dict
del dict # 刪除 dict
del dict [ key ] # 刪除 key 所指的一項
len ( dict ) # 計算 key 的總數

Set


條件式

比較運算符:< 、 > 、 <= 、 >= 、 == 、 !=
邏輯運算符: and、or、not

 if branch

1 num = int ( input ( ) )
2 if num >= 70 :
3      print ( "70以上" )
4 elif num >= 60 :
5     print ( "介於60~69" )
6 else :
7     print ( "其他狀況" )

loop 迴圈

for loop
1 mylist = [ 'a' , 'b' , 'c' ]
2     for item in mylist :
3         print item

1 for item in range ( 0 , 3 , 1 ) :
2  #range(開始值,結束值(不算),間距),範例裡的間距為1,可省略不寫
3     print item

1 for i in range ( 1,10 ) :
2     if i == 3 :
3         continue
4         print i

1 result_f = open ( "results.txt" )
2 for each_line in result_f :
3     print ( each_line )
4 result_f . close ( )

while loop
1 count = 0 #初始值
2 while count < 3 : #讓迴圈結束的條件
3     print count
4     count += 1

1 count = 0
2 while True : #無窮迴圈起手式
3     print count
4     count += 1
5     if count > 2 : #當count大於2時,迴圈結束
6         break


pass、continue、break、exit() 的差異

pass:不做任何事
continue:跳出本次迴圈,進入下次迴圈
break:跳出整個迴圈
exit():程式至此全部結束

1 for element in "Python":
2     if element == "y":
3         pass
4     else:
5         print element # 印出 Pthon

1 for element in "Python":
2     if element == "t":
3         exit()
4     else:
5         print element # 印出 Py


例外處理

1 for row in range(0, map_size, 1) :
2         try :
3             column = map_list[row].index(move_where) #如果找不到 index 這行會錯
4         except Exception as ex : # 接住例外存入變數 ex
5             continue # 此例外處理方式

1 try :
2       print(n)
3 except :
4       print("發生錯誤,變數 n 沒有宣告") # try 之前如果沒有宣告變數 n,就執行例外這行
5 else :
6       print("一切正常") # try 之前如果有宣告變數 n,就執行 else 這行

輸出 print()

一般輸出:
print ( "平均:" , average )

變更連接分隔符號:
print ( 'Good', 'Bad', 'Ugly', sep = '/' )
# Output:  Good/Bad/Ugly

格式化輸出:
print ( " pi = { 1 } { 1 } { 0 } " .format ( "hello " , "world" ) ) # 帶編號
pi = world world hello
print ( " { a } , { tom } , { a }" .format ( tom="hello" , a="world" ) ) # 帶關鍵字
world , hello , world
print ( " { 0: 02d } " .format ( 8 ) ) # 整數 2 位,不足補 0
08
print ( " { 0: >6.2f } " .format ( 8 ) ) # 整體 6 位,小數 2 位,靠右對齊
  8.00


不換行輸出:
1 print ( "Hello World" , end = "" ) # end = 後放取代換行符號的字符
2 print ( " , Same Line" )

輸入 input( )

1 text = input ( "請輸入文字:" )
2 number = int ( input("請輸入數字:" ) )
3 number = float ( input("請輸入數字:" ) )

檔案讀寫

r     只能讀,不會創建不存在的文件,從頂部開始讀
r+   可讀可寫,不會創建不存在的文件,從頂部開始寫,會覆蓋之前此位置的内容,如果先讀後寫,則從底部開始寫
w+ 可讀可寫,無論讀寫,如果文件存在,則清空覆蓋整個文件,不存在則創建
w   只能寫,清空覆蓋整個文件,不存在則創建
a    只能寫,從文件底部添加内容,不存在則創建
a+  可讀可寫,無論讀寫,都從文件底部開始,所以讀不到内容,不存在則創建

file.seek ( 0 ) # 指向文件開頭

1 file_obj = open ( "scores.txt" )
2 for each_line in file_obj
3     ( name, score ) = each_line.split ( " ; " )
4     print ( name, score )
5 file.close ( ) # 一定要關閉檔案

1 with open ( "scores.txt", "a" ) as file_obj :
2     file_obj.write ( " { : 10s } { : 5d } ". format ( " Johnny ", 89 ) )
# 會自動關閉檔案

註解

# 單行註解
""" 多行註解 """ 或 ''' 多行註解 '''