13.
大概写了下设想的样式,stock函数中的价格,应该由市场来调用,每日更改。这个地方设成定值,就没写程序验证了。
核心在于用户再去调用当时保存的stock类时,price已经改变就有了利润。
stack类只应该是和这只股票相关的数据。股票当日价格,股票名字,股票id
mystack应保存,用户选的股票,买入的价格,日期,数量这些和股票本身无关的信息
还应该有一个大的类用于更新股票价格。类似市场类
#股票应有一个市场价格,每日变动,这个地方我设成定值3.0
class stock(object):
price = 3.0
def __init__(self,name,id):
self.name = name
self.id = id
#数据库应该记录的是某个用户手里的股票
class mystock(object):
db = []
lirun = 0.0
def add(self,name,id,date,number):
st = stock(name,id)
price = st.price
li = [st,price,date,number]
self.db.append(li)
def sub(self,name,subnum):
for i in self.db:
if i[0].name == name:
i[3] = i[3]-subnum
#获取当前价格,与当时买的价格差价就是利润
self.lirun = (i[0].price - i[1])*subnum + self.lirun
#删除数量为0的股票
def delstock(self):
for i in self.db:
if i[3] == 0 :
self.db.remove(i)
14.
写一个shell 的意思就是,输入的是unix的命令,但是要在DOS的环境下达到该命令想要的效果。
参考了一下网上的答案,在注释部分做了修改,更直接的应该是用os.system就直接对转换过的unix命令进行执行即可
# -*- coding: utf-8 -*-
import os
class Shell(object):
def __init__(self):
self.cmds = {'ls':'dir','more':'more','cat':'type','cp':'copy','mv':'ren','rm':'del'}
def translate(self,cmd):
opt = cmd.split()
if opt[0] in self.cmds:
opt[0] = self.cmds[opt[0]]
return ' '.join(opt)
def start(self):
while 1:
cmd = raw_input('#')
cmd = self.translate(cmd)
if cmd == 'exit':
break
else:
#原博客用的os.popen函数,不是很理解
os.system(cmd)
if __name__ == '__main__':
s = Shell()
s.start()
15.
两者是没有差别的,因为在CapOpen中没有覆盖readlines方法。还是调用的file对象提供的。
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 __getattr__(self, item):
return getattr(self.file,item)
if __name__ == '__main__':
f = CapOpen('ar.txt','r')
print f
lines = f.readlines()
for i in lines:
print i,
f.close()
g = open('ar.txt','r')
print g
lines = g.readlines()
for j in lines:
print j,
g.close()
测试输出
<open file 'ar.txt', mode 'r' at 0x00F9D1D8>
Cnna:2828,2017 09 13 10 00
Anna:2727,2017 09 13 10 00
Bnna:23214,21214
<open file 'ar.txt', mode 'r' at 0x00F9DF40>
Cnna:2828,2017 09 13 10 00
Anna:2727,2017 09 13 10 00
Bnna:23214,21214
16.
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 __getattr__(self, item):
return getattr(self.file,item)
def writelines(self,list,index = False):
#根据换行标记来设置每行结束是否写换行符
if index == False:
tem = ' '
else:
tem = '\n'
for i in list:
self.file.write(i.upper())
self.file.write(tem)
if __name__ == '__main__':
#用列表表示一下多行数据
lines = ['line1','line2','line3','line4']
f = CapOpen('ar.txt','w')
f.writelines(lines)
17.
看网上答案应该是生成一个float类型的子类
没那样写,在moneyfmt.py的基础上改的
在pycharm下运行的,有些就没调试了。
str可以控制 str()以及print语句
repr可以控制repr()和”操作符
比较需要注意的是小数的保留两位并四舍五入的问题。
网上普遍说的round函数和decimal来处理都有问题,这个地方是用的二进制模拟十进制方法来完成的四舍五入。这个处理麻烦了,但是暂时是唯一正确的一种。这种方法需要补充代码,下面写的只是4位小数保留两位的情况。
# -*- coding: utf-8 -*-
from __future__ import division
class MoneyFmt(object):
def __init__(self,value):
self.value = float(value)
def update(self,value = None):
st = str(value)
index = st.index('.')
st1 = st[:index]
st2 = st[index + 1:]
st3 = st1 + st2
st4 = st3[:-2]
# print st3, st4
yu = int(st3) % 100
if yu >= 5:
sang = int(st4) + 1
else:
sang = int(st4)
re = sang * 10 / 1000
self.value = re
return self.value
def __repr__(self):
return '\''+str(self.value)+'\''
def __str__(self):
if self.value>=0:
val = '$'
val = val + str(self.value)
else:
val = '-$'
val = val + str(self.value)[1:]
return val
def __nonzero__(self):
if self.value == 0:
return False
else:
return True
if __name__ == '__main__':
cash = MoneyFmt(-123.45)
18.
网上答案是生成一个list类型的子类
这里我是生成了13-4自己写的类的子类来做的
这段代码只写了逻辑,没测试运行了,写的不是很完善。
生成了个userdb的子类,子类中有个方法可以修改用户密码。
用户密码进行了保存,数据格式{name:[[passwd,time],[…]]}需要判断时去遍历读取。
判断相似只判断了用户是否只更改了密码的大小写,想到的比较严谨的是使用余弦向量对文本进行判断。
# -*- coding: utf-8 -*-
import time
class userdb(object):
db = {}
psdb = {}
index = False
#初始化时加载文件信息,这个地方严格来说也要加载一个passwd的数据进来
#感觉自己的算法写的不是很好,就不实现这个了
def __init__(self):
f = open('ar.txt','r')
lines = f.readlines()
f.close()
for line in lines:
#split返回的是list
st1 = line.split(':')
st2 = st1[1].split(',')
name = st1[0]
paswd = int(st2[0])
time = st2[1].strip()
li = []
li.append(paswd)
li.append(time)
self.db[name] = li
# for i in self.db:
# print i,self.db[i]
#登录
def login(self,name,paswd):
if self.db[name][0] == paswd:
#判断密码是否过期
li = self.psdb[name]
for i in li:
if i[0] == paswd :
if time.localtime() - i[1]>12*30*24*60*60:
print 'passwd out of time'
break
else:
print 'your last time login:',self.db[name][1]
self.db[name][1] = time.strftime("%Y %m %d %H %M", time.localtime())
self.index = True
else:
print 'login fail'
#添加
def adduser(self,newname,newpaswd):
if self.index == True:
ti = time.strftime("%Y %m %d %H %M", time.localtime())
li = []
li.append(newpaswd)
li.append(ti)
self.db[newname] = li
#这个密码的初始时间
self.psdb[newname] = [[newpaswd,time.localtime()]]
else:
print 'you have not login in'
def __del__(self):
f = open('ar.txt','w')
for keys in self.db:
st = keys+':'+str(self.db[keys][0])+','+self.db[keys][1]
# print st
f.write(st)
f.write('\n')
f.close()
class changePd(userdb):
def __init__(self,uname):
userdb.__init__(self)
self.uname = uname
def pdchange(self,newpd):
#相似这里就判断一下是否只改了大小写,认真写的话可以用相似度来判断一下,例如余弦向量什么的
li = self.psdb[self.uname]
#只要没有break就会执行else里面的内容
for i in li:
#当两个密码相似且时间间隔不到一年
if i[0].upper() == newpd.upper() and time.localtime() - i[1] < 12*30*24*60*60:
print 'similar passwd in one year'
break
else:
self.db[self.uname][0] = newpd
self.savefile()
def savefile(self):
f = open('ar.txt', 'w')
for keys in self.db:
st = keys+':'+str(self.db[keys][0])+','+self.db[keys][1]
# print st
f.write(st)
f.write('\n')
f.close()
if __name__ =='__main__':
user = changePd('Anna')
user.pdchange('2132')
olduser = userdb()
19.
会陷入无限循环里面,因为重写了.keys方法, self.keys会首先调用子类的.keys方法,而子类的.keys方法中又调用了自己,形成了循环。这个地方必须申明调用父类的.keys方法才能取到键的值
python2.7版本里,super方法是只能用于新类的,在继承标准类时使用会出错。使用dict.keys(),即直接使用名字调用也会出错。
暂时没有找到子类同名函数中调用父类为标准类的方法,可能是版本不够的问题。
# -*- coding: utf-8 -*-
class mydic(dict):
def skeys(self):
return sorted(self.keys())
if __name__ =='__main__':
mydic = mydic((('zheng',23),('hui',32),('xin',56)))
print 'By itertor:'.ljust(12),[key for key in mydic]
print mydic.skeys()
20.
radd方法不用在这里实现,它是一个自定义的类操作符,作用是在a+b时(a,b都是实例),当a中没有定义add方法时,就在b中找radd操作符
add定义该类实例的加法(a+b中的a)
iadd定义该实例用于自加语法时的操作方法 a += b
# -*- coding: utf-8 -*-
class Time60(object):
def __init__(self,*rest):
#输入的是这几种特殊的
if len(rest) == 1:
#注意这里rest已经是一个tuple类型
if type(rest[0]) == tuple:
self.hr = rest[0][0]
self.min = rest[0][1]
elif type(rest[0]) == dict:
self.hr = rest[0]['hr']
self.min = rest[0]['min']
elif type(rest[0]) == str:
index = rest[0].index(':')
self.hr = int(rest[0][:index])
self.min = int(rest[0][index+1:])
#无输入
elif len(rest) == 0:
self.hr = 0
self.min = 0
#正常输入
else:
self.hr = rest[0]
self.min = rest[1]
def __str__(self):
#2位,不足时以0占位
return '%02d:%02d' % (self.hr,self.min)
def __repr__(self):
return repr('%02d:%02d' % (self.hr,self.min))
def __add__(self, other):
hr = self.hr + other.hr
min = self.min + self.min
if min >=60:
min = min - 60
hr = hr + 1
return self.__class__(hr,min)
def __iadd__(self, other):
self.hr += other.hr
self.min += other.min
if self.min>=60:
self.min = self.min -60
self.hr =self.hr+1
return self
if __name__ =='__main__':
# ti = Time60(12,5)
ti1 = Time60((10,30))
ti2 = Time60({'hr':10,'min':30})
ti3 = Time60('10:5')
# print ti
print ti1
print ti2
print ti3
print ti1+ti2
ti1 += ti2
print ti1
21.
装饰器的语法:
@deco
def foo():pass
foo = deco(foo)
x = property(x)
x = property(**x()) 不是很能理解,按装饰器翻译过来应该是上面那句。