一起玩Python程式:新手寫程式也可以這麼簡單!

函式設計(上) - 打造程式積木樂園!

張傑帆

National Taiwan University

函式設計(上) - 打造程式積木樂園!

目錄

Alt1

🎯 學習目標

今天我們要建立自己的魔法咒語庫!

  • ✨ 理解函式的概念與重要性
  • 🔧 學會定義和呼叫函式
  • 🎁 掌握參數傳遞的技巧
  • 🔄 運用回傳值讓函式更強大
  • 🌍 了解變數的作用域
  • ⚔️ 設計自己的魔法咒語系統

準備好打造你的程式積木樂園了嗎?

Let's create functions! 🐍

🧙‍♂️ 什麼是函式?

生活中的函式

想像你有一個「煮咖啡機器」:

  • 🔹 輸入:咖啡豆、水
  • 🔹 過程:研磨、加熱、萃取
  • 🔹 輸出:一杯香濃咖啡 ☕

函式就像這台機器,把複雜的步驟包裝起來,需要時只要按下按鈕!

為什麼需要函式?

優點 說明 比喻
🔄 重複使用 寫一次,用很多次 魔法咒語可以重複施展
📦 程式模組化 把功能分門別類 方便整理不同體系的咒語
🐛 易於除錯 問題出在哪一塊很清楚 找出故障的零件
👥 團隊合作 大家分工寫不同函式 各司其職的冒險隊伍

📝 函式的基本語法

定義函式的格式

# 基本結構
def 函式名稱():
    # 函式內容(縮排很重要!)
    執行的程式碼
    執行的程式碼

第一個函式:打招呼

# 定義一個打招呼的函式
def say_hello():
    print("🎉 歡迎來到魔法世界!")
    print("✨ 準備好學習函式了嗎?")

# 呼叫函式(執行函式)
say_hello()

執行結果:

🎉 歡迎來到魔法世界!
✨ 準備好學習函式了嗎?

重點提醒

  1. def 是定義函式的關鍵字
  2. 函式名稱後面要加 小括號 ()
  3. 冒號 : 不能忘記
  4. 函式內容要 縮排(通常4個空格)
  5. 定義函式後,要呼叫才會執行
def my_function():  # ← 定義函式(還不會執行)
    print("Hello")

my_function()  # ← 呼叫函式(這時才執行)

🎁 參數傳遞的魔法

什麼是參數?

參數就像是函式的「控器器」
讓同一個函式可以產生不同結果!

# 有參數的函式
def greet(name):
    print(f"哈囉,{name}!歡迎加入冒險!")

# 傳入不同的參數
greet("小明")  # 輸出:哈囉,小明!歡迎加入冒險!
greet("小華")  # 輸出:哈囉,小華!歡迎加入冒險!
greet("小美")  # 輸出:哈囉,小美!歡迎加入冒險!

多個參數的使用

# 攻擊魔法函式
def attack(attacker, target, damage):
    print(f"⚔ {attacker}{target} 發動攻擊!")
    print(f"💥 造成 {damage} 點傷害!")

# 呼叫函式
attack("勇者", "哥布林", 50)

執行結果:

⚔ 勇者 對 哥布林 發動攻擊!
💥 造成 50 點傷害!

位置參數 vs 關鍵字參數

def introduce(name, age, job):
    print(f"我是{name},今年{age}歲,職業是{job}")

# 位置參數(按順序傳入)
introduce("小明", 20, "魔法師")

# 關鍵字參數(指定名稱,順序可調換)
introduce(job="戰士", name="小華", age=22)

# 混合使用(位置參數要在前面)
introduce("小美", age=21, job="弓箭手")

預設參數值

# 設定預設值
def power_up(character, power=10):
    print(f"✨ {character} 的力量提升 {power} 點!")

# 使用預設值
power_up("勇者")  # 輸出:✨ 勇者 的力量提升 10 點!

# 覆蓋預設值
power_up("勇者", 50)  # 輸出:✨ 勇者 的力量提升 50 點!

🔄 回傳值的應用

什麼是回傳值?

回傳值就是函式執行後「交還」給你的結果!

# 沒有回傳值的函式
def say_hello():
    print("Hello!")

# 有回傳值的函式
def calculate_sum(a, b):
    result = a + b
    return result  # 把結果回傳出去

n = say_hello()  # 沒有回傳值
print(n)  # 輸出:None

# 接收回傳值
total = calculate_sum(10, 20)
print(f"總和是:{total}")  # 輸出:總和是:30

定義函式

alt text

example

魔法傷害計算

def calculate_damage(base_damage, critical=False):
    """計算攻擊傷害"""
    if critical:
        damage = base_damage * 2
        print("💥 暴擊!")
    else:
        damage = base_damage
    
    return damage

# 使用函式
normal_hit = calculate_damage(50)
print(f"普通攻擊傷害:{normal_hit}")

critical_hit = calculate_damage(50, critical=True)
print(f"暴擊傷害:{critical_hit}")

回傳多個值

def battle_result(attacker_hp, damage_taken):
    """計算戰鬥結果"""
    remaining_hp = attacker_hp - damage_taken
    is_alive = remaining_hp > 0
    
    return remaining_hp, is_alive  # 回傳多個值

# 接收多個回傳值
hp, alive = battle_result(100, 60)
print(f"剩餘HP:{hp}")
print(f"是否存活:{alive}")

🌍 變數的作用域

區域變數 vs 全域變數

# 全域變數(整個程式都看得到)
game_title = "魔法冒險"

def start_game():
    # 區域變數(只有函式內看得到)
    player_name = "勇者"
    print(f"遊戲:{game_title}")
    print(f"玩家:{player_name}")

start_game()
print(game_title)  # ✅ 可以使用
# print(player_name)  # ❌ 錯誤!區域變數在外面看不到

變數作用域圖解

變數類型 定義位置 可見範圍 生命週期
🌍 全域變數 函式外 整個程式 程式開始到結束
🏠 區域變數 函式內 只在函式內 函式執行期間
level = 1  # 全域變數

def level_up():
    level = 2  # 這是新的區域變數,不會改到全域變數
    print(f"函式內level: {level}")

level_up()
print(f"函式外level: {level}")  # 還是1

使用global關鍵字

player_hp = 100  # 全域變數

def take_damage(damage):
    global player_hp  # 宣告要使用全域變數
    player_hp = player_hp - damage
    print(f"💔 受到 {damage} 點傷害!")
    print(f"❤ 剩餘HP:{player_hp}")

take_damage(30)
print(f"當前HP:{player_hp}")  # HP真的改變了

⚔️ 魔法咒語實戰

範例1:基礎攻擊魔法

def fire_ball(target, power=30):
    """火球術"""
    damage = power * 1.5
    print(f"🔥{target}施放火球術!")
    print(f"💥 造成{damage}點火焰傷害!")
    return damage

# 使用魔法
fire_ball("哥布林")
fire_ball("惡龍", power=50)

範例2:治療魔法

def heal(target, heal_amount=50):
    """治療術"""
    print(f"✨{target}施放治療術!")
    print(f"💚 恢復{heal_amount}點HP!")
    return heal_amount

def check_hp(current_hp, max_hp=100):
    """檢查HP狀態"""
    percentage = (current_hp / max_hp) * 100
    
    if percentage <= 30:
        status = "⚠ 危險"
    elif percentage <= 60:
        status = "⚡ 注意"
    else:
        status = "✅ 健康"
    
    return status

# 使用魔法
heal("勇者", 40)
status = check_hp(70)
print(f"狀態:{status}")

範例3:完整魔法系統

def magic_attack(caster, target, magic_type, power):
    """魔法攻擊系統"""
    # 根據魔法類型計算傷害
    if magic_type == "火":
        damage = power * 1.5
        emoji = "🔥"
    elif magic_type == "冰":
        damage = power * 1.3
        emoji = "❄"
    elif magic_type == "雷":
        damage = power * 1.7
        emoji = "⚡"
    else:
        damage = power
        emoji = "✨"
    
    # 顯示攻擊訊息
    print(f"{emoji} {caster}{target} 施放 {magic_type} 系魔法!")
    print(f"💥 造成 {damage} 點傷害!")
    
    return damage

# 實戰演練
magic_attack("魔法師小明", "暗黑騎士", "雷", 50)

小練習 1

🎯 任務:設計你的專屬魔法

請完成以下函式:

def my_magic(caster, target, magic_name):
    """
    設計一個專屬魔法
    參數:
        caster: 施法者名稱
        target: 目標名稱
        magic_name: 魔法名稱
    """
    # 在這裡寫下你的魔法效果
    pass  # 刪除這行,開始寫程式

# 測試你的魔法
my_magic("勇者", "怪物", "聖光術")

💡 練習提示

  1. 使用 print() 顯示魔法效果
  2. 可以加入emoji讓畫面更生動
  3. 試著加入傷害計算
  4. 回傳魔法造成的效果數值
def my_magic(caster, target, magic_name):
    ...# 在這裡寫下你的魔法效果
    return damage # 回傳傷害值

休息時間


喝口水,活動一下筋骨!
等等我們繼續深入函式的奧秘 🌟

🎮 進階應用:參數組合技 - 魔法連擊系統

def combo_attack(character, *targets, power=50):
    """
    對多個目標發動連擊
    *targets 可以接收任意數量的參數
    """
    print(f"⚔ {character} 發動連擊技!")
    total_damage = 0
    
    for target in targets:
        damage = power
        print(f"  💥 攻擊 {target},造成 {damage} 傷害")
        total_damage += damage
    
    print(f"✨ 總傷害:{total_damage}")
    return total_damage

# 攻擊多個敵人
combo_attack("劍士", "哥布林A", "哥布林B", "哥布林C", power=40)

關鍵字參數組合技

def create_character(**attributes):
    """
    創建角色,接收任意關鍵字參數
    **attributes 會把所有關鍵字參數收集成字典
    """
    print("🎨 創建新角色:")
    for key, value in attributes.items():
        print(f"  {key}: {value}")

# 創建不同的角色
create_character(name="勇者", level=10, hp=150, mp=80, job="戰士")
create_character(name="魔法師", level=8, hp=100, mp=200, job="法師", element="火")

🧩 函式設計原則

好的函式設計

# ✅ 好的設計:功能單一、名稱清楚
def calculate_total_price(price, quantity):
    """計算總價"""
    return price * quantity

def apply_discount(price, discount_rate):
    """套用折扣"""
    return price * (1 - discount_rate)

# 使用
total = calculate_total_price(100, 3)
final_price = apply_discount(total, 0.1)

避免的寫法

# ❌ 不好的設計:功能混雜、名稱不清
def do_something(x, y, z):
    """這個函式做太多事了"""
    result1 = x * y
    result2 = result1 - z
    print(result2)
    return result2 * 2

# 誰看得懂這在做什麼?

📚 函式設計的黃金法則

原則 說明 範例
🎯 單一職責 一個函式只做一件事 calculate_damage()
📝 命名清楚 名稱要能說明功能 heal_player() 而非 func1()
📦 適當參數 參數不要太多(建議≤5個) 太多就用字典或類別
🔄 有回傳值 盡量回傳結果而非直接print return damage
📖 加上註解 說明函式的用途 使用docstring

小練習2 - 🎮 任務:角色管理系統

設計一個完整的角色管理系統,包含以下函式:

# 1. 創建角色
def create_hero(name, job, hp=100, mp=50):
    """創建英雄角色"""
    # 請完成此函式
    pass

# 2. 升級角色
def level_up(hero_name, current_level):
    """角色升級"""
    # 請完成此函式
    pass

# 3. 顯示角色資訊
def show_status(name, level, hp, mp):
    """顯示角色狀態"""
    # 請完成此函式
    pass

💡 練習提示

  1. create_hero() 要回傳角色資訊(可用字典)
  2. level_up() 要計算新等級的HP和MP
  3. show_status() 要美化顯示角色資訊

測試程式:

hero = create_hero("亞瑟", "騎士")
show_status(hero["name"], hero["level"], hero["hp"], hero["mp"])
hero = level_up(hero["name"], hero["level"])

🧠 運算思維總整理

今天學到的運算思維

運算思維 在函式中的應用 實例
🧩 問題分解 將大功能拆成小函式 戰鬥系統 → 攻擊、防禦、治療
🎭 抽象化 函式封裝複雜邏輯 attack() 內部計算傷害
🔍 模式識別 找出重複的程式碼 相似的攻擊 → 統一函式
🔧 演算法設計 設計函式執行步驟 傷害計算流程

函式設計思考流程

1. 📋 確認功能需求
   ↓
2. 🧩 分解成小功能
   ↓
3. 📝 設計函式介面(名稱、參數、回傳值)
   ↓
4. 💻 實作函式內容
   ↓
5. 🧪 測試與除錯
   ↓
6. 📚 整理與優化

本週總結 🎉 你已經學會了:

✅ 函式的定義與呼叫語法 (def)
✅ 參數的使用(位置、關鍵字、預設值)
✅ 回傳值的應用 (return)
✅ 區域變數與全域變數的差異
✅ 設計實用的魔法函式
✅ 運用運算思維分解問題

你現在可以:

  • 🔧 建立可重複使用的程式模組
  • 🎯 設計清晰的函式介面
  • 🧩 將複雜功能分解成簡單函式

作業:打造你的魔法咒語庫 📚

選擇一個選項完成作業:

📝 選項一:基礎練習 (適合初學者)

設計一個「冒險者魔法系統」,包含以下函式:

  1. 專屬魔法my_magic(caster, target, magic_name)

    • 顯示施法者、目標和魔法名稱
    • 回傳魔法造成的傷害數值
  2. 角色管理create_hero(name, job, hp=100, mp=50)

    • 創建角色並回傳角色資訊(字典格式)
  3. 角色升級level_up(hero)

    • 提升角色等級,並增加HP和MP
  1. 顯示角色資訊show_status(hero)
    • 美化顯示角色的當前狀態

測試程式:

# 測試專屬魔法
damage = my_magic("勇者", "怪物", "聖光術")
print(f"造成的傷害:{damage}")

# 測試角色管理
hero = create_hero("亞瑟", "騎士")
show_status(hero)
hero = level_up(hero)
show_status(hero)

🔧 選項二:進階應用 (有點挑戰性)

設計一個「魔法戰鬥系統」:

  1. 多重魔法cast_spell(caster, target, spell_type, power, critical=False)
    • 支援至少3種魔法類型(火、冰、雷)
    • 有暴擊機制(傷害x2)
    • 回傳實際造成的傷害
  1. 連續施法chain_cast(caster, targets, spell_type, power)

    • 對多個目標施放同一魔法
    • 每個目標傷害遞減10%
    • 回傳總傷害
  2. 魔力管理check_mp(current_mp, spell_cost, max_mp=100)

    • 檢查MP是否足夠
    • 顯示剩餘MP百分比
    • 回傳是否可以施法(True/False)

🚀 選項三:創意發揮 (自由度高)

設計一個「完整的RPG角色系統」:

需求:

  • 至少5個函式,包含角色創建、戰鬥、升級、裝備系統等
  • 使用各種參數類型(位置、關鍵字、預設值)
  • 要有適當的回傳值
  • 函式之間要能互相配合運作
  • 加上清楚的註解說明

額外挑戰:

  • 設計一個函式接收任意數量的參數(*args
  • 設計一個函式接收任意關鍵字參數(**kwargs

感謝聆聽!

Happy Coding! 🐍✨

-----------------------------------------

圖片放大特效

table樣式

- [🧠 運算思維總整理](#🧠-運算思維總整理)

![bg](image-3.png)

![alt text](image-1.png)

![alt text](image.png)

```python def my_magic(caster, target, magic_name): """ 設計一個專屬魔法 參數: caster: 施法者名稱 target: 目標名稱 magic_name: 魔法名稱 """ damage = 100 print(f"⭐ {caster} 對 {target} 施放 {magic_name}!") print(f"✨ 造成 {damage} 點神聖傷害!") return damage # 測試魔法 my_magic("勇者", "怪物", "聖光術") ```

**範例參考:** ```python def my_magic(caster, target, magic_name): damage = 100 print(f"⭐ {caster} 對 {target} 施放 {magic_name}!") print(f"✨ 造成 {damage} 點神聖傷害!") return damage # 回傳傷害值 ```

#### 📝 **選項一:基礎練習** (適合初學者) 設計一個「冒險者工具包」,包含以下函式: 1. **背包檢查**:`check_inventory(item_name, quantity)` - 顯示物品名稱和數量 2. **使用物品**:`use_item(item_name, effect_value)` - 根據物品類型顯示效果(HP藥水、MP藥水等) 3. **購買物品**:`buy_item(item_name, price, money)` - 計算購買後剩餘金錢 - 如果金錢不足要顯示訊息

--- ### 📤 作業繳交說明 1. 將程式存檔為 `week09_functions.py` 2. 確保程式可以正常執行 3. 每個函式都要加上註解說明 4. 在程式最後加上測試區域,示範如何使用你的函式 **範例格式:** ```python # Week 09 作業:函式設計 # 姓名:你的名字 # 日期:2024/XX/XX # 函式定義區 def function1(): pass # 測試區 if __name__ == "__main__": print("=== 測試函式 ===") function1() ```

--- ![height:250px](../images/thank-you-6.gif) ### 下週預告 🔮 **Week 10: 函式設計(下) - 進階魔法修煉** - 遞迴函式的奧秘 - Lambda表達式 - 裝飾器入門 繼續精進你的程式魔法!✨