owned this note
owned this note
Published
Linked with GitHub
# Python 101
###### tags: 2022電機營教學組
## Syntax
Syntax是學習程式語言的基本。
## print()
將括弧中的object印出。
```python
print("Hello, world!")
print("Hello, Jimmy!")# Say hello to Jimmy
```
## Variable
儲存資料的容器,利用 "=" assign
```python
# if his name is Jimmy...
name = "Jimmy"
print("Hello,", name)
```
### 命名原則
* 以 _ 、英文字開頭
* 不包含 _ 以外的符號
* 大小寫有別
* 避免使用keyword(已經有其他定義/用途的字,見[這裡](https://docs.python.org/3/reference/lexical_analysis.html#keywords))
### Text Sequence Type
* 這種類別的物件被稱為 String
* 由 “” 或 ‘’ 標示
* 利用 input() 可獲取輸入的 String
```python
# Ask his/her name first!
name = input("What's your name?")
print("Hello,", name)
```
* '+' 可用於接合複數 String
```python
name1 = "Amy"
name2 = "Jenny"
names = name1 + " and " + name2
print(names + " are my best friend!")
```
### Numeric Type
* int, float, complex
* operator
* +-*/ 加減乘除
* % mod(取餘數)
* // 整數除法
* \** 次方
```python
print("Input your score...")
#Since input() returns String, use float() to convert their type
chinese = float(input("Chinese score:"))
english = float(input("English score:"))
math = float(input("Math score:"))
average = (chinese + english + math)/3
print("Your average score is", average)
```
### String Formatting -- f-string
結合 String 與其他 variable
* f"{value} some other text"
```python
name = input("input your name:")
print("input your score...")
chinese = float(input("Chinese score:"))
english = float(input("English score:"))
math = float(input("Math score:"))
average = (chinese + english + math)/3
print(f"{name}'s average score is {average}")
```
## if...else
用於條件判斷、流程控制。
若對應的條件為真,則執行其中的程式碼,否則進入對應的 else (elif 代表else if)。
* 判斷數字的正負
```python
number = int(input("input a integer"))
if number>0:
print("It's positive")
elif number==0:
print("Is's zero")
else:
print("It's negative")
```
### Relational operator
比較兩旁的 variable
* \>(大於)、<(小於)
* ==(等於)
* !=(不等於)
* \>=(大於等於)、<=(小於等於)
### Boolean and Logical Operations
Boolean 為 Variable 的一種,有 True (是,1)與 False (否,0)兩種數值。
* Logical Operation
* and (且,兩者皆1時為1,否則為0)
* or (或,兩者皆0時為0,否則為1)
* not (對右側判斷式/ boolean 生效,顛倒右側真假性)
判斷輸入分數是否合理
```python
score = float(input("input your score:"))
if score>=0 and score<=100:
print("It's valid.")
else:
print("It's not valid.")
```
## while loop
若條件成立,則執行迴圈中動作,並再次判定條件。
```python
while <condition>:
action
```
例子: 利用 while loop 設計猜數字遊戲
```python
answer = int(input("input a positive integer:"))
guess = int(input("guess the number:"))
while guess!=answer:
if(guess>answer):
print("It's bigger than the answer.")
elif(guess<answer):
print("It's smaller than the answer.")
guess = int(input("guess the number:"))
print("You win!")
```
### break and continue
* break
在迴圈中遇到時,跳出此層迴圈。
* continue
在迴圈中遇到時,跳過迴圈中剩餘的動作,回到頂部判斷條件。
**Exercise 1** while loop
藉由二分法可以查找在給定兩數 $x_1, x_2$ 間連續函數$f(x)$的根。假定 $x_1, x_2$ 間只有一個根 $x_0$,且$f(x_1)$與$f(x_2)$異號;令 $x={(x_1+x_2)}/{2}$,若$f(x)$與$f(x_1)$同號,則將 $x_1$ 以此 $x$ 替換,反之則將 $x_2$ 以此 $x$ 替換。此方法的誤差 $\delta=|x-x_0|\le|x_1-x_2|/2$ ,請估計$\sqrt{2}$ 並使誤差小於$10^{-6}$。(提示:考慮$f(x)=x^2-2$)
## List
List,可以只用一個變數名稱,儲存一群資料。
舉例來說,假設我們要儲存小隊員的身高,那寫12個變數就會顯得很麻煩,但是如果我們所有人的身高儲存在一個叫做member的list中的話,那麼不但變得比較方便,看起來也比較整潔。
### Declaration :
```python
blank = []
height = [172 , 180 , 175 , 183 , 190]
classmates = ['Bob', 'Eric', 'Max', 'Walker']
num = [[1, 3, 5], [2, 4, 6]]
```
### Index : (list的編號從0開始)
```python
classmates = ['Bob', 'Eric', 'Max', 'Walker']
print(classmates[1])
## Eric
print(classmates[4])
## IndexError: list index out of range
```
### Slicing :
```python
classmates = ['Bob', 'Eric', 'Max', 'Walker']
#list[x:y] means "from index x to index y-1"
print(classmates[1:3])
## ['Eric', 'Max']
#[x:] means "from index x to the end"
print(classmates[2:])
## ['Max', 'Walker']
#[:-y] means "from index 0 to the y+1 one from the last"
print(classmates[:-2])
## ['Bob', 'Eric']
```
### Basic Methods :
1. len(list) : 取得list的元素個數
```python
classmates = ['Bob', 'Eric', 'Max', 'Walker']
L = len(classmates)
print(L)
## 4
```
2. list.append(x) : 從list後面新增一個元素 x
```python
classmates = ['Bob', 'Eric', 'Max', 'Walker']
classmates.append('Evelyn')
print(classmates)
## ['Bob', 'Eric', 'Max', 'Walker', 'Evelyn']
```
3. list.pop(int a) : 刪除 list 中第 a 個元素,若括號中沒有放入任何數字,將預設為刪除最後一個元素
```python
classmates = ['Bob', 'Eric', 'Max', 'Walker', 'Evelyn']
classmates.pop(0)
print(classmates)
## ['Eric', 'Max', 'Walker', 'Evelyn']
```
4. list.insert(int a, x) : 在 index a 的位置插入元素 x
```python
classmates = ['Eric', 'Max', 'Walker', 'Evelyn']
classmates.insert(3, 'David')
print(classmates)
## ['Eric', 'Max', 'Walker', 'David', 'Evelyn']
```
### Copying a list :
1. Assignments(=)
```python
classmates = ['Eric', 'Max', 'Walker', 'Evelyn']
bffs = classmates
bffs.pop(1)
print(classmates)
## [['Eric', 'Walker', 'Evelyn']
print(bffs)
## ['Eric', 'Walker', 'Evelyn']
```
2. list.copy() :
```python
classmates = ['Eric', 'Max', 'Walker', 'Evelyn']
bffs = classmates.copy()
bffs.pop(1)
print(classmates)
## ['Eric', 'Max', 'Walker', 'Evelyn']
print(bffs)
## ['Eric', 'Walker', 'Evelyn']
```
3. copy.deepcopy(list_name) :
```python
import copy
classmates = ['Eric', 'Max', 'Walker', 'Evelyn']
bffs = copy.deepcopy(classmates)
bffs.pop(1)
print(classmates)
## ['Eric', 'Max', 'Walker', 'Evelyn']
print(bffs)
## ['Eric', 'Walker', 'Evelyn']
```
### Common applications :
1. for x in list : 對 list 內的所有元素執行以下動作
```python
bffs = ['Eric', 'Walker', 'Evelyn']
for bff in bffs:
print(bff," , lets go to the movies together !")
## Eric , lets go to the movies together !
## Walker , lets go to the movies together !
## Evelyn , lets go to the movies together !
```
2. list comprehensions :
```python
classmates = ['Eric', 'Max', 'Walker', 'Evelyn']
L = len(classmates)
seet_number = [x+1 for x in range(L)]
print(seet_number)
## [1, 2, 3, 4]
stds_on_duty = [classmates[i] for i in range(L) if seet_number[i]%2 == 1]
print(stds_on_duty)
## ['Eric', 'Walker']
```
**Exercise 2** List operation
請在 todo 的地方填入適當的 list operation 使得結果印出 "NTUEE"
```python
camp = ["N", "A", "T", "U", "R", "E"]
### TODO:
###
print(f'result = {result}')
result = ''.join(camp)
# output = "NTUEE"
```
* More details and applications are shown in the official sites of python : [https://docs.python.org/zh-tw/3/tutorial/datastructures.html#more-on-lists]
## for loop
遍歷(enumerate)一個物件中的元素
```python
for variable in obj:
action
```
* break 與 continue 同樣適用 for loop
### range(start, stop)
* 生成一個如[start, start+1..., stop-1]的數字序列(從 start 開始,到 stop-1 結束)。
* start 若被省略(意即range()中只有一個 argument),則預設為0。
#### 範例(用於執行指定次數)
1. 列印簡易聖誕樹
```python
print(" "*4 + "*"*1)
print(" "*3 + "*"*3)
for i in range(2):# 3 layers
print(" "*2 + "*"*5)
print(" "*1 + "*"*7)
print(" "*0 + "*"*9)
for i in range(2):# trunk
print(" "*3 + "*"*3 )
## *
## ***
## *****
## *******
##*********
## *****
## *******
##*********
## ***
## ***
```
2. factorial(階乘)
```python
n = int(input("input a integer:"))
ans = 1
for i in range(1, n+1):
ans *= i # ans = ans * i
print(ans)# factorial
```
### Nested loop
迴圈中含有迴圈,稱作nested(巢狀) loop。
#### 範例 : 九九乘法表
```python
for i in range(1,10):# let i from 1 to 9
for j in range(1,10):# for a fixed i, let j from 1 to 9
print(f"{j}*{i} = {i*j:<{2}}",end=" ")
print()
```
## Function
以下這段程式碼功能簡單,若每次使用都需要重複一次卻會有些繁瑣。
```python
average = (chinese + english + math)/3
```
因此,我們可以將一連串動作函數化,增加程式可重複利用性、可讀性。(如前文之print()、input()等)
```python
def average(Ch, En, math):
return (Ch+En+math)/3
#for Chinese, English, math = 90, 78, 93
print(f"Average score is{average(90, 78, 93)}")
```
### rules
* pass by keyword
因為使用者未必能知道(或記得)函數中的 argument(引數)順序,在 python 中也可透過名稱識別。
```python
def weighted_average(ch, en, math):
return (ch+en+math*3)/5
#for Chinese, English, math = 90,76,65
print(weighted_average(en=76, math=65, ch=90))
```
* default argument
* 呼叫函數時若未提供數值,自動設定為預設值
* 要由右而左填入
```python
def print_score(score, name = "John"):
print(f"{name} gets {score}.")
return
print_score(score = 98)
## "John gets 98"
```
### recursion(遞迴)
讓 function 呼叫(call) 它自己,並在某個條件下跳出
#### 範例: factorial(階乘)
```python
def factorial(n):
if n==0:
return 1
else:
return n * factorial(n-1)
print(factorial(4))
## 4 * factorial(3)
## = 4 * (3 * factorial(2))
## = 4 * 3 * (2 * factorial(1))
## = 4 * 3 * 2 * 1 = 4! = 24
```
## Dict
dict就是dictionary,dict_name[] 中的[]放的是keyword,而字典裡對應到keyword的東西是唯一的。當資料量很大的時候,可以透過 keyword 快速找到想要的資料。
keyword 可以是任何不可變的型別,如字串和數字。但我們無法使用 list 當作keyword,因為 list 可以經由 slice assignment, append(),extend() 等 methods 被修改。(TypeError: unhashable type: 'list')
### Common ways of construction:
1. dict_name = { key_a: a , key_b: b ,...}
2. dict_name[key_x] = x
```python
birthdays = {'Eric': '0312','Max': '0511','Walker': '0808'}
birthdays['Evelyn'] = '0218'
print(birthdays['Evelyn'])
## 0218
```
### Useful methods:
1. del dict_name[key_x] : 刪除鍵值對 x
2. key_x in / not in dict_name : 判斷 key_x 是否在dict內
```python
del birthdays['Eric']
print(birthdays)
## {'Max': '0511', 'Walker': '0808', 'Evelyn': '0218'}
print('Eric' in birthdays)
## False
print('Eric' not in birthdays)
## True
```
**Exercise 2** Fibbonacci sequence
已知斐波那契數列 (Fibonacci sequence) 定義如下:
$F_0=0,~F_1=1$
$F_n=F_{n-1}+F_{n-2},~\rm {for}$$~n\ge{2}$
又 $\lim_{n\rightarrow{\infty}}\frac{F_n}{F_{n-1}}=\phi=\frac{1+\sqrt{5}}{2}$,請計算第51和第50項的比值,藉此估計 $\phi$。
## class
- 可以想成是一堆variables以及functions的集合。利用class來整理程式,可以從原本的函式導向轉換為物件導向,就能更容易維持某些共同特性,讓程式更有條理,在許多地方非常常用。
- 在程式中,可能存在許多 Object (物件),底下可能包括基本資訊 (attribute) ,以及可能的操作 (member method)。
- syntax
- 產生class
```python
class <className>:
```
- 建立時initialize(初始化) attribute, self指的是自己這個object
```python
def __init__(self, <parameters>):
...
```
- 加入functions
```python
def <method>(self, ...):
...
```
- 建立class後,產生object,並access/call
```python
<variableName> = <className>() # initialize
<object>.<attribute> # 存取屬性
<object>.<method>() # 執行方法
```
- Example
```python=
class Transcript:
def __init__(self, name, ch=0, en=0):
self.name = name
self.ch = ch
self.en = en
def en_result(self):
'''check whether his/her English score fail or not'''
if self.en < 60:
print("Ohh! You failed your English!")
else:
print("Congratulation! You passed your English!")
# name = Nick , Chinese = 50 , English = 80
student1 = Transcript("Nick", 50, 80)
# change his English score to 55
student1.en = 55
student1.en_result()
# output: Ohh! your English is failed!
```
Supplement: Fstring & Dunder Method
```python=
class Transcript:
def __init__(self, name, ch=0, en=0):
self.name = name
self.ch = ch
self.en = en
def __str__(self):
return f"{self.name}'s English score is {self.en}."
student1 = Transcript("Nick", 50, 80)
print(student1)
# output: Nick's English score is 80.
```
## Script and Module
在上面的例子裡,如果我們打開一個 .py file並且用terminal執行
這樣的檔案叫做一份script。
### Script(程式檔案)
一般而言,python的編譯是一次執行一行。但如果我們想要把程式碼都打好再一次執行,就像剛剛我們做的那樣,我們就必須使用Script功能。製作Script檔的方式很簡單,請大家先開啟一個檔案(.py檔為佳),並輸入以下指令。
```python=
total1 = 1 + 1
print(total1)
total2 = 3 * 3
print(total2)
```
儲存成 test.py,即完成一份Python srcipt了!
接著打開terminal,進入test.py所在的資料夾。
並輸入以下指令。
```python=
python test.py #執行test.py檔
```
有些版本的python指令有所不同,可能是以下這版。
```python=
python3 test.py #執行test.py檔
```
理論上,可以得到以下的結果
```
2 9
```
### Module(模組)
當我們寫的程式越來越長的時候,我們可能會需要分成多個檔案,以利於維護與管理。在python中,我們可以將一些自己定義的函數寫成一個檔案,稱為**module(模組)**。在**模組裡定義的函數可以import到其他檔案來做使用**。module(模組)的檔案名稱是module(模組)名稱加上 .py。
Example:
**./mymath.py :**
```python=
def sigma(num):
total = 0
for i in range(num):
total += (i+1)
print(total)
```
**./main.py :**
```python=
from mymath import sigma
sigma(20)
```
或
```python=
import mymath
mymath.sigma(20)
```
可得結果如下:
```python=
210
```
**Exercise 3** module
為了執行以下程式碼,請寫出對應的模組 (module) 檔案。
```python=
import mymath
a = mymath.sigma(5)
b = mymath.factorial(5)
print(a)
## 15
print(b)
## 120
```
## read document
python一個很大的特點就是有許多模組,而且擴充性很好,這是它和很多程式語言的差異。但是也因此,很多東西都要自己查和自己看。
許多有名的library都會有document,提供範例以及method的argument如何擺放。遇到使用import的套件有報錯,也可以上網搜尋解決方法。
### 下載與使用import module的方法
#### 範例1: Googletrans
When you import googletrans, you can use the class Translator, which is defined in the module “googletrans”.
由於這些模組不是內建的,必須先下載。
下載方法是先打開Windows的cmd,並輸入以下指令
``` bash
pip install googletrans==4.0.0-rc1
```
接著輸入以下程式碼:
```python=
import googletrans
print(googletrans.Translator().translate('早上好中國', dest='en').text)
```
還有一些有趣的語言
'en': 'english',
'es': 'spanish',
'fr': 'french',
'ja': 'japanese',
'ko': 'korean',
'zh-tw': 'chinese (traditional)'....
##### To learn more languages:
```python=
import googletrans
print(googletrans.LANGUAGES)
```
#### 範例2: Art
接著我們來看Art模組
```python=
from art import *
print(text2art('Hello world!'))
```
看看可以print出什麼東西吧!
## Reference
- https://docs.python.org/zh-tw/3/tutorial/modules.html
## Solutions
**Exercise 1** while loop
藉由二分法可以查找在給定兩數 $x_1, x_2$ 間連續函數$f(x)$的根。假定 $x_1, x_2$ 間只有一個根 $x_0$,且$f(x_1)$與$f(x_2)$異號;令 $x={(x_1+x_2)}/{2}$,若$f(x)$與$f(x_1)$同號,則將 $x_1$ 以此 $x$ 替換,反之則將 $x_2$ 以此 $x$ 替換。此方法的誤差 $\delta=|x-x_0|\le|x_1-x_2|/2$ ,請估計$\sqrt{2}$ 並使誤差小於$10^{-6}$。(提示:考慮$f(x)=x^2-2$)
參考解答
```python
x1, x2 = 0, 2
while (x2-x1)/2>=10**(-6):
x = (x2+x1)/2
if x**2-2<0:
x1 = x
else:
x2 = x
print(f"sqrt(2)~{(x1+x2)/2}")
print(f"error={(x1+x2)/2-2**0.5}")
```
**Exercise 2** List operation
請在 todo 的地方填入適當的 list operation 使得結果印出 "NTUEE"
```python
camp = ["N", "A", "T", "U", "R", "E"]
### TODO:
###
print(f'result = {result}')
result = ''.join(camp)
# output = "NTUEE"
```
參考解答
```python
camp = ["N", "A", "T", "U", "R", "E"]
### TODO:
camp.append('E')
camp.pop(-2)
camp.pop(1)
###
print(f'result = {result}')
result = ''.join(camp)
# output = "NTUEE"
```
**Exercise 3** Fibbonacci sequence
已知斐波那契數列 (Fibonacci sequence) 定義如下:
$F_0=0,~F_1=1$
$F_n=F_{n-1}+F_{n-2},~\rm {for}$$~n\ge{2}$
又 $\lim_{n\rightarrow{\infty}}\frac{F_n}{F_{n-1}}=\phi=\frac{1+\sqrt{5}}{2}$,請計算第51和第50項的比值,藉此估計 $\phi$。
參考解答(利用 for loop)
```python
last = 0 # F_0
now = 1 # F_1
for i in range(50):
temp = now
now = last+now
last = temp
# you can also write: last, now = now, now+last
print(f"F_51/F_50 = {now/last}")
```
參考解答2(利用遞迴與 dict)
```python
fib_dict={0:0,1:1}
def fib(n):
if n not in fib_dict:
fib_dict[n]=fib(n-1)+fib(n-2)
return fib_dict[n]
print(f"F_51/F_50 = {fib(51)/fib(50)}")
```
**bonus question: 為何本題不能直接用遞迴定義計算? (提示:利用樹狀圖觀察$F_5$(或$F_n$)呼叫幾次$F_0+F_1$,以及思考該如何避免重複計算。)**
補充酷酷的答案
```python
from functools import lru_cache
@lru_cache(maxsize=3)
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
print(fib(100))
```
**Exercise 4** module
為了執行以下程式碼,請寫出對應的模組(module)檔案。
```python
import mymath
a = mymath.sigma(5)
b = mymath.factorial(5)
print(a)
## 15
print(b)
## 120
```
參考解答
```python
def sigma(n):
if n < 0:
print("invalid input")
return
elif n == 0:
return 0
return n + sigma(n-1)
def factorial(n):
if n < 0:
print("invalid input")
return
elif n == 0:
return 1
return n * factorial(n-1)
```