# Group 2 Week 2 part 2
###### tags: `Tag(Python)`
## :memo: [What is module and package?](https://www.learncodewithmike.com/2020/01/python-module-and-package.html)
### 模組(Module)
就是一個檔案,包含了==相關性較高==的程式碼,但隨著專案越大,開發規模就會越大,需要把關聯性較高的程式碼抽出,放在不同的檔案,形成==模組(Module)==
**EX: 所有function都放在同一個檔案**

### **將function模組化**
將上面檔案,以關聯度區分為兩個檔案==login==、==member==,並建立類別class
login.py

member.py

### 模組引用方式(Import)
使用==from-import語法==
EX: 結構範例

## 如何import
#### 方法一:
1. from 之後==加上模組(Module)的檔名====沒有.py 副檔名==,
2. 接著 import 引用所需的==物件==。

#### 方法二:
1. import 後加上 ==*== 可引用全部的物件

#### 方法三:
1. import 之後加上模組(Module)的檔名
* 和上一個語法不一樣的地方是,此語法雖然引用整個模組(Module),但是在主程式中必須透過模組(Module)的名稱來存取其中的成員。

#### 補充:
import Module as new_name: 透過==as==關鍵字,給予 Module 新的名字,這樣在後面存取 Module 中的 Function 時,我們就可以不用打那麼多字
範例:
import tool as t
print(t.sum_mul(1, 2, 3))
#### 補充:
引用模組(Module),並且執行後,會發現多了一個==pycache== 資料夾,包含了引用模組的已編譯檔案,當下一次執行主程式 main.py 時,Python編譯器看到已編譯的模組檔案,會直接載入該模組(Module),而省略編譯的動作,藉此來==加速載入模組(Module)的速度==

#### 補充: if __name__ == '__main__' 的涵義
當 Python 檔案(模組、module)被引用的時候,檔案內的每一行都會被 Python 直譯器讀取並執行,
所以當A模組引用B模組, 那B模組被引用時,也會執行一次,造成多印出不需要的結果。
因為Python 直譯器執行程式碼時,有一些內建、隱含的變數,__name__就是其中之一,其意義是「模組名稱」。
如果該檔案是被引用,其值會是『模組名稱』;(例如: A模組引用B模組, 那B模組被引用時,__name__ == 'A')
但若該檔案是(透過命令列)直接執行,其值會是『__main__』。(例如: 被引用的B模組,假設單獨執行,__name__ == '__main__')
所以在被引用的B模組的最後一段,加上if __name__ == '__main__'判斷式後,再放上那個模組要執行的結果,就能防止被引用時重覆執行
### 套件(Package)
就是一個容器(資料夾),包含了一個或多個的模組(Module),並且擁有 ==__init__.py== 檔案,其中可以撰寫套件(Package)初始化的程式碼。
#### 檔案結構:


#### 使用方法:

## :memo: [What is Pandas Module?](https://ithelp.ithome.com.tw/articles/10208412)
**介紹**
Pandas是python的一個數據分析模組,2009 年底開源出來,提供高效能、簡易使用的資料格式(Data Frame)讓使用者可以快速操作及分析資料,Pandas強化了資料處理的方便性也能與處理網頁資料與資料庫資料等,==有點類似於Office的Excel能更加方便的進行運算、分析等==
**資料結構**
1. **Series**:用來處理時間序列相關的資料(如感測器資料等),主要為==建立索引的一維陣列==。
2. **DataFrame**:用來處理結構化(Table like)的資料,==有列索引與欄標籤的二維資料集==,
* 例如關聯式資料庫、CSV 等等。
3. **Panel**:用來==處理有資料及索引、列索引與欄標籤的三維資料集==(除了特殊需求之外少使用… 略過)。
## :memo: [What is DataFrame in Pandas?](https://www.learncodewithmike.com/2020/11/python-pandas-dataframe-tutorial.html)
**介紹**
用來處理結構化(Table like)的資料,有列索引與欄標籤的二維資料集,可以==透過Dictionary或是 Arra(List)y來建立==,就像是Excel一樣具備欄與列的概念可形成完整表格形式,也可以利用外部的資料來讀取後來建立,像是資料表資料或csv檔案等

**基本用法**
```python=1
#最基本的 array + dict 可直接輸入
import pandas as pd
scores = [{"姓名":"小華","數學":90, "國文":80},
{"姓名":"小明","數學":70, "國文":55},
{"姓名":"小李","數學":45, "國文":75}]
score_df = pd.DataFrame(scores)
#純字典格式->利用from_dict功能
scores = {"姓名":["小華","小明","小李"],
"國文":[80,55,75],
"數學":[90,70,45]}
score_df = pd.DataFrame.from_dict(scores)
#兩個都會產生一樣的dataframe
#>> 姓名 國文 數學
#>> 0 小華 80 90
#>> 1 小明 55 70
#>> 2 小李 75 45
```
**其他用法 - 新增一列**
```python=1
import pandas as pd
小華 = {'數學':90, '國文':80}
小明 = {'數學':70, '國文':55}
小李 = {'數學':45, '國文':75}
df = pd.DataFrame.from_dict([小華,小明,小李])
#>> 國文 數學
#>> 0 80 90
#>> 1 55 70
#>> 2 75 45
#增加一列的方法
df['姓名'] = ['小華','小明','小李']
#這個時候就跟上面一樣了
print(df)
#>> 國文 數學 姓名
#>> 0 80 90 小華
#>> 1 55 70 小明
#>> 2 75 45 小李
```
**其他用法 - 將某一欄位設為index**
```python=19
df.set_index('姓名', inplace=True)
print(df)
#>> 國文 數學
#>> 姓名
#>> 小華 80 90
#>> 小明 55 70
#>> 小李 75 45
```
**其他用法 - head()取前N筆資料,並回傳新的pandas**
```python=26
new_df = df.head(1)
print("取得最前面的一筆資料")
print(new_df)
#>> 國文 數學
#>> 姓名
#>> 小華 80 90
```
**其他用法 - tail():取得最後面的n筆資料,並且會回傳一個新的Pandas**
```python=26
new_df = df.tail(1)
print("取得最後面一筆資料")
print(new_df)
#>> 國文 數學
#>> 姓名
#>> 小李 75 45
```
**其他用法 - fillna():把NaN的資料以某個值取代Pandas**
```python=26
new_df = df.fillna("N/A")
print("")
print(new_df)
#>> 國文 數學
#>> 姓名
#>> 小李 75 45
```
## :memo: [What is Exception Handling?](https://docs.python.org/zh-tw/3/tutorial/errors.html)
**攔截系統 Runtime 錯誤發生時,所產生的錯誤訊息。(或者為特定目的而 Raise Error)**
**什麼是==例外 (Exception)==**
即使一段陳述式或運算式使用了正確的語法,嘗試執行時仍可能導致錯誤。執行時檢測到的錯誤稱為例外
[**常見的錯誤**](https://medium.com/ccclub/ccclub-python-for-beginners-tutorial-edd15e2b5d1e)
**Ex: <font color="#f00">SyntaxError</font> 語法錯誤**
1. if-else statement 、 for loop 、 函式宣告的 def 等等沒有加冒號
2. 在判斷式當中,將 == 寫成 =
3. 字串前後並未完整加上引號

**Ex: <font color="#f00">ZeroDivisionError</font>**
1. 指的是我們在進行運算時,拿 ==0 當成除數==時所產生的錯誤。

**Ex: <font color="#f00">NameError</font> 使用了並未宣告過的變數**
1. 指當電腦無法找到我們所指定的變數時產生的錯誤,通常發生在打錯變數名稱,或是使用了並未宣告過的變數的時候

**Ex: <font color="#f00">TypeError</font>型別錯誤**
1. 通常出現在當我們==誤用了變數的資料型態==的時候
Ex: 試圖改變 string 字串的特定字元、對著兩個不同資料型態( int 與 float 之間除外)使用 >、<、== 等等判斷用的運算子

**Ex: <font color="#f00">IndexError</font>超出範圍**
1. 使用 list 或是 string 時可能會遇到的 IndexError,
2. 誤來自於使用了錯誤的 index ,也就是可能使用到了可用範圍之外的 index

**處理==例外try expect==**
**try 陳述式可以==有不只一個 except 子句==,為不同的例外指定處理者,而最多只有一個處理者會被執行。處理者只處理對應的 try 子句中發生的例外,而不會處理同一 try 陳述式裡其他處理者內的例外。**
```python=1
def division(x, y):
try:
print(x/y)
except ZeroDivisionError:
print(f'{y} cannot be 0')
except TypeError:
print(f'{y} should be integer')
except:
print("Other Exceptions")
print("---Finish---")
division(100, 0)
1. 首先,執行 try 子句(try 和 except 關鍵字之間的陳述式
2. 如果沒有發生例外,則 except 子句會被跳過,try 陳述式執行完畢。
3. 如果執行 try 子句時發生了例外,則該子句中剩下的部分會被跳過。如果例外的類型與 except 關鍵字後面的例外名稱相符,則 except 子句被執行,然後,繼續執行 try/except 區塊之後的程式碼。
4. 如果發生的例外未符合 except 子句中的例外名稱,則將其傳遞到外層的 try 陳述式;如果仍無法找到處理者,則它是一個未處理例外 (unhandled exception),執行將停止
5. 如需要補抓其他的錯誤,可以再加上不帶條件的except
```
**一個 except 子句可以用一組括號內的 tuple 列舉多個例外**
```python=1
def division(x, y):
try:
print(x/y)
except (TypeError, ZeroDivisionError):
print('GG')
division(100, 0)
```
**Finally: 不論在 try 區塊內的程式碼是否有出現例外,finally 區塊內的程式碼都會被執行,可以用來關閉檔案及清理資源**
```python=1
try:
print(x)
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
```
## :memo: Why do we need Exception Handling?
**程式能夠被其他人所使用的同時,我們當然==不希望程式碼在執行過程因為錯誤而中斷==,而是能夠妥善的處理這些例外情況**