define function 的用法


函數是程式中完成一定功能的一段獨立程式碼,可供程式中的其他程式呼叫。該段獨立程式需要有一個名稱以供呼叫,也可接受呼叫者傳遞的參數,使處理更加靈活。函數執行後可以有傳回值,返還呼叫者。通俗的說,函數是一種程式元件事組成大程式的小程式。<
為什麼要使用函數?
(1)一次定義,多次使用,實現軟體重用
使用函數可以避免重複程式出現,使程式更精解。
(2)功能切割、模組化、結構化
使用函數不僅可以使程式的結構清晰,更易於閱讀和維護,也便於多人合作,共同開發程式,並可實現自頂向下,分而治之,逐步求精的結構化程式設計。
(3)身為程式元件,完成特殊的功能
函數也是實現的遞迴演算法必不可少的工具。

1. 絕對值: visual 模組中abs可用於整數,浮點數,複數,向量之絕對值。

在下面這一個樣本程式當中我們定義了求兩數最大值的函數。


from visual import *	#在這邊我們輸入了vpython的visual模組,方便我們對向量取絕對值
def max_length(a,b):   # def開頭來定義函數,a,b是輸入的變數值
    if abs(a > abs(b):
        return a	# 用return傳回計算的絕對值較大者,回到呼叫程式呼叫的地方。
    elif abs(b) > abs(a):
        return b 	# 用return傳回計算的絕對值較大者,回到呼叫程式呼叫的地方。
    else:
        return 'equal'  # 用return傳回字串'equal',回到呼叫程式呼叫的地方。
a, b = 5, -8	# 這是元組(tuple)的用法
print a,b,max_length(a,b)  #return傳回計絕對值較大者在這邊呈現
c = vector(3,4,5)	# c,d是透過vpython visual模組定義的兩個向量
d = vector(2,8,7)
print c,d,max_length(c,d)  # return傳回計算向量之絕絕對值較大者在這邊呈現
e = 5+3j	# e,f是兩個複數
f = 3+5j
print e,f,max_length(e,f) # return傳回計算複數之絕絕對值較大者在這邊呈現



2. 計算兩整數的公因數。

下面的程式定義了一個計算最大公因數的函數。
def computeHCF(x,y):
    if x > y:
	 smaller = y
    else:
	 smaller = x
    for i in range(1, smaller+1):
	if((x % i == 0) and (y % i == 0)):
	    hcf = i
    return hcf
num1 = 54
num2 = 24
print("The H.C.F. of", num1, "and", num2, "is", computeHCF(num1, num2))



3. 直角三角形圖案

下面這個程式中我們透過一個函數輸出直角三角形圖案,在主程式呼叫該函數時,透過將變數c中的數值傳遞給函數參數a,並列出三角形的行數。這個程式沒有回傳(return)。
def rt(a):
    for n in range(1,a+1):
        print('*'*n)
while True:
    b=input("input the number of lines for the triangle=")
    if(b == 0): print 'none';   break
    c=int(b)
    rt(c)



4. \(C_n^m=\frac{m!}{n!(m-n)!}\)

下面這個程式中我們透過定義n!的函數來計算\(C_n^m=\frac{m!}{n!(m-n)!}\)。
def fact(n): 	# n是由主程式傳入之參數
    m=1
    for n in range(1,n+1):
        m=m*n
    return m  # 回傳m至主程式的呼叫點
m,n=10,3
Cmn=fact(m)/(fact(n)*fact(m-n))
print m,n,Cmn



5. 從外部檔案讀取運動的數據,再用vpython的物件呈現出軌跡。

這個程式沒有回傳(return)。外部軌跡檔案:
projectile-tr.txt

spiral-tr.txt
mag-bottle-tr.txt

from visual import *
scene = display(width=800, height=800, center=(0,0,0),background=(0.5,0.5,0))

def traject(tr):
    ball = sphere(radius = 0.1, color=(1,0,0),make_trail=True,trail_type="points", 
		interval=1, retain=200)
    arrX=arrow(pos=(0,0,0),axis=(5,0,0),shaftwidth=0.04,color=(1,0,0))
    arrY=arrow(pos=(0,0,0),axis=(0,5,0),shaftwidth=0.04,color=(0,1,0))
    arrZ=arrow(pos=(0,0,-5),axis=(0,0,10),shaftwidth=0.04,color=(0,0,1))
    f=open(tr,'r')
    a=f.read()
    print a
    b=a.split()
    Nb=len(b)
    N=Nb/4
    t=[float(b[i*4+0]) for i in range(N)]
    x=[float(b[i*4+1]) for i in range(N)]
    y=[float(b[i*4+2]) for i in range(N)]
    z=[float(b[i*4+3]) for i in range(N)]
    ball.pos=vector(x[0],y[0],z[0])
    print ball.pos
    for i in range(N):
        rate(10)
        ball.pos=vector(x[i],y[i],z[i])    
        print t[i],x[i],y[i],z[i]

traject('spiral-tr.txt')
#traject('mag-bottle-tr.txt')
#traject('projectile-tr.txt')



6. 自行建立模組與簡易應用。

首先編寫了一個儲存許多物理常數的python程式(constants.py)。
在 Python 中,模組是幾個重要抽象層的機制之一,也許是最自然的機制之一,只要你建立了一個原始碼檔案 modu.py,你就建立了一個模組 modu,原始碼主檔名就是模組名稱。 import modu 陳述句會在相同目錄下尋找 modu.py,如果沒找到,則會試著尋找在 sys.path 中遞迴地尋找 modu.py,如果還是沒有,則會引發 ImportError 例外。
模組提供了名稱空間。模組中的變數、函式與類別,基本上需透過模組的名稱空間來取得。在 Python 中,import, import as 與 from import 是陳述句,可以出現在程式中陳述句可出現的任何位置,它們基本上用來在現有範疇(Scope)中匯入、設定名稱空間,舉例來說,如果先前程式範例是撰寫於 constants.py 檔案中,那麼以下是一些 import、import as 與 from import 的使用實例,假設這些程式是撰寫在與 constants.py 相同目錄的另一個 main.py 檔案:
main.py(主程式)的內容如下:

import constants as C   # 載入constants模組並以C命名 
print C.ke,C.G,C.e,C.me,C.a0	# C.xxx即為模組中的xxx變數,C.ke=庫倫常數,C.G=重力宇宙常數
fe=C.ke*C.e*C.e/C.a0**2		# 兩個電子相距一個波耳半徑的靜電排斥力
fg=C.G*C.me*C.me/C.a0**2	# 兩個電子相距一個波耳半徑的重力吸引力
print fe,fg,fe/fg

g=C.G*C.ME/C.RE**2	# 地球的重力加速度的公式
print 'g=',g

f1=C.FE(C.e,C.e,C.a0) 	#呼叫模組中的函數(靜電力)
f2=C.FG(C.me,C.me,C.a0)	#呼叫模組中的函數(重力)
print f1,f2,f1/f2



模組程式constants.py如下:
def FE(q1,q2,r):
    ke=8.99E9
    f=ke*q1*q2/r**2
    return f

def FG(m1,m2,r):
    G=6.67E-11
    f=G*m1*m2/r**2
    return f

C=3.0E8  	#光速
pi=3.1416	
G=6.67E-11	#重力宇宙常數
ke=8.99E9	#庫倫常數
e=1.6E-16	#電子的帶電量
h=6.26E-34	#普郎克常數
hbar=1.05E-34
mu=4*pi*10.E-7
epsilon=8.85E-12
a0=5.29E-11	#波耳半徑
me=9.1E-31 	#電子的質量
mp=1.67E-27	#質子的質量
Ry=1.1E7
NA=6.02E23	#亞佛加厥數
kB=1.38E-23	#波茲曼常數
muB=9.27E-24	#波耳磁元
ME=6E24		#地球的質量
RE=6.38E6	#地球的半徑



如果你希望模組內的變數名稱直接匯入主程式,不需再用math.pi or C.pi之類的變數名稱,那你可以參考下面的語法,並且與上面的程式比較。
from constants import *
print ke,G,e,me,a0
fe=ke*e*e/a0**2
fg=G*me*me/a0**2
print fe,fg,fe/fg

g=G*ME/RE**2
print 'g=',g

f1=FE(e,e,a0)
f2=FG(me,me,a0)
print f1,f2,f1/f2



但是上面的用法有些危險例如下例:
from constants import *  #匯入自訂的模組
print e,me  #此處的e是電子的帶電量
from math import *  #匯入python的內建math模組
print sin(pi/3.)
print e  #此處的e是自然指數



7. 一元二次方程式的根

這個程式回傳元組(x1,x2)。

import math
def root2(a,b,c):
    i=0.+1.j  # sqrt(-1)
    D=b**2-4.*a*c
    if(D == 0.):
        x1,x2=-b/2./a, -b/2./a
    elif D > 0.:
        x1=(-b+math.sqrt(D))/2./a
        x2=(-b-math.sqrt(D))/2./a
    else:
        x1=(-b+i*math.sqrt(-D))/2./a
        x2=(-b-i*math.sqrt(-D))/2./a
    return (x1,x2)  #回傳元組

(x1,x2)=root2(1.,-2.,5.)   #以元組方式傳回
print (x1,x2)		   #列印元組