软工作业:用python实现论文查重

github项目地址

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229
这个作业的目标 python实现论文查重并进行单元测试

我的github仓库链接:https://github.com/LilaSlin/se

一、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 25
Estimate 估计这个任务需要多少时间 30 35
Development 开发 1000 1400
Analysis 需求分析 (包括学习新技术) 120 150
Design Spec 生成设计文档 30 30
Design Review 设计复审 30 35
Coding Standard 代码规范 (为目前的开发制定合适的规范) 15 20
Design 具体设计 60 60
Coding 具体编码 70 120
Code Review 代码复审 20 30
Test 测试(自我测试,修改代码,提交修改) 60 60
Reporting 报告 20 60
Test Repor 测试报告 20 20
Size Measurement 计算工作量 10 15
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 10 10
合计 1500 1800

二、运行环境

IDE:PyCharm 2024.1.4

三、主函数设计

流程图

一、程序分析

程序实现了以下主要功能:

  1. 文件读取功能 (read_file):
  • 从指定的文件路径读取文件内容,如果文件不存在,则抛出 FileNotFoundError 并退出程序。
  • 使用了 sys.exit(1) 来确保程序在找不到文件时以状态码 1 退出,表示异常状态。
  • 该函数的设计非常简单,读取文件内容时使用了上下文管理(with open),确保即使在异常情况下文件也会被正确关闭。
  • 错误处理部分使用了 try...except 捕获 FileNotFoundError,这很好地避免了文件不存在时的崩溃。
  1. 文本预处理功能 (preprocess_text):
  • 对文本进行预处理,步骤包括:
  • 使用正则表达式去除所有非单词字符和空白字符之外的内容(即去掉标点符号等)。
  • 使用 jieba.lcut 进行中文分词,之后将分词结果用空格连接为一个字符串。jieba 是一种常用的中文分词库,适合处理中文文本。
  • 使用正则表达式去除文本中的标点符号,这是非常有效的清理方式。
  • jieba.lcut 可以将中文文本进行分词,分词后再通过 ' '.join 拼接成适合向量化处理的格式。这一部分对中文文本处理非常重要,因为中文是没有空格分隔的,直接向量化处理中文可能会产生不正确的结果。*
  1. 相似度计算功能 (calculate_similarity):
  • 使用 TfidfVectorizer 对输入的两个文本进行词频-逆文档频率(TF-IDF)向量化处理。
  • 生成的TF-IDF矩阵用于计算两个文本之间的 余弦相似度,这是一种常用的文本相似度度量方法。计算的余弦相似度结果在0到1之间,0表示完全不同,1表示完全相同。
  1. 相似度写入功能 (write_output):
  • 将计算出的相似度结果写入指定的文件。结果会被格式化为保留两位小数的形式,并在文件中显示。
  • 该函数直接将相似度结果格式化并写入指定的输出文件,功能简单明了。
  • 使用 with open 确保文件操作安全,不会因异常情况导致文件未关闭或数据未写入。

二、设计优点

该程序通过合理的模块化设计、可靠的错误处理、适当的中文处理工具、稳健的文本相似度计算方法,以及安全的文件操作,展现了以下优点:

  • 简洁易用:每个功能都十分明确,接口简单,用户可以轻松使用。
  • 高效准确:利用 TF-IDF 和余弦相似度计算文本相似度,具有较高的准确性。
  • 可维护性高:由于功能模块独立、职责单一,代码非常易于修改和维护。

三、主要函数设计代码

1.文件读取功能 (read_file):

def read_file(file_path):"""读取指定路径的文件内容,并返回去掉空白符的字符串。:param file_path: 文件路径:return: 去掉首尾空白符后的字符串"""try:with open(file_path, 'r', encoding='utf-8') as file:return file.read().strip()  # 读取文件内容并去掉首尾空白符except FileNotFoundError:# 文件未找到时,打印错误信息并退出程序print(f"File {file_path} not found.")sys.exit(1)

2.文本预处理功能 (preprocess_text):

def preprocess_text(text):"""预处理输入文本,去除标点符号并使用结巴分词对中文进行分词。:param text: 输入的原始文本:return: 经过标点去除和分词后的文本"""# 使用正则表达式去除文本中的标点符号text = re.sub(r'[^\w\s]', '', text)# 使用结巴分词对文本进行分词,并通过空格连接分词结果return ' '.join(jieba.lcut(text))

3.相似度计算功能 (calculate_similarity):

def calculate_similarity(text1, text2):"""计算两个文本之间的TF-IDF余弦相似度。:param text1: 文本1:param text2: 文本2:return: 计算得到的余弦相似度值"""# 初始化TF-IDF向量化器vectorizer = TfidfVectorizer()# 将两个文本转换为TF-IDF矩阵tfidf_matrix = vectorizer.fit_transform([text1, text2])# 计算两个文本的余弦相似度,返回第一个文本与第二个文本的相似度值return cosine_similarity(tfidf_matrix[0], tfidf_matrix[1])[0][0]

4.相似度写入功能 (write_output):

def write_output(output_path, similarity):"""将相似度结果写入指定的输出文件。:param output_path: 输出文件路径:param similarity: 计算得到的相似度值"""# 以写入模式打开文件,并将相似度写入文件,保留两位小数with open(output_path, 'w', encoding='utf-8') as f:f.write(f"{similarity:.2f}\n")

四、性能分析

通过cprofile可以对整个程序的执行进行性能分析,找到耗时较多的部分,然后进一步优化。
main函数运行

cProfile.run("main(orig_path, plagiarized_path, output_path)", filename="performance_analysis_result")

命令行运行

snakeviz.exe -p 8080 .\performance_analysis_result

得到性能分析图

可见在主函数中preprocess_text运行时间最长,故可以考虑对函数preprocess_text进行优化。

五、单元测试

关于测试点的思维导图

测试代码如下:
1.文件操作测试
测试点1: 文件读取成功
测试点2: 文件不存在错误处理
测试点3: 文件输出 - 正确写入相似度
测试点4: 文件输出 - 文件不可写错误处理

# 文件操作测试
# 测试点1: 文件读取成功
def test_read_file_success():mock_data = "这是一个测试文件"with patch("builtins.open", mock_open(read_data=mock_data)) as mock_file:result = read_file("test.txt")mock_file.assert_called_once_with("test.txt", "r", encoding="utf-8")assert result == mock_data.strip()# 测试点2: 文件不存在错误处理
def test_read_file_not_found():with patch("builtins.open", side_effect=FileNotFoundError):with pytest.raises(SystemExit):read_file("non_existent.txt")# 测试点3: 文件输出 - 正确写入相似度
def test_write_output_success():similarity = 0.85with patch("builtins.open", mock_open()) as mock_file:write_output("output.txt", similarity)mock_file.assert_called_once_with("output.txt", "w", encoding="utf-8")mock_file().write.assert_called_once_with("0.85\n")# 测试点4: 文件输出 - 文件不可写错误处理
def test_write_output_file_permission_error():with patch("builtins.open", side_effect=PermissionError):with pytest.raises(PermissionError):write_output("output.txt", 0.85)

2.文本预处理测试
测试点5: 文本预处理 - 去除标点符号
测试点6: 文本预处理 - 分词功能
测试点7: 文本预处理 - 空白文本处理
测试点8: 长文本处理

# 文本预处理测试
# 测试点5: 文本预处理 - 去除标点符号
def test_preprocess_text_remove_punctuation():text = "这是一个测试,包含标点符号!"expected_output = "这是 一个 测试 包含 标点符号"result = preprocess_text(text)assert result == expected_output# 测试点6: 文本预处理 - 分词功能
def test_preprocess_text_segmentation():text = "这是一个测试"expected_output = "这是 一个 测试"result = preprocess_text(text)assert result == expected_output# 测试点7: 文本预处理 - 空白文本处理
def test_preprocess_empty_text():text = ""result = preprocess_text(text)assert result == ""# 测试点8: 长文本处理
def test_long_text_processing():long_text = "这是一个非常长的测试文本。" * 10000  # 模拟非常长的文本result = preprocess_text(long_text)assert isinstance(result, str)assert len(result) > 0  # 检查处理后的文本不为空

3.相似度计算测试
测试点9: 计算相似度 - 完全相同文本
测试点10: 计算相似度 - 完全不同文本
测试点11: 计算相似度 - 部分相似文本
测试点12: TF-IDF 向量化处理

# 相似度测试
# 测试点9: 计算相似度 - 完全相同文本
def test_calculate_similarity_identical_text():text1 = "测试文本"text2 = "测试文本"similarity = calculate_similarity(text1, text2)assert similarity == 1.0# 测试点10: 计算相似度 - 完全不同文本
def test_calculate_similarity_different_text():text1 = "这是测试A"text2 = "这是测试B"similarity = calculate_similarity(text1, text2)assert similarity == 0.0# 测试点11: 计算相似度 - 部分相似文本
def test_calculate_similarity_partial_similarity():text1 = "这是一个测试"text2 = "这是一个不同的测试"orig_text1 = preprocess_text(text1)orig_text2 = preprocess_text(text2)similarity = calculate_similarity(orig_text1, orig_text2)assert 0 < similarity < 1.0# 测试点12: TF-IDF 向量化处理
def test_tfidf_vectorization():text = "我喜欢学习"vectorizer = TfidfVectorizer()tfidf_matrix = vectorizer.fit_transform([text])assert tfidf_matrix.shape == (1, len(vectorizer.get_feature_names_out()))

测试覆盖率

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/796883.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

modbus调试助手/mqtt调试工具/超轻巧物联网组件/多线程实时采集/各种协议支持

一、前言说明 搞物联网开发很多年,用的最多的当属modbus协议,一个稳定好用的物联网组件是物联网平台持续运行多年的基石,所以这个物联网组件从一开始就定位于自研,为了满足各种场景的需求,当然最重要的一点就是大大提升了自己对该协议的深度理解和应用,尤其是面对各种场景…

VMware NSX Advanced Load Balancer (NSX ALB) 22.1.7 发布下载,新增功能概览

VMware NSX Advanced Load Balancer (NSX ALB) 22.1.7 发布下载,新增功能概览VMware NSX Advanced Load Balancer (NSX ALB) 22.1.7 - 多云负载均衡平台 应用交付:多云负载均衡、Web 应用防火墙和容器 Ingress 服务 请访问原文链接:https://sysin.org/blog/vmware-nsx-alb-2…

4、循环单链表

1、代码实现#include<stdio.h> #include<malloc.h> #include<assert.h> typedef int ElemType;typedef struct Node{ElemType data;struct Node* next; }Node,*PNode;typedef struct SCList{PNode first;PNode last;int size; }SCList;void initSCList(SCLis…

论文分享 《Timing Side-channel Attacks and Countermeasures in CPU Microarchitectures》

Attack 概述 传统攻击(CONVENTIONAL ATTACKS) 在传统攻击中,Attacker 通常:与 Victim 共享硬件资源 (比如说 LLC,BP,Prefetcher 等) 可以观察,改变微架构状态攻击步骤本文作者将传统攻击分为以下三步,如 Fig 1 所示:定位“漏洞”:该漏洞包括“代码漏洞”(vulnerab…

PbootCMS访问页面出现PHP Fatal error: Allowed memory size of 13421

当访问 PbootCMS 页面时出现 PHP Fatal error: Allowed memory size of 13421 的错误,通常是由于 PHP 的内存限制过低导致的。这个错误表明 PHP 脚本在运行过程中耗尽了分配给它的内存。 解决方案增加 PHP 内存限制 检查 PHP 配置文件 (php.ini) 在脚本中动态增加内存限制详细…

什么是 PHP? 为什么用 PHP? 有谁在用 PHP?

PHP,全称“PHP: Hypertext Preprocessor”,是一种开源的服务器端脚本语言,主要用于网页开发,能够产生动态交互性数据。它由Rasmus Lerdorf在1994年创建,并随着时间的推移不断更新迭代,以适应互联网技术的发展。为什么使用 PHP? 开源免费:PHP作为一个开源项目,用户可以…

系统配置nginx环境运行pbootcms访问首页直接404的问题

在安装 PbootCMS 时遇到访问首页返回 404 错误的问题,尤其是在 Windows + Nginx + PHP 的环境下,可能涉及到多个方面的配置问题。根据你的描述,填写授权码后问题得以解决。以下是详细的分析和解决方案,希望能帮助遇到类似问题的朋友。 问题分析与解决方案 1. 配置 Nginx 伪…

基于Java+Springboot+Vue开发的在线摄影预约管理系统

项目简介该项目是基于Java+Springboot+Vue开发的在线摄影预约管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的在线摄影管理系统项目,大学生可以在实践…

【痛点解决】跨网跨区域的文件传输摆渡解决办法指南

跨网跨区域的文件传输摆渡,顾名思义就是需要跨越不同网络、不同地区,或者是不同安全域的文件传输,一般有这样传输需求的机构,在组织架构、网络结构,或者传输需求上,都会比较复杂。 跨网跨区域文件传输是什么样的场景? 跨网跨区域文件传输涉及在不同的网络和地理区域之间…

SQL Server 中的 NUL 设备/NIL设备

SQL Server 中的 NUL 设备/NIL设备 在 SQL Server 中,有一个特殊的设备叫做 NUL(注意,不是 NULL),它类似于文件系统中的“黑洞”。NUL 设备类似于 Linux 系统中的 /dev/null,所有写入到 NUL 的数据都会被直接丢弃。 我们可以利用这个特性,在不需要实际生成备份文件的情况…

PbootCMS调用内容中换行符br不换行怎么办

在 PbootCMS 中,如果你在后台输入的文字包含换行符(如 <br>),但在前台显示时这些换行符被直接输出为文本(如 <br>),可以通过解码标签来解决这个问题。 解决方案 在需要输出的标签中加入 decode=1 参数,这样可以将 HTML 特殊字符解码为实际的 HTML 标签,从…

PbootCMS提交留言成功后跳转到指定的网址

要实现在 PbootCMS 中留言表单提交成功后跳转到指定网址,可以通过修改相关文件来实现。以下是详细的步骤: 步骤 1:定位相关文件 首先找到包含留言表单提交逻辑的相关文件。通常情况下,留言表单的提交逻辑会在 /core/function/helper.php 文件中。 步骤 2:修改提交成功后的…