“计算概论”作业

作业和代码诚信声明

参加本课程学习的同学,通过教学网提交作业,即被自动假定是做出了下面的诚信声明:

我声明所交作业和代码为本人根据课程作业的要求独立完成。任何他人(包括同学,助教)的重要帮助,出自其他来源(包括但不限于互联网)的所有内容,都已在所提交的文件中明确声明并致谢。

注:程序文件中的致谢可以用注释的形式写,即 # 开头的程序行。


作业基本要求

  • 程序文件和其他作业都要标明姓名和学号。程序请尽可能写得清晰规整,加上必要注释;
  • 作业应该在要求的截止日期前通过教学网提交。超过日期一周之内,成绩递减1/2,其余类推;
  • 请将独立的程序文件通过上载,其他作业可用DOC或PDF格式的文件,同样上载。
  • 为各位同学指定的辅导老师见下面和 “课程通知”
  • 文件开头一律用 Python 注释形式提供下面信息:
    # 姓名
    # 学号
    # 完成作业所用时间(估计)
    # Computing 序号
    
    其中的“姓名”,“学号”和“完成作业所用时间”和“序号”填入具体信息。“序号”就是第一次作业写 1,第二次写 2。如果一次作业有几个文件,分别标明 1.1, 1.2 等。

    注意事项:

    1. 作业中有些题目要求定义函数。请在每个函数定义后面附几行代码,调用所定义函数做一些典型计算,并用 print 以容易看明白的方式输出计算结果(产生的输出行中应说明输出的是什么)。
    2. 请只用布置作业时已讨论的 Python 语言机制完成作业,使用其他“高级”机制将适当扣分。

程序作业成绩判定的基本规则

  • 程序文件应能用 Python 3.4 系统正常处理,实现所需功能,执行中不出现不应该出现的错误(80%);
  • 所用的计算方法合理有效(10%);
  • 代码清晰易读,格式合理(10%);
  • 请特别注意完成题目要求的所有工作,如有遗漏将根据情况扣分。
2015年春季辅导教师:
程海波 分工负责:学号14001602-14001646
李季 分工负责:学号14001647-14001685
张鹏浩 分工负责:学号14001686-14001719
甘锐 分工负责:学号14001720以上及其他同学
序号 布置日期 提交日期 作业内容
13 6.8 6.18 请完成下面练习:

1,任选题:做一个你认为有趣的程序,除程序文件外另提交一个doc或pdf文件,其中说明你做的是什么,怎样使用。

2,选择一个你原来做的程序,为其配一个图形用户界面。

12 5.29 6.4 请完成下面练习:

1,基于你上次有关矩阵的工作定义一个矩阵类,其中定义一组适当的方法。用注释说明所定义的方法,并用几个例子表现该类的使用和效果。

2,请基于 Person 类定义几个为公司人员管理系统使用的类,包括一个一般雇员类 Employee,一个工人类 Worker 和一个管理人员类 Manager。写一段代码调用这些类的功能建一个小公司的人员表,并用 print 函数输出一些说明公司情况的信息。

11 5.21 5.28 请完成下面练习:

1,写一个程序(其中定义适当函数)统计你本学期至今总共写了多少行 Python 代码,包含多少注释行,多少空白行。写了多少非注释的非空白字符,及使用各 Python 关键字的使用情况。程序最后输出非注释且非空白的 Python 程序行数,非注释的非空白字符数,以及程序里使用各 Python 关键字的次数(请注意哪些关键字还没用过)。
注意:标准库包 os 里有一个函数 listdir,调用它能返回一个目录(默认为 “当前目录”)下所有文件名的表,这是一个字符串的表。利用它就不需要自己写具体文件名了(如需要请查 Python 文档等);另外 s.endswith(".py") 检查串 s 是否以 ".py" 结尾。把你的 .py 文件和这个程序放在同一目录下,程序运行时这些都在“当前目录”下,工作比较方便。请先检查原有的程序代码,尽量使统计结果准确。统计结果用注释形式包含在上交的程序文件里。如果程序里有中文应注意文件打开方式。
再用你的程序处理一下 IDLE 的所有源文件,做同样统计。这些源文件在 Python 系统目录的 Lib 子目录下,自己设法找一找。用标准库库 os 里的函数 chdir(path) 可以把当前目录转到用“path”指定的目录下,然后事情就很简单了。注意,在用字符串描述 Windows 的文件目录路径时,作为路径分隔符的反斜线字符需要双写,因为反斜线符是 Python 字符串里的特殊字符,要在字符串里写它就必须双写。例如 c:\python34\Lib 可以写 "c:/python34/Lib"。

2,请为浮点数矩阵设计一种对象表示的形式,针对这种形式定义两个函数,一个求矩阵的行列式值,另一个求两个矩阵的乘积。设有正文文件里保存着两个浮点数矩阵的数据,文件里的一行对应矩阵一行(一串浮点数,两个浮点数之间用空格分隔),两个矩阵之间用一个空行分隔(如 示例文件 data2.dat)。请写一段程序,它从指定文件读入两个矩阵,求出它们各自的行列式值,并求出两个矩阵的乘积。还请另定义一个检查矩阵表示的正确性的函数。在提交的作业文件里,请用注释说明你采用的矩阵表示形式(例如是一个表,或者其他复合对象等)。注意,直接按矩阵行列式求值的基本数学定义,会得到一种非常慢的算法(请估算一下,在计算一个10*10矩阵的行列式时,将构造出多少个9*9行列式,多少个8*8行列式等等),一种合理算法是采用高斯消元法(请顺便估算一下计算10*10矩阵的行列式,需要做多少次加减和乘除)。

10 5.14 5.21 请完成下面练习:

1,修改课堂介绍的统计文本中单词出现频率的程序,设法去掉各种标点符号等不属于单词的字符,使之能更好完成统计工作。建议把矫正被统计单词的功能定义为函数 clarify(word),它处理直接切分得到的 word,返回矫正后的单词,这样可使对原程序的直接修改最少,也更容易改变单词的矫正方法。原程序文件见课件页,这里有一个试验数据文件(海明威的《太阳照常升起》book 1 文本)。编程中可能用到一些字符串操作,请参考课题幻灯片和 Python 文档。修改函数行为方式,如果调用时给了统计文件名参数,函数就将统计数据存入文件;否则这个函数返回做出的字典。请另外定义一个函数,它调用上述统计函数,并在屏幕上输出(用print)这篇文章中使用最多的20个单词及其使用次数。请考虑如何利用系统函数sorted完成这一工作。

2,请开发一个猜单词游戏程序:程序启动后从一个事先准备好的文件里读入一组单词(用一个单词表),然后进入游戏状态。做每轮游戏时程序从这些单词里随机选出一个。一轮游戏包含若干回合,每个回合程序从单词中随机选出一个字母,输出该字母及其在单词里的位置作为提示。如果用户认为已经猜到,就输入所猜的单词,前面写一个叹号“!”,程序评判其对错并记录有关信息。如果用户觉得无法猜出结果,可以输入一个单独的问号“?”要求程序继续给出提示。基于提示次数和单词长度设置一种失败阈值,要求提示的次数超过这个值即认为本轮游戏失败,程序输出被猜单词后结束本轮。一轮游戏结束后用户输入命令“quit”时程序结束,此时输出一组统计信息:本次游戏共猜了几个单词,正确和错误统计,平均每个单词要求了几次提示。

9 5.7 5.14 请完成下面练习:

1,考虑下面游戏:n 个人围成一圈,每次游戏随机取两个数 m 和 k。游戏开始,从编号为 m 的人开始计数,数到第 k 个人出列。然后再从出列的人之后数下去,直到圈子里只剩一个人为止。请写一个函数 CGame(n, m, k) 模拟这个游戏:围成一圈可以用计数到最大的编号后重新回到最小编号值来处理。

2,请定义一个生成器函数,它顺序检查一段文本(一个字符串),挑选出在文本中遇到的所有长度超过 8 个字符的单词,顺序 yield 出这些单词。在定义这个生成器时不使用 split 等函数构造字符串(不调用任何可能构造字符串的函数或操作),只用从字符串中取字符的操作(即,s[i])检查字符串内容,用 s[i].isspace() 判断是否空白字符(空格,换行等)。也就是说,你的生成器应设法确定字符串中顺序的由空格分隔的段,做出正确切片字符串(单词)。为简单起见,文本中的标点符号也看作单词内容。定义函数后,请用上次课(4.27)代码文件里的 “Python 语言说明”作为例子试验这个函数的功能(拷贝到你的程序文件里)。

3,在 Python 标准库的 Program Framework 栏目下有一个图形包 turtle,它模拟了著名的 logo 语言的一些功能。请自己查阅 Python 文档,阅读该程序包的说明,并基于这个包写一点程序,画出(至少)3 个有趣的图形(自选图形)。请在程序文件里用注释的形式说明你做的工作。

8 4.30 5.9 请完成下面练习(表和字符串):

1,定义函数 squeeze(list1, list2),两个参数都是整数的表。squeeze 从 list1 里删除所有比表 list2 里的某个整数大 1 的数。注意,这个函数不适合采用简单的 for 循环实现(因为删除元素导致被处理表的长度和内容都变了)。如果你想试试,请用一些例子试验,注意观察计算中出现的情况。

2,写一个函数计算并输出直至第 n 行的杨辉三角形。(这里特别的不要求输出形式,但杨辉三角形的一行应输出在一行,整数之间用空格分隔。)

3,定义函数 disjoins(lst),其参数是一个表。这种表的元素都是形如 [a, b] 的包含两个整数的表,表示数轴上的一个闭区间。disjoins 返回一个表,其中包含从 lst 中选出的一组(最大的)不相交区间(也就是说,如果你选了一个或几个区间,它们应互不相交,而且没选的区间里不存在与它们都不相交的区间。本题目不要求考虑区间的总长度最大等其他问题,可以作为自我练习)。

4,考虑模拟一个金属杆上的热传导过程。杆的左端有一个100度的稳定热源,右端有一个70度的稳定热源。将杆分为10段,除两个端点外,其余分段点的初 始温度都是0度。通过一轮轮计算模拟热传导的过程,每个点的下一时刻温度是其自身与其左右两个相邻点当前温度的平均值。(1),请输出前10轮传导的过程 杆上各分段点的温度情况;(2),确定通过多少轮传导后杆上各点的最低温度超过了60度,并输出在此期间每5轮传导后的情况。请用 Python 的格式化功能把输出排列整齐。

7 4.23 4.30 请完成下面练习(请注意题目要求):

1,请用表描述式生成包含下面元素的表:

  • 100 以内 7 的所有倍数的平方根。
  • 一个半轴长 1,3,6,7,另一半轴长 14,8,9,11 的所有椭圆的面积。
  • 类似上表,但只对两个半轴长度之和是偶数的求出面积。
  • 对角线元素全为 0 其他元素全为 1 的 20*20 矩阵,用元素是 list 的 list 表示。例如 [[1, 2], [3, 4]] 是一个 2*2 矩阵。
2,写一个函数 prime_factors(n),它返回一个表,其中包含正整数 n 的所有素因子(重复的因子在表中重复出现)。

3,请定义函数 rem_duples(lst),它基于 lst 构造并返回一个新表,其中按 lst 里原来的顺序包含了 lst 的所有元素值,但消除了重复出现。例如,rem_duples([1, 4, 3, 2, 4, 2, 4, 4, 0]) 的结果应该是表 [1, 4, 3, 2, 0]。注意,要求不修改作为实际参数的表。

4,请开发一个程序包(一个 Python 文件),其中采用课堂上讨论的简单的一元多项式表示法(表示为系数的表),包里除包含多项式的求值函数外,另请定义多项式求和,多项式求乘积,多项式求负,以及多项式输出函数。你可以根据自己的喜好设计多项式的输出形式(假设其自变量是 x),还可以考虑定义其他函数。请在文件里包含几个利用你的函数做多项式计算的例子,在文件最前面用注释的形式说明完成了哪些工作。

6 4.9 4.16 请完成下面习题:

1,请设法找到辛普森(数值)积分公式,并定义一个基于辛普森公式做数值积分的函数,其中采用课堂提出的逐步加细划分的方法,通过多次求数值积分逼近函数的实际积分值。请写出几个用你的函数完成积分的实例。

2,蒙特卡罗积分是利用随机试验求函数的数值积分的方法。请考虑定义一个蒙特卡罗积分函数 mt_int,通过生成平面上区域 [x1,x2] * [y1,y2] 里的随机点数据,检查其位于被积函数 f 的值之下的比率,得到函数积分的近似值。

3,赌场有一种游戏称为“幸运七”,说你丢两个骰子,如果它们点数之和为 7 你就赢 4 元,如果不是 7 你输 1 元。请定义一个函数模拟这种游戏,看看赌场的规则是否“公平”。另外,请定义一个函数 lucky7(a, b),其中 a 表示你的初始赌资,b 是你准备见好就收的款额。函数模拟“幸运七”游戏,直至你的赌资输光或者你手头的钱超过 b。函数结束之前打印出过程中的投骰子次数,曾经达到的最高和最低款额。

5 4.2 4.9 请完成下面习题:

1,利用课堂给的代码,比较采用二分法求立方根和采用立方根逼近公式两种计算的操作效率。定义函数对给定范围中等差的值检查它们的迭代次数,并生成出比较结果的表格。

2,修改递归的 fib 函数,使之能借助一个全局变量(或非局部变量)统计出在计算 fib(n) 的过程中函数调用的总次数。请写另一个函数,它用一些正整数值调用修改后的 fib,输出相应的斐波那契项的值和相应的函数递归调用次数。你看到了什么情况,请在程序文件里用注释说明?

3,写函数 draw_4square(m, n),它输出用字符 "-", "|", "+" 拼出的“田”字,四个小方块的长度和宽度分别为 m 和 n 个字符或行数。例如,drawTian(4, 2) 输出下面的“田”字:

+----+----+
|    |    |
|    |    |
+----+----+
|    |    |
|    |    |
+----+----+
基于你完成上面函数的认识定义另一个函数 draw_board(m, n),它能生成用同样三个字符拼出的 m * n 个格子的棋盘(例如 8*8 个格子的国际象棋棋盘)。请注意在工作中定义有用的辅助函数。注意,为了保证空格和各种字符宽度相同,以便输出字符对齐,应该把 Python Shell 的窗口设置为采用某种等宽字体输出(在 Options 菜单里的 configure IDLE下设置字体,例如用 consolas。苹果机在 File 菜单的 preferences 菜单项下)。

4 3.26 4.2 请完成下面习题(注意,定义函数的题目需要给出使用实例):

1,哥德巴赫猜想说任一大于等于 6 的偶数可以分解为两个奇素数之和。请利用课堂给出的素数判断函数定义一个函数,它对 6 到 n 的偶数输出其素数分解。请设法保证每个偶数只输出一种分解。
请尝试不用素数判断函数,直接写出这个函数的定义。并用注释的形式简单比较这两个函数。

2,如果一个正整数 m 的所有因子(包括 1,但不包括 m 自身)之和 s 等于 m,则称 m 为完全数;如果 s < m 称 m 为亏数;如果 s > m 称 m 为盈数。请定义一个函数,在参数 m 为亏数、完全数或盈数时分别返回 -1, 0, 1。基于这个函数定义另一函数,它检查 a 到 b 范围里的整数,统计其中亏数、完全数和盈数的个数并输出。最后调用你定义的函数统计几个范围里的整数的情况。

3,函数 f(n) 由如下规则定义:当 n 小于 3 时,f(n) = n;对于更大的 n,f(n) = f(n-1) + 2 * f(n-2) + 3 * f(n-3)。请采用递归的方式直接定义一个计算 f 的函数,再按照递推的方式用循环结构定义一个计算 f 的函数。

4,假设需要从很长的钢条上剪裁出长度为 5 厘米、8 厘米、17 厘米和 28 厘米的短条。请写一个函数,它计算出从长度为 n 厘米的钢条上裁出这些短条的不同方式的数目,要求浪费的钢条长度不超过 3 厘米。(注意:裁短钢条的不同方式与顺序无关。请考虑如下递归看法:从长 n 钢条上剪裁的不同方式等于...)。在上交的程序里用注释形式论述你的做法的正确性。请在你的函数定义之后调用你的函数求出对 100,160 和 240 长的钢条的计算结果,以清晰明了的形式产生输出。

3 3.19 3.26 请完成下面习题:

1,请定义一个函数 prime_factors(n),它确定正整数 n 的所有素因子,并调用 print 逐个输出,重复的因子重复输出。请在函数开始检查参数情况,只对满足要求的参数计算。

2,请利用(修改/使用)课堂上讨论的有关 Collatz 猜想的函数,定义三个函数:第一个函数返回(注意,不是输出)对正整数 n 做 Collatz 计算的过程中历经的最大值。第二个函数检查 m 到 n 的所有正整数,输出其中造成 Collatz 函数迭代次数最多的数 k 以及它的迭代次数;第三个函数检查从 m 到 n 的所有正整数,找出其中的 k,在对 k 的迭代中历经的最大整数值比其他数都大,输出 k 和对它的迭代中达到的最大数值。

3,用下面方法可以为一段计算计时:

from time import time
t = time()
... ... # 你的计算
t = time() - t
# 这时变量 t 的值是两次调用 time() 之间经过的时间,以秒计。
请写程序计算调和级数的部分和,检查这个“和”在你机器上达到 10, 11,..., 16, 17, 18 时所用的时间,输出这些结果。你看到了什么情况?(请在你的程序文件里用注释的方式说明试验的情况)

注意事项:

作业中有些题目要求定义函数。请在每个函数定义后面附加几行代码,调用所定义函数做几个典型计算,并用 print 以容易看明白的方式输出计算结果(产生的输出行中应说明输出的是什么)。

请只用到布置作业时已经讨论过的 Python 语言机制完成作业,使用其他“高级”机制的作业将适当扣分。

2 3.12 3.19 请完成下面练习:

1,写一个程序,它对 0 到 90 度之间(包括两端点)每隔 5 度的角度,在一行里输出角度值以及其正弦、余弦函数值。

2,写一个程序,它用等差的一系列值比较 math 包的求平方根函数和课堂给出的求平方根程序,在一行里输出一对两个函数值和它们之差的绝对值,并在最后输出误差的平均值。请以比较清晰的方式输出。

3,写程序计算连分式 1 + 1 / (1 + 1 / (...(1 + 1 / (1 + x)))),是有 n 层嵌套的连分式。其中的 n 和 x 由输入得到。

4,写一个二进制浮点数转换计算器程序,通过输入送给它任意一个包含(一个)小数点的二进制串,它求出相应的浮点数并输出。该程序应反复读入二进制串并输出,直到人输入特殊的串 end。(注意,人输入三个字符 end 并按 Enter 键,input 函数返回的串相当于写 "end",用 == 运算符可以判断两个字符串是否相等。)

13.5 - 本次作业不交,作为自我练习。通过做这些题目检查自己对教学内容的理解,学习基本的编程过程,熟悉用 Python 编写程序的基本过程。注意,完成一个程序不仅是写出一段代码,还应该确认它具有所希望的功能,需要用一些具体数据试运行程序。

题目:

  1. 利用 Python 的 math 包检验几个三角恒等式。用具体数值检验,计算等式两边的值和它们的差。可以在代码里写好具体数值,也可以通过人输入。可以考虑下面写法,以便执行时看到具体情况:
    	a = ... # 计算恒等式左边的值
    	b = ... # 计算恒等式右边的值
    	print(a, b, a - b)
    
  2. 铁的比重为 7.86,金的比重为 19.3。请写一个程序,给它圆球的半径,它计算并输出具有该半径的铁球和金球的重量。
  3. 基于课堂上的求二次方程根的程序写一个程序,它验证初等代数给出的二次方程求根公式是正确的,求根程序给出的结果误差不大。
  4. 圆周率 pi 是 4/1 - 4/3 + 4/5 - 4/7 + ... 逼近的值,请写一个程序计算出这一公式前 n 项的值。
  5. 请写程序输出不大于 n 的所有不能被 7 整除但能被 3 整除的自然数。考虑用两种不同的方法完成这一工作。
-- - -

本页及相关页面(除另声明者外)由裘宗燕创建维护,可自由用于各种学习活动。其他使用需得到作者许可。