第一次个人编程作业
- 题目要求
- 查阅资料
- 模块接口的设计与实现过程
- 模块接口部分的性能改进
- 单元测试展示
- 异常处理
- PSP表格
- 参考资料
项目
|软件工程|https://edu.cnblogs.com/campus/gdgy/informationsecurity1812|
| ---- | ---- | ---- |
|作业要求|https://edu.cnblogs.com/campus/gdgy/informationsecurity1812/homework/11155|
|作业目标|实现具有文本查重功能的程序,熟悉PSP表格|
|Github地址|https://github.com/K-YOUTH/3118005389|
题目要求
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
查阅资料
方法:利用余弦定理求相似度,语言使用python
具体步骤:

模块接口的设计与实现过程
removePunctuation函数:对标点符号过滤,只剩下数字,中文,英文
def removePunctuation(text):
query = []
for s in text:
if (re.match(u"[a-zA-Z0-9\u4e00-\u9fa5]", s)):
query.append(s)
return query
get_sim函数:jieba分词,将文本转化为稀疏向量,得出相似度
def get_sim(path1,path2):
text1 = open(path1, encoding='utf8').read()
text2 = open(path2, encoding='utf8').read()
# jieba 进行分词
text_cut1 = jieba.lcut(text1)
text_cut1 = removePunctuation(text_cut1)
# 去除标点符号(只留字母、数字、中文)
text_cut2 = jieba.lcut(text2)
text_cut2 = removePunctuation(text_cut2)
text_cut = [text_cut1,text_cut2]
# 检验分词内容,成功后可去掉
print(text_cut)
#corpora语料库建立字典
dictionary = gensim.corpora.Dictionary(text_cut)
# 对字典进行doc2bow处理,得到新语料库
new_dictionary = [dictionary.doc2bow(text) for text in text_cut]
num_features = len(dictionary)# 特征数
# SparseMatrixSimilarity 稀疏矩阵相似度
similarity = gensim.similarities.Similarity('-Similarity-index', new_dictionary, num_features)
text_doc = dictionary.doc2bow(text_cut1)
sim = similarity[text_doc][1]
f = open(r'C:/Users/youth/Desktop/test/output.txt', 'w')
print('%.2f' % sim, file=f)
print('文本相似度: %.2f'% sim)
总的代码:
# -*- coding: utf-8 -*-
import re
import time
import jieba
import gensim
'''
# 仅去常见标点
def removePunctuation(text):
text = [i for i in text if i not in (' ',',','.','。','?','?','!','!','')]
return text
'''
'''
def removePunctuation(query):
rule = re.compile(u"[^a-zA-Z0-9\u4e00-\u9fa5]")
query = rule.sub('', query)
return query
'''
# 去除标点、符号(只留字母、数字、中文)
def removePunctuation(text):
query = []
for s in text:
if (re.match(u"[a-zA-Z0-9\u4e00-\u9fa5]", s)):
query.append(s)
return query
def get_sim(path1,path2):
text1 = open(path1, encoding='utf8').read()
text2 = open(path2, encoding='utf8').read()
# jieba 进行分词
text_cut1 = jieba.lcut(text1)
text_cut1 = removePunctuation(text_cut1)
# 去除标点符号(只留字母、数字、中文)
text_cut2 = jieba.lcut(text2)
text_cut2 = removePunctuation(text_cut2)
text_cut = [text_cut1,text_cut2]
# 检验分词内容,成功后可去掉
print(text_cut)
#corpora语料库建立字典
dictionary = gensim.corpora.Dictionary(text_cut)
# 对字典进行doc2bow处理,得到新语料库
new_dictionary = [dictionary.doc2bow(text) for text in text_cut]
num_features = len(dictionary)# 特征数
# SparseMatrixSimilarity 稀疏矩阵相似度
similarity = gensim.similarities.Similarity('-Similarity-index', new_dictionary, num_features)
text_doc = dictionary.doc2bow(text_cut1)
sim = similarity[text_doc][1]
f = open(r'C:/Users/youth/Desktop/test/output.txt', 'w')
print('%.2f' % sim, file=f)
print('文本相似度: %.2f'% sim)
if __name__ == '__main__':
path1 = "C:/Users/youth/Desktop/test//orig.txt"
path2 = "C:/Users/youth/Desktop/test/orig_0.8_dis_1.txt"
'''
#现实使用中可将固定路径改为以下模块,更改工作路径
#工作路径为桌面
#work_dir = "C:/Users/youth/Desktop/test/"
print("工作路径为桌面,请输入原文本文件名:\n")
path1_1 = ""
path2_1 = ""
path1_1 = input(path1_1)
path1 = work_dir + path1_1
print("请输入第二个文本文件名:\n")
path2_1 = input(path2_1)
path2 = work_dir + path2_1
'''
start = time.time()
get_sim(path1, path2)
end = time.time()
print('运行时间: %s 秒' % (end - start))
模块接口部分的性能改进
原采用jieba.cut进行分词,分词后需要将利用for循环分词结果转换为列表;
改成jieba.lcut进行分词,直接将分词结果转为列表。
(main2.py采用jieba.cut进行分词,main.py改成jieba.lcut进行分词,文件见github仓库)
单元测试
性能分析:

代码覆盖率:

测试:
文本路径:

答案文件路径:

orig.txt 、orig_0.8_add.txt

orig.txt 、orig_0.8_del.txt

orig.txt 、orig_0.8_dis_1.txt

如果采用以下去除标点(仅去常见标点)的函数,相识度会降低,原因是英文连符'-'。(orig.txt 、orig_0.8_dis_1.txt)
def removePunctuation(text):
text = [i for i in text if i not in (' ',',','.','。','?','?','!','!','')]
return text

异常处理
print("工作路径为桌面,请输入原文本文件名:\n")
path1_1 = ""
path2_1 = ""
path1_1 = input(path1_1)
path1 = work_dir + path1_1
print("请输入第二个文本文件名:\n")
path2_1 = input(path2_1)
path2 = work_dir + path2_1
采用以上代码,若输入的文件名错误,程序异常。
PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 30 | 35 |
| · Estimate | · 估计这个任务需要多少时间 | 30 | 30 |
| Development | 开发 | 120 | 150 |
| · Analysis | · 需求分析 (包括学习新技术) | 60 | 60 |
| · Design Spec | · 生成设计文档 | 15 | 15 |
| · Design Review | · 设计复审 | 20 | 20 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
| · Design | · 具体设计 | 40 | 45 |
| · Coding | · 具体编码 | 30 | 40 |
| · Code Review | · 代码复审 | 30 | 40 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 40 | 60 |
| Reporting | 报告 | 30 | 30 |
| · Test Repor | · 测试报告 | 15 | 15 |
| · Size Measurement | · 计算工作量 | 15 | 15 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 8 | 10 |
| · 合计 | 453 | 530 |
参考资料
https://blog.csdn.net/Nonoroya_Zoro/article/details/80342532
https://titanwolf.org/Network/Articles/Article?AID=26627f5e-1ce9-40cb-a091-b771ae91d69d
https://www.cnblogs.com/airnew/p/9563703.html
https://blog.csdn.net/qq236237606/article/details/107815605
https://www.bilibili.com/video/BV1SQ4y1A739?t=1510

浙公网安备 33010602011771号