简介:工程热力学是能源动力类专业的核心基础课,这份PDF为期末考试题资料,适合正在复习备考的本科生及需要梳理知识框架的初学者。资源为单个PDF文件,大小仅28KB,可直接打印或导入移动端随时刷题。文件内按判断题、填空题、问答题、计算题四大部分编排,完整覆盖热力学第一定律、第二定律、熵产与作功能力损失、理想气体状态方程、水蒸气临界压力、朗肯循环与再热、喷管流动和马赫数计算等高频考点,其中计算题给出了详细求解过程,便于对照检查。已有152人浏览学习,适合作为考前自测与查漏补缺的辅助资料。资源以试卷形式呈现,答案要点与解题步骤均包含在题目和解答中,能有效帮助学习者快速回顾核心公式、辨析易混概念,并训练规范解题思路。
1. 工程热力学期末考试题.pdf 这份材料,到底该怎么被程序消费
拿到一份《工程热力学期末考试题.pdf》,很多人第一反应是打开看,但看完就忘了。真正能帮上忙的做法,是把这份 PDF 变成一份结构化题库,让其中的每一个选择题、答案、公式和图像都变成可以被程序检索、标记和重排的数据。这篇文章就是讲这件事的落地路径:从 PDF 提取文本,到拆分题目,再到识别公式和图片,最后接进 Anki。如果你正被大量工程热力学习题困住,或者想给教学资料做自动化整理,下面这些操作可以直接照抄。
2. 从 PDF 里把工程热力学期末考试题变成纯文本的技术选型与坑位
工程热力学期末考试题这种 PDF,版式一般有两种:一种是 Word 转出来的文字型 PDF,另一种是扫描或拍照后合并的图片型 PDF。前者可以直接抽文本,后者必须先做 OCR。先判断类型,再决定管线,这是我处理这类文件的一贯顺序。
2.1 为什么先选 pdfplumber 而不是 PyPDF2
处理文字型工程热力学期末考试题,我会优先用 pdfplumber,而不是 PyPDF2 或 pypdf。原因很直接:PyPDF2 只提供extract_text()这种简单的文本抽取,它不告诉你每段文字在哪一页哪个位置,也无法在文字和图片之间建立关联。工程热力学的题目里有大量公式、角标、上下标,PDF 内嵌字体如果带自定义编码,PyPDF2 抽出来的经常是乱码。pdfplumber 基于 pdfminer.six,保留了字符级坐标,遇到排版混乱的页面可以按位置过滤。
下面是最小提取脚本:
import pdfplumber with pdfplumber.open('工程热力学期末考试题.pdf') as pdf: print('总页数:', len(pdf.pages)) for i, page in enumerate(pdf.pages): text = page.extract_text(layout=True) if text and len(text.strip()) > 20: print(f'--- Page {i + 1} ---') print(text[:300])layout=True会在输出时保留文本的横向间隔,这样选择题的A. B. C. D.能保持在近似的列位置。实际使用中,我一般先打印每页前 300 个字符,快速确认哪些页有正文,哪些页是空白或只有图片。参数上还可以加x_tolerance=3来调整字符宽度容忍度,默认值是 3,遇到字距较疏的页面,这个值要适当提高。
2.2 处理两类排版:文字型题目和图片型公式
工程热力学题目里最头疼的是公式和图表。文字型 PDF 中的公式可能是被转换成图片的,也可能是 OMML 转换时生成的矢量字体。如果公式是图片,extract_text()只能抽到图周围的文字,公式本身是空白。这种情况需要结合page.images来定位图片区域。
page = pdf.pages[3] for img in page.images: print('图片对象:', img['name'], '尺寸', img['width'], 'x', img['height'], '位置', (img['x0'], img['top'], img['x1'], img['bottom']))这段代码把第四页所有图片的位置和大小列出来。看到某个图片坐标处在题目编号附近,基本就能判断它是公式图还是示意图。工程热力学期末考试题里的压-焓图、焓熵图通常以大幅图片存在,宽度可能超过页面一半,而公式图片往往又小又窄。靠这个特征就能区分。
2.2.1 用 pdfplumber 抽取文字和坐标
如果需要按题目位置把文字和公式图对应起来,可以用extract_words()拿到每个词的坐标,再结合题号的位置做局部切割。
words = page.extract_words(use_text_flow=False, keep_blank_chars=False) for w in words: print(w['text'], (w['x0'], w['top'], w['x1'], w['bottom']))use_text_flow=False表示按物理排版顺序取词,不重新排序。试卷题目有时会分栏,如果启用 text flow,它会自动按阅读顺序排列,反而打乱原始坐标。工程热力学期末考试题如果需要保留原始版式,这个参数不要打开。
2.3 遇到扫描版 PDF 时切换 OCR 管线的判定条件
文本提取失败不能只靠肉眼判断,要有一个客观条件。我一般这么设阈值:某页extract_text()返回的字符数少于 15,且该页图片数量大于等于 1,就判定为扫描页。这时整份 PDF 走 OCR 管线。
常见做法是先用 ocrmypdf 在 PDF 上叠加一层文本,再用 pdfplumber 去读:
ocrmypdf 工程热力学期末考试题.pdf 工程热力学期末考试题_ocr.pdf -l chi_sim --force-ocr-l chi_sim指定简体中文语言包,--force-ocr强制对所有页做 OCR,哪怕页面上已经有文本也会重做。处理后的新 PDF 每个字符都有坐标,再用之前的 pdfplumber 代码就能正常提取。工程热力学期末考试题里的专业英文缩写如h、s、cp可能会被误识别,OCR 输出后要多做一轮字符替换。
3. 用正则和结构规则把工程热力学期末考试题拆成题目、选项、答案
文本抽出来之后,下一步就是结构化。工程热力学期末考试题的题型通常有选择、判断、填空、计算。每种题型的版式有规律,但只要用对方法,都可以用正则加状态机解决。
3.1 先观察版面:题目编号规律、选项对齐方式
在写分割脚本之前,我会先打印一份完整文本,仔细看题号格式。常见格式有:
1.或1、或(1)一、或第 1 题- 选择题选项往往在同一行,如
A. 增大 B. 减小,也可能换行排列
这些规律决定后续的正则表达式,不要一开始就写死。观察后把规律记录在配置里,后面参数调整方便。
3.2 写一个能处理单选/多选/判断题的分割脚本
先按题号切分,再在每个切分块内识别选项和答案。下面是一个简洁的分割函数:
import re def split_questions(text): # 匹配 1/2/3 开头,后面跟 . 或 、 的数字题号 pattern = r'\n(?=\d{1,3}[、.])' parts = re.split(pattern, text) questions = [] for part in parts: part = part.strip() if not part: continue m = re.match(r'(\d{1,3})[、.](.*)', part, re.S) if not m: continue num = int(m.group(1)) body = m.group(2).strip() questions.append({'id': num, 'raw': body}) return questions这里用\n(?=\d{1,3}[、.])作为分割点:匹配换行符后紧跟着一到三位数字和顿号/点的情况。重点在于(?=...)是零宽断言,它只把\n当作分割点,不会吞掉题号。如果工程热力学期末考试题里同时有(1)这种括号题号,就把 pattern 改成r'\n(?=\(\d{1,3}\)|\d{1,3}[、.])'。
3.3 参数表:页码范围、题号正则、答案行特征
实际抓题时,我通常会把这些参数集中放在一个字典里,方便按不同 PDF 调整。
| 参数项 | 当前示例 | 说明 |
|---|---|---|
| 页码范围 | pdf.pages[2:-1] | 跳过封面和目录 |
| 题号正则 | \n(?=\d{1,3}[、.]) | 识别题号开始位置 |
| 选项正则 | (?=\n?[A-D])[A-D][.、] | 匹配选项行 |
| 答案行特征 | 答[::]或答案[::] | 题干尾部直接给答案 |
| 公式图片尺寸阈值 | 宽 < 200,高 < 100 | 判定为公式图而非图表 |
在脚本里把这些参数暴露出来,遇到一份新的工程热力学期末考试题,只需要改这张表里的值,不用动代码逻辑。
3.4 处理跨页题目和题号混淆的 3 个方法
跨页是高频坑。题目在第 2 页末尾断了,第 3 页开头继续,直接按页处理会把一道题拆成两半。我一般用以下 3 个方法:
第一,合并文本时保留分页标记\n=== PAGE BREAK ===\n,切分题目时如果某个raw里包含分页标记,就把它替换成空,再重新拼接下一题。第二,检测题号连续性。如果分割后第 1 题后面直接出现第 3 题,缺少第 2 题,说明第 2 题被打散了,需要检查上一块的raw中是否已经包含了第 2 题的题干。第三,根据选项数量判断截断位置。一道完整的单选题一定有四到五个选项,如果切分出的块里选项数不足,就把下一块的文本并入。
实际经历中,判断题是最容易误判的。判断题往往没有选项,题干直接跟( )或者答案标记。正则如果按选项行匹配,很容易把判断题的括号当成空白选项。这时要单独把判断题和选择题分开处理,用题干是否含( )来区分。
4. 公式与图表从 PDF 里“抠”出来的常用工具和调用参数
工程热力学期末考试题里的热力学第一定律方程、熵变计算式、压-焓图,是复习时最需要的部分。文本提取过程往往拿不到公式内容,这一章专门讲怎么把公式和图表从 PDF 中拆出来,并转成可编辑格式。
4.1 用 LaTeX 识别工具 Mathpix 把公式转成 LaTeX 的注意事项
Mathpix 是目前识别公式最稳定的云服务,但它是收费的,注册后会送少量免费额度。它的 HTTP API 接受图片 URL 或 base64 图片内容,返回 LaTeX 字符串。常见做法是先上传图片获得 URL,再调用 API。
curl -X POST https://api.mathpix.com/v3/latex \ -H "app_key: YOUR_APP_KEY" \ -H "app_id: YOUR_APP_ID" \ -H "Content-Type: application/json" \ -d '{"url": "https://your-image-host/formula.png"}'响应里的latex字段就是识别出的 LaTeX 代码。使用它时要注意:识别结果里经常包含\text { }包裹的中文,实际排版时需要手动处理。工程热力学期末考试题里的变量下标如h_1、s_2,识别成h_{1}、s_{2}的准确率较高,但角标带括号时容易出错,需要人工复核。
4.2 开源方案 pix2tex 的本地跑通最小命令
不想付费就用开源模型 pix2tex。它的模型是 LaTeX-OCR,可以本地运行。传统安装方式很简单:
pip install pix2tex[gui]装完之后,命令行直接调用:
python -m pix2tex.cli --file path/to/formula.png --temperature 0.2--temperature在这里控制采样随机度,0.2 是较保守的值,能减少错误变量名。实际对工程热力学期末考试题里的公式图做测试,温度调低之后,像T_1这种简单下标更稳;温度太高会产生离谱的字母。
如果不想装 GUI 依赖,也可以只装推理核心:
pip install pix2tex然后写一个 Python 脚本调用模型。这种方式适合批量处理。需要注意 pix2tex 对裁剪后的干净公式图识别最好,带噪声或倾斜的图要先预处理。
4.3 当题目里带压-焓图、焓熵图时,怎么用 OpenCV 做区域裁剪
工程热力学考试题里的压焓图、焓熵图往往是整页扫描件里的一部分。直接用 Mathpix 识别整页图,公式会被淹没。这时候需要先用 PyMuPDF 或 pdfplumber 提取图片区域,再用 OpenCV 裁剪。
下面是用 PyMuPDF 提取页面中所有图片的代码:
import fitz # PyMuPDF doc = fitz.open('工程热力学期末考试题.pdf') for page_index in range(len(doc)): page = doc[page_index] images = page.get_images(full=True) for img_index, img in enumerate(images): xref = img[0] base_image = doc.extract_image(xref) image_bytes = base_image['image'] with open(f'page{page_index+1}_img{img_index}.png', 'wb') as f: f.write(image_bytes)提取出的图片可能带着大片白边,先用 OpenCV 做前景裁剪:
import cv2 import numpy as np img = cv2.imread('page1_img0.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV) coords = cv2.findNonZero(thresh) x, y, w, h = cv2.boundingRect(coords) crop = img[y:y+h, x:x+w] cv2.imwrite('crop.png', crop)cv2.threshold的阈值 200 是根据白底黑线公式图算的。压-焓图通常有网格线,阈值过高会丢线条,过低会把网格当成前景,导致裁切范围变大。实际调参时,可以把阈值从 180 到 230 每次加 10,分别保存结果,看哪个裁剪出的矩形最贴近实际图线区域。工程热力学期末考试题里的图大多是黑白印刷,所以二值化效果比彩色图更稳定。
5. 把结构化后的题库接进 Anki 或自建小系统的一个具体技巧
题库结构化完成后,最常用的产出是导入 Anki 做间隔重复复习。这里有一个容易被忽略的坑:Anki 的 CSV 导入默认使用 UTF-8 编码,但 Windows 下的 Excel 打开会乱码。所以导出 CSV 时一定要带 BOM。
5.1 生成可直接导入 Anki 的 CSV 文件模板
Anki 导入模板很简单,一行一条记录,字段之间用逗号分隔。如果字段内容包含换行,需要用\n转义,但 Anki 支持 HTML 标签,所以我会把换行替换成<br>。
import csv def to_anki_csv(questions, output_path): with open(output_path, 'w', newline='', encoding='utf-8-sig') as f: writer = csv.writer(f) writer.writerow(['题干', '选项', '答案', '解析']) for q in questions: stem = q['raw'].replace('\n', '<br>') options = q.get('options', '') answer = q.get('answer', '') analysis = q.get('analysis', '') writer.writerow([stem, options, answer, analysis])encoding='utf-8-sig'会把 BOM 写进文件,这样 Excel 打开不再乱码,Anki 导入时也不会自动识别成其他编码。选项字段可以用分号分隔,Anki 侧的卡片模板里再用条件替换拆成A..B..C..。
5.2 验证题库完整性的一个快速脚本
导入 Anki 之前,先跑一遍完整性检查,比在手机上发现漏题再回头改效率高得多。我写了一个 30 行的验证脚本,专门检查工程热力学期末考试题拆分后是否缺题、缺选项、缺答案。
def validate(questions): errors = [] ids = [q['id'] for q in questions] if len(ids) != len(set(ids)): errors.append('存在重复题号') for q in questions: if len(q['raw']) < 5: errors.append(f"题号 {q['id']} 题干过短") if q.get('type') == 'choice': if len(q.get('options', '').split(';')) < 2: errors.append(f"题号 {q['id']} 选项不足") if not q.get('answer'): errors.append(f"题号 {q['id']} 缺少答案") return errors这个脚本会输出所有异常,不会自动修复。检查时优先看“缺少答案”,因为有些工程热力学期末考试题的答案在试卷末尾而不是题后,需要单独匹配。如果答案全部集中在末尾,先按题号建立索引,再完成答案回填,最后用这个验证函数确认覆盖。这个流程跑通以后,再拿到别的科目的 PDF,只需要改题号正则和答案位置参数,剩下的逻辑全部复用。
本文还有配套的精品资源,点击获取