├── .gitignore ├── README.md ├── cases ├── 9x9.py ├── google_lady.py ├── lotto.py ├── multiple.py ├── prime_number.py ├── video_cutter.py ├── youtube.py └── zip.py ├── examples ├── .env ├── 10-1.py ├── 10-2.py ├── 11-1.py ├── 11-2.py ├── 11-3.py ├── 12-1.py ├── 2-1.py ├── 2-2.py ├── 3-1.py ├── 3-2.py ├── 3-3.py ├── 4-1-1.py ├── 4-1-2.py ├── 4-1-3.py ├── 4-1-4.py ├── 4-1-5.py ├── 4-1.py ├── 4-2.py ├── 4-3-1.py ├── 4-3-2.py ├── 4-3.py ├── 4-4.py ├── 4-5-1.py ├── 4-5-2.py ├── 4-5.py ├── 4-6.py ├── 5-1.py ├── 5-2.py ├── 5-3.py ├── 6-1.py ├── 6-2.py ├── 6-3.py ├── 7-1.py ├── 7-2.py ├── 7-3.py ├── 8-1.py ├── 8-2.py ├── 8-3.py ├── 9-1.py ├── 9-2.py ├── 9-3.py └── myModule.py ├── python_basics.docx └── python_basics.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | test.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python_basics 2 | Python 基礎程式設計講義與範例 3 | 4 | ## 提問原則 5 | - 通則 6 | - 課程期間或結業前,可以提問、討論,要把多餘時間和資源,留給當前上課的學員;課程結束或結業後,我最多只能給一點方向,讓學員嘗試靠自己解決問題,如果打算從事資訊工作,可以聊聊或分享心得,但請不要把工作丟給我。 7 | - 寫信 8 | - E-mail: darren@darreninfo.cc 9 | - 信件標題寫上你的**班別和姓名**,或是在哪裡參與我的課程。 10 | - 提問的內容要與本專案有關,**其它課程的部分,去請益原本授課的老師**。 11 | - **不要把程式碼寄給我**,可能沒時間看,討論儘量以解決問題的方向為主。 12 | - 不符合以上幾點,將**直接刪除**,敬請見諒。 13 | - 社群 14 | - 可以在 Instagram 或 LinkedIn,然後透過傳訊來討論,沒事可以加我好友,看我發發廢文(? 15 | - 記得跟我說你是哪一班,路人我就只好略過了,我只把時間留給學生 (茶~ 16 | 17 | ## 合作聯絡方式 18 | - [YouTube](https://www.youtube.com/@darreninfo-boatman) 19 | - [Instagram](https://www.instagram.com/darreninfo.cc/) 20 | - [Facebook](https://www.facebook.com/profile.php?id=61551064765585) 21 | - [LinkedIn](https://www.linkedin.com/in/telunyang/) -------------------------------------------------------------------------------- /cases/9x9.py: -------------------------------------------------------------------------------- 1 | # 9 x 9 乘法表 2 | for i in range(1, 10): 3 | for j in range(1, 10): 4 | print(f'{i} x {j} = {i*j}', end="\t") 5 | print() -------------------------------------------------------------------------------- /cases/google_lady.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 下載 google 小姐的聲音 3 | 4 | Web API 網址: 5 | https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=zh-TW&q=你的自訂文字 6 | 7 | 將文字進行 url encode 網頁: 8 | https://www.onlinewebtoolkit.com/url-encode-decode 9 | 10 | 在 Terminal 使用 curl 指令下載 mp3: 11 | curl -X GET "https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=zh-TW&q=%E4%BD%A0%E7%9A%84%E8%87%AA%E8%A8%82%E6%96%87%E5%AD%97" -o ./test.mp3 12 | 13 | tl=zh-TW 的其它設定: 14 | https://gist.github.com/JT5D/a2fdfefa80124a06f5a9 15 | ''' 16 | import subprocess 17 | from urllib.parse import quote 18 | import os, time 19 | 20 | 21 | ''' 22 | 測試單句下載 mp3 23 | ''' 24 | # 設定給 google 小姐發音的文字 25 | words = '我的優點就是帥,缺點就是帥得不明顯' 26 | 27 | # # 轉成符合 url 格式的文字 28 | encode_url = quote(words) 29 | 30 | # 定義指令 31 | cmd = [ 32 | 'curl', 33 | '-X', 34 | 'GET', 35 | f'https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=zh-TW&q={encode_url}', 36 | '-o', 37 | f'./{words}.mp3' 38 | ] 39 | 40 | # 執行指令,回傳 Process 物件,其中的屬性 returncode == 0 代表成功 41 | std_output = subprocess.run(cmd) 42 | if std_output.returncode == 0: 43 | print(f'[{words}] 下載成功') 44 | else: 45 | print(f'[{words}] 下載失敗') 46 | 47 | 48 | 49 | ''' 50 | 將 google 小姐的聲音加速 - 使用 ffmpeg 51 | 52 | 參考網頁: 53 | https://ffmpeg.org/download.html 54 | 55 | 下載工具: 56 | - Windows 10: https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip 57 | - MacOS: https://evermeet.cx/ffmpeg/ffmpeg-110057-g1e406692e5.zip 58 | 59 | Windows 說明: 60 | 1. 下載 zip 檔,解壓縮到專案目錄 (python_basics) 底下。 61 | 2. 如果解壓縮的目錄叫作「ffmpeg-6.0-essentials_build」,請改成「ffmpeg」。 62 | 3. ffmpeg 資料夾裡面有個 bin 資料夾,裡面的 ffmpeg.exe 是主要的轉檔程式。 63 | 64 | MacOS 說明: 65 | 1. 下載 zip 檔,解壓縮後,會直接看到 ffmpeg 這個檔案。 66 | 2. 給它可以執行的權限,例如在 Terminal 裡面對它輸入「chmod +x ffmpeg」。 67 | 3. 如果 ffmpeg 檔案顯示成綠色,代表它可以用來當作指令來執行,是主要的轉檔程式。 68 | 69 | 參考指令: 70 | - Windows 10: ./ffmpeg/bin/ffmpeg.exe -i test.mp3 -filter:a "atempo=1.5" test_atempo.mp3 71 | - MacOS: ./ffmpeg -i test.mp3 -filter:a "atempo=1.5" test_atempo.mp3 72 | ''' 73 | cmd = [ 74 | './ffmpeg/bin/ffmpeg.exe', # 左邊是 Windows 指令。MacOS: ./ffmpeg 75 | '-i', 76 | f'./{words}.mp3', 77 | '-filter:a', 78 | 'atempo=1.5', 79 | f'./{words}_atempo.mp3' 80 | ] 81 | std_output = subprocess.run(cmd) 82 | if std_output.returncode == 0: 83 | print(f'[{words}] 轉換成功') 84 | else: 85 | print(f'[{words}] 轉換失敗') 86 | 87 | 88 | 89 | 90 | 91 | ''' 92 | 多句下載 93 | ''' 94 | # 如果沒有自訂的資料夾,則自動新增 95 | if not os.path.exists('mp3'): 96 | os.makedirs('mp3') 97 | 98 | # 設定多個給 google 小姐發音的句子 99 | list_words = [ 100 | '人生短短幾個秋啊', 101 | '不醉不罷休', 102 | '東邊我的美人哪', 103 | '西邊黃河流' 104 | ] 105 | 106 | # 把每一句都下載成 mp3 107 | for index, words in enumerate(list_words): 108 | # 轉成符合 url 格式的文字 109 | encode_url = quote(words) 110 | 111 | # 定義指令 112 | cmd = [ 113 | 'curl', 114 | '-X', 115 | 'GET', 116 | f'https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=zh-TW&q={encode_url}', 117 | '-o', 118 | f'./mp3/{index}.mp3' 119 | ] 120 | 121 | # 執行指令,回傳 Process 物件,其中的屬性 returncode == 0 代表成功 122 | std_output = subprocess.run(cmd) 123 | if std_output.returncode == 0: 124 | print(f'[{index}] 下載成功') 125 | else: 126 | print(f'[{index}] 下載失敗') 127 | 128 | cmd = [ 129 | './ffmpeg/bin/ffmpeg.exe', # 左邊是 Windows 指令。MacOS: ./ffmpeg 130 | '-i', 131 | f'./mp3/{index}.mp3', 132 | '-filter:a', 133 | 'atempo=1.5', # 'asetrate=44100*0.4,atempo=1.5' 134 | f'./mp3/{index}_atempo.mp3' 135 | ] 136 | std_output = subprocess.run(cmd) 137 | if std_output.returncode == 0: 138 | print(f'[{index}_atempo] 轉換成功') 139 | else: 140 | print(f'[{index}_atempo] 轉換失敗') -------------------------------------------------------------------------------- /cases/lotto.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 威力彩 3 | https://www.taiwanlottery.com.tw/Superlotto638/index.asp 4 | 5 | 規則: 6 | 威力彩是一種樂透型遊戲,其選號分為兩區, 7 | 您必須從第1個選號區中的 01 ~ 38 的號碼中任選6個號碼, 8 | 並從第2個選號區中的 01 ~ 08 的號碼中任選 1 個號碼進行投注, 9 | 這 六個 + 一個 號碼即為您的投注號碼。 10 | 11 | 12 | 參考網址: 13 | [1] Python 随机数生成 14 | https://www.runoob.com/python3/python3-func-number-random.html 15 | [2] Python math 模块 16 | https://www.runoob.com/python3/python-math.html 17 | [3] Python random randint() 方法 18 | https://www.runoob.com/python3/ref-random-randint.html 19 | ''' 20 | 21 | 22 | '''匯入套件(模組)''' 23 | import random, math 24 | 25 | # 放置第一選號區 6 個號碼的變數 26 | set_01 = set() 27 | 28 | # 放置第二選號區的 1 個號碼的變數 29 | num_02 = None 30 | 31 | # 取得 1 ~ x 之間的值 32 | def get_random_num(x): 33 | ''' 34 | 假設 x 為 38, 35 | 「random.random() * x」產生的值就落在 0.00... - 37.99... 之間, 36 | 透過 math.floor() 取得無條件捨去,此時程式後面再加 1,代表產生的值落在 1 - 38 之間, 37 | 最後進行回傳 38 | ''' 39 | return math.floor( random.random() * x ) + 1 40 | 41 | 42 | # 暴力法 43 | while True: 44 | # 先取得第一選號區的六個號碼 45 | num_01 = get_random_num(38) 46 | 47 | # 如果第一選號區不足六個號碼,同時號碼也不曾在第一選號區出現過,則加入 set 48 | if len(set_01) < 6: 49 | set_01.add(num_01) 50 | else: 51 | # 為第二選號區加入一個號碼 52 | num_02 = get_random_num(8) 53 | 54 | # 離開 while 迴圈 55 | break 56 | 57 | # 有關 sorted 可參考: https://www.w3schools.com/python/ref_func_sorted.asp 58 | print('第一選號區: ', sorted(set_01, reverse=False)) 59 | print('第二選號區: ', num_02) 60 | 61 | ''' 62 | 問題1: 63 | 把 num_01 = get_random_num(38) 改成 num_01 = random.randint(1, 38) 64 | 把 num_02 = get_random_num(8) 改成 num_02 = random.randint(1, 8) 65 | 結果會是如何呢? 66 | 67 | 問題2: 68 | 是否有辦法整合「問題1」的方法,建立一個函式, 69 | 函式參數只有一個數字,代表回傳多少組選號結果? 70 | ''' -------------------------------------------------------------------------------- /cases/multiple.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 在限定範圍內,只印出某個數字的倍數 3 | ''' 4 | 5 | # 印出 3 的倍數 6 | for i in range(1, 101): 7 | if i % 3 == 0: 8 | print(i, end=" ") 9 | 10 | # 印出 50 個 = 號 11 | print("=" * 50) 12 | 13 | # 印出 2 跟 3 的公倍數 14 | for i in range(1, 101): 15 | if i % 2 == 0 and i % 3 == 0: 16 | print(i, end=" ") -------------------------------------------------------------------------------- /cases/prime_number.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 找出 1 到 n 之間的質數 3 | 4 | 5 | 參考資料: 6 | [1] 神奇的質數 7 | http://epaper.gotop.com.tw/pdf/ACL047800.pdf 8 | 9 | 10 | 規則: 11 | 無法被 1 和 自已 以外的數字整除 (整除代表餘數為 0),即為質數 12 | 13 | 14 | 例如 1 ~ 1000 以內的質數: 15 | 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 16 | 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 17 | 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 18 | 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 19 | 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 20 | 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 21 | 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 22 | 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 23 | 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 24 | 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 25 | 977 983 991 997 26 | ''' 27 | 28 | # 放置質數的列表變數 29 | list_prime_number = [] 30 | 31 | # 初始狀態,用來判斷是否為質數 (先假設處理的數字為質數) 32 | isPrimeNumber = True 33 | 34 | # 數字範別 (1 到 自訂的 num) 35 | num = 10 36 | 37 | # 每次執行一個 i,內部的 j 都會執行完一次迴圈 38 | for i in range(2, num + 1): 39 | 40 | # i 都會跟 2 ~ i 之間的值相除 41 | for j in range(2, i): 42 | 43 | # 只要 i 被 j 整除,例如 4(i) % 2(j) == 0,代表 i 不是質數 44 | if i % j == 0: 45 | 46 | # 修改狀態為「非質數」 47 | isPrimeNumber = False 48 | 49 | # 確認非質數,則直接跳出迴圈,不用將 j 整個比對過一輪,增加效率 50 | break 51 | 52 | # 計算過程中,isPrimeNumber 沒有被改為 False,代表 i 沒有被 j 整除,i 是質數 53 | if isPrimeNumber == True: 54 | 55 | # 將 i 加入質數列表 56 | list_prime_number.append(i) 57 | 58 | # 改回原先的狀態,方便下一次判斷 59 | isPrimeNumber = True 60 | 61 | # 檢視質數列表,例如 [2, 3, 5, 7] 62 | print(list_prime_number) -------------------------------------------------------------------------------- /cases/video_cutter.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 執行環境: Windows 10 3 | 4 | 套件安裝 5 | $ pip install wget 6 | 7 | 用法 8 | $ wget.download(下載來源網路連結, 存放路徑) 9 | 10 | 11 | 參考網頁 12 | [1] How to download portion of video with youtube-dl command? 13 | https://unix.stackexchange.com/questions/230481/how-to-download-portion-of-video-with-youtube-dl-command 14 | [2] FFmpeg: Seeking 15 | https://trac.ffmpeg.org/wiki/Seeking 16 | [3] Python 使用 zipfile 模組壓縮、解壓縮 ZIP 檔案教學與範例 17 | https://officeguide.cc/python-zipfile-module-compression-decompression-tutorial-examples/ 18 | [4] 下載 yt-dlp (Linux 和 MacOS 版本,要設定「chmod +x yt-dlp」,MacOS 也要改成 yt-dlp) 19 | - GitHub: https://github.com/yt-dlp/yt-dlp 20 | - Windows: https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe 21 | - Linux: https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp 22 | - MacOS: https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos 23 | [5] 下載 ffmpeg binary 24 | - 網站: https://ffmpeg.org/download.html 25 | - Windows: https://www.gyan.dev/ffmpeg/builds/ 26 | - Linux: https://ffmpeg.org/download.html#build-linux 27 | - MacOS: https://ffmpeg.org/download.html#build-mac 28 | 29 | 30 | 31 | 測試指令: 32 | 33 | - 下載影片 34 | - Windows 10: ./yt-dlp.exe https://www.youtube.com/watch?v=t0igPuDjYUE -f "b[ext=mp4]" -o "%(id)s.%(ext)s" 35 | - MacOS: ./yt-dlp "https://www.youtube.com/watch?v=t0igPuDjYUE" -f "b[ext=mp4]" -o "%(id)s.%(ext)s" 36 | 37 | - 切割影片 方式1 (設定持續時間,意思是從 ss 開始往後多少時間,速度快) 38 | - Windows 10: ./ffmpeg/bin/ffmpeg.exe -ss 00:02:43.000 -i t0igPuDjYUE.mp4 -t 00:00:24.000 -y -c copy output.mp4 39 | - MacOS: ./ffmpeg -ss 00:02:43.000 -i t0igPuDjYUE.mp4 -t 00:00:24.000 -y -c copy output.mp4 40 | 41 | - 切割影片 方式2 (準確指定結束時間,就是真的從 ss 看到 to,速度慢) 42 | - Windows 10:./ffmpeg/bin/ffmpeg.exe -i t0igPuDjYUE.mp4 -ss 00:02:39.5 -to 00:03:06 -y -c copy output.mp4 43 | - MacOS: ./ffmpeg -i t0igPuDjYUE.mp4 -ss 00:02:39.5 -to 00:03:06 -y -c copy output.mp4 44 | 45 | 可能延伸應用: 46 | [1] [nodejs] Youtube Video Downloader, Splitter and Converter (ubuntu, nodejs, socketio, ffmpeg) 47 | https://youtu.be/2whO3-DBXkw 48 | ''' 49 | 50 | import subprocess, os, wget, zipfile 51 | 52 | 53 | 54 | ''' 55 | 下載工具 56 | ''' 57 | # 下載 ffmpeg 58 | if not os.path.exists('./ffmpeg.zip'): 59 | print('[下載 ffmpeg]') 60 | wget.download( 61 | 'https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip', 62 | './ffmpeg.zip' 63 | ) 64 | 65 | # 對 ffmpeg 解壓縮 至 指定路徑 66 | with zipfile.ZipFile('./ffmpeg.zip', 'r') as zf: 67 | # 解壓縮 68 | print('[解壓縮 zip]') 69 | zf.extractall(path='./') 70 | 71 | # 更改資料夾名稱 72 | os.rename(zf.namelist()[0], './ffmpeg') 73 | 74 | # 下載 yt-dlp 75 | if not os.path.exists('./ffmpeg/bin/yt-dlp.exe'): 76 | print('[下載 yt-dlp]') 77 | wget.download( 78 | 'https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe', 79 | './ffmpeg/bin/yt-dlp.exe' 80 | ) 81 | 82 | 83 | 84 | ''' 85 | 下載影片 86 | ''' 87 | # 設定 YouTube 影片 id 和 video 連結 88 | video_id = 't0igPuDjYUE' 89 | video_url = f'https://www.youtube.com/watch?v={video_id}' 90 | # video_id = '509549031488846' 91 | # video_url = f'https://www.facebook.com/JesseTang11/videos/{video_id}' 92 | 93 | # 判斷影片是否已經下載 94 | if not os.path.exists(f'./{video_id}.mp4'): 95 | # 設定下載影片指令 96 | cmd = [ 97 | './ffmpeg/bin/yt-dlp.exe', 98 | video_url, 99 | '-f', 'w[ext=mp4]', 100 | '-o', './%(id)s.%(ext)s' 101 | ] 102 | 103 | # 執行指令,並取得輸出訊息 104 | print("[下載影片]") 105 | std_output = subprocess.run(cmd) 106 | if std_output.returncode == 0: 107 | print(f'成功') 108 | else: 109 | print(f'失敗') 110 | 111 | 112 | 113 | ''' 114 | 影像剪輯 115 | ''' 116 | # 選擇方式 1 或 2 (會影響執行程式的指令選擇) 117 | choice = 1 118 | 119 | # 定義剪輯指令 120 | if choice == 1: # 切割影片 方式1 (設定持續時間,意思是從 ss 開始往後多少時間,速度快) 121 | cmd = [ 122 | './ffmpeg/bin/ffmpeg.exe', 123 | '-ss', '00:02:43.000', 124 | '-i', f'./{video_id}.mp4', 125 | '-t', '00:00:24.000', 126 | '-y', 127 | '-c', 'copy', 128 | './output.mp4' 129 | ] 130 | elif choice == 2: # 切割影片 方式2 (準確指定結束時間,就是真的從 ss 看到 to,速度慢) 131 | cmd = [ 132 | './ffmpeg/bin/ffmpeg.exe', 133 | '-i', f'./{video_id}.mp4', 134 | '-ss', '00:02:39.5', 135 | '-to', '00:03:06', 136 | '-y', 137 | '-c', 'copy', 138 | './output.mp4' 139 | ] 140 | 141 | # 執行指令 142 | print("[切割影片]") 143 | std_output = subprocess.run(cmd) 144 | if std_output.returncode == 0: 145 | print(f'成功') 146 | else: 147 | print(f'失敗') -------------------------------------------------------------------------------- /cases/youtube.py: -------------------------------------------------------------------------------- 1 | ''' 2 | YouTube 下載工具: 3 | - 由於這類工具遊走灰色地帶,所以有時候會不穩。 4 | - 之後會跟大家介紹 youtube-dl 或 yt-dlp 這類工具,直接下載執行檔,透過指令來取得多媒體。 5 | 6 | 7 | 參考資料: 8 | [1] pytube (pip 套件版本) 9 | https://pytube.io/en/latest/index.html 10 | [2] 下載 Youtube 影片 ( mp4、mp3、字幕 ) 11 | https://steam.oxxostudio.tw/category/python/example/youtube-download.html 12 | 13 | 14 | 首先,我們到終端機 (Terminal) 輸入下列指令,然後按下 Enter 安裝套件 15 | pip install -U pytube 16 | ''' 17 | 18 | # 匯入套件 19 | from pytube import YouTube 20 | from pprint import pprint # Pretty-Print 21 | 22 | ''' 23 | 建立 pytube 物件 24 | 25 | 下列功能可以參考: https://pytube.io/en/latest/api.html 26 | ''' 27 | yt = YouTube('https://www.youtube.com/watch?v=dQw4w9WgXcQ') 28 | 29 | # 物件屬性 30 | print(f'影片標題: {yt.title}') 31 | print(f'影片長度(秒): {yt.length}') 32 | print(f'影片作者: {yt.author}') 33 | print(f'影片作者頻道網址: {yt.channel_url}') 34 | print(f'影片縮圖網址: {yt.thumbnail_url}') 35 | print(f'影片觀看數: {yt.views}') 36 | 37 | 38 | ''' 39 | 簡單說明 40 | - yt.streams 是 StreamQuery 物件 41 | - yt.streams.filter().get_highest_resolution() 指定高畫質 42 | - yt.streams.filter().get_by_resolution('360p') 指定解析度 43 | ''' 44 | 45 | # 支援哪些格式 (直接印出 yt.streams 也可以) 46 | pprint(yt.streams.all()) 47 | 48 | # 高畫質 49 | print('下載 高畫質 的影音檔...') 50 | yt.streams.filter().get_highest_resolution().download(filename='Never_Gonna_Give_You_Up.mp4') 51 | print('下載完成') 52 | 53 | # 360p 54 | print('下載 360p 的影音檔...') 55 | yt.streams.filter().get_by_resolution('360p').download(filename='Never_Gonna_Give_You_Up_360p.mp4') 56 | print('下載完成') -------------------------------------------------------------------------------- /cases/zip.py: -------------------------------------------------------------------------------- 1 | ''' 2 | ZIP 檔案解壓縮 3 | 4 | 需要下載範例檔案,請先安裝 wget 5 | $ pip install wget 6 | 7 | 參考資料 8 | [1] Python 使用 zipfile 模組壓縮、解壓縮 ZIP 檔案教學與範例 9 | https://officeguide.cc/python-zipfile-module-compression-decompression-tutorial-examples/ 10 | ''' 11 | 12 | import os, zipfile, wget 13 | 14 | # zip 檔案若是不存在 15 | if not os.path.exists("./f-instrument01.zip"): 16 | # 下載 zip 17 | wget.download( 18 | 'https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip', 19 | './ffmpeg.zip' 20 | ) 21 | 22 | 23 | # 存放路徑 (將解壓縮的內容另存到這裡) 24 | path_folder = './files' 25 | 26 | # 確認 資料夾是否存在 27 | if not os.path.exists(path_folder): 28 | # 建立資料夾 29 | os.makedirs(path_folder) 30 | 31 | try: 32 | # 對 zip 檔案解壓縮 至 指定路徑 33 | with zipfile.ZipFile("./ffmpeg.zip", 'r') as zf: 34 | # 檢視 zip 檔案內容 (zf.namelist()[0] 通常是放置檔案的資料夾) 35 | print(zf.namelist()) 36 | 37 | # 解壓縮 38 | zf.extractall(path = path_folder) 39 | except Exception as err: 40 | print('zip 無法開啟') 41 | print(err) 42 | else: 43 | print('zip 解壓縮成功') -------------------------------------------------------------------------------- /examples/.env: -------------------------------------------------------------------------------- 1 | USERNAME=darren 2 | PASSWORD=123456 -------------------------------------------------------------------------------- /examples/10-1.py: -------------------------------------------------------------------------------- 1 | # 匯入 sys 模組 2 | import sys 3 | 4 | # 確認 argv 的內容 5 | print(sys.argv) 6 | ''' 7 | 請在 Terminal 使用以下範例指令: 8 | python 10-1.py 100 3 9 | 10 | 輸出: 11 | ['10-1.py', '100', '3'] 12 | ''' 13 | 14 | # 簡單範例: 輸出 1 ~ 100 之間,3 的倍數 15 | if len(sys.argv) < 3: 16 | print("參數量不足,至少需要 3 個參數。") 17 | print("使用方式: python 10-1.py <被除數> <除數>") 18 | 19 | ''' 20 | sys.exit(): 21 | 中斷程式執行,直接結束程式, 22 | 之後的程式碼不會繼續執行 23 | ''' 24 | sys.exit() 25 | 26 | for i in range(1, int(sys.argv[1])): 27 | if i % int(sys.argv[2]) == 0: 28 | print(i, end=" ") -------------------------------------------------------------------------------- /examples/10-2.py: -------------------------------------------------------------------------------- 1 | # 匯入模組 2 | from argparse import ArgumentParser 3 | 4 | # 建立 AugumentParser 物件 5 | parser = ArgumentParser() 6 | 7 | # 加入參數與說明 (例如: -D 和 --dividend 都是參數名稱) 8 | parser.add_argument("-D", "--dividend", help="設定被除數", default=100, type=int) 9 | parser.add_argument("-d", "--divisor", help="設定除數", default=3, type=int) 10 | parser.add_argument("--msg", help="輸出說明文字", default="取得3的倍數", type=str) 11 | 12 | # 取得使用者資料 (來自指令參數) 13 | args = parser.parse_args() 14 | ''' 15 | 註1: 16 | 要撰寫 parser.parse_args(), 17 | 執行指令「python 10-2.py --help」才有效 18 | 19 | 註2: 20 | 執行指令「python 10-2.py -D 100 -d 3 --msg 輸出1到100之間3的倍數」時, 21 | -D 的資料,要用 args.dividend 去取值, 22 | -d 的資料,要用 args.divisor 去取值, 23 | --msg 的資料,因為沒有設定縮寫名稱,需要直接使用 args.msg 24 | ''' 25 | # 需要先提示使用方式的,可以設定 parser.print_help() 26 | parser.print_help() 27 | 28 | # 輸出使用者資料 29 | print(args.dividend, args.divisor, args.msg) 30 | 31 | # 簡單範例 32 | print("=" * 50) 33 | print(f"輸出訊息: {args.msg}") 34 | for i in range(1, args.dividend): 35 | if i % args.divisor == 0: 36 | print(i, end=" ") -------------------------------------------------------------------------------- /examples/11-1.py: -------------------------------------------------------------------------------- 1 | # 建立一個函式 price_a,回傳 100 2 | def price_a(): 3 | return 100 4 | 5 | # 第一個是 function 物件,第二個是執行 function (回傳 100) 的結果 6 | print(price_a) 7 | print(price_a()) 8 | 9 | # 建立函式 price_b,作為 decorator, 10 | # 收到函式物件,並在 price_b 執行該函式物件 11 | def price_b(func): 12 | ''' 13 | 將 func (price_a) 執行後所回傳的值 (100), 14 | 乘上 1.2 後,再以暱名函式回傳 15 | ''' 16 | return lambda: func() * 1.2 17 | 18 | # 修飾子執行結果 19 | myFunc = price_b(price_a) 20 | print(myFunc()) -------------------------------------------------------------------------------- /examples/11-2.py: -------------------------------------------------------------------------------- 1 | # 建立函式 price_b (decorator) 2 | def price_b(func): 3 | ''' 4 | 將 func (price_a) 執行後所回傳的值 (100), 5 | 乘上 1.2 後,再以暱名函式回傳 6 | ''' 7 | return lambda: func() * 1.2 8 | 9 | # python 以「@」作為修飾子符號 10 | @price_b 11 | def price_a(): 12 | return 100 13 | 14 | # 修飾子執行結果 15 | print(price_a()) -------------------------------------------------------------------------------- /examples/11-3.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 使用 @ 語法的修飾子可以「由下往上」疊加, 3 | 將 @price_c 放到 @price_b 上方, 4 | 再執行、輸出 price_a() 的結果看看。 5 | ''' 6 | 7 | # 建立函式 price_b (decorator) 8 | def price_b(func): 9 | ''' 10 | 將 func (price_a) 執行後所回傳的值 (100), 11 | 乘上 1.2 後,再以暱名函式回傳 12 | ''' 13 | return lambda: func() * 1.2 14 | 15 | # 用來疊加的修飾子 16 | def price_c(func): 17 | ''' 18 | 將 func (price_2) 執行後所回傳的值 (120), 19 | 乘上 2 後,再以暱名函式回傳 20 | ''' 21 | return lambda: func() * 2 22 | 23 | # 除了暱稱函式外,常見還有以下寫法 24 | ''' 25 | def tempFunc(): 26 | return func() * 2 27 | return tempFunc 28 | ''' 29 | 30 | # python 以「@」作為修飾子符號 31 | @price_c 32 | @price_b 33 | def price_a(): 34 | return 100 35 | 36 | # 修飾子執行結果 37 | print(price_a()) -------------------------------------------------------------------------------- /examples/12-1.py: -------------------------------------------------------------------------------- 1 | from dotenv import load_dotenv, dotenv_values 2 | import os 3 | 4 | # 讀取 .env 檔案 (使用 load_dotenv) 5 | load_dotenv() 6 | 7 | # 取得 .env 檔案內容 (內容的變數名稱可以是小寫,也可以是大寫) 8 | username = os.getenv('USERNAME') 9 | password = os.getenv('PASSWORD') 10 | print(username, password) 11 | 12 | # 讀取 .env 檔案 (使用 dotenv_values) 13 | config = dotenv_values(".env") 14 | 15 | # 取得 .env 檔案內容 (內容的變數名稱可以是小寫,也可以是大寫) 16 | print(config) # config = {'USERNAME': 'darren', 'PASSWORD': 123456} 17 | print(config['USERNAME'], config['PASSWORD']) -------------------------------------------------------------------------------- /examples/2-1.py: -------------------------------------------------------------------------------- 1 | x = 1 2 | name = "Alex" 3 | 4 | print(x) 5 | print(name) -------------------------------------------------------------------------------- /examples/2-2.py: -------------------------------------------------------------------------------- 1 | # 算術運算子 2 | print(9 + 4) 3 | print(3 / 2) 4 | print(2 ** 3) 5 | 6 | 7 | 8 | # 賦值運算子 9 | a = 9 10 | b = 4 11 | a += b # 等於 a = a + b 12 | print(a) 13 | c = 3 14 | d = 2 15 | d **= c # 等於 d = d ** c 16 | print(d) 17 | 18 | 19 | 20 | # 比較運算子 (用 if 判斷) 21 | e = 4 22 | if e == 4: 23 | print('e 等於 4') 24 | if e > 2: 25 | print('e 大於 2') 26 | if e != 4: 27 | print('e 不等於 4') 28 | 29 | # 如果程式區塊只需要執行 1 行程式碼,則可以這麼寫 30 | if e == 4: print('e 等於 4') 31 | 32 | 33 | 34 | # 邏輯運算子 35 | f = 8 36 | name = 'Bill' 37 | if f == 8 and name == 'Bill': 38 | print('ok') 39 | if f == 6 or name == 'Bill': 40 | print('name 等於 Bill') 41 | 42 | 43 | 44 | # 成員運算子 45 | myList = [5, 5, 6, 6, 3, 3, 1, 2] 46 | if 6 in myList: 47 | print('6 在 list 裡') 48 | if 4 not in myList: 49 | print('4 不在 list 裡') -------------------------------------------------------------------------------- /examples/3-1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 條件判斷 3 | if ... else; if ... elif ... else; True 和 False 4 | ''' 5 | 6 | # if 7 | num = 10 8 | ''' 9 | 可以用以下符號來進行條件判斷 10 | == (等於) 11 | > (大於) 12 | >= (大於等於) 13 | < (小於) 14 | <= (小於等於) 15 | != (不等於) 16 | ''' 17 | if num > 5: 18 | print("num 大於 5") 19 | 20 | # if else 21 | name = 'apple' 22 | if name == 'apple': 23 | print('名稱是 apple') 24 | else: 25 | print("名稱不是 apple") 26 | 27 | # if elif else 28 | name = 'darren' 29 | if name == "alex": 30 | print("名稱: alex") 31 | elif name == "bill": 32 | print("名稱: bill") 33 | elif name == "carl": 34 | print("名稱: carl") 35 | else: 36 | print("Not found") 37 | 38 | # 補充: True (真) 和 False (假、偽) 39 | is_available = True 40 | if is_available == True: 41 | print("真") 42 | else: 43 | print("假") 44 | 45 | # 也可以不用加「 == True」 46 | if is_available: 47 | print("真") 48 | else: 49 | print("假") -------------------------------------------------------------------------------- /examples/3-2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | while 迴圈 3 | for 迴圈 4 | ''' 5 | # while 迴圈 6 | count = 1 7 | while count <= 5: 8 | print(count, end="") 9 | count = count + 1 # 或是寫成 count += 1 10 | 11 | 12 | 13 | # for 迴圈 01 14 | ''' 15 | 用法 16 | range(n, m-1) 17 | 18 | 說明 19 | 會走訪 n 到 m-1 的數字 20 | ''' 21 | for i in range(5, 8): 22 | print(i, end = ",") 23 | 24 | 25 | 26 | # for 迴圈 02 27 | ''' 28 | 用法 29 | range(n, m-1, step) 30 | 31 | 說明 32 | 以每 step 為間距,走訪 n 到 m-1 的數字 33 | ''' 34 | for i in range(5, 20, 2): 35 | print(i, end = ",") -------------------------------------------------------------------------------- /examples/3-3.py: -------------------------------------------------------------------------------- 1 | # break 2 | ''' 3 | 說明 4 | 當偵測到字母 t 時,就會強制結束迴圈 5 | ''' 6 | for char in 'content': 7 | if char == 't': 8 | break 9 | print(char, end="") 10 | 11 | 12 | 13 | # continue 14 | ''' 15 | 說明 16 | 當偵測到字母 t 時, 17 | 會跳過本次迴圈剩下的程式碼 print(char), 18 | 但不會結束迴圈,仍然會進入下一圈繼續執行 19 | ''' 20 | for char in 'content': 21 | if char == 't': 22 | continue 23 | print(char, end="") 24 | 25 | 26 | 27 | # pass 28 | ''' 29 | 說明 30 | 當偵測到字母 t 時,會忽略該條件,繼續像正常迴圈一樣運行程序 31 | 32 | 備註 33 | 有時候寫 pass,是為了將某塊或某行列入 to-do 34 | ''' 35 | for char in 'content': 36 | if char == 't': 37 | pass 38 | print(char, end="") -------------------------------------------------------------------------------- /examples/4-1-1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 格式化字串 - 使用 % 3 | ''' 4 | # 多組文字 5 | msg = '%s, %s!' % ('Hello', 'World') 6 | print(msg) 7 | 8 | # 整數 9 | msg = 'I am %d years old.' % 5 10 | print(msg) 11 | 12 | # 文字與整數 13 | msg = '%s is %d years old.' % ('Alex', 18) 14 | print(msg) 15 | 16 | # 指定寬度 (維持 10 個字元長度,預設向右對齊) 17 | msg = '[%10s]' % 'Hello' 18 | print(msg) 19 | 20 | # 靠左對齊 (維持 10 個字元長度,向左對齊) 21 | msg = '[%-10s]' % 'Hello' 22 | print(msg) 23 | 24 | # 指定浮點數位數 25 | msg = '[%8.3f]' % 12.3456 26 | print(msg) 27 | 28 | # 指定文字長度上限 (只有文字,才在格式化字串中加入「.」來限定字串長度) 29 | msg = '[%.3s]' % 'Hello' 30 | print(msg) 31 | 32 | # 空白補 0 33 | msg = '[%06.2f]' % 3.1415926 34 | print(msg) -------------------------------------------------------------------------------- /examples/4-1-2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 格式化字串 - 使用 string.format() 3 | ''' 4 | # 嵌入文字 5 | msg = '{}, {}!'.format('Hello', 'World') 6 | print(msg) 7 | 8 | # 改變參數順序 9 | msg = '{1}, {0}'.format('Hello', 'World') 10 | print(msg) 11 | 12 | # 指定寬度 13 | msg = '[{:10}]'.format('Hello') 14 | print(msg) 15 | 16 | # 靠右對齊 17 | msg = '[{:>10}]'.format('Hello') 18 | print(msg) 19 | 20 | # 靠左對齊 21 | msg = '[{:<10}]'.format('Hello') 22 | print(msg) 23 | 24 | # 置中對齊 25 | msg = '[{:^10}]'.format('Hello') 26 | print(msg) 27 | 28 | # 指定浮點數位數 29 | msg = '[{:8.3f}]'.format(12.3456) 30 | print(msg) 31 | 32 | # 指定文字長度上限 (只有文字,才在格式化字串中加入「.」來限定字串長度) 33 | msg = '[{:.3}]'.format('Hello') 34 | print(msg) 35 | 36 | # 空白補 0 37 | msg = '[{:06.2f}]'.format(3.1415926) 38 | print(msg) -------------------------------------------------------------------------------- /examples/4-1-3.py: -------------------------------------------------------------------------------- 1 | # f-string (又稱作 formatted string literals, version >= 3.6) 2 | name = "Darren" 3 | age = 18 4 | result = f"name: {name}, age: {age}" 5 | print(result) 6 | 7 | # 靠左對齊、靠右對齊 8 | result = f"name: [{name:<10}], age: [{age:>10}]" 9 | print(result) 10 | 11 | # 靠左對齊、靠右對齊,字數不足,補「ㄏ」(沒寫補什麼,預設空格) 12 | result = f"name: [{name:ㄏ<10}], age: [{age:ㄏ>10}]" 13 | print(result) 14 | 15 | # 置中對齊 16 | result = f"name: [{name:^10}], age: [{age:^10}]" 17 | print(result) 18 | 19 | # 指定文字長度上限 (只有文字,才在格式化字串中加入「.」來限定字串長度) 20 | result = f"name: [{name:^10.2}]" 21 | print(result) -------------------------------------------------------------------------------- /examples/4-1-4.py: -------------------------------------------------------------------------------- 1 | # 取得使用者輸入的資料 2 | data = input('輸入文字後,按下 Enter: ') 3 | print(data) 4 | 5 | # 將使用者輸入強制轉型成 int 6 | num = int(input('請輸入數字: ')) 7 | print(type(num)) 8 | print(num) -------------------------------------------------------------------------------- /examples/4-1-5.py: -------------------------------------------------------------------------------- 1 | # 簡單計算 2 | expression = "2 + 3 * 4" 3 | result = eval(expression) 4 | print(result) 5 | 6 | 7 | # 執行程式碼 8 | x = 10 9 | code = "x * 2 + 5" 10 | result = eval(code) 11 | print(result) 12 | 13 | 14 | # 字串轉數值 15 | result = eval("3.14") 16 | print(type(result)) 17 | result = eval("314") 18 | print(type(result)) -------------------------------------------------------------------------------- /examples/4-1.py: -------------------------------------------------------------------------------- 1 | # 字串變數初始化 2 | string01 = "1,2,3,4" 3 | print(string01) 4 | 5 | 6 | # 替換字串 7 | ''' 8 | 用法 9 | string.replace(str1, str2) 10 | 說明 11 | 將 string 中的 str1 替換成 str2 12 | ''' 13 | string02 = "Alex" 14 | string02 = string02.replace('ex', 'len') 15 | print(string02) 16 | 17 | 18 | # 去除字串兩側空格 19 | ''' 20 | 用法 21 | string.strip() 22 | 說明 23 | 去除字串 string 左、右兩邊的空格 24 | ''' 25 | string03 = " ___ccc___ " 26 | print(string03) 27 | print(string03.strip()) 28 | 29 | 30 | # 字串變成小寫或大寫 31 | ''' 32 | 用法 33 | string.lower() 34 | 說明 35 | 將字串 string 裡的字母全部改成小寫 36 | ''' 37 | print("CAR".lower()) 38 | 39 | ''' 40 | 用法 41 | string.upper() 42 | 說明 43 | 將字串 string 裡的字母全部改成大寫 44 | ''' 45 | print("good".upper()) -------------------------------------------------------------------------------- /examples/4-2.py: -------------------------------------------------------------------------------- 1 | # 初始化一個 list 2 | ids = [1, 2, 3, 4, 5, 6] 3 | print(ids) 4 | 5 | # 新增元素在 list 尾端 6 | ids.append(7) 7 | print(ids) 8 | 9 | # 修改索引位置的元素 10 | ids[4] = 99 11 | print(ids) 12 | 13 | # 刪除索引位置的元素 14 | ids.pop(4) 15 | print(ids) 16 | 17 | # 新增元素 9 在指定索引 1,其餘元素往後移 18 | ids.insert(1, 9) 19 | print(ids) 20 | 21 | # 移除指定的值 22 | ids.remove(9) 23 | print(ids) 24 | 25 | 26 | 27 | # 補充: 字串分割成 list 28 | ''' 29 | 用法 30 | string.split() 31 | 說明 32 | 默認以空格、換行字元分割字串 string,回傳 list 33 | ''' 34 | string04 = "1,2,3,4" 35 | list04 = string04.split(',') 36 | print(list04) 37 | 38 | 39 | 40 | # 補充: 將 list 元素合併成字串 41 | ''' 42 | 用法 43 | string.join(seq) 44 | 說明 45 | 以 string 為分隔符號,將 seq 中的元素串起來成為一個新的字串 46 | ''' 47 | list05 = ['古道', '西風', '瘦馬'] 48 | string05 = '-'.join(list05) 49 | print(string05) 50 | 51 | string05 = ''.join(list05) 52 | print(string05) -------------------------------------------------------------------------------- /examples/4-3-1.py: -------------------------------------------------------------------------------- 1 | '''一般 list 用法''' 2 | list01 = [] 3 | for x in range(10): 4 | list01.append(x) 5 | print(list01) 6 | 7 | 8 | 9 | '''List Comprehension''' 10 | # 一行直接建立 list 11 | list02 = [x for x in range(10)] 12 | print(list02) 13 | 14 | # 還可以設定條件 15 | list03 = [x for x in range(10) if x % 2 == 0] 16 | print(list03) -------------------------------------------------------------------------------- /examples/4-3-2.py: -------------------------------------------------------------------------------- 1 | '''透過 enumerate() 逐一將序列的索引與值進行回傳''' 2 | seq = ['人', '帥', '真好'] 3 | for index, value in enumerate(seq): 4 | print("=" * 30) # 將字元或字串進行乘法運算,可以作到字元/字串生成的效果 5 | print(index) # 輸出 索引 6 | print(value) # 輸出 值 -------------------------------------------------------------------------------- /examples/4-3.py: -------------------------------------------------------------------------------- 1 | # 初始化一個字串 2 | myStr = 'Hello,World!' 3 | 4 | 5 | ''' 6 | 透過冒號(:)進行分割 7 | ''' 8 | # 從頭取到 5(不包含第 5 個元素,實際為 0 ~ 4) 9 | print( myStr[0:5] ) # 索引從 0 開始,到 5 - 1 的索引位置 10 | 11 | # 從頭取到 5(不包含第 5 個元素,實際為 0 ~ 4) 12 | print( myStr[:5] ) # 冒號前面留空,效果跟 [0:5] 一樣 13 | 14 | # 從 7 取到尾 15 | print( myStr[7:] ) # 冒號後面留空 16 | 17 | # 從 7 取到 9(不包含第 9 個元素,實際為 7 ~ 8) 18 | print( myStr[7:9] ) 19 | 20 | 21 | 22 | ''' 23 | 使用負號 24 | ''' 25 | # 從倒數第 10 取到倒數第 7(不包含倒數第 7 的元素) 26 | print( myStr[-10:-7] ) 27 | 28 | # 從倒數第 5 取到尾 29 | print( myStr[-5:] ) 30 | 31 | # 從頭取到倒數第 7(不包含倒數第 7 的元素) 32 | print( myStr[:-7] ) 33 | 34 | 35 | 36 | # 取得檔案全名 37 | string06 = "/home/darren/ebook.txt" 38 | list06 = string06.split("/") 39 | print(list06[-1]) 40 | 41 | 42 | 43 | # 搜尋字串 44 | string07 = 'believe' 45 | result07 = string07.find('lie') 46 | ''' 47 | 用法 48 | string.find(str) 49 | 說明 50 | 回傳 string 第一次在字串 string 中出現的 index,若找不到則回傳 -1 51 | ''' 52 | print(result07) -------------------------------------------------------------------------------- /examples/4-4.py: -------------------------------------------------------------------------------- 1 | # Tuple 初始化: 第一種 2 | myTuple01 = ("人", "帥", "得體") 3 | print(myTuple01) 4 | print(type(myTuple01)) 5 | 6 | # Tuple 初始化: 第二種 7 | myTuple02 = "哆", "啦", "A", "夢" 8 | print(myTuple02) 9 | print(type(myTuple02)) 10 | 11 | # 透過指定索引輸出值 12 | print( myTuple01[1] ) 13 | print( myTuple02[1] ) 14 | 15 | # 複數變數修改值 16 | a = 10 17 | b = 20 18 | print("交換前: a = {}, b = {}".format(a, b)) 19 | a, b = b, a 20 | print("交換後: a = {}, b = {}".format(a, b)) 21 | 22 | # list 可以修改指定索引的值 23 | myList = ["人", "帥", "任性"] 24 | myList[2] = "真好" 25 | print(myList) 26 | 27 | # tuple 不可以修改指定索引的值 28 | myTuple = ("人", "帥", "任性") 29 | myTuple[2] = "真好" 30 | print(myTuple) 31 | 32 | # 新增資料到 tuple (類似合併的方式) 33 | myTuple01 = myTuple01 + ("哈",) # 只加入 1 個字 34 | print(myTuple01) 35 | myTuple01 = myTuple01 + ("哈", "哈") # 2 個字以上,最後一個元素不用加「,」 36 | print(myTuple01) 37 | 38 | # tuple 之間可用 + 來合併 39 | myTuple03 = myTuple01 + myTuple02 40 | print(myTuple03) 41 | 42 | # 用 for 迴圈逐一輸出資料 43 | for value in myTuple01: 44 | print(value) 45 | 46 | # 用 len 計算 tuple 資料個數 47 | print( len(myTuple02) ) 48 | 49 | # 因為無法修改 tuple 的資料,所以也無法指定索引進行刪除 50 | del myTuple01[1] 51 | print(myTuple01) 52 | 53 | # 只能從記憶體刪除整個 tuple 變數 54 | del myTuple01 55 | print(myTuple01) -------------------------------------------------------------------------------- /examples/4-5-1.py: -------------------------------------------------------------------------------- 1 | # 用來建立 dict key(s) 的 list 2 | list01 = ["name", "school", "phone_number"] 3 | 4 | # 建立 dict 5 | dict01 = {key: "" for key in list01} 6 | 7 | # 檢索目前的 dict 8 | print(dict01) 9 | 10 | # 各別填寫 dict 的 value 11 | dict01['name'] = 'Alex' 12 | dict01['school'] = 'ntu' 13 | dict01['phone_number'] = '0911111111' 14 | 15 | # 檢索結果 16 | print(dict01) -------------------------------------------------------------------------------- /examples/4-5-2.py: -------------------------------------------------------------------------------- 1 | # 建立字典 2 | dict02 = {"name": "John", "age": 25, "city": "New York"} 3 | 4 | # 透過items()方法取得字典的鍵值對 5 | for t in dict02.items(): 6 | print(t) 7 | print(f"key: {t[0]}, value: {t[1]}") 8 | print("=" * 50) -------------------------------------------------------------------------------- /examples/4-5.py: -------------------------------------------------------------------------------- 1 | # 初始化 dict 2 | dict01 = {"蘋果": 100, "橘子": 20, "水梨": 50} 3 | print(dict01) 4 | 5 | ''' 6 | 上面的例子,可以透過排版,寫成: 7 | 8 | dict01 = { 9 | "蘋果": 100, 10 | "橘子": 20, 11 | "水梨": 50 12 | } 13 | ''' 14 | 15 | # 上面的初始化過程,也可以寫成: 16 | dict01 = dict() 17 | dict01['蘋果'] = 100 18 | dict01['橘子'] = 20 19 | dict01['水梨'] = 50 20 | print(dict01) 21 | 22 | # 印出蘋果的價格 23 | print(dict01["蘋果"]) 24 | 25 | # 修改橘子的價格 26 | dict01["橘子"] = 30 27 | print(dict01["橘子"]) 28 | 29 | # 刪除 水梨 30 | del dict01["水梨"] 31 | print(dict01) 32 | 33 | ''' 34 | 有時候會遇到比較複雜的結構,需要一層一層去走訪,取得資料 35 | ''' 36 | dict02 = { 37 | 'name': 'Darren', 38 | 'age': 18, 39 | 'info': { 40 | 'nickname': 'boatman', 41 | 'favorite_role': 'Doraemon', 42 | 'phone_number': [ 43 | '0911111111', 44 | '0922222222', 45 | '0933333333' 46 | ] 47 | } 48 | } 49 | 50 | # 取得 nickname 51 | print( dict02['info']['nickname'] ) 52 | 53 | # 取得所有 phone_number 54 | for number in dict02['info']['phone_number']: 55 | print(number) -------------------------------------------------------------------------------- /examples/4-6.py: -------------------------------------------------------------------------------- 1 | # Set 初始化: 第一種 2 | mySet01 = {"網路", "爬蟲", "真好玩"} 3 | print(mySet01) 4 | 5 | # Set 初始化: 第二種 (裡面放 tuple) 6 | mySet02 = set( ("網路", "爬蟲", "真好玩") ) 7 | print(mySet02) 8 | 9 | # 一筆筆讀資料 : for 迴圈 10 | for data in mySet02: 11 | print(data) 12 | 13 | # 總共有幾筆資料: len() 14 | print( len(mySet02) ) 15 | 16 | # 因為沒有序號、索引的概念,所以無法透過指定索引輸出 17 | print( mySet01[0] ) 18 | 19 | # 添加一筆資料: add() 20 | mySet01.add("嗎?") 21 | mySet02.add("對不對?") 22 | 23 | print(mySet01) 24 | print(mySet02) 25 | 26 | # 此時新增重複的資料,不會增加 27 | mySet01.add("真好玩") 28 | print(mySet01) 29 | 30 | # 添加多筆資料: update() 31 | mySet01.update(["甲", "乙", "丙"]) 32 | mySet02.update(["子", "丑", "寅"]) 33 | print(mySet01) 34 | print(mySet02) 35 | 36 | # 查詢 set 中有沒有我要的資料: in (只回傳 true 或 false) 37 | if "乙" in mySet01: 38 | print("有資料") 39 | else: 40 | print("找不到資料") 41 | 42 | # 刪除元素: discard() or remove() 43 | '''如果 .discard() 的元素不存在,不會報錯''' 44 | mySet01.discard("丙") 45 | print(mySet01) 46 | '''如果 .remove() 的元素不存在,會報錯 (KeyError)''' 47 | mySet02.remove("丑") 48 | print(mySet02) 49 | 50 | # 清空: clear()、del 51 | '''.clear() 會清空 set 變數,但變數依然存在,所以會印出空 set''' 52 | mySet01.clear() 53 | print(mySet01) 54 | ''' del 會將 set 變數從記憶體中刪除,所以刪除完後,變數會變成未宣告的狀態''' 55 | del mySet02 56 | print(mySet02) -------------------------------------------------------------------------------- /examples/5-1.py: -------------------------------------------------------------------------------- 1 | '''不回傳 值''' 2 | 3 | # 定義函式 4 | def show_name(): 5 | print("Doraemon") 6 | 7 | # 執行函式 8 | show_name() 9 | 10 | 11 | 12 | '''回傳 值''' 13 | 14 | # 定義函式 15 | def get_name(): 16 | name = "Doraemon" 17 | return name 18 | # 也可以寫成 return "Doraemon" 19 | 20 | # 執行函式 21 | result = get_name() 22 | 23 | # 輸出回傳結果 24 | print(result) 25 | 26 | 27 | 28 | '''傳遞參數''' 29 | 30 | # 定義函式 31 | def get_greeting(name): 32 | return "Hello, " + name 33 | 34 | # 執行函式 35 | result = get_greeting("Darren") 36 | 37 | # 輸出回傳結果 38 | print(result) -------------------------------------------------------------------------------- /examples/5-2.py: -------------------------------------------------------------------------------- 1 | '''區域變數無法修改全域變數''' 2 | # 全域變數 3 | name = "Bill" 4 | 5 | # 定義函式 6 | def set_name(): 7 | # 區域變數 8 | name = "Doraemon" 9 | 10 | # 執行函式 11 | set_name() 12 | 13 | # 輸出結果 14 | print(name) 15 | 16 | 17 | 18 | '''區域變數可以修改全域變數''' 19 | # 全域變數 20 | name = "Bill" 21 | 22 | # 定義函式 23 | def set_name(): 24 | ''' 25 | 想在函式內部使用、修改外部變數的值, 26 | 必須在變數前加上 global 關鍵字, 27 | 但是不能在加上 global 的時候進行變數初始化 28 | ''' 29 | global name 30 | name = "Doraemon" 31 | 32 | # 執行函式 33 | set_name() 34 | 35 | # 輸出結果 36 | print(name) -------------------------------------------------------------------------------- /examples/5-3.py: -------------------------------------------------------------------------------- 1 | # 帶入參數,並將計算結果直接回傳 2 | add = lambda x, y : x * y 3 | print( add(3, 5) ) 4 | 5 | # 回傳之前的條件判斷 (需要練習一下語法,否則一開始不好理解) 6 | abs = lambda x : x if x >= 0 else -x 7 | print( abs(5) ) 8 | print( abs(-5) ) 9 | 10 | # 不使用變數當作函式名稱,直接執行 11 | print( (lambda x,y : x * y)(4, 5) ) 12 | 13 | # 與 map 函式一起使用 14 | list_map = list(map(lambda x : x ** 2, [1, 2, 3, 4, 5])) 15 | print(list_map) 16 | 17 | # 與 sorted 函式一起使用 18 | myList = [ 19 | {"name": "Alex", "age": 18}, 20 | {"name": "Bill", "age": 25}, 21 | {"name": "Carl", "age": 21}, 22 | {"name": "Darren", "age": 10}, 23 | ] 24 | list_sorted = sorted(myList, key=lambda d: d['age'], reverse=False) 25 | print(list_sorted) -------------------------------------------------------------------------------- /examples/6-1.py: -------------------------------------------------------------------------------- 1 | # 建立一個家長類別 2 | class Parent(): 3 | def __init__(self): 4 | pass 5 | def post(self): 6 | return '發話中' 7 | 8 | # 實體化 (instantiation) 9 | obj_parent = Parent() 10 | print(obj_parent.post()) -------------------------------------------------------------------------------- /examples/6-2.py: -------------------------------------------------------------------------------- 1 | # 建立一個家長類別 2 | class Parent(): 3 | def __init__(self, height, weight): 4 | self.height = height 5 | self.weight = weight 6 | self.money = 100000000 7 | def post(self): 8 | return '發話中' 9 | 10 | # 實體化 (instantiation) 11 | obj_parent = Parent(165, 80) 12 | print(obj_parent.height) 13 | print(obj_parent.weight) 14 | print(obj_parent.money) 15 | print(obj_parent.post()) -------------------------------------------------------------------------------- /examples/6-3.py: -------------------------------------------------------------------------------- 1 | # 建立家長類別 2 | class Parent(): 3 | def __init__(self, height, weight): 4 | self.height = height 5 | self.weight = weight 6 | self.money = 100000000 7 | def post(self): 8 | return '發話中' 9 | 10 | # 建立子類別 11 | class Child(Parent): 12 | ''' 13 | 這裡的 __init__ 屬於 Child 類別的,會將 Parent 的 __init__ 覆蓋掉 14 | ''' 15 | def __init__(self, height, weight): 16 | ''' 17 | super() 代表父類別, 18 | super().__init__() 代表使用父類別的建構子, 19 | 在執行這行程式碼時,會自動將 Parent 所有屬性、方法繼承下來 20 | (包括 self.money) 21 | ''' 22 | super().__init__(height, weight) 23 | self.height = height 24 | self.weight = weight 25 | def reply(self): 26 | return '回話中' 27 | def content(self): 28 | return '我知道了' 29 | def post(self): # overwrite (覆寫) 父類別的方法 30 | return '不要再發話了' 31 | 32 | # 實體化 Parent 物件 33 | obj_parent = Parent(165, 80) 34 | print(obj_parent.height) 35 | print(obj_parent.weight) 36 | print(obj_parent.post()) 37 | 38 | # 實體化 Child 物件 39 | # (此時 Child 除了自己的屬性、方法外,還擁有父類別的屬性、方法) 40 | obj_child = Child(172, 95) 41 | print(obj_child.height) 42 | print(obj_child.weight) 43 | print(obj_child.money) 44 | print(obj_child.reply()) 45 | print(obj_child.content()) 46 | print(obj_child.post()) -------------------------------------------------------------------------------- /examples/7-1.py: -------------------------------------------------------------------------------- 1 | # 可以連續定義數個例外處理機制,最符合的例外事件類別會先拋出 2 | try: 3 | print(x) 4 | except NameError: 5 | print("x 尚未宣告") 6 | except: 7 | print("某個東西出錯了") 8 | 9 | 10 | 11 | # 多層例外處理: 內部的例外處理會優先補捉,捕捉不到,才會由在外部的例外處理來補捉 12 | try: 13 | try: 14 | print(y) 15 | except NameError as err: 16 | print("NameError:") 17 | print(str(err)) 18 | except Exception as err: 19 | print("Exception:") 20 | print(str(err)) 21 | 22 | 23 | 24 | # 如果沒有錯誤,就會執行 else 程式區塊,finally 程式區塊是無論有無錯誤,都會執行 25 | try: 26 | z = 5 27 | print(z) 28 | except NameError: 29 | print("變數尚未宣告") 30 | else: 31 | print('沒有例外發生') 32 | finally: 33 | print('程式結束') -------------------------------------------------------------------------------- /examples/7-2.py: -------------------------------------------------------------------------------- 1 | # 自訂例外處理 2 | x = -1 3 | 4 | try: 5 | if x < 0: 6 | raise Exception("數字小於 0") 7 | except Exception as e: 8 | # 可以在這裡加入處理錯誤的程式碼,例如 logging 機制 9 | print(e) 10 | 11 | 12 | # 自訂型別錯誤的例外處理 13 | x = "hello" 14 | 15 | try: 16 | if type(x) is not int: 17 | raise TypeError("只接受整數型別") 18 | except TypeError as e: 19 | # 自訂處理錯誤的程式碼 20 | print(e) -------------------------------------------------------------------------------- /examples/7-3.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | ''' 4 | Logging 設定 5 | ''' 6 | # 基本設定 7 | logger = logging.getLogger('my_app') 8 | 9 | # 設定等級 10 | logger.setLevel(logging.INFO) 11 | 12 | # 設定輸出格式 13 | formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S") 14 | 15 | # 儲存在 log 當中的事件處理器 16 | fileHandler = logging.FileHandler('my_app.log', mode='a', encoding='utf-8') # a: append, w: write 17 | fileHandler.setFormatter(formatter) 18 | 19 | # 輸出在終端機介面上的事件處理器 20 | console_handler = logging.StreamHandler() 21 | console_handler.setFormatter(formatter) 22 | 23 | # 加入事件 24 | logger.addHandler(console_handler) 25 | logger.addHandler(fileHandler) 26 | 27 | 28 | 29 | # 基本範例 30 | for x in range(0, 11): 31 | if x > 5: 32 | logger.warning(f"數字 {x} 大於 5") 33 | else: 34 | logger.info(f"數字 {x} 在合理範例") 35 | 36 | # 整合 try - except 機制 (非正式) 37 | for x in range(0, 11): 38 | try: 39 | if x > 5: 40 | raise Exception(f"數字 {x} 大於 5") 41 | else: 42 | logger.info(f"數字 {x} 在合理範例") 43 | except Exception as err: 44 | logger.warning(err) -------------------------------------------------------------------------------- /examples/8-1.py: -------------------------------------------------------------------------------- 1 | # 讀取檔案內容 - 舊的寫法 2 | f = open(file="./2-1.py", mode="r", encoding="utf-8") 3 | print( f.read() ) 4 | f.close() # 關閉檔案,否則執行期間,在關閉前,會變成唯讀狀態 5 | 6 | # 印出 50 個 等號 7 | print("=" * 50) 8 | 9 | # 讀取檔案內容 - 現今常用的寫法 (執行完畢會自動關閉檔案) 10 | with open(file="./2-1.py", mode="r", encoding="utf-8") as f: 11 | print( f.read() ) 12 | 13 | # 印出 50 個 等號 14 | print("=" * 50) 15 | 16 | # 一行一行讀出來 17 | with open(file="./2-1.py", mode="r", encoding="utf-8") as f: 18 | for line in f: 19 | print(line) # 每一行後面會用 \n 結尾,所以輸出會有多次斷行的效果 -------------------------------------------------------------------------------- /examples/8-2.py: -------------------------------------------------------------------------------- 1 | # 文字內容 2 | text = '''人生短短幾個秋啊 3 | 不醉不罷休 4 | 東邊我的美人哪 5 | ''' 6 | 7 | # 寫入檔案 8 | with open("./8-2.txt", "w", encoding="utf-8") as f: 9 | f.write(text) 10 | 11 | # 寫入最後一行 (附加文字在檔案內容最後一行) 12 | with open("./8-2.txt", "a", encoding="utf-8") as f: 13 | f.write("西邊黃河流" + "\n") -------------------------------------------------------------------------------- /examples/8-3.py: -------------------------------------------------------------------------------- 1 | # 刪除檔案 2 | import os # 匯入套件 3 | 4 | # 檔案路徑 5 | file_path = './8-2.txt' 6 | 7 | # 如果指定路徑的檔案存在,則進行刪除 8 | if os.path.exists(file_path): 9 | os.remove(file_path) 10 | else: 11 | print('Not found') -------------------------------------------------------------------------------- /examples/9-1.py: -------------------------------------------------------------------------------- 1 | # 匯入模組 2 | import myModule 3 | 4 | if __name__ == '__main__': 5 | # 計算幾次方 6 | num = myModule.pow(2, 3) 7 | print(num) 8 | 9 | # 簡單斷詞 10 | txt = "I will always love you" 11 | list_result = myModule.segment(txt) 12 | print(list_result) -------------------------------------------------------------------------------- /examples/9-2.py: -------------------------------------------------------------------------------- 1 | # 直接從模組中匯入函式 2 | from myModule import pow, segment 3 | 4 | if __name__ == '__main__': 5 | # 計算幾次方 6 | num = pow(2, 3) 7 | print(num) 8 | 9 | # 簡單斷詞 10 | txt = "I will always love you" 11 | list_result = segment(txt) 12 | print(list_result) -------------------------------------------------------------------------------- /examples/9-3.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | from pprint import pprint 3 | 4 | # 取得當前 python 版本所使用的環境變數 5 | pprint(sys.path) 6 | 7 | # 輸出當前工作/專案/教材目錄的絕對路徑 8 | print(os.getcwd()) 9 | 10 | # 設定絕對/相對路徑,取得自訂模組 11 | sys.path.insert(0, os.getcwd() + '\\examples') 12 | from myModule import pow, segment 13 | 14 | ''' 15 | 補充範例 16 | 17 | 如果在 python_basics 的上一層目錄裡,新增 modules 資料夾, 18 | 新增一個 tools.txt 記事本檔案,將 myModule.py 裡面的內容複製到 tools.txt 裡面, 19 | 而且把 tools.txt 的副檔名改成 py。 20 | 21 | 最後將前面的程式碼改成以下的樣子: 22 | 23 | sys.path.insert(0, '..\\modules') 24 | from tools import pow, segment 25 | ''' 26 | 27 | # 確認環境變數是否有新增 28 | pprint(sys.path) 29 | 30 | if __name__ == '__main__': 31 | # 計算幾次方 32 | num = pow(2, 3) 33 | print(num) 34 | 35 | # 簡單斷詞 36 | txt = "I will always love you" 37 | list_result = segment(txt) 38 | print(list_result) -------------------------------------------------------------------------------- /examples/myModule.py: -------------------------------------------------------------------------------- 1 | # 計算幾次方 2 | def pow(x, y): 3 | return x**y 4 | 5 | # 簡單斷詞 6 | def segment(text): 7 | list_words = text.split(' ') 8 | return list_words -------------------------------------------------------------------------------- /python_basics.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telunyang/python_basics/7a321a9307d3973f55aa544e4011bfc267d99fab/python_basics.docx -------------------------------------------------------------------------------- /python_basics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telunyang/python_basics/7a321a9307d3973f55aa544e4011bfc267d99fab/python_basics.pdf --------------------------------------------------------------------------------