# Python Module / import
資訊之芽 Python 語法班 2023/04/16
鄧人豪
---
## 課程大綱 Outline
----
1. Modules 概念
2. import 語法
3. 常用 Modules
4. 自己寫 Module
5. 補充
---
## Modules
----
### 什麼是 Modules?
具體來說就是:
- 一個或多個 .py 檔案
----
### 什麼是 Modules?
它的概念與用處就是:
- 把常用的程式碼包裝起來
- 下一次可以直接被其他 Python 檔案使用
- 也可以使用其他人寫好的功能,而且不用了解其中的實作細節
- 當作大型專案各個檔案之間的橋樑
---
## import
----
### 為什麼需要 import 呢?
- Modules 是一堆被包好的程式碼
- 要用 import 使用它們
----
### 4 種 import 方法
```python=
# 1. import <模組名>
import math
# 2. import <模組名> as <自訂名稱>
import math as m
# 3. from <模組名> import <該模組內的東西>
# 模組內的東西包括:<子模組>, <函式>, <變數>, <Class>
from math import factorial, sqrt, pi
# 4. from <模組名> import <該模組內的東西> as <自訂名稱>
from math import factorial as fact
```
----
### 1. import <模組名>
```python=
import math
print(math.factorial(4))    # 1 * 2 * 3 * 4 = 24
```
----
### 2. import <模組名> as <自訂名稱>
```python=
import math as m
print(m.factorial(4))    # 1 * 2 * 3 * 4 = 24
```
----
### 3. from <模組名> import <該模組內的東西>
```python=
# 模組內的東西包括:<子模組>, <函式>, <變數>, <Class>
from math import factorial, sqrt, pi
print(factorial(4))    # 1 * 2 * 3 * 4 = 24
print(sqrt(2))    # 1.4142135623730951
print(pi)    # 3.141592653589793
```
----
### 4. from <模組名> import <該模組內的東西> as <自訂名稱>
```python=
from math import factorial as fact
print(fact(4))    # 1 * 2 * 3 * 4 = 24
```
----
### 補充:從該模組 import 全部東東
- 不建議使用,在正式環境盡量避免
```python=
# from <模組名> import *
from math import *
print(factorial(4))    # 1 * 2 * 3 * 4 = 24
print(sqrt(2))    # 1.4142135623730951
print(pi)    # 3.141592653589793
# Symbol table
print(dir())    # 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e'...
```
----
### ModuleNotFoundError
```python=
import numpy as np
Traceback (most recent call last):
  File "python_path", line 1, in <module>
    import numpy as np
ModuleNotFoundError: No module named 'numpy'
```
解決辦法
- 在 command prompt 輸入:
    `pip install numpy`
- 或是在 jupyter notebook 的 cell 中輸入:
    `!pip install numpy`
----
### Questions?
---
## 常用 Modules
----
### math 數學
```python=
import math
# floor(a): a 的下高斯, ceil(a): a 的上高斯
print(math.floor(1.9), math.ceil(2.1))    # 1 3
# pow(a, b): a 的 b 次方, sqrt(a): a 的開根號
print(math.pow(2, 10), math.sqrt(2))    # 1024.0 1.4142135623730951
# gcd(a, b): a, b 的最大公因數
print(math.gcd(18, 45))    # 9
# 常數 pi 與 e
print(math.pi, math.e)    # 3.141592653589793 2.718281828459045
# sin(a), cos(a) (單位為弧度 radian)
print(math.sin(math.pi/2), math.cos(math.pi/4))    # 1.0 0.7071067811865476
```
----
### string 字串
```python=
import string
# 小寫字母:abcdefghijklmnopqrstuvwxyz
print(string.ascii_lowercase)
# 大寫字母:ABCDEFGHIJKLMNOPQRSTUVWXYZ
print(string.ascii_uppercase)
# 十六進制位元:0123456789abcdefABCDEF
print(string.hexdigits)
# 標點符號:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
print(string.punctuation)
# 數字:0123456789
print(string.digits)
```
----
### random 隨機
```python=
import random
# [0, 1) 之間的浮點數
print(random.random())
# uniform(a, b): [a, b] 之間的浮點數
print(random.uniform(1, 10))
# randint(a, b): [a, b] 之間的整數
print(random.randint(1, 10))
```
```python=
numbers = [i for i in range(10)]
print(numbers)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# choice(a): 從 list a 中隨機挑選一個
print(random.choice(numbers))
# shuffle(a): 直接將 list a 打亂
random.shuffle(numbers)
print(numbers)  # 被打亂後的 numbers
```
----
### os 操作文件目錄
```python=
import os
# 取得當前目錄
print(os.getcwd()) 
# 列出目錄底下的檔案,以根目錄為例
print(os.listdir('/'))
# 組合成完整路徑名
print(os.path.join('/usr', 'bin'))  #/usr/bin
# 檢查路徑或檔案是否存在
print(os.path.exists(path))
# 刪除檔案
print(os.remove('trash_file')) 
```
----
### sys 操作執行環境
```python=
import sys
# 命令列的參數 (list)
print(sys.argv) 
# Python 的版本
print(sys.version) 
# 操作系統平台名稱
print(sys.platform) 
# 標準輸出
print(sys.stdout)
```
----
### time 時間
```python=
import time
# 從 1970/1/1, 00:00:00 到現在經過的秒數
print(time.time()) 
# 目前時間
print(time.localtime())
# 格式化時間
print(time.asctime()) 
# 暫停 3 秒
time.sleep(3)
# 時間會比上面的多 3 秒
print(time.time())
```
----
### datetime 日期與時間
```python=
import datetime
# 現在日期與時間
t = datetime.datetime.now() # 2023-04-05 03:09:36.040984
print(t)
# 取得特定時間
print(t.year, t.month, t.day)   # 2023 4 5
# 將時間轉換成指定的字串格式
print(t.strftime("%Y %m %d %A"))  # 2023 04 05 Wednesday
```
[strftime() Format Codes](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes)
----
### Questions?
---
## 自己寫 Module
----
### 步驟:
1. 新增一個 `.py` 的 python 檔案
2. 在該檔案中定義想要的函式與變數
3. 在其他 python 檔案中 import 該 module
注意:新增的 module 檔案與使用 module 的檔案要在同一個路徑下
----
### 範例:
1. 新增一個 `number_list.py` 的 python 檔案,假如你主要使用的檔案是 `main.py`,那目錄大概會長這樣:
```text
    python_module/            頂層目錄
    ├── main.py(main.ipynb)   ├── 主要程式
    ├── number_list.py        ├── 模組檔案
```
----
### 範例:
2. 在 `number_list.py` 中定義想要的函式與變數
```python=
def get_number_list(num):
    # 取得範圍為 [0, num) 的整數 list
    number_list = [i for i in range(num)]
    return number_list
```
----
3. 在 `main.py` 或 `main.ipynb` 中 import 該 module
```python=
import number_list
num_list = number_list.get_number_list(10)
print(num_list)    # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```
注意:假如是在 `.ipnyb` 檔案中 import 其他檔案,建議加上以下程式碼。
避免在更改 module 內容後,`.ipynb` 檔案的 kernel 中記得的仍然是舊的 module 內容
```python=
%load_ext autoreload
%autoreload 2
```
[IPython autoreload 參考資料](https://ipython.org/ipython-doc/3/config/extensions/autoreload.html)
----
### Questions?
---
## 補充
----
### json 格式
----
### json 是什麼?
- 一種輕量級的資料交換格式
- 常用於網路應用程式中傳送資料
- 它使用易於閱讀和編寫的文字格式,並可被多種程式語言支援和解析
----
### json 格式處理
json 轉 python
```python=
import json
# json 格式的字串
json_string = '{ "name": "thomas", "age": 20, "email": ["email1@example.com", "email2@example.com"]}'
# 將 json 格式的字串轉為 python (這個範例中是被轉為 python dictionary)
py_dict = json.loads(json_string)
print(type(py_dict)) # <class 'dict'>
print(py_dict['name'], py_dict['age'], py_dict['email'])  # thomas 20 ["email1@example.com", "email2@example.com"]
```
----
### json 格式處理
python 轉 json
```python=
import json
# 一個 python object (dictionary)
py_dict = {
  "name": "thomas",
  "age": 20,
  "email": ["email1@example.com", "email2@example.com"]
}
# 將 python object 轉為 json 格式
json_string = json.dumps(py_dict)
print(type(json_string)) # <class 'str'>
print(json_string)  # {"name": "thomas", "age": 20, "email": ["email1@example.com", "email2@example.com"]}
```
[json viewer](https://jsoneditoronline.org/)
----
### CSV 檔案
----
### CSV (Comma Separated Values) 檔案是什麼?
- CSV 檔案是一種純文字檔案格式,其中數據以逗號分隔,每行代表一個記錄,每個記錄包含一個或者多個區段。
- 它可以被許多程式語言支援,並且常被用來在不同程式之間交換數據。
----
### CSV 檔案處理
將 list 資料寫入 csv 檔案
```python=
import csv
# 開啟要寫入的 csv 檔案
with open('output.csv', 'w', newline='') as csvfile:
    # 建立 csv 檔寫入器
    writer = csv.writer(csvfile)
    # 寫入一列 header
    writer.writerow(['name', 'height', 'weight'])
    # 寫入幾列儲存資料 (list)
    writer.writerow(['John', 175, 60])
    writer.writerow(['Thomas', 180, 57])
    writer.writerow(['Marry', 160, 49])
```
----
將 dictionary 資料寫入 csv 檔案
```python=
import csv
with open('output.csv', 'w', newline='') as csvfile:
    # 定義欄位名稱 (header)
    header = ['name', 'height', 'weight']
    # 將 dictionary 寫入 csv 檔
    writer = csv.DictWriter(csvfile, fieldnames=header)
    # 寫入第一列的欄位名稱
    writer.writeheader()
    # 寫入幾列儲存資料 (dictionary)
    writer.writerow({'name': 'John', 'height': '175', 'weight': '60'})
    writer.writerow({'name': 'Thomas', 'height': '180', 'weight': '57'})
    writer.writerow({'name': 'Marry', 'height': '160', 'weight': '49'})
```
----
你的 `output.csv` 內容應該會長這樣:
```text=
name,height,weight
John,175,60
Thomas,180,57
Marry,160,49
```
----
讀取 csv 檔案到 list 中
```python=
import csv
# 開啟 csv 檔案
with open('output.csv', 'r', newline='') as csvfile:
    # 讀取 csv 檔案內容
    rows = csv.reader(csvfile)
    # 以迴圈輸出每一列 (包括 header)
    for row in rows:
        print(row)  # 每一行都是一個 list
```
----
讀取 csv 檔案到 dictionary 中
```python=
import csv
# 開啟 csv 檔案
with open('output.csv', 'r', newline='') as csvfile:
    # 讀取 csv 檔內容,將每一列轉成一個 dictionary
    rows = csv.DictReader(csvfile)
    # 以迴圈輸出每一列 (不包括 header)
    for row in rows:
        print(row)  # 每一行都是一個 dictionary
```
----
假如我不想用 comma(逗號)分隔資料,
而是用 colon(冒號)分隔呢?
方法:在寫入時,使用
`csv.writer(..., delimiter=":")`
```python=
import csv
# 開啟要寫入的 csv 檔案
with open('output_colon_separated.csv', 'w', newline='') as csvfile:
    # 建立 csv 檔寫入器
    writer = csv.writer(csvfile, delimiter=":")
    # 寫入一列 header
    writer.writerow(['name', 'height', 'weight'])
    # 寫入幾列儲存資料 (list)
    writer.writerow(['John', 175, 60])
    writer.writerow(['Thomas', 180, 57])
    writer.writerow(['Marry', 160, 49])
```
----
你的 `output_colon_separated.csv`
內容應該會長這樣:
```text=
name:height:weight
John:175:60
Thomas:180:57
Marry:160:49
```
----
讀取 `output_colon_separated.csv` 時要用
`csv.reader(..., delimiter=":")`
```python=
import csv
# 開啟 csv 檔案
with open('output_colon_separated.csv', 'r', newline='') as csvfile:
    # 讀取 csv 檔案內容
    rows = csv.reader(csvfile, delimiter=":")
    # 以迴圈輸出每一列 (包括 header)
    for row in rows:
        print(row)  # 每一行都是一個 list
```
----
### Questions?
---
# Thanks!
             
            {"metaMigratedAt":"2023-06-18T00:53:36.074Z","metaMigratedFrom":"YAML","title":"Python Module/Import - 資訊之芽 2023 python 語法班","breaks":true,"contributors":"[{\"id\":\"4f7954d3-8899-4aaf-a4b8-756ab47563e1\",\"add\":11059,\"del\":1914}]"}