您的位置:首页 > 编程语言 > Python开发

SICP_Python版第二章(1)

2016-07-11 18:10 302 查看

练习以下是关于有理数的定义和计算,通过最大公约数和对负号的处理,进行化简。

from fractions import gcd
from operator import getitem
def make_rat(n, d):
if n*d < 0:n,d = -abs(n),abs(d)
g = gcd(n,d)
return (n//g,d//g)
def numer(x):
return getitem(x, 0)
def denom(x):
return getitem(x, 1)
def add_rat(x,y):
nx,ny = numer(x),numer(y)
dx,dy = denom(x),denom(y)
return make_rat(nx*dy+ny*dx,dx*dy)
def sub_rat(x,y):
return add_rat(x,make_rat(-numer(y),denom(y)))
def mul_rat(x,y):
nx,ny = numer(x),numer(y)
dx,dy = denom(x),denom(y)
return make_rat(nx*ny,dx*dy)
def div_rat(x,y):
return mul_rat(x,make_rat(denom(y),numer(y)))
def str_rat(x):
return '{0}/{1}'.format(numer(x),denom(x))
a = make_rat(-3,-5)
b = make_rat(4,-6)
print(str_rat(add_rat(a,b)),str_rat(sub_rat(a,b)),str_rat(mul_rat(a,b)),str_rat(div_rat(a,b)))


练习 设计一些产生和运算点,线的过程

def make_segment(b_p,e_p):
return (b_p,e_p)
def start_segment(s):
return getitem(s,0)
def end_segment(s):
return getitem(s,1)
def make_point(x,y):
return (x,y)
def x_point(p):
return getitem(p,0)
def y_point(p):
return getitem(p,1)
def midpoint_segment(s):
b_p,e_p = start_segment(s),end_segment(s)
return make_point(0.5*(x_point(b_p)+y_point(e_p)),
0.5*(y_point(b_p)+y_point(e_p)))
def str_point(p):
return '({0},{1})'.format(x_point(p),y_point(p))
s = make_segment(make_point(0,5),make_point(2,4))
print(str_point(midpoint_segment(s)))


练习定义一个平面上矩形的表示方式,并且定义一个过程用来计算它的面积,周长。用另外一种方式定义矩形,并保证计算面积和周长的函数还能继续使用

PS:这道题很重要,可以加深对AbstractionBarrier的理解,想要成功定义一个合理且灵活的体系,最关键的是要考虑到基本元素的适用性。任何一个矩形无论怎么定义,一个有长和宽这两个基本元素。所以可以利用这两个元素作为抽象屏障,来计算面积和周长。反之,如果使用顶点的概念来进行抽象过程的定义,那么如果矩形不是垂直或平行于坐标轴的图像,这个顶点的定义将不适用!当然,为了简单起见,第一种定义还是使用顶点法:

Implemention(a)

def compute_area(rec):
return width(rec)*height(rec)
def compute_length(rec):
return 2*(width(rec)+height(rec))
def make_rec(p1,p2):
return (p1,p2)
def top_left(rec):
return getitem(rec,0)
def low_right(rec):
return getitem(rec,1)
def height(rec):
p1 = top_left(rec)
p2 = low_right(rec)
return y_point(p1)-y_point(p2)
def width(rec):
p1 = top_left(rec)
p2 = low_right(rec)
return x_point(p2)-x_point(p1)


Implemention(b)

这种定义让我们可以以任意两条边来定义一个矩形,当然作为代价,我们要对输入的参数进行排序和处理,这样就可以忽略两条边的关系是(垂直/平行)什么。

def make_rec(s1,s2):
return (s1,s2)
def side1(rec):
return getitem(rec,0)
def side2(rec):
return getitem(rec,1)
def get_bounds(rec):
s1,s2 = side1(rec),side2(rec)
p1,p2 = start_segment(s1),start_segment(s2)
p3,p4 = end_segment(s1),end_segment(s2)
xs = set([x_point(p1),x_point(p2),x_point(p3),x_point(p4)])
ys = set([y_point(p1),y_point(p2),y_point(p3),y_point(p4)])
return xs,ys
def width(rec):
xs,ys = get_bounds(rec)
return max(xs)-min(xs)
def height(rec):
xs,ys = get_bounds(rec)
return max(ys)-min(ys)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: