python核心编程2 第13章 练习

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', '123456')
    user.login('admin', '123456')
    user.updateuser('admin', '123456')
    user.updateuser('test', '123456')
    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', '123', '01/01/2019', 1.0, 1000)
s2 = Stock('yy', '234', '05/01/2019', 18.0, 1000)
op1 = Operator()
op1.newcode(s1)
op1.newcode(s2)
op1.showdb()
op1.popcode('234')
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', '123456')
    user.newuser('test', '123456')
    user.login('admin', '123456')
    user.login('test', '123456')
    user.updateuser('admin', '123456')
    user.updateuser('test', '123456')
    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))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值