🪐 L2: 木星軌道站

B3: 複雜工程學:函式、模組化與作用域

⏱️ 預計時間:4-5 小時 🎯 目標級分:3 級分 📊 難度:⭐⭐⭐☆☆

🚀 任務背景

在木星軌道站,你需要管理多個複雜的子系統:生命維持、能源管理、通訊系統等。如果將所有邏輯寫在一個巨大的程式中,維護將是噩夢!

作為系統工程師,你需要學會將複雜問題分解為多個獨立的模組(函式),每個模組負責一個明確的任務。這不僅讓程式更易於理解和除錯,也能讓程式碼重複使用。

在這個訓練模組中,你將學習:
  • 如何定義和使用函式
  • 理解變數的作用域(Scope)
  • 掌握 Python 的參數傳遞機制
  • 函式的最佳實踐

📚 知識點說明

為什麼需要函式?

問題分解(Problem Decomposition):將一個複雜問題拆解成多個更小、更易於管理的子問題。
# ❌ 不好的做法:所有邏輯混在一起
data = input()
# ... 100 行程式碼 ...
result = ...
print(result)

# ✅ 好的做法:模組化 def parse_data(raw_data): """解析輸入數據""" return processed_data

def calculate(data): """執行計算""" return result

def format_output(result): """格式化輸出""" return formatted

# 主程式清晰易讀 data = parse_data(input()) result = calculate(data) print(format_output(result))

函式定義語法

def function_name(parameter1, parameter2):
    """
    函式說明文件(Docstring)
    """
    # 函式主體
    result = parameter1 + parameter2
    return result  # 回傳值

作用域(Scope)

區域變數 vs 全域變數
global_var = 100  # 全域變數

def my_function(): local_var = 50 # 區域變數 print(global_var) # 可以讀取全域變數 print(local_var) # 可以讀取區域變數

my_function() # print(local_var) # ❌ 錯誤!無法在函式外存取區域變數

⚠️ 最佳實踐:盡量避免使用全域變數,通過參數傳遞和回傳值來溝通。

Python 的參數傳遞機制

Python 使用「物件參考傳遞」(Call by Object Reference):

可變物件(Mutable)
def modify_list(lst):
    lst.append(999)  # 會修改原始列表
    
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list)  # [1, 2, 3, 999] ✓ 被修改了
不可變物件(Immutable)
def modify_number(n):
    n = n + 100  # 創建新物件,不影響原始變數
    
my_num = 50
modify_number(my_num)
print(my_num)  # 50 ✓ 沒有被修改

💻 範例程式碼

範例 1:計算火箭燃料消耗

import sys

def calculate_fuel(distance, efficiency): """ 計算所需燃料 distance: 飛行距離(公里) efficiency: 燃料效率(公里/公升) """ fuel_needed = distance / efficiency return fuel_needed

def format_report(distance, fuel): """格式化報告""" return f"飛行 {distance} 公里需要 {fuel:.2f} 公升燃料"

# 主程式 distance = int(sys.stdin.readline()) efficiency = float(sys.stdin.readline())

fuel = calculate_fuel(distance, efficiency) print(format_report(distance, fuel))
輸入範例
1000
25.5
輸出範例
飛行 1000 公里需要 39.22 公升燃料

範例 2:溫度轉換系統

import sys

def celsius_to_fahrenheit(celsius): """攝氏轉華氏""" return celsius * 9/5 + 32

def fahrenheit_to_celsius(fahrenheit): """華氏轉攝氏""" return (fahrenheit - 32) * 5/9

def kelvin_to_celsius(kelvin): """克耳文轉攝氏""" return kelvin - 273.15

# 讀取溫度和單位 temp = float(sys.stdin.readline()) unit = sys.stdin.readline().strip()

if unit == 'C': print(f"{celsius_to_fahrenheit(temp):.2f} °F") elif unit == 'F': print(f"{fahrenheit_to_celsius(temp):.2f} °C") elif unit == 'K': print(f"{kelvin_to_celsius(temp):.2f} °C")

範例 3:質數檢測

import sys

def is_prime(n): """ 檢查 n 是否為質數 回傳 True 或 False """ if n < 2: return False if n == 2: return True if n % 2 == 0: return False # 只需檢查到 sqrt(n) i = 3 while i * i <= n: if n % i == 0: return False i += 2 return True

# 主程式 n = int(sys.stdin.readline())

if is_prime(n): print(f"{n} 是質數") else: print(f"{n} 不是質數")

範例 4:列表統計函式

import sys

def calculate_stats(numbers): """ 計算列表的統計數據 回傳:(總和, 平均值, 最大值, 最小值) """ total = sum(numbers) avg = total / len(numbers) maximum = max(numbers) minimum = min(numbers) return total, avg, maximum, minimum

# 讀取數據 n = int(sys.stdin.readline()) numbers = list(map(int, sys.stdin.readline().split()))

# 呼叫函式並解包回傳值 total, avg, maximum, minimum = calculate_stats(numbers)

print(f"總和:{total}") print(f"平均:{avg:.2f}") print(f"最大:{maximum}") print(f"最小:{minimum}")

🔍 程式碼解說

關鍵技術點

#### 1. 函式設計原則

單一職責原則(Single Responsibility Principle)
  • 每個函式只做一件事
  • 函式名稱應清楚描述其功能
  • 函式長度建議不超過 20-30 行

#### 2. 參數與回傳值

def process_data(input_data, option=True):
    """
    input_data: 必要參數
    option: 選擇性參數(有預設值)
    """
    if option:
        return input_data * 2
    return input_data

#### 3. 多個回傳值

Python 可以回傳多個值(實際上是回傳一個 tuple):

def get_min_max(numbers):
    return min(numbers), max(numbers)
minimum, maximum = get_min_max([1, 5, 3, 9, 2])

#### 4. 遞迴初探

函式可以呼叫自己:

def factorial(n):
    """計算階乘"""
    if n <= 1:  # 基礎情況
        return 1
    return n * factorial(n - 1)  # 遞迴呼叫

📝 Quiz: 太空站系統管理

題目

木星軌道站需要一個氧氣管理系統。請設計以下函式:

  1. calculate_oxygen_consumption(crew_size, days) - 計算氧氣消耗量
  2. 每人每天消耗 0.84 公斤氧氣
  1. check_oxygen_level(current, required) - 檢查氧氣是否足夠
  2. 回傳 True(足夠)或 False(不足)
  1. format_warning(shortage) - 格式化警告訊息
  2. 如果短缺,回傳警告訊息
輸入格式
第一行:機組人員數量
第二行:任務天數
第三行:當前氧氣儲量(公斤)
輸出格式
  • 如果足夠:氧氣充足:剩餘 X.XX 公斤
  • 如果不足:警告:氧氣短缺 X.XX 公斤!
輸入範例
5
30
100
輸出範例
警告:氧氣短缺 26.00 公斤!

Quiz 解答

import sys

def calculate_oxygen_consumption(crew_size, days): """計算氧氣消耗量""" consumption_per_person_per_day = 0.84 total_consumption = crew_size days consumption_per_person_per_day return total_consumption

def check_oxygen_level(current, required): """檢查氧氣是否足夠""" return current >= required

def format_warning(shortage): """格式化警告訊息""" if shortage < 0: return f"警告:氧氣短缺 {abs(shortage):.2f} 公斤!" else: return f"氧氣充足:剩餘 {shortage:.2f} 公斤"

# 主程式 crew_size = int(sys.stdin.readline()) days = int(sys.stdin.readline()) current_oxygen = float(sys.stdin.readline())

# 計算所需氧氣 required = calculate_oxygen_consumption(crew_size, days)

# 計算剩餘或短缺 difference = current_oxygen - required

# 輸出結果 print(format_warning(difference))

解答說明

模組化設計的優勢
  1. 易於測試:每個函式可以獨立測試
  2. 易於維護:修改某個功能只需改對應函式
  3. 易於重用:函式可以在不同地方使用
  4. 易於理解:主程式邏輯清晰
函式命名
  • 使用動詞開頭:calculate_, check_, format_
  • 名稱描述功能:一看就知道做什麼
🎉

訓練完成!

恭喜你完成 函式與模組化工程 訓練!