Python实现文章查重

软件工程https://edu.cnblogs.com/campus/gdgy/CSGrade21-12
作业要求 https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13014
作业目标 个人项目

github链接 :https://github.com/momotaaa/3121004806

题目:论文查重

描述如下:

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

原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:

从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。

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

PSP表格记录

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

代码实现

jieba分词

  通过jieba库来对文本进行分词

words1 = list(jieba.cut(content1))
words2 = list(jieba.cut(content2))

文件读取

def read_file(file_path):
    # Check file path
    if not os.path.exists(file_path):
        print("File path does not exist. Please check!")
        return None

    # Read file content
    with open(file_path, 'r', encoding='utf-8') as file:
        content = file.read()
    return content


def write_to_file(file_path, data):
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(data)

difflib.SequenceMatcher计算相似度

similarity_ratio = difflib.SequenceMatcher(None, words1, words2).ratio()

余弦值计算相似度

for tup1, tup2 in zip(words1, words2):
inner_product += tup1[1]*tup2[1]
square_length_vec1 += tup1[1]**2
square_length_vec2 += tup2[1]**2
return (inner_product/sqrt(square_length_vec1*square_length_vec2))

命令行参数

parser = argparse.ArgumentParser(description='Compute similarity between two files.')
parser.add_argument('file1', default='orig.txt', help='path to the original file')
parser.add_argument('file2', default='modify_orig.txt', help='path to the modified file', )
parser.add_argument('output_file', default='res.txt', help='path to the output file', )
args = parser.parse_args()

上述提供了两种方法计算文本相似度,一种是基于文本匹配,另外一种是通过计算余弦相似度

运行结果

在终端输入命令行参数

python .\main.py .\orig.txt .\modify_orig.txt .\res.txt
Namespace(file1='.\\orig.txt', file2='.\\modify_orig.txt', output_file='.\\res.txt')
Building prefix dict from the default dictionary ...                  
Loading model from cache C:\Users\26685\AppData\Local\Temp\jieba.cache
Loading model cost 0.418 seconds.
Prefix dict has been built successfully.
0.76

结果显示程序运行0.418秒,重复率为76%,性能比较优秀。

 分词部分结果:

['活着', '前言', '\n', '\n', ' ', ' ', ' ', ' ', '一位', '真正', '', '作家', '永远', '', '', '内心', '写作', '', '只有', '内心', '', '', '真实', '', '告诉', '', '', '', '', '自私', '', '', '', '高尚', '', '多么', '突出', '', '内心', '
', '', '真实', '', '了解', '自己', '', '一旦', '了解', '', '自己', '', '', '了解', '', '世界', '', '很多年', '', '', '', '明白', '', '这个', '原则', '', '可是', '', '捍卫', '这个', '原则', '必须', '付出', '艰辛', '', '劳动', '', '', '时期', '', '痛苦', '', '因为', '内心', '并非', '时时刻刻', '', '', '敞开', '', '', '', '', '', '', '时候', '', '', '封闭', '起来', '', '于是', '只有', '写作', '', '不停', '', '写作', '才能', '使', '内心', '敞开', '', '才能', '使',
 '自己', '置身于', '发现', '之中', '', '', '', '日出', '', '光芒', '照亮', '', '黑暗', '', '灵感', '这时候', '', '', '突然', '来到', '', '\n', '\n', ' ', ' ', ' ', ' ', '长期以来', '', '', '', '作品', '', '', '', '出于', '', '现实', '
', '', '一层', '紧张', '关系', '', '', '沉湎', '', '想象', '之中', '', '', '', '现实', '紧紧', '控制', '', '', '明确', '感受', '', '自我', '', '分裂', '', '', '无法', '使', '自己', '变得', '纯粹', '', '', '曾经', '希望', '自己', '成为
', '一位', '童话', '作家', '', '', '', '就是', '一位', '实实在在', '作品', '', '拥有者', '', '如果', '', '能够', '成为', '', '两者', '', '', '任何', '一个', '', '', '', '', '内心', '', '痛苦', '将会', '轻微', '', '', '', '可是', '与
此同时', '', '', '力量', '', '', '削弱', '很多', '', '\n', '\n', ' ', ' ', ' ', ' ', '事实上', '', '只能', '成为', '现在', '这样', '', '作家', '', '', '始终', '', '内心', '', '需要', '', '写作', '', '理智', '代替', '不了', '', '', '写作

 代码覆盖率:

Name      Stmts   Miss  Cover
-----------------------------
main.py      40      3    92%
-----------------------------
TOTAL        40      3    92%

在pycharm中通过coverage插件得到,代码覆盖率为92%,其中没有执行的3行是由于文件读取没有出现异常,未执行异常抛出代码,该程序性能较好。

性能已经到达瓶颈,无需再做出改进。选择不同的相似度计算函数会有不同的效果。

异常处理说明

  在读取指定文件路径时,如果文件路径不存在,程序将会抛出异常,在运行前应检查文件是否存在,然后再在终端执行代码。

  引入os.path.exists()方法用于检验文件是否存在。

 

posted @ 2023-09-11 19:41  dongzhi123  阅读(314)  评论(0编辑  收藏  举报