# Python 練習題
###### tags: `tutor` `python`
本文所有內容與資料皆由本人蒐集與撰寫,轉載請註明出處。
- [Python 教學講義](https://hackmd.io/w5n1Ow8NSea_-UAeXTJDSw?view)
- 亦可參考 [ZeroJudge](https://zerojudge.tw/Problems)
## If-else 與基本語法練習
- BMI 計算機
撰寫一個程式,讀入使用者的身高、體重
並判斷使用者為過輕、正常、或異常
若異常則再判斷為過重、輕度、中度、或重度
BMI = 體重 除以 身高的平方
體重的單位為公斤,身高的單位為公尺
![](https://i.imgur.com/OBF8hEt.png =50%x)
- 買賣交易小工具
撰寫一個程式,可以讀入使用者的以下輸入:
- 商品售價
- 現有預算
- 購買意願(Y/N)
並做以下判斷,將結果回傳至螢幕上:
- 若沒有購買意願,則印出再見並結束執行
- 若有購買意願,但預算不夠,則印出預算不夠
- 若有購買意願且預算夠,印出最大可購買的數量與剩餘的錢
舉例:
```
>>> 商品售價:500
>>> 現有預算:1000
>>> 購買意願:Y
Output:最大可購買 2 個,沒有剩餘的錢。
>>> 商品售價:500
>>> 現有預算:1100
>>> 購買意願:Y
Output:最大可購買 2 個,剩餘 100 元。
>>> 商品售價:800
>>> 現有預算:600
>>> 購買意願:Y
Output:預算不夠
>>> 商品售價:800
>>> 現有預算:600
>>> 購買意願:N
Output:再見
```
- 三數比大小(1)
撰寫一個程式,讀入三個整數
兩兩比對,判斷三個整數大小,並依照其大小輸出
舉例:
輸入3、6、4,輸出6 4 3
輸入6、6、5,輸出6 6 5
- 三數比大小(2)
撰寫一個程式,讀入三個整數
兩兩比對,判斷三個整數大小,並依照其大小關係輸出對應結果
舉例:
輸入3、6、4,輸出6>4>3
輸入6、6、5,輸出6=6>5
## 迴圈練習
- 菱形
給定輸入整數n,印出高度為2n的菱形
可以用任何符號代替星號,其他的地方為空白
![](https://i.imgur.com/UhU6IoZ.png)
- 遊戲執行
撰寫一個程式,不斷詢問使用者是否繼續遊玩
若使用者輸入Y則繼續詢問,輸入N則印出結束並結束
若輸入其他東西則顯示輸入錯誤並再詢問一次
- 九九乘法表(Hint:雙重迴圈)
印出九九乘法表,順序為:1x1=1,1x2=2,1x3=3 ... 9x9=81
![image](https://hackmd.io/_uploads/Bk6Hcq-TT.png)
- 階乘總和
給定輸入整數n,計算1!+2!+3!+...n!
- 費波納契數列
給定輸入整數n,輸出前n項費波納契數列
舉例:n = 8,輸出為 1 1 2 3 5 8 13 21
## 函數
- 找最大
撰寫一個函數,輸入為 list,回傳 list 中最大的數字
並實際使用幾個例子呼叫函數以測試正確性(不要使用 max())
舉例:
input - [1,2,3,4,5]
output - 5
- 歐幾里得距離
請參考下列函數說明,完成兩個函數
提示:函數預設值、在函數中使用函數
```python=
def eucidean_distance(x1y1, x2y2=[0,0]):
"""
x1y1: list of 2 integers (兩個整數)
x2y2: list of 2 integers (兩個整數,預設值為 [0,0])
return: the distance between the two points (回傳兩點距離)
"""
# TODO
# Implement the function to calculate the distance between two points
# 完成此函數,計算兩點之間的距離
pass
def find_closer(x1y1, x2y2):
"""
x1y1: list of 2 integers (兩個整數)
x2y2: list of 2 integers (兩個整數)
return: the closer point to the origin and its distance (回傳較接近原點的座標,與其距離)
"""
# TODO
# Implement the function to find the closer point to the origin
# 完成此函數,回傳較接近原點的座標與其距離 (有兩個回傳值)
pass
# Test Cases,輸出應該要跟下面的一樣
dis = eucidean_distance([3,4])
print(dis) # 5.0
dis = eucidean_distance([3,4], [9,12])
print(dis) # 10.0
point, dis = find_closer([3,4], [6,8])
print(point) # [3,4]
print(dis) # 5.0
point, dis = find_closer([1,1], [6,8])
print(point) # [1,1]
print(dis) # 1.4142135623730951
```
- 找因數
請參考下列函數說明,完成兩個函數
提示:for 迴圈判斷,在函數中使用函數
```python=
def find_factor(n):
"""
n: integer (整數)
return: list of factors of n (清單,n 的因數)
"""
# TODO
# Implement the function to find the factors of n
# 回傳 n 的因數
pass
def find_multiple_factor(list):
"""
list: list of integers (整數清單)
return: list of factors of all integers in the list (清單中還有清單,所有整數的因數)
"""
# TODO
# Implement the function to find the factors of all integers in the list
# 回傳所有整數的因數
pass
def find_common_factor(x, y):
"""
x: integer (整數)
y: integer (整數)
return: list of common factors of x and y (清單,x 和 y 的共同因數)
"""
# TODO
# Implement the function to find the common factors of x and y
# 回傳 x 和 y 的共同因數
pass
# Test Cases,輸出應該要跟下面的一樣
factors = find_factor(12)
print(factors) # [1, 2, 3, 4, 6, 12]
factors = find_factor(15)
print(factors) # [1, 3, 5, 15]
all_factors = find_multiple_factor([12, 15])
print(all_factors) # [[1, 2, 3, 4, 6, 12], [1, 3, 5, 15]]
all_factors = find_multiple_factor([9, 12])
print(all_factors) # [[1, 3, 9], [1, 2, 3, 4, 6, 12]]
common_factors = find_common_factor(12, 15)
print(common_factors) # [1, 3]
common_factors = find_common_factor(6, 24)
print(common_factors) # [1, 2, 3, 6]
```
## 其他資料類別練習
- 驗證身份證號碼
撰寫一個函數,輸入為身份證字串,驗證其是否為真實身份證
輸出為布林值,可自由印出提示訊息,驗證規則可參考[這裡](https://web.fg.tp.edu.tw/~anny/idtest.htm?fbclid=IwAR0pI0ymRmanb3sx2noxsfYO1UgzSBVyh3VIM-U3Sl_TaGg6ZrezNT5srwg)
當檢查碼等於最後一位數字時,即為有效身份證號碼
- 字母與數字的對照可使用 dict 來儲存,如下:
```python=
map = {'A':10, 'B':11, 'C':12, 'D':13, 'E':14,
'F':15, 'G':16, 'H':17, 'I':34, 'J':18,
'K':19, 'L':20, 'M':21, 'N':22, 'O':35,
'P':23, 'Q':24, 'R':25, 'S':26, 'T':27,
'U':28, 'V':29, 'W':32, 'X':30, 'Y':31,
'Z':33 }
```
- 需先判定輸入格式正確(共10碼、第一碼為英文、後九碼為數字、第二碼為1或2),可使用 isaplha()、isdigit() 來判定
- 可以用 [身分證字號產生器](https://people.debian.org/~paulliu/ROCid.html) 來驗證程式結果是否正確
舉例:
input - "A123456789"
output - True
- 商品價目表
已知餅乾20元有3包、飲料30元有2罐、麵包10元有1個、泡麵15元有5包、爆米花50元有1個、茶葉蛋8元有10個、便當90元有5個
請將上述資訊存入字典,並撰寫一個程式
輸入為商品名稱與欲購買數量
輸出為是否可以購買,以及總花費
舉例:
input - 泡麵 3
output - 可以購買,共需 45 元
- 字母頻率表
撰寫一個函數,輸入為一個英文字串
回傳一個字典,其中 key 為每個出現過的字母, value 為其出現次數
舉例:
input - 'brontosaurus'
output - {'b': 1, 'r': 2, 'o': 2, 'n': 1, 't': 1, 's': 2, 'a': 1, 'u': 2}
- Inverse Dictionary
撰寫一個函數,輸入為一個字典
將其所有 key 與 value 對調,再以字典形式回傳
若原始 value 有重複則用 list.append()
參考以下例子:
input - {'b': 1, 'r': 2, 'o': 2, 'n': 1, 't': 1, 's': 2, 'a': 1, 'u': 2}
output - {1: ['b', 'n', 't', 'a'], 2: ['r', 'o', 's', 'u']}
- 基本集合操作之一
給定兩集合 A、B,試求其聯集、交集與差集(A-B)
- 基本集合操作之二
給定三事件集合 A、B、C,試求
- A 且 B 且 C
- A 且 B 且 非C
- A 或 B 或 C
- A 或 B 且 非C
- 非A 且 非B 且 C
參考文氏圖:
![](https://i.imgur.com/OiwLMiD.png =50%x)
## 複習:條件、清單、字串、迴圈、字典
給定一個列表 book_list,內含多本書的資訊,每本書都是一個字典,字典中包含三個欄位:"book_name","author","ratings"。
請寫一個函式,計算每本書的平均評分(ratings 的平均分數),並以"book_name by author"為鍵,平均評分為值,回傳一個字典 book_rating,僅記錄評分大於3分的書。
Input:
```python=
book_list = [{"book_name": "To Kill a Mockingbird", "author": "Harper Lee", "ratings": [4, 5, 4, 5, 5]},
{"book_name": "Pride and Prejudice", "author": "Jane Austen", "ratings": [3, 4, 2, 4, 4]},
{"book_name": "1984", "author": "George Orwell", "ratings": [5, 5, 4, 4, 5]},
{"book_name": "The Great Gatsby", "author": "F. Scott Fitzgerald", "ratings": [2, 3, 3, 2, 3]},
{"book_name": "One Hundred Years of Solitude", "author": "Gabriel García Márquez", "ratings": [5, 5, 5, 5, 4]},
{"book_name": "Moby-Dick", "author": "Herman Melville", "ratings": [2, 2, 2, 2, 2]},
{"book_name": "Brave New World", "author": "Aldous Huxley", "ratings": [3, 4, 4, 5, 4]}
]
```
Output:
```python=
{
'To Kill a Mockingbird by Harper Lee': 4.6,
'1984 by George Orwell': 4.6,
'One Hundred Years of Solitude by Gabriel García Márquez': 4.8,
'Pride and Prejudice by Jane Austen': 3.4,
'Brave New World by Aldous Huxley': 4.0
}
```
## 檔案操作、例外處理練習
使用例外處理(`try-except`),試著讀入 'file.txt'
當讀檔成功時,印出檔案所有內容,讀檔失敗時則產生 'ReadFileError'(`raise`)
## Lambda
- 函數改寫:試著將「計算歐幾里得距離」改寫為 Lambda
- map():將「找最大」 map 到一個 list 中的各個元素,測試其是否正確(可以使用 max())
Input: [[1,2,3,4,5],[100,10,1,0],[2,5,10,6,8,3]]
Output: [5, 100, 10]
- filter() & sorted():
使用 filter() 與 sorted(),將以下 list 依照給定條件排序或篩選
各項元素分別代表名字、身高、體重、分數
```python=
grade = [('Bobby', 175, 65, 80),
('Amy', 160, 50, 90),
('Kent', 180, 90, 65),
('Dennis', 170, 70, 70),
('Jeremy', 178, 102, 95),
('Wednesday', 165, 55, 100)]
```
- 依照名字字母順序(A~Z)排序
- 依照名字長度小到大排序
- 依照身高從大排到小
- 依照身高從小排到大
- 篩選出BMI>=25的人
- 篩選出分數>=90分的人,並依分數從高到低排序
## 套件使用練習
以下題請挑一題用上課提到的不同方法各撰寫一次(如下),請自行搜尋所需要使用的函數。
在學習 Python 的路途上,自行尋找適合套件/函數的能力是很重要的,在學習完基礎後多半也是透過自主搜尋跟大量練習來熟悉 Python 的用法。
- `import [package]`
- `from [package] import [module/function]`
- `import [package] as [name]`
題目:
- 使用 `os` 套件印出當前路徑裡下的所有檔案
- 使用 `math` 套件內的函數計算階乘(e.g. 5!= 120)
- 使用 `random` 套件撰寫一個程式,每次執行時會給出一個隨機整數,範圍介於 1~100000 之間
- 使用 `random` 套件撰寫一個程式,給定一個 List,每次執行會回傳該 List 中的隨機元素
- 使用 `datetime` 套件撰寫一個程式,每次執行時會印出現在時間,需包含年/月/日/時/分/秒
- 使用 `time` 套件計算執行以下程式碼所需時間:
```python=
cnt = 0
while cnt <= 1000000:
cnt += 1
```
- 使用 `matplotlib.pyplot` 套件繪出以下圖表,第二張圖中,y值使用 `random` 隨機產生,而 x 與 y 皆為 1 - 10 之間的整數:
![](https://i.imgur.com/DgsBPu9.png =70%x)
![](https://i.imgur.com/UKXkZR7.png =70%x)
![](https://i.imgur.com/TzP5vOc.png =70%x)
![](https://i.imgur.com/pGmEnP2.png =70%x)
## Class
- 銀行帳戶
設計一個銀行帳戶類別(Account),每個帳戶都有自己的帳號(account_number)、所有者的姓名(owner_name)、餘額(balance),並提供以下功能:
- 存款(deposit)
- 提款(withdraw)
- 查詢帳戶信息(get_account_info)
- 轉賬(transfer),將款項從一個帳戶轉移到另一個帳戶
- 學生
設計一個學生類別(Student),每個學生都有自己的學號(student_id)、姓名(name)、年級(grade)、和科目成績(subject_scores),並提供以下功能:
- 新增一科成績(add_subject_score),可以新增一科科目的成績,包括科目名稱和成績。
- 查詢全部科目成績(get_all_subject_scores),可以獲取該學生的所有科目成績。
- 計算平均成績(calculate_average_score),可以計算該學生的平均成績。
- 獲取學生資訊(get_student_info),可以獲取該學生的所有資訊,包括學號、姓名、年級、科目成績和平均成績。