owned this note
owned this note
Published
Linked with GitHub
# 樹莓派
## Raspberry Pi 環境介紹
* Raspberry Pi OS (舊稱 Raspbian)
* 
* 一個簡易的 Linux 系統
* 
## Linux
* 一種自由和開放原始碼的類UNIX作業系統,很多資料庫、Server都是用Linux去建立
* 
* 各種種類的linux比例
* 
## 小技巧
* help & man
* 查看指令說明
* man又比help更加詳細
* 
* google
* 你遇到的問題,一定有其他人遇過
* tab
* 列出可使用的指令 或補全指令
* ctrl-C - keyboard interrupt
* 向上方向鍵:上一個指令
## Linux文字編輯器-vim
* Linux中有很多種文字編輯器nano、vi、vim…等,在此次Lab中將使用vim作為文字編器。
* 如果沒有vim的話,用指令```sudo apt install vim```去下載
* 使用vim編輯檔案功能是透過鍵盤完成的
* 在terminal中鍵入:vim <a>"test.py"</a>。(此指令將會利用vim去建立一個檔名叫做 <a>"test.py"</a>的新檔案)
* 若當前目錄已經存在<a>"test.py"</a>,指令將會開啟此檔案。
* 按 i 進入編輯模式 按ESC退出編輯模式
* 退出編輯模式後,按:後輸入wq可以儲存並退出,按:後輸入q!
* w代表儲存 q代表退出 !代表強制執行
[vim詳細使用教學](https://linux.vbird.org/linux_basic/centos7/0310vi.php)
當然 你也可以直接用visual studio code進行檔案編輯
或者是雙擊mobaxterm左邊的檔案列表進行編輯
# python
* 為什麼要特別介紹Python?
* 樹莓派不只可以使用Python,C++、C語言…等都可以使用,但由於其功能強大,Raspberry Pi Foundation將Python指定為主要語言。
## Python的特色
* Python是一款擁有許多強大功能且容易學習的程式語言,舉凡深度學習、圖像處理、網路爬蟲…等問題,Python都有對應的第三方套件可以使用。
* Python的程式檔案副檔名為".py"檔。
* 執行.py檔時,我們需要在terminal中輸入:python 檔名.py 即可。
* Python和其他語言最大的差異在於其相較自由的撰寫風格
* 在C語言中宣告變數需要鍵入int a = 10; * 而在Python語言中你僅需要鍵入a = 10(連分號都不需要)
* Python語言有強大的社群,Stack Overflow有大量的除錯教學,甚至Youtube都有許多人製作一系列的教學影片提供學習。
* [python介紹](https://www.youtube.com/watch?v=Y8Tko2YC5hA)
# python練習
## Practice 1 變數型態 & 陣列取數值 & 字串與變數輸出結合
```python=
a="15"
b=15
c=[1,2,3]
print(type(a) == type(b))
print(type(a))
print(type(b))
print(type(c))
print(f'b={b},c[2]={c[2]}')
```
## Practice 2 if條件式
```python=
num = int(input("Please input a number:"))
if(num%2==0):
print("It's even")
else:
print("It's odd")
```
## Practice 3 if elseif else 條件式
```python=
account = input("Account:")
pwd = input("Password:")
if account == "user" and pwd == "123456":
print("Login Success!")
elif account =="" or pwd =="":
print("Account or Password can't be space!")
else:
print("Login Failed!")
```
## Practice 4 while 流程
```python=
a=0
while (a<10):
a = a+1
print(a)
```
## Practice 5 使用 while 方法讓練習2或練習3的程式可以多次運行
```python=
while True:
num = int(input("Please input a number:"))
if(num%2==0):
print("It's even")
else:
print("It's odd")
```
## Practice 6 使用 For 迴圈讀取陣列內的數值
```python=
numList = [0,1,2,3,4,5]
for i in numList:
print(i)
```
## Practice 7 請同學使用兩個 for 迴圈列印出9x9乘法表
```python=
for i in range(1,10):
for j in range(1,10):
if j==9:
print("\t", i*j) # j == 9 時,換行
else:
print("\t",i*j,end=('')) # j < 9 時,不換行
```
# Python基本教學
## list
1. 可以儲存多個資料
2. 屬於序列結構
3. 值是可變的(Modifiable)
4. Iterable
## 如何建立list()
1. 建立Python串列,最直觀的方式就是直接以**中括號 []** 包覆你要建立串列的內容
例如,下面建立兩個星期一到星期五的晚餐項目的list
dinner代表吃的店家
price代表對應的價格
```python=
dinner = ['關東煮', '涮奶葉', '小赤佬', '班迪先生', '倫敦派'] # 建立dinner這個list
price = ['90', '555', '270', '230', '80'] # 建立price這個list
```
2. 宣告一個空的list()
```python=
a = []
print(type(a))
# <class 'list'>
```
## list的基本操作
### 取得 list 的元素

* 想要取得元素的話,可以在 list 的名稱後面使用中括號 [] 加上想取得元素的**位置 (index)**
* 注意 : 程式語言中的 index 是從 0 開始的
* 如果想要取得第一個位置的元素,要輸入的位置值會是 0 ,想取得第二個元素則得輸入 1 ,以此類推
* -1 來表示最後一個元素
```python=
dinner = ['關東煮', '涮奶葉', '小赤佬', '班迪先生', '倫敦派']
price = ['90', '555', '270', '230', '80']
print(dinner[0])
# 關東煮
print(price[2])
# 270
print(dinner[3])
# 班迪先生
print(dinner[-1])
# 倫敦派
print(price[-5])
# 90
```
#### 以範圍取值
`my_list[start(開始的index):end(結束的index)]`
```python=
dinner = ['關東煮', '涮奶葉', '小赤佬', '班迪先生', '倫敦派']
price = ['90', '555', '270', '230', '80']
print(dinner[0:3])
# ['關東煮', '涮奶葉', '小赤佬']
```
輸入 [0:3] 所得到的結果,會是 index 為 0、 1、 2 的元素,並不會包含索引值是 3 的值
#### 取得list的長度 len()
```python=
dinner = ['關東煮', '涮奶葉', '小赤佬', '班迪先生', '倫敦派']
price = ['90', '555', '270', '230', '80']
print(len(dinner))
# 5
print(len(price))
# 5
```
#### 增加list元素 append()
```python=
a = ['1', '2', '3', '4']
a.append('12345')
print(a)
# ['1', '2', '3', '4', '12345']
```
#### 刪除list元素 remove() pop()
```python=
dinner = ['關東煮', '涮奶葉', '小赤佬', '班迪先生', '倫敦派']
price = ['90', '555', '270', '230', '80']
dinner.remove('涮奶葉')
print(dinner)
# ['關東煮', '小赤佬', '班迪先生', '倫敦派']
dinner.pop() #刪除list的最後一個元素
# ['關東煮', '小赤佬', '班迪先生']
```
## time
```python=
import time
#傳回從 1970/1/1 00:00:00 算起至今的秒數
print(time.time())
# 將秒數轉為本地時間字串
print(time.ctime())
# 1679321569.017426
# Mon Mar 20 22:12:49 2023
## 例外處理
* 無論撰寫何種程度的程式,開發過程中難免會出現bug導致程式無法如預期運行,原因可能來自程式語法的錯誤、變數型態相悖、函數輸入…等,使用例外處理可以在bug發生時有效處理許多事情。
* 例外處理的重要性:在一般程式撰寫中,若在執行更改檔案內容相關程式時發生bug導致檔案未依照正常程序關閉,將有可能造成檔案遺失,為此我們需要使用例外處理來執行當發生bug時,能讓程式合乎正確的程序結束。
* 語法
``` python=
try:
...
except:
...
* 例外處理流程圖

* 造成程式中斷的例外有許多種類,如:ImportError、SyntaxError、TypeError…等都是常見的例外,而在此次lab中會使用到之例外為KeyboardInterrupt例外信號。
* 當程式在執行時,使用者可以通過^C = Crtl+C中斷程式,此種中斷類型及為KeyboardInterrupt例外信號。
``` python=
try:
while(True):
print("hello")
except KeyboardInterrupt:
print("KeyboardInterrupt occur")
```
## import
* 如同前述所提,Python有許多強大的套件可以使用,在此Lab中我們首要需要用到的套件便是Rpi.GPIO。
* 程式用法 : import RPi.GPIO as GPIO
* 此套件有許多控制樹莓派接腳的函式提供我們使用
* 在此Lab中我們還需要另一個import套件—time套件, time套件是提供各種與時間有關的功能,如:測量程式執行時間、獲取當前時間…等。
* 程式用法 : import time
* 程式用法 : time.sleep(sec) #讓程式暫停指定的秒數(sec)
* 在使用函數時,我們可以把它想像成是一個”販賣機”給予特定輸入獲得相對應的輸出,在使用第三方套件函數時,函數的功能往往就能透過函數名得知,
* 如:cv2.imread()、list.append(),在此lab中我們會用到GPIO.setmode其函數功能顯而易見。
## python dictionary
* Python雖然已經有提供相當便利、簡潔的資料型態list,但有時為了增加程式的可讀性會使用稍微複雜一點的dictionary進行撰寫。
* 舉例如下:若今天要記錄學生之身高、體重、年紀使用list紀錄會是:
student_list = [175,65,32]
* 但改以使用dictionary紀錄,可以清楚了解每個值和屬性對應的關係,進行後續調用值時也會提高整個程式之可讀性。
student_dict = {'height':175,'weight':65,'age':32}
* Python中的Dictionary有幾個特性:
* key的唯一性: Dictionary的key不允許重複出現
* Value:value則不受規範可以重複使用
* Dictionary提供多種內置函式方便使用者對其進行更動
| 方法 | 意義 |
| -------- | -------- |
| len(dict1) | 取得字典元素個數 |
| dict1.copy() | 複製字典 |
| 鍵 in dict1 | 檢查鍵是否存在 |
| dict1.keys() | 取得以「鍵」為元素的組合 |
|dict1.values() | 取得以「值」為元素的組合 |
### dict和list的比較
| | list | dict |
| -------- | -------- | -------- |
| 表示方法 | list1 = [ 20, 30, 40 ] | dict1 = { “apple”:20, “banana”:30, “orange”:40 } |
| index | index從0開始分配,每個element都會到分配一個index。(順序性 sequential) | 以key-value為一組,字典中的項目沒有順序性,是按照key來做紀錄。 |
| 插入及查找速度 | 插入及查找速度較慢 | 較快,"理論上"不會應為key增加而變慢 |
| 占用的記憶體空間 | 較小 | 較大的記憶體空間 (空間換取時間) |
# Linux基本指令介紹
## sudo
需要取得系統最高權限才能對 Linux 系統進行修改、更新或安裝,因此執行時需配合「sudo」指令來暫時切換至系統最高權限

## apt
新增與移除軟體是Linux或任何其他作業系統最基本的工作之一。
你經常會需要安裝發佈版本未隨附的軟體,或移除不需要的軟體來釋放硬碟空間。
樹莓派OS預設的軟體管理員是 apt (Advanced Packaging Tool)。
註:所有以Debian為基礎的Linux發佈版本皆是。
此工具的主要指令為 `apt` ,下載與安裝軟體套件為 apt 最簡單與常用的形式,但它也可以用在更新與升級軟體。

### 新增軟體 (下載、安裝軟體)
指令:`apt install 套件名稱`
e.g. 要安裝 "vim":`sudo apt install vim`
註:vim 為一種文字檔編輯器
### 移除軟體
指令:`apt remove 套件名稱`
e.g. 要移除"vim":`sudo apt remove vim`
### 更新軟體套件
因系統套件或應用軟體會隨著時間進行版本更新,所以在執行「系統更新」或「安裝、更新應用程式」前,會建議先使用「apt update」指令更新軟體庫清單,以確保安裝或更新系統、軟體時會是當前最新版本。
### 升級軟體套件
更新軟體庫清單後,可透過「apt upgrade」指令進行系統或軟體更新
## 路徑
* 絕對路徑:路徑的寫法『一定由根目錄 / 寫起』,例如: /usr/share/doc 這個目錄。
* 相對路徑:路徑的寫法『不是由 / 寫起』,意指『相對於目前工作目錄的路徑!』
例如由 /usr/share/doc 要到 /usr/share/man 底下時,可以寫成: 『cd ../man』
* / 目前資料夾
* ../ 上一層資料夾
* ~/ 家目錄
* / 根目錄
* 
## ping

ping 這個指令是一個最常用的網路檢測工具,它可以藉由發送 ICMP ECHO_REQUEST 的封包,檢查自己與特定設備之間的網路是否暢通,並同時測量網路連線的來回通訊延遲時間(round-trip delay time),通常如果網路出問題時,我們都會使用 ping 這個指令來做初步的檢查。

測試是否連上網際網路(ping google的server)
```
ping 8.8.8.8 (對8.8.8.8這個ip發送封包進行測試)
```

## pwd

顯示目前路徑
```
pwd (顯示目前路徑)
```
## ls (LS 不是 is)

取得當前資料夾與檔案名稱

-l 詳細資料
-a 顯示隱藏檔案

```
ls -la (以詳細資料格式列出當前資料夾與檔案名稱,並顯示隱藏檔案)
```

## mkdir

make directory
建立資料夾

```
mkdir demo (建立一個名為demo的資料夾)
```
* 禁用字元:/、空白
* 建議使用數字、符號、_(底線)
## cd
切換目錄

```
cd demo (進入名為demo的資料夾)
cd ../ (返回至上一層資料夾)
cd (返回家目錄)
```
## vim
linux 最常使用的文字編輯器

`sudo apt install vim` (下載vim)

```
vim text (新增並編輯一個叫做text的檔案)(若已存在就會直接編輯 不會新增)
```

按 i 進入編輯模式

按ESC 結束編輯模式
結束編輯後
按 :wq 存檔並離開
按 :q! 不存檔直接離開

[vim詳細使用教學](https://linux.vbird.org/linux_basic/centos7/0310vi.php)
當然 你也可以直接用visual studio code進行檔案編輯
或者是雙擊mobaxterm左邊的檔案列表進行編輯

## mv
移動檔案或資料夾/更改檔案或資料夾名稱

```
mv text text2 (將text名稱改為text2)
```
## cp
複製檔案
-r 複製資料夾

```
cp text2 text (複製text2檔案 並命名為text)
```
## rm

刪除檔案
```
rm text2 (刪除叫做text2的檔案)
```
-r 刪除資料夾
```
rm -r demo (刪除叫做demo的資料夾)
```
## wget
下載檔案
```
wget https://raw.githubusercontent.com/MCAS-LAB/demo/main/helloworld.py
```

## python
執行python程式
樹梅派內預設安裝好python,不用自己安裝
```
python helloworld.py (用python執行helloworld.py檔案)
```
| 指令 | 功能 | 用法 |
| -------- | ----------------- | ------------------------------------------------------------------------------------------ |
| apt | 軟體/套件管理 | apt ==install(操作)== ==vim(套件名稱)== |
| ping | 測試ip是否有回應 | ping ==8.8.8.8== ==(ip位址)== |
| pwd | 終端機目前路徑 | pwd |
| wget | 下載檔案 | wget ==https://raw.githubusercontent.com/MCAS-LAB/demo/main/helloworld.py== ==(檔案網址)== |
| ls | 列出目標路徑檔案 | ls ==../(路徑位置 可略)== |
| cd | 移動到目標路徑 | ping ==8.8.8.8== ==(ip位址)== |
| mkdir | 建立新資料夾 | mkdir ==directory== ==(資料夾名稱)== |
| vim | 建立/編輯文件 | vim ==text== ==(文件名稱)== |
| cat | 查看檔案內容 | cat ==helloworld.py== ==(目標檔案路徑)== |
| mv | 移動/重新命名文件 | mv ==a(目標檔案路徑)== ==b(改完後的檔案路徑)== |
| cp | 複製檔案 | cp ==a(目標檔案路徑)== ==b(複製出來的檔案路徑)== |
| python | 執行python程式 | python ==helloworld.py== ==(目標檔案路徑)== |
| ifconfig | 查看網卡狀態 | ifconfig |
參考資料:[linux指令集](https://linux.vbird.org/linux_basic/redhat6.1/linux_06command.php)
## Vim的優化
有很多大佬有自己的vim設定,可以去google 觀摩一下其他人的設定
1. `vim .vimrc`
2. 進入insert模式
3. :set nu ==顯示幾行==
4. :syntax on ==增加顏色易讀==
5. `Esc`, `:wq`
<!-- 1. `cd /etc/vim`
2. `sudo vim vimrc`
3. 移到檔案最後一行輸入 `set nu`
4. `Esc`, `:wq` -->