SICP_Python版第二章(1)

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

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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值