Introduction to Python Applications 2025 - Lecture 1
===
###### tags: `Python` `Python and Its Application 2025`
### 電腦是如何計算的?
- 電腦可以
- 儲存資料。
- 讀取資料。
- 自其他裝置接收資料。
- 傳送資料到其他裝置。
- 對資料進行運算,產生新資料。
- 程式運作過程 [Machine Cycle](https://www.google.com/search?q=Machine+Cycle&tbm=isch)
- 程式作為一種資料存在儲存裝置(storage)裡,如硬碟。
- 將程式從儲存裝置搬到記憶體(memory)
- CPU 將記憶體中的指令解碼,視需求從記憶體或其他裝置取得資料存放到暫存器(register),或進行計算。
- 算完後再視情況將計算的結果存回記憶體 memory 或是其他裝置。
### 電腦儲存資料的單位
- bit: 0/1,開/關 (通常用 小b 表示)
- byte: 8 bits => 可以表示 $2^8 = 256$ 種數字 (通常用 大B 表示)
- 1 KB = 1024 B
- 1 MB = 1024 KB
- 1 GB = 1024 MB
- 1 TB = 1024 GB
### 整數(int)的儲存
- 電腦最基本的儲存資料室 0 跟 1
- 因為基本單位是 0 跟 1,常採用二進位制表示數字
- $1_{10} = 1_2$, $2_{10} = 1\times 2^1+0\times 2^0 = 10_2$, $3_{10} = 1\times 2^1+1\times 2^0 = 11_2$, ...
- 1 跟 0 要如何不被搞混成 10 呢?
- 固定數字儲存長度,假設為 8 bits (每台電腦都不一樣)
- 1 存成 `00000001`, 0 存為 `00000000` => 放在一起時是 `0000000100000000` 也不會搞混成 2 (存成`00000010`)
- 這種作法能表示的數字有限,當儲存的數字不大時,會採用這種方式。
- 如何表示整數的的正負呢?
- Python 基本上採 [二補數法(2's complement)](https://zh.wikipedia.org/wiki/%E4%BA%8C%E8%A3%9C%E6%95%B8)
- Python 語言中,直接寫十進制數字就可以代表一個整數資料。如一百五十六寫做 `156` 。
### 浮點數(float)
- 利用二進位版本的[科學記號](https://en.wikipedia.org/wiki/Scientific_notation)表示法 [IEEE-754](https://zh.wikipedia.org/wiki/IEEE_754)
- 剛剛有講到電腦是用 0 跟 1 儲存資料的,所以數字類的資料都會使用二進位
- 如何用二進位表示小數呢?
- $0.5_{10} = \frac{5}{10} = \frac{1}{2} = 1\times 2^{-1} = 0.1_2$
- 常見問題:十進位的有限小數在二進位是無窮小數。
- 0.3 在二進位下是無窮小數,不能使用有限位數的二進位制完整表達,記錄下來就會有誤差,常造成一些不預期的結果。
- 簡單介紹儲存方法
- 32 bits 為例
- 第一位是 sign bit
- 接下來 8bits 是指數 (exponent),用超額表示法:用其二進位表示的數,扣掉一個固定的值。
- 剩下 23bits 是有效數 (英文用fraction、significand、metissa),是真正的數值部分,其中因為是沿用科學記號,非零的數字部分必定是大於等於 $1$ 但小於 $2$ ,因此小數點前一定是 1 ,一般不需要特別最前面 1.xxx 的 1 。
- 因此,下圖的數字應該是 $1.01_2 \times 10_2^{-3} = 1.25_{10} \times 2_{10}^{-3}$ (這裡的 exp 是用超額表示)
-  圖片引自維基百科 https://upload.wikimedia.org/wikipedia/commons/d/d2/Float_example.svg
- Python 語言中,直接寫十進位小數就可以代表一個浮點數(`float`)資料。但由於轉換成二進位時可能變成無窮小數,或是 fraction 位數過多的,可能會與寫在程式碼內的十進位數有些許誤差。例如 `0.3` 就無法無誤差的存成 `float` 。
### 文字表示
- 電腦存 0 與 1,要使用一些對照表 (Encoding table) ,讓數字代表文字。
- 數字與文字之間的對應關係稱為編碼 (Encoding)
- 文字編碼可能是在中文 Windows 安裝 Python 套件的痛
- 世界上目前主流的編碼系統是 `utf8` ,但中文 Windows 環境下經常是 `cp950` ,因此一些世界通用的程式碼,碰上中文 Windows 上的中文檔案路徑會出狀況。
- 像是 97 通常代表 'a',98 通常代表 'b'...
- 要存文章,就需要更多的定義,比如一些特殊的符號,像是換行等等。
- Python 語言中,文字通常以 `str` 的型態儲存。一段文字如果由一對單引號或是雙引號夾住,就是 Python 語言中的 `str`,如 `'abc'` 、 `"123"`。
### 其他資料
- 要儲存更複雜的資料,就需要先定義格式,該如何解讀一串0與1。
### 語言的基本構成
- 以英文為例
- 單字由一些字母構成
- 句子由合乎**語法**的一些單字構成
- Syntax (語法)
- 語言的規則
- 以英文為例: I meat eat 不合語法,主詞受詞動詞並不是英文語法,主詞動詞受詞才正確。
- 以算術為例: `3 5 +` 不合語法,不是一個能夠計算的算式。
- 本課程會教語法
- Semantics (語意)
- 把 3 加上 5 的結果貼上 `a` 的標籤: `a = 3 + 5`
- 幫我買兩顆蘋果回來,如果看到蛋的話,買十個。
- 語意解析
- 自然語言同一句話可能可以解釋成多種意思
- 我養的豬很好吃。
- 程式語言中,一個句子通常只會解釋成特定一種意思 (或是特定幾種意思)
- 只是這句話的意思不一定是工程師要的
- 工程師可以是你我他
- 如果不只一種可能性,稱作「Undefined behavior」
- 有些語言也會跳錯,因為不確定你要做什麼,電腦也可能不想幹。
- 可能造成非預測行為,因為你都不確定要做什麼,就可以選一種方式隨便做。
### 錯誤
- syntax errors
- 簡單好抓,因為語法錯,電腦看不懂就不給執行啊。
- semantic errors
- 語法正確但語意上並非設計者原意。
- 不容易偵測
- 常見的有
- Python: `a == 1 or 2`,不管 `a` 是多少,這個邏輯運算都會是「成立」。
- C/C++: `if (a = 1) printf("a is 1\n"); else printf("a is not 1");` 不管 `a` 是多少,都會印出 `a is 1`。
- 程式的行為與程式設計師想要得不一樣,通常稱作 bug
- 症狀可能有:
- 程式意外終止
- 無窮迴圈
- 錯誤答案
- 非預期的行為
- 原因百百種
- 程式的語意跟程式設計師認知的不同 (semantic errors)
- 電路裡可能有昆蟲入侵導致短路
- 晶片電路設計有瑕疵
## Python Programs
- program (程式) 是一系列的定義與指令 (command)
- command (statement) 指揮 Python 直譯器
### Objects (物件) and Values (值)
- 所有資料都是物件
- 所有物件都有 type (型別),python 會根據型別,知道你可以對這個物件做哪些事情
- ex. 數字,是可以相加、相減、相乘、相除。
- ex. 字串,可以串接。
- 常用的資料型態有
+ `int` Integers: `1`,`0`,`-2`
+ `float` Decimals: `1.23`, `456.7`
+ Numbers in scientific notation: `1.234e5`, `-6.78e-2`
+ `str` Strings: `'abc'`, `"ABC"`, `'"'`,`"'"`
- 可以用 type() 來看型別
- 型別轉換
- float(3): 將 整數 3 轉為 浮點數 3.0
- int(3.9): 將 浮點數 3.9 轉為 整數 3
+ `tuple` 序列
+ `tpl = (3,5)`
+ `list` 清單
+ `lst = [1,2,3,4]`
+ `lst[1] = 9`
+ `dict` 字典
+ `dct = {}`
+ `dct = {1:2}`
+ `dct['name'] = 'MZ'`
### Expressions (運)算式
- 將 objects 跟 operators 連接形成 expressions
- expression 必定有 value
- 簡單 expression 的 syntax
- {object}
- ({expression})
- {expression} {operator} {expression}
- 以數字為例的運算
| 運算子 | 意思 | 用法 | 運算結果的型態 |
| :-: | :-: | :-: | :-: |
| + | 加 | i + j | 若 i or j 中有任一是浮點數,則為浮點數,若無,則為整數 |
| - | 減 | i - j | 同上 |
| * | 乘 | i * j | 同上 |
| / | 除 | i / j | 浮點數 |
| // | 整數除 | i // j | 若 i or j 中有任一是浮點數,則為浮點數,若無,則為整數 |
| % | 餘數 | i % j | 若 i or j 中有任一是浮點數,則為浮點數,若無,則為整數 |
| ** | 次方 | i ** j | 若 i or j 中有任一是浮點數,則為浮點數,若無,則為整數 |
- 運算優先序
- () 最優先
- `** > {*,/} > {+,-}`
- 同等級左邊優先:`+`,`-`,`*`,`/`
- 同等級右邊優先:`**`
### 綁定 變數 (variable) / 名稱 (name) 與 值 (value)

- 用 等號(=) 綁定(binding):貼標籤的概念
- 物件具有編號:`id()`
- 重新綁定
- 同一個變數可以改變綁定的值
```python3=
a = 10
print(a) # 10
a = 20
print(a) # 20
```
- 為何要使用變數
- 可以儲存數據,避免在程式中寫大量的重複數值
- 可讀性較高、好維護
- 便於重複使用與計算
- 提升靈活性
### 函數 (function)
- Python 的函數也是一種物件,一種資料
- 計算(執行)函數要透過加上`(argument, ...)`,這也是拿來實踐各種功能的基礎用法。
- 如 `print(argument)` 會將 `argument` 的值給印出來。
### [`pyautogui`](https://pyautogui.readthedocs.io/)
+ 用程式控制鍵盤和滑鼠
+ 你可以用程式操作鍵盤輸入以及滑鼠的點擊,將可以取代很多人工操作。
+ 避免裝備不夠靈敏、感應延遲等問題。
+ <del>使用範例:在《蟒蛇谷》遊戲裡,若玩家想要獲得PillowDrawer特殊道具,則必須點擊主城的Tree一千下,每點擊一千下後有一定機率獲得。在學習了pyautogui之後,我們就可以以對滑鼠較友善的方式獲得這個道具。</del>
+ `import pyautogui`
+ 這也是一種綁定的方式。
+ 控制滑鼠
+ 取得螢幕大小資訊
+ `width, height = pyautogui.size()`
+ 取得鼠標位置資訊
+ `x, y = pyautogui.position()`
+ 螢幕的座標方式
+ 左上方: (0,0)
+ 右下方: `pyautogui.size()`
+ 移動鼠標到指定位置
+ 絕對位置: `pyautogui.moveTo(x, y, duration)`
+ 你目前可以忽略 `duration` 這個參數。僅輸入 `pyautogui.moveTo(x, y)`,鼠標將移動至`(x, y)`的位置。
+ 相對位置: `pyautogui.moveRel(x, y, duration)`
+ 若當前座標為`(a, b)`,輸入上方指令後鼠標將移動到`(a+x, b+y)`位置
+ 點擊滑鼠
+ `pyautogui.click(x, y)`
+ 左鍵點擊`(x, y)`處
+ `pyautogui.rightClick(x, y)`
+ 右鍵點擊`(x, y)`處
+ `pyautogui.doubleClick(x, y)`
+ 左鍵雙擊`(x, y)`處
+ 拖曳(指得是長按的動作)
+ 絕對位置: `pyautogui.dragTo(x, y, duration)`
+ 由當前位置拖曳鼠標至`(x, y)`
+ 相對位置: `pyautogui.dragRel(x, y, duration)`
+ 若當前位置為`(a, b)`,由此處拖曳鼠標至`(a+x, b+y)`
+ 滑鼠滾輪
+ `pyautogui.scroll(y)`
+ `y`若為正值,代表向上滾動`y`單位;負值則是向下滾動。
+ 控制鍵盤
+ 輸入文字串
+ `pyautogui.typewrite(text,delay)`
+ 按下特定按鍵
+ `pyautogui.press(key)`
+ `pyautogui.keyDown(key)`
+ 按下某個鍵
+ `pyautogui.keyUp(key)`
+ 鬆開某個鍵
+ `keyDown`與`keyUp`組合即為`press`
+ [Key table](https://automatetheboringstuff.com/chapter18/#calibre_link-36)
+ 快捷鍵輸入
+ `pyautogui.hotkey(key1, key2, ..., keys)`
+ Example: `pyautogui.hotkey('ctrl', 'c')`
+ 範例
+ Windows
+ 叫出命令提示字元,印出`Hello World!`
```python=
import pyautogui
pyautogui.PAUSE = 1
pyautogui.hotkey('win','r')
# 如果會卡中文輸入法,請切換到英文輸入法
pyautogui.typewrite('cmd')
pyautogui.press('enter')
# 如果會卡中文輸入法,請切換到英文輸入法
pyautogui.typewrite('echo Hello World!',0)
pyautogui.press('enter')
```
+ 其他
+ `pyautogui.PAUSE = t`
+ 代表每個`pyautogui`的指令間間隔`t`秒
+ 因為`pyautogui`的指令執行很快,可能在電腦畫面還沒有反應之前就執行到下一個指令,因此適當的延遲才能順利執行。
+ 暫停一下
+ 先寫一行 `from time import sleep`
+ 之後就可以用 `sleep()` 來暫停程式
+ `sleep(1)` 就是暫停一秒
+ `sleep(5.678)` 就是暫停 5.678 秒
+ 作業一:
+ 寫一個程式,完成下列指令:
+ 開啟瀏覽器。
+ 開啟陽明交大首頁:https://www.nycu.edu.tw/
+ 作業二:
+ 寫一個程式,開啟 [GeoGebra Classic](https://www.geogebra.org/classic) 網站,畫出一個三角形。
+ 作業三:
+ 寫一個程式,開啟 [SketchPad](https://sketchpad.app/) 網站,畫出一棵樹。