Commits

Anonymous committed c1724c4

Jibo 修改后的第二章

Comments (0)

Files changed (26)

source/_static/snap/Thumbs.db

Binary file modified.

source/_static/snap/name error- demo variable scope.png

Added
New image

source/ch02/FileProcessing.rst

+文本处理
+===============
+
+小白的苦恼
+---------------
+
+在接触了列表和字典这两个Python数据类型后,小白如获至宝。很快以字典为存储形式 (如下所示),完成了通讯录的原型开发。
+::
+
+	_Info = {"张三":'138-1000-2345',
+			"李四":'138-8888-8888'}
+
+接着,小白开始开心地录入全班同学的姓名和联系方式。刚刚开始录入信息的时候,小白依然兴致盎然。可当他录入了20多名同学的信息后,逐渐发现不对劲了!如果用字典存储联系人信息,那么一个人占一行代码。全班60来号人,就有60行代码。如果用户再多,代码文件就基本上变成了联系人信息了。这根本没有办法调试。小白意识到,”为了以后调试方便,得把联系人信息和代码本身分开存放才行。何不把联系人信息存储到一个文本文件中呢?“
+
+想到这里,小白放弃了继续在代码中录入联系人信息,改把联系人信息放到一个文本文件中。小白把这个联系人信息的文本文件取名为Contact.txt。这个文件中一个人的信息占一行。姓名和电话之间以制作符(Tab键)分隔,格式如下:
+::
+
+	张三	138-1000-2345
+	李四	138-8888-8888
+	王二麻子	138-8888-9999
+小白耐心地把全班同学的信息都输入到Contact.txt这个文本文件中了。他还特别地检查了一下班花小红的电话是否输入正确。小红的电话对小白非常重要。
+
+”终于把数据录完了!“小白舒展了一下筋骨,”下面,应该把文本文件中数据读入,然后再存放到字典这个数据库里就可以了。可是,应该怎么读取文本文件呢?“
+
+	
+读取文本文件
+----------------
+”我从来没有用Python处理过文本文件。怎么办呢?“。
+”写邮件去邮件列表里问吧?“小白马上有了到邮件列表里问的想法。可是小白转念又想,如果一遇到问题,就写信问大家,可能会被大牛们鄙视的。
+”对了,用必应搜索一下!“经过第一章的探索,小白已经了解到了搜索引擎的强大。他决定向搜索引擎求助。
+小白在必应搜索中查找”Python 文本文件“,发现搜索结果中提到了文本读取,创建文本,更新文本等操作概念。“哦,原来文件操作还挺多,有读,创建,更新等”。于是,小白使用新的关键词“Python 文本文件 读”重新搜索,以细化搜索结果。在搜索结果中,小白首先就看来了来自IBM.com的一篇文章, 网址是 http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html  。“恩,出自IBM,应该靠谱。”小白决定细细地看看这篇文章 ,了解一下Python的文本文件操作。
+
+
+小白通过了他在网上搜索到的几篇关于文本文件操作的文章,了解到Python读取文本文件主要有三种方法 ,分别是.read(), .readline()和.readlines()。.read()是将整个文件一次性读入,然后存放到一个字符串变量中。网上不太推荐这种文件读取方法。因为一次性读入大文件,可能造成内存溢出,数据存为字符串变量也不太好对数据进行逐行操作。.readline()读入一行。.readlines()是将文件所有内容一次性读入,将文件内容存为一个行的列表。这个列表可以使用for ... in...的结构进行逐行操作。
+
+小白看了一下IBM上的读文件操作,似乎挺简单的。读取一个文件也就三行代码。小白根据示例代码,稍作修改,自己运行了一下。小白修改后的代码如下:
+::
+
+	 '''
+	ReadFileDemo.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		demo read file
+	Reference:
+		http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+	Dependencies:
+		Contact.txt
+	'''
+	fh = open('Contact.txt')
+	for line in fh.readlines():
+		print line
+
+小白运行了上面的代码,马上看到了Python输出的文本文件内容。小白赞叹道,“Python 大利害了,三行代码就可以读取文件内容。”
+
+以文本文件存储联系人信息
+~~~~~~~~~~~~~~~
+
+由于Python读取文本文件非常简单,小白很快学会了使用读取文本文件操作。接下来,小白打算实现他先前计划的,把联系人信息存放到文本文件中。小白已经会读文本了,在第一章中已经完成了在字典数据库中搜索联系人的方法 。小白需要做的,就是把文本文件中读到的字符串转存到他先前的字典数据类型中。
+这个任务对小白不算太难。小白把先前写的ReadFileDemo.py和dict.py两个文件的代码拷贝到一起,把代码保存为ReadFile2Dict.py,用于将文本文件读取到字典中。将先前写的代码合并到一起后,小白就完成了主要的工作了。现在,只差的是把文本文件中的每一行的信息,存到字典数据_Info中。“怎么将每一行中的联系人姓名和联系方式转存到字典中呢?” 小白思考着这个仅缺的功能。小白比较了代码之前的差异。从文件中读到的每一行的变量line是一个字符串,比如"张三	138-1000-2345"。小白需要的是分别得到"张三"和“138-1000-2345”这两个联系人姓名和联系方式信息。“哦。将文本文件内容转存到字典数据中,实际上缺的功能就是一个字符串提取信息功能呀”。小白恍然大悟!小白翻了翻他在第一章节学习字符串处理和字典数据类型的笔记。很快完成了这个功能。小白使用cell = line.split('\t') 将每一行的数据转化成一个名叫cell的列表。这个cell列表存放着行中的每一个元素,第一个元素就是姓名,第二个元素就是联系方式。然后小白使用_Info[name] = contact 就把联系人姓名和联系方式存放到字典中了。
+
+下面是小白完成的ReadFile2Dict.py的最终代码。ReadFile2Dict.py实现了联系人信息和代码的分离。联系人信息存放在Contact.txt这个文本文件中。ReadFile2Dict.py实现读取文本文件,完成联系人搜索功能。
+
+::
+
+	# -*- coding: cp936 -*-
+	'''
+	ReadFile2Dict.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		- read data from Contact.txt
+		- Convert data into a dict
+		- combine features in ReadFileDemo.py and dict.py
+	Reference:
+		http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+	Dependencies:
+		Contact.txt
+	'''
+	#_Info = {"张三":'138-1000-2345',
+	#        "李四":'138-8888-8888'}
+
+	_Info = {}
+
+	fh = open('Contact.txt')
+	for line in fh.readlines():
+		#print line
+		# 将每一行分隔开,提取姓名和联系方式
+		cell = line.split('\t') 
+		name = cell[0]
+		contact = cell[1]
+		#print cell
+		_Info[name] = contact
+
+	print _Info
+
+
+	_run = True
+	while _run:
+		_User_input = raw_input("输入联系人名:")
+		if _Info.has_key(_User_input) == True:
+			print _Info[_User_input]
+		elif _User_input == "退出":
+			_run = False
+		else:
+			print "无此联系人"
+
+
+小白又运行了自己写的ReadFile2Dict.py多次,把玩自己写的搜索功能。一种成就感油然而生。“我真聪明!”小白默默自喜道。
+
+写文本文件
+~~~~~~~~~~~~~~~~~
+我会使用Python 读文本了,那么写文本应该怎么做呢?已经会读文本了,把写文本也学了吧。 以后继续开发通讯录可能用得着。 通讯录的三个主要功能,搜索,增加和更新。搜索对应的就是读文本操作,增加和更新对应的就是写文本操作了。
+ 
+小白依照读文本的学习过程进一步探索写文本文件操作。他使用关键词“Python 文本文件 写“在必应中进行搜索,寻找一些写文本的操作方法。由于有了读文本的经验,
+写文件也比较类似。这对小白并不难。通过阅读一些搜索结果,小白了解到,写文件包括三个步骤,打开文件,写内容到文件中,然后关闭文件。Python提供了三个非常名副其实的函数来完成这三个文件操作。open函数打开文件,write函数写内容到文件,close函数关闭文件。作为练习,小白写了一个简单的写文本文件的代码,文件名为 WriteFileDemo.py。代码如下:
+
+::
+
+	'''
+	WriteFileDemo.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		demo write file
+	'''
+
+	fh = open('outfile.txt', 'w')
+	fh.write('Hello, Python!')
+	fh.close()
+
+小白运行完WriteFileDemo.py后,将会生成outfile.txt这个文本文件,里面有一行字符串,"Hello, Python!"。
+
+小白伸了伸懒腰,放松一下筋骨,开心地念到,“Python读写文本还真的挺方便的,几行代码就完成了!”
+
+小结
+~~~~~~~~~~~~~~~~
+
+至此,小白已经掌握了如何使用 Python 读写文本。 Python 提供了open 函数打开文件,使用 readlines() 函数可以读文本,使用 write 函数可以写文本, 最后用close 函数关闭文本。小白将第一章节代码中的联系人信息,转存到文本文件中,然后通过读文本地形式来查询联系人。这很好地提高了代码的可读性。
+
+关键词
+~~~~~~~~~~~~~~~~
+open	write	close	readlines	readline
+

source/ch02/Function.rst

+函数化
+===============
+
+函数的好处
+---------------
+小白学习完文本处理并完成用文本存储联系人(请见第二章第二节ReadFile2Dict.py)后,对学习 Python的表现非常满意。他兴致勃勃地把通讯录给舅舅展示了一番,“舅舅,怎么样?我用 Python 开发的通讯录还不错吧?”。 
+
+舅舅看了看小白写的通讯录 (ReadFile2Dict.py),“还不错!进步很快呀!不过,你 Python 的功力才在第一层次。”
+
+“什么?!才第一层次。我最近一致很努力学习 Python 呢。” 小白对舅舅的评价不太满意。他继续追问道,“什么是 Python的第一层次? 怎么才能提高 Python 功力到更高层次呢?”
+
+舅舅耐心地向小白解释道,“你开发的通讯录已经不错了,进步很快。不过,你的代码是从上到下逐行运行的,没有函数和类等功能。这是初学编程的程序员的典型特点。代码从上到下逐行运行符合初级程序员较简单的逻辑思维,这样的代码写着比较容易。但这样的代码重用性很低。比如,你再次要用到读取通讯录文本,或者搜索联系人这些功能时,需要重新写这些代码。这种编程方式使得代码重复度很高,也不利于维护。如果你能够把一些基本功能,比如,读取通讯录文本文件 ,搜索联系人等用函数或者类实现,你就可以重用这些代码。使用函数和类等特性,可以使程序开发效率更高,更容易维护。”
+
+听了舅舅一席话,小白感到胜读十年书。“函数有这么多好处呀!那我尝试把读取通讯录,搜索联系人这些功能‘函数化’吧。”
+
+
+什么是函数?
+---------------
+“舅舅,什么是函数呀?Python 中的函数和我们初中数学中学的函数有什么不同呢?” 小白向舅舅追问,希望舅舅能够将他引入 “函数化”的大门。 
+舅舅看小白对新的概念 “函数”有点儿迷惑不解,便举了一个很简单的例子。我们上初中数学时,都学过函数。比如y = x +1,就是一个函数,x是自变量, y是因变量。我们有一个x值,希望做一定计算后得到最终的 y值。有时候,我们也记作y = f(x),表示y是关于x的函数,函数名为f 。数学学得好,编程也会很牛逼的。
+程序中的函数和数学中的函数非常相似。我们写程序时,经常会重复很多功能,比如多次搜索联系人信息。函数就是一块完成一定功能的代码。最简单的函数可以只有一个函数名,使用函数名就可以调用函数里的代码块。复杂一点儿的函数有输入变量,也就是我们提供给函数的变量信息,比如 y = f (x),x就是函数的输入变量,f就是函数名。我们在执行函数后,通常还希望得到函数的运行结果,因此,一些函数还有返回值,比如 y 。 
+ 
+Python 提供了很多自带的函数,比如你作文本处理时用到的open, write, close等都是系统的函数。你自己写的函数,就叫自定义函数。
+
+小白听了舅舅讲了这么多,有点儿云里雾里的。“舅舅,行胜于言,你讲这么多,还不如直接给我看一个函数。”
+
+Hello,函数
+---------------
+舅舅想到了所有程序语言的入门程序,"Hello World"系列。“小白,你刚刚学 Python 时,写的Hello World程序在哪里呀?”。
+小白翻了翻自己的学习笔记,在第一章节找到了Hello World程序。对于 Python,就一行代码 "print 'Hello World'"。
+
+舅舅告诉小白,函数不难,给这个helloworld.py程序,加一个函数名就是函数了。舅舅写了个函数示例代码给小白, hellofunction.py 如下:
+::
+
+	'''
+	hellofunction.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		demo function in python
+		based on helloworld.py in chapter 1
+	'''
+	# 定义 HelloWorld 函数
+	def HelloWorld():
+		print 'Hello World'
+
+	#调用 HelloWorld
+	HelloWorld()
+
+小白比较了helloworld.py和hellofunction.py,发现舅舅也就增加了两行代码。"def HelloWorld()" 定义了一个叫作 HelloWorld 的函数,HelloWorld()调用这个函数。
+其中,"def" 是 Python 的关键词,是英文 "define" (定义)的缩写,用于创建一个函数。HelloWorld是 定义的函数名。括号内可以加入函数的参数。这个简单的 HelloWorld 函数没有参数,因此,括号内是空白的。要调用这个函数时,只需要使用函数名,就可以运行函数内的全部代码块了。 
+
+
+变量作用域
+---------------
+看了代码后,小白初不了解了函数。“函数不就是给要重复使用的代码块取个名字,方便重复使用。这还不简单。”小白决定,把自己写的通讯录 (ReadFile2Dict.py)给函数化。
+小白决定仿照helloworld.py函数化的方式。他把ReadFiles2Dict.py重新取名为ReadFile2DictFunctoin-variable.py。然后把从文本文件中读取联系人的代码块缩进,在前面加上" def ReadContact(): ",把这段代码块定义为一个函数,取名为ReadContact。
+
+::
+
+	# -*- coding: cp936 -*-
+	'''
+	ReadFile2DictFunctoin-variable.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		- read data from Contact.txt
+		- Convert data into a dict
+		- combine features in ReadFileDemo.py and dict.py
+		- demo variable scope in a function
+	Dependencies:
+		Contact.txt
+	'''
+
+	def ReadContact():
+		_Info = {}
+
+		fh = open('Contact.txt')
+		for line in fh.readlines():
+			#print line
+			# 将每一行分隔开,提取姓名和联系方式
+			cell = line.split('\t')
+			name = cell[0]
+			contact = cell[1]
+			#print cell
+			_Info[name] = contact
+
+		print _Info
+
+	_run = True
+	while _run:
+		_User_input = raw_input("输入联系人名:")
+
+		ReadContact()
+
+		if _Info.has_key(_User_input) == True:
+			print _Info[_User_input]
+		elif _User_input == "退出":
+			_run = False
+		else:
+			print "无此联系人"
+
+		
+小白本以为函数化会像Hello World一样简单,可是当他运行上面的代码时,却出现了错误。错误如下:
+::
+
+	>>> 
+	输入联系人名:张三
+	{'\xd5\xc5\xc8\xfd': '138-1000-2345\n', '\xc0\xee\xcb\xc4': '138-8888-8888\n', '\xcd\xf5\xb6\xfe\xc2\xe9\xd7\xd3': '138-8888-9999\n'}
+
+	Traceback (most recent call last):
+	  File "D:\Dropbox\python book\ch02\ReadFile2DictFunction-variable.py", line 36, in <module>
+		if _Info.has_key(_User_input) == True:
+	NameError: name '_Info' is not defined
+
+小白还是略微懂英文的。“NameError: name '_Info' is not defined”是说'_Info'没有被定义。这是怎么回事呢?原来定义了的变量'_Info',在函数化后,就变成了没有定义了。小白在必应中搜索"NameError: name '_Info' is not defined"这个错误信息,以尽量找到更多的信息。在阅读了一些搜索结果后,小白了解到"name XXX is not defined"的错误就是表明某个变量没有被定义。小白接着在必应中搜索“python 函数  变量 定义”,想解决变量在函数化后没有被定义的问题。小白逐渐接触到了局域变量和全局变量。
+“哦!原来函数内的变量是局域变量,在函数外是不存在的。” 小白终于找到了问题的症结所在。可是,怎么才能获得函数内的变量值,比如'_Info' 呢?
+
+小白大致了解问题所在,可是不知道应该用什么关键词进行搜索。实在想不到别的办法了,小白决定向 Python 邮件列表求助。他把错误信息和代码发到了 Python 邮件列表,很快得到了回复。邮件列表里的热心行者们很快做出了回复。 他们说, 函数里的变量通常是局域变量,在函数外是不能访问的。要解决这个问题,可以把函数内的变量通过"global _Info"申明为全局变量,或者通过"return _Info"把变量作为函数返回值。一些行者跟贴说,global 申明全局变量的方法虽然可行,但是不推荐,因为这可能导致变量冲突。
+
+根据行者们的帮助, 小白先试了试在ReadContact函数内加了一行代码 "global _Info",把_Info申明为全局变量。这果然轻松解决了问题。 小白的代码如下:
+::
+
+	# -*- coding: utf-8 -*-
+	'''
+	ReadFile2DictFunctionGlobal.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		- read data from Contact.txt
+		- Convert data into a dict
+		- combine features in ReadFileDemo.py and dict.py
+		- demo function in python
+	Reference:
+		http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+	Dependencies:
+		Contact.txt
+	'''
+
+	def ReadContact():
+		#申明全局变量
+		global _Info
+		_Info = {}
+
+		fh = open('Contact.txt')
+		for line in fh.readlines():
+			#print line
+			# 将每一行分隔开,提取姓名和联系方式
+			cell = line.split('\t')
+			name = cell[0]
+			contact = cell[1]
+			#print cell
+			_Info[name] = contact
+
+		print _Info
+
+	_run = True
+	while _run:
+		_User_input = raw_input("输入联系人名:")
+
+		# 调用读取联系人文本文件函数
+		ReadContact()
+
+		if _Info.has_key(_User_input) == True:
+			print _Info[_User_input]
+		elif _User_input == "退出":
+			_run = False
+		else:
+			print "无此联系人"
+
+小白又尝试了一下函数返回值的解决方法。他在ReadContact的末尾加上了"return _Info" 这行代码。然后再通过"_Info = ReadContact()"把函数运行后的值赋给_Info。这种方法也成功地解决了前面遇到的_Info变量没有被定义的问题。 小白的代码如下:
+::
+
+	# -*- coding: utf-8 -*-
+	'''
+	ReadFile2DictFunctoin.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		- read data from Contact.txt
+		- Convert data into a dict
+		- combine features in ReadFileDemo.py and dict.py
+		- demo function in python
+	Reference:
+		http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+	Dependencies:
+		Contact.txt
+	'''
+
+	def ReadContact():
+		_Info = {}
+
+		fh = open('Contact.txt')
+		for line in fh.readlines():
+			#print line
+			# 将每一行分隔开,提取姓名和联系方式
+			cell = line.split('\t')
+			name = cell[0]
+			contact = cell[1]
+			#print cell
+			_Info[name] = contact
+
+		print _Info
+		# 返回函数值
+		return _Info
+
+
+	_run = True
+	while _run:
+		_User_input = raw_input("输入联系人名:")
+
+		# 调用读取联系人文本文件函数
+		_Info = ReadContact()
+
+		if _Info.has_key(_User_input) == True:
+			print _Info[_User_input]
+		elif _User_input == "退出":
+			_run = False
+		else:
+			print "无此联系人"
+
+
+带参数的函数,搜索联系人函数
+---------------
+小白通过搜索引擎和行者们的帮助,完成了读取联系人文本文件的函数化。比较了一下原来的代码,和函数化后的代码,他发现,函数化使代码结构更清晰了。”恩!使用函数有挺多优势的。何不把其它功能,比如搜索联系人的代码块也函数化呢?这样我就不用每次查找联系人都重复这一大块代码了。”
+于是,小白动手写搜索联系人的函数。他首先把搜索联系人的代码块缩进,使用"def SearchContact():"给这段代码取了一个函数名,叫做SearchContact。与前面两次函数化不同的是,小白希望能够把用户查询的联系人做为自变量输入函数。他隐约记得舅舅说过,函数括号里是放变量名的。于是,他把SearchQuery加到了自定义的函数中,这行代码变为了"def SearchContact(SearchQuery):"。下面是小白完成函数化后的通讯录软件。舅舅所言不虚,函数化后的程序果然结构更清楚易懂了。
+
+::
+
+	# -*- coding: utf-8 -*-
+	'''
+	ReadFile2DictFunctoinParameter.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		- read data from Contact.txt
+		- Convert data into a dict
+		- combine features in ReadFileDemo.py and dict.py
+		- demo function parameter in python
+	Dependencies:
+		Contact.txt
+	'''
+
+	def ReadContact():
+		'''读取联系人信息文本文件'''
+		_Info = {}
+
+		fh = open('Contact.txt')
+		for line in fh.readlines():
+			#print line
+			# 将每一行分隔开,提取姓名和联系方式
+			cell = line.split('\t')
+			name = cell[0]
+			contact = cell[1]
+			#print cell
+			_Info[name] = contact
+
+		print _Info
+		# 返回函数值
+		return _Info
+
+	def SearchContact(SearchQuery):
+		'''搜索联系人函数'''
+		if _Info.has_key(SearchQuery) == True:
+			print _Info[SearchQuery]
+		elif SearchQuery == "退出":
+			_run = False
+		else:
+			print "无此联系人"
+
+
+	_run = True
+	while _run:
+		_User_input = raw_input("输入联系人名:")
+
+		# 调用读取联系人文本文件函数
+		_Info = ReadContact()
+		SearchContact(_User_input)
+
+
+	
+保存联系人的函数
+---------------
+在完成通讯录的函数化后,小白对自己学习 Python 的能力有了更多的自信。他决定进一步开发通讯录的功能。现在的通讯录,只有查询功能。但是他用过的其它通讯录软件都有新建联系人和更新联系人等功能。小白计划先给软件增加一个新建联系人功能。当查不到联系人时,提醒用户提供这个联系人的信息,然后保存到文本文件中。小白将这个新建联系人的函数取名为"CreateNewContact",定义这个函数的代码为 "def CreateNewContact():" 。当搜索联系人函数找不到联系人时,即"print "无此联系人""代码之后,调用CreateNewContact函数。
+
+这个新建联系人的功能主要包括两部分。一是提示用户输入,二是将用户输入的联系人信息写入文件文件中。对于提示用户输入,可以使用NewContact = raw_input("输入新的联系人信息:")就可以了。 对于将信息写入文本文件,小白在上一节文本处理时已经有不少了解。使用fh = open('Contact.txt', 'w')是创建一个新的叫做Contact.txt文件。小白需要的是在已经存在的Contact.txt的末尾增加新的记录。小白回忆了学习文本处理时看到的帖子,更新已经存在的文本,应该使用'a'(append的英文缩写)这个参数,代码为"fh = open('Contact.txt', 'a')"。
+
+小白在函数化后的通讯录(见代码ReadFile2DictFunctoinParameter.py)的基础上,加上了这个新建联系人的函数。下面是小白完成的代码(SearchCreateContact.py):
+::
+
+	# -*- coding: utf-8 -*-
+	'''
+	SearchCreateContact.py
+	By Jibo He @ueseo.org
+	hejibo@ueseo.org
+	Function:
+		- search contact
+		- create new contact
+	Dependencies:
+		Contact.txt
+	'''
+
+	def ReadContact():
+		'''读取联系人信息文本文件'''
+		_Info = {}
+
+		fh = open('Contact.txt')
+		for line in fh.readlines():
+			#print line
+			# 将每一行分隔开,提取姓名和联系方式
+			cell = line.split('\t')
+			name = cell[0]
+			contact = cell[1]
+			#print cell
+			_Info[name] = contact
+
+		print _Info
+		# 返回函数值
+		return _Info
+
+	def SearchContact(SearchQuery):
+		'''搜索联系人函数'''
+		if _Info.has_key(SearchQuery) == True:
+			print _Info[SearchQuery]
+		elif SearchQuery == "退出":
+			_run = False
+		else:
+			print "无此联系人"
+			CreateNewContact()
+
+	def CreateNewContact():
+		'''在联系人不存在时,新建联系人信息,并保存到Contact.txt中'''
+		NewContact = raw_input("输入新的联系人信息(以制表符Tab 分隔):\n")
+		fh = open('Contact.txt', 'a')
+		fh.seek(2)
+		fh.write(NewContact)
+		fh.close()
+		print "已经将新的联系人加入数据库。"
+		
+	_run = True
+	while _run:
+		_User_input = raw_input("输入联系人名:")
+
+		# 调用读取联系人文本文件函数
+		_Info = ReadContact()
+		SearchContact(_User_input)
+
+小白反复测试了一下自己的通讯录。这个软件已经可以查询联系人和新建联系人了。小白对这个软件的功能非常满意。 
+
+
+小结
+~~~~~~~~~~~~~~~~
+小白在舅舅的建议下,将通讯录软件函数化,完成了读取通讯录文本,查询通讯录联系人和新建联系人的功能。函数是完成特定功能的代码块。函数化使得通讯录软件的结构更加清晰了。 
+
+
+关键词
+~~~~~~~~~~~~~~~~
+def		return		global
+
+

source/ch02/MakeAModule.rst

-制作、使用自己的模块
+制作、使用自己的模块
 ====================
 
 小白的虚荣心

source/ch02/UseCMD.rst

-模块万岁!
+模块万岁!
 ===============
 
 小白的苦恼
  
 哦,原来CMD是一个Python模块,可以很容易地实现交互命令行程序。网上说CMD所生成的程序和Python的交互环境相似。看到这里小白立刻来了劲儿,把自己的程序变得和脚本语言一样?爽!
  
-于是小白从网上复制了代码,并修改成了伪代码 ::
+于是小白从网上复制了代码,并修改成了伪代码
+
+::
 
  '''
  CLI.py
 
   -后面不加参数也可以,那么就输出
  
- ::
+::
    
    Documented commands (type help <topic>):
   ========================================
 
 不光有字符串分割,还有字符串的其它操作的介绍呢!
         
-其中split函数是分隔字符串的,split('/')就是把字符串从"/"处分割成很多字符串::
+其中split函数是分隔字符串的,split('/')就是把字符串从"/"处分割成很多字符串
+::
 
   >>> a="a/b/c/d/e/d/c/f"
   >>> a.split('/')
   ['a', 'b', 'c', 'd', 'e', 'd', 'c', 'f']
   >>> 
-如果要将john和john 123-456-789从"add john 123-456-789"这个命令语句中分隔出来,应该用split(' ')就可以了。小白根据上面的例子,照葫芦画瓢地写了下面的代码,以从命令行中分隔出参数。::
+如果要将john和john 123-456-789从"add john 123-456-789"这个命令语句中分隔出来,应该用split(' ')就可以了。小白根据上面的例子,照葫芦画瓢地写了下面的代码,以从命令行中分隔出参数。
+::
+
   >>> a="add john 123-456-789"
   >>> a.split(' ')
   ['add', 'john', '123-456-789']
   >>> 
 
-这样就可以得到命令语句中的参数了。 小白立刻动手,在do_add函数中添加了下面的代码代码::
+这样就可以得到命令语句中的参数了。 小白立刻动手,在do_add函数中添加了下面的代码代码
+::
 
   list_=txt.split(' ')
   namelist.append(list_[0])
 
 txt存放着命令语句,如"add john 123-456-789"。然后通过txt.split(' '),就把参数一个个按顺序放到namelist这个列表里面了。
 
-do_view方法也要进行相应的修改 ::
+do_view方法也要进行相应的修改 
+::
 
   if name=="all":
       for num in range(len(namelist)):
 
 有点难以理解,配合代码看看
 
-总结出来::
+总结出来
+::
 
   class myprint():           # 定义了一个叫做myprint的类
     a='hello'                # 建立一个变量
   f.write()
 
 输出:
- 
+::
+
   hello,world!
 
 小结
 但是小白这么简陋而且丑陋的代码,谁愿意用呢?还需要修改和整理一下。
 
 嗯!小白确定明天要干的事情了:重构代码,写出自己的模块!
+
+关键词
+~~~~~~~~~~~~~~~~
+class

source/ch02/UseRe.rst

-使用正则表达式
+使用正则表达式
 ===================
 
 小白回顾了一下自己写的代码。“哇!代码已经超过100行了!”小白不由地沾沾自喜,一种成就感油然而生。至此,小白已经完成了通讯录的增加,和读写了。 
 
 在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。Python提供了re模块进行正则表达式的操作。小白在ubuntu的wiki上知道了re.complie是编译正则表达式,创建一个正则对象。re.match是匹配字符串,当不能匹配时,就返回空值!
 
-所以,小白只要使用 ::
+所以,小白只要使用 
+::
 
   if nam:
   

source/ch02/WriteDocument.rst

-写文档
+写文档
 ==================
 
 小白听到同学的抱怨后,自己尝试着从用户的眼光再看了看自己写的代码。小白发现,同学的抱怨也挺有道理的。随着通讯录功能的增加,软件也越来越难用了。
   ::
     code
 
-相同效果的HTML代码::
+相同效果的HTML代码
+
+::
+
   <html>
   <body>
   <h1>title</h1>

source/ch02/index.rst

-模块
-============================================
-
-小白给同学秀他的通讯录软件,却被同学逼视了! 命令行的通讯录实在太难用了。那么多参数,实在太难记住了! 难道就不能有个对话框,提示查询词语的参数吗?!
-
-
-.. include:: intro.rst
-
-
-.. toctree::
-   
-   intro.rst
-   UseCMD.rst
-   MakeAModule.rst
-   UseRe.rst
-   WriteDocument.rst
-   setuppy.rst
-   summary.rst
-   suggested_reading.rst
-
+模块
+============================================
+
+小白给同学秀他的通讯录软件,却被同学逼视了! 命令行的通讯录实在太难用了。那么多参数,实在太难记住了! 难道就不能有个对话框,提示查询词语的参数吗?!
+
+
+.. include:: intro.rst
+
+
+.. toctree::
+   
+   intro.rst
+   FileProcessing.rst
+   Function.rst
+   UseCMD.rst
+   MakeAModule.rst
+   UseRe.rst
+   WriteDocument.rst
+   setuppy.rst
+   summary.rst
+   suggested_reading.rst
+

source/ch02/intro.rst

-
+
 
 
 

source/ch02/setuppy.rst

-setup.py
+setup.py
 ===============================
 
 刚刚学习 Python 时, 小白特别羡慕那些能够自己发布软件包的牛人们。小白多么希望自己也可以发布一个软件包呀。小白想让自己的程序也能通过::

source/ch02/suggested_reading.rst

-推荐阅读
+推荐阅读
 ===============
 

source/ch02/summary.rst

-小结
+小结
 ===============
 
 

src/2_dbmala/CLI (hejibo-THINK).py

+ '''
+ CLI.py
+ ?????????
+ '''
+import cmd    #??cmd??
+class CLI(cmd.Cmd):
+    def __init__(self):  #self????????????????
+          cmd.Cmd.__init__(self)
+          self.prompt = ">>"  #??????
+      def do_add(self,arg):   #???????????
+          print "????"   #?????????????
+
+   #????????
+cli=CLI()
+cli.cmdloop()

src/2_dbmala/CLI.py

+'''
+ CLI.py
+ ?????????
+'''
+import cmd    #??cmd??
+class CLI(cmd.Cmd):
+    def __init__(self):  #self????????????????
+        cmd.Cmd.__init__(self)
+        self.prompt = ">>"  #??????
+    def do_add(self,arg):   #???????????
+        print "????"   #?????????????
+
+#????????
+cli=CLI()
+cli.cmdloop()

src/2_dbmala/ReadFile.py

+# -*- coding: cp936 -*-
+'''
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Apr 29, 2012
+address book project
+
+demo:
+  - read file
+'''
+
+_Info = {"����":'138-1000-2345',
+        "����":'138-8888-8888'}
+
+_run = True
+while _run:
+    _User_input = raw_input("������ϵ������")
+    if _Info.has_key(_User_input) == True:
+        print _Info[_User_input]
+    elif _User_input == "�˳�":
+        _run = False
+    else:
+        print "�޴���ϵ��"
+        

src/2_dbmala/ReadFile2Dict.py

+# -*- coding: cp936 -*-
+'''
+ReadFile2Dict.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    - read data from Contact.txt
+    - Convert data into a dict
+    - combine features in ReadFileDemo.py and dict.py
+Reference:
+    http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+Dependencies:
+    Contact.txt
+'''
+#_Info = {"����":'138-1000-2345',
+#        "����":'138-8888-8888'}
+
+_Info = {}
+
+fh = open('Contact.txt')
+for line in fh.readlines():
+    #print line
+    # ��ÿһ�зָ�����ȡ��������ϵ��ʽ
+    cell = line.split('\t')
+    name = cell[0]
+    contact = cell[1]
+    #print cell
+    _Info[name] = contact
+
+print _Info
+
+
+_run = True
+while _run:
+    _User_input = raw_input("������ϵ������")
+    if _Info.has_key(_User_input) == True:
+        print _Info[_User_input]
+    elif _User_input == "�˳�":
+        _run = False
+    else:
+        print "�޴���ϵ��"

src/2_dbmala/ReadFile2DictFunction-variable.py

+# -*- coding: cp936 -*-
+'''
+ReadFile2DictFunctoin.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    - read data from Contact.txt
+    - Convert data into a dict
+    - combine features in ReadFileDemo.py and dict.py
+    - demo variable scope in a function
+Dependencies:
+    Contact.txt
+'''
+
+def ReadContact():
+    _Info = {}
+
+    fh = open('Contact.txt')
+    for line in fh.readlines():
+        #print line
+        # ��ÿһ�зָ�����ȡ��������ϵ��ʽ
+        cell = line.split('\t')
+        name = cell[0]
+        contact = cell[1]
+        #print cell
+        _Info[name] = contact
+
+    print _Info
+
+_run = True
+while _run:
+    _User_input = raw_input("������ϵ������")
+
+    ReadContact()
+
+    if _Info.has_key(_User_input) == True:
+        print _Info[_User_input]
+    elif _User_input == "�˳�":
+        _run = False
+    else:
+        print "�޴���ϵ��"

src/2_dbmala/ReadFile2DictFunction.py

+# -*- coding: utf-8 -*-
+'''
+ReadFile2DictFunctoin.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    - read data from Contact.txt
+    - Convert data into a dict
+    - combine features in ReadFileDemo.py and dict.py
+    - demo function in python
+Reference:
+    http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+Dependencies:
+    Contact.txt
+'''
+
+def ReadContact():
+    _Info = {}
+
+    fh = open('Contact.txt')
+    for line in fh.readlines():
+        #print line
+        # 将每一行分隔开,提取姓名和联系方式
+        cell = line.split('\t')
+        name = cell[0]
+        contact = cell[1]
+        #print cell
+        _Info[name] = contact
+
+    print _Info
+    # 返回函数值
+    return _Info
+
+
+_run = True
+while _run:
+    _User_input = raw_input("输入联系人名:")
+
+    # 调用读取联系人文本文件函数
+    _Info = ReadContact()
+
+    if _Info.has_key(_User_input) == True:
+        print _Info[_User_input]
+    elif _User_input == "退出":
+        _run = False
+    else:
+        print "无此联系人"

src/2_dbmala/ReadFile2DictFunctionGobal.py

+# -*- coding: utf-8 -*-
+'''
+ReadFile2DictFunctionGlobal.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    - read data from Contact.txt
+    - Convert data into a dict
+    - combine features in ReadFileDemo.py and dict.py
+    - demo function in python
+Reference:
+    http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+Dependencies:
+    Contact.txt
+'''
+
+def ReadContact():
+    #申明全局变量
+    global _Info
+    _Info = {}
+
+    fh = open('Contact.txt')
+    for line in fh.readlines():
+        #print line
+        # 将每一行分隔开,提取姓名和联系方式
+        cell = line.split('\t')
+        name = cell[0]
+        contact = cell[1]
+        #print cell
+        _Info[name] = contact
+
+    print _Info
+
+_run = True
+while _run:
+    _User_input = raw_input("输入联系人名:")
+
+    # 调用读取联系人文本文件函数
+    ReadContact()
+
+    if _Info.has_key(_User_input) == True:
+        print _Info[_User_input]
+    elif _User_input == "退出":
+        _run = False
+    else:
+        print "无此联系人"

src/2_dbmala/ReadFile2DictFunctionParameter.py

+# -*- coding: utf-8 -*-
+'''
+ReadFile2DictFunctoinParameter.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    - read data from Contact.txt
+    - Convert data into a dict
+    - combine features in ReadFileDemo.py and dict.py
+    - demo function parameter in python
+Dependencies:
+    Contact.txt
+'''
+
+def ReadContact():
+    '''读取联系人信息文本文件'''
+    _Info = {}
+
+    fh = open('Contact.txt')
+    for line in fh.readlines():
+        #print line
+        # 将每一行分隔开,提取姓名和联系方式
+        cell = line.split('\t')
+        name = cell[0]
+        contact = cell[1]
+        #print cell
+        _Info[name] = contact
+
+    print _Info
+    # 返回函数值
+    return _Info
+
+def SearchContact(SearchQuery):
+    '''搜索联系人函数'''
+    if _Info.has_key(SearchQuery) == True:
+        print _Info[SearchQuery]
+    elif SearchQuery == "退出":
+        _run = False
+    else:
+        print "无此联系人"
+
+
+_run = True
+while _run:
+    _User_input = raw_input("输入联系人名:")
+
+    # 调用读取联系人文本文件函数
+    _Info = ReadContact()
+    SearchContact(_User_input)
+
+

src/2_dbmala/ReadFileDemo.py

+'''
+ReadFileDemo.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    demo read file
+Reference:
+    http://www.ibm.com/developerworks/cn/linux/sdk/python/python-5/index.html
+Dependencies:
+    Contact.txt
+'''
+fh = open('Contact.txt')
+for line in fh.readlines():
+    print line

src/2_dbmala/SearchCreateContact.py

+# -*- coding: utf-8 -*-
+'''
+SearchCreateContact.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    - search contact
+    - create new contact
+Dependencies:
+    Contact.txt
+'''
+
+def ReadContact():
+    '''读取联系人信息文本文件'''
+    _Info = {}
+
+    fh = open('Contact.txt')
+    for line in fh.readlines():
+        #print line
+        # 将每一行分隔开,提取姓名和联系方式
+        cell = line.split('\t')
+        name = cell[0]
+        contact = cell[1]
+        #print cell
+        _Info[name] = contact
+
+    print _Info
+    # 返回函数值
+    return _Info
+
+def SearchContact(SearchQuery):
+    '''搜索联系人函数'''
+    if _Info.has_key(SearchQuery) == True:
+        print _Info[SearchQuery]
+    elif SearchQuery == "退出":
+        _run = False
+    else:
+        print "无此联系人"
+        CreateNewContact()
+
+def CreateNewContact():
+    '''在联系人不存在时,新建联系人信息,并保存到Contact.txt中'''
+    NewContact = raw_input("输入新的联系人信息(以制表符Tab 分隔):\n")
+    fh = open('Contact.txt', 'a')
+    fh.seek(2)
+    fh.write(NewContact)
+    fh.close()
+    print "已经将新的联系人加入数据库。"
+    
+_run = True
+while _run:
+    _User_input = raw_input("输入联系人名:")
+
+    # 调用读取联系人文本文件函数
+    _Info = ReadContact()
+    SearchContact(_User_input)
+
+

src/2_dbmala/WriteFileDemo.py

+'''
+WriteFileDemo.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    demo write file
+'''
+
+fh = open('outfile.txt', 'w')
+fh.write('Hello, Python!')
+fh.close()

src/2_dbmala/dict.py

+# -*- coding: cp936 -*-
+
+_Info = {"����":'138-1000-2345',
+        "����":'138-8888-8888'}
+
+_run = True
+while _run:
+    _User_input = raw_input("������ϵ������")
+    if _Info.has_key(_User_input) == True:
+        print _Info[_User_input]
+    elif _User_input == "�˳�":
+        _run = False
+    else:
+        print "�޴���ϵ��"
+        

src/2_dbmala/hellofunction.py

+'''
+hellofunction.py
+By Jibo He @ueseo.org
+hejibo@ueseo.org
+Function:
+    demo function in python
+    based on helloworld.py in chapter 1
+'''
+# ?? HelloWorld ??
+def HelloWorld():
+    print 'Hello World'
+
+#?? HelloWorld
+HelloWorld()