---
title: 進階資料結構
tags: 教學簡報
---
# 遞迴函數
函數自己呼叫自己
----
## 費氏數列
$$
F_n = \begin{cases}
1, &\text{ if } n = 1 \text{ or } 2\\
F_{n-1} + F_{n-2}, &\text{ if } n > 2
\end{cases}
$$
```python!
def fib(n):
if n <= 2:
return 1
else:
return fib(n - 1) + fib(n - 2)
n = int(input('想看費氏數列前幾項?'))
for x in range (1, n + 1): # fib(1) ~ fib(n)
print(fib(x), end=' ')
# 1 1 2 3 5 8 ...
```
---
# list
----
## 宣告方式 : [逗點分隔的清單]
```python!
nums = [1, 2, 3.0, '4'] # 不一定要相同型別
arr = [] # 也可以是空的 list
```
----
## 取得 list 的元素
```python!
# 0, 1, 2, 3
# -4, -3, -2, -1
nums = [ 1, 1, 2, 3]
print(nums[0]) # 1
print(nums[2]) # 2
print(nums[-1]) # 3
print(nums[-2]) # 2
```
----
## 新增元素到 list 結尾
```python!
nums = [1, 1, 2, 3]
nums.append(5)
print(nums) # [1, 1, 2, 3, 5]
```
----
## 練習
輸入一個 list,再把他 print 出來。
```python
n = int(input('請輸入 list 的長度:'))
# 提示:迴圈 + 一個個 append
```
期望執行結果:
```
請輸入 list 的長度:3
4
5
6
[4, 5, 6]
```
----
### 參考解答
```python
n = int(input('請輸入 list 的長度:'))
arr = []
for i in range(n):
inp = int(input())
arr.append(inp)
print(arr)
```
----
## 取得 list 的長度:len()
```python
arr = []
len(arr) # 0
arr = [2, 4, 6]
len(arr) # 3
```
----
## 練習
給定一個 list, 印出裡面每個元素 + 1
```python
arr = [1, 3, 5, 2, 4, 6]
# 提示:迴圈
```
----
### for 迴圈解 1
```python
arr = [1, 3, 5, 2, 4, 6]
for i in range(len(arr)):
print(arr[i] + 1)
```
----
### for 迴圈解 2
```python
arr = [1, 3, 5, 2, 4, 6]
for a in arr: # 這樣 a 會依序是 arr 內的每個元素
print(a + 1)
```
----
## 練習
給定一個 list, 找出裡面最大的元素
```python
arr = [1, 3, 5, 6, 4, 2]
# 提示:使用變數來紀錄目前最大值
```
----
### 參考答案
```python
arr = [1, 3, 5, 6, 4, 2]
maxval = arr[0]
for i in range(1, len(arr)): # i from 1 to len(arr)
if arr[i] > maxval: # 若看到比目前的最大值還大的元素
maxval = arr[i] # 更新最大值
print(maxval) # 6
```
----
## max(), min()
內建用來找最大、最小值的函數
----
```python!
m = min(10, 20, 30, 40)
print(m) # 10 (最小值)
arr = [1, 3, 5, 6, 4, 2]
# 也可以用來找 list 內的最大值
print(max(arr)) # 6
```
----
## 補充:sorted()
回傳排序過的 list
```python!
arr = [-2, 6, 5, 8, 200, 6]
print(sorted(arr)) # [-2, 5, 6, 6, 8, 200] (小排到大)
print(arr) # [-2, 6, 5, 8, 200, 6] (arr 不會變)
# 指定 reverse=True 會把排的順序顛倒
print( sorted(arr, reverse=True) )
# [200, 8, 6, 6, 5, -2] (大排到小)
```
----
## 補充:插入元素到指定的 index
```python!
nums = [1, 1, 2, 3, 5]
# 在 1 這個 index 插入 0, 原本在 1 的元素被往後移
nums.insert(1, 0)
print(nums) # [1, 0, 1, 2, 3, 5]
```
----
## 補充:移除指定 index 的元素
```python!
nums = [2, 4, 6, 8, 10]
del nums[3] # 移除 index 為 3 的元素 (8)
print(nums) # [2, 4, 6, 10]
```
----
## 補充:list comprehension
```python!
arr1 = [2, 4, 6, 8, 10]
arr2 = [ x//2 for x in arr1 ]
print(arr2) # [1, 2, 3, 4, 5]
```
有點類似數學中的寫法:
$$
\text{arr2} = \{\frac{x}{2} | x \in \text{arr1}\}
$$
----
## 補充:list comprehension
可以用這種語法來方便的建立想要的 list
```python!
arr1 = [0 for x in range(10)]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
arr2 = [x for x in range(10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
arr3 = [[0 for i in range(3)] for j in range(4)]
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
# 4 * 3 的二維陣列
```
---
# tuple
跟 list 很像,但 tuple 不能改變內容
----
## example
```python!
coord = (1, 2, 3)
print(coord[1]) # 2
coord[1] = 100 # 錯誤,tuple 不能改變內容
```
----
## 回傳多個值的函數
```python!
def get_coord():
return 1, 2 # 這種寫法隱式的回傳一個 tuple
c = get_coord() # c = (1, 2)
x, y = get_coord() # x = 1, y = 2
```
----
## 交換兩個變數
```python!
a = 1
b = 2
a, b = b, a
print(a, b) # 2 1
```
---
# dictionary (dict)
----
## 宣告 : {key: value, ...}
```python!
rick = {'class': 409, 'number': 55, 'name': 'Rick'}
```
----
### key
不可變的資料結構:數字、字串、tuple
list 和 dict 不可當 key
```python
d1 = {(1, 2): '1'} # tuple 當 key
d2 = {[1, 2]: '1'} # 錯誤:list 不可當 key
```
----
### value
任何資料結構:數字、字串、tuple、list
也可以是另外一個 dict
----
## 存取內容
```python!
print(rick['class']) # 409
```
----
## 修改/新增內容
```python!
rick['number'] = 1 # 修改 'number'
rick['gender'] = 'male' # 新增 'gender'
print(rick)
# {
# 'class': 409,
# 'number': 1,
# 'name': 'Rick',
# 'gender': 'male'
# }
```
----
## 遍歷 dict
```python!
for key, val in rick.items():
print(key, '=>', val)
# class => 409
# number => 1
# name => Rick
# gender => male
```
----
## 只取得 key 或 value
```python!
print(rick.keys()) # ['class', 'number', 'name', 'gender']
print(rick.values()) # [409, 1, 'Rick', 'male']
```
---
# module
----
## 什麼是 module
python 中的一個概念,一個 module 可以提供函數、變數給其他 module 「引用」
一個 `.py` 檔或是資料夾都可以是一個 module
----
## 怎麼用 module
import
```python
import math
print(math.pi) # 3.14159...
```
- `math` 這個 module 提供了 `pi`
- 要用 module 提供的東西就是用 `<module>.xxx`
- 如 `math.pi`
----
## 怎麼用 module
假如 import 進來後想用另一個名字叫這個 module 呢?
```python
import math as M # 之後 M 就代表 math
print(M.pi) # 3.14159...
```
----
## 怎麼用 module
我們只要 module 中的某樣東西呢?
```python
from math import pi
print(pi) # 3.14159...
from math import * # 把所有東西 import 進來
```
- 和之前的差別是不用先指定 module 的名子才能使用他提供的東西
- 之前: `math.pi`
- 現在: `pi`
----
## 怎麼寫 module
- python 會在兩個地方找 module:
- 當前資料夾
- 你自己寫的 module 就放在這
- 系統的 module 資料夾
- 內建的 module 或是後來安裝的 module
----
## 怎麼寫 module

----
## 怎麼寫 module

----
## 怎麼寫 module
- 一個 python 檔就可以是 module
- 裡面的全域變數、函數都是可以被 import 的
- 一個資料夾也可以是 module
- module 可以幫我們架構出整潔的程式碼
- 也可以在多人分工時比較好合作
---
# Discord Bot設置
----
## 先找到Discord Developer Portal

----
### 創建一個Application並點選Bot啟用後再點選OAuth2,並從裡面選擇Bot即可邀請機器人

----
## 開啟你的cmd,打上這串enter後就設置完環境了
```
pip install discord.py
```
----
## 找不到選項或忘記的人可以參考這支影片
https://www.youtube.com/watch?v=NX58mXVKXdo&t=29s