《Python核心编程》第13章 面向对象编程 练习

13-3.对类进行定制。

写一个类,用来将浮点型值转换为金额。

class MoneyFmt(object):
    def __init__(self, value=0.0):
        self.value = float(value)

    def update(self, value=None):
        if value != None:
            self.value = float(value)

    def __repr__(self):
        return `self.value`

    def __str__(self):
        pre = '$' if self.value >= 0 else '-$'
        return pre + str(round(abs(self.value), 2))

    def __nonzero__(self):
        return self.value > 0.5
13-4.用户注册。

建立一个用户数据库类,来管理一个系统,该系统要求用户在登录后才能访问某些资源。这个数据库类对用户进行管理,并在实例化操作时加载之前保存的用户信息,提供访问函数来添加或更新数据库的信息。在数据修改后,数据库会在垃圾回收时将新信息保存到磁盘。

import shelve
import os
import time

class UserData(object):
    def __init__(self, dbfile):
        self._db = {}
        if os.path.exists(dbfile):
            self._db = shelve.open(dbfile, 'r')
        self._dbfile = dbfile

    def __del__(self):
        data = shelve.open(self._dbfile, 'c')
        data.update(self._db)
        data.close()

    def update(self, name, passwd):
        self._db[name] = [passwd, time.time()]

    def delete(self, name):
        self._db.pop(name)

    def login(self, name, passwd):
        if self._db.get(name, None)[0] == passwd:
            self._db[name][1] = time.time()
            return True
        return False

    def listall(self):
        for name in self._db:
            print name, self._db[name][0], time.ctime(self._db[name][1])
13-5.几何。

创建一个由有序数值对(x,y)组成的Point类,代表某个点的X和Y坐标。

class Point(object):
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __str__(self):
        return '(%d, %d)' % (self.x, self.y)

    __repr__ = __str__
13-6.几何。

创建一个直线类,除主要属性:一对坐标值外,它还具有长度和斜线属性。你需要覆盖__repr__()方法,使得代表那条直线的字符串表示形式是由一对元组构成的元组。

from math import sqrt

class Line(object):
    def __init__(self, x1=0, y1=0, x2=0, y2=0):
        self.p1 = Point(x1, y1)
        self.p2 = Point(x2, y2)

    def __str__(self):
        return '(%s, %s)' % (str(self.p1), str(self.p2))

    __repr__ = __str__

    def slope(self):
        try:
            k = float(self.p2.y - self.p1.y) / (self.p2.x - self.p1.x)
        except ZeroDivisionError:
            k = None
        return k

    def length(self):
        return sqrt((self.p2.y - self.p1.y)**2 + (self.p2.x - self.p1.x)**2)
13-7.数据类。

提供一个time模块的接口,允许用户按照自己给定的时间格式来查看日期。你的类应该维护一个日期值,并用给定的时间创建一个实例,如果没有给出时间值,程序执行时会默认采用当前的系统时间。

import time

class TimeFmt(object):

    def __init__(self, time=time.time()):
        self.__time = time

    def update(self, time=time.time()):
        self.__time = time

    def display(self, fmt=None):
        fmtdb = {}
        fmtdb['MDY'] = '%m/%d/%y'
        fmtdb['MDYY'] = '%m/%d/%Y'
        fmtdb['DMY'] = '%d/%m/%y'
        fmtdb['DMYY'] = '%d/%m/%Y'
        fmtdb['MODYY'] = '%m %d, %Y'
        if fmt in fmtdb:
            t = time.localtime(self.__time)
            print time.strftime(fmtdb[fmt], t)
        else:
            print time.ctime(self.__time)
13-8.堆栈类。

实现一个堆栈类,类中应该有push()和pop()方法,还有一个isempty()方法,如果堆栈是空的,返回布尔值1,否则返回0。

class Stack(object):

    def __init__(self):
        self.__ls = []

    def push(self, obj):
        self.__ls.append(obj)

    def pop(self):
        if not self.isempty():
            return self.__ls.pop()

    def isempty(self):
        return len(self.__ls) == 0

    def peek(self):
        return self.__ls[len(self.__ls)-1]
13-9.队列类。

实现一个队列类,这个类必须支持下面几种方法:enqueue()在队列的尾部加入一个新的元素,dequeue()在队列的头部取出一个元素,返回它并且把它从列表中删除。

class Queue(object):

    def __init__(self):
        self.__ls = []

    def __str__(self):
        return str(self.__ls)

    def enqueue(self, obj):
        self.__ls.append(obj)

    def dequeue(self):
        if not self.isempty():
            return self.__ls.pop(0)

    def isempty(self):
        return len(self.__ls) == 0
13-11.电子商务。

你需要为一家B2C零售商编写一个基础的电子商务引擎。你需要写一个针对顾客的类User,一个对应存货清单的类Item,还有一个对应购物车的类叫Cart。货物放到购物车里,顾客可以有多个购物车。同时购物车里可以有多个货物,包括多个同样的货物。

class Item(object):

    def __init__(self, name, price):
        self.name = name
        self.price = price


class Cart(object):

    def __init__(self):
        self.ls = {}

    def append(self, item, count):
        if item not in self.ls:
            self.ls[item] = count
        else:
            self.ls[item] += count

    def delete(self, item, count):
        if (item in self.ls) and (self.ls[item] >= count):
            self.ls[item] -= count
            if self.ls[item] == 0:
                self.ls.pop(item)


class User(object):

    def __init__(self):
        self.ls = []

    def append(self, cart):
        self.ls.append(cart)

    def delete(self, cart):
        self.ls.remove(cart)   
13-12.聊天室。

你需要三个类:一个Message类,它包含一个消息字符串以及诸如广播、单方收件人等其他信息。一个User类,包含了进入你聊天室的某个人的所有信息。一个Room类,它体现了一个更加复杂的聊天系统,用户可以在聊天时创建单独的房间,并邀请其他人加入。

class Message(object):

    def __init__(self, info='', isbroad=False, to='', froms=''):
        self.info = info
        self.isbroad = isbroad
        self.to = to
        self.froms = froms

    def __str__(self):
        if self.isbroad:
            msg = '%s say to everone: %s' % (self.froms, self.info)
        else:
            msg = '%s say to %s: %s' % (self.froms, self.to, self.info)
        return msg


class User(object):

    def __init__(self, name='', sex=True, age=18):
        self.name = name
        self.sex = sex
        self.age = age

    def __str__(self):
        return '%s %s %s' % (self.name, self.sex, self.age)

    def say(self, room, info, to=''):
        if to == '':
            msg = Message(info, True, '', self.name)
        else:
            msg = Message(info, False, to, self.name)
        room.receive(msg)

    def hear(self, msg):
        print msg

    def createroom(self, name):
        return Room(name)


class Room(object):

    def __init__(self, name):
        self.name = name
        self.userlist = []

    def add(self, user):
        self.userlist.append(user)

    def receive(self, msg):
        if msg.isbroad:
            print msg
        else:
            for user in self.userlist:
                if user.name == msg.to:
                    user.hear(msg)

 

if __name__ == '__main__':
    user1 = User('Tom', True, 16)
    user2 = User('Lily', False, 15)
    user3 = User('Lucy', False)

    room = user1.createroom('chatting room')
    room.add(user1)
    room.add(user2)
    room.add(user3)
   
    user1.say(room, 'Hi, Lily', 'Lily')
    user2.say(room, 'Hello, Tom', 'Tom')
    user3.say(room, 'Hey, you two')

13-14.DOS。

为DOS机器编写一个Unix操作界面的shell。你向用户提供一个命令行,使得用户可以在那里输入unix命令,你可以对这些命令进行解释,并把返回相应的输出。

import os

class Shell(object):

    def __init__(self):
        self.cmds = {'ls': 'dir', 'cat': 'type', 'rm': 'del'}

    def translate(self, cmd):
        words = cmd.split()
        if words[0] in self.cmds:
            words[0] = self.cmds[words[0]]
        return ' '.join(words)

    def start(self):
        while True:
            cmd = raw_input('$')
            cmd = self.translate(cmd)
            if cmd == 'exit':
                break
            else:
                f = os.popen(cmd)
                for data in f:
                    print data,
                print
                f.close()

if __name__ == '__main__':
    sh = Shell()
    sh.start()
13-16.授权和函数编程。
(a)请为示例中的CanOpen类编写一个writelines()方法,这个新函数可以一次读入多行文本,然后将文本转化为大写的形式。
(b)在writelines()方法中添加一个参数,用这个参数来指明是否需要为每行文本加上一个换行符。此参数的默认值是False,表示不加换行符。

from os import linesep

class CanOpen(object):

    def __init__(self, fn, mode='r', buf=-1):
        self.file = open(fn, mode, buf)

    def __str__(self):
        return str(self.file)

    def __repr__(self):
        return `self.file`

    def write(self, line):
        self.file.write(line.upper())

    def writelines(self, lines, newline=False):
        for line in lines:
            if newline:
                line += linesep
            self.file.write(line.upper())

    def __getattr__(self, attr):
        return getattr(self.file, attr)
13-20.类的定制。改进脚本time60.py
(a)允许“空”实例化:如果小时和分钟的值没有给出,默认为0小时0分钟。
(b)用0占位组成两位数的形式,因为当前的时间格式不符合要求。
(c)除了用hours(hr)和minutes(min)进行初始化外,还支持以下时间输入格式:
一个由小时和分钟组成的元组,如(10,30)
一个由小时和分钟组成的字典,如{'hr':10, 'min':30}
一个代表小时和分钟的字符串,如"10:30"
(e)实现__repr__()。
(f)添加60进制的运算功能。

 

class Time60(object):
    'Time60 - track hours and minutes'

    def __init__(self, hr=0, min=0):
        if isinstance(hr, basestring):
            t = hr.split(':')
            self.hr = int(t[0])
            self.min = int(t[1])
        else:
            self.hr = hr
            self.min = min

    def __str__(self):
        return '%02d:%02d' % (self.hr, self.min)

    def __repr__(self):
        return "%s('%s')" % (self.__class__.__name__, str(self))

    def add60(self, other):
        hr = self.hr + other.hr
        min = self.min + other.min
        carry = min // 60
        min %= 60
        hr += carry
        return (hr, min)

    def __add__(self, other):
        return self.__class__(*self.add60(other))

    def __iadd__(self, other):
        (self.hr, self.min) = self.add60(other)
        return self

if __name__ == '__main__':
    print Time60()
    print Time60(12,5)
    print Time60(*(10, 30))
    print Time60(**{'hr': 10, 'min': 30})
    print Time60('10:30')
    print `Time60('10:10')`
    print Time60(10, 30) + Time60(8, 45)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值