yoimmy

博客园 首页 新随笔 联系 订阅 管理

第一次个人编程作业

描述 详情
这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229
这个作业的目标 上传代码至github,熟悉软件项目开发流程与异常处理

个人项目github地址👇

https://github.com/115any/3222004512.git

一.个人统计PSP表格

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

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

一、代码组织

  1. 类的设计:此代码中未设计任何类。
  2. 函数的设计
    • calculate_similarity(ori_file, cop_file):用于计算两个文件的相似度,是核心功能函数。
    • split_arguments():提取命令行参数中的文件路径。
    • write_to_file(answer_file, message):将消息写入指定文件。
    • main():主函数,执行论文查重流程,协调调用其他函数。
  3. 函数关系
    • main函数作为程序入口,调用split_arguments获取文件路径,然后将获取的文件路径传递给calculate_similarity函数进行相似度计算。根据calculate_similarity的计算结果,main函数再调用write_to_file将结果写入指定文件。

二、关键函数流程图(以总代码与calculate_similarity为例)

总代码(主函数)流程图

graph TD A[开始] --> B[解析命令行参数] B --> C{参数是否正确} C -- 是 --> D[打开原文文件] C -- 否 --> E[打印错误信息并退出] D --> F[打开抄袭版文件] F --> G[读取文件内容] G --> H{文件是否成功打开} H -- 是 --> I[去除标点符号、空格和空行] H -- 否 --> E I --> J[计算重复词的数量] J --> K[计算文本重复率] K --> L{重复率是否计算成功} L -- 是 --> M[构建消息] L -- 否 --> E M --> N[将消息写入指定文件] N --> O[打印结果已写入文件] O --> P[结束]

calculate_similarity函数流程图

graph TD A[开始] --> B[打开原文文件] B --> C[打开抄袭版文件] C --> D[读取原文文件内容] D --> E[读取抄袭版文件内容] E --> F{文件是否成功打开} F -- 是 --> G[去除原文标点符号、空格和空行] F -- 否 --> H[打印错误信息并返回 None] G --> I[去除抄袭版标点符号、空格和空行] I --> J[将原文转换为小写] J --> K[将抄袭版转换为小写] K --> L[使用正则表达式提取原文单词] L --> M[使用正则表达式提取抄袭版单词] M --> N[计算原文单词集合] N --> O[计算抄袭版单词集合] O --> P[计算两个集合的交集] P --> Q[计算交集的大小] Q --> R{原文单词集合是否为空} R -- 是 --> S[返回 0] R -- 否 --> T[计算重复率] T --> U[返回重复率] U --> V[结束]

三、算法关键及独到之处

  1. 算法关键
    • 读取两个文件的内容,将其进行预处理,去除标点符号、空格和空行,并转换为小写,提取出单词。
    • 通过计算两个文本中单词集合的交集来确定重复的单词数量,进而计算文本重复率。
  2. 独到之处
    • 使用正则表达式简洁高效地提取单词,避免了复杂的字符串处理逻辑。
    • 对错误处理较为完善,在文件打开错误和计算过程中可能出现的问题时,都能给出明确的错误信息并进行适当的处理。
    • 通过终端命令行输入参数实现,增加了程序的灵活性和可扩展性,方便用户在不同场景下使用。

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

1.代码质量改进(Code Quality Analysis工具的分析并消除所有的警告)

本人采用pycharm内部插件pylint进行性能分析操作

解决警告前

解决警告后


性能分析图

本人使用的是pycharm内部插件profiler,Profiler 是一种性能分析工具,用于监控和分析软件程序的运行时性能。它帮助开发者了解程序在执行过程中的行为,特别是在 CPU 使用、内存消耗、输入/输出操作和线程活动等方面。通过使用 Profiler,可以识别程序的性能瓶颈,优化代码,提高程序的运行效率。

main.py👇

运行前:

运行后:


test_main.py:point_down[原图太长,仅提取其中一部分展示]:



由上图可知,运行时间最长的函数为main()函数,但是实际上main函数是一个集齐所有子函数功能的函数,实际上子函数中运行时间最长的函数为calculate_similarity()

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

1.单元测试代码

创建日期:2024 年 9 月 21 日

import unittest
import sys
from main import calculate_similarity, split_arguments, write_to_file

class TestFunctions(unittest.TestCase):
    """
    测试用例类,用于对论文查重程序中的各个函数进行单元测试。
    """

    def setUp(self):
        """
        测试用例初始化方法,在每个测试方法执行前都会被调用。
        设置测试所需的文件路径。
        """
        self.original_file_path = r'C:\Users\YANGY\Desktop\testbar\orig.txt'
        self.copied_file_paths = [
            r'C:\Users\YANGY\Desktop\testbar\orig_0.8_add.txt',
            r'C:\Users\YANGY\Desktop\testbar\orig_0.8_del.txt',
            r'C:\Users\YANGY\Desktop\testbar\orig_0.8_dis_1.txt',
            r'C:\Users\YANGY\Desktop\testbar\orig_0.8_dis_10.txt',
            r'C:\Users\YANGY\Desktop\testbar\orig_0.8_dis_15.txt'
        ]
        self.answer_file_path = r'C:\Users\YANGY\Desktop\testbar\answer.txt'

    def test_calculate_similarity(self):
        """
        测试 calculate_similarity 函数,确保计算结果不为 None。
        """
        for copied_file_path in self.copied_file_paths:
            similarity = calculate_similarity(self.original_file_path, copied_file_path)
            self.assertIsNotNone(similarity)

    def test_split_arguments(self):
        """
        测试 split_arguments 函数,确保提取的文件路径正确。
        """
        sys.argv = [
            'script_name', 
            self.original_file_path, self.copied_file_paths[0], self.answer_file_path
        ]
        original_file, copied_file, answer_file = split_arguments()
        self.assertEqual(original_file, self.original_file_path)
        self.assertEqual(copied_file, self.copied_file_paths[0])
        self.assertEqual(answer_file, self.answer_file_path)

    def test_write_to_file(self):
        """
        测试 write_to_file 函数,确保能正确写入文件并读取验证内容。
        """
        test_message = "Test message"
        write_to_file(self.answer_file_path, test_message)
        with open(self.answer_file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        self.assertEqual(content, test_message)

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

2.测试数据构造思路

以下是对这段测试代码中所测试的函数以及构造测试数据思路的说明:

一、测试的函数

这段测试代码主要测试了三个函数,分别来自外部模块(假设为your_module):

  1. calculate_similarity(ori_file, cop_file):该函数用于计算两个文件的相似度,返回一个表示重复率的数值,如果发生错误则返回None
  2. split_arguments():这个函数提取命令行参数中的文件路径,如果参数数量不正确则打印使用说明并退出程序,返回原文文件路径、抄袭版文件路径和结果文件路径。
  3. write_to_file(answer_file, message):将给定的消息写入指定的文件路径,如果文件存在则覆盖写入,不存在则创建并写入。

二、构造测试数据的思路

(一)测试calculate_similarity函数
  1. 不同相似度的文件组合

    • 完全相同的文件:通过复制原始文件创建两个完全一致的文件,确保在这种情况下函数应该返回相似度为 1。这可以验证函数在处理完全相同内容时的准确性。
    • 部分相同的文件:手动创建一些文件,在原始文件的基础上进行部分修改,如添加一些内容、删除一些内容或者进行一些小的改动。这样可以模拟实际中可能出现的部分抄袭情况,测试函数对不同程度相似度的计算能力。
    • 完全不同的文件:创建两个内容毫无关联的文件,用于测试函数在处理完全不相似的文本时是否能正确返回接近 0 的相似度。
  2. 特殊情况的文件

    • 空文件:创建一个空文件,与另一个非空文件进行组合测试。这可以检查函数在处理空文件时的行为,是否能正确处理并返回合理的结果。
    • 包含特殊字符的文件:在文件中加入一些特殊字符,如中文标点、特殊符号等,测试函数在处理包含特殊字符的文本时是否稳定,不会因为特殊字符而出现错误。
(二)测试split_arguments函数

通过设置特定的命令行参数来模拟实际运行情况。在测试中,将已知的文件路径(包括原始文件路径、抄袭版文件路径和结果文件路径)设置为命令行参数,然后调用split_arguments函数,验证函数是否能够正确提取这些路径并返回与预期一致的结果。

(三)测试write_to_file函数
  1. 使用一个固定的测试消息,将其写入指定的文件路径。然后,读取该文件并验证写入的内容是否与测试消息一致。这可以确保函数能够正确地将消息写入文件,并且在文件存在和不存在的两种情况下都能正确处理。
  2. 可以尝试不同的文件路径和消息内容,以进一步验证函数的稳定性和灵活性。

3.测试结果图

4.测试覆盖率截图

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

论文查重程序的改进

一、初始代码的问题

在一开始的代码中,未考虑空格、空行对重复率的影响,这导致最终得出的抄袭率偏低。

二、改进的设计原理
(一)准确性

考虑到准确性,在某些情况下,标点符号、空格和空行可能具有特定的语义价值,不应该被简单地去除。保留这些元素可以更准确地反映文本的实际内容和相似性。例如,一个特定的排版格式或标点的使用可能是作者独特的表达方式,去除它们可能会导致不准确的相似度计算。

(二)通用性

不同的文本类型和领域可能对标点符号、空格和空行的使用有不同的规范和重要性。不处理这些元素可以使程序适用于更广泛的文本类型,而不仅仅局限于特定的格式或风格。

(三)灵活性

保留这些元素可以为用户提供更多的灵活性。用户可以根据自己的需求和特定的文本特点来决定是否要考虑标点符号、空格和空行在相似度计算中的作用。例如,在某些特定的学术领域,标点符号的使用可能非常严格,去除它们可能会影响对抄袭的判断。

三、设计流程说明

calculate_similarity函数中:

  1. 读取原文文件和抄袭版文件的内容。
  2. 不再对文本进行去除标点符号、空格和空行的处理。
  3. 使用正则表达式提取出小写的单词序列,但不进行额外的处理。
  4. 计算两个文本中单词集合的交集得到重复的单词数量。
  5. 计算文本重复率。如果原文单词数量为 0,则返回 0。
posted on 2024-09-14 21:32  yoimmy  阅读(8)  评论(0编辑  收藏  举报