1. 程式人生 > >python核心程式設計十三章練習

python核心程式設計十三章練習

13-2

#!/user/bin/env python
# -*- coding:utf-8 


class MoneyFmt(object):
    '''把函式dollarize轉換為一個類,並且包含以下的五個方法'''
    def __init__(self, value=0.0, default='-'):
        self.value = float(value)
        self.default = default

    def update(self, newvalue=None):
        self.value = newvalue

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

    # 相關說明參考13-3.py
    def __str__(self):
        try:
            fl = str(round(self.value, 2))
            if self.value < 0:
                fl = str(round(self.value, 2)).split('-')[1]
            dec = fl.split('.')[1]
            while len(dec) < 2:
                dec = dec + '0'
            fl2 = fl.split('.')[0] + '.' + dec
            fl2 = list(fl2)
            lens = len(fl2)
            i, j = 6, 0
            while lens > i:
                fl2.insert(-i-j, ',')
                i += 3
                j += 1
            if self.value < 0:
                if self.default is not '-':
                    self.default = '<->'
                return self.default + '$' + ''.join(fl2)
            else:
                return '$' + ''.join(fl2)

        except (TypeError, ValueError):
            return 'Input should be a number'

        def __nonzero__(self):
            return int(self.value)


moneyfmt = MoneyFmt(-121234567.8991)
print moneyfmt
print moneyfmt.__repr__
print MoneyFmt(-121234567.8991,'o')
print bool(MoneyFmt(-121234567.8991))
moneyfmt.update(0.5)
print moneyfmt
13-3
#!/user/bin/env python
# -*- coding:utf-8

def dollarize(num):
    '''編寫一個dollarize()函式,它以一個浮點型值作為輸入,返回一個字串形式的金額'''
    try:
        fl = str(round(num, 2))  # 先對輸入的數值取兩位小數,並轉換為字串
        # 因為round函式的特性,在0.899時無法保留兩位數值,所以取小數部分,判斷小數位數,補全兩位小數
        if num < 0:
            fl = str(round(num, 2)).split('-')[1]
        dec = fl.split('.')[1]  # 小數部分
        while len(dec) < 2:
            dec = dec + '0'
        fl2 = fl.split('.')[0] + '.' + dec  # 對分離部分進行組合
        fl2 = list(fl2)
        lens = len(fl2)
        i, j = 6, 0  # i表示從倒數第六位開始,三位加一個逗號;j則表示插入逗號的個數
        # 根據輸入數字的長度,判斷是否要加逗號,從倒數第六位開始,三位加一個逗號,因為插入都要影響原來排序,所以要對此進行計數j
        while lens > i:
            fl2.insert(-i-j, ',')
            i += 3
            j += 1
        # 若輸入為負數則在$前面加入負號
        if num < 0:
            return '-' + '$' + ''.join(fl2)
        else:
            return '$' + ''.join(fl2)

    except (TypeError, ValueError):
        return 'Input should be a number'


print dollarize(1234567.8901)
print dollarize(-121234567.8991)
print dollarize(1234567)
print dollarize('lit')
13-4
#!/user/bin/env python
# -*- coding:utf-8

import time, getpass, hashlib, shelve


class UserDatabase(object):
    def __init__(self, fn):
        self.db = shelve.open(fn)

    def __del__(self):
        self.db.close()

    def recive(self, prompt=None, flag=True):
        try:
            if flag:
                reciver = raw_input(prompt).strip().lower()
            else:
                reciver = getpass.getpass()
        except (KeyboardInterrupt, EOFError):
            reciver = 'System quit!'
        return reciver

    def sigup(self):
        while True:
            user = self.recive('Sigup: ')
            if user in self.db:
                print 'Username taken, try another!'
                continue
            elif not user.isalnum() or ' ' in user:
                print 'Invalid username!'
                continue
            else:
                break
        psw = self.recive(flag=False)
        timeNow = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        self.db[user] = hashlib.md5(psw).hexdigest(), timeNow
        print '>You has already sigup, return to login page.>>>'

    def login(self):
        while True:
            user = self.recive('Login: ')
            psw = self.recive(flag=False)
            if (user in self.db and
                    self.db.get(user)[0] == hashlib.md5(psw).hexdigest()):
                break
            else:
                print 'Password or username is not right, try again.'
                continue
        timeNow = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        self.db[user] = hashlib.md5(psw).hexdigest(), timeNow
        diffTime = float(time.time() - time.mktime(time.strptime(self.db[user][1],'%Y-%m-%d %H:%M:%S'))) / 3600
        if diffTime <= 4:
            print 'You already logged in at: ', self.db[user][1]
        print '>***Welcome, %s!***' % user

    def admin(self):
        choice = raw_input('del a user or show all users: ').strip()[0].lower()
        if choice == 'd':
            user = self.recive('Username: ')
            if user in self.db:
                del self.db[user]
                print 'Remove %s ... Done!' % user
            else:
                print 'User has no name: %s ' % user
        elif choice == 's':
            for user in self.db:
                print user
        else:
            print 'Invalid input!'

    def updatepsw(self):
        user = self.recive('Username: ')
        if user in self.db:
            psw = self.recive(flag=False)
            self.db[user] = psw
        else:
            print 'Username error!'


def start():
    # 展示你可以輸入的標語
    prompt = """
    (S)igup
    (L)ogin
    (A)dmin
    (Q)uit
    >Enter your choice: """
    # 是否要跳出迴圈
    done = False

    while not done:
        # 是否要跳出選擇
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice
            if choice not in 'slaq':
                print '>Invalid option, try again!'
            else:
                chosen = True

        if choice == 'q':
            done = True
        if choice == 's':
            user_database.sigup()
        if choice == 'a':
            user_database.admin()
        if choice == 'l':
            user_database.login()

if __name__ == '__main__':
    user_database = UserDatabase('userpw2.shelve')
    start()
13-5
#!/user/bin/env python
# -*- coding:utf-8 


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

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

point = Point()
print point
point = Point(3, 4)
print point

13-6
#!/user/bin/env python
# -*- coding:utf-8 

import math

class LineSegment(object):
    def __init__(self, x1=0, y1=0, x2=0, y2=0):
        self.x1 = x1
        self.x2 = x2
        self.y1 = y1
        self.y2 = y2

    def __str__(self):
        return '(%s, %s), (%s, %s)' % (self.x1, self.y1, self.x2, self.y2)

    __repr__ = __str__

    def length(self):
        self.leng1 = self.y2 - self.y1
        self.leng2 = self.x2 - self.x1
        leng = math.sqrt(self.leng1 ** 2 + self.leng2 ** 2)
        return round(leng, 2)

    def slope(self):
        k = self.leng1 / self.leng2
        return round(k, 2)

line = LineSegment(1, 2, 3, 4)
print line
print line.length()
print line.slope()
13-7
#!/user/bin/env python
# -*- coding:utf-8 

import time
from datetime import date


class TimeFmt(object):
    today = date.today().timetuple()
    # 設定預設值為今天
    def __init__(self, year=today[0], mon=today[1], day=today[2], fmt=None):
        self.year = year
        self.mon = mon
        self.day = day
        self.fmt = fmt

    def update(self, year, mon, day):
        self.year = year
        self.mon = mon
        self.day = day

    def display(self):
        # 為了顯示YY需要對年進行切片處理
        year = str(self.year)[-2:]
        mon = self.mon
        day = self.day
        # 假如輸入的月份和天為個位,則補充零
        if self.mon < 10:
            mon = '0' + str(self.mon)
        if self.day < 10:
            day = '0' + str(self.day)
        if self.fmt == 'MDY':
            return '%s/%s/%s' % (mon, day, year)
        elif self.fmt == 'MDYY':
            return '%s/%s/%s' % (mon, day, self.year)
        elif self.fmt == 'DMY':
            return '%s/%s/%s' % (day, mon, year)
        elif self.fmt == 'DMYY':
            return '%s/%s/%s' % (day, mon, self.year)
        elif self.fmt == 'MODYY':
            return '%s %s, %s' % (day, mon, self.year)
        else:
            return time.ctime()

timefmt = TimeFmt(2015, 6, 13, 'DMYY')
print timefmt.display()
timefmt.update(2011, 10, 2)
print timefmt.display()
13-8
#!/user/bin/env python
# -*- coding:utf-8


class Stack(object):
    def __init__(self, stack=[]):
        self.stack = stack

    def __str__(self):
        return '%s' % self.stack

    __repr__ = __str__

    def push(self, item):
        self.stack.append(item)  # add an item to the stack

    def pop(self):
        self.stack.pop()  # remove an item from the stack

    def isempty(self):
        # Boolean method
        if self.stack == []:
            return True
        else:
            return False

    def peek(self):
        # returns the item at the top of the stack without popping it off
        return self.stack[-1]

13-9
#!/user/bin/env python
# -*- coding:utf-8


class Queue(object):
    def __init__(self, queue=[]):
        self.queue = queue

    def __str__(self):
        return '%s' % self.queue

    __repr__ = __str__

    def enqueue(self, element):
        self.queue.append(element)

    def dequeue(self):
        return self.queue.pop(0)

13-10
#!/user/bin/env python
# -*- coding:utf-8


class StacksAndQueues(object):
    def __init__(self, arr=[]):
        self.arr = arr

    def __str__(self):
        return '%s' % self.arr

    __repr__ = __str__

    def shift(self):
        '''returns the first element and removes it from the list.'''
        return self.arr.pop(0)

    def unshift(self, element):
        '''"pushes" a new element to the front or head of the list'''
        self.arr.insert(0, element)

    def push(self, element):
        '''adds a new element to the end of a list'''
        self.arr.append(element)

    def pop(self):
        '''returns the last element and removes it from the list'''
        return self.arr.pop()

13-11
#!/user/bin/env python
# -*- coding:utf-8

'''Items go in Carts, and Users can have multiple Carts. Also, multiple
   items can go into Carts, including more than one of any single item.'''


class User(object):
    carts = []
    print carts
    def buy(self, item):
        return Cart(item)


class Item:
    def __init__(self, item):
        self.item = item


class Cart:
    def __init__(self, item):
        self.items = []
        self.items.append(item)
        print self.items


banana = Item('banana')
apple = Item('apple')
orange = Item('orange')


mike = User()
mike.buy(banana)
mike.buy(apple)
mike.buy(orange)
mike.carts = Cart(banana)

print mike
13-12
#!/user/bin/env python
# -*- coding:utf-8


class Message(object):
    '''containing a message string and any additional information,
    such as broadcast or single recipient'''
    def __init__(self, fr, to, info):
        self.fr = fr
        self.to = to
        self.info = info

    def fr(self):
        return self.fr

    def to(self):
        return self.to

    def info(self):
        return self.info



class User(object):
    '''contains all the information for a persion entering your chat rooms'''
    def __init__(self, username, sex):
        self.username = username
        self.sex = sex

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

    __repr__ = __str__

    def send(self, room, to, info):
        message = Message(self.username, to, info)
        return room.reciver(message)

    def quit_room(self, room):
        return room.quit(self.username)

    def create_room(self, roomname):
        return Room(roomname, self.username)


class Room(object):
    '''users can create separate 'room' within the chat area and
    invite others to join'''
    def __init__(self, roomname, creator):
        self.roomname = roomname
        self.users = []
        self.users.append(creator)

    def __str__(self):
        return '%s: create by %s, members: %s' % \
            (self.roomname, self.users[0], ' '.join(self.users))

    __repr__ = __str__

    def invite(self, user):
        self.user = user
        self.users.append(user.username)
        print '%s has been invited.' % user.username

    def reciver(self, message):
        if message.fr in self.users:
            if message.to in self.users:
                print '%[email protected]%s:%s' % (message.fr, message.to, message.info)
            elif message.to == 'all':
                print '%[email protected]%s:%s' % (message.fr, message.to, message.info)
            else:
                print '%s is not in this room' % message.to
        else:
            print 'You are not in this room'
    def quit(self, username):
        try:
            self.users.remove(username)
            print '%s has quit.' % username
        except ValueError:
            print 'You are not in this room'
13-13
#!/user/bin/env python
# -*- coding:utf-8

import time, json


db = {300059:[u'東方財富', 'Wes Jul 13 15:15:12 2016', 22.43, 1000]}
db_json = json.dumps(db, ensure_ascii=False)


class bond(object):
    def add(self, code, arr):
        db_json[code] = arr

    def dele(self, code):
        if code in db_json:
            print '%s sold out.' % code
            del db_json[code]
        else:
            print 'No such stock code'
13-14
#!/user/bin/env python
# -*- coding:utf-8

import os
import subprocess


class UnixCmd(object):
    def __cd__(self, path):
        self.redirect_stdout('cd', path)

    def __ls__(self):
        self.redirect_stdout('dir', os.getcwd())

    def __cat__(self, fname):
        self.redirect_stdout('type', fname)

    def __cp__(self, fname, path):
        self.redirect_stdout('copy', fname, path)

    def __mv__(self, org_name, new_name):
        self.redirect_stdout('ren', org_name, new_name)

    def __rm__(self, fname):
        self.redirect_stdout('del', fname)

    def __more__(self, fname):
        self.redirect_stdout('more', fname)

    @staticmethod
    def redirect_stdout(cmd, *path):
        line = 0
        fp = subprocess.Popen([cmd, path], stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT, shell=True)
        for eachline in fp.stdout:
            line += 1
            print eachline.strip('\r\n')
            if line >= 32:
                raw_input('-more-')


def shell():
    cmd = UnixCmd()
    sh_cmd = {'cd': cmd.__cd__, 'ls': cmd.__ls__, 'cat': cmd.__cat__,
              'cp': cmd.__cp__, 'mv': cmd.__mv__, 'rm': cmd.__rm__,
              'more': cmd.__more__}
    while True:
        msg = raw_input('[%s:]$' % os.name).strip()
        sh = msg.split(' ')
        if sh[0] not in sh_cmd.keys():
            print 'Invalid command.'
            continue
        if msg == 'ls':
            sh_cmd[msg]()
            continue
        # 如果只輸入了一個命令,沒有path或者filename且不為ls命令,則預設在後面加多一個空位鍵補充,防止超出列表錯誤
        if len(sh) < 2:
            sh.append('')
        if sh[0] in ['cd', 'cat', 'rm', 'more']:
            sh_cmd[sh[0]](sh[1])
            continue
        if len[sh] < 3:
            sh.append('')
        if sh[0] in ['mv', 'cp']:
            sh_cmd[sh[0]](sh[1], sh[2])
        if sh[0] == 'exit':
            break



shell()

13-16
#!/user/bin/env python
# -*- coding:utf-8


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)

    __repr__ = __str__

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

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

    def __getattr__(self, attr):
        return getattr(self.file, attr)

13-17
#!/user/bin/env python
# -*- coding:utf-8 


class RoundFloat(float):
    def __new__(cls, value):
        return super(RoundFloat, cls).__new__(cls, round(value, 2))


class MoneyFmt(object):
    '''把函式dollarize轉換為一個類,並且包含以下的五個方法'''
    def __init__(self, value=0.0, default='-'):
        self.value = float(value)
        self.default = default

    def update(self, newvalue=None):
        self.value = newvalue

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

    # 相關說明參考13-3.py
    def __str__(self):
        try:
            fl = str(RoundFloat(self.value))
            if self.value < 0:
                fl = str(RoundFloat(self.value)).split('-')[1]
            dec = fl.split('.')[1]
            while len(dec) < 2:
                dec = dec + '0'
            fl2 = fl.split('.')[0] + '.' + dec
            fl2 = list(fl2)
            lens = len(fl2)
            i, j = 6, 0
            while lens > i:
                fl2.insert(-i-j, ',')
                i += 3
                j += 1
            if self.value < 0:
                if self.default is not '-':
                    self.default = '<->'
                return self.default + '$' + ''.join(fl2)
            else:
                return '$' + ''.join(fl2)

        except (TypeError, ValueError):
            return 'Input should be a number'

        def __nonzero__(self):
            return int(self.value)
13-18
#!/user/bin/env python
# -*- coding:utf-8

import time, getpass, hashlib, shelve


class UserDatabase(object):
    def __init__(self, fn):
        self.db = shelve.open(fn)

    def __del__(self):
        self.db.close()

    def recive(self, prompt=None, flag=True):
        try:
            if flag:
                reciver = raw_input(prompt).strip().lower()
            else:
                reciver = getpass.getpass()
        except (KeyboardInterrupt, EOFError):
            reciver = 'System quit!'
        return reciver

    def sigup(self):
        while True:
            user = self.recive('Sigup: ')
            if user in self.db:
                print 'Username taken, try another!'
                continue
            elif not user.isalnum() or ' ' in user:
                print 'Invalid username!'
                continue
            else:
                break
        psw = self.recive(flag=False)
        timeNow = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        self.db[user] = hashlib.md5(psw).hexdigest(), timeNow
        print '>You has already sigup, return to login page.>>>'

    def login(self):
        while True:
            user = self.recive('Login: ')
            psw = self.recive(flag=False)
            if (user in self.db and
                    self.db.get(user)[0] == hashlib.md5(psw).hexdigest()):
                break
            else:
                print 'Password or username is not right, try again.'
                continue
        timeNow = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        self.db[user] = hashlib.md5(psw).hexdigest(), timeNow
        diffTime = float(time.time() - time.mktime(time.strptime(self.db[user][1],'%Y-%m-%d %H:%M:%S'))) / 3600
        if diffTime <= 4:
            print 'You already logged in at: ', self.db[user][1]
        print '>***Welcome, %s!***' % user

    def admin(self):
        choice = raw_input('del a user or show all users: ').strip()[0].lower()
        if choice == 'd':
            user = self.recive('Username: ')
            if user in self.db:
                del self.db[user]
                print 'Remove %s ... Done!' % user
            else:
                print 'User has no name: %s ' % user
        elif choice == 's':
            for user in self.db:
                print user
        else:
            print 'Invalid input!'

    def updatepsw(self):
        user = self.recive('Username: ')
        if user in self.db:
            psw = self.recive(flag=False)
            self.db[user] = psw
        else:
            print 'Username error!'


def start():
    # 展示你可以輸入的標語
    prompt = """
    (S)igup
    (L)ogin
    (A)dmin
    (Q)uit
    >Enter your choice: """
    # 是否要跳出迴圈
    done = False

    while not done:
        # 是否要跳出選擇
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice
            if choice not in 'slaq':
                print '>Invalid option, try again!'
            else:
                chosen = True

        if choice == 'q':
            done = True
        if choice == 's':
            user_database.sigup()
        if choice == 'a':
            user_database.admin()
        if choice == 'l':
            user_database.login()

if __name__ == '__main__':
    user_database = UserDatabase('userpw2.shelve')
    start()

13-19
class SortedKeyDict(dict):
    def key(self):
        return sorted(self.keys())

d = SortedKeyDict((('zheng-cai', 67), ('hui-jun', 68), ('xin-yi', 2)))
print 'By iterator:'.ljust(12), [key for key in d]
print 'By keys():'.ljust(12), d.key()

13-20
#!/user/bin/env python
# -*- coding:utf-8


class Time60(object):
    def __init__(self, *val):
        if isinstance(val[0], str):
            self.hr = int(val[0].split(':')[0])
            self.mi = int(val[0].split(':')[1])
        elif isinstance(val[0], dict):
                self.hr = val[0]['hr']
                self.mi = val[0]['min']
        elif isinstance(val[0], tuple):
            self.hr = val[0][0]
            self.mi = val[0][1]
        elif isinstance(val[0], int):
            self.hr = val[0]
            self.mi = val[1]
        else:
            self.hr = 0
            self.mi = 0

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

    __repr__ = __str__

    def __add__(self, other):
        return self.__class__(self.hr + other.hr,
                              self.mi + other.mi)

    def __iadd__(self, other):
        self.hr += other.hr
        self.mi += other.mi
        return self


相關推薦

no