13-3.对类进行定制。写一个类,用来将浮点型值转换为金额。
 class MoneyFmt(object):

     def __init__(self, value=0.0, flag='-'):

         self.value = float(value)
self.flag = flag def dollarize(self):
"""转换"""
val = round(self.value, 2)
strvalue = str(val)
if strvalue.startswith('-'):
strvalue = strvalue[1:]
len = strvalue.find('.')
while (len-3) > 0:
strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
len -= 3
return self.flag + '$' + strvalue len = strvalue.find('.')
while (len-3) > 0:
strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
len -= 3
return '$' + strvalue def update(self, newvalue=None):
"""更新"""
if newvalue is not None:
self.value = float(newvalue) def __nonzero__(self):
"非零"
if self.value == 0:
return False
return True def __str__(self):
return self.dollarize() def __repr__(self):
return repr(self.value)

13-4.用户注册。

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

 from datetime import datetime
import shelve class Userdatabase(object): def __init__(self, dbfile):
"""创建数据库"""
self.dbfile = dbfile
self.db = shelve.open(self.dbfile, 'c')
self.db.close() def newuser(self, user, pwd):
"""注册"""
self.db = shelve.open(self.dbfile, 'r')
if user in self.db:
print("User already exists")
self.db = shelve.open(self.dbfile, 'c')
self.db[user] = [user, pwd, datetime.now()]
self.db.close()
self.flag = False def login(self, user, pwd):
"""登录"""
self.db = shelve.open(self.dbfile, 'r')
if user not in self.db:
self.flag = False
elif self.db[user][1] == pwd:
self.flag = True
self.db.close() def deluser(self, user):
"""删除"""
self.db = {}
if self.flag:
self.db = shelve.open(self.dbfile, 'r')
if user in self.db:
self.db.pop(user)
else:
print('login first') def updateuser(self, user, pwd):
"""更新"""
if self.flag:
self.db = shelve.open(self.dbfile, 'c')
self.db[user] = [user, pwd, datetime.now()]
self.db[user] = self.db[user]
else:
print('login first') def listall(self):
"""查看"""
if self.flag:
for user in self.db:
print(self.db[user][0], self.db[user][1])
else:
print('login first') if __name__ == '__main__':
user = Userdatabase('shelve.data')
user.newuser('admin', '')
user.login('admin', '')
user.updateuser('admin', '')
user.updateuser('test', '')
user.listall()
user.deluser('test')
user.listall()

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) if __name__ == '__main__':
p = Point(1, 1)
print(p)

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

 from math import sqrt

 class Beeline(object):

     def __init__(self, x1=0, y1=0, x2=0, y2=2):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
self.length = 0
self.slope = None def getLength(self):
"""长度"""
if self.x1 == self.x2 and self.y1 == self.y2:
self.length = 0
elif self.x1 == self.x2:
self.length = abs(self.y2 - self.y1)
elif self.y1 == self.y2:
self.length = abs(self.x2 - self.x1)
else:
self.length = sqrt((self.y2 - self.y1)**2 + (self.x2 - self.x1)**2)
return self.length def getSlope(self):
"""斜率"""
if self.length == 0:
self.slope = None
elif self.x1 == self.x2 or self.y1 == self.y2:
self.slope = None
else:
self.slope = float(self.y2 - self.y1) / (self.x2 - self.x1)
return self.slope def __str__(self):
return '((%d, %d),(%d, %d))' % (self.x1, self.y1, self.x2, self.y2) __repr__ = __str__ if __name__ == '__main__':
b = Beeline(1, 2, 3, 4)
print(b)
print('Length is %f' % b.getLength())
print('Slope is %s' % b.getSlope())

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

 import time

 class TimeFormat(object):

     def __init__(self, t=time.time()):
self.mytime = t def update(self, t=time.time()):
self.mytime = t def display(self, ft=None):
fmt = {}
fmt['MDY'] = '%m/%d/%y'
fmt['MDYY'] = '%m/%d/%Y'
fmt['DMY'] = '%d/%m/%y'
fmt['DMYY'] = '%d/%m/%Y'
fmt['MODYY'] = '%b %d,%Y'
if ft in fmt:
return (time.strftime(fmt[ft], time.localtime(self.mytime)))
return time.ctime(self.mytime) if __name__ == '__main__':
tf = TimeFormat()
print(tf.display())
print(tf.display('MDY'))
print(tf.display('MDYY'))
print(tf.display('DMY'))
print(tf.display('DMYY'))
print(tf.display('MODYY'))
tf.update(time.time() + 60)
print(tf.display())

13-8.堆栈类。

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

 class Stack(object):

     def __init__(self, l=[]):
self.l = l def isempty(self):
if len(self.l) == 0:
return 1
return 0 def push(self, element):
print('pushed [', element, ']')
self.l.append(element) def peek(self):
if self.isempty():
print('can not peek from an empty stack')
return self.l[0] def pop(self):
if self.isempty():
print('can not pop from an empty stack')
else:
print('removed [', self.l.pop(), ']') def viewstack(self):
print(self.l) if __name__ == '__main__':
s = Stack()
s.viewstack()
s.pop()
s.viewstack()
s.push(2)
s.viewstack()

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

 class Queue(object):

     def __init__(self, l=[]):
self.l = l def enqueue(self, element):
print('enter queue [', element, ']')
self.l.append(element) def dequeue(self):
if self.l:
print('removed [', self.l.pop(0), ']')
else:
print('can not pop from an empty stack') def viewstack(self):
print(self.l) if __name__ == '__main__':
q = Queue([1, 2, 3])
q.viewstack()
q.enqueue(4)
q.dequeue()
q.viewstack()

13-10.堆栈和队列。编写一个类,定义一个能够同时具有堆栈和队列操作行为的数据结构。这个类和Perl语言中数组相像。需要实现四个方法。

 class FifoLifo(object):

     def __init__(self, l=[]):
self.l = l def shift(self):
"""删除头"""
if self.l:
print('removed [', self.l.pop(0), ']')
else:
print('can not pop from an empty stack') def unshift(self, element):
"""插入头"""
print('inserted [', element, ']')
self.l.insert(0, element) def push(self, element):
"""插入尾"""
print('pushed [', element, ']')
self.l.append(element) def pop(self):
"""删除尾"""
if self.l:
print('removed [', self.l.pop(), ']')
else:
print('can not pop from an empty stack') def viewstack(self):
print(self.l) if __name__ == '__main__':
f = FifoLifo([1, 2, 3, 4, 5])
f.viewstack()
f.shift()
f.unshift(6)
f.push(0)
f.pop()
f.viewstack()

13-11.电子商务。

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

 class Item(object):
"""物品价格清单"""
def __init__(self, product, price):
self.product = product
self.price = price def __str__(self):
return '(%s, %.2f)' % (self.product, self.price) class Cart(object):
"""购物车"""
def __init__(self, cartname):
self.cartname = cartname
self.cartlist = {} def appenditem(self, item, count=1):
"""增加数量"""
if item not in self.cartlist:
self.cartlist[item] = count
else:
self.cartlist[item] += count def showcart(self):
"""查看"""
for i in self.cartlist:
print(self.cartname, i, self.cartlist[i]) def deleteitem(self, item, count=1):
"""减少数量"""
if item in self.cartlist and self.cartlist[item]>=count:
self.cartlist[item] -= count
if self.cartlist[item] == 0:
self.cartlist.pop(item) class User(object):
"""顾客"""
def __init__(self, name):
self.name = name
self.userdb = [] def appendcart(self, cart):
self.userdb.append(cart.cartname) def showuser(self):
print(self.name, self.userdb) if __name__ == '__main__':
i1 = Item('huawei', 15000)
i2 = Item('iphone', 7000)
print(i1, i2)
c1 = Cart('cart1')
c2 = Cart('cart2')
c3 = Cart('cart3')
c1.appenditem(i1, 1)
c1.appenditem(i2, 1)
c2.appenditem(i2, 2)
c3.appenditem(i1, 2)
c1.showcart()
c2.showcart()
c3.showcart()
u1 = User('Tom')
u2 = User('Jerry')
u1.appendcart(c1)
u2.appendcart(c2)
u2.appendcart(c3)
u1.showuser()
u2.showuser()

13-12.聊天室。

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

 class Message(object):

     def __init__(self, msg='', broadcast=False, froms='', to=''):

         self.msg = msg
self.broadcast = broadcast
self.froms = froms
self.to = to def __str__(self):
"""广播"""
if self.broadcast:
return 'message: %s from %s send to everyone' % (self.msg, self.froms)
else:
return 'message: %s from %s send to %s' % (self.msg, self.froms, self.to) class User(object): hear = {'everyone': ''} def __init__(self, name, sex, age): self.name = name
self.sex = sex
self.age = age def __del__(self): User.hear.clear() def __str__(self): return 'user:%s ,sex:%s ,age:%d' % (self.name, self.sex, self.age) def talk(self, to='', msg=''):
"""发送广播"""
if to == 'everyone':
m = Message(msg, True, self.name)
User.hear['everyone'] = m
elif to:
m = Message(msg, False, self.name, to)
User.hear[to] = m
else:
print('receiver can not be empty') def hearmsg(self):
"""显示消息"""
if self.name in User.hear:
print(User.hear[self.name])
elif User.hear['everyone']:
print(User.hear['everyone'])
else:
print('no msg for %s' % self.name) def talkroom(self, room, to='', msg=''):
"""room广播"""
if to == 'everyone':
m = Message(msg, True, self.name)
room.receive(m)
elif to:
m = Message(msg, False, self.name, to)
room.receive(m)
else:
print('receiver can not be empty') def hearroom(self, m):
"""显示room消息"""
print('room %s' % m) def createroom(self, name, count=3):
"""room人员"""
return Room(name, count) class Room(object): def __init__(self, rname, count=3): self.rname = rname
self.count = count
self.userlist = [] def adduser(self, user):
"""room用户邀请"""
if len(self.userlist) <= self.count:
self.userlist.append(user)
else:
print('user number limits') def receive(self, m):
"""room广播"""
if m.broadcast:
print('room %s' % m)
else:
for user in self.userlist:
if user.name == m.to:
user.hearroom(m) if __name__ == '__main__':
u1 = User('bob', 'male', 33)
u2 = User('jim', 'female', 31)
u3 = User('Tom', 'female', 31)
u1.talk('jim', 'hello')
u2.hearmsg()
u3.hearmsg()
room1 = u2.createroom('girls', 2)
room1.adduser(u2)
room1.adduser(u3)
u2.talkroom(room1, 'Tom', 'hello')
u3.talkroom(room1, 'everyone', 'hello')

13-13. 股票投资组合类。你的数据库中记录了每个公司的名字、股票代码、购买日期、购买价格和持股数量。需要编写的方法包括:添加新代号、删除代号、根据当前价格计算出的YTD或年回报率。

 class Stock(object):

     def __init__(self, name, code, date, price, amount):

         self.name = name
self.code = code
self.date = date
self.price = price
self.amount = amount def __str__(self):
return '%s %s %s %.2f %d' % (self.name, self.code, self.date, self.price, self.amount) class Operator(object): def __init__(self): self.db = {} def newcode(self, stock): self.db.setdefault(stock.code, [stock.name, stock.date, stock.price, stock.amount]) def popcode(self, code): self.db.pop(code) def years(self, year): if (year % 4 == 0 and year % 100 != 0) or (year % 4 == 0 and year % 400 == 0):
return True def months(self, str1, str2): month1 = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
month2 = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
bdate = str1.split('/')
bdate[0], bdate[1], bdate[2] = int(bdate[0]), int(bdate[1]), int(bdate[2])
edate = str2.split('/')
edate[0], edate[1], edate[2] = int(edate[0]), int(edate[1]), int(edate[2]) if bdate == edate:
return 0 elif bdate[1] == edate[1] and bdate[2] == bdate[2]:
return abs(bdate[0]-edate[0]) elif bdate[1] != edate[1] and bdate[2] == edate[2]:
bdays = 0
edays = 0
if self.years(bdate[2]):
for i in range(1, bdate[1]):
bdays += month2[i]
bdays = bdays + bdate[0]
for i in range(1, edate[1]):
edays += month2[i]
edays = edays + edate[0]
return abs(edays - bdays)
else:
for i in range(1, bdate[1]):
bdays += month1[i]
bdays = bdays + bdate[0]
for i in range(1, edate[1]):
edays += month1[i]
edays = edays + edate[0]
return abs(edays - bdays) elif bdate[2] != edate[2]:
days = 0
for i in range(bdate[2]+1, edate[2]):
if self.years(i):
days += 366
else:
days += 365
if self.years(bdate[2]):
for i in range(bdate[1]+1, 13):
days += month2[i]
days += (month2[bdate[1]]-bdate[0])
else:
for i in range(bdate[1]+1, 13):
days += month1[i]
days += (month1[bdate[1] - bdate[0]])
if self.years(edate[2]):
for i in range(1, edate[1]):
days += month2[i]
days += edate[0]
return days
else:
for i in range(1, edate[1]):
days += month1[i]
days += edate[0]
return days def YTD(self, stock, newprice, newdate): holddays = self.months(stock.date, newdate)
costmoney = stock.price * stock.amount
curmoney = newprice * stock.amount
benifit = curmoney - costmoney if stock.code in self.db:
print('YTD of %s is %.2f %%' %(stock.code, benifit/holddays*365/costmoney))
else:
print('Stock %s does not exists' % stock.code) def showdb(self):
print(self.db) s1 = Stock('xx', '', '01/01/2019', 1.0, 1000)
s2 = Stock('yy', '', '05/01/2019', 18.0, 1000)
op1 = Operator()
op1.newcode(s1)
op1.newcode(s2)
op1.showdb()
op1.popcode('')
op1.showdb()
op1.YTD(s1, 1.01, '11/03/2019')

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

 import os

 class Shell(object):

     def __init__(self):

         self.cmddict = {'ls': 'dir', 'more': 'more', 'cat': 'type', 'cp': 'copy', 'mv': 'ren', 'rm': 'del'}

     def translate(self, cmd):

         opt = cmd.split()
if opt[0] in self.cmddict:
opt[0] = self.cmddict[opt[0]]
return ' '.join(opt) def start(self): while True:
cmd = input('#')
cmd = self.translate(cmd)
if cmd == 'exit':
break output = os.popen(cmd).readlines()
for out in output:
print(out) if __name__ == '__main__':
s = Shell()
s.start()

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

 import os

 class CapOpen(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, enter=False):

         for line in lines:
if enter:
line += os.linesep
self.write(line) def __getattr__(self, attr): return getattr(self.file, attr) if __name__ == '__main__':
f1 = CapOpen('test.txt')
lines = f1.readlines()
f1.close() f2 = CapOpen('newtest.txt', 'w')
f2.writelines(lines, False)
f2.close()

13-17. 数值类型子类化。在示例13.3中所看到的moneyfmt.py脚本基础上修改它,使得它可以扩展Python的浮点类型。请确保它支持所有操作,而且是不可变的。

 class MoneyFmt(float):

     def __new__(cls, value=0.0, flag='-'):

         cls.flag = flag
cls.value = super(MoneyFmt, cls).__new__(cls, value)
return cls.value def dollarize(cls):
"""转换"""
val = round(cls.value, 2)
strvalue = str(val)
if strvalue.startswith('-'):
strvalue = strvalue[1:]
len = strvalue.find('.')
while (len-3) > 0:
strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
len -= 3
return cls.flag + '$' + strvalue len = strvalue.find('.')
while (len-3) > 0:
strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
len -= 3
return '$' + strvalue def __nonzero__(cls):
"非零"
if cls.value == 0:
return False
return True def __str__(cls): return cls.dollarize() if __name__ == '__main__':
money = input('Money: ')
moneyfmt = MoneyFmt(money)
print(moneyfmt.dollarize())

13-18. 序列类型子类化。模仿前面练习13-4中的用户注册类的解决方案,编写一个子类。要求允许用户修改密码,但密码有效期是12个月,过期后不能重复使用。

 import time, shelve

 class Userdatabase(object):

     def __init__(self, dbfile):
"""创建数据库"""
self.dbfile = dbfile
self.db = shelve.open(self.dbfile, 'c')
self.db.close() def newuser(self, user, pwd):
"""注册""" self.db = shelve.open(self.dbfile, 'r')
if user in self.db:
print("User already exists")
self.db = shelve.open(self.dbfile, 'c')
self.db[user] = [user, [pwd, time.time()], time.ctime()]
self.db.close()
self.flag = False def login(self, user, pwd):
"""登录"""
self.db = shelve.open(self.dbfile, 'r')
if user not in self.db:
self.flag = False
elif self.db[user][1][0] == pwd:
if self.db[user][1][-1] - time.time() > 365*24*60*60:
print("Password has expired")
self.flag = False
else:
self.flag = True
self.db.close() def deluser(self, user):
"""删除"""
self.db = {}
if self.flag:
self.db = shelve.open(self.dbfile, 'r')
if user in self.db:
self.db.pop(user)
else:
print('login first') def updateuser(self, user, pwd):
"""更新密码"""
newdb = {}
if self.flag:
self.db = shelve.open(self.dbfile, 'r')
if pwd in self.db[user][1]:
print("The new password cannot be the same as the used password")
else:
value = [user, self.db[user][1], time.ctime()]
value[1].insert(0, pwd)
value[1][-1] = time.time()
newdb[user] = value
self.db = shelve.open(self.dbfile, 'c')
self.db[user] = newdb[user]
print(self.db[user])
else:
print('login first') def listall(self):
"""查看"""
if self.flag:
for user in self.db:
print(self.db[user][0], self.db[user][1][0])
else:
print('login first') if __name__ == '__main__':
user = Userdatabase('shelve.data')
user.newuser('admin', '')
user.newuser('test', '')
user.login('admin', '')
user.login('test', '')
user.updateuser('admin', '')
user.updateuser('test', '')
user.listall()
user.deluser('test')
user.listall()

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, *time):
'Time60 constructor - takes hours and minutes'
if len(time) == 1:
if type(time[0]) == tuple:
self.hr = time[0][0]
self.min = time[0][1]
elif type(time[0]) == dict:
self.hr = time[0]['hr']
self.min = time[0]['min']
elif type(time[0]) == str:
all = time[0].split(':')
self.hr = int(all[0])
self.min = int(all[1]) elif len(time) == 0:
self.hr = 0
self.min = 0 else:
self.hr = time[0]
self.min = time[1] def __str__(self):
'Time60 - string representation'
return '%02d:%02d' % (self.hr, self.min) def __repr__(self): return repr('%02d:%02d' % (self.hr, self.min)) def __add__(self, other):
'Time60 - overloading the addition operator'
hr = self.hr + other.hr
min = self.min + other.min
ahr = min // 60
min %= 60
hr += ahr
if hr > 23: hr = 0
return self.__class__(hr, min) def __iadd__(self, other):
'Time60 - overloading in-place addition'
self.hr += other.hr
self.min += other.min
return self print(Time60())
print(Time60(10, 30))
print(Time60("15:31"))
print(Time60((10, 30)))
print(Time60({'hr':11, 'min':15}))
print(Time60(1, 5))
print(Time60("15:31") + Time60(8,31))

最新文章

  1. JavaScript动画-拖拽改变元素大小
  2. python 中文乱码问题
  3. Sql Server 中一个非常强大的日期格式化函数
  4. Smart210学习记录-------文件操作
  5. 线性模型(1):Perceptron Learning Algorithm (PLA)
  6. 我只是不甘心-------Day51
  7. 学习笔记——装饰器模式Decorator
  8. python监控微信报警
  9. PageHelper分页异常(java.base/java.util.ArrayList cannot be cast to com.github.pagehelper.Page)
  10. How to change Eclipse loading image
  11. 配置合适的Visual Studio 2017 开发环境(其它版本的也适用)
  12. HierarchicalClustering:编写HierarchicalClustering层次聚类算法—Jason niu
  13. 《算法导论》——顺序统计RandomizedSelect
  14. 搭建GitLab+Jenkins
  15. 乐视mysql面试题【转】
  16. 纯css3实现的3D按钮
  17. [转]分布式中使用Redis实现Session共享(二)
  18. 在Centos7中安装elasticsearch5.5
  19. 用boost::lexical_cast进行数值转换
  20. ionic新手教程第七课-简要说明几种界面之间的參数传递及优缺点

热门文章

  1. Python爬虫《http和https协议》
  2. 在asp.net中如何使用Session
  3. Java &amp; COM
  4. 超级表格:要山寨Excel,还是与之Say Byebye?
  5. 一、选择与安装——Linux学习笔记
  6. Selenium2学习(七)-- 定位一组元素find_elements
  7. oracle_union_operator
  8. 怎么看电脑有没有安装USB3.0驱动
  9. May 24th 2017 Week 21th Wednesday
  10. March 21 2017 Week 12 Tuesday