# 主題
* Numpy/Matplotlib
* Flask
* beautifulsoup&Selenium
# 責編的話
* 內容先以補充為主,之後再濃縮
* 主要是介紹,可參考reference
[TOC]
# Numpy/Matplotlib(繪圖)
- [x] **學習目標**
* 理解數據處理與數值運算中的 Numpy 套件
* 使用 Matplotlib 套件繪製數據視覺化圖表
* 提升資料科學與數據分析中的效率與可視化能力
- [x] **知識點**
這篇內容詳細介紹了 `NumPy` 和 `Matplotlib`,並幫助你理解如何在 Python 中使用這兩個強大的工具來進行數值計算和數據可視化。
---
## **1. 什麼是 NumPy?為什麼要使用 NumPy?**
### 什麼是 NumPy?
`NumPy` 是一個 Python 的開源數值計算庫,它提供了多維array(`ndarray`)對象和大量的數學函數,專門用於高效處理數據和進行數值運算。它的主要優勢在於能夠對大量的數據進行高效操作,並且提供了向量化運算,可以避免傳統 Python `list`操作中的效率瓶頸。
### 為什麼使用 NumPy?
- **速度**:`NumPy` 提供的Array運算比 Python 原生`list`運算快,因為它是用 C 語言實現的底層數據結構。
- **功能強大**:除了基本的Array操作,還支持矩陣運算、隨機數生成、統計函數等高級功能,並且支持多維Array(矩陣、張量等)。
- **兼容性**:`NumPy` 是許多科學計算庫(如 `SciPy`, `Pandas`, `Matplotlib` 等)的基礎庫。
### 範例
```python
import numpy as np
# 創建一個一維 Numpy 陣列
arr = np.array([1, 2, 3, 4, 5])
print(arr)
```
輸出:
```
[1 2 3 4 5]
```
這段程式創建了一個包含五個整數的 Numpy 陣列。
---
## **2. NumPy 陣列與 Python `list`的區別**
`NumPy` 陣列和 Python `list`的最大區別在於:
- **效能**:`NumPy` 陣列的數值運算速度比 Python `list`要快得多,因為 `NumPy` 底層使用 C 語言實現的向量化操作。
- **數據類型**:`NumPy` 陣列中的所有元素必須是相同類型的,而 Python `list`可以包含不同類型的元素。
- **功能**:`NumPy` 提供了更多數學、統計運算的函數,並且可以高效處理多維數據。
### 範例
```python
import numpy as np
# 與 Python list的對比
python_list = [1, 2, 3, 4, 5]
numpy_array = np.array([1, 2, 3, 4, 5])
print(type(python_list)) # <class 'list'>
print(type(numpy_array)) # <class 'numpy.ndarray'>
```
輸出:
```
<class 'list'>
<class 'numpy.ndarray'>
```
---
## **3. NumPy 基本操作**
`NumPy` 提供了多種方法來創建和操作array。以下是一些常用的函數:
- `np.array()`:用來創建一維或多維array。
- `np.arange()`:創建規則間隔的數列。
- `np.linspace()`:創建等間隔的數列,常用於生成範圍內的數據點。
- `np.zeros()`、`np.ones()`:創建全零或全一的array。
### 範例
```python
import numpy as np
# 創建範圍內的數列
range_array = np.arange(0, 10, 2)
print(range_array) # [0 2 4 6 8]
# 創建等間隔的數列
linspace_array = np.linspace(0, 1, 5)
print(linspace_array) # [0. 0.25 0.5 0.75 1. ]
# 創建全零array
zeros_array = np.zeros((3, 3))
print(zeros_array)
```
輸出:
```
[0 2 4 6 8]
[0. 0.25 0.5 0.75 1. ]
[[0. 0. 0.],[0. 0. 0.],[0. 0. 0.]]
```
---
## **4. 數學運算與統計函數**
`NumPy` 提供了豐富的數學和統計函數來進行數據分析:
- `np.mean()`:計算平均數
- `np.median()`:計算中位數
- `np.std()`:計算標準差
- `np.sum()`:計算總和
- `np.min()`、`np.max()`:計算最小值和最大值
### 範例
```python=
import numpy as np
data = np.array([1, 2, 3, 4, 5])
print(np.mean(data)) # 3.0
print(np.median(data)) # 3.0
print(np.std(data)) # 1.4142135623730951
```
輸出:
```
3.0
3.0
1.4142135623730951
```
這段程式演示了如何使用 `NumPy` 計算array的基本統計量。
---
### **1. 什麼是Matplotlib**
Matplotlib 是一個廣泛使用的 Python 圖形繪製庫,主要用於創建靜態、動態和交互式的可視化圖表。它支持各種不同類型的圖形,包括線圖、條形圖、散點圖、直方圖等,並且非常適合用來展示數據分析和科學計算的結果。
### **2. Matplotlib 繪圖基礎**
這一部分介紹了如何使用 `Matplotlib` 創建一個簡單的折線圖:
#### 範例:
```python=
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.show()
```

#### 圖表解釋:
- **Sine Wave**:這個圖表展示了正弦波的形狀,X 軸是數值範圍(0 到 10),而 Y 軸表示對應於 X 軸的 `sin(x)` 值。這是數學中的基本波形,顯示了週期性變化。
---
### **3. 常見圖表類型**
這一部分展示了幾種常見的圖表類型:
#### 範例:散點圖(Scatter Plot)
```python=
import numpy as np # 匯入 numpy 模組
import matplotlib.pyplot as plt
# 散點圖範例
x = np.random.rand(50)
y = np.random.rand(50)
plt.scatter(x, y)
plt.title('Random Scatter Plot')
plt.show()
```

#### 圖表解釋:
- **散點圖**:這個圖展示了 50 個隨機生成的點。X 和 Y 軸的數值來自 `np.random.rand()` 函數,它會生成介於 0 和 1 之間的隨機數。每個點的座標是 `(x, y)`,並且散點圖用來顯示數據點之間的關係。此圖的目的是展示隨機分布。
---
### **4. 自定義圖表設置**
這一部分講解了如何對圖表進行標題、軸標籤、圖例等設置。
#### 範例:
```python=
import numpy as np # 匯入 numpy 模組
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x, y1, label='sin(x)')
plt.plot(x, y2, label='cos(x)')
plt.title('Sine and Cosine Waves')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
```

#### 圖表解釋:
- **Sine and Cosine Waves**:這個圖表繪製了正弦波和餘弦波。X 軸是數值範圍(0 到 10),Y 軸顯示對應於 X 軸的 `sin(x)` 和 `cos(x)` 值。圖例(`plt.legend()`)用來區分正弦波和餘弦波,並標註它們分別對應的曲線。
---
### **5. 多個子圖(Subplots)**
這部分介紹了如何在同一個畫布上繪製多個圖表,讓不同的數據可以並排展示。
#### 範例:
```python
import numpy as np # 匯入 numpy 模組
import matplotlib.pyplot as plt
fig, axs = plt.subplots(2, 1)
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
axs[0].plot(x, y1)
axs[0].set_title('Sine Wave')
axs[1].plot(x, y2)
axs[1].set_title('Cosine Wave')
plt.tight_layout()
plt.show()
```

#### 圖表解釋:
- **兩個子圖**:這個例子使用了 `plt.subplots()` 函數來創建一個 2 行 1 列的畫布,並在其中放置了兩個圖表。上方圖表顯示正弦波,下方圖表顯示餘弦波。`plt.tight_layout()` 用來避免子圖之間重疊。
---
### **6. 將 Numpy 和 Matplotlib 結合使用**
這一部分展示了如何將 `NumPy` 用來生成數據,再用 `Matplotlib` 進行可視化。
#### 範例:
```python=
import numpy as np # 匯入 numpy 模組
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.grid(True) # 顯示網格線
plt.show()
```

#### 圖表解釋:
- **Sine Wave with Grid**:這個圖顯示了正弦波,並在圖表中加入了網格線(`plt.grid(True)`)。網格線有助於讀取數據值,使得圖表更加易於解讀。
---
### **7. 進階應用:3D 繪圖**
這部分展示了如何使用 `Matplotlib` 進行 3D 圖表的繪製,這對於可視化三維數據非常有用。
#### 範例:
```python
import numpy as np # 修正:匯入 numpy 模組
import matplotlib.pyplot as plt # 確保也匯入 matplotlib
# 建立 x 和 y 的數據範圍
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
x, y = np.meshgrid(x, y)
# 計算 z 值
z = np.sin(np.sqrt(x**2 + y**2))
# 建立 3D 繪圖
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z, cmap='viridis')
# 顯示圖形
plt.show()
```

#### 圖表解釋:
- **3D Surface Plot**:這個圖表是 3D 曲面圖,顯示了 `z = sin(sqrt(x^2 + y^2))` 的表面。X 和 Y 軸代表二維空間的座標,Z 軸則是計算後的數值。這個圖使用了 `viridis` 顏色映射,使得數值區域的顏色有所區分。
---
## 先等等
# Flask (server)
- [x] 學習目標
* 了解 Flask 框架的基本概念及其用法。
* 能夠建立簡單的 Web 伺服器。
* 提升程式碼的可讀性與可維護性,並有效設計與部署 API 服務。
- [ ] 知識點
### 1. 什麼是 Flask?為什麼要使用 Flask?
Flask 是一個輕量級的 Web 框架,基於 Python 開發。它的主要目標是讓開發者能夠快速構建 Web 應用和 API。Flask 比較注重簡潔性,並不會強制開發者遵循繁瑣的規範,這使得它非常靈活且可擴展。
#### 為什麼要使用 Flask:
- **簡潔易學**:Flask 的結構和語法設計得很直觀,即使是初學者也能快速寫出一個基本的網站。
- **靈活性高**:Flask 並不綁定任何具體的資料庫或前端框架,因此開發者可以自由選擇。
- **擴展性強**:如果有更高階的需求,可以透過第三方擴展(如 `Flask-SQLAlchemy`用於資料庫管理、`Flask-WTF` 處理表單)來實現。
### 2. 使用 Flask 建立基本 Web 伺服器
Flask 是通過 `Flask` 類來創建應用的,並且使用裝飾器 `@app.route` 來設置 URL 路由。每當有 HTTP 請求進來時,Flask 會匹配路由並調用對應的view函數來處理請求。
#### 範例程式碼:
```python
from flask import Flask
app = Flask(__name__)
# 設定根路由
@app.route('/')
def hello_world():
return "Hello, World!"
if __name__ == '__main__':
app.run(debug=True)
```
#### 解析:
- `Flask(__name__)`: 創建一個 Flask 應用實例。`__name__` 參數告訴 Flask 當前模塊的名稱,這有助於定位應用的資源。
- `@app.route('/')`: 設置路由,當用戶訪問根目錄 `/` 時,Flask 會調用 `hello_world()` 函數返回 "Hello, World!"。
- `app.run(debug=True)`: 啟動應用,並開啟調試模式,當程式變更時,Flask 會自動重啟。
---
### 3. 路由參數與動態路由
Flask 支援動態路由,這意味着你可以在 URL 中包含變量,並通過這些變量來處理請求。
#### 範例程式碼:
```python
@app.route('/greet/<name>')
def greet(name):
return f"Hello, {name}!"
```
#### 解析:
- `<name>` 是一個動態路由參數,Flask 會將 URL 中的 `name` 部分提取出來並傳遞給 `greet()` 函數。
- 當用戶訪問 `/greet/Alice` 時,`name` 的值會是 "Alice",並返回 "Hello, Alice!"。
---
### 4. 處理 HTTP 方法:GET、POST、PUT、DELETE
Flask 預設處理 GET 請求,但可以使用 `methods` 參數來指定其他 HTTP 方法,例如 POST、PUT、DELETE 等。
#### 範例程式碼:
```python
from flask import request
@app.route('/submit', methods=['POST'])
def submit_data():
data = request.form['data'] # 從 POST 請求的表單數據中獲取
return f"Received data: {data}"
```
#### 解析:
- `methods=['POST']`: 指定該路由只會處理 POST 請求。
- `request.form['data']`: 從請求中提取表單資料,`form` 是一個包含所有表單字段的字典。
---
### 5. 使用模板引擎 Jinja2 渲染 HTML 頁面
Flask 使用內建的 Jinja2 模板引擎來渲染 HTML 頁面,可以將 Python 中的變量直接插入 HTML 中,實現動態頁面生成。
#### 範例程式碼:
```python
from flask import render_template
@app.route('/welcome/<name>')
def welcome(name):
return render_template('welcome.html', name=name)
```
#### 解析:
- `render_template('welcome.html', name=name)`: 渲染 `welcome.html` 模板,並將 `name` 變數傳遞給模板。模板文件中可以使用 `{{ name }}` 來顯示 `name` 變數的值。
---
### 6. 使用 Flask 的 Blueprint 組織大型應用
Blueprint 允許將大型應用拆分成多個模組,這樣可以使應用的結構更加清晰,並便於維護和擴展。
#### 範例程式碼:
```python
from flask import Blueprint
# 定義藍圖
auth_bp = Blueprint('auth', __name__)
# 設定路由
@auth_bp.route('/login')
def login():
return "Login Page"
# 註冊藍圖
app.register_blueprint(auth_bp, url_prefix='/auth')
```
#### 解析:
- `Blueprint('auth', __name__)`: 創建一個藍圖,用來處理與身份驗證相關的路由。
- `app.register_blueprint(auth_bp, url_prefix='/auth')`: 註冊藍圖,並指定路由前綴為 `/auth`,因此這個藍圖中的路由會以 `/auth/login` 來訪問。
---
### 7. 使用 Flask 的 session 管理用戶狀態
Flask 提供簡單的 session 機制,允許在多次請求之間儲存用戶資料(如登入狀態等)。
#### 範例程式碼:
```python
from flask import session
@app.route('/set_session')
def set_session():
session['user'] = 'Alice'
return "Session data set!"
@app.route('/get_session')
def get_session():
user = session.get('user', 'Guest')
return f"Hello, {user}!"
```
#### 解析:
- `session['user'] = 'Alice'`: 在 session 中儲存用戶資料。
- `session.get('user', 'Guest')`: 獲取 session 中的 `user` 資料,如果沒有則默認為 `'Guest'`。
---
### 8. 使用 Flask 中的資料庫(如 SQLite)
Flask 常與 SQLAlchemy ORM 搭配使用,提供簡單且強大的資料庫操作方式。
#### 範例程式碼:
```python
from flask_sqlalchemy import SQLAlchemy
# 初始化資料庫
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
db = SQLAlchemy(app)
# 定義資料模型
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
# 初始化資料庫
with app.app_context():
db.create_all()
```
#### 解析:
- `SQLAlchemy(app)`: 初始化資料庫物件,並與 Flask 應用關聯。
- `db.Model`: 定義資料模型類別,`User` 類會映射到資料庫中的一個表格。
---
### 9. 進階 Flask 應用:API 開發
Flask 常被用來開發 RESTful API。你可以使用 `Flask-RESTful` 套件來簡化 API 的開發過程。
#### 範例程式碼:
```python
from flask_restful import Api, Resource
api = Api(app)
class HelloWorld(Resource):
def get(self):
return {'message': 'Hello, World!'}
api.add_resource(HelloWorld, '/api/hello')
```
#### 解析:
- `Resource`: 定義 API 的資源類,`HelloWorld` 是一個資源,處理 `/api/hello` 路由的 GET 請求。
- `api.add_resource`: 把資源與路由關聯,這樣就可以通過 `/api/hello` 訪問這個資源。
---
### 10. 測試與除錯技巧
Flask 提供了許多有用的工具來幫助開發者調試應用。
- **設置中斷點**:在程式中設置 `breakpoint()` 可以啟動 Python 調試器進行調試。
- **開啟調試模式**:通過設置 `debug=True` 開啟 Flask 的調試模式,這樣可以在程式出錯時獲得詳細的錯誤訊息。
---
### 11. 使用 Lambda 函式與高階函式處理路由
Flask 允許使用高階函式來簡化路由處理,以下是使用 `lambda` 函式的範例。
#### 範例程式碼:
```python
app.add_url_rule('/square/<int:number
>', 'square', lambda number: str(number ** 2))
```
#### 解析:
- `lambda number: str(number ** 2)`: 使用匿名函式來處理數字平方的計算,當訪問 `/square/4` 時,返回 `16`。
---
# beautifulsoup&Selenium (web crawling)
- [x] 學習目標
* 了解網頁爬蟲的基本概念及其應用。
* 掌握如何使用 `BeautifulSoup` 和 `Selenium` 爬取網頁資料。
* 學習如何解析網頁資料,並將資料結構化,便於後續處理或分析。
---
- [ ] 知識點
### 1. 什麼是網頁爬蟲?為什麼要使用網頁爬蟲?
- **網頁爬蟲**(Web Crawler),也被稱為「網頁蜘蛛」,是一種自動化程序,通過 HTTP 請求從互聯網抓取網頁資料。爬蟲會遍歷網站的每個頁面,從中提取有用的資訊。
- 網頁爬蟲常被應用於:
- **資料蒐集**:許多行業會使用爬蟲收集來自網絡的資料,如價格比較、社會媒體數據分析等。
- **網站測試與監控**:定期測試網站的可用性、速度以及其內容的更新狀態。
- **搜尋引擎**:搜尋引擎會使用爬蟲來索引網站資料,讓用戶能夠進行高效的搜索。
爬蟲的目的基本上是將網頁中的有用數據提取出來,然後以結構化的形式進行儲存與處理。
---
### 2. **BeautifulSoup** 簡介及基本用法
`BeautifulSoup` 是一個用於解析 HTML 和 XML 文件的 Python 库,它可以讓我們輕鬆地提取、遍歷和修改網頁中的資料。通常,`BeautifulSoup` 被用來處理靜態網頁,因為它直接從網頁的 HTML 程式中抓取資料,無需執行 JavaScript。
#### 安裝:
```bash
pip install beautifulsoup4 requests
```
`BeautifulSoup` 需要與 `requests` 库配合使用,`requests` 用來發送 HTTP 請求,抓取網頁內容。
#### 基本用法:
```python
import requests
from bs4 import BeautifulSoup
# 發送 HTTP 請求
url = "http://example.com"
response = requests.get(url)
# 使用 BeautifulSoup 解析 HTML 內容
soup = BeautifulSoup(response.text, 'html.parser')
# 提取資料
title = soup.title.text # 提取 <title> 標籤的文本內容
print(title)
```
在這個範例中,`requests.get(url)` 發送一個 GET 請求到指定的 URL,並返回網頁的 HTML 內容。`BeautifulSoup(response.text, 'html.parser')` 則將這個 HTML 內容轉換為一個 `BeautifulSoup` 物件,讓我們可以方便地使用方法來提取其中的資料。
#### 常見的 BeautifulSoup 操作:
1. **查找元素:**
`BeautifulSoup` 提供了許多方法來查找 HTML 標籤,最常用的是 `find()` 和 `find_all()`:
```python
# 查找第一個匹配的 <a> 標籤
first_link = soup.find('a')
print(first_link)
```
`find()` 方法返回第一個匹配的元素,而 `find_all()` 則返回所有匹配的元素,並以`list`形式返回:
```python
all_links = soup.find_all('a')
for link in all_links:
print(link.get('href')) # 提取每個 <a> 標籤的 href 屬性(即鏈接)
```
2. **選擇器選擇元素:**
使用 CSS 選擇器可以快速找到特定的元素:
```python
# 使用 CSS 選擇器來選擇元素
divs = soup.select('div.classname')
for div in divs:
print(div.text)
```
`select()` 方法可以讓你通過 CSS 樣式選擇器來定位元素,這是非常靈活的方式。
---
### 3. **Selenium** 簡介及基本用法
`Selenium` 是一個強大的工具,它用來控制瀏覽器,特別適用於需要執行 JavaScript 的動態網頁。與 `BeautifulSoup` 主要針對靜態網頁不同,`Selenium` 可以幫助我們抓取由 JavaScript 渲染後的網頁資料。
#### 安裝:
```bash
pip install selenium
```
此外,`Selenium` 需要一個 WebDriver(例如 `ChromeDriver`)來控制瀏覽器,你可以從 [官方網站](https://sites.google.com/a/chromium.org/chromedriver/) 下載對應版本的 WebDriver。
#### 基本用法:
```python
from selenium import webdriver
from selenium.webdriver.common.by import By
# 啟動瀏覽器
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
# 打開網頁
driver.get("http://example.com")
# 查找元素並獲取資料
element = driver.find_element(By.TAG_NAME, 'h1')
print(element.text)
# 關閉瀏覽器
driver.quit()
```
`Selenium` 允許你控制瀏覽器進行網頁操作,可以模擬用戶的操作(如點擊按鈕、填寫表單等),並抓取由 JavaScript 渲染後的資料。
#### 操作動態網頁:
1. **等待網頁元素:**
在動態網頁中,元素可能需要時間才能加載,因此 `Selenium` 提供了顯示等待和隱式等待功能來等待元素的加載。
```python
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 等待直到指定元素可見
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "element_id"))
)
print(element.text)
```
2. **模擬點擊操作:**
在動態網站上,你可能需要模擬點擊操作來觸發某些事件(如加載更多資料):
```python
button = driver.find_element(By.ID, "button_id")
button.click()
```
---
### 4. 使用 BeautifulSoup 和 Selenium 結合
有時候網頁的資料是由 JavaScript 動態生成的,而這些資料只有在頁面完全加載後才能被提取。此時,你可以使用 `Selenium` 來模擬頁面加載和操作,然後再用 `BeautifulSoup` 來解析頁面的 HTML 結構。
#### 範例:先用 Selenium 模擬操作,再用 BeautifulSoup 解析頁面內容:
```python
from selenium import webdriver
from bs4 import BeautifulSoup
# 啟動瀏覽器
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
# 打開網頁
driver.get("http://example.com")
# 執行一些動態操作(例如點擊按鈕)
button = driver.find_element(By.ID, "load_more_button")
button.click()
# 等待頁面加載完成
driver.implicitly_wait(10)
# 用 BeautifulSoup 解析頁面
soup = BeautifulSoup(driver.page_source, 'html.parser')
# 提取資料
title = soup.title.text
print(title)
# 關閉瀏覽器
driver.quit()
```
這個範例先用 `Selenium` 控制瀏覽器加載網頁,並模擬點擊按鈕來加載更多資料,然後用 `BeautifulSoup` 解析並提取頁面中的 `<title>` 標籤。
---
### 5. 使用 Lambda 函式與高階函式結合
你可以將 `lambda` 函式與 `Selenium` 或 `BeautifulSoup` 的操作結合,實現一些簡單的資料處理操作。例如,使用 `map()` 對提取的資料進行轉換:
```python
# 使用 map() 和 lambda 函式將數字平方
numbers = [1, 2, 3, 4]
squared_numbers = `list`(map(lambda x: x ** 2, numbers))
print(squared_numbers) # [1, 4, 9, 16]
```
這樣的高階函式結合 `lambda` 使得資料的轉換和處理更加靈活高效。
---
# 工作
- [ ] 把內容潤飾
# reference
* 2022資訊之芽 py 語法班
[https://sprout.tw/py2022/slides](https://)
* 為你自己學 PYTHON
https://pythonbook.cc/chapters/basic/variable
* Python 3.13.0 Documentation
https://docs.python.org/3/
* Python 3.13.0 Module Index
https://docs.python.org/3/py-modindex.html#cap-t
* Python 3.13.0 Standard Library
https://docs.python.org/3/library/index.html
* PEP-8 Style Guide
https://peps.python.org/pep-0008/