软工作业2:python实现论文查重
| 项目 | 链接 |
|---|---|
| 软件工程 | 软件工程链接 |
| 作业要求 | 作业要求的链接 |
| 作业目标 | 熟悉个人开发流程,了解项目单元测试,使用python实现论文查重 |
| github项目链接 | github项目链接 |
1. PSP表格
PSP表格通常用于软件工程中,用于跟踪和记录开发者在项目中的时间估计和实际工作量。这有助于跟踪任务的时间管理和效率,并提供了有关项目进展的信息。
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 30 | 40 |
| · Estimate | · 估计这个任务需要多少时间 | 30 | 40 |
| Development | 开发 | 490 | 540 |
| · Analysis | · 需求分析 (包括学习新技术) | 60 | 100 |
| · Design Spec | · 生成设计文档 | 40 | 50 |
| · Design Review | · 设计复审 | 10 | 20 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
| · Design | · 具体设计 | 40 | 50 |
| · Coding | · 具体编码 | 120 | 110 |
| · Code Review | · 代码复审 | 80 | 60 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 110 | 120 |
| Reporting | 报告 | 50 | 70 |
| · Test Repor | · 计算工作量 | 20 | 30 |
| · Size Measurement | · 事后总结, 并提出过程改进计划 | 30 | 40 |
| · 合计 | 570 | 650 |
2. 项目需求
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
- 原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
- 抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
- 从命令行参数给出:论文原文的文件的绝对路径。
- 从命令行参数给出:抄袭版论文的文件的绝对路径。
- 从命令行参数给出:输出的答案文件的绝对路径。
orig.txt是原文,其他orig_add.txt等均为抄袭版论文。答案文件中输出的答案为浮点型,精确到小数点后两位。
3. 模块接口的设计与实现

3.1 关键函数
3.1.1 TextSimilarityCalculator 类
作用:用于处理原始文本和抄袭文本。该类的构造函数 __init__ 接受两个文本参数,用于初始化原始文本和抄袭文本。
| 函数名 | 作用 |
|---|---|
| preprocess_text | 用于文本预处理,将文本分词并返回预处理后的文本 |
| calculate_similarity | 计算文本相似度 |
| calculate_and_save_similarity | 计算文本相似度并将结果保存到文件 |
3.1.2 TestSimilarityCalculation 类
作用:对main.py文件中的文本预处理功能、文本读取功能以及文本相似度计算的功能进行测试。
| 函数名 | 作用 |
|---|---|
| test_preprocess_text | 测试文本预处理是否正常工作 |
| test_read_text_file | 测试文本读取是否正常工作 |
| test_calculate_similarity | 测试文本相似度计算是否正常工作 |
3.2 流程图

3.3 算法的关键
- 文本预处理:在计算文本相似度之前,原始文本和抄袭文本都需要进行预处理。这包括分词、去除标点符号等。这个过程使得文本更容易进行比较和分析。
- TF-IDF 向量化:TF-IDF计算了文本中每个词语的重要性,以便进行比较。这种方法允许算法将文本表示为向量,其中每个维度对应一个词语,并且词语的重要性影响了向量中的值。
- 余弦相似度计算:余弦相似度是本算法用于计算文本相似度的核心方法。它通过比较两个文本向量之间的夹角来度量它们之间的相似度。余弦相似度值在-1到1之间,值越接近1表示文本越相似,值越接近-1表示文本越不相似。
- 单元测试:算法通过单元测试来验证其核心功能的正确性。这包括测试文本预处理、文本读取和文本相似度计算功能。通过单元测试,可以确保算法在各个步骤都能够按照预期工作。
- 命令行界面:算法通过命令行界面接受输入文件路径,并将计算结果输出到指定文件。这种用户友好的界面使得算法易于使用。
3.4 独到之处
- 使用了 argparse 库来处理命令行参数,使程序更易于使用。
- 通过 unittest 框架编写了测试用例,确保代码的可靠性和稳定性。
- 使用了常见的文本处理库(jieba、sklearn)来处理文本和计算文本相似度,提高了代码的可维护性和性能。
4. 性能改进
使用py-spy查看和监控正在运行的Python进程,以便进行性能调优和故障排除,是一个极佳的应用程序的性能分析工具。
py-spy主要用于生成Flamegraph(火焰图)和Top(顶部)视图,以可视化Python应用程序的性能数据。这两种视图可以帮助更好地理解应用程序中的性能瓶颈和函数调用情况。
-
Flamegraph(火焰图):用于可视化函数调用层次的图表,通常用于分析性能数据,能计算模块性能上所花费的时间。Flamegraph的横轴表示堆栈中的函数调用,纵轴表示堆栈的深度。每个矩形块代表一个函数调用,块的宽度表示该函数占用的时间比例。通过Flamegraph可以快速识别哪些函数消耗了大量的时间,从而帮助优化性能。
![]()
-
Top(顶部)视图:这个视图显示了正在运行的Python进程中占用CPU时间最多的函数,能展示程序中消耗最大的函数。
![]()

由上面的性能分析图可得到:耗时最多的为初始化及文件的读取。由于外部包的调用无法优化,暂时难以改进性能。
5. Code Quality Analysis
代码质量分析是一种评估和改进软件代码的过程,旨在确保代码在可维护性、可读性、性能和可扩展性等方面达到高质量标准。
PyCharm的Inspect Code功能是一个内置的代码质量分析工具,它用于检查Python代码中的潜在问题、代码风格违规、错误、警告和改进建议。这个功能可以帮助开发者识别和改善代码的质量,以确保代码的可读性、可维护性和性能。

由图中可看到:当前代码无错误、无警告,代码性能良好。
6. 单元测试
6.1 单元测试用例
本文将选用orig.txt和orig_0.8_add.txt,对文本预处理函数preprocess_text()、计算文本相似度函数calculate_and_save_similarity()、获取当前脚本所在目录函数read_text_file()进行单元测试。

测试结果如下:

这说明测试成功通过,成功地验证了主代码的功能。
6.2 测试覆盖率
我们使用了Coverage对python代码覆盖率进行了测量。它可以帮助开发人员和测试人员了解他们的Python程序中哪些代码已经被测试覆盖,哪些代码尚未被覆盖。覆盖率工具是软件质量保证的重要组成部分,它有助于发现未经测试的代码路径和潜在的错误。

在main.py文件中,代码测试覆盖率达到了100%,意味着在运行测试套件期间,每一行代码都至少被执行了一次。这证明这段代码是非常好的,因为它表明测试用例已经覆盖了所有的代码路径和分支,包括正常情况和异常情况。
7. 异常说明处理
7.1 文件未找到

在异常类中添加了error_code属性和log_error方法。error_code用于存储自定义的错误代码,log_error方法用于将错误信息记录到日志文件。
当引发此异常时可选择提供错误代码和文件路径,然后在捕获异常后可访问这些属性,并使用log_error方法记录错误信息到日志文件中。这种方式可以增强异常的信息和处理能力。
7.2 文本过短


在TextTooShortError异常类中添加了text属性和suggest_correction方法。text用于存储引发异常的文本内容,suggest_correction方法用于提供建议的文本纠正。当引发此异常时可选择提供文本和最小长度,然后在捕获异常后可访问这些属性,并使用suggest_correction方法提供建议的文本纠正。
8. 后续优化改进
1)错误处理和日志记录改进: 目前已经实现了自定义异常类和错误处理,进一步改进可以包括将错误日志的位置和格式进行配置,以便更好地管理和监视错误。还可以考虑使用Python的内置日志模块(logging)来更灵活地记录日志,包括日志级别和不同输出目标。
2)命令行界面改进: 目前命令行界面使用了argparse进行参数解析。可以添加选项来控制输出详细程度、选择分析器、自定义停用词列表等。
3)多语言支持: 目前代码中使用了中文分词器(jieba),若需要支持其他语言可考虑使用多语言分词器,或通过配置文件来选择不同的分词器。
附录
- 文件的代码及相关文件可在github仓库中获取。
- 本次开发测试使用的库包括:
main.py文件中使用的库
import os
import jieba
import argparse
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
main.py文件中使用的库
import unittest
import tempfile
from main import *


浙公网安备 33010602011771号