软件工程第一次作业

Github链接:https://github.com/BearSur/3123004753
以下为PSP表格

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

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

本程序用于计算论文原文与多个抄袭版本的相似度,整体采用 函数式结构。

模块划分

cosine_similarity(text1, text2)

输入:两个字符串。

输出:相似度(浮点数,范围 0~1)。

功能:利用余弦相似度算法,计算两个文本的相似度。

main()

输入:原始论文文件路径,多个抄袭版文件路径(存放在列表中)。

输出:结果文件,内容为 “文件名: 相似度”。

功能:调用 cosine_similarity 对每个文件逐一计算相似度并写入结果。

调用关系
main()-->读取原文--> 遍历文件列表-->cosine_similarity()--> 输出结果

核心算法说明

程序使用 字粒度的向量空间模型:

将文本拆分为单字,统计词频;

构造向量,计算点积与模长;

使用余弦相似度公式:

image

这种方法的特点是 实现简单、计算快速,能很好应对“在原文基础上的增删改”场景。

性能改进

在初版实现中,cosine_similarity 每次调用都会重复构造大向量,在处理长文本时效率较低。

改进思路

使用集合操作 counter1.keys() | counter2.keys() 替代多次循环。

用 zip 遍历向量,减少字典查询次数。

对于超长文本,可按段落拆分计算平均相似度,降低内存消耗。

改进耗时

性能分析与优化时间:约 20 分钟

性能分析截图

image

由于使用了社区版,只能使用CProfile

最耗时函数

cosine_similarity():主要耗时在 向量构造与点积计算。

单元测试展示

本程序使用 Python 的 unittest 框架 进行测试。测试覆盖了两个核心部分:

相似度计算函数 cosine_similarity

文件处理函数 process_files(包括文件读取、异常处理、结果输出)

单元测试

测试数据思路

完全相同文本 → 相似度应为 1.0

完全不同文本 → 相似度应接近 0.0

部分相似文本 → 相似度在中间值

覆盖率截图

image

  1. 异常处理说明

为了保证程序稳定运行,对常见异常情况做了处理。

异常设计

文件不存在

目标:输入路径错误时提示用户。

示例:

try:
open("non_exist.txt")
except FileNotFoundError:
print("文件未找到")

空文件

目标:文件为空时,相似度返回 0.0。

单元测试:

def test_empty_file():
assert cosine_similarity("", "") == 0.0

编码错误

目标:保证中文文件用 UTF-8 打开,避免 UnicodeDecodeError。

异常测试案例

在单元测试中加入对应的输入数据,可以验证这些异常是否被正确捕获。

总结

通过本次实验,我完成了论文查重程序的开发,并从以下方面进行了完善:

模块接口设计:明确了函数职责和调用关系;

性能优化:改进向量构造方式,降低运行开销;

单元测试:通过不同输入保证了函数的正确性;

异常处理:保证了在多种不正常输入下的稳定性。

这一过程帮助我更好地理解了 软件工程流程,也提升了我在 设计、优化、测试、健壮性 等方面的编程实践能力。

posted @ 2025-09-22 18:47  二熊苏尔  阅读(14)  评论(0)    收藏  举报