1.
第6.1.3节讨论数据平均值和均方差的程序时,提出了3种可能实现方法,并实现了其中一种方法。请另选一种实现方法,完成一个具有同样功能的程序。请讨论,你选用的方法与本章正文中选用的方法各有哪些优缺点?
2.
在第6.1.3节最后讨论书中实现词频统计的示例程序时,说明了该程序的一些不足。请选择一个具体的英语文本(例如海明威的《太阳照样升起》的第一部分),设法修改和扩充本章正文中给出词频统计程序,使之能得到更好的结果。请说明你所做的各项修改的理由,并分析结果程序的效果。
3.
修改第6.1.3节的词频统计函数,如果调用时给了一个统计文件名参数,函数就将统计数据存入该文件;否则就返回包含统计结果的字典。请另外定义一个函数,它调用上述统计函数,并在屏幕上输出(用print)被统计的文本中使用最多的20个单词及其使用次数。
4.
请写一个程序,它统计在一个英文文本中的句子的平均单词数,以句号等若干个符号作为句子分隔符。这种平均长度也是文章复杂程度的一个指标。找10篇不同的英文文本,各属于不同类别(自己定义类别),用你的程序对它们做统计,并报告结果。你也可以对中文的文本文件做类似的工作。
5.
请写一个程序,它读入一个英文文本文件,然后按字典顺序输出文本中仅出现一次的所有单词。
6.
请开发一个统计中文文本中汉字出现频率的程序,并选择几个实际文本做试验,观察实际结果,并做些简单的改进。
7.
请开发一个“罕见词抽取程序”,它要求首先输入一个常用英语单词表文件(设法找一个这样的文件),然后读入一本书的文本,检查并汇集文本中所有没出现在英语单词表里的单词,并输出这些单词(罕用词)。
8.
假设英语动词的不同形式已按如下格式存储在文本文件verbs.txt里(一行一个单词):
... ...
be am are is were
was being been
... ...
take takes taking taken took
... ...
请定义函数verb_dict,使函数调用verb_dict("verbs.txt")返回一个字典,该字典把动词的各种形式映射到其原形形式。
另请定义函数verb_counts,函数调用verb_counts("text.txt")将统计出文件text.txt里不同动词的出现次数,返回记录结果的对象。文本中出现verbs.txt里的单词都看作是动词(虽然其中一些动词在文中实际上作为名词等使用)。
利用前面函数的工作结果,输出文本中使用最频繁的n个动词,n的具体值可以通过程序的命令行参数给定,不给参数时输出排位前10的动词。
9.
请改造第5章的猜单词程序,从文件中读入单词表,然后开始猜单词游戏。
10.
请自己定义一个功能和使用方式与标准函数range完全相同的生成器函数。
11.
请定义一个生成随机数的生成器函数。具体算法请自己查找讨论伪随机数生成问题的材料,例如网络上介绍伪随机数的材料。
12.
请定义生成器函数chain(*iterables),其参数可以是任意多个可迭代对象,它顺序yield出各参数(可迭代对象)的内容,就像它们来自一个统一的序列。
13.
请定义生成器函数sum_mean,其参数是一个浮点数的序列。sum_mean生成出参数序列的前i项之和与前i项平均值的序对。
14.
请定义一个生成器函数,它顺序检查一个文件里的文本,选出在文本中长度超过8个字符的单词,顺序yield这些单词。
15.
请定义闭包函数,实现与本书6.2.1节给出的各个生成器函数实例类似的功能。从实现方式和复杂程度方面比较不同的实现。
16.
请进一步完善6.2.3节的银行账户生成函数,在函数里增加必要的检查。请设计并实现一个主程序,利用这个账户生成函数完成一个银行的账户管理。
17.
请定义一个函数,它在一个表示矩阵的两层数组里找出第一个元素值全为正的行。存在时返回这个行,否则引发ValueError异常。
18.
请定义一个函数,其参数是一个字符串,如果这个字符串满足Python浮点数的形式要求,函数返回相应的浮点数值,否则引发ValueError异常。
19.
采用字典的get操作重新定义6.3.7节的电话簿邮件地址提取函数。另外,也请考虑用描述式技术生成所需的表。请比较这几种实现方式。
20.
请参考6.3.7节的讨论,定义一个提取电话簿中邮件地址的生成器函数,使之可以作为迭代器使用,每次对其调用next给出一个人的姓名和邮件地址。
21.
假定文件里有一些学生成绩,现在希望通过比较形象的方式了解学生成绩的分布情况。一种简单做法是写一个程序,要求它输出一种字符直方图。
所谓字符直方图就在每行中连续输出某个字符,用字符的多少(排列的长度)形象地表示被统计量的多少。例如,假设不及格的学生有10个,60~79分的学生有100个,80~100分的同学有80个,从下面的输出可以很直观地看清情况:
00~59 10|X
60~79
100|XXXXXXXXXX
80~100: 80|XXXXXXXX
请定义一个函数,它能对任意一组成绩数据生成字符直方图(为此需要为学生成绩设计一种表示方式),而后写一个程序从学生成绩文件生成这种直方图。注意,学生成绩可能很多,我们不希望直方图中代换柱形的字符序列超长并换行。请考虑并正确处理这个问题,保证直方图中最长行的长度不超过(例如)60个字符。
22.
6.4.1节讨论了生成随机的英文文本的技术,但没有完成一个完整可运行的程序。请参考那里的讨论,补充一些具体考虑,完成一个通过随机方式生成英文文本的程序,然后基于一两个现成文本做试验,观察生成的效果。
23.
请参考6.4.1节的讨论,补充一些具体考虑,完成一个通过随机方式生成中文文本的程序,然后用一两个现成的文本做试验,观察生成的效果。
24.
如6.4.1节讨论马尔可夫链算法时所言,不采用特殊前缀开始也可以完成这个程序。请完成相应的程序,并将它与正文中的程序比较。
25.
请推广6.4.1节的马尔可夫链算法,增加一个表示算法阶数的参数degree,并修改原来的程序,使它可以对任意自然数n实现n阶的马尔可夫链算法。
26.
6.4.1节介绍过,对一个特定的文本,如果前缀足够长,就会出现每个前缀的关联词都唯一的情况,满足这一情况的最小前缀长度n称为这个文本的阶数。显然,文本的阶数从一个角度反映了文本的复杂程度。请基于前一题已经实现的功能开发一个程序,它用不同的阶数试验同一段文本,得到原文本的阶数。
27.
设法修改6.4.1节基于马尔可夫链的文本生成程序,加入对分段的处理。也就是说,如果原文件中出现换行,应设法在word_dic里记录这种信息,使得程序产生的输出中也能“随机地”出现换行,形成分段。
28.
请参考6.4.1节的马尔可夫链算法程序,实现一个生成中文文本的程序。它根据一些文本中汉字的上下文关系生成带有随机性的中文文本。
a)
请用这个程序读入一批古诗词,生成出一些文本,观察效果;
b)
修改程序,使之能从前期读入的古诗词中(随机选取)某一首的头几个字(根据阶数),从它们开始生成一段文本。
c)
设法改造你的程序,使之可以生成七律或者七绝,也就是说,总是7个字一句,四句或者8句作为一个生成单位。
d)
找一些中文的“朦胧诗”做类似试验,并根据需要完善你的程序。
e)
与你的同学比赛,选出程序生成的“最佳诗文”。
注意,这里的若干问题也需要设法自动生成换行,以便生成的文本更像真实文本。如果处理诗词,这件事就更重要。请提出方法并解决这个问题。
29.
请设法扩展6.4.1节中基于语法的句子生成程序,加入形容词、介词短语、副词、子句等更加复杂的英语句子结构。
30.
请为6.4.2节的电话簿程序增加一些有用的操作。
31.
请改用直接判断的方式实现的6.4.2节的电话簿程序的命令解释(不采用数据驱动技术),并尽可能简化程序的描述。加入你在上一练习中对这个程序的扩充。请将这种实现与正文中采用数据驱动技术的命令解释器做比较。
32.
修改电话簿程序,改用标准库pickle包提供的功能保存和恢复数据。对比同一程序的两个实现,看看减少了多少代码。
33.
仔细检查6.4.2节或6.5.1节的电话簿程序,找出其中可能的薄弱点并修正它们,保证无论用户怎样使用,这个程序总能正常运行并正常结束,不会崩溃。
34.
参考6.4.4节有关with语句及其文件应用的有关讨论,考察本章正文中给出的示例程序,以及你在学习中自己写的程序。看看哪些程序有可能出现不能保证关闭文件的情况。请修改这些程序,消除其安全缺陷。
35.
检查本章正文中的程序实例,看看哪些程序可以用with语句改造和简化。选择一两个实例,实际完成这一改造。比较改造后的程序和原来的程序。
36.
请定义一对功能与系统内置函数map和filter完全一样的函数。它们应返回迭代器(而不是序列),map也允许多元函数作为参数,带有适当个数的序列参数。
37.
请定义一个函数,其参数是一个字符串的表,每个字符串是一个Python程序文件名。该函数读入这些文件,统计其中各个Python关键字出现的次数。
38.
请写一个程序(其中定义适当的函数)统计你从开始学习本书至今总共写多少行Python代码,其中有多少注释行,多少空白行,多少个非注释且非空白的字符,以及各Python关键字的使用情况。程序最后输出得到的信息。输出关键字情况时先输出用过的关键字及其使用次数,再输出还没用过的关键字。
注意,用标准库包os的函数listdir可得到一个目录下的文件名表。如果你的 .py文件和本程序都在同一目录下,程序运行时它们都在“当前目录”下,工作比较方便。如果你的程序分别放在一些子目录下,请参考本章最后补充材料一节中有关“其他文件操作”的介绍。如果程序里有中文应注意文件打开方式。
请用你的程序统计IDLE的所有源文件的情况。这些源文件在Python系统目录的Lib子目录下,自己设法找到其位置并完成统计工作。
39.
请些一个程序,用它检查在你开始学习本书后写出的所有程序里,统计其中各种名字(即,非关键词,非标准函数名等,应包括程序里所有的变量名、函数名等)的使用情况。结果应包括:你总共用过多少个不同的名字,各个名字出现的次数,最常用的几个名字。你还可以分别对每个文件做这种统计。请分析得到的结果,讨论你的程序书写习惯是否合理。如果不合理,你应该如何改进。
40.
请为浮点数矩阵设计一种表示形式,并针对这种表示定义几个函数,包含求两个矩阵之和与求乘积的函数,求方阵的行列式值的函数,还可以考虑其他函数。请为矩阵设计一种正文文件表示形式(注意,矩阵可能任意大)。然后定义两个函数完成矩阵的输出和输入。还请定义一个检查矩阵表示合法性的函数,一个判断是否方阵的函数。请注意,直接用行列式求值的数学定义将得到一种非常慢的行列式算法(请估算一下,计算一个10*10矩阵的行列式时,需要构造出多少个9*9行列式,多少个8*8行列式等),合理的算法采用高斯消元法(也请估算一下计算10*10矩阵的行列式,需要做多少次加减和乘除)。
41.
Python标准库的Program Framework栏目下有一个图形包turtle,它模拟了著名的logo语言的一些功能。请自己查阅Python文档,阅读该程序包的说明,并基于这个包写几个程序,画出(至少)3个有趣的图形(自选图形)。
42.
请利用turtle包的功能重新做第21题学生成绩直方图的工作。