Berkeley's SICP in python3(三)

這段時間讀到了第二章,這一章感覺比第一章要難一點,講的也更抽象。
對於英文不好的我來說,只能選擇我覺得重要的點記錄一下,並實現裏面的全部程序。

1. 介紹

第一章中瞭解了計算過程和函數在編程設計中的作用。知道了怎麼用原始數據和原始操作符,怎樣組成複合函數,創建函數的抽象,瞭解了高階函數,這些是編程的本質。
本章重點是數據。

1.1. 對象的比喻

分清函數和數據:函數對數據進行操作。當將函數作爲數據是,承認數據也有行爲。函數能像數據那樣被操作,也叫做執行操縱。對象(object)包含了信息和過程,具有屬性,交互和複雜行爲。
a data is a kind of simple object.
from datetime import data
data是一種類。具體的日期是類的一個實例。可以通過調研調用類的構造函數來實例化一個類。
today = date(2011, 9 ,12)
當被實例化後,today就成爲了數據。

對象有屬性,是對象的一部分。python用.號指定對象的一個屬性。

experssion.name

today.year #2011
對象也有方法,方法根據參數和對象計算其結果。
today.strftime('%A, %B %d') #'Monday, September 12'
儘管還沒有清晰描述對象是如何工作的,但是是時候將數據作爲對象考慮了,python中一切都是對象。

1.2. 原始數據類型

任何對象在python都有類型。

>>> type(today)
<classdatetime.date’>

聲音,圖形等都是數據,都能被抽象表示,都能被python基本的數據類型表示。
基本數據(native or primitive data)有如下兩個屬性:
1. 有基本表達式來對這些基本對象進行計算,稱爲字面值。
2. 有內置函數,操作符和操作這些對象的方法。

python有三種基本數據類型。int 和float 和complex。

2. 數據抽象

數據抽象是一種方法論,使我們不必考慮複合數據對象構造的細節,從而使用它。
數據抽象的基本思想是構造函數以便於對操作對抽象數據進行處理。我們的程序應該用這樣的抽象數據而儘量少用假設的數據。
構造器和選擇器:實現抽象數據方面的具體表現。
記住計算機科學不僅僅是學會如何使用一門語言,而應該深入瞭解它是如何工作的。

2.1. 有理數的四則運算

在實現程序的部分功能之後,我們就可可以用函數抽象開始高效率編程了。
假設我們已經實現了方法:給一個有理數,可以得到分子和分母。這樣就可以得到如下的構造器和選擇器。

• make_rat(n, d) returns the rational number with numerator n and denominator d.
• numer(x) returns the numerator of the rational number x.
• denom(x) returns the denominator of the rational number x.

這裏我們用到一種強有力的策略:wishful thinking。儘管還沒有對這三個函數進行實現。假設如果我們有了這三個函數,就可以調用它們對有理數進行加,乘,判斷相等操作。

>>> def add_rat(x, y):
        nx, dx = numer(x), denom(x)
        ny, dy = numer(y), denom(y)
        return make_rat(nx * dy + ny * dx, dx * dy)
>>> def mul_rat(x, y):
        return make_rat(numer(x) * numer(y), denom(x) * denom(y))
>>> def eq_rat(x, y):
        return numer(x) * denom(y) == numer(y) * denom(x)

現在已經有了構造器(make_rat)和選擇器(numer和demon),但是還沒有實現它們。我們需要一種方法將分子和分聚合在一個單元。

元組(tuples)

基本操作:

元組的元素可以通過兩種方式獲得:

>>> pair = (1, 2)
>>> pair
(1, 2)
>>> x, y = pair
>>> x
1
>>> y
2
>>> pair[0]
1
>>> pair[1]
2

下標:從0開始。一種約定:下標表示一個元素偏離元組開始元素的距離。
表示有理數:程序如下:

from operator import getitem
from fractions import gcd   #導入求最大公約數的函數gcd
def make_rat(n, d):  #returns the rational number with numerator n and denominator d
    g = gcd(n, d)
    return (n//g, d//g)

def numer(x):   #returns the numerator of the rational number x.
    return getitem(x, 0)
def denom(x):   #returns the denominator of the rational number x.
    return getitem(x, 1)

def add_rat(x, y):
    nx, dx = numer(x), denom(x)
    ny, dy = numer(y), denom(y)
    return make_rat(nx * dy + ny * dx, dx * dy)

def mul_rat(x, y):
    return make_rat(numer(x) * numer(y) ,denom(x) * denom(y))

def eq_rat(x, y):
    return numer(x) * denom(y) == numer(y) * denom(x)

def str_rat(x):
    """return a string 'n/d' for numerator n and demominator d."""
    return '{0}/{1}'.format(numer(x), denom(x))

half = make_rat(1, 2)
print(str_rat(half)) #1/2
third = make_rat(1, 3)
print(str_rat(third))      #1/3
print(str_rat(mul_rat(half, third)))    #1/6
print(str_rat(add_rat(third, third)))   #2/3

2.3. 抽象界限

一般來說,數據抽象的根本思想是爲了給每種類型的值確定一種基本操作,就這種操作來說,所有的類型的值將被表達,然後只使用這些這些操作在操縱數據。。
抽象界限提供了好多好處:一個好處是使程序維護和修改更加簡單。較小的函數取決與特定的表式,當需要改變時只需要做少量的修改。

2.4. 數據屬性

def make_pair(x, y):
    """
    return a function that behaves like a pair.
    """
    def dispatch(m):
        if 0 == m:
            return x
        elif 1 == m:
            return y
    return dispatch

def getitem_pair(p, i):
    """
    Return the element at index i of pair p.
    """
    return p(i)

p = make_pair(4, 5)  
print(getitem_pair(p, 0))
#4
print(getitem_pair(p, 1))
#5
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章