---
# System prepended metadata

title: 函數
tags: [計算機概論]

---

# 函數

## 使用函式的時機
- 當我們發現在我們的程式碼中，有許多相似的片段，便可以使用函式將程式進行簡化。具有以下優點：
    - Reuseable
    - Readable
    - Easy to debug


## 基本架構
```python
# 定義
def sayHi(input):
  """這邊寫關於函數的說明
  Args:
    input (int): 參數解釋
  Return:
    ans(int):返回類型說明
  """
  print("hello, how are you.")

# 呼叫
sayHi(input)
```


## 沒有參數的函數
```python
def greeting( ):
    """函數設計"""
    print("姊姊你會不會畫哈基咪呀")

greeting( ) # 姊姊你會不會畫哈基咪呀
```

## 包含參數（parameter）的函數
- 其中給引數的方式有兩種：
    -   positiotnal arguments: add(4, 5)
    -   keyword arguments: add(x=4, y=5)
```python
def add(x, y): # parameter
# def add(x, y=5): # default parameter
  return x+y

add(4, 5) # 9
```

## 沒有回傳->none
```python
def greeting(name):
    """Python函數需傳遞名字name"""
    print(name, "你難過一定要跟我說，讓我知道妳也有今天。")
    
return_value = greeting('前女友XXX') # 前女友XXX 你難過一定要跟我說，讓我知道妳也有今天。
print(return_value) # None
print(type(return_value)) # <class 'NoneType'>
```

## first-class objects
- 白話就是，函數可以把它視為一個物件
- 詳細內容: https://ithelp.ithome.com.tw/articles/10222472




## 給定任意參數（arbitrary number of arguments）

- 語法：`def f1(*args, **kwargs):`
-   \*args: 包成 tuple
-   \*\*kwargs: 包成字典

* 從max()去想如何做出任意參數的函數
```python
ans = max(1,2,3)
print(ans) # 3
```

- 按照之前所說的，參數他是一個一個去對應的，但..要怎麼知道我一次傳的參數有幾個?
- 所以，其實`max()`他內部大概是長這樣
```python
def aa(*args):
    return max(args) # 在tuple裡面找max


print(aa(1,2,3))
```
- 以下為一些相關用法
```python
# 示範*args:
def sum(*args):
  ans = 0
  for i in range(len(args)): ans += args[i]
  return ans

sum(1,2,3,4,5) # 15
```

```python
# 示範*args:
def f(**kwargs):
  print(f"{kwargs['name']} is now {kwargs['age']} years old.")

f(name="TA", age=23, address="tainan") # TA is now 23 years old.
```

```python
# 合併使用
def f1(*args, **kwargs):
  print("I would like to eat {} {}".format(args[2], kwargs['food']))

f1(14, 17, 23, food="eggs") # I would like to eat 23 eggs
```

## 匿名函數（lambda）
- 匿名函式不需要定義名稱，一般函式需定義名稱。
- 匿名函式只能有一行運算式，一般函式可以有多行運算式。
- 匿名函式執行完成後自動回傳結果，一般函式加上 return 關鍵字才能回傳結果。

```python
ans = (lambda x: x**2)(5)
print(ans) # 25
```

```python
ans = (lambda x, y: (x+y, x-y))(15, 30)
print(ans) # (45, -15)
```

```python
# 一般寫法
def x(n):
    a = list(range(n))
    return a

# lambda
y = lambda n: [i for i in range(n)]   # 計算後回傳串列結果
print(x(5))    # [0, 1, 2, 3, 4]
print(y(5))    # [0, 1, 2, 3, 4]
```

```python
# 搭配 if 判斷式
def y(n):
    if n<10: return True
    else:return False
    
x = lambda n: True if n<10 else False   # 判斷是否小於 10，回傳 True 或 False
print(x(5))   # True
print(y(5))   # True
```

- 在list章節中，有提到關於list相關函數(map, filter)
```python
# 搭配 map 方法
a = [1,2,3,4,5,6,7,8,9]
b = map(lambda x: x*x, a)
print(list(b)) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
```

```python
# 搭配 filter 方法
a = [1,2,3,4,5,6,7,8,9]
b = filter(lambda x: x>5, a)
print(list(b)) # [6, 7, 8, 9]
```

```python
# 搭配 sorted 方法 
a = [[1,2],[4,3],[5,1],[9,2],[3,7]]
b = sorted(a, key = lambda x: x[1])
print(list(b)) # [[5, 1], [1, 2], [9, 2], [4, 3], [3, 7]]
```





## Lab06作業題目
- 繳交方式 : 到 [https://140.116.179.59:8080](https://140.116.179.59:8080) 完成作業題目並上傳 Github
- 作業開放時間：到隔週周一中午12點前，照系統出題時間而定，請同學盡量在當周周日24:00前完成
- 題目為基本題4題
    - Lab06_01~04(各25分)(不符規定九折，未註解七折，遲交六折)
    - ~~Lab06_plus加分題直接列入期末成績計算~~
- github檔名格式：
    - 每一個檔案為：Lab06_OO.py
    - ~~加分題檔案為：Lab06_plus.py~~
    - 所有檔案放入資料夾學號_Lab06在將資料夾上傳




