# Python程式設計 綜合練習(解答)
## 1. 身分證字號驗證器
我國的身分證字號有底下這樣的規則,因此對於任意輸入的身分證字號可以有一些基本的判斷原則:
(1) 英文代號以下表轉換成數字
```
A=10 台北市 J=18 新竹縣 S=26 高雄縣
B=11 台中市 K=19 苗栗縣 T=27 屏東縣
C=12 基隆市 L=20 台中縣 U=28 花蓮縣
D=13 台南市 M=21 南投縣 V=29 台東縣
E=14 高雄市 N=22 彰化縣 W=32 金門縣
F=15 台北縣 O=35 新竹市 X=30 澎湖縣
G=16 宜蘭縣 P=23 雲林縣 Y=31 陽明山
H=17 桃園縣 Q=24 嘉義縣 Z=33 連江縣
I=34 嘉義市 R=25 台南縣
```
(2) 英文轉成的數字, 個位數乘9再加上十位數的數字
(3) 各數字從右到左依次乘1, 2, 3, 4,...,8,並且相加
(4) 求出(2),(3) 及最後一碼的和
(5) 如果求出的和可以被10整除,則為合法身分證字號,否則為非法身分證字號
例如: T112663836
2 + 7x9 + 1x8 + 1x7 + 2x6 + 6x5 + 6x4 + 3x3 + 8x2 + 3x1 + 6 = 180
因為180可以被10 整除,此身分證字號為合法身分證字號
請你寫一個Python程式:
- 請使用者輸入身分證字號
- 如果通過公式驗證,則顯示為合法身分證字號;否則,顯示非法身分證字號
```
請輸入要驗證的身分證字號(輸入-1 關閉程式)> A123456789
這個身分證字號是合法的
請輸入要驗證的身分證字號(輸入-1 關閉程式)> A100200300
這個身分證字號是非法的
請輸入要驗證的身分證字號(輸入-1 關閉程式)> -1
程式已關閉
```
```python=
'''
A=10 台北市 J=18 新竹縣 S=26 高雄縣
B=11 台中市 K=19 苗栗縣 T=27 屏東縣
C=12 基隆市 L=20 台中縣 U=28 花蓮縣
D=13 台南市 M=21 南投縣 V=29 台東縣
E=14 高雄市 N=22 彰化縣 W=32 金門縣
F=15 台北縣 O=35 新竹市 X=30 澎湖縣
G=16 宜蘭縣 P=23 雲林縣 Y=31 陽明山
H=17 桃園縣 Q=24 嘉義縣 Z=33 連江縣
I=34 嘉義市 R=25 台南縣
'''
def city_id_transfer(first_char):
if first_char == 'A':
return 10
elif first_char == 'B':
return 11
elif first_char == 'C':
return 12
elif first_char == 'D':
return 13
elif first_char == 'E':
return 14
elif first_char == 'F':
return 15
elif first_char == 'G':
return 16
elif first_char == 'H':
return 17
elif first_char == 'I':
return 34
elif first_char == 'J':
return 18
elif first_char == 'K':
return 19
elif first_char == 'L':
return 20
elif first_char == 'M':
return 21
elif first_char == 'N':
return 22
elif first_char == 'O':
return 35
elif first_char == 'P':
return 23
elif first_char == 'Q':
return 24
elif first_char == 'R':
return 25
elif first_char == 'S':
return 26
elif first_char == 'T':
return 27
elif first_char == 'U':
return 28
elif first_char == 'V':
return 29
elif first_char == 'W':
return 32
elif first_char == 'X':
return 30
elif first_char == 'Y':
return 31
elif first_char == 'Z':
return 33
else:
print("請輸入有效字元")
# 請使用者輸入身分證字號
id = list(input("請輸入要驗證的身分證字號> "))
# 使用id_num存放所有轉換後的數字
id_num = []
# 將首位字母轉換成代號
id_num.append(city_id_transfer(id[0])/10)
id_num.append(city_id_transfer(id[0])%10)
# 將其它字元轉成數字
for i in range(len(id)-1):
id_num.append(int(id[i+1]))
# 代入驗證公式
check_sum = id_num[0]
x = 9
for i in range(1, 11, 1):
check_sum += id_num[i] * x
x -= 1
check_sum += id_num[-1]
# 檢查check sum是否可以被10整除,輸出驗證結果
if check_sum % 10 == 0:
print("這個身分證字號是合法的")
else:
print("這個身分證字號是非法的")
```
## 2. 列印圖形
請設計一個程式
- 讓使用者輸入選項(1: 畫矩形, 2: 畫三角形, 3: 畫金字塔, 0: 結束程式)
- 如果使用者輸入1
- 請使用者輸入寬度跟長度,按下Enter後畫出矩形
- 參考執行範例如下:
```
讓選擇要畫的圖形(1: 畫矩形, 2: 畫三角形, 3: 畫金字塔, 0: 結束程式)> 1
請輸入矩形的長度與寬度(以空格隔開)> 5 4
*****
*****
*****
*****
```
- 如果使用者輸入2
- 請使用者輸入高度,按下Enter後畫出矩形
- 參考執行範例如下:
```
讓選擇要畫的圖形(1: 畫矩形, 2: 畫三角形, 3: 畫金字塔, 0: 結束程式)> 2
請輸入三角形的高度> 4
*
***
*****
*******
```
- 如果使用者輸入3
- 請使用者輸入高度,按下Enter後畫出金字塔
- 參考執行範例如下:
```
讓選擇要畫的圖形(1: 畫矩形, 2: 畫三角形, 3: 畫金字塔, 0: 結束程式)> 1
請輸入金字塔的高度> 4
*
* *
* *
*******
```
- 如果使用者輸入0
- 結束程式
- 參考執行範例如下:
```
讓選擇要畫的圖形(1: 畫矩形, 2: 畫三角形, 3: 畫金字塔, 0: 結束程式)> 0
程式已關閉
```
:::spoiler 參考程式碼
```python=
def draw(choice):
if choice == 1:
draw_rectangle()
elif choice == 2:
draw_triangle()
elif choice == 3:
draw_pyramid()
elif choice == 0:
print()
else:
print("請輸入有效字元")
def draw_rectangle():
width = int(input("請輸入矩形寬度> "))
length = int(input("請輸入矩形長度> "))
for i in range (0, length, 1):
for j in range (0, width, 1):
print("*", end='')
print("")
def draw_triangle():
n= int(input("請輸入三角形的高度> "))
for i in range(0, n, 1):
for j in range(0, n-i-1, 1):
print(" ", end=" ")
for k in range(0, i+1, 1):
print("*", end=" ")
print("")
def draw_pyramid():
n = int(input("請輸入金字塔高度> "))
for i in range(0, n, 1):
# 根據層數印出正確空白數量
for j in range(0, n-i, 1):
print(" ", end="")
# 分三種情況討論
# 第一層
if i == 0:
print("*")
# 最後一列
elif i == n-1:
for j in range(0, n*2-1, 1):
print("*", end="")
print()
# 其他列
else:
print("*", end="")
for j in range(0, int(2*i-1), 1):
print(" ",end="")
print("*")
choice = -1
while choice != 0:
choice = int(input("請輸入你想繪製的圖形(1: 矩形, 2: 三角形, 3: 金字塔, 0: 結束程式)> "))
draw(choice)
print("程式已關閉")
```
:::
## 3. 終極密碼
請設計一個程式:
1. 讓電腦當莊家,隨機選定一個介於 1~100 之間的整數
2. 使用者要輸入數字去猜那個數字,直到猜中為止
- 沒猜中時電腦會限縮範圍當作提示,讓使用者再次嘗試
- Your answer is higher than final answer
- Your answer is lower than final answer
- 當使用者猜中時,告知使用者答案,以及花費的答題次數
- 程式會回傳訊息範例如下:「Congratulation! The answer is **32**. You take 3 rounds to get the answer!」
:::spoiler 參考程式碼
```python=
from random import randint
lowest = 1
highest = 100
count = 1
ans = randint(lowest, highest)
while True:
guess = int(input(f"從{lowest}~{highest}猜個數字吧 >"))
if guess <= lowest or guess >= highest:
print("請輸入範圍內數字")
else:
if guess == ans:
print(f"Congratulation! The answer is {guess}. You take {count} rounds to get the answer!")
break
elif guess > ans:
print("Your answer is higher than final answer")
highest = guess
count += 1
else:
print("Your answer is lower than final answer")
lowest = guess
count += 1
```
:::
## 4. 成績指標
![](https://i.imgur.com/5A3TCE3.png)
![](https://i.imgur.com/3BXkF6E.png)
![](https://i.imgur.com/rXodML1.png)
:::info
**本題演算法設計參考:**
1. 請使用者輸入學生人數,定義`成績list`的長度
2. 請使用者輸入成績,以`成績list`儲存
3. 呼叫sort()進行`成績list`排序,並且依序將元素印出
4. 條件判斷:
- 檢查最低成績是否及格,如果是,表示全部都及格
- 輸出`best case`
- 印出`最低及格者成績`
- 結束迴圈
- 或者,檢查最高成績是否不及格,如果是,表示全部人都不及格
- 印出`最高不及格者成績`
- 印出`worst case`
- 結束迴圈
- 其他情況
- 掃描`成績list`,找出最高不及格者
- 掃描`成績list`,找出最低及格者
- 結束迴圈
:::
:::spoiler 參考程式碼
```python=
#請使用者輸入學生人數,定義成績list的長度
stu_num = int(input())
#請使用者輸入成績,以成績list儲存
stu_list = []
temp = input().split()
for i in range(stu_num):
stu_list.append(int(temp[i]))
#呼叫sort()進行成績list排序,並且輸出
stu_list.sort()
for i in range(stu_num):
print(f"{stu_list[i]} ",end='')
print()
#條件判斷:
#檢查最低成績是否及格
#如果是,輸出best case、最低及格者成績,結束迴圈
if (stu_list[0] >= 60):
print("best case")
print(stu_list[0])
#檢查最高成績是否不及格
#如果是,輸出worst case,結束迴圈
elif(stu_list[stu_num-1] <= 60):
print(stu_list[stu_num-1])
print("worst case")
#其他情況
#掃描成績list,找出最高不及格者或是最低及格者
else:
#找出最高不及格者
for i in range(stu_num-1, -1, -1):
if (stu_list[i] < 60):
print(stu_list[i])
break
#最低及格者
for i in range(stu_num):
if (stu_list[i] >= 60):
print(stu_list[i])
break
```
:::
## 5. 收銀機
```python=
# 將可以找的面額列出
denomination = [1000, 500, 100, 50, 10, 5, 1]
# 請使用者輸入,計算要找錢金額
amount = int(input("請輸入結帳金額> "))
paid = int(input("請輸入顧客支付金額> "))
change = paid - amount
print(f"共要找{change}元")
# 計算要找錢的面額
for i in denomination:
num = change // i
# 只輸出需要找錢的面額數量
if num != 0:
print(f"{num} 個 {i} 元 ", end=" ")
# 將找錢總數扣掉已經找的面額數量
change %= i
```
```
請輸入結帳金額> 416
請輸入顧客支付金額> 1000
共要找584元
1 個 500 元 1 個 50 元 3 個 10 元 4 個 1 元
```