• python核心编程2 第十三章 练习


    13-3.对类进行定制。写一个类,用来将浮点型值转换为金额。
     1 class MoneyFmt(object):
     2 
     3     def __init__(self, value=0.0, flag='-'):
     4 
     5         self.value = float(value)
     6         self.flag = flag
     7 
     8     def dollarize(self):
     9         """转换"""
    10         val = round(self.value, 2)
    11         strvalue = str(val)
    12         if strvalue.startswith('-'):
    13             strvalue = strvalue[1:]
    14             len = strvalue.find('.')
    15             while (len-3) > 0:
    16                 strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
    17                 len -= 3
    18             return self.flag + '$' + strvalue
    19 
    20         len = strvalue.find('.')
    21         while (len-3) > 0:
    22             strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
    23             len -= 3
    24         return '$' + strvalue
    25 
    26     def update(self, newvalue=None):
    27         """更新"""
    28         if newvalue is not None:
    29             self.value = float(newvalue)
    30 
    31     def __nonzero__(self):
    32         "非零"
    33         if self.value == 0:
    34             return False
    35         return True
    36 
    37     def __str__(self):
    38         return self.dollarize()
    39 
    40     def __repr__(self):
    41         return repr(self.value)

    13-4.用户注册。

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

     1 from datetime import datetime
     2 import shelve
     3 
     4 class Userdatabase(object):
     5 
     6     def __init__(self, dbfile):
     7         """创建数据库"""
     8         self.dbfile = dbfile
     9         self.db = shelve.open(self.dbfile, 'c')
    10         self.db.close()
    11 
    12     def newuser(self, user, pwd):
    13         """注册"""
    14         self.db = shelve.open(self.dbfile, 'r')
    15         if user in self.db:
    16             print("User already exists")
    17         self.db = shelve.open(self.dbfile, 'c')
    18         self.db[user] = [user, pwd, datetime.now()]
    19         self.db.close()
    20         self.flag = False
    21 
    22     def login(self, user, pwd):
    23         """登录"""
    24         self.db = shelve.open(self.dbfile, 'r')
    25         if user not in self.db:
    26             self.flag = False
    27         elif self.db[user][1] == pwd:
    28             self.flag = True
    29         self.db.close()
    30 
    31     def deluser(self, user):
    32         """删除"""
    33         self.db = {}
    34         if self.flag:
    35             self.db = shelve.open(self.dbfile, 'r')
    36             if user in self.db:
    37                 self.db.pop(user)
    38         else:
    39             print('login first')
    40 
    41     def updateuser(self, user, pwd):
    42         """更新"""
    43         if self.flag:
    44             self.db = shelve.open(self.dbfile, 'c')
    45             self.db[user] = [user, pwd, datetime.now()]
    46             self.db[user] = self.db[user]
    47         else:
    48             print('login first')
    49 
    50     def listall(self):
    51         """查看"""
    52         if self.flag:
    53             for user in self.db:
    54                 print(self.db[user][0], self.db[user][1])
    55         else:
    56             print('login first')
    57 
    58 if __name__ == '__main__':
    59     user = Userdatabase('shelve.data')
    60     user.newuser('admin', '123456')
    61     user.login('admin', '123456')
    62     user.updateuser('admin', '123456')
    63     user.updateuser('test', '123456')
    64     user.listall()
    65     user.deluser('test')
    66     user.listall()

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

     1 class Point(object):
     2 
     3     def __init__(self, x=0, y=0):
     4         self.x = x
     5         self.y = y
     6 
     7     def __str__(self):
     8         return '(%d, %d)' % (self.x, self.y)
     9 
    10 if __name__ == '__main__':
    11     p = Point(1, 1)
    12     print(p)

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

     1 from math import sqrt
     2 
     3 class Beeline(object):
     4 
     5     def __init__(self, x1=0, y1=0, x2=0, y2=2):
     6         self.x1 = x1
     7         self.y1 = y1
     8         self.x2 = x2
     9         self.y2 = y2
    10         self.length = 0
    11         self.slope = None
    12 
    13     def getLength(self):
    14         """长度"""
    15         if self.x1 == self.x2 and self.y1 == self.y2:
    16             self.length = 0
    17         elif self.x1 == self.x2:
    18             self.length = abs(self.y2 - self.y1)
    19         elif self.y1 == self.y2:
    20             self.length = abs(self.x2 - self.x1)
    21         else:
    22             self.length = sqrt((self.y2 - self.y1)**2 + (self.x2 - self.x1)**2)
    23         return self.length
    24 
    25     def getSlope(self):
    26         """斜率"""
    27         if self.length == 0:
    28             self.slope = None
    29         elif self.x1 == self.x2 or self.y1 == self.y2:
    30             self.slope = None
    31         else:
    32             self.slope = float(self.y2 - self.y1) / (self.x2 - self.x1)
    33         return self.slope
    34 
    35     def __str__(self):
    36         return '((%d, %d),(%d, %d))' % (self.x1, self.y1, self.x2, self.y2)
    37 
    38     __repr__ = __str__
    39 
    40 if __name__ == '__main__':
    41     b = Beeline(1, 2, 3, 4)
    42     print(b)
    43     print('Length is %f' % b.getLength())
    44     print('Slope is %s' % b.getSlope())

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

     1 import time
     2 
     3 class TimeFormat(object):
     4 
     5     def __init__(self, t=time.time()):
     6         self.mytime = t
     7 
     8     def update(self, t=time.time()):
     9         self.mytime = t
    10 
    11     def display(self, ft=None):
    12         fmt = {}
    13         fmt['MDY'] = '%m/%d/%y'
    14         fmt['MDYY'] = '%m/%d/%Y'
    15         fmt['DMY'] = '%d/%m/%y'
    16         fmt['DMYY'] = '%d/%m/%Y'
    17         fmt['MODYY'] = '%b %d,%Y'
    18         if ft in fmt:
    19             return (time.strftime(fmt[ft], time.localtime(self.mytime)))
    20         return time.ctime(self.mytime)
    21 
    22 if __name__ == '__main__':
    23     tf = TimeFormat()
    24     print(tf.display())
    25     print(tf.display('MDY'))
    26     print(tf.display('MDYY'))
    27     print(tf.display('DMY'))
    28     print(tf.display('DMYY'))
    29     print(tf.display('MODYY'))
    30     tf.update(time.time() + 60)
    31     print(tf.display())

     13-8.堆栈类。

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

     1 class Stack(object):
     2 
     3     def __init__(self, l=[]):
     4         self.l = l
     5 
     6     def isempty(self):
     7         if len(self.l) == 0:
     8             return 1
     9         return 0
    10 
    11     def push(self, element):
    12         print('pushed [', element, ']')
    13         self.l.append(element)
    14 
    15     def peek(self):
    16         if self.isempty():
    17             print('can not peek from an empty stack')
    18         return self.l[0]
    19 
    20     def pop(self):
    21         if self.isempty():
    22             print('can not pop from an empty stack')
    23         else:
    24             print('removed [', self.l.pop(), ']')
    25 
    26     def viewstack(self):
    27         print(self.l)
    28 
    29 if __name__ == '__main__':
    30     s = Stack()
    31     s.viewstack()
    32     s.pop()
    33     s.viewstack()
    34     s.push(2)
    35     s.viewstack()

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

     1 class Queue(object):
     2 
     3     def __init__(self, l=[]):
     4         self.l = l
     5 
     6     def enqueue(self, element):
     7         print('enter queue [', element, ']')
     8         self.l.append(element)
     9 
    10     def dequeue(self):
    11         if self.l:
    12             print('removed [', self.l.pop(0), ']')
    13         else:
    14             print('can not pop from an empty stack')
    15 
    16     def viewstack(self):
    17         print(self.l)
    18 
    19 if __name__ == '__main__':
    20     q = Queue([1, 2, 3])
    21     q.viewstack()
    22     q.enqueue(4)
    23     q.dequeue()
    24     q.viewstack()

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

     1 class FifoLifo(object):
     2 
     3     def __init__(self, l=[]):
     4         self.l = l
     5 
     6     def shift(self):
     7         """删除头"""
     8         if self.l:
     9             print('removed [', self.l.pop(0), ']')
    10         else:
    11             print('can not pop from an empty stack')
    12 
    13     def unshift(self, element):
    14         """插入头"""
    15         print('inserted [', element, ']')
    16         self.l.insert(0, element)
    17 
    18     def push(self, element):
    19         """插入尾"""
    20         print('pushed [', element, ']')
    21         self.l.append(element)
    22 
    23     def pop(self):
    24         """删除尾"""
    25         if self.l:
    26             print('removed [', self.l.pop(), ']')
    27         else:
    28             print('can not pop from an empty stack')
    29 
    30     def viewstack(self):
    31         print(self.l)
    32 
    33 if __name__ == '__main__':
    34     f = FifoLifo([1, 2, 3, 4, 5])
    35     f.viewstack()
    36     f.shift()
    37     f.unshift(6)
    38     f.push(0)
    39     f.pop()
    40     f.viewstack()

     13-11.电子商务。

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

     1 class Item(object):
     2     """物品价格清单"""
     3     def __init__(self, product, price):
     4         self.product = product
     5         self.price = price
     6 
     7     def __str__(self):
     8         return '(%s, %.2f)' % (self.product, self.price)
     9 
    10 class Cart(object):
    11     """购物车"""
    12     def __init__(self, cartname):
    13         self.cartname = cartname
    14         self.cartlist = {}
    15 
    16     def appenditem(self, item, count=1):
    17         """增加数量"""
    18         if item not in self.cartlist:
    19             self.cartlist[item] = count
    20         else:
    21             self.cartlist[item] += count
    22 
    23     def showcart(self):
    24         """查看"""
    25         for i in self.cartlist:
    26             print(self.cartname, i, self.cartlist[i])
    27 
    28     def deleteitem(self, item, count=1):
    29         """减少数量"""
    30         if item in self.cartlist and self.cartlist[item]>=count:
    31             self.cartlist[item] -= count
    32         if self.cartlist[item] == 0:
    33             self.cartlist.pop(item)
    34 
    35 class User(object):
    36     """顾客"""
    37     def __init__(self, name):
    38         self.name = name
    39         self.userdb = []
    40 
    41     def appendcart(self, cart):
    42         self.userdb.append(cart.cartname)
    43 
    44     def showuser(self):
    45         print(self.name, self.userdb)
    46 
    47 if __name__ == '__main__':
    48     i1 = Item('huawei', 15000)
    49     i2 = Item('iphone', 7000)
    50     print(i1, i2)
    51     c1 = Cart('cart1')
    52     c2 = Cart('cart2')
    53     c3 = Cart('cart3')
    54     c1.appenditem(i1, 1)
    55     c1.appenditem(i2, 1)
    56     c2.appenditem(i2, 2)
    57     c3.appenditem(i1, 2)
    58     c1.showcart()
    59     c2.showcart()
    60     c3.showcart()
    61     u1 = User('Tom')
    62     u2 = User('Jerry')
    63     u1.appendcart(c1)
    64     u2.appendcart(c2)
    65     u2.appendcart(c3)
    66     u1.showuser()
    67     u2.showuser()

     13-12.聊天室。

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

      1 class Message(object):
      2 
      3     def __init__(self, msg='', broadcast=False, froms='', to=''):
      4 
      5         self.msg = msg
      6         self.broadcast = broadcast
      7         self.froms = froms
      8         self.to = to
      9 
     10     def __str__(self):
     11         """广播"""
     12         if self.broadcast:
     13             return 'message: %s from %s send to everyone' % (self.msg, self.froms)
     14         else:
     15             return 'message: %s from %s send to %s' % (self.msg, self.froms, self.to)
     16 
     17 
     18 class User(object):
     19 
     20     hear = {'everyone': ''}
     21 
     22     def __init__(self, name, sex, age):
     23 
     24         self.name = name
     25         self.sex = sex
     26         self.age = age
     27 
     28     def __del__(self):
     29 
     30         User.hear.clear()
     31 
     32     def __str__(self):
     33 
     34         return 'user:%s ,sex:%s ,age:%d' % (self.name, self.sex, self.age)
     35 
     36     def talk(self, to='', msg=''):
     37         """发送广播"""
     38         if to == 'everyone':
     39             m = Message(msg, True, self.name)
     40             User.hear['everyone'] = m
     41         elif to:
     42             m = Message(msg, False, self.name, to)
     43             User.hear[to] = m
     44         else:
     45             print('receiver can not be empty')
     46 
     47     def hearmsg(self):
     48         """显示消息"""
     49         if self.name in User.hear:
     50             print(User.hear[self.name])
     51         elif User.hear['everyone']:
     52             print(User.hear['everyone'])
     53         else:
     54             print('no msg for %s' % self.name)
     55 
     56     def talkroom(self, room, to='', msg=''):
     57         """room广播"""
     58         if to == 'everyone':
     59             m = Message(msg, True, self.name)
     60             room.receive(m)
     61         elif to:
     62             m = Message(msg, False, self.name, to)
     63             room.receive(m)
     64         else:
     65             print('receiver can not be empty')
     66 
     67     def hearroom(self, m):
     68         """显示room消息"""
     69         print('room %s' % m)
     70 
     71     def createroom(self, name, count=3):
     72         """room人员"""
     73         return Room(name, count)
     74 
     75 
     76 class Room(object):
     77 
     78     def __init__(self, rname, count=3):
     79 
     80         self.rname = rname
     81         self.count = count
     82         self.userlist = []
     83 
     84     def adduser(self, user):
     85         """room用户邀请"""
     86         if len(self.userlist) <= self.count:
     87             self.userlist.append(user)
     88         else:
     89             print('user number limits')
     90 
     91     def receive(self, m):
     92         """room广播"""
     93         if m.broadcast:
     94             print('room %s' % m)
     95         else:
     96             for user in self.userlist:
     97                 if user.name == m.to:
     98                     user.hearroom(m)
     99 
    100 
    101 if __name__ == '__main__':
    102     u1 = User('bob', 'male', 33)
    103     u2 = User('jim', 'female', 31)
    104     u3 = User('Tom', 'female', 31)
    105     u1.talk('jim', 'hello')
    106     u2.hearmsg()
    107     u3.hearmsg()
    108     room1 = u2.createroom('girls', 2)
    109     room1.adduser(u2)
    110     room1.adduser(u3)
    111     u2.talkroom(room1, 'Tom', 'hello')
    112     u3.talkroom(room1, 'everyone', 'hello')

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

      1 class Stock(object):
      2 
      3     def __init__(self, name, code, date, price, amount):
      4 
      5         self.name = name
      6         self.code = code
      7         self.date = date
      8         self.price = price
      9         self.amount = amount
     10 
     11     def __str__(self):
     12         return '%s %s %s %.2f %d' % (self.name, self.code, self.date, self.price, self.amount)
     13 
     14 class Operator(object):
     15 
     16     def __init__(self):
     17         
     18         self.db = {}
     19 
     20     def newcode(self, stock):
     21         
     22         self.db.setdefault(stock.code, [stock.name, stock.date, stock.price, stock.amount])
     23 
     24     def popcode(self, code):
     25         
     26         self.db.pop(code)
     27 
     28     def years(self, year):
     29         
     30         if (year % 4 == 0 and year % 100 != 0) or (year % 4 == 0 and year % 400 == 0):
     31             return True
     32 
     33     def months(self, str1, str2):
     34         
     35         month1 = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
     36         month2 = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
     37         bdate = str1.split('/')
     38         bdate[0], bdate[1], bdate[2] = int(bdate[0]), int(bdate[1]), int(bdate[2])
     39         edate = str2.split('/')
     40         edate[0], edate[1], edate[2] = int(edate[0]), int(edate[1]), int(edate[2])
     41         
     42         if bdate == edate:
     43             return 0
     44         
     45         elif bdate[1] == edate[1] and bdate[2] == bdate[2]:
     46             return abs(bdate[0]-edate[0])
     47         
     48         elif bdate[1] != edate[1] and bdate[2] == edate[2]:
     49             bdays = 0
     50             edays = 0
     51             if self.years(bdate[2]):
     52                 for i in range(1, bdate[1]):
     53                     bdays += month2[i]
     54                 bdays = bdays + bdate[0]
     55                 for i in range(1, edate[1]):
     56                     edays += month2[i]
     57                 edays = edays + edate[0]
     58                 return abs(edays - bdays)
     59             else:
     60                 for i in range(1, bdate[1]):
     61                     bdays += month1[i]
     62                 bdays = bdays + bdate[0]
     63                 for i in range(1, edate[1]):
     64                     edays += month1[i]
     65                 edays = edays + edate[0]
     66                 return abs(edays - bdays)
     67             
     68         elif bdate[2] != edate[2]:
     69             days = 0
     70             for i in range(bdate[2]+1, edate[2]):
     71                 if self.years(i):
     72                     days += 366
     73                 else:
     74                     days += 365
     75             if self.years(bdate[2]):
     76                 for i in range(bdate[1]+1, 13):
     77                     days += month2[i]
     78                 days += (month2[bdate[1]]-bdate[0])
     79             else:
     80                 for i in range(bdate[1]+1, 13):
     81                     days += month1[i]
     82                 days += (month1[bdate[1] - bdate[0]])
     83             if self.years(edate[2]):
     84                 for i in range(1, edate[1]):
     85                     days += month2[i]
     86                 days += edate[0]
     87                 return days
     88             else:
     89                 for i in range(1, edate[1]):
     90                     days += month1[i]
     91                 days += edate[0]
     92                 return days
     93 
     94     def YTD(self, stock, newprice, newdate):
     95 
     96         holddays = self.months(stock.date, newdate)
     97         costmoney = stock.price * stock.amount
     98         curmoney = newprice * stock.amount
     99         benifit = curmoney - costmoney
    100         
    101         if stock.code in self.db:
    102             print('YTD of %s is %.2f %%' %(stock.code, benifit/holddays*365/costmoney))
    103         else:
    104             print('Stock %s does not exists' % stock.code)
    105 
    106     def showdb(self):
    107         print(self.db)
    108 
    109 s1 = Stock('xx', '123', '01/01/2019', 1.0, 1000)
    110 s2 = Stock('yy', '234', '05/01/2019', 18.0, 1000)
    111 op1 = Operator()
    112 op1.newcode(s1)
    113 op1.newcode(s2)
    114 op1.showdb()
    115 op1.popcode('234')
    116 op1.showdb()
    117 op1.YTD(s1, 1.01, '11/03/2019')

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

     1 import os
     2 
     3 class Shell(object):
     4 
     5     def __init__(self):
     6 
     7         self.cmddict = {'ls': 'dir', 'more': 'more', 'cat': 'type', 'cp': 'copy', 'mv': 'ren', 'rm': 'del'}
     8 
     9     def translate(self, cmd):
    10 
    11         opt = cmd.split()
    12         if opt[0] in self.cmddict:
    13             opt[0] = self.cmddict[opt[0]]
    14         return ' '.join(opt)
    15 
    16     def start(self):
    17 
    18         while True:
    19             cmd = input('#')
    20             cmd = self.translate(cmd)
    21             if cmd == 'exit':
    22                 break
    23 
    24             output = os.popen(cmd).readlines()
    25             for out in output:
    26                 print(out)
    27 
    28 if __name__ == '__main__':
    29     s = Shell()
    30     s.start()

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

     1 import os
     2 
     3 class CapOpen(object):
     4 
     5     def __init__(self, fn, mode='r', buf=-1):
     6         
     7         self.file = open(fn, mode, buf)
     8 
     9     def __str__(self):
    10         
    11         return str(self.file)
    12 
    13     def __repr__(self):
    14         
    15         return 'self.file'
    16 
    17     def write(self, line):
    18         
    19         self.file.write(line.upper())
    20 
    21     def writelines(self, lines, enter=False):
    22         
    23         for line in lines:
    24             if enter:
    25                 line += os.linesep
    26             self.write(line)
    27 
    28     def __getattr__(self, attr):
    29         
    30         return getattr(self.file, attr)
    31 
    32 if __name__ == '__main__':
    33     f1 = CapOpen('test.txt')
    34     lines = f1.readlines()
    35     f1.close()
    36 
    37     f2 = CapOpen('newtest.txt', 'w')
    38     f2.writelines(lines, False)
    39     f2.close()

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

     1 class MoneyFmt(float):
     2 
     3     def __new__(cls, value=0.0, flag='-'):
     4 
     5         cls.flag = flag
     6         cls.value = super(MoneyFmt, cls).__new__(cls, value)
     7         return cls.value
     8 
     9     def dollarize(cls):
    10         """转换"""
    11         val = round(cls.value, 2)
    12         strvalue = str(val)
    13         if strvalue.startswith('-'):
    14             strvalue = strvalue[1:]
    15             len = strvalue.find('.')
    16             while (len-3) > 0:
    17                 strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
    18                 len -= 3
    19             return cls.flag + '$' + strvalue
    20 
    21         len = strvalue.find('.')
    22         while (len-3) > 0:
    23             strvalue = strvalue[:len-3] + ',' + strvalue[len-3:]
    24             len -= 3
    25         return '$' + strvalue
    26 
    27     def __nonzero__(cls):
    28         "非零"
    29         if cls.value == 0:
    30             return False
    31         return True
    32 
    33     def __str__(cls):
    34 
    35         return cls.dollarize()
    36 
    37 
    38 if __name__ == '__main__':
    39     money = input('Money: ')
    40     moneyfmt = MoneyFmt(money)
    41     print(moneyfmt.dollarize())

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

     1 import time, shelve
     2 
     3 class Userdatabase(object):
     4 
     5     def __init__(self, dbfile):
     6         """创建数据库"""
     7         self.dbfile = dbfile
     8         self.db = shelve.open(self.dbfile, 'c')
     9         self.db.close()
    10 
    11     def newuser(self, user, pwd):
    12         """注册"""
    13 
    14         self.db = shelve.open(self.dbfile, 'r')
    15         if user in self.db:
    16             print("User already exists")
    17         self.db = shelve.open(self.dbfile, 'c')
    18         self.db[user] = [user, [pwd, time.time()], time.ctime()]
    19         self.db.close()
    20         self.flag = False
    21 
    22     def login(self, user, pwd):
    23         """登录"""
    24         self.db = shelve.open(self.dbfile, 'r')
    25         if user not in self.db:
    26             self.flag = False
    27         elif self.db[user][1][0] == pwd:
    28             if self.db[user][1][-1] - time.time() > 365*24*60*60:
    29                 print("Password has expired")
    30                 self.flag = False
    31             else:
    32                 self.flag = True
    33         self.db.close()
    34 
    35     def deluser(self, user):
    36         """删除"""
    37         self.db = {}
    38         if self.flag:
    39             self.db = shelve.open(self.dbfile, 'r')
    40             if user in self.db:
    41                 self.db.pop(user)
    42         else:
    43             print('login first')
    44 
    45     def updateuser(self, user, pwd):
    46         """更新密码"""
    47         newdb = {}
    48         if self.flag:
    49             self.db = shelve.open(self.dbfile, 'r')
    50             if pwd in self.db[user][1]:
    51                 print("The new password cannot be the same as the used password")
    52             else:
    53                 value = [user, self.db[user][1], time.ctime()]
    54                 value[1].insert(0, pwd)
    55                 value[1][-1] = time.time()
    56                 newdb[user] = value
    57                 self.db = shelve.open(self.dbfile, 'c')
    58                 self.db[user] = newdb[user]
    59                 print(self.db[user])
    60         else:
    61             print('login first')
    62 
    63 
    64     def listall(self):
    65         """查看"""
    66         if self.flag:
    67             for user in self.db:
    68                 print(self.db[user][0], self.db[user][1][0])
    69         else:
    70             print('login first')
    71 
    72 if __name__ == '__main__':
    73     user = Userdatabase('shelve.data')
    74     user.newuser('admin', '123456')
    75     user.newuser('test', '123456')
    76     user.login('admin', '123456')
    77     user.login('test', '123456')
    78     user.updateuser('admin', '123456')
    79     user.updateuser('test', '123456')
    80     user.listall()
    81     user.deluser('test')
    82     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进制的运算功能。

     1 class Time60(object):
     2     'Time60 - track hours and minutes'
     3 
     4     def __init__(self, *time):
     5         'Time60 constructor - takes hours and minutes'
     6         if len(time) == 1:
     7             if type(time[0]) == tuple:
     8                 self.hr = time[0][0]
     9                 self.min = time[0][1]
    10             elif type(time[0]) == dict:
    11                 self.hr = time[0]['hr']
    12                 self.min = time[0]['min']
    13             elif type(time[0]) == str:
    14                 all = time[0].split(':')
    15                 self.hr = int(all[0])
    16                 self.min = int(all[1])
    17 
    18         elif len(time) == 0:
    19             self.hr = 0
    20             self.min = 0
    21 
    22         else:
    23             self.hr = time[0]
    24             self.min = time[1]
    25 
    26     def __str__(self):
    27         'Time60 - string representation'
    28         return '%02d:%02d' % (self.hr, self.min)
    29 
    30     def __repr__(self):
    31 
    32         return repr('%02d:%02d' % (self.hr, self.min))
    33 
    34     def __add__(self, other):
    35         'Time60 - overloading the addition operator'
    36         hr = self.hr + other.hr
    37         min = self.min + other.min
    38         ahr = min // 60
    39         min %= 60
    40         hr += ahr
    41         if hr > 23: hr = 0
    42         return self.__class__(hr, min)
    43 
    44     def __iadd__(self, other):
    45         'Time60 - overloading in-place addition'
    46         self.hr += other.hr
    47         self.min += other.min
    48         return self
    49 
    50 print(Time60())
    51 print(Time60(10, 30))
    52 print(Time60("15:31"))
    53 print(Time60((10, 30)))
    54 print(Time60({'hr':11, 'min':15}))
    55 print(Time60(1, 5))
    56 print(Time60("15:31") + Time60(8,31))
  • 相关阅读:
    移动端拖拽
    原生js增加,移除类名
    js自执行函数
    页面加载初始化方法
    writing-mode,文字竖直书写,字符之间距离,单词之间距离
    滚动鼠标达到一点范围时的跑秒效果,从0开始一直加在规定时间内加到最大值
    haley解决中文字段名称字数不同时两端对齐的问题
    常用的一些css实现的小效果,比如三角形,小三角,阴影等
    html几个比较常用的颜色名称
    Spring--通过注解来配置bean
  • 原文地址:https://www.cnblogs.com/QQ269075164/p/10494188.html
Copyright © 2020-2023  润新知