第一次个人编程作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229
这个作业的目标 完成论文查重项目,了解项目开发工程流程,学会使用PSP表格,性能分析以及单元测试等

一、Github 项目地址

https://github.com/Memset-Lee/Memset-Lee/tree/main/3122004695

二、需求

设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。

原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。

要求输入输出采用文件输入输出,规范如下:

从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。

注意:答案文件中输出的答案为浮点型,精确到小数点后两位。

三、PSP

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

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

代码总共包含get_argumentsread_filewrite_filesegment_textget_anscheck_file_pathcheck_empty_file七个函数:

get_arguments:获取命令行参数
read_file:读取文件内容
write_file:写入文件内容
segment_text:对文本进行分词
get_ans:构建TF-IDF特征矩阵并计算相似度
check_file_path:判断路径是否正确
check_empty_file:判断文件是否为空

代码逻辑和函数关系:

首先通过get_arguments获取命令行参数,然后通过check_file_path判断输入的路径是否正确,接着通过read_file将这些路径的文件内容读取出来,再通过check_empty_file判断文件是否为空,然后通过segment_text利用jieba库对文本内容进行分词,再通过get_ans根据分词后的结果构建TF-IDF特征矩阵并计算相似度,最后打印相似度并通过write_file保存到答案文本中。

关键之处和独到之处:

代码的关键之处在于对文本内容进行分词、构建TF-IDF特征矩阵以及计算相似度。在进行这些操作时,我选择调用了jieba库和scikit-learn库,因此代码逻辑会清晰明了许多,可读性也大大提高。
因为代码流程十分简单,并且我也在代码中写了许多注释,所以在这里就不给出流程图了,相信只要看过代码都能马上理解。

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

首先使用PyCharm提供了代码静态审查功能,消除了代码的所以警告:

image

然后使用第三方库line_profiler,对代码进行性能分析,结果如下图所示:

image
image

分析:

从结果中可以知道segment_text函数所消耗的时间是最多的,比其他所有函数所消耗的时间的总和还多。该函数用于对文本进行分词并去除标点符号,其中调用jieba库进行分词将近占了该函数所消耗时间的100%。因为这是调用第三方库,并且调用jieba库进行分词已经十分高效了,所以暂时没有什么地方可以进一步提高代码性能。

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

以下是我对segment_text函数所编写的单元测试代码:

构造测试数据的主要思路是要尽可能多的包含不同的符号,如中文、数字、标点符号等等。该单元测试包含了5组数据,能够全面的测试出segment_text函数的功能以及函数的设计是否有漏洞。

import re
import jieba
import unittest


def segment_text(text):  # 对文本进行分词
    text_without_punctuation = re.sub(r'[^\w\s]', '', text)  # 去除标点符号
    segment_list = jieba.cut(text_without_punctuation, cut_all=False)
    text_with_spaces = " ".join(segment_list)  # 用空格分词
    return text_with_spaces


class TestSegmentText(unittest.TestCase):
    def test_1(self):
        self.assertEqual(segment_text('你好,我是计科三班的一名学生。'), '你好 我 是 计科 三班 的 一名 学生')

    def test_2(self):
        self.assertEqual(segment_text('你好我是计科三班的一名学生'), '你好 我 是 计科 三班 的 一名 学生')

    def test_3(self):
        self.assertEqual(segment_text('123,456,789'), '123456789')

    def test_4(self):
        self.assertEqual(segment_text('123456789'), '123456789')

    def test_5(self):
        self.assertEqual(segment_text(',,。。!!'), '')


if __name__ == '__main__':
    unittest.main()

# cd C:\Users\26973\Desktop\Tools\Python Code\SEPersonalProject
# coverage run test_segment_text.py
# coverage report

以下是测试结果:

可以看出,五组数据全部通过,并且测试覆盖率达到100%,说明segment_text函数基本没有漏洞。
image

其余函数的单元测试,我就不再这里一一展示了,我将所有测试代码都上传到了 Github,需要的可以上Github找。我在本地测试时,全部函数都通过了单元测试的所有数据,并且测试覆盖率达到100%。

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

在项目中,我设计了路径不存在、文件为空、输入参数过少三个异常处理。

路径不存在:

目标:当输入的路径不存在时,会在cmd窗口中显示出哪些路径是不存在的。
如下图所示,第二和第三个路径是不存在的,它就会在cmd中打印出第二和第三个路径。
image
通过以下代码来具体实现该功能:

def check_file_path(file_paths):  # 判断路径是否正确
    flag = 0
    for file_path in file_paths:
        if not os.path.exists(file_path):
            print(f'Path does not exist: {file_path}')
            flag = 1
    if flag == 1:
        sys.exit()

文件为空:

目标:当原文文件或者抄袭文件为空时,会在cmd窗口显示出哪些文件是空的。
如下图所示,抄袭文件是空的,它就会在cmd中显示抄袭文件是空的。
image
通过以下代码来具体实现该功能:

def check_empty_file(text1, text2):  # 判断文件是否为空
    flag = 0
    if not text1:
        print('The original text file is empty.')
        flag = 1
    if not text2:
        print('The plagiarized text file is empty.')
        flag = 1
    if flag == 1:
        sys.exit()

输入参数过少:

目标:当输入的参数过少时,会在cmd窗口中显示缺少了哪些文件。
如下图所示,只输入了原文文件的路径,他就会在cmd中显示缺少抄袭文件和答案文件。
image
通过系统报错来具体实现该功能

posted on 2024-09-11 21:41  Memset_Lee  阅读(20)  评论(0编辑  收藏  举报