Size: 29120
Comment:
|
Size: 28971
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 14: | Line 14: |
'''cdays-5-exercise-1.py this year is a leap year or not | '''cdays-5-exercise-1.py 判断今年是否是闰年 |
Line 30: | Line 30: |
'''cdays-5-exercise-2.py basic operation and math library | '''cdays-5-exercise-2.py 基本表达式运算及使用math模块 |
Line 57: | Line 57: |
'''cdays-5-exercise-3.py print out and for expression | '''cdays-5-exercise-3.py for语句的使用 |
Line 131: | Line 131: |
'''cdays-4-exercise-6.py file operation | '''cdays-4-exercise-6.py 文件操作 |
Line 203: | Line 203: |
Line 209: | Line 208: |
'''cdays-3-exercise-2.py using sys.args, dict and function invoke | '''cdays-3-exercise-2.py 使用sys.args, dict和函数调用 |
Line 215: | Line 214: |
''' function collect: change the key-value to value-key @param file: file object @return: a dict type, get the value-key pairs |
''' 改变 key-value对为value-key对 @param file: 文件对象 @return: 一个dict包含value-key对 |
Line 248: | Line 247: |
'''cdays-3-exercise-3.py using global varibles, invoke function recursively | '''cdays-3-exercise-3.py 使用全局变量和函数递归调用 |
Line 258: | Line 257: |
''' function output: print out one state | ''' 输出一种有效结果 |
Line 265: | Line 264: |
''' function do_queen: generate all states of queens' position @param i: the number of queen |
''' 生成所有正确解 @param i: 皇后的数目 |
Line 371: | Line 370: |
'''cdays-2-exercise-2.py using class and object | '''cdays-2-exercise-2.py 类和对象的使用 |
Line 376: | Line 375: |
user-defined stack, has basic stack operations, such as put(), get() and isEmpty() | 自定义栈,主要操作有put(), get() and isEmpty() |
Line 380: | Line 379: |
init the stack: the head of stack and empty the stack @param max: specify the max length of stack |
初始化栈:初始栈头指针和清空栈 @param max: 指定栈的最大长度 |
Line 391: | Line 390: |
put item into the stack @param item: anything want to put the current stack |
将item压入栈中 @param item: 所要入栈的项 |
Line 405: | Line 404: |
get the top item of current stack @return: the top item |
获得当前栈顶item @return: 栈顶item |
Line 419: | Line 418: |
get the state of current stack @return: True(the stack is empty) or False(else) |
获得当前栈的状态,空或者非空 @return: True(栈空) or False(栈非空) |
Line 445: | Line 444: |
'''cdays-1-exercise-1.py using chardet and urllib2 | '''cdays-1-exercise-1.py 使用chardet和urllib2 |
Line 454: | Line 453: |
detect the coding of blog @param blogurl: some url string |
检测blog的编码方式 @param blogurl: 要检测blog的url |
Line 479: | Line 478: |
Line 485: | Line 483: |
'''cdays-1-exercise-2.py using chardet, urllib2 | '''cdays-1-exercise-2.py 熟悉chardet和urllib2 |
Line 493: | Line 491: |
detect the coding of blog and save the blog in utf-8 @param blogurl: some url string |
检测blog的编码方式 @param blogurl: 要检测blog的url |
Line 529: | Line 527: |
Line 569: | Line 566: |
'''cdays+1-exercise-1.py using os.stat | '''cdays+1-exercise-1.py 使用os.stat获取相关信息 |
Line 575: | Line 572: |
''' get the three big size of files in the path @param path: specify the files of path @return one list contains item like (size, filename) |
''' 获取给定路径中文件大小最大的三个 @param path: 指定路径 @return 返回一个list,每项为 (size, filename) |
Line 622: | Line 619: |
'''cdays+1-exercise-2.py using ConfigParser | '''cdays+1-exercise-2.py 使用ConfigParser解析 |
Line 646: | Line 643: |
''' get the three big size of files in the path @param path: specify the files of path @return one list contains item like (size, filename) |
''' 获取给定路径中文件大小最大的三个 @param path: 指定路径 @return 返回一个list,每项为 (size, filename) |
Line 697: | Line 694: |
Line 699: | Line 695: |
Line 701: | Line 696: |
Line 703: | Line 697: |
Line 720: | Line 713: |
import pickle # 神奇的序列化模块 | import pickle # 神奇的序列化模块 |
Line 781: | Line 774: |
Line 791: | Line 783: |
'''cdays+3-exercise-1.py using Thread and RLock | '''cdays+3-exercise-1.py 使用Thread和RLock实现简单线程同步 |
Line 799: | Line 791: |
user-defined thread | 自定义的线程,多个线程共同访问一个变量 |
Line 827: | Line 819: |
Line 833: | Line 824: |
'''cdays+3-exercise-2.py using Thread and Queue @author: U{shengyan<mailto:[email protected]>} @version:$Id$ |
'''cdays+3-exercise-2.py 使用Thread和Queue保持多线程间同步 |
Line 842: | Line 831: |
'''Input Thread: read one string from stdio, then add this string into queue | '''输入线程: 从标准输入中读一个string,然后把该string加入到queue |
Line 856: | Line 845: |
'''Output Thread: read one string from queue, then print it out | '''输出线程:从queue中得到一个string,并将它输出到屏幕 |
Line 887: | Line 876: |
Line 893: | Line 881: |
'''cdays+3-exercise-3.py using Thread and Event | '''cdays+3-exercise-3.py 使用Thread和Event实现简单的线程通信 |
Line 901: | Line 889: |
user-defined thread | 自定义线程 |
status |
校对 |
完成度70% |
1. 故事练习解答
1.1. CDays
1.1.1. CDays-5
- 计算今年是闰年嘛?
1 #coding:utf-8
2 '''cdays-5-exercise-1.py 判断今年是否是闰年
3 '''
4 #导入time模块
5 import time
6 #获取当前年份
7 thisyear = time.localtime()[0]
8 #判断闰年条件,满足模400为0,或者模4为0但模100不为0
9 if thisyear % 400 == 0 or thisyear % 4 ==0 and thisyear % 100 <> 0:
10 print 'this year %s is a leap year' % thisyear
11 else:
12 print 'this year %s is not a leap year' % thisyear
利用python作为科学计算器。熟悉Python中的常用运算符,并分别求出表达式12*34+78-132/6、(12*(34+78)-132)/6、(8.6/4)**5的值。并利用math模块进行数学计算,分别求出145/23的余数,0.5的sin和cos值等等,详细可参考help(math)。
1 #coding:utf-8
2 '''cdays-5-exercise-2.py 基本表达式运算及使用math模块
3 '''
4 #表达式计算
5 x = 12*34+78-132/6
6 y = (12*(34+78)-132)/6
7 z = (8.6/4)**5
8 print '12*34+78-132/6 = %d' % x
9 print '(12*(34+78)-132)/6 = %d' % y
10 print '(8.6/4)**5 = %f' % z
11 #导入数学计算模块
12 import math
13 #求余函数
14 a = math.fmod(145, 23)
15 #正弦函数
16 b = math.sin(0.5)
17 #余弦函数
18 c = math.cos(0.5)
19 print '145/23的余数 = %d' % a
20 print 'sin(0.5) = %f' %b
21 print 'cos(0.5) = %f' %c
- 编写程序,在屏幕上打印出如下图案: attachment:cdays-5-exercise-3.png
- 运行结果截图 attachment:cdays-5-exercise-123.png
1.1.2. CDays-4
os 模块中还有哪些功能可以使用? -- 提示使用 dir() help()
- os.error, os.path, os.popen, os.stat_result, os.sys, os.system等等等
详细可参见dir(os)和python帮助文档help(os)
open() 还有哪些模式可以使用?
- 'r': 以只读方式打开已存在文件,若文件不存在则抛出异常。此方式是默认方式
- 'U'或者'rU': python惯例构造了通用换行支持;提供'U'模式以文本方式打开一个文件,但是行可能随时结束:Unix的结束符规定为'\n',苹果系统则为'\r',还有windows规定为'\r\n',所有这些规定在python程序中统一为'\n'.如果python不构造一个通用换行支持模式'u'来用统一对待正常文本模式的话
- 'w': 以可写方式打开存在或者不存在的文件,若文件不存在则先新建该文件,若文件存在则覆盖该文件
- 'a': 用于追加,对unix系统而言,所有的内容都将追加到文件末尾而不管指针的当前位置如何
- 'b': 以二进制方式打开。打开一个二进制文件必须用该模式。增加'b'模式是用来兼容系统对当二进制和文本文件的处理不同
- 'r+','w+'和'a+'以更新方式打开文件(注意'w+'覆盖文件)
尝试for .. in .. 循环可以对哪些数据类型进行操作?
- for..in循环对于任何序列(列表,元组,字符串)都适用。但从广义说来可以使用任何种类的由任何对象组成的序列
- 格式化声明,还有哪些格式可以进行约定?
- d Signed integer decimal.
- i Signed integer decimal.
- o Unsigned octal.
- u Unsigned decimal.
- x Unsigned hexadecimal (lowercase).
- X Unsigned hexadecimal (uppercase).
- e Floating point exponential format (lowercase).
- E Floating point exponential format (uppercase).
- f Floating point decimal format.
- F Floating point decimal format.
- g Floating point format. Uses exponential format if exponent is greater than -4 or less than precision, decimal format otherwise.
- G Floating point format. Uses exponential format if exponent is greater than -4 or less than precision, decimal format otherwise.
- c Single character (accepts integer or single character string).
- r String (converts any python object using repr()).
- s String (converts any python object using str()).
- % No argument is converted, results in a "%" character in the result.
- 现在的写入文件模式好嘛? 有改进的余地?
CDay-4-5.py中使用了字符串的+连接,而CDay-4-6.py中是利用join。字符串的join要比'+'操作效率高。因为对象的反复+,比一次性内建处理,要浪费更多的资源。
CDay-4-5.py 好在哪里? :
CDay-4-6.py 又更加好在哪里? :
- 读取文件cdays-4-test.txt内容,去除空行和注释行后,以行为单位进行排序,并将结果输出为cdays-4-result.txt。
1 #coding:utf-8
2 '''cdays-4-exercise-6.py 文件操作
3 '''
4 #以读方式打开文件
5 f = open('cdays-4-test.txt', 'r')
6 result = list()
7 #依次读取每行
8 for line in f.readlines():
9 #去掉每行头尾空白
10 line = line.strip()
11 #判断是否是空行或注释行
12 if not len(line) or line.startswith('#'):
13 #是的话,跳过不处理
14 continue
15 result.append(line)
16 #排序结果
17 result.sort()
18 #保存入结果文件
19 open('cdays-4-result.txt', 'w').write('%s' % '\n'.join(result))
- 运行结果截图 attachment:cdays-4-exercise-6.png
1.1.3. CDays-3
根据 [http://www.woodpecker.org.cn/diveintopython/scripts_and_streams/command_line_arguments.html DiPy 10.6. 处理命令行参数] 使用getopt.getopt() 优化当前功能函式。
1 # coding=utf-8
2 '''Lovely Python -3 PyDay
3 PyCDC v0.3
4 '''
5 import os,sys
6 import getopt
7
8 CDROM = '/media/cdrom0'
9 def cdWalker(cdrom,cdcfile):
10 export = ""
11 for root, dirs, files in os.walk(cdrom):
12 export+="\n %s;%s;%s" % (root,dirs,files)
13 open(cdcfile, 'w').write(export)
14
15 def usage():
16 print '''PyCDC 使用方式:
17 python cdays-3-exercise-1.py -d cdc -k 中国火
18 #搜索 cdc 目录中的光盘信息,寻找有“中国火”字样的文件或是目录,在哪张光盘中
19 '''
20
21 try:
22 opts, args = getopt.getopt(sys.argv[1:], 'hd:e:k:')
23 except getopt.GetoptError:
24 usage()
25 sys.exit()
26
27 if len(opts) == 0:
28 usage()
29 sys.exit()
30
31 c_path = ''
32 for opt, arg in opts:
33 if opt in ('-h', '--help'):
34 usage()
35 sys.exit()
36 elif opt == '-e':
37 #判别sys.argv[2]中是否有目录,以便进行自动创建
38 #cdWalker(CDROM, arg)
39 print "记录光盘信息到 %s" % arg
40 elif opt == '-d':
41 c_path = arg
42 elif opt == '-k':
43 if not c_path:
44 usage()
45 sys.exit()
46 #进行文件搜索
读取某一简单索引文件cdays-3-test.txt,其每行格式为文档序号 关键词,现需根据这些信息转化为倒排索引,即统计关键词在哪些文档中,格式如下:包含该关键词的文档数 关键词 => 文档序号。其中,原索引文件作为命令行参数传入主程序,并设计一个collect函数统计关键字-序号结果对,最后在主程序中输出结果至屏幕。
1 #coding:utf-8
2 '''cdays-3-exercise-2.py 使用sys.args, dict和函数调用
3 '''
4 #导入sys模块
5 import sys
6
7 def collect(file):
8 ''' 改变 key-value对为value-key对
9 @param file: 文件对象
10 @return: 一个dict包含value-key对
11 '''
12 result = {}
13 #依次读取每行
14 for line in file.readlines():
15 #将一行以空格分割为左右两部分
16 left, right = line.split()
17 #判断是否已经含有right值对应的key
18 if result.has_key(right):
19 #若有,直接添加到result[right]的值列表
20 result[right].append(left)
21 else:
22 #没有,则新建result[right]的值列表
23 result[right] = [left]
24 return result
25
26 if __name__ == "__main__":
27 #判断参数个数
28 if len(sys.argv) == 1:
29 print 'usage:\n\tpython cdays-3-exercise-2.py cdays-3-test.txt'
30 else:
31 #调用collect函数,返回结果
32 result = collect(open(sys.argv[1], 'r'))
33 #输出结果
34 for (right, lefts) in result.items():
35 print "%d '%s'\t=>\t%s" % (len(lefts), right, lefts)
- 八皇后问题。在8*8的棋盘上,放置8个皇后,使得任两个皇后不在同行同列同正负对角线上。
1 #coding:utf-8
2 '''cdays-3-exercise-3.py 使用全局变量和函数递归调用
3 '''
4 #定义一些全局变量
5 global col
6 global row
7 global pos_diag
8 global nag_diag
9 global count
10
11 def output():
12 ''' 输出一种有效结果
13 '''
14 global count
15 print row
16 count += 1
17
18 def do_queen(i):
19 ''' 生成所有正确解
20 @param i: 皇后的数目
21 '''
22 #依次尝试0~7位置
23 for j in range(0, 8):
24 #若该行,正对角线,负对角线上都没有皇后,则放入i皇后
25 if col[j] == 1 and pos_diag[i-j+7] == 1 and nag_diag[i+j] == 1:
26 row[i] = j
27 #调整各个列表状态
28 col[j] = 0
29 pos_diag[i-j+7] = 0
30 nag_diag[i+j] = 0
31 if i < 7:
32 #可递增或递减
33 do_queen(i+1)
34 else:
35 #产生一个结果,输出
36 output()
37 #恢复各个列表状态为之前的
38 col[j] = 1
39 pos_diag[i-j+7] = 1
40 nag_diag[i+j] = 1
41
42 if __name__ == '__main__':
43 #矩阵列的列表,存储皇后所在列,若该列有皇后,则相应置为1,反之则0
44 col = []
45 #矩阵行的列表,存放每行皇后所在的位置,随着程序的执行,在不断的变化中,之间输出结果
46 row = []
47 #正对角线,i-j恒定,-7~0~7,并且b(i)+7统一到0~14
48 pos_diag = []
49 #负对角线,i+j恒定,0~14
50 nag_diag = []
51 count = 0
52 #一些初始化工作
53 for index in range(0, 8):
54 col.append(1)
55 row.append(0)
56 for index in range(0, 15):
57 pos_diag.append(1)
58 nag_diag.append(1)
59 #开始递归,先放一个,依次递增,反过来,从7开始递减也可
60 do_queen(0)
61 print 'Totally have %d solutions!' % count
- 运行结果截图 attachment:cdays-3-exercise-123.png
1.1.4. CDays-2
把最后探索出的 cdcGrep()嵌入 pycdc-v0.5.py 实现完成版本的 PyCDC
1 # coding= utf-8
2 '''pycdc-v0.5.py
3 Lovely Python -2 PyDay
4 '''
5 import sys, cmd
6 from cdctools import *
7 class PyCDC(cmd.Cmd):
8 def __init__(self):
9 cmd.Cmd.__init__(self) # initialize the base class
10 self.CDROM = '/media/cdrom0'
11 self.CDDIR = 'cdc/'
12 self.prompt="(PyCDC)>"
13 self.intro = '''PyCDC0.5 使用说明:
14 dir 目录名 #指定保存和搜索目录,默认是 "cdc"
15 walk 文件名 #指定光盘信息文件名,使用 "*.cdc"
16 find 关键词 #遍历搜索目录中所有.cdc文件,输出含有关键词的行
17 ? # 查询
18 EOF # 退出系统,也可以使用Crtl+D(Unix)|Ctrl+Z(dos/windows)
19 '''
20
21 def help_EOF(self):
22 print "退出程序 Quits the program"
23 def do_EOF(self, line):
24 sys.exit()
25
26 def help_walk(self):
27 print "扫描光盘内容 walk cd and export into *.cdc"
28 def do_walk(self, filename):
29 if filename == "":filename = raw_input("输入cdc文件名:: ")
30 print "扫描光盘内容保存到:'%s'" % filename
31 cdWalker(self.CDROM,self.CDDIR+filename)
32
33 def help_dir(self):
34 print "指定保存/搜索目录"
35 def do_dir(self, pathname):
36 if pathname == "": pathname = raw_input("输入指定保存/搜索目录: ")
37 self.CDDIR = pathname
38 print "指定保存/搜索目录:'%s' ;默认是:'%s'" % (pathname,self.CDDIR)
39
40 def help_find(self):
41 print "搜索关键词"
42 def do_find(self, keyword):
43 if keyword == "": keyword = raw_input("输入搜索关键字: ")
44 print "搜索关键词:'%s'" % keyword
45 cdcGrep(self.CDDIR,keyword)
46
47 if __name__ == '__main__': # this way the module can be
48 cdc = PyCDC() # imported by other programs as well
49 cdc.cmdloop()
- 编写一个类,实现简单的栈。数据的操作按照先进后出(FILO)的顺序。主要成员函数为put(item),实现数据item插入栈中;get(),实现从栈中取一个数据。
1 #coding:utf-8
2 '''cdays-2-exercise-2.py 类和对象的使用
3 '''
4
5 class MyStack(object):
6 '''MyStack
7 自定义栈,主要操作有put(), get() and isEmpty()
8 '''
9 def __init__(self, max):
10 '''
11 初始化栈:初始栈头指针和清空栈
12 @param max: 指定栈的最大长度
13 '''
14 self.head = -1
15 self.stack = list()
16 self.max = max
17 for i in range(self.max):
18 self.stack.append(0)
19
20 def put(self, item):
21 '''
22 将item压入栈中
23 @param item: 所要入栈的项
24 '''
25 #判断当前栈是否满了
26 if self.head >= self.max:
27 #提示栈溢出
28 return 'Put Error: The Stack is Overflow!'
29 else:
30 #不满,则将item入栈,调整栈顶指针
31 self.head += 1
32 self.stack[self.head] = item
33
34 def get(self):
35 '''
36 获得当前栈顶item
37 @return: 栈顶item
38 '''
39 #判断当前栈是否为空
40 if self.head < 0:
41 #提示栈空
42 return 'Get Error: The Stack is Empty!'
43 else:
44 #出栈,返回栈顶元素,并调整栈顶指针
45 self.head -= 1
46 return self.stack[self.head+1]
47
48 def isEmpty(self):
49 '''
50 获得当前栈的状态,空或者非空
51 @return: True(栈空) or False(栈非空)
52 '''
53 if self.head < -1:
54 return True
55 return False
56
57 if __name__ == "__main__":
58 mystack = MyStack(100)
59 mystack.put('a')
60 mystack.put('b')
61 print mystack.get()
62 mystack.put('c')
63 print mystack.get()
64 print mystack.get()
65 print mystack.get()
- 运行结果截图 attachment:cdays-2-exercise-12.png
1.1.5. CDays-1
- 自动判定你自个儿的Blog 是什么编码的?
1 #coding:utf-8
2 '''cdays-1-exercise-1.py 使用chardet和urllib2
3 '''
4
5 import sys
6 import urllib2
7 import chardet
8
9 def blog_detect(blogurl):
10 '''
11 检测blog的编码方式
12 @param blogurl: 要检测blog的url
13 '''
14 try:
15 #尝试打开给定url
16 fp = urllib2.urlopen(blogurl)
17 except Exception, e:
18 #若产生异常,则给出相关提示并返回
19 print e
20 print 'download exception %s' % blogurl
21 return 0
22 #读取内容
23 blog = fp.read()
24 #检测得到编码方式
25 codedetect = chardet.detect(blog)["encoding"]
26 print '%s\t<-\t%s' % (blogurl, codedetect)
27 #关闭
28 fp.close()
29 return 1
30
31 if __name__ == "__main__":
32 if len(sys.argv) == 1:
33 print 'usage:\n\tpython cdays-1-exercise-1.py http://xxxx.com'
34 else:
35 blog_detect(sys.argv[1])
- 在题一基础上,如果blog的编码不是utf-8,编写小程序自动将其转换成utf-8 编码保存到本地?
1 #coding:utf-8
2 '''cdays-1-exercise-2.py 熟悉chardet和urllib2
3 '''
4 import sys
5 import urllib2
6 import chardet
7
8 def blog_detect(blogurl):
9 '''
10 检测blog的编码方式
11 @param blogurl: 要检测blog的url
12 '''
13 try:
14 #尝试打开给定url
15 fp = urllib2.urlopen(blogurl)
16 except Exception, e:
17 #若产生异常,则给出相关提示并返回
18 print e
19 print 'download exception %s' % blogurl
20 return 0
21 #读取内容
22 blog = fp.read()
23 fp.close()
24 #检测得到编码方式
25 codedetect = chardet.detect(blog)["encoding"]
26 if codedetect <> 'utf-8': #是否是utf-8
27 try:
28 #不是的话,则尝试转换
29 blog = unicode(blog, codedetect)
30 blog = blog.encode('utf8')
31 except:
32 print u"bad unicode encode try!"
33 return 0
34 #保存入文件
35 filename = '%s_utf-8' % blogurl[7:]
36 filename = filename.replace('/', '_')
37 open(filename, 'w').write('%s' % blog)
38 print 'save to file %s' % filename
39 return 1
40
41 if __name__ == "__main__":
42 if len(sys.argv) == 1:
43 print 'usage:\n\tpython cdays-1-exercise-2.py http://xxxx.com'
44 else:
45 blog_detect(sys.argv[1])
- 运行结果截图 attachment:cdays-1-exercise-12.png
1.1.6. CDays-0
- 请根据软件发布的流程和软件开发的编码规范,将读者之前章节写的程序修改并发布出去。另外,可以查找下除了epydoc外还有哪些较好的py文档生成器?
- 步骤:
- 编写epydoc的配置文件,如下cdays0-epydoc.cfg。
- 在终端中输入epydoc --config cdays0-epydoc.cfg,即可生成文档。
[epydoc] # Epydoc section marker (required by ConfigParser) # Information about the project. name: MyStack url: http://wiki.woodpecker.org.cn/moin/ObpLovelyPython # The list of modules to document. Modules can be named using # dotted names, module filenames, or package directory names. # This option may be repeated. modules: ./cdays0-exercise-1.py # Write html output to the directory "apidocs" output: html target: apidocs/ # Include all automatically generated graphs. These graphs are # generated using Graphviz dot. graph: all dotpath: /usr/bin/dot
- 运行结果截图 attachment:cdays-0-exercise-1.png
1.1.7. CDays+1
- 编程实现以下功能并进行最大化的优化:遍历指定目录下的所有文件,找出其中占用空间最大的前3个文件。
1 #coding:utf-8
2 '''cdays+1-exercise-1.py 使用os.stat获取相关信息
3 '''
4 import sys
5 import os
6
7 def get_top_three(path):
8 ''' 获取给定路径中文件大小最大的三个
9 @param path: 指定路径
10 @return 返回一个list,每项为 (size, filename)
11 '''
12 all_file = {}
13 #遍历path
14 for root, dirs, files in os.walk(path):
15 for onefile in files:
16 #获得当前处理文件的完整名字
17 fname = os.path.join(root, onefile)
18 #获得当前处理文件大小
19 fsize = os.stat(fname).st_size
20 #按照文件大小存储
21 if all_file.has_key(fsize):
22 all_file[fsize].append(fname)
23 else:
24 all_file[fsize] = [fname]
25 #得到所有的文件大小
26 fsize_key = all_file.keys()
27 #排序,从小到大
28 fsize_key.sort()
29 result = []
30 #依次取最大的三个
31 for i in [-1, -2, -3]:
32 for j in all_file[fsize_key[i]]:
33 result.append((fsize_key[i], j))
34 #返回前三个
35 return result[:3]
36
37 if __name__ == "__main__":
38 if len(sys.argv) == 1:
39 print 'usage:\n\tpython cdays+1-exercise-1.py path'
40 else:
41 #得到绝对路径
42 abs_path = os.path.abspath(sys.argv[1])
43 #判断所给的路径是否存在
44 if not os.path.isdir(abs_path):
45 print '%s is not exist' % abs_path
46 else:
47 top = get_top_three(abs_path)
48 for (s, f) in top:
49 print '%s\t->\t%s' % (s, f)
利用ConfigParser,将上述题目中产生的结果按照cdays+1-my.ini格式存储到文件cdays+1-result.txt中。
1 #coding:utf-8
2 '''cdays+1-exercise-2.py 使用ConfigParser解析
3 '''
4 import os
5 import sys
6 from ConfigParser import RawConfigParser
7
8 def iniTT(size_file):
9 ''' 按照.ini的格式,存储size_file
10 '''
11 cfg = RawConfigParser()
12 print size_file
13 index = 1
14 for (s, f) in size_file:
15 #增加一个section
16 cfg.add_section("%d" % index)
17 #在该section设置Filename及其值
18 cfg.set("%d" % index, 'Filename', f)
19 #在该section设置FileSize及其值
20 cfg.set("%d" % index, 'FileSize', s)
21 index += 1
22
23 cfg.write(open('cdays+1-result.txt',"w"))
24
25 def gtt(path):
26 ''' 获取给定路径中文件大小最大的三个
27 @param path: 指定路径
28 @return 返回一个list,每项为 (size, filename)
29 '''
30 all_file = {}
31 #遍历path
32 for root, dirs, files in os.walk(path):
33 for onefile in files:
34 #获得当前处理文件的完整名字
35 fname = os.path.join(root, onefile)
36 #获得当前处理文件大小
37 fsize = os.stat(fname).st_size
38 #按照文件大小存储
39 if all_file.has_key(fsize):
40 all_file[fsize].append(fname)
41 else:
42 all_file[fsize] = [fname]
43 #得到所有的文件大小
44 fsize_key = all_file.keys()
45 #排序,从小到大
46 fsize_key.sort()
47 result = []
48 #依次取最大的三个
49 for i in [-1, -2, -3]:
50 for j in all_file[fsize_key[i]]:#保存
51 result.append((fsize_key[i], j))
52 #返回前三个
53 return result[:3]
54
55 if __name__ == "__main__":
56 if len(sys.argv) == 1:
57 print 'usage:\n\tpython cdays+1-exercise-2.py path'
58 else:
59 abs_path = os.path.abspath(sys.argv[1])
60 if not os.path.isdir(abs_path):
61 print '%s is not exist' % abs_path
62 else:
63 #from cdays+1-exercise-1 import get_top_three as gtt
64 iniTT(gtt(abs_path))
- 运行结果截图 attachment:cdays+1-exercise-12.png
1.1.8. CDays+2
- 如果在Karrigell 实例中,不复制 cdctools.py 到webapp 目录中,也可以令 index.ks 引用到?
- 修改python的环境变量PYTHONPATH,把cdctools.py的所在目录路径加入
- 在程序里动态的修改sys.path,如下所示:
- 经过本章Karrigell的初步学习,实现一个简易的web留言系统。主要利用Karrigell_quick_form实现提交留言并显示出来。
- 具体步骤:
- 下载karrigell,解压后,根据默认设置直接就可以运行了,但一般修改conf/下Karrigell.ini中的port=8081,表示使用端口8081,保存
将msg拷贝至webapps/,并在index.pih中增加链接<a href='msg/'> Message</a>
- 编辑msg中的index.ks,完成所需功能
- cd至karrigell所在目录,输入python Karrigell.py运行后,在浏览器地址栏中输入localhost:8081就可以看到页面,点击Message链接即可到达。
- 具体步骤:
1 # -*- coding: utf-8 -*-
2
3 import os,sys
4 import pickle # 神奇的序列化模块
5 from HTMLTags import * # Karrigell 提供页面输出支持模块
6 from Karrigell_QuickForm import Karrigell_QuickForm as KQF
7
8 def _htmhead(title):
9 '''默认页面头声明
10 @note: 为了复用,特别的组织成独立函式,根据Karrigell 非页面访问约定,函式名称前加"_"
11 @param title: 页面标题信息
12 @return: 标准的HTML代码
13 '''
14 htm = """<html><HEAD>
15 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
16 <title>%s</title></HEAD>
17 <body>"""%title
18 return htm
19 ## 默认页面尾声明
20 htmfoot="""
21 <h5>design by:<a href="mailto:[email protected]">lizzie</a>
22 powered by : <a href="http://python.org">Python</a> +
23 <a href="http://karrigell.sourceforge.net"> KARRIGELL 2.4.0</a>
24 </h5>
25 </body></html>"""
26
27 def index(**args):
28 '''默认主
29 @note: 使用简单的表单/链接操作来完成原有功能的界面化
30 @param args: 数组化的不定参数
31 @return: 标准的HTML页面
32 '''
33 print _htmhead("Leave Messages")
34 p = KQF('fm_message','POST',"index","Message")
35 p.addHtmNode('text','yname','Name',{'size':20,'maxlength':20})
36 p.addTextArea('Words','10','90')
37 p.addGroup(["submit","btn_submit","Submit","btn"])
38 p.display()
39
40 if 0 == len(QUERY):
41 pass
42 else:
43 if "Submit" in QUERY['btn_submit']:
44 yname = QUERY['yname']
45 ywords = QUERY['Words']
46 if 0 == len(ywords):
47 print H3("please say something!")
48 else:
49 if 0 == len(yname):
50 yname = 'somebody'
51 try:
52 msg = pickle.load(open("message.dump"))
53 except:
54 msg = []
55 msg.append((yname, ywords))
56 index = len(msg)-1
57 while index >= 0:
58 print H5(msg[index][0]+' says: ')
59 print P('------ '+msg[index][1])
60 index -= 1
61 pickle.dump(msg,open("message.dump","w"))
62 else:
63 pass
64 print htmfoot
- 运行结果截图 attachment:cdays+2-exercise-2.png
1.1.9. CDays+3
- 熟悉线程相关知识后,利用Lock和RLock实现线程间的简单同步,使得10个线程对同一共享变量进行递增操作,使用加锁机制保证变量结果的正确。
1 #coding:utf-8
2 '''cdays+3-exercise-1.py 使用Thread和RLock实现简单线程同步
3 '''
4 from threading import Thread
5 from threading import RLock
6 import time
7
8 class myThread(Thread):
9 '''myThread
10 自定义的线程,多个线程共同访问一个变量
11 '''
12 def __init__(self, threadname):
13 Thread.__init__(self, name = threadname)
14
15 def run(self):
16 #共享一全局变量
17 global share_var
18 #调用lock的acquire,获得锁
19 lock.acquire()
20 #修改共享变量
21 share_var += 1
22 #time.sleep(2)
23 print share_var
24 #释放
25 lock.release()
26
27 if __name__ == "__main__":
28 share_var = 0
29 lock = RLock()
30 threadlist = []
31 #产生10个线程
32 for i in range(10):
33 my = myThread('Thread%d' % i)
34 threadlist.append(my)
35 #开始10个线程
36 for i in threadlist:
37 i.start()
- 使用Queue实现多线程间的同步。比如说,十个输入线程从终端输入字符串,另十个输出线程依次获取字符串并输出到屏幕。
1 #coding:utf-8
2 '''cdays+3-exercise-2.py 使用Thread和Queue保持多线程间同步
3 '''
4 from threading import Thread
5 import Queue
6 import time
7
8 class Input(Thread):
9 '''输入线程: 从标准输入中读一个string,然后把该string加入到queue
10 '''
11 def __init__(self, threadname):
12 Thread.__init__(self, name = threadname)
13 def run(self):
14 #输入一个字符串
15 some_string = raw_input('please input something for thread %s:' % self.getName())
16 global queue
17 #加入到队列
18 queue.put((self.getName(), some_string))
19 #延时一段时间
20 #time.sleep(5)
21
22 class Output(Thread):
23 '''输出线程:从queue中得到一个string,并将它输出到屏幕
24 '''
25 def __init__(self, threadname):
26 Thread.__init__(self, name = threadname)
27 def run(self):
28 global queue
29 #从queue中读取
30 (iThread, something) = queue.get()
31 print 'Thread %s get "%s" from Thread %s' % (self.getName(), something, iThread)
32
33 if __name__ == "__main__":
34 #创建Queue对象
35 queue = Queue.Queue()
36 inputlist = []
37 outputlist = []
38 for i in range(10):
39 #输入线程列表
40 il = Input('InputThread%d' % i)
41 inputlist.append(il)
42 #输出线程列表
43 ol = Output('outputThread%d' % i)
44 outputlist.append(ol)
45 for i in inputlist:
46 #依次开始输入线程
47 i.start()
48 #等待
49 i.join()
50 for i in outputlist:
51 #依次开始输出线程
52 i.start()
53 #i.join()
- Python中的Event是用于线程间的相互通信,主要利用信号量机制。修改题一的程序,利用信号量重新实现多线程对同一共享变量进行递增操作。
1 #coding:utf-8
2 '''cdays+3-exercise-3.py 使用Thread和Event实现简单的线程通信
3 '''
4 from threading import Thread
5 from threading import Event
6 import time
7
8 class myThread(Thread):
9 '''myThread
10 自定义线程
11 '''
12 def __init__(self, threadname):
13 Thread.__init__(self, name = threadname)
14
15 def run(self):
16 global event
17 global share_var
18 #判断event的信号标志
19 if event.isSet():
20 #若设置了,则清除
21 event.clear()
22 #并调用wait方法
23 event.wait()
24 #time.sleep(2)
25 #修改共享变量
26 share_var += 1
27 print '%s ==> %d' % (self.getName(), share_var)
28 else:
29 #未设置,则直接修改
30 share_var += 1
31 print '%s ==> %d' % (self.getName(), share_var)
32 #time.sleep(1)
33 #设置信号标志
34 event.set()
35
36 if __name__ == "__main__":
37 share_var = 0
38 #创建Event对象
39 event = Event()
40 #设置内部信号标志为真
41 event.set()
42 threadlist = []
43 #创建10个线程
44 for i in range(10):
45 my = myThread('Thread%d' % i)
46 threadlist.append(my)
47 #开启10个线程
48 for i in threadlist:
49 i.start()
- 运行结果截图 attachment:cdays+3-exercise-12.png attachment:cdays+3-exercise-3.png
1.2. KDays
1.3. 小结