practice_exercises.py
Python/01_beginner_level/practice_exercises.py
"""
Python 初學者練習題 - Core Syntax & Control Flow
Practice Exercises for Core Syntax and Control Flow
涵蓋主題 (Topics Covered):
- 變數與賦值 (Variables & Assignment)
- 資料型態 (Data Types)
- 運算子 (Operators)
- 字串操作 (String Operations)
- 輸入與輸出 (Input & Output)
- 條件判斷 (Conditional Statements)
- 迴圈 (Loops)
- 綜合練習 (Combined Exercises)
使用方法 (How to Use):
1. 閱讀每道題目的說明
2. 在 "YOUR CODE HERE" 區塊中撰寫程式碼
3. 執行程式碼確認結果是否正確
4. 參考最下方的解答 (Solutions) 進行對照
"""
# ============================================================
# PART 1: 變數與資料型態 (Variables & Data Types)
# ============================================================
print("=" * 60)
print("PART 1: 變數與資料型態 (Variables & Data Types)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 1.1: 變數宣告與賦值
# 宣告以下變數並印出它們的值與型態
# - student_name: 你的名字 (字串)
# - student_age: 你的年齡 (整數)
# - student_height: 你的身高,單位公分 (浮點數)
# - is_enrolled: 是否已經註冊 (布林值)
#
# 預期輸出範例:
# Name: Alice, Type: <class 'str'>
# Age: 20, Type: <class 'int'>
# Height: 165.5, Type: <class 'float'>
# Enrolled: True, Type: <class 'bool'>
# ----------------------------------------------------------
print("\n--- Exercise 1.1: 變數宣告與賦值 ---")
student_name = "Alice"
student_age = 20
student_height = 165.5
is_enrolled = True
print(f"Name: {student_name}, Type: {type(student_name)}")
print(f"Age: {student_age}, Type: {type(student_age)}")
print(f"Height: {student_height}, Type: {type(student_height)}")
print(f"Enrolled: {is_enrolled}, Type: {type(is_enrolled)}")
# ----------------------------------------------------------
# Exercise 1.2: 多重賦值 (Multiple Assignment)
# 使用一行程式碼同時宣告三個變數:
# x = 10, y = 20, z = 30
# 然後交換 x 和 z 的值 (使用 Pythonic 方式)
# 印出交換前後的結果
#
# 預期輸出:
# Before swap: x=10, y=20, z=30
# After swap: x=30, y=20, z=10
# ----------------------------------------------------------
print("\n--- Exercise 1.2: 多重賦值 ---")
x, y, z = 10, 20, 30
print(f"Before swap: x={x}, y={y}, z={z}")
x, z = z, x
print(f"After swap: x={x}, y={y}, z={z}")
# ----------------------------------------------------------
# Exercise 1.3: 型態轉換 (Type Conversion)
# 給定以下字串,將它們轉換成適當的型態並進行計算
# price_str = "49.99"
# quantity_str = "3"
# discount_str = "True"
#
# 計算: total = price * quantity
# 如果 discount 為 True,打 9 折 (total * 0.9)
# 印出最終價格 (保留 2 位小數)
#
# 預期輸出:
# Price: 49.99, Quantity: 3
# Subtotal: 149.97
# Discount applied: True
# Final total: $134.97
# ----------------------------------------------------------
print("\n--- Exercise 1.3: 型態轉換 ---")
price_str = "49.99"
quantity_str = "3"
discount_str = "True"
price = float(price_str)
quantity = int(quantity_str)
discount = discount_str == "True"
subtotal = price * quantity
print(f"Price: {price}, Quantity: {quantity}")
print(f"Subtotal: {subtotal}")
print(f"Discount applied: {discount}")
if discount:
total = subtotal * 0.9
else:
total = subtotal
print(f"Final total: ${total:.2f}")
# ----------------------------------------------------------
# Exercise 1.4: 數字系統 (Number Systems)
# 將十進位數字 255 分別轉換為:
# - 二進位 (binary)
# - 八進位 (octal)
# - 十六進位 (hexadecimal)
# 並印出結果
#
# 提示: 使用 bin(), oct(), hex() 函數
#
# 預期輸出:
# Decimal: 255
# Binary: 0b11111111
# Octal: 0o377
# Hex: 0xff
# ----------------------------------------------------------
print("\n--- Exercise 1.4: 數字系統 ---")
decimal_num = 255
print(f"Decimal: {decimal_num}")
print(f"Binary: {bin(decimal_num)}")
print(f"Octal: {oct(decimal_num)}")
print(f"Hex: {hex(decimal_num)}")
# ----------------------------------------------------------
# Exercise 1.5: 布林運算 (Boolean Operations)
# 判斷以下運算式的結果 (先不要執行,先自己想)
# 然後印出結果驗證
#
# a) True and False
# b) True or False
# c) not True
# d) (5 > 3) and (10 < 20)
# e) (5 > 3) or (10 > 20)
# f) not (5 == 5)
# g) bool(0)
# h) bool("")
# i) bool("Hello")
# j) bool(42)
# ----------------------------------------------------------
print("\n--- Exercise 1.5: 布林運算 ---")
print(f"a) True and False = {True and False}")
print(f"b) True or False = {True or False}")
print(f"c) not True = {not True}")
print(f"d) (5 > 3) and (10 < 20) = {(5 > 3) and (10 < 20)}")
print(f"e) (5 > 3) or (10 > 20) = {(5 > 3) or (10 > 20)}")
print(f"f) not (5 == 5) = {not (5 == 5)}")
print(f"g) bool(0) = {bool(0)}")
print(f"h) bool('') = {bool('')}")
print(f"i) bool('Hello') = {bool('Hello')}")
print(f"j) bool(42) = {bool(42)}")
# ============================================================
# PART 2: 運算子 (Operators)
# ============================================================
print("\n" + "=" * 60)
print("PART 2: 運算子 (Operators)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 2.1: 算術運算子 (Arithmetic Operators)
# 給定兩個數字 a = 17, b = 5
# 計算並印出所有算術運算的結果:
# 加法、減法、乘法、除法、整數除法、取餘數、次方
#
# 預期輸出:
# a + b = 22
# a - b = 12
# a * b = 85
# a / b = 3.4
# a // b = 3
# a % b = 2
# a ** b = 1419857
# ----------------------------------------------------------
print("\n--- Exercise 2.1: 算術運算子 ---")
a = 17
b = 5
print(f"a + b = {a + b}")
print(f"a - b = {a - b}")
print(f"a * b = {a * b}")
print(f"a / b = {a / b}")
print(f"a // b = {a // b}")
print(f"a % b = {a % b}")
print(f"a ** b = {a ** b}")
# ----------------------------------------------------------
# Exercise 2.2: 複合賦值運算子 (Compound Assignment Operators)
# 從 x = 100 開始,依序執行以下操作,並在每步印出結果:
# 1. x += 50 (加 50)
# 2. x -= 30 (減 30)
# 3. x *= 2 (乘以 2)
# 4. x //= 3 (整除 3)
# 5. x %= 7 (取餘數 7)
# 6. x **= 3 (三次方)
#
# 每步印出: Step N: x = ???
# ----------------------------------------------------------
print("\n--- Exercise 2.2: 複合賦值運算子 ---")
x = 100
x += 50
print(f"Step 1: x = {x}") # 150
x -= 30
print(f"Step 2: x = {x}") # 120
x *= 2
print(f"Step 3: x = {x}") # 240
x //= 3
print(f"Step 4: x = {x}") # 80
x %= 7
print(f"Step 5: x = {x}") # 3
x **= 3
print(f"Step 6: x = {x}") # 27
# ----------------------------------------------------------
# Exercise 2.3: 比較運算子 (Comparison Operators)
# 給定 score = 78,判斷以下各條件是否為 True:
# a) score >= 90 (A 等級)
# b) score >= 80 (B 等級)
# c) score >= 70 (C 等級)
# d) score == 78 (剛好 78 分)
# e) score != 100 (不是滿分)
# f) 60 <= score < 80 (D 或 C 等級)
#
# 預期輸出:
# score >= 90: False
# score >= 80: False
# score >= 70: True
# score == 78: True
# score != 100: True
# 60 <= score < 80: True
# ----------------------------------------------------------
print("\n--- Exercise 2.3: 比較運算子 ---")
score = 78
print(f"score >= 90: {score >= 90}")
print(f"score >= 80: {score >= 80}")
print(f"score >= 70: {score >= 70}")
print(f"score == 78: {score == 78}")
print(f"score != 100: {score != 100}")
print(f"60 <= score < 80: {60 <= score < 80}")
# ----------------------------------------------------------
# Exercise 2.4: 運算優先順序 (Operator Precedence)
# 計算以下運算式的結果 (先自己算,再用 Python 驗證)
# a) 2 + 3 * 4
# b) (2 + 3) * 4
# c) 10 - 2 ** 3
# d) 15 // 4 + 15 % 4
# e) 2 ** 3 ** 2 (提示: ** 是右結合)
# f) not True or False and True
# ----------------------------------------------------------
print("\n--- Exercise 2.4: 運算優先順序 ---")
print(f"a) 2 + 3 * 4 = {2 + 3 * 4}") # 14
print(f"b) (2 + 3) * 4 = {(2 + 3) * 4}") # 20
print(f"c) 10 - 2 ** 3 = {10 - 2 ** 3}") # 2
print(f"d) 15 // 4 + 15 % 4 = {15 // 4 + 15 % 4}") # 6
print(f"e) 2 ** 3 ** 2 = {2 ** 3 ** 2}") # 512
print(f"f) not True or False and True = {not True or False and True}") # False
# ============================================================
# PART 3: 字串操作 (String Operations)
# ============================================================
print("\n" + "=" * 60)
print("PART 3: 字串操作 (String Operations)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 3.1: 字串基本操作
# 給定字串 sentence = " Hello, Python World! "
# 完成以下操作:
# a) 去除前後空白
# b) 轉為大寫
# c) 轉為小寫
# d) 將 "Python" 替換為 "Java"
# e) 用空格分割成 list
# f) 計算字串長度 (去除空白後)
#
# 印出每步結果
# ----------------------------------------------------------
print("\n--- Exercise 3.1: 字串基本操作 ---")
sentence = " Hello, Python World! "
cleaned = sentence.strip()
print(f"a) Stripped: '{cleaned}'")
print(f"b) Upper: '{cleaned.upper()}'")
print(f"c) Lower: '{cleaned.lower()}'")
print(f"d) Replaced: '{cleaned.replace('Python', 'Java')}'")
print(f"e) Split: {cleaned.split()}")
print(f"f) Length: {len(cleaned)}")
# ----------------------------------------------------------
# Exercise 3.2: 字串索引與切片 (String Indexing & Slicing)
# 給定字串 text = "Programming"
# 取出以下子字串:
# a) 第一個字元 -> "P"
# b) 最後一個字元 -> "g"
# c) 前 4 個字元 -> "Prog"
# d) 後 4 個字元 -> "ming"
# e) 從第 3 到第 7 個字元 -> "gram"
# f) 反轉字串 -> "gnimmargorP"
# g) 每隔一個字元取 -> "Pormig"
# ----------------------------------------------------------
print("\n--- Exercise 3.2: 字串索引與切片 ---")
text = "Programming"
print(f"a) First char: {text[0]}")
print(f"b) Last char: {text[-1]}")
print(f"c) First 4: {text[:4]}")
print(f"d) Last 4: {text[-4:]}")
print(f"e) 3rd to 7th: {text[2:6]}")
print(f"f) Reversed: {text[::-1]}")
print(f"g) Every other: {text[::2]}")
# ----------------------------------------------------------
# Exercise 3.3: f-string 格式化
# 使用 f-string 格式化以下資料:
# name = "Alice"
# score = 87.5
# rank = 3
#
# 印出:
# Student: Alice
# Score: 87.50 (保留 2 位小數)
# Rank: 003 (補零到 3 位)
# Result: Alice got 87.5 points and ranked #3
# ----------------------------------------------------------
print("\n--- Exercise 3.3: f-string 格式化 ---")
name = "Alice"
score = 87.5
rank = 3
print(f"Student: {name}")
print(f"Score: {score:.2f}")
print(f"Rank: {rank:03d}")
print(f"Result: {name} got {score} points and ranked #{rank}")
# ----------------------------------------------------------
# Exercise 3.4: 字串方法練習
# 給定以下電子郵件地址:
# email = " User.Name@Example.COM "
#
# 完成以下操作:
# a) 清除前後空白並轉為小寫
# b) 檢查是否包含 "@" 符號
# c) 取出 "@" 前面的使用者名稱
# d) 取出 "@" 後面的網域名稱
# e) 檢查網域是否以 ".com" 結尾
# f) 將使用者名稱中的 "." 替換為 "_"
#
# 預期輸出:
# Cleaned email: user.name@example.com
# Contains @: True
# Username: user.name
# Domain: example.com
# Is .com: True
# Modified username: user_name
# ----------------------------------------------------------
print("\n--- Exercise 3.4: 字串方法練習 ---")
email = " User.Name@Example.COM "
cleaned_email = email.strip().lower()
print(f"Cleaned email: {cleaned_email}")
print(f"Contains @: {'@' in cleaned_email}")
at_index = cleaned_email.index("@")
username = cleaned_email[:at_index]
domain = cleaned_email[at_index + 1:]
print(f"Username: {username}")
print(f"Domain: {domain}")
print(f"Is .com: {domain.endswith('.com')}")
print(f"Modified username: {username.replace('.', '_')}")
# ----------------------------------------------------------
# Exercise 3.5: 字串檢查方法 (String Checking Methods)
# 判斷以下字串各屬於什麼類型:
# a) "Hello123" -> isalnum()? isalpha()? isdigit()?
# b) "12345" -> isalnum()? isalpha()? isdigit()?
# c) "Hello" -> isalnum()? isalpha()? isdigit()?
# d) "hello world" -> isalnum()? isalpha()? islower()?
# e) "HELLO" -> isupper()? isalpha()?
# f) " " -> isspace()?
# ----------------------------------------------------------
print("\n--- Exercise 3.5: 字串檢查方法 ---")
test_strings = ["Hello123", "12345", "Hello", "hello world", "HELLO", " "]
for s in test_strings:
print(f"'{s}': isalnum={s.isalnum()}, isalpha={s.isalpha()}, "
f"isdigit={s.isdigit()}, islower={s.islower()}, "
f"isupper={s.isupper()}, isspace={s.isspace()}")
# ============================================================
# PART 4: 條件判斷 (Conditional Statements)
# ============================================================
print("\n" + "=" * 60)
print("PART 4: 條件判斷 (Conditional Statements)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 4.1: 基本 if/else
# 給定一個年份 year,判斷它是否為閏年
# 閏年規則:
# - 能被 4 整除 且 不能被 100 整除 → 閏年
# - 能被 400 整除 → 閏年
# - 其他 → 平年
#
# 測試: year = 2024, 1900, 2000, 2023
# ----------------------------------------------------------
print("\n--- Exercise 4.1: 閏年判斷 ---")
test_years = [2024, 1900, 2000, 2023]
for year in test_years:
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
print(f"{year} is a leap year")
else:
print(f"{year} is not a leap year")
# ----------------------------------------------------------
# Exercise 4.2: 成績等級判斷
# 給定一個分數 score (0-100),判斷等級:
# 90-100: A+ (Outstanding)
# 85-89: A (Excellent)
# 80-84: B+ (Very Good)
# 75-79: B (Good)
# 70-74: C+ (Above Average)
# 60-69: C (Average)
# 50-59: D (Below Average)
# 0-49: F (Fail)
# 其他: Invalid score
#
# 測試: scores = [95, 87, 82, 76, 71, 65, 55, 42, -5, 105]
# ----------------------------------------------------------
print("\n--- Exercise 4.2: 成績等級判斷 ---")
scores = [95, 87, 82, 76, 71, 65, 55, 42, -5, 105]
for score in scores:
if score < 0 or score > 100:
grade = "Invalid score"
elif score >= 90:
grade = "A+ (Outstanding)"
elif score >= 85:
grade = "A (Excellent)"
elif score >= 80:
grade = "B+ (Very Good)"
elif score >= 75:
grade = "B (Good)"
elif score >= 70:
grade = "C+ (Above Average)"
elif score >= 60:
grade = "C (Average)"
elif score >= 50:
grade = "D (Below Average)"
else:
grade = "F (Fail)"
print(f"Score {score}: {grade}")
# ----------------------------------------------------------
# Exercise 4.3: BMI 計算器
# 給定體重 weight (kg) 和身高 height (m)
# 計算 BMI = weight / (height ** 2)
# 判斷 BMI 類別:
# BMI < 18.5: Underweight
# 18.5 <= BMI < 24: Normal
# 24 <= BMI < 27: Overweight
# 27 <= BMI < 30: Mild Obesity
# 30 <= BMI < 35: Moderate Obesity
# BMI >= 35: Severe Obesity
#
# 測試資料:
# weight = 70, height = 1.75
# weight = 50, height = 1.70
# weight = 95, height = 1.65
# ----------------------------------------------------------
print("\n--- Exercise 4.3: BMI 計算器 ---")
test_data = [
(70, 1.75),
(50, 1.70),
(95, 1.65),
]
for weight, height in test_data:
bmi = weight / (height ** 2)
if bmi < 18.5:
category = "Underweight"
elif bmi < 24:
category = "Normal"
elif bmi < 27:
category = "Overweight"
elif bmi < 30:
category = "Mild Obesity"
elif bmi < 35:
category = "Moderate Obesity"
else:
category = "Severe Obesity"
print(f"Weight: {weight}kg, Height: {height}m, BMI: {bmi:.1f}, Category: {category}")
# ----------------------------------------------------------
# Exercise 4.4: 簡易計算機 (Nested Conditions)
# 寫一個簡易計算機:
# 1. 給定兩個數字和一個運算符號
# 2. 支援 +, -, *, /, //, %, **
# 3. 除法需要檢查除數是否為零
# 4. 印出計算結果
#
# 測試資料:
# (10, "+", 3) -> 10 + 3 = 13
# (10, "/", 0) -> Error: Division by zero!
# (2, "**", 8) -> 2 ** 8 = 256
# (17, "%", 5) -> 17 % 5 = 2
# ----------------------------------------------------------
print("\n--- Exercise 4.4: 簡易計算機 ---")
test_calculations = [
(10, "+", 3),
(10, "-", 3),
(10, "*", 3),
(10, "/", 3),
(10, "/", 0),
(2, "**", 8),
(17, "%", 5),
(17, "//", 5),
]
for num1, op, num2 in test_calculations:
if op == "+":
result = num1 + num2
elif op == "-":
result = num1 - num2
elif op == "*":
result = num1 * num2
elif op == "/":
if num2 == 0:
print(f"{num1} {op} {num2} = Error: Division by zero!")
continue
result = num1 / num2
elif op == "//":
if num2 == 0:
print(f"{num1} {op} {num2} = Error: Division by zero!")
continue
result = num1 // num2
elif op == "%":
result = num1 % num2
elif op == "**":
result = num1 ** num2
else:
print(f"Unknown operator: {op}")
continue
print(f"{num1} {op} {num2} = {result}")
# ----------------------------------------------------------
# Exercise 4.5: 三角形判斷
# 給定三個邊長 a, b, c,判斷:
# 1. 是否能構成三角形 (任兩邊之和大於第三邊)
# 2. 如果能構成三角形,判斷是什麼類型:
# - 等邊三角形 (Equilateral): 三邊相等
# - 等腰三角形 (Isosceles): 恰好兩邊相等
# - 不等邊三角形 (Scalene): 三邊都不相等
# 3. 額外判斷是否為直角三角形 (Pythagorean theorem)
#
# 測試資料:
# (3, 4, 5) -> Scalene, Right triangle
# (5, 5, 5) -> Equilateral
# (3, 3, 5) -> Isosceles
# (1, 2, 10) -> Not a valid triangle
# ----------------------------------------------------------
print("\n--- Exercise 4.5: 三角形判斷 ---")
test_triangles = [
(3, 4, 5),
(5, 5, 5),
(3, 3, 5),
(1, 2, 10),
(5, 12, 13),
(7, 7, 7),
]
for a, b, c in test_triangles:
if a + b > c and b + c > a and a + c > b:
if a == b == c:
triangle_type = "Equilateral"
elif a == b or b == c or a == c:
triangle_type = "Isosceles"
else:
triangle_type = "Scalene"
sides = sorted([a, b, c])
if sides[0] ** 2 + sides[1] ** 2 == sides[2] ** 2:
triangle_type += ", Right triangle"
print(f"({a}, {b}, {c}): Valid - {triangle_type}")
else:
print(f"({a}, {b}, {c}): Not a valid triangle")
# ============================================================
# PART 5: for 迴圈 (For Loops)
# ============================================================
print("\n" + "=" * 60)
print("PART 5: for 迴圈 (For Loops)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 5.1: 基本 range 練習
# 使用 range() 和 for 迴圈:
# a) 印出 1 到 20 的所有偶數
# b) 印出 100 到 50 的倒數 (每次減 10)
# c) 印出 1 到 100 的總和
# d) 印出 1 到 10 的階乘 (10!)
# ----------------------------------------------------------
print("\n--- Exercise 5.1: 基本 range 練習 ---")
# a) 偶數
print("Even numbers 1-20:", end=" ")
for i in range(2, 21, 2):
print(i, end=" ")
print()
# b) 倒數
print("100 to 50 countdown:", end=" ")
for i in range(100, 49, -10):
print(i, end=" ")
print()
# c) 總和
total = 0
for i in range(1, 101):
total += i
print(f"Sum 1 to 100: {total}")
# d) 階乘
factorial = 1
for i in range(1, 11):
factorial *= i
print(f"10! = {factorial}")
# ----------------------------------------------------------
# Exercise 5.2: 九九乘法表
# 印出完整的九九乘法表 (1x1 到 9x9)
# 格式要求:
# 1x1= 1 1x2= 2 1x3= 3 ...
# 2x1= 2 2x2= 4 2x3= 6 ...
# ...
# 9x1= 9 9x2=18 9x3=27 ...
# ----------------------------------------------------------
print("\n--- Exercise 5.2: 九九乘法表 ---")
for i in range(1, 10):
for j in range(1, 10):
print(f"{i}x{j}={i*j:2}", end=" ")
print()
# ----------------------------------------------------------
# Exercise 5.3: 星號圖案 (Star Patterns)
# 使用 for 迴圈印出以下圖案 (n = 5):
#
# Pattern A: 直角三角形
# *
# **
# ***
# ****
# *****
#
# Pattern B: 倒直角三角形
# *****
# ****
# ***
# **
# *
#
# Pattern C: 等腰三角形
# *
# ***
# *****
# *******
# *********
#
# Pattern D: 菱形
# *
# ***
# *****
# *******
# *********
# *******
# *****
# ***
# *
# ----------------------------------------------------------
print("\n--- Exercise 5.3: 星號圖案 ---")
n = 5
# Pattern A
print("Pattern A:")
for i in range(1, n + 1):
print("*" * i)
# Pattern B
print("\nPattern B:")
for i in range(n, 0, -1):
print("*" * i)
# Pattern C
print("\nPattern C:")
for i in range(1, n + 1):
spaces = " " * (n - i)
stars = "*" * (2 * i - 1)
print(spaces + stars)
# Pattern D
print("\nPattern D:")
for i in range(1, n + 1):
spaces = " " * (n - i)
stars = "*" * (2 * i - 1)
print(spaces + stars)
for i in range(n - 1, 0, -1):
spaces = " " * (n - i)
stars = "*" * (2 * i - 1)
print(spaces + stars)
# ----------------------------------------------------------
# Exercise 5.4: List 迭代練習
# 給定一個學生成績列表:
# grades = [88, 72, 95, 60, 45, 83, 91, 77, 68, 54]
#
# 使用 for 迴圈計算:
# a) 最高分和最低分
# b) 平均分數
# c) 及格 (>= 60) 和不及格的人數
# d) 高於平均的學生編號 (從 1 開始)
#
# 注意: 不要使用 max(), min(), sum() 等內建函數
# ----------------------------------------------------------
print("\n--- Exercise 5.4: List 迭代練習 ---")
grades = [88, 72, 95, 60, 45, 83, 91, 77, 68, 54]
max_grade = grades[0]
min_grade = grades[0]
total = 0
pass_count = 0
fail_count = 0
for i, g in enumerate(grades):
total += g
if g > max_grade:
max_grade = g
if g < min_grade:
min_grade = g
if g >= 60:
pass_count += 1
else:
fail_count += 1
average = total / len(grades)
print(f"Max: {max_grade}, Min: {min_grade}")
print(f"Average: {average:.2f}")
print(f"Pass: {pass_count}, Fail: {fail_count}")
print("Above average students:", end=" ")
for i, g in enumerate(grades):
if g > average:
print(f"#{i+1}({g})", end=" ")
print()
# ----------------------------------------------------------
# Exercise 5.5: enumerate 和 zip 練習
# 給定:
# names = ["Alice", "Bob", "Charlie", "Diana", "Eve"]
# scores = [88, 72, 95, 60, 83]
#
# a) 使用 enumerate 印出每個學生的排名和名字
# (排名從 1 開始)
# b) 使用 zip 將名字和分數配對印出
# c) 找出最高分的學生名字
# ----------------------------------------------------------
print("\n--- Exercise 5.5: enumerate 和 zip 練習 ---")
names = ["Alice", "Bob", "Charlie", "Diana", "Eve"]
scores = [88, 72, 95, 60, 83]
# a) enumerate
print("a) Student list:")
for i, name in enumerate(names, 1):
print(f" #{i}: {name}")
# b) zip
print("b) Name-score pairs:")
for name, score in zip(names, scores):
print(f" {name}: {score}")
# c) 最高分
best_name = names[0]
best_score = scores[0]
for name, score in zip(names, scores):
if score > best_score:
best_score = score
best_name = name
print(f"c) Top student: {best_name} ({best_score})")
# ----------------------------------------------------------
# Exercise 5.6: 字典迭代 (Dictionary Iteration)
# 給定一個學生資料字典:
# students = {
# "Alice": {"age": 20, "grade": 88, "major": "CS"},
# "Bob": {"age": 21, "grade": 72, "major": "Math"},
# "Charlie": {"age": 19, "grade": 95, "major": "CS"},
# "Diana": {"age": 22, "grade": 60, "major": "Physics"},
# "Eve": {"age": 20, "grade": 83, "major": "CS"},
# }
#
# 使用 for 迴圈:
# a) 印出所有學生的名字和成績
# b) 計算 CS 主修學生的平均成績
# c) 找出成績最高的學生
# d) 列出所有不同的主修 (不重複)
# ----------------------------------------------------------
print("\n--- Exercise 5.6: 字典迭代 ---")
students = {
"Alice": {"age": 20, "grade": 88, "major": "CS"},
"Bob": {"age": 21, "grade": 72, "major": "Math"},
"Charlie": {"age": 19, "grade": 95, "major": "CS"},
"Diana": {"age": 22, "grade": 60, "major": "Physics"},
"Eve": {"age": 20, "grade": 83, "major": "CS"},
}
# a) 印出所有學生的名字和成績
print("a) All students:")
for name, info in students.items():
print(f" {name}: grade={info['grade']}")
# b) 計算 CS 主修學生的平均成績
cs_total = 0
cs_count = 0
for name, info in students.items():
if info["major"] == "CS":
cs_total += info["grade"]
cs_count += 1
print(f"b) CS average: {cs_total / cs_count:.2f}")
# c) 找出成績最高的學生
top_name = ""
top_grade = 0
for name, info in students.items():
if info["grade"] > top_grade:
top_grade = info["grade"]
top_name = name
print(f"c) Top student: {top_name} ({top_grade})")
# d) 列出所有不同的主修
majors = []
for name, info in students.items():
if info["major"] not in majors:
majors.append(info["major"])
print(f"d) Majors: {majors}")
# ============================================================
# PART 6: while 迴圈 (While Loops)
# ============================================================
print("\n" + "=" * 60)
print("PART 6: while 迴圈 (While Loops)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 6.1: 數字猜測
# 不使用 input(),模擬猜數字遊戲:
# - 目標數字 target = 42
# - 猜測列表 guesses = [10, 30, 50, 40, 45, 42]
# - 從列表中依序取出猜測值
# - 印出 "Too low!", "Too high!", 或 "Correct!"
# - 記錄猜了幾次
# ----------------------------------------------------------
print("\n--- Exercise 6.1: 數字猜測 ---")
target = 42
guesses = [10, 30, 50, 40, 45, 42]
index = 0
while index < len(guesses):
guess = guesses[index]
if guess == target:
print(f"Guess {guess}... Correct! Found in {index + 1} attempts!")
break
elif guess < target:
print(f"Guess {guess}... Too low!")
else:
print(f"Guess {guess}... Too high!")
index += 1
# ----------------------------------------------------------
# Exercise 6.2: Collatz 猜想 (3n+1 問題)
# 給定一個正整數 n:
# - 如果 n 是偶數,n = n / 2
# - 如果 n 是奇數,n = 3n + 1
# - 重複直到 n = 1
#
# 印出整個過程和步數
#
# 測試: n = 27
# 預期: 27 → 82 → 41 → 124 → 62 → 31 → ... → 1
# ----------------------------------------------------------
print("\n--- Exercise 6.2: Collatz 猜想 ---")
n = 27
steps = 0
print(n, end="")
while n != 1:
if n % 2 == 0:
n = n // 2
else:
n = 3 * n + 1
steps += 1
print(f" → {n}", end="")
print(f"\nTotal steps: {steps}")
# ----------------------------------------------------------
# Exercise 6.3: 反轉數字
# 使用 while 迴圈將一個整數反轉
# 例如: 12345 → 54321
# -6789 → -9876
#
# 提示: 使用 % 10 取得個位數,// 10 去掉個位數
# 注意: 不要使用字串轉換的方式
# ----------------------------------------------------------
print("\n--- Exercise 6.3: 反轉數字 ---")
test_numbers = [12345, -6789, 100, 7, 9900]
for num in test_numbers:
original = num
negative = num < 0
num = abs(num)
reversed_num = 0
while num > 0:
reversed_num = reversed_num * 10 + num % 10
num //= 10
if negative:
reversed_num = -reversed_num
print(f"{original} → {reversed_num}")
# ----------------------------------------------------------
# Exercise 6.4: 數字拆解與統計
# 使用 while 迴圈,對於一個正整數:
# a) 計算位數 (幾位數)
# b) 計算各位數字之和
# c) 判斷是否為回文數 (正反讀都一樣)
# d) 找出最大和最小的位數
#
# 測試: numbers = [12321, 9876, 1001, 54321, 11111]
#
# 注意: 只能使用 while 迴圈和數學運算,不能轉字串
# ----------------------------------------------------------
print("\n--- Exercise 6.4: 數字拆解與統計 ---")
numbers = [12321, 9876, 1001, 54321, 11111]
for num in numbers:
original = num
digit_count = 0
digit_sum = 0
max_digit = 0
min_digit = 9
reversed_num = 0
temp = num
while temp > 0:
d = temp % 10
digit_count += 1
digit_sum += d
if d > max_digit:
max_digit = d
if d < min_digit:
min_digit = d
reversed_num = reversed_num * 10 + d
temp //= 10
is_palindrome = original == reversed_num
print(f"{original}: digits={digit_count}, sum={digit_sum}, "
f"max={max_digit}, min={min_digit}, palindrome={is_palindrome}")
# ============================================================
# PART 7: 迴圈控制 (Loop Control: break, continue, pass)
# ============================================================
print("\n" + "=" * 60)
print("PART 7: 迴圈控制 (Loop Control)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 7.1: break 練習
# 在列表中搜尋目標值,找到時立即停止
# data = [4, 7, 2, 9, 1, 5, 8, 3, 6, 10]
# target = 5
#
# 印出搜尋過程和結果:
# Checking 4... not found
# Checking 7... not found
# Checking 2... not found
# Checking 9... not found
# Checking 1... not found
# Checking 5... FOUND at index 5!
# ----------------------------------------------------------
print("\n--- Exercise 7.1: break 練習 ---")
data = [4, 7, 2, 9, 1, 5, 8, 3, 6, 10]
target = 5
for i, val in enumerate(data):
if val == target:
print(f"Checking {val}... FOUND at index {i}!")
break
else:
print(f"Checking {val}... not found")
# ----------------------------------------------------------
# Exercise 7.2: continue 練習
# 給定一個混合列表:
# items = [1, "hello", 3.14, None, 5, "world", 7, None, 9.5, 2]
#
# 只印出數字 (int 和 float),跳過其他型態
# 並計算所有數字的總和
# ----------------------------------------------------------
print("\n--- Exercise 7.2: continue 練習 ---")
items = [1, "hello", 3.14, None, 5, "world", 7, None, 9.5, 2]
total = 0
for item in items:
if not isinstance(item, (int, float)):
continue
print(f"Number found: {item}")
total += item
print(f"Sum of numbers: {total}")
# ----------------------------------------------------------
# Exercise 7.3: 質數判斷 (Prime Number)
# 寫程式判斷一個數字是否為質數
# 然後找出 2 到 100 之間的所有質數
#
# 提示:
# - 質數: 只能被 1 和自己整除的大於 1 的正整數
# - 檢查 2 到 sqrt(n) 的因數即可
# - 使用 break 提早結束檢查
#
# 預期輸出: 2, 3, 5, 7, 11, 13, ...
# ----------------------------------------------------------
print("\n--- Exercise 7.3: 質數判斷 ---")
primes = []
for num in range(2, 101):
is_prime = True
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
primes.append(num)
print(f"Primes (2-100): {primes}")
# ----------------------------------------------------------
# Exercise 7.4: FizzBuzz
# 經典面試題: 印出 1 到 50 的數字,但:
# - 如果是 3 的倍數,印 "Fizz"
# - 如果是 5 的倍數,印 "Buzz"
# - 如果同時是 3 和 5 的倍數,印 "FizzBuzz"
# - 其他情況印數字
#
# 輸出格式: 每行 10 個,用 tab 分隔
# ----------------------------------------------------------
print("\n--- Exercise 7.4: FizzBuzz ---")
for i in range(1, 51):
if i % 15 == 0:
val = "FizzBuzz"
elif i % 3 == 0:
val = "Fizz"
elif i % 5 == 0:
val = "Buzz"
else:
val = str(i)
print(f"{val}\t", end="")
if i % 10 == 0:
print()
# ============================================================
# PART 8: 巢狀迴圈 (Nested Loops)
# ============================================================
print("\n" + "=" * 60)
print("PART 8: 巢狀迴圈 (Nested Loops)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 8.1: 座位表
# 一個教室有 4 排 (rows),每排 6 個座位 (seats)
# 印出所有座位號碼:
# Row 1: [1-1] [1-2] [1-3] [1-4] [1-5] [1-6]
# Row 2: [2-1] [2-2] [2-3] [2-4] [2-5] [2-6]
# Row 3: [3-1] [3-2] [3-3] [3-4] [3-5] [3-6]
# Row 4: [4-1] [4-2] [4-3] [4-4] [4-5] [4-6]
# ----------------------------------------------------------
print("\n--- Exercise 8.1: 座位表 ---")
rows = 4
seats = 6
for r in range(1, rows + 1):
print(f"Row {r}: ", end="")
for s in range(1, seats + 1):
print(f"[{r}-{s}]", end=" ")
print()
# ----------------------------------------------------------
# Exercise 8.2: 二維列表處理
# 給定一個 4x4 的矩陣 (二維列表):
# matrix = [
# [1, 2, 3, 4],
# [5, 6, 7, 8],
# [9, 10, 11, 12],
# [13, 14, 15, 16],
# ]
#
# 計算:
# a) 所有元素的總和
# b) 每一列 (row) 的總和
# c) 每一行 (column) 的總和
# d) 對角線的總和 (主對角線 + 副對角線)
# e) 印出矩陣的轉置 (行列互換)
# ----------------------------------------------------------
print("\n--- Exercise 8.2: 二維列表處理 ---")
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]
# a) 所有元素的總和
total = 0
for row in matrix:
for val in row:
total += val
print(f"a) Total sum: {total}")
# b) 每一列的總和
print("b) Row sums:")
for i, row in enumerate(matrix):
row_sum = 0
for val in row:
row_sum += val
print(f" Row {i+1} sum: {row_sum}")
# c) 每一行的總和
print("c) Column sums:")
for j in range(len(matrix[0])):
col_sum = 0
for i in range(len(matrix)):
col_sum += matrix[i][j]
print(f" Column {j+1} sum: {col_sum}")
# d) 對角線的總和
main_diag = 0
anti_diag = 0
size = len(matrix)
for i in range(size):
main_diag += matrix[i][i]
anti_diag += matrix[i][size - 1 - i]
print(f"d) Main diagonal sum: {main_diag}")
print(f" Anti diagonal sum: {anti_diag}")
# e) 轉置矩陣
print("e) Transposed matrix:")
for j in range(len(matrix[0])):
for i in range(len(matrix)):
print(f"{matrix[i][j]:4}", end="")
print()
# ----------------------------------------------------------
# Exercise 8.3: 密碼驗證器
# 給定一組密碼列表,檢查每個密碼是否符合以下規則:
# - 長度至少 8 個字元
# - 至少包含 1 個大寫字母
# - 至少包含 1 個小寫字母
# - 至少包含 1 個數字
# - 至少包含 1 個特殊字元 (!@#$%^&*)
#
# 對每個密碼印出驗證結果和不符合的條件
#
# 測試:
# passwords = ["Abc12345!", "password", "SHORT1!", "NoSpecial1",
# "alllowercase1!", "ALLUPPERCASE1!", "NoDigits!abc"]
# ----------------------------------------------------------
print("\n--- Exercise 8.3: 密碼驗證器 ---")
passwords = [
"Abc12345!",
"password",
"SHORT1!",
"NoSpecial1",
"alllowercase1!",
"ALLUPPERCASE1!",
"NoDigits!abc",
]
special_chars = "!@#$%^&*"
for pwd in passwords:
errors = []
if len(pwd) < 8:
errors.append("too short")
has_upper = False
has_lower = False
has_digit = False
has_special = False
for ch in pwd:
if ch.isupper():
has_upper = True
elif ch.islower():
has_lower = True
elif ch.isdigit():
has_digit = True
elif ch in special_chars:
has_special = True
if not has_upper:
errors.append("no uppercase")
if not has_lower:
errors.append("no lowercase")
if not has_digit:
errors.append("no digit")
if not has_special:
errors.append("no special char")
if errors:
print(f"'{pwd}': WEAK - {', '.join(errors)}")
else:
print(f"'{pwd}': STRONG")
# ============================================================
# PART 9: 綜合練習 (Combined Exercises)
# ============================================================
print("\n" + "=" * 60)
print("PART 9: 綜合練習 (Combined Exercises)")
print("=" * 60)
# ----------------------------------------------------------
# Exercise 9.1: 購物車計算器
# 給定一個購物車資料:
# cart = [
# {"item": "Apple", "price": 1.50, "quantity": 4},
# {"item": "Bread", "price": 2.99, "quantity": 2},
# {"item": "Milk", "price": 3.49, "quantity": 1},
# {"item": "Eggs", "price": 4.99, "quantity": 2},
# {"item": "Rice", "price": 8.99, "quantity": 1},
# ]
#
# 計算:
# a) 每個商品的小計 (price * quantity)
# b) 購物車總金額
# c) 如果總金額超過 $30,打 9 折
# d) 稅金 (5%)
# e) 最終付款金額
# f) 印出漂亮的收據 (receipt)
# ----------------------------------------------------------
print("\n--- Exercise 9.1: 購物車計算器 ---")
cart = [
{"item": "Apple", "price": 1.50, "quantity": 4},
{"item": "Bread", "price": 2.99, "quantity": 2},
{"item": "Milk", "price": 3.49, "quantity": 1},
{"item": "Eggs", "price": 4.99, "quantity": 2},
{"item": "Rice", "price": 8.99, "quantity": 1},
]
print("=" * 40)
print(" RECEIPT")
print("=" * 40)
subtotal = 0
for item in cart:
item_total = item["price"] * item["quantity"]
subtotal += item_total
print(f"{item['item']:<10} x{item['quantity']} ${item['price']:>6.2f} ${item_total:>7.2f}")
print("-" * 40)
print(f"{'Subtotal':<25} ${subtotal:>7.2f}")
if subtotal > 30:
discount = subtotal * 0.1
print(f"{'Discount (10%)':<25} -${discount:>6.2f}")
after_discount = subtotal - discount
else:
discount = 0
after_discount = subtotal
tax = after_discount * 0.05
final = after_discount + tax
print(f"{'Tax (5%)':<25} ${tax:>7.2f}")
print("=" * 40)
print(f"{'TOTAL':<25} ${final:>7.2f}")
print("=" * 40)
# ----------------------------------------------------------
# Exercise 9.2: 學生成績報告
# 給定多個學生的多科成績:
# report = {
# "Alice": {"Math": 92, "English": 88, "Science": 95, "History": 78},
# "Bob": {"Math": 76, "English": 82, "Science": 71, "History": 90},
# "Charlie": {"Math": 88, "English": 91, "Science": 84, "History": 87},
# "Diana": {"Math": 65, "English": 70, "Science": 62, "History": 68},
# "Eve": {"Math": 95, "English": 93, "Science": 98, "History": 92},
# }
#
# 計算並印出:
# a) 每個學生的平均成績和等級 (A/B/C/D/F)
# b) 每個科目的班級平均分
# c) 全班最高分的學生和科目
# d) 全班最低分的學生和科目
# e) 印出漂亮的成績報告表格
# ----------------------------------------------------------
print("\n--- Exercise 9.2: 學生成績報告 ---")
report = {
"Alice": {"Math": 92, "English": 88, "Science": 95, "History": 78},
"Bob": {"Math": 76, "English": 82, "Science": 71, "History": 90},
"Charlie": {"Math": 88, "English": 91, "Science": 84, "History": 87},
"Diana": {"Math": 65, "English": 70, "Science": 62, "History": 68},
"Eve": {"Math": 95, "English": 93, "Science": 98, "History": 92},
}
print(f"{'Student':<10} {'Math':>6} {'Eng':>6} {'Sci':>6} {'Hist':>6} {'Avg':>6} {'Grade'}")
print("-" * 52)
all_highest = ("", "", 0)
all_lowest = ("", "", 101)
for student, subjects in report.items():
total = 0
for subj, score in subjects.items():
total += score
if score > all_highest[2]:
all_highest = (student, subj, score)
if score < all_lowest[2]:
all_lowest = (student, subj, score)
avg = total / len(subjects)
if avg >= 90:
grade = "A"
elif avg >= 80:
grade = "B"
elif avg >= 70:
grade = "C"
elif avg >= 60:
grade = "D"
else:
grade = "F"
print(f"{student:<10} {subjects['Math']:>6} {subjects['English']:>6} "
f"{subjects['Science']:>6} {subjects['History']:>6} {avg:>6.1f} {grade:>5}")
print(f"\nHighest: {all_highest[0]} - {all_highest[1]}: {all_highest[2]}")
print(f"Lowest: {all_lowest[0]} - {all_lowest[1]}: {all_lowest[2]}")
# ----------------------------------------------------------
# Exercise 9.3: 數字猜謎遊戲 (進階版)
# 模擬一個二分搜尋猜數字的策略:
# - 目標數字 target = 73
# - 範圍: 1 到 100
# - 每次猜中間值 (low + high) // 2
# - 根據結果調整範圍
# - 記錄每次猜測和結果
#
# 預期輸出:
# Round 1: Guess = 50, Too low! (Range: 1-100)
# Round 2: Guess = 75, Too high! (Range: 51-100)
# Round 3: Guess = 62, Too low! (Range: 51-74)
# ...
# Correct! Found 73 in N rounds!
# ----------------------------------------------------------
print("\n--- Exercise 9.3: 二分搜尋猜數字 ---")
target = 73
low = 1
high = 100
rounds = 0
while low <= high:
rounds += 1
guess = (low + high) // 2
if guess == target:
print(f"Round {rounds}: Guess = {guess}, Correct! (Range: {low}-{high})")
break
elif guess < target:
print(f"Round {rounds}: Guess = {guess}, Too low! (Range: {low}-{high})")
low = guess + 1
else:
print(f"Round {rounds}: Guess = {guess}, Too high! (Range: {low}-{high})")
high = guess - 1
print(f"Found {target} in {rounds} rounds!")
# ----------------------------------------------------------
# Exercise 9.4: 文字直方圖 (Text Histogram)
# 給定一段文字,統計每個字母出現的次數
# 並用 * 印出水平直方圖 (忽略空格和標點符號)
#
# 文字: "Hello World Python Programming"
#
# 預期輸出 (部分):
# d: *
# e: *
# g: **
# h: **
# i: *
# l: ***
# ...
# ----------------------------------------------------------
print("\n--- Exercise 9.4: 文字直方圖 ---")
histogram_text = "Hello World Python Programming"
char_count = {}
for ch in histogram_text.lower():
if ch.isalpha():
if ch in char_count:
char_count[ch] += 1
else:
char_count[ch] = 1
sorted_keys = sorted(char_count.keys())
for key in sorted_keys:
print(f"{key}: {'*' * char_count[key]}")
# ----------------------------------------------------------
# Exercise 9.5: 凱撒密碼 (Caesar Cipher)
# 實作凱撒密碼的加密和解密:
# - 加密: 每個字母向後移動 shift 個位置
# - 解密: 每個字母向前移動 shift 個位置
# - 只處理英文字母,其他字元保持不變
# - 處理大小寫
#
# 測試:
# message = "Hello, World! Python 3.14"
# shift = 3
# 加密後: "Khoor, Zruog! Sbwkrq 3.14"
# 解密後: "Hello, World! Python 3.14"
# ----------------------------------------------------------
print("\n--- Exercise 9.5: 凱撒密碼 ---")
message = "Hello, World! Python 3.14"
shift = 3
# Encrypt
encrypted = ""
for ch in message:
if ch.isalpha():
base = ord('A') if ch.isupper() else ord('a')
encrypted += chr((ord(ch) - base + shift) % 26 + base)
else:
encrypted += ch
print(f"Original: {message}")
print(f"Encrypted: {encrypted}")
# Decrypt
decrypted = ""
for ch in encrypted:
if ch.isalpha():
base = ord('A') if ch.isupper() else ord('a')
decrypted += chr((ord(ch) - base - shift) % 26 + base)
else:
decrypted += ch
print(f"Decrypted: {decrypted}")
# ----------------------------------------------------------
# Exercise 9.6: 數列生成器
# 生成以下數列的前 N 項 (N = 10):
#
# a) 費波那契數列 (Fibonacci):
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
#
# b) 三角數 (Triangular Numbers):
# 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
# (第 n 個 = n * (n+1) / 2)
#
# c) 完全平方數 (Perfect Squares):
# 1, 4, 9, 16, 25, 36, 49, 64, 81, 100
#
# d) 質數列 (Prime Numbers):
# 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
# ----------------------------------------------------------
print("\n--- Exercise 9.6: 數列生成器 ---")
N = 10
# a) Fibonacci
fib = [0, 1]
for i in range(2, N):
fib.append(fib[-1] + fib[-2])
print(f"a) Fibonacci: {fib}")
# b) Triangular Numbers
tri = []
for i in range(1, N + 1):
tri.append(i * (i + 1) // 2)
print(f"b) Triangular: {tri}")
# c) Perfect Squares
squares = []
for i in range(1, N + 1):
squares.append(i ** 2)
print(f"c) Squares: {squares}")
# d) Prime Numbers
primes = []
num = 2
while len(primes) < N:
is_prime = True
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
primes.append(num)
num += 1
print(f"d) Primes: {primes}")
# ----------------------------------------------------------
# Exercise 9.7: 簡易排序 (Sorting)
# 不使用 sort() 或 sorted(),實作以下排序演算法:
#
# a) 氣泡排序 (Bubble Sort)
# b) 選擇排序 (Selection Sort)
#
# 測試資料: data = [64, 34, 25, 12, 22, 11, 90]
# 每一輪排序後印出陣列狀態
# ----------------------------------------------------------
print("\n--- Exercise 9.7: 簡易排序 ---")
data = [64, 34, 25, 12, 22, 11, 90]
# a) Bubble Sort
print("=== Bubble Sort ===")
arr = data.copy()
print(f"Original: {arr}")
for i in range(len(arr)):
for j in range(len(arr) - 1 - i):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
print(f"Round {i+1}: {arr}")
print(f"Bubble Sort result: {arr}")
# b) Selection Sort
print("\n=== Selection Sort ===")
arr = data.copy()
print(f"Original: {arr}")
for i in range(len(arr)):
min_idx = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
print(f"Round {i+1}: {arr}")
print(f"Selection Sort result: {arr}")
# ============================================================
# PART 10: 挑戰題 (Challenge Exercises)
# ============================================================
print("\n" + "=" * 60)
print("PART 10: 挑戰題 (Challenge Exercises)")
print("=" * 60)
# ----------------------------------------------------------
# Challenge 10.1: 猜拳遊戲模擬
# 模擬兩個玩家的猜拳遊戲 (不使用 random):
# player1_moves = ["rock", "paper", "scissors", "rock", "paper"]
# player2_moves = ["scissors", "rock", "scissors", "paper", "paper"]
#
# 判斷每局的勝負,最終統計:
# - Player 1 勝場數
# - Player 2 勝場數
# - 平局次數
# - 最終勝者
# ----------------------------------------------------------
print("\n--- Challenge 10.1: 猜拳遊戲模擬 ---")
player1_moves = ["rock", "paper", "scissors", "rock", "paper"]
player2_moves = ["scissors", "rock", "scissors", "paper", "paper"]
p1_wins = 0
p2_wins = 0
draws = 0
for i in range(len(player1_moves)):
p1 = player1_moves[i]
p2 = player2_moves[i]
if p1 == p2:
result = "Draw"
draws += 1
elif (p1 == "rock" and p2 == "scissors") or \
(p1 == "paper" and p2 == "rock") or \
(p1 == "scissors" and p2 == "paper"):
result = "Player 1 wins"
p1_wins += 1
else:
result = "Player 2 wins"
p2_wins += 1
print(f"Round {i+1}: {p1} vs {p2} -> {result}")
print(f"\nP1: {p1_wins}, P2: {p2_wins}, Draws: {draws}")
if p1_wins > p2_wins:
print("Player 1 wins overall!")
elif p2_wins > p1_wins:
print("Player 2 wins overall!")
else:
print("It's a tie!")
# ----------------------------------------------------------
# Challenge 10.2: 停車場收費系統
# 停車場收費規則:
# - 前 1 小時: 免費
# - 1-3 小時: 每小時 $30
# - 3-6 小時: 每小時 $50
# - 6-12 小時: 每小時 $40
# - 超過 12 小時: 一律 $500 (全日最高)
# - 不足 1 小時以 1 小時計算
#
# 計算以下停車時間的費用:
# times = [0.5, 1, 2.5, 3, 4.5, 6, 8, 12, 15, 24]
# ----------------------------------------------------------
print("\n--- Challenge 10.2: 停車場收費系統 ---")
import math
times = [0.5, 1, 2.5, 3, 4.5, 6, 8, 12, 15, 24]
for hours in times:
if hours <= 1:
fee = 0
elif hours <= 3:
billable = math.ceil(hours) - 1
fee = billable * 30
elif hours <= 6:
fee = 2 * 30
billable = math.ceil(hours) - 3
fee += billable * 50
elif hours <= 12:
fee = 2 * 30 + 3 * 50
billable = math.ceil(hours) - 6
fee += billable * 40
else:
fee = 500
print(f"{hours:5.1f} hours: ${fee}")
# ----------------------------------------------------------
# Challenge 10.3: 數獨驗證器 (Sudoku Validator)
# 驗證一個已填完的 9x9 數獨是否合法:
# - 每一列 (row) 包含 1-9 不重複
# - 每一行 (column) 包含 1-9 不重複
# - 每個 3x3 小方格包含 1-9 不重複
#
# 注意: 只需要驗證,不需要解題
# ----------------------------------------------------------
print("\n--- Challenge 10.3: 數獨驗證器 ---")
valid_sudoku = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9],
]
invalid_sudoku = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 8], # 最後一個 9 改成 8 (重複)
]
def validate_sudoku(grid):
for row in grid:
if sorted(row) != list(range(1, 10)):
return False
for j in range(9):
col = []
for i in range(9):
col.append(grid[i][j])
if sorted(col) != list(range(1, 10)):
return False
for box_r in range(3):
for box_c in range(3):
box = []
for i in range(3):
for j in range(3):
box.append(grid[box_r * 3 + i][box_c * 3 + j])
if sorted(box) != list(range(1, 10)):
return False
return True
print(f"Valid sudoku: {validate_sudoku(valid_sudoku)}")
print(f"Invalid sudoku: {validate_sudoku(invalid_sudoku)}")
# ----------------------------------------------------------
# Challenge 10.4: 生命遊戲 (Conway's Game of Life) - 簡化版
# 在一個 10x10 的網格上模擬生命遊戲:
# - 活細胞 (1) 周圍有 2 或 3 個活鄰居 → 存活
# - 活細胞 周圍少於 2 或多於 3 個活鄰居 → 死亡
# - 死細胞 (0) 周圍恰好 3 個活鄰居 → 復活
#
# 初始狀態 (Glider):
# 在 (1,2), (2,3), (3,1), (3,2), (3,3) 放置活細胞
#
# 模擬 5 代,每代印出網格狀態
# ----------------------------------------------------------
print("\n--- Challenge 10.4: 生命遊戲 ---")
GRID_SIZE = 10
GENERATIONS = 5
grid = [[0] * GRID_SIZE for _ in range(GRID_SIZE)]
# Glider pattern
grid[1][2] = 1
grid[2][3] = 1
grid[3][1] = 1
grid[3][2] = 1
grid[3][3] = 1
def print_grid(g, gen):
print(f"\nGeneration {gen}:")
for row in g:
line = ""
for cell in row:
line += "█ " if cell else ". "
print(line)
def count_neighbors(g, r, c):
count = 0
for dr in [-1, 0, 1]:
for dc in [-1, 0, 1]:
if dr == 0 and dc == 0:
continue
nr, nc = r + dr, c + dc
if 0 <= nr < GRID_SIZE and 0 <= nc < GRID_SIZE:
count += g[nr][nc]
return count
print_grid(grid, 0)
for gen in range(1, GENERATIONS + 1):
new_grid = [[0] * GRID_SIZE for _ in range(GRID_SIZE)]
for r in range(GRID_SIZE):
for c in range(GRID_SIZE):
neighbors = count_neighbors(grid, r, c)
if grid[r][c] == 1:
if neighbors in (2, 3):
new_grid[r][c] = 1
else:
if neighbors == 3:
new_grid[r][c] = 1
grid = new_grid
print_grid(grid, gen)
print("\n=== All exercises completed! ===")
Articoli correlati
01_getting_started.py
01_getting_started.py — python source code from the Python learning materials (Python/01_beginner_level/01_getting_started.py).
Leggi l'articolo →02_core_syntax.py
02_core_syntax.py — python source code from the Python learning materials (Python/01_beginner_level/02_core_syntax.py).
Leggi l'articolo →03_control_flow.py
03_control_flow.py — python source code from the Python learning materials (Python/01_beginner_level/03_control_flow.py).
Leggi l'articolo →04_data_structures.py
04_data_structures.py — python source code from the Python learning materials (Python/01_beginner_level/04_data_structures.py).
Leggi l'articolo →05_functions.py
05_functions.py — python source code from the Python learning materials (Python/01_beginner_level/05_functions.py).
Leggi l'articolo →06_error_handling.py
06_error_handling.py — python source code from the Python learning materials (Python/01_beginner_level/06_error_handling.py).
Leggi l'articolo →