简介:这是一份《Python语言程序设计(刘卫国)》实验指导的部分答案文档,主要面向使用该教材的高校学生、自学编程的入门者以及需要布置上机练习的教师。文档按实验顺序整理了实验1至实验4、实验6至实验8中的代表性题目,对应Python基础语法、顺序结构、选择结构、循环结构、字符串与正则表达式、列表与元组、字典与集合等知识模块。每道题不仅给出可直接运行的代码,还补充了必要的分析说明,例如实验2中输入函数的eval用法与日期格式化控制、实验3中浮点数比较误差及round处理思路、实验7中元组不可修改引发的append报错等,便于读者理解关键点并排查上机中的常见问题。资源包共包含1个doc文档,大小145KB,内容紧凑,打开后即可按实验章节查阅。目前该资源已有6689人学习浏览,适合作为实验作业参考和考前复习的轻量备查材料。
1. 这份“实验指导_部分答案.doc”,值得你花一个晚上认真读一遍
很多人是从班级群、网盘或某个学长的“学习资料包”里翻出这份《python语言程序设计实验指导_部分答案.doc》的。第一反应是抄实验报告,十秒钟复制一段代码,然后被查重、跑不通、改到崩溃。我的看法恰恰相反:这类“部分答案”文档不是用来抄的,它是一张实验地图——告诉你哪些实验是重点、哪些答案能跑、哪些地方是故意留空等着你自己填。如果你还没做完课程实验,或正在补上机作业,这份文档能让你少走两三天弯路;如果你已经写完,它也值得拿来当验收清单和调试字典。接下来我按处理这类文档的常规流程,从拆结构、提代码、跑环境、避坑到改造,一步步说清楚。
2. 拆开文档看结构:答案在哪,缺失在哪
2.1 实验指导的常规模块划分,答案一般集中在哪几章
这种实验指导的编排基本跟着指定教材目录走,不会太跳。常见的顺序是:基础语法与输入输出、分支循环、字符串与正则、列表/元组/字典、函数与递归、文件读写、面向对象、异常处理,最后是一个综合设计,比如学生成绩管理、图书管理系统、简单爬虫或数据分析。不是每章都有完整答案,“部分答案”四个字已经说明:覆盖集中在前面基础模块,越到后面越稀疏。
拿到文档后别急着看代码,先做三步定位。第一步,打开文档的目录页;没有目录就分别搜“实验一”“实验二”这类关键词,数清楚一共几个实验。第二步,在每个实验标题下找“参考代码”“参考答案”“运行结果”等字样,标出哪些题有答案、哪些只有要求。第三步,把“有答案的题号”单独记一张表。我一般会画一个矩阵:横轴是实验编号,纵轴是知识点,答案覆盖用圆圈标出来。这张表就是你的止损清单——哪里能直接参考,哪里必须自己写,一眼就能看明白。
一个很常见的现象是:文档后面的答案其实是半成品,只有函数签名或几行注释,连缩进都丢了。这类半答案的价值在于告诉你“该用什么函数”,而不是“代码怎么补全”。所以读到后面时先降低预期,重点提取思路,不要期待粘贴就能跑。
2.2 参考答案的三种呈现形式,对应三种读法
同一份 .doc 里,答案呈现形式往往不统一,因为不是同一个人同一个时间敲进去的。我总结出三种常见形式。
第一种是完整代码块,通常用等宽字体或灰色底纹,能从import看到最后一行。这种答案可以直接提取运行,但要注意它是按作者当时的环境写的,缩进和编码都可能出问题。第二种是带>>>的交互式代码,像 Python Shell 截图。这类代码如果直接复制到.py文件里,提示符会造成语法错误,需要手工把>>>和...去掉。第三种是填空式答案,代码中间用下划线或高亮标记留空,比如for i in ____:。这种题往往就是老师故意留的,答上才能得分。
读法也不一样。完整代码,先把代码抄进编辑器,运行一遍,观察输出是否符合实验报告里的预期;交互式代码,把提示符去掉后当脚本跑,同时注意它背后“一步一步算”的过程;填空式答案,不要只看空格填什么,要问自己“为什么作者选这个变量名、这个边界条件”。这样读一遍,比直接抄十遍更能应对老师现场提问。
2.3 代码块识别不要靠肉眼:先看样式再看内容
Word 里的代码块在“样式”面板里通常有固定标记,比如字体是 Courier New、段落有左缩进、语言是 Python。直接用肉眼在大段题目文字里找代码,很容易漏掉短代码段,尤其是只有两三行的for循环。更稳的做法是先把视图切到“草稿/大纲模式”,关闭图片,再看段落缩进;或者在副本里把正文全部改成黑色,代码块因为带底纹会保留灰色,这样扫一眼就能定位。
如果你习惯用脚本处理,可以先用 2.1 里说的搜索方式把每个实验标题位置的“样式名称”记录下来。在 Word 中,代码块的样式名可能是“代码”“HTML 代码”或自定义样式。后续从 docx 提取时,直接按样式名过滤段落,比按文本内容猜要准得多。这也是为什么我不推荐一开始就转纯文本——纯文本会把样式信息全部丢掉,第 3 章的提取脚本就少了最可靠的线索。
2.4 “部分答案”意味着什么:利用目录反推缺口
既然叫“部分答案”,就说明一定有你必须自己补的题。这些缺口通常集中在三类:课程设计类、算法优化类、思考题类。课程设计类为了防全班一样,老师只给部分流程,不给核心函数;算法优化类会要求“用两种方式实现”,文档里通常只有一种;思考题类本来就不该有答案,因为它考的是报告里的文字说明。
所以拿到文档后要主动造一个“缺口清单”,而不是等卡住再找。我的做法是:把课程大纲或教材目录拿出来,对照实验指导的题目清单,逐条标出“文档里有没有答案”。标完后,按风险给缺口排序——优先补平时成绩占比大、上机随机抽测的实验,其次才是课后思考题。补缺口的顺序也有讲究:先自己写一版,再拿文档里有答案的相似题对比,看自己的代码和答案思路差在哪。这样到期末复习时,你已经有一份“自己的部分答案”,比原文档好用得多。
3. 把 .doc 答案变成能跑的程序:转换与验证
3.1 先转成 .docx 或 .txt:命令行一条龙
.doc 是旧版 Word 二进制格式,用记事本打开是一堆乱码,Python 的标准库也不能直接读。常见做法是先把它转成 .docx 或纯文本。我这里通常用开源办公套件的无头模式,直接在命令行转格式:
soffice --headless --convert-to docx --outdir ./converted "./python语言程序设计实验指导_部分答案.doc"这段命令的含义是:--headless表示不打开图形界面,--convert-to docx是转换目标格式,--outdir指定输出目录,最后的字符串是要转换的源文件。注意如果文件名里有中文或空格,必须用双引号包起来,否则 shell 会把它拆成多个参数。转换完成后,converted目录下会多一个同名 .docx 文件,后面就能用处理 docx 的库来读。
如果只想快速抽取文本,也可以转成纯文本:
soffice --headless --convert-to txt --outdir ./converted "./python语言程序设计实验指导_部分答案.doc"转出来的 .txt 排版顺序一般不会乱,但表格会变成一堆空格,图片里的代码块会完全丢失。所以如果文档里有大量“截图式代码”,转成 txt 后还需要对照原文档人工补;优先转 docx,再用脚本抽取才是更稳的路线。
3.2 用正则批量抽代码块:提取到 .py 文件
转成 .docx 后,可以用 python-docx 读取每个段落和样式。代码块在 Word 里通常有两种表现:一是段落字体为等宽字体;二是整段缩进或带灰色底纹。最省事的做法是先把所有段落写进纯文本,再用正则把像代码的行筛出来:
from docx import Document import re doc = Document("./converted/python语言程序设计实验指导_部分答案.docx") lines = [] for para in doc.paragraphs: text = para.text.strip() if not text: continue lines.append(text) joined = "\n".join(lines) # 匹配以>>>开头的交互式行,或行首有4个空格/tab的缩进行 pattern = r"^(?: {4,}|\t+|>>>\s?).*$" code_chunks = re.findall(pattern, joined, flags=re.MULTILINE) with open("extracted_code.py", "w", encoding="utf-8") as f: f.write("\n".join(code_chunks))这段脚本的逻辑是:先遍历所有段落,去掉空行;再用多行正则找出“以四个空格、Tab 或 Python 提示符开头”的行,把它们拼接写入.py文件。re.MULTILINE参数保证^能匹配每一行开头,而不是整个文本开头。这样抽取出来的代码比手动复制快得多,但不会完美——如果文档在代码块里用了【】做高亮,或代码行前面有行号,正则就没法一步到位,抽完要靠肉眼把行号和说明文字清干净。
如果你发现正则抽出来的代码断得很厉害,说明文档里的代码并不是缩进开头的,这时回到 docx,改用“字体名过滤”更可靠:
from docx import Document doc = Document("./converted/python语言程序设计实验指导_部分答案.docx") code = [] for para in doc.paragraphs: for run in para.runs: # 等宽字体一般是代码块常见标志,按实际情况调整 if run.font.name in ("Courier New", "Consolas", "等线 Light"): code.append(run.text) print("\n".join(code))这段代码把字体名符合要求的 run 文本拼起来。缺点是同一个段落里可能混着正文和代码,去重和顺序需要人工确认。两种方案选一种即可,我的习惯是先用正则跑一遍,抽不出来的再用字体定位,最后总是要人工过一眼。
3.3 运行结果与文档结论不一致时先查什么
代码抽出来,第一件事不是改,而是跑一遍,直接用最原始的“python 文件”方式,而不是在交互式环境里粘贴:
python extracted_code.py如果报错,按下面的优先级查。先查 Python 版本:文档里的代码如果写着print "hello"或xrange,那是 Python 2 的语法,在当前环境跑必挂。再看编码:文件头有没有# -*- coding: utf-8 -*-,代码里有没有u'中文'。很多旧答案是 GBK 编码存进去的,直接跑可能报UnicodeDecodeError。最后看输入:如果代码里有input(),运行到那里会等键盘,这在自动化跑批时会被误判成卡死,需要用交互输入或重定向输入文件。
我的习惯是给每一个抽出来的代码文件建一个同名.in文件,内容就是它需要的输入数据;运行命令变成python extracted_code.py < test.in。这样既能复现输出,也能在验证时把结果存下来。等这些都跑通了,这份文档对你就从“参考”变成了“可验证的基准”。
4. 照答案跑实验的 6 个避坑点:血泪经验都在这里
4.1 全角空格让缩进秒变 SyntaxError
现象:从 Word 复制代码到编辑器,怎么看都对,一运行就报IndentationError: unexpected indent。
原因:Word 在自动排版时会在行首插入全角空格(U+3000),Python 解释器不认它,只认普通空格和 Tab。
解决:用编辑器开正则替换,搜索[ ](半角加全角空格),全部替换为普通空格;或者直接在命令行跑sed -i 's/ / /g' extracted_code.py。注意替换后重新检查缩进层级,避免全角空格换成空格后缩进对不齐。这个问题最容易出现在代码块前面有编号或项目符号的段落,抽代码时先删掉行首的序号再写文件。
4.2print后面的括号,暴露了 Python 2 血统
现象:文档里写print "total:", total,在 Python 3 里运行直接报SyntaxError: Missing parentheses in call to 'print'。
原因:老教材和旧答案大量基于 Python 2,而现在教学环境基本是 Python 3。
解决:不要一个个改,写个小脚本批量把print "xxx"转成print("xxx"),但要注意print "a", "b"转成print("a", "b")输出会多个空格,对格式敏感的实验要手工校核。更好的办法是先把文档里的代码放在一个临时的 Python 2.7 虚拟环境里跑一遍,拿到基准输出,再决定要不要迁移到 3。很多情况下,你并不需要完全迁移——只把明显语法错误修掉,实验报告里说明“原答案为 Python 2 语法,已在 Python 3 下调整”反而能加分。
4.3 教材配套环境版本偏老,第三方库装不上
现象:文档要求import PIL或import scipy,用最新版 Python 安装失败或运行报错。
原因:文档作者当时的库版本接口跟现在差别很大,比如 PIL 已经被 Pillow 取代,scipy.misc在较新版本里被移除。
解决:优先按要求装兼容版本,常见做法是pip install pillow==9.2.0这类固定版本,但不要盲目追新。如果你的项目需要跑旧代码,用 venv 建一个独立环境,把库版本锁进requirements.txt,避免污染全局环境。还有一个容易被忽略的点:某些库在 64 位 Python 下没有预编译轮子,需要编译器,这时换个 Anaconda 环境通常比硬装快得多。
4.4 文件名和模块名带中文、空格、括号
现象:把文档里的代码存成第3题.py,运行没问题,但一旦import给别的代码用就报错。
原因:Python 的模块导入要求文件名是合法标识符,中文、空格、连字符都不能作为包名或模块名。
解决:所有从 .doc 里提出的代码统一重命名成小写字母加下划线的形式,比如exp2_q1.py。同时把代码里出现的#!/usr/bin/python之类路径注释去掉,因为它在 Windows 环境不是必需,还可能造成干扰。如果文档里已经出现了import 第3题这种写法,说明答案作者自己也没跑通过,直接改成合法模块名。
4.5 实验报告直接粘贴答案,查重系统一眼识破
现象:实验报告交了,查重率 87%,被要求重写。
原因:全班都拿着同一份“部分答案”,查重系统会把相同代码段标红。
解决:抄之前先把代码重构成自己的风格。具体做法是:改变量名、拆函数、加注释、把多行写成一行的循环拆开,这些操作不影响运行结果但能改变语义结构。更重要的是,实验报告里除了代码,必须写清楚“为什么要这样设计”,这就倒逼你去理解答案,而不是复制。记住一个原则:粘贴的代码最多占报告代码量的三分之一,剩下三分之二必须有你自己的改动和解释。
4.6 自动化测试遇到input()卡住,不是程序死循环
现象:脚本跑批时,执行到一半停住,CPU 是 0%,像死锁。
原因:答案里有input()或raw_input(),程序在等待标准输入,但批处理脚本没有给它喂数据。
解决:提前构造输入文件,运行命令改为python exp2_q1.py < data.in;或者写驱动脚本时用subprocess.run(..., input="3\n5\n", text=True)传输入。这样不仅能在命令行验证,也能接入自动化验证流程。我在检查这类代码时,通常还会顺手把input()里的提示参数拿掉,避免测试日志被提示语刷屏。
5. 把“部分答案”当成你自己的实验模板来改造
5.1 从答案反推实验要求,先写思路注释
文档里的答案代码通常没有注释,或者只有一行题号。我拿到一个能跑的答案后不会直接写报告,而是先把它“讲回人话”。做法是在每段代码上面加三行注释:这步在解决什么、输入是什么、输出格式是什么。举个例子,假设文档里有一个统计字符串字母个数的答案,常见的原生写法可能是:
s = input("input a string: ") count = 0 for ch in s: if ch.isalpha(): count += 1 print(count)如果为了实验报告,我会把它改写成带注释的版本:
# 实验要求:统计字符串中英文字母个数,忽略数字和符号 # 输入:一行字符串;输出:一个整数 s = input("input a string: ") count = sum(1 for ch in s if ch.isalpha()) print(count)这样改完,报告里的“程序设计思路”就有话可写,而且代码逻辑更紧凑。注意不要为了“看起来不一样”刻意把isalpha()换成 ASCII 判断,除非你能解释边界差异,否则老师一问反而露馅。
5.2 把代码从“脚本”改成“函数”:为了以后能复用
实验指导里的答案大多是脚本式代码,从上到下跑完就结束。真正的项目里不会这么写,所以我习惯把核心逻辑抽成函数,把交互输入移到main块。以上面的统计为例:
def count_alpha(s: str) -> int: return sum(1 for ch in s if ch.isalpha()) if __name__ == "__main__": s = input("input a string: ") print(count_alpha(s))这样改造最大的价值不是格式,而是可测试性:你能直接从另一个脚本import这个函数,给它传不同输入验证边界,而不是反复用键盘敲。参数说明:s是输入字符串,返回整数;类型标注-> int只是为了可读性,Python 并不强制。把input()放在if __name__ == "__main__"下面,是为了避免别人 import 这个模块时也会卡在输入上,这是一个非常实用的边界习惯。
5.3 用测试用例让改造结果“可见”
改造完没有验证等于白改。我一般会顺手写一个极简的测试文件,用标准库的unittest,跑起来不需要额外依赖:
import unittest from exp2_q1 import count_alpha class TestCountAlpha(unittest.TestCase): def test_basic(self): self.assertEqual(count_alpha("hello 123"), 5) def test_chinese(self): self.assertEqual(count_alpha("你好abc"), 3) if __name__ == "__main__": unittest.main()用python -m unittest test_exp2_q1.py -v运行,看到OK才算答案真正属于你了。这一步看起来花时间,但期末上机抽测时,你能告诉老师“这个函数我测试过边界”,比背答案扎实得多。如果你的实验被自动评测脚本检测,这个测试文件还可能直接帮你定位边界错误,比如空字符串、全数字、大小写混排。
6. 让这份文档的价值翻倍的三个小习惯
第一个习惯:每个答案代码都跑一遍并截图存证。别高估自己的记忆,一周后你可能忘了哪个版本跑通了。我习惯在实验文件夹里放一个screenshots子目录,把每次运行结果截图命名成exp2_q1_before_edit.png,报告需要的时候直接取用,不用重新跑或重新截。截图还能帮你在和老师核对时省去“打开文件再运行”的等待时间。
第二个习惯:用 git 管理你从文档提取出来的“答案库”。即使是课程作业,也建议git init后按次提交。改了缩进、修了语法、加了一段注释,都提交一次。这样万一改坏了,随时有后悔药;更重要的是,你能从提交记录里看到自己是怎么把一份“部分答案”逐步变成完整理解的。提交信息不用写得多规范,fix print,add test这种就够。
第三个习惯:实验报告里永远写“我改了什么”,而不是“答案是这段代码”。老师真正想看的不是你能背出答案,而是你能不能把答案消化成自己的。每次粘贴代码前,先补一段“原答案的不足”和“我的修改理由”,哪怕只改一个变量名,也要写清楚为什么。这会逼着你把每行代码都看懂。
说到底,文档只是原料,真正值钱的是你加工它的过程。我之前带过的A同学,把同一份文档里的三个答案用函数重写后互相调用,最后做出了完全不一样的小项目,平时分先不说,期末上机抽测直接一遍过。我虽然没有这种运气,但养成了一个习惯:拿到任何一部分答案,先跑通、再拆开、再按自己的方式组装,一步都不省。这个方法已经帮我应付过很多次“老师突然要检查”的场面,希望也能帮到你。
本文还有配套的精品资源,点击获取