2016年5月31日 星期二

Python_Note06

Function


函數 (function) 是一種功能性的程式碼集合,可以將程式 (program) 分割成小部分,藉由呼叫 (call) 函數安排執行順序

呼叫函數的基本方法




Built-in Function

查詢內建函數 (built-in function) : dir(__builtins__)

https://docs.python.org/3.3/library/functions.html

查詢函數用法 : 
In[76]: help(abs)
Help on built-in function abs in module builtins:

abs(x, /)
    Return the absolute value of the argument.


自訂函數


定義函數使用關鍵字 (keyword) def ,其後空一格接函數名稱與小括弧,小括弧用來放參數列 (parameter list) ,函數可以有參數 (parameter) 也可以沒有參數,沒有參數的函數的小括弧留空,另外函數可用 return 設定回傳值 (return value) ,沒有回傳值的函數也就不需要 return 。


函數的命名
  1. 函數之命名慣例:
  • GUI函數習慣以駝峰式(Camel-Case)命名 Ex: GetStudentName()
  • 一般函數習慣以小寫或輔以底線命名   Ex: sum_grades()
  • 避免非慣用縮寫
  • 函數之命名應有意義,且須指出函數之目的或回傳之資料,而非達成目的所使用的方法

Parameter and Argument


參數Parameter
引數Argument
•函數運行時之參考
•放在函數的標記式,用來說明這個函數,當它被呼叫時必須接收到什麼樣的資料
•用以引發函數
•當呼叫函數的時候,可以放在括號內的東西


傳遞引數給參數

以引數呼叫函數而將其值賦予參數以供函數(副程式)運行參考
依序一個對一個(只是一個丟接遊戲!), 這種依參數順序給定的引數
稱為positional argument
傳遞的動作可以想像成若干個賦值運算
即:
Pra1 = Arg1
Pra2 = Arg2
…
PraN = ArgN

函數參數傳入的型態有四種

  1. F(arg1, arg2, ...)
    最常見的格式。
  2. F(arg1, arg2=value2, ...)
    在宣告函式的時候,可以先給預設值。
  3. F(*arg1)
    不限參數數量,參數將保存為一個tuple。
  4. F(**arg1)
    不限參數數量,參數將保存為一個dictionary。
函數解析參數的過程,依序由 1> 2> 3> 4 這個順序來解析。

函數的回傳值

一 個函數於運行完畢之後可以回傳結果(也可以忽略不回傳)。當程式運行到 return陳述句時將會無條件直接離開(結束)函數並回傳結果。


回傳值可以為:
  • 單一的值或 物件
  • 多個值或物件所構成的 tuple
  • 當未使用 return陳述句時,預設將會回傳None

參數預設值可減少function call撰寫上的麻煩

即便呼叫函數時沒有給定引數,函數依然有參考值(預設參數值)。

且自定義函數的參數規則:

  • 無預設值之參數在前
  • 有預設值之參數在後

因為引數之傳遞是依序的

  • 當有預設值之參數仍有引數之分配時,引數值將會取代預設值


範例1:
# (for 迴圈版本)
n = int(input('Please input n:'))

total = 0
for i in range(1,n+1):    
    total += i   # total += i  等價於 total = total + i

print('Total is:',total)

範例2:
# (函數版本)
def sumation(n):
    total = 0
    for i in range(1,n+1):        
        total += i   # total += i  等價於 total = total + i
    print('Total is:',total)

n = int(input('Please input n:'))
sumation(n)

利用參數名稱之函數呼叫
呼叫函數時不使用參引數依序一對一對應傳遞,而是換成以參數名稱來進行傳遞與函式之呼叫(名稱呼叫)。這種依名稱傳遞的引數稱為 keyword argument。




—函數 (function) 可以有不定個數的參數 (parameter),也就是可以在參數列 (paramenter list) 提供任意長度的參數個數



— *arguments 就是參數識別字 (identifier) 前面加上一個星號,當成一組序對 (tuple)。
— **keywords 參數識別字前面加上兩個星號,當成一組字典(dictionary)。

Yield產生器
函數 (function) 中若使用 return ,函數會直接回傳數值 (value) ,也隨之終止函數執行。若使用另一個關鍵字 (keyword) yield,可使函數產生數值,而不會結束函數執 行,這樣的函數被稱為產生器函數(generator function)

範例:
#  使用 yield 模擬 range() # 
def myrange(n):
    x = 0
    while True:
        yield x
        x += 1
        if x == n:
            break            


print(list(myrange(10)))

變數的有效範圍

每個變數有其有效範圍, 也就是被認定(認識)的範圍

Globe
一般定義在函數外的變數其範圍是一整個模組, 又稱全域變數(全域指的是整個模組)

有的時候在函數中我們希望改變或存取的是全域變數時,為了確認使用到正確的全域變數,而非定義一個新的區域變數時,我們需要利用 global敘述句來告知 python 某變數名稱指稱的是全域變數

範例:
#name 變數宣告在最外層,為全域變數
name = "Tony"
def change_name(n):
    global name   
    name = n
    print('In change_name function, name=%s' % name)

print('Before change_name function called, name=%s' % name)
change_name('John')

print('After change_name function called, name=%s' % name)

Local
被定義在一個函數中的變數稱為區域變數, 其範圍是一整個函數

以上兩種範圍都必須從變數定義被python看到開始算起
當區域變數與全域變數名稱相同產生衝突時,區域內以區域變數為主,區域外以全域變數為主


Python_Note04

Control Flow Tools

  • if是最單純的一種條件分支敘述句
  • if 後面接 condition,最後需要加上冒號:
  • 冒號:之後的下一行程式碼記得要縮排
  • 當條件(condition)成立時(True), 執行冒號後面的suite程式碼, 若條件不成立 (False), 略過整個suite開始執行 suite之後一行程 式碼
  • 用 condition來選擇suite程式碼做或不做
  • if語句可以有多個條件(condition),可以用and、or、及 ( ) 來串接。Ex : if Condition_A and Condition_B : [即為條件A與B必須同時成立]



if-elif-else

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...     x = 0
...     print('Negative changed to zero')
... elif x == 0:
...     print('Zero')
... elif x == 1:
...     print('Single')
... else:
...     print('More')


for Statement

for迴圈是另外一個可以重複進行運算的結構

Iterable object:是指可迭代物件, 可以想像成這種物件裡面有可數的項目可依特定順序一個一個取出
Var:稱控制變數又或迴圈變數



for迴圈的執行流程

  1. 自可迭代物件中取出一個項目, 代入至Var中 (迭代物件 ex: 從list = [1,3,5,10,14],依序取)
  2. 執行suite
  3. 回到第一步直到可迭代物件中的項目盡皆取出

這種依次取出(探訪)並且進行代入的動作稱為迭代,當然, break 和 continue 也可以在 for 迴圈中出現。


range() Function

for迴圈中需要用來做迭代的物件可以使用內建函數range(),

range(start,end,step),預設start為0,step為1
使用時須改成要用的型態
ex: >>> range(10)
range(0,10)
ex: >>> list (range(0,10,2))
[0,2,4,6,8,10]

while Statement

  • 當expression條件成立(True)時, 進行區塊(suite)運算
  • 區塊執行完畢後, 再次檢查條件, 若依然成立則執行suite否則開始執行區塊之後的敘述
  • 這種重複的結構我們稱為迴圈
  • 不再繼續執行區塊的動作稱為跳出迴圈或離開迴圈






else Statement

重複結構while和for都支援額外的else敘述



當while迴圈或for迴圈不是因為break, return或例外終止時(指迴圈正常中止), else_suite會被執行

for / while 的使用時機
  • 當需要重複進行運算的時候使用迴圈(for/while)
  • 當重複的次數可以清楚被計算或當迭代的表現明顯時使用 for迴圈
  • 當重複的次數難以計算(但條件清楚)或是有條件的重複時使用 while

break and continue Statements

對於迴圈想要擁有更高的控制性

  • 利用break在任何時候跳出迴圈
  • 利用continue在任何時候略過迴圈(略過本次迴圈剩餘的運算) , 而這些時機點通常搭配選擇結構來進行




巢狀結構
  • 不論是if/elif/else結構,while迴圈或for迴圈都支援巢狀(層疊式)的撰寫, 各層之間的縮排務必清楚, 冒號也要記得加上
  • 雙重迴圈(多重迴圈)是程式中重要的結構, 是處理多層(多軌)迭代或是運算的必要手段
  • 多重迴圈的運行次序可回到基本定義上想


範例:
'''
分別用for,while迴圈各寫1個n x n的乘法表
程式可以讀取使用者輸入的值 n, n>1
'''
num = int(input('input a number : '))

for i in range(1,num+1,1):
    for j in range(1,num+1,1):
        print('%d * %d = %d' %(i,j,i*j))

i = 1
j = 1
while i <= num:
    while j <=num:
        print('%d * %d = %d' % (i, j, i * j))
        j += 1
    i += 1

    j = 1




Python_Note02

語法特色


  • 以冒號(:)做為敘述的開始
  • 不必使用分號(;)做為結尾
  • 井字號(#)做為註解符號,同行#字號後的任何字將被忽略
  • 使用tab鍵做為縮排區塊的依據
  • 不必指定變數型態 (runtime時才會進行binding)


Python Token

直譯器利用標記 (token) 解析程式的功能, Python 中的標記有關鍵字 (keyword) 、識別字 (identifier) 、字面常數 (literal) 、運算子 (operator) 等四類—

Python Key Words

關鍵字為具有語法功能的保留字 (reserved word) 
False      class      finally    is         return
None       continue   for        lambda     try
True       def        from       nonlocal   while
and        del        global     not        with
as         elif       if         or         yield
assert     else       import     pass
break      except     in         raise

Python Identifier

識別字 (identifier) 為寫程式時依需求自行定義的名稱,包括變數 (variable) 、函數 (function) 、類別 (class) 等,皆為使用自行定義的識別字。除了關鍵字之外, Python 可用任何 Unicode 編碼的字元當作識別字。

習慣上識別字的命名仍是以英文字母大寫 A-Z (\u0041-\u005a),小寫 a-z (\u0061-\u007a) ,底線符號 (_, \u005f) 與數字 0-9 (\u0030-\u0039) 為主。

Python Literal

字面常數的意思就是字面上的意義,也就是說, 1234 就代表整數數值一千兩百三十四的意
義,因此,所謂的字面常數就是直接寫進 Python 程式原始碼的數值,依資料型態分類有

  • 字串字面常數 (string literal)
  • 字節字面常數 (bytes literal)
  • 整數字面常數 (integer literal)
  • 浮點數字面常數 (floating-point literal)
  • 複數字面常數 (imaginary literal)


Python Operator

一般運算子的用法如同平常數學使用方式,在不同序列型態 (sequence types)則會有一些特別用法,但觀念都是一樣的。
+
-
*
**
/
//
%
<< 
>> 
&
|
^
~
< 
> 
<=
>=
==
!=
分隔符號
()[]{}
,:.;@=
+=-=*=/=//=%=
&=|=^=<<=>>=**=



Python Standard Library

Python包含了大量的模組提供使用
  • String processing
  • Operating system interfaces
  • Networking
  • Threads
  • GUI
  • Database
  • Language services
  • Security
範例:
>>> import math
>>> math.log(math.e) 
1.0


Python_Note09

Exception Handling

大部分執行中的錯誤, Python 直譯器 (interpreter) 會以發起例外 (exception) 的方式來中斷程式的執行。實際上,很多情況下我們需要自行控制可能會產生例外的程式碼,因為例外並不全然是程式的邏輯錯誤,例如程式中打算開啟檔案,然而實際檔名並不存在,這種情況下,我們需要的是例外發生後的處理動作,而非中止程式的執行。

凡是可能會產生例外的程式碼, Python 利用 try-except 陳述 (try-except statement) 讓程式設計師自行處理例外。 try-except 為關鍵字 (keyword) 之一,專門用來例外處理 (exception handling) 的。

try-except表示式:
expect NameError:
expect IndexError:
expect 特定例外:

在try suite中的程式碼會被Python嘗試執行,一旦產生例外,會交由except suite 中的程式碼來處理。

In[8]: try:
...     a = 0            
...     b.split()       #發生例外
...     b = 0            #運算不會被執行
... except:           
...     c = 0            #跳過例外至except 區塊
...    
In[9]: a
Out[8]: 0
In[10]: b
Traceback (most recent call last):
  File "C:\Users\cash.chien\AppData\Local\Continuum\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3066, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-9-3b5d5c371295>", line 1, in <module>
    b
NameError: name 'b' is not defined
In[11]: c
Out[10]: 0

try ... except 還支援 else 和 finally 敘述句以提供更有彈性的控制

若try區塊中並未引發任何例外,則else會在try 區塊執行完後被執行,反之則不執行

finally 區塊不論例外發生與否,捕捉與否,總是會在最後被執行

raise

使用raise敘述句可引發例外
引發例外時所帶有的參數(args)會在例外被印出時同時被輸出

範例:
try:
    raise NameError
except NameError:
    print("something wrong")

print("after exception....")

Out:
something wrong
after exception....

自定義例外

  • 在python中一切皆物件, 例外也不例外
  • 每個發生的例外都是物件, 而同一類型的例外屬於同一個類別
  • 自定義例外的方法其實就是定義一個新的例外類別
  • 簡單的例外定義可以藉由下述的類別定義



範例:
#-*-coding:UTF-8 -*-
#  自訂例外範例
#  錢包總金額為1000元,如果購買商品總金額超過1000
#  將會引發一個金額不足的例外 

shoppingcart = {'fruits':400,'shoes':700 }

class insufficientError(Exception): pass

def buy(items):
    cash = 1000
    total = 0
    try:
        for price in items.values():
            total += price
        if total > cash:
            raise insufficientError
    except insufficientError:
        print('INSUFFICIENT FUND')

buy(shoppingcart)

Out:
INSUFFICIENT FUND







2016年5月30日 星期一

Python_When should i use str() and when should i use repr() ?

http://stackoverflow.com/questions/19331404/str-vs-repr-functions-in-python-2-7-5

When should i use str() and when should i use repr() ?
Almost always use str when creating output for end users.
repr is mainly useful for debugging and exploring. For example, if you suspect a string has non printing characters in it, or a float has a small rounding error, repr will show you; str may not.
repr can also be useful for for generating literals to paste into your source code. It can also be used for persistence (with ast.literal_eval or eval), but this is rarely a good idea--if you want editable persisted values, something like JSON or YAML is much better, and if you don't plan to edit them, use pickle.
2.In which cases i can use either of them ?
Well, you can use them almost anywhere. You shouldn't generally use them except as described above.
3.What can str() do which repr() can't ?
Give you output fit for end-user consumption--not always (e.g., str(['spam', 'eggs']) isn't likely to be anything you want to put in a GUI), but more often than repr.
4.What can repr() do which str() can't
Give you output that's useful for debugging--again, not always (the default for instances of user-created classes is rarely helpful), but whenever possible.
And sometimes give you output that's a valid Python literal or other expression--but you rarely want to rely on that except for interactive exploration.

Python_cmp() between 3.x vs 2.x

Python 3沒有cmp()這個函數了,如果想要比較的話,可以採用
(a > b) - (a < b),相當於cmp(a,b)

Ordering Comparisons

Python 3.0 has simplified the rules for ordering comparisons:
  • The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering. Thus, expressions like 1 < '', 0 > None or len <= len are no longer valid, and e.g. None < None raises TypeError instead of returning False. A corollary is that sorting a heterogeneous list no longer makes sense – all the elements must be comparable to each other. Note that this does not apply to the == and != operators: objects of different incomparable types always compare unequal to each other.
  • builtin.sorted() and list.sort() no longer accept the cmp argument providing a comparison function. Use the key argument instead. N.B. the key and reverse arguments are now “keyword-only”.
  • The cmp() function should be treated as gone, and the __cmp__() special method is no longer supported. Use __lt__() for sorting, __eq__()with __hash__(), and other rich comparisons as needed. (If you really need the cmp() functionality, you could use the expression (a > b) -(a < b) as the equivalent for cmp(a, b).)

Python_Built-in Function

https://docs.python.org/3.3/library/functions.html

In[76]: help(abs)
Help on built-in function abs in module builtins:

abs(x, /)
    Return the absolute value of the argument.