# Chapter 3 Python函數與條件

## 3.1 函數基本寫法

def 函數名稱(input1,input2=value,*input3,**input4):

/* 程序每行「內縮2格」 */

return ...

input1：無預設值的input

input2：有預設值的input

*input3：將「無」keyword的arguments合成tuple物件input3。

**input4：將「有」keyword的arguments合成dictionary物件input4。

### 3.1.1 預設值

def test(input1, input2=0):
print('input1 is ', input1)
print('input2 is ', input2)
return None

test(1,1)
test(input1=1,input2=1)

test(1) # 動用到預設值

### 3.1.2 pack to tuple

def test2(input1,*input3):
print('input1 is ', input1)
print('input3 is ', input3)
return None

test2(1,1.2,4,5)
test2(1,[1.2,4],5)
test2(["1","b"],{2,5,7},10)
def test2(input1,**input4):
print('input1 is ', input1)
print('input4 is ', input4)
return None

test3(1,a=10,b={2,3})

Any variables specified after a packed variable must be called by name:

def f(x, *seq, y):
print("x is: ", x)
print("seq is: ", seq)
print("y is: ", y)
return None

f(1, 2, 3, 4, 5)
f(1, 2, 3, 4, y=5)

### 3.1.3 unpacking usage

f(1,2,3)是在call f這個函數, 當進行function calling時，*可以用在input arguments, 它代表unpacking。（注意，在define function時*代表packing。

def f(a,b,c):
return a+b+c

f(1,3,4)
f(*[1,3],4)
f(1,*[3,4])
f(*[1,3,4])

#### 範例: normal pdf

$\frac{1}{\sqrt{2\pi\sigma^2}}*exp(-\frac{(z-\mu)^2}{2\sigma^2})$

from math import *

def normal_pdf(z,mu,sigma):
return 1/(sqrt(2*pi*sigma**2))*exp(-(z-mu)**2/(2*sigma**2))

normal_pdf(0.8,0,1)

#### 範例: Cobb-Douglass

$u(x,y|\alpha,\beta)=x^{\alpha}y^{\beta}$

def utility_cobb_douglass(x,y,alpha=1,beta=3):

utilValue = x**alpha*y**beta # 程序產生output值

return utilValue # 傳回output值

utility_cobb_douglass(1,1,0.5,0.5)
utility_cobb_douglass(1,1)

#### 3.1.3.1 範例: 負值index

listA=[1,-2,3,-4,10,"-4"]
[i for i in range(len(listA)) if type(listA[i]) in {int, float} and listA[i]<0]

def negValue_index(listInput):
"""回傳list中負值的位置"""
return [i for i in range(len(listInput)) if
type(listInput[i]) in {int, float} and  listInput[i]<0]

import pandas as pd

dict_finStatement=finStatement.to_dict()
profit=list(dict_finStatement.get('營業利益（損失）').values())
[dict_finStatement.get('公司名稱').get(index) for index in negValue_index(profit)]

## 3.2 條件

### 3.2.1 Block statement

if condition1:
body1
elif condition2:
body2
elif condition3:
body3
.
.
.
elif condition(n-1):
body(n-1)
else:
body(n)

body部份要內縮(indentation):

• One or more whitespace characters (spaces or tabs) is sufficient to serve as indentation.
• A given indented block must use a uniform level of indentation. E.g. if the first line of an indented block has two leading spaces, all subsequent lines in that block must lead with exactly two white spaces.

#### 範例

Function with specified domain. $f(x)=1/x\ with x\neq0$

from math import *
def f(x):
if x!=0:
return 1/x
else:
return nan # 使用math模組的nan

f(1); f(-2); f(0)

#### 範例

$f(x)=1/x$
1. Domain $$D_1=(1,2)$$.
2. Domain $$D_2 =[1,2]$$.

()不包含界限；[]包含

def f1(x):
if x>1 and x<2:
return 1/x
else:
return nan
f1(1); f1(1.5); f1(3)

#### 範例

$\begin{array}{lcl} f1(x) &=& \begin{cases} +x^2 &\quad x≥0,\\ -x^2 &\quad -1<x<0 \end{cases} \\ f2(x) &=& \begin{cases} x^3 &\quad x<0,\\ 3x-2 &\quad 2>x\geq0 \end{cases} \end{array}$
def f1(x):
if x >= 0:
return x**2
elif x>-1 and x<0:
return -x**2
else:
return nan

f1(1); f1(-0.5); f1(-3)

### 3.2.2 inline statement

A if <condition> else B

x=3
y=5 if x>3 else 7

def f1(x):
if x>1 and x<2:
return 1/x
else:
return nan

def f2(x):
return 1/x if x!=0 else nan

## 3.3 local and global

c='one'
def funDemo():
print(c)

def funDemo():
localC="two"
print(localC)

funDemo() # localC沒有return所以只在函數執行暫時environment存在，函數執行完就消失了。

localC

function被call時會開啟一個環境，叫executive environment，在裡面執行函數程序，中間如果有創造出任何物件（如localC）會存活在executive environment，然而函數程序完成後整個executive environment會刪除，裡面的物件除非有return，否則值（這裡的"two"）就消失了。

function input（比如叫x）若是直接來自global variable（比如叫global1），它相當於是在做x=global1的定義式複製。如果global1是mutable，要小心函數裡對x值的更改會動到global1

global1=[1,3,[4,5]]
def funtest(x):
x[0]="a"
y=x[:]
y[1]="b"
y[2][1]="c"
return None

global1
funtest(global1)
global1
global1=[1,3,[4,5]]
funtest(global1.copy())
global1

import copy
global1=[1,3,[4,5]]
funtest(copy.deepcopy(global1))
global1

## 3.4 視函數為元素

funDemo
funDemo2=funDemo

funDemo2()

PythonFun={
"funDemo": funDemo,
}

PythonFun["funDemo2"]=funDemo2 # 額外加一個不存在的元素

PythonFun.get("funDemo")(); # 或
PythonFun["funDemo"]()

PythonFun.get("funDemo2")(); # 或
PythonFun["funDemo2"]()

## 3.5 Anonymous函數

lambda input_arguments : expression
(lambda x, y: x + y)(2, 3)

def fun(x, y):
return x+y

fun(2,3)

fun=lambda x, y: x+y

fun(2,3)