第一次个人编程作业

第一次个人编程作业

这个作业属于哪个课程 信安1912-软件工程
这个作业要求在哪里 作业要求
这个作业的目标 论文查重;PSP表格使用

作业GitHub地址

https://github.com/YzGLBigTiger/3119005408

PSP表格

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

计算模块算法的设计与实现过程

编程环境

  • Python 3.9
  • PyCharm 2021.2.21
  • Windows 10专业版

论文查重算法

用余弦相似度算法计算文本相似度

接口设计

  • 文件读取 import_file(file_name) -> str
    将文件中的字节流以字符串形式返回。

  • 分词 jieba_cut(str) -> list
    使用jieba模块的lcut()函数将字符串分词,返回一个列表。

  • 合并 merge_lists(list1, list2) -> list
    将两个文件的字符串的分词列表进行不重复地合并,将合并后地道德列表返回。
    合并后的列表不含有以下符号:

    invalid_words_list = [',', ' ', '.', '。', ',', '(', '"', ')', '\'', '_', ':', ':', '“', '‘', '\n', '、']
  • 文章向量化 get_vector(words_list, merged_list)
    将文章分词得到的列表根据合并的列表进行向量化,返回一个向量列表

  • 计算余弦夹角 cal_vector_cos(vector1, vector2) -> float
    计算两个向量的夹角,作为文本的相似度,返回float型数。

  • 计算文本相似度 cal_sim_cosine(file_name1, file_name2) -> float
    使用以上接口计算给出两个文件的余弦相似度,返回保留两位小数的float型数。

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

性能分析

​ 被调用最多的函数是python处理dict类型变量的get()函数,因为文章数量多,词汇大量储存在dict类型变量中,因此需要大量该操作。

​ 占用时间最多的是jieba分词模块的cut函数。

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

单元测试

​ 对cal_sim_cosine.py模块的每个功能都进行了测试。

import unittestimport syssys.path.append("..")import cal_sim_cosine as calclass CalSimCosineTest(unittest.TestCase):    def setUp(self):        print("单元测试开始:")    def tearDown(self):        print("单元测试结束.\n")    def test_import_file(self):        """测试文件导入"""        self.assertIsNotNone(cal.import_file("测试文本//orig.txt"))        self.assertEqual(cal.import_file("测试文本//None"), '')    def test_jieba_cut(self):        """测试字符串分词"""        self.assertIn("我", cal.jieba_cut("我很帅。"))        self.assertNotIn("你", cal.jieba_cut("我很帅。"))        self.assertNotIn("。", cal.jieba_cut("我很帅。"))        self.assertEqual([], cal.jieba_cut("。."))    def test_merge_words(self):        """测试合并词表"""        self.assertEqual(['1', '2'], cal.merge_words(['1', '.'], ['2']))        self.assertEqual(['1'], cal.merge_words(['1', '.'], []))        self.assertEqual(['1'], cal.merge_words(['1', '.'], ['1']))    def test_get_vector(self):        """测试获得向量"""        self.assertEqual([2, 0], cal.get_vector([1, 1], [1, 0]))        self.assertEqual([3, 0], cal.get_vector([1, 1, 1], [1, 0]))        self.assertEqual([1, 2, 0], cal.get_vector([0, 1, 1], [0, 1, 2]))    def test_cal_vector_cos(self):        """测试求向量夹角余弦"""        self.assertEqual(1, round(cal.cal_vector_cos([1, 1, 1], [1, 1, 1]), 2))        self.assertEqual(0, cal.cal_vector_cos([0, 1, 9], [3, 0, 0]))    def test_cal_sim_cosine(self):        """测试整个计算文本相似度模块"""        self.assertEqual(1.0, cal.cal_sim_cosine("测试文本//orig.txt", "测试文本//orig.txt"))        self.assertGreater(1.0, cal.cal_sim_cosine("测试文本//orig.txt", "测试文本//orig_0.8_add.txt"))if __name__ == "__main__":    unittest.main()

测试结果

代码覆盖率

​ 覆盖94%的代码,剩余代码为异常处理。

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

  • IndexError
    用户输入的命令行参数不全造成的列表越界。
  • IOError
    文件不存在、文件拒绝访问造成的IO错误。
  • ZeroDivisionError
    由于文件为空或者文件没有有效字符,造成在获取文本向量时产生0向量,计算向量余弦时出现除数为0的错误。

个人总结

  • 本以为查重算法十分复杂,但是经过查资料才知道有许多有用的库和算法可以完成。查阅资料是现代编程中很重要的一种方法。
  • 通过对PSP表格的填写,我更加了解和熟悉开发一个项目的具体流程。