# 資研 4/26 社課講義
[**提問表單**](https://forms.gle/z4dPC1JPV6uA2q9w7)
---
## Numpy
[**Numpy 官網**](https://numpy.org/)
:::danger
中文翻譯都是參考用的,如果要查資料建議用英文去查!
:::
```python=
import numpy as np
```
### 重塑 reshape
使用`arr.reshape(a, b, c...)`將原本的矩陣重新組合成指定大小的多維矩陣
>a, b, c ... 為各維度中指定個數
:::warning
注意矩陣內的元素**總數**需相同,否則會報錯
>使用 -1 可以讓電腦自行運算
:::
```python=
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
arr = arr.reshape(2, 4)
print(arr)
print(arr.shape)
```
### 疊加 stacking
分別利用`np.vstack((arr1, arr2))`、`np.hstack((arr1, arr2))`將兩 <font color="#CE0000">**Tuple、List、ndarray**</font> 依 **鉛直軸vertical axis 、 水平軸horizontal axis** 疊加,並一律用ndarray回傳值
:::warning
若使用`np.vstack`,則兩陣列**列數**需相同
若使用`np.hstack`,則兩陣列**行數**需相同
**arr1和arr2在傳入時需事先包裝成一個Tuple**
:::
```python=
# vstack 列數相同
arr1 = [[1, 2],
[3, 4],
[5, 6]]
arr2 = [[-1, 2],
[3, 4]]
np.vstack((arr1, arr2))
```
```python=
# hstack 行數相同
arr1 = [[1, 2],
[3, 4],
[5, 6]]
arr2 = [[-1, 2, 4],
[3, 4, 2],
[6, 8, 9]]
np.hstack((arr1, arr2))
```
### 轉置 transpose
$A$ 轉置後的矩陣記做 $A^T$,在程式中利用`arr.T`回傳轉置後的陣列
```python=
arr = np.array([[2, 3, 10], [4, -1, 3]])
print(arr)
print(arr.T)
```
### 迭代函數 arange
利用`np.arange(a, b, c)`可以直接創造出一個符合迭代函數的List
>a 是起點,b 是終點(不包含),c 是間隔
```python=
a = np.arange(10)
print(a)
```
### 線性間距向量 linspace
利用`np.linspace(a, b, c)`,在 a 和 b 之間取出平均的 c 個點
>範圍包含 a、b
```python=
a = np.linspace(1, 7, 3)
print(a)
```
### 矩陣乘法
程式上利用`np.dot(arr1, arr2)`或是`arr1.dot(arr2)`回傳相乘過後的矩陣
>`np.dot(arr1, arr2)`也適用於List
```python=
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[-1, 2], [6, 10]])
print(arr1.dot(arr2))
print(np.dot(arr1, arr2))
```
### 解方程式
利用`np.linalg.solve(A, B)`可以回傳該方程式未知數矩陣的值
>A 是係數矩陣,B 是常數矩陣
$3x+6y=-9$
$-x-7y=13$
```python=
A = np.array([[3, 6],
[-1, -7]])
B = np.array([-9,
13])
print(np.linalg.solve(A, B))
```
:::info
**練習**
請利用此反矩陣函式`np.linalg.inv(arr)`,寫一個不需要用`np.linalg.solve(A, B)`也能解出方程式的函式
$A*X = B$
$\Rightarrow A*A^{-1}*X = B*A^{-1}$
$\Rightarrow X = B*A^{-1}$
```python=
A = np.array([[3, 6], [-1, -7]])
B = np.array([-9, 13])
A_inv = np.linalg.inv(A)
print(np.dot(A_inv, B))
```
:::
## Random
[**Random 官網**](https://docs.python.org/zh-tw/3/library/random.html)
```python=
import random
```
### randint
利用`random.randint(a, b)`隨機產生一個 a ~ b 間的整數
>有包含 b
```python=
random.randint(1, 10)
```
### random
利用`random.random()`隨機產生一個 0 ~ 1 間的實數
>有包含 0 不包含 1
```python=
random.random()
```
### randrange
利用`random.randrange(a, b, c)`以 c 為間隔,隨機產生一個 a ~ b 間的整數
>相當於在`np.arange(a, b, c)`中,隨機取一個數字
```python=
random.randrange(1, 100, 10)
```
### choice
從 A 中隨機抽取一個元素
>A 可以是 String、List、Tuple
```python=
L = [1, 23, 3, 4, 2, 7, 18, 29, 8, 72]
random.choice(L)
```
從 A 中隨機抽取 n 個元素(可能重複)
```python=
L = [1, 23, 3, 4, 2, 7, 18, 29, 8, 72]
random.choices(L, k=3)
```
### sample
從 A 中隨機抽取 n 個元素(不重複)
```python=
L = [1, 23, 3, 4, 2, 7, 18, 29, 8, 72]
random.sample(L, k=6)
```
### shuffle
將 A 中原本的元素順序打亂
```python=
L = [1, 23, 3, 4, 2, 7, 18, 29, 8, 72]
random.shuffle(L)
print(L)
```
:::info
**練習**
請試著用`random`寫出一個終極密碼(1~100)的程式
```python=
import random
seed = random.randint(1, 100)
game = True
ceil = 100
floor = 1
c = 0
while game:
ans = int(input(f"請在{floor}~{ceil}之間猜一個數字"))
if ans > seed:
print("太大囉\n")
ceil = ans
c += 1
continue
elif ans < seed:
print("太小囉\n")
floor = ans
c += 1
continue
else: # ans = seed
c += 1
break
print(f"恭喜遊戲結束,您猜對的正確答案為{seed},一共猜了{c}次")
```
:::