第一次编程作业

news/2024/11/16 9:16:24/文章来源:https://www.cnblogs.com/firejs/p/18406888
这个作业属于哪个课程 计科22级34班
这个作业要求在哪里 个人项目
这个作业的目标 1.设计一个查重算法。
2. 了解并学习项目的PSP表格
3. 学习如何运用github进行代码管理
4. 学习使用性能分析工具,分析代码性能
5. 学习如何进行单元测试

我的github仓库链接:https://github.com/zfirejs/3122004631

PSP表格

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

计算模块接口设计与实现过程

过程描述:

代码实现了一个基于文本相似度的查重功能,用于比较两篇中文文本的相似度,并将相似度结果输出到文件中。程序中使用了jieba库进行中文分词处理,再利用余弦相似度计算两篇文本的相似程度。

代码组成:

代码中只有一个类:DuplicateChecking

该类包含以下几个函数:
1.init:类的构造函数,初始化类变量,用于保存原始文本和待查重文本的内容及分词列表。
2.read_file:读取原始文件和待查重文件的内容,并将其保存为类变量 original_text 和 compare_text。。
3.long_text_preprocess:文本的预处理函数,去除标点符号后使用 jieba.analyse.extract_tags 提取文本中的关键词(20 个),并将关键词存储在 original_list 和 compare_list 中。
4.text_checking:核心查重函数,分别调用文件读取(read_file)、文本预处理(long_text_preprocess),然后构建词频向量并计算余弦相似度。最后输出相似度结果到指定文件。

算法核心

将文本去除标点符号后使用,提取文本中的关键词(20 个),然后构建词频向量并计算余弦相似度,从而得出文本相似度。

流程图

计算模块接口部分的性能改进

改进思路

本程序的计算模块的主要性能瓶颈为文本的输入,其中短文本可以使用python文件IO类的read()方法,但是对于较长文本的输入,则需要使用readlines()方法实现逐行输入,避免因内存容量导致的IO速率过慢

改进部分代码

try:with open(original_text_address, "r", encoding="utf-8") as file1:self.original_list = file1.readlines()# 将读取的行拼接成单个字符串存储self.original_text = self.original_text.join(self.original_list)
except FileNotFoundError:print("未找到原始文本文件 " + original_text_address + " 请重试")original_text_address = ""       

性能分析图

消耗最大的函数(text_checking)

def text_checking(self):"""主功能方法,负责根据文本长度选择适合的预处理方法。长文本(超过1000字符)会调用 `long_text_preprocess` 方法,短文本会调用 `short_text_preprocess` 方法。最终使用余弦相似度计算两个文本之间的相似度。"""original_vector = []compare_vector = []# 读取文件,检查读取是否成功if not self.read_file():return False# 根据文本长度判断选择预处理方法,超过1000字符的文本被视为长文本if len(self.original_text) > 1000 or len(self.compare_text) > 1000:self.long_text_preprocess()else:self.short_text_preprocess()# 合并分词列表并去重,创建词汇表self.word_store = list(set(self.original_list + self.compare_list))# 构建词频向量for word in self.word_store:original_vector.append(self.original_list.count(word))compare_vector.append(self.compare_list.count(word))original_vector = numpy.array(original_vector)compare_vector = numpy.array(compare_vector)# 使用 scipy 库的余弦相似度函数计算相似度cos_sim = 1 - spatial.distance.cosine(original_vector, compare_vector)# 将相似度写入文件并提示用户print("请输入查重结果文件输出的地址:")duplicate_data_address = input("请输入抄袭文本的绝对路径")#"C:\\Users\\周晨佳\\Desktop\\ceshi\\shuchu.txt"try:with open(duplicate_data_address, "w", encoding="utf-8") as file:file.write("待查文本与原文本的相似度为:" + str(round(cos_sim, 2)))print("查重结果已输出到文件!")except IOError:print("查重结果文件创建失败,请检查路径并重试。")return True

计算模块部分单元测试展示:

测试思路

单元测试使用pycharm自带的unittest测试框架,运用unittest框架的TestCase类,在类中实例化测试函数,运行测试python文件,实现main程序的测试。
对于项目中的输入模块,引入unittest测试框架中的patch类模拟用户的输入,实现输入模块的测试。
单元测试通过模拟用户的行为,以及对于main.py中DuplicateChecking查重类中的每个函数运行流程进行模拟,使用框架自带的断言函数assertEqual(),实现对项目中的类及其方法的测试。

测试代码(test.py)

import unittest
import random
from src.main import DuplicateChecking
from unittest.mock import patch  # 用于模拟输入
# 记录测试文本地址
original_text = [r'C:\Users\周晨佳\Desktop\ceshi\orig.txt', '666', '777','888', '999']
test_text = [r'C:\Users\周晨佳\Desktop\ceshi\orig_0.8_add.txt',r'C:\Users\周晨佳\Desktop\ceshi\orig_0.8_del.txt',r'C:\Users\周晨佳\Desktop\ceshi\orig_0.8_dis_1.txt',r'C:\Users\周晨佳\Desktop\ceshi\orig_0.8_dis_10.txt',r'C:\Users\周晨佳\Desktop\ceshi\orig_0.8_dis_15.txt','666', '777', '888', '999']class MyTestCase(unittest.TestCase):@patch('builtins.input')def test_IO(self, mock_input):result = DuplicateChecking()# 实例化测试对象mock_input.side_effect = [original_text[0], test_text[random.randint(0, 4)]]  # 正确的输入self.assertEqual(result.read_file(), True)# 断言测试判断mock_input.side_effect = [original_text[random.randint(1, 4)], test_text[random.randint(5, 8)]]  # 错误的输入self.assertEqual(result.read_file(), False)@patch('builtins.input')def test_long_text_preprocess(self, mock_input):result = DuplicateChecking()mock_input.side_effect = [original_text[0], test_text[random.randint(0, 4)]]  # 正确的输入result.read_file()self.assertEqual(result.long_text_preprocess(), True)def test_short_text_preprocess(self):result = DuplicateChecking()result.original_text = "废话覅哦说不定v哦i被释冯绍峰放北京库房不玩"result.compare_text = "我IC呢嫩IC那我可浪放放瑟夫费钱农村"self.assertEqual(result.short_text_preprocess(), True)@patch('builtins.input')def test_text_checking(self, mock_input):result = DuplicateChecking()mock_input.side_effect = [original_text[0], test_text[random.randint(0, 4)],r'C:\Users\周晨佳\Desktop\ceshi\output.txt']  # 正确的输入self.assertEqual(result.text_checking(), True)mock_input.side_effect = [original_text[random.randint(1, 4)], test_text[random.randint(5, 8)],r'C:\Users\周晨佳\Desktop\ceshi\output.txt']  # 错误的输入self.assertEqual(result.text_checking(), False)if __name__ == '__main__':unittest.main()

测试覆盖率:

计算模块部分异常处理说明

1.输入异常(文件不存在):

 try:with open(original_text_address, "r", encoding="utf-8") as file1:self.original_list = file1.readlines()# 将读取的行拼接成单个字符串存储self.original_text = self.original_text.join(self.original_list)
except FileNotFoundError:print("未找到原始文本文件 " + original_text_address + " 请重试")original_text_address = ""   

输入异常对应的单元测试

@patch('builtins.input')
def test_IO(self, mock_input):result = DuplicateChecking()# 实例化测试对象mock_input.side_effect = [original_text[0], test_text[random.randint(0, 4)]]  # 正确的输入self.assertEqual(result.read_file(), True)# 断言测试判断mock_input.side_effect = [original_text[random.randint(1, 4)], test_text[random.randint(5, 8)]]  # 错误的输入self.assertEqual(result.read_file(), False)

2.输出异常(文件不存在):

try:with open(duplicate_data_address, "w", encoding="utf-8") as file:file.write("待查文本与原文本的相似度为:" + str(round(cos_sim, 2)))print("查重结果已输出到文件!")
except IOError:print("查重结果文件创建失败,请检查路径并重试。")

输出异常对应的单元测试

@patch('builtins.input')
def test_text_checking(self, mock_input):result = DuplicateChecking()mock_input.side_effect = [original_text[0], test_text[random.randint(0, 4)],r'C:\Users\周晨佳\Desktop\ceshi\output.txt']  # 正确的输入self.assertEqual(result.text_checking(), True)mock_input.side_effect = [original_text[random.randint(1, 4)], test_text[random.randint(5, 8)],r'C:\Users\周晨佳\Desktop\ceshi\output.txt']  # 错误的输入self.assertEqual(result.text_checking(), False)

心得

本次作业使用到了一些专业的关于测试项目的工具,让我学会了如何进行代码覆盖率的测试。最大的收获就是学习了如何进行项目的单元测试,学会了如何编写测试代码,怎么样才能尽可能提高代码覆盖率。总的来说,这次作业让我对软件工程中的测试有了更深的理解,让我受益匪浅。

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

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

相关文章

mysql 拼接字段

select spot_position,req_line,CONCAT(spot_position,-,req_line) from pdm_qc_apply where req_qctype != 2;结果展示:

Origin2024中绘制多因子分组柱状图,直观展示不同组别内的数据变化!

当我们需要对比多组平行数据时,采用Origin多因子分组柱状图,不仅可以直接的对比多组数据,同时还能够直观展示各个指标因子的数据变化及趋势操作步骤: 1、先打开Origin2024软件,然后在Book1中输入如下示例数据: 2、第一步,绘制分组柱形图图表,选中所有数据:3、点击菜单…

floorplan-reconsturtion-based-plane-triangle

一个iter算25s, 每个epoch31个iter,480个epoch需要 2531480/3600/24 = 4.3(天)改用30个epoch,训练5个小时Loss曲线

易基因:Adv Sci:ACE等揭示产前不良环境暴露通过DNA羟甲基化变化介导子代自闭症|国人佳作

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 自闭症谱系障碍(Autism spectrum disorder,ASD)是一种神经发育障碍,以社交沟通障碍和刻板行为为主要特征。许多研究证明,妊娠期暴露于环境毒素会导致儿童中ASD患病率快速增长。1-硝基芘(1-Nitropyrene,…

第十一章 图论 Part7

最小生成树算法(无向图) 1.prim算法 2.kruskal算法目录最小生成树算法prim算法适用范围:无向图思路kruskal算法适用范围: 无向图思路 最小生成树算法 prim算法 适用范围:无向图 思路 以将所有点归入最小生成树为目标,每次并入一个,最终生成最小生成树。 每次并入的步骤:…

小甲鱼FishC课后作业

第009讲:了不起的分支和循环30.下面的循环会打印多少次”i love fishc“ for i in range(0,10,2):print("i love fishc") 答:范围0-10,步进为2,打印5次1.下面的循环会打印多少次"I Love FishC"? for i in 5:print(I Love FishC) 答:报错int object i…

图与网络——最短路问题精解

最短路问题(Shortest Path Problem)是图论中的一个经典问题,广泛应用于现实世界中的多个领域。该问题的核心在于如何在一个图中找到给定起点和终点之间路径权重最小的路径。路径权重通常代表时间、成本、距离等因素,因此最短路问题不仅具有理论上的研究价值,还在实际问题的…

原始数据都一样,为啥Pyecharts做出来的图一个是彩色的,另一个是黑白的?

大家好,我是Python进阶者。 前言 前几天在铂金交流群里,有个叫【小朋友】的粉丝在Python交流群里问了一道关于Pyecharts可视化的问题,初步一看觉得很简单,实际上确实是有难度的,问题如下。乍一看,这个问题不知道他在说什么,看完代码之后,我才明白他的意思。 一、思路 下…

JDK mac版本安装及环境变量配置

官网下载jdk 8 注意:M芯片必须ARM版本否则编译报错安装失败!安装jdk (双击 -- 继续) 配置环境变量3.1 打开终端窗口,执行以下命令:3.2 执行命令打开.zshrc文件修改环境变量配置3.3 执行以下命令修改配置:export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-1.8.jd…

NATAPP实现内网穿透简易教程

NATAPP是什么 NATAPP是一个十分容易上手的内网穿透工具,可以把本机的ip和端口映射到公网,将本机暴露在公网中供他人访问。 这在进行一些回调接口的本地测试(如支付宝微信支付的回调接口)时十分好用,同时也可以用来搭建服务器私服,和朋友一起畅快联机。 NETAPP提供了两条免…

ThreadLocal线程重用时带来的问题

背景 我们都知道ThreadLocal实现了资源在线程内独享,线程之间隔离。 实际使用中,ThreadLocal适用于变量在线程间隔离,而在方法或类间共享的场景。比如用户信息,当用户信息需要在多个方法之间传递或者共享使用的时候,同时,每个Tomcat请求的用户信息是私有的。这时可使用Th…

Windows Server 2022 rdp

继续水一篇: 2022废弃了xddm转而使用wddm, rdp的渲染有比较大的变化。 高版本的unreal又需要2022支持,被迫走上魔改windows以提升2022 rdp环境下抓屏帧数的道路。 测试代码来自 https://github.com/robmikh/Win32CaptureSample ,只手动添加了输出fps逻辑。 patch windows后…