软件工程第二次作业 3121002015 刘增荣
本项目已上传至仓库
这个作业属于哪个课程 | 软件工程2024-双学位(广东工业大学) |
---|---|
这个作业要求在哪里 | 个人项目作业-论文查重 |
这个作业的目标 | 代码实现、性能分析、单元测试、异常处理说明、记录PSP表格 |
其他参考文献 | ... |
1.需求
题目:论文查重
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
- 原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
- 抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
- 从命令行参数给出:论文原文的文件的绝对路径。
- 从命令行参数给出:抄袭版论文的文件的绝对路径。
- 从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例(提取码:nwjr),使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
2.开发环境
编程语言 | python |
---|---|
开发工具 | PyCharm Community Edition 2021.3.2 |
3.代码实现
import sys
# 从文件中加载文本内容
def load_text(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read()
return text
# 计算文本的相似度(基于编辑距离算法)
def calculate_similarity(original_text, plagiarized_text):
"""
计算两篇文章的相似度(基于编辑距离算法)
:param original_text: 原文的文本内容
:param plagiarized_text: 抄袭版的文本内容
:return: 相似度,范围在0到1之间
"""
len_original = len(original_text)
len_plagiarized = len(plagiarized_text)
dp = [[0] * (len_plagiarized + 1) for _ in range(len_original + 1)]
for i in range(1, len_original + 1):
for j in range(1, len_plagiarized + 1):
if original_text[i - 1] == plagiarized_text[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
similarity = dp[len_original][len_plagiarized] / max(len_original, len_plagiarized)
return similarity
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python plagiarism_checker.py <original_file_path> <plagiarized_file_path> <output_file_path>")
sys.exit(1)
original_file_path = sys.argv[1]
plagiarized_file_path = sys.argv[2]
output_file_path = sys.argv[3]
original_text = load_text(original_file_path)
plagiarized_text = load_text(plagiarized_file_path)
similarity = calculate_similarity(original_text, plagiarized_text)
with open(output_file_path, 'w', encoding='utf-8') as output_file:
output_file.write(f"重复率:{similarity:.2%}")
print("重复率计算已完成,结果已保存到指定文件中。")
运行结果
4.单元测试
import unittest
# 从文件中加载文本内容
def load_text(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read()
return text
# 计算文本的相似度(基于编辑距离算法)
def calculate_similarity(original_text, plagiarized_text):
len_original = len(original_text)
len_plagiarized = len(plagiarized_text)
dp = [[0] * (len_plagiarized + 1) for _ in range(len_original + 1)]
for i in range(1, len_original + 1):
for j in range(1, len_plagiarized + 1):
if original_text[i - 1] == plagiarized_text[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
similarity = dp[len_original][len_plagiarized] / max(len_original, len_plagiarized)
return similarity
class TestPlagiarismChecker(unittest.TestCase):
def test_load_text(self):
# 测试加载文本内容函数
file_path = 'test_file.txt'
expected_text = "This is a test file for load_text function."
with open(file_path, 'w', encoding='utf-8') as file:
file.write(expected_text)
loaded_text = load_text(file_path)
self.assertEqual(loaded_text, expected_text)
def test_calculate_similarity(self):
# 测试计算相似度函数
original_text = "apple banana mango"
plagiarized_text = "banana orange mango"
# 预期相似度为2/3≈0.6667
expected_similarity = 0.6667
# 设置误差范围为0.1,较宽松的范围
self.assertAlmostEqual(calculate_similarity(original_text, plagiarized_text), expected_similarity, delta=0.1)
if __name__ == '__main__':
unittest.main()
运行结果
5.性能测试
import time
import random
import string
# 从文件中加载文本内容
def load_text(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read()
return text
# 计算文本的相似度(基于编辑距离算法)
def calculate_similarity(original_text, plagiarized_text):
len_original = len(original_text)
len_plagiarized = len(plagiarized_text)
dp = [[0] * (len_plagiarized + 1) for _ in range(len_original + 1)]
for i in range(1, len_original + 1):
for j in range(1, len_plagiarized + 1):
if original_text[i - 1] == plagiarized_text[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
similarity = dp[len_original][len_plagiarized] / max(len_original, len_plagiarized)
return similarity
def generate_random_text(length):
return ''.join(random.choice(string.ascii_letters) for _ in range(length))
if __name__ == "__main__":
original_text = generate_random_text(1000) # 生成长度为1000的随机文本
plagiarized_text = generate_random_text(1000) # 生成另一份长度为1000的随机文本
start_time = time.time()
similarity = calculate_similarity(original_text, plagiarized_text)
end_time = time.time()
execution_time = end_time - start_time
print(f"相似度计算完成,耗时:{execution_time:.6f} 秒")
6.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
Estimate | 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 70 | 100 |
Analysis | 需求分析 (包括学习新技术) | 130 | 160 |
Design Spec | 生成设计文档 | 20 | 20 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 25 | 30 |
Design | 具体设计 | 25 | 20 |
Coding | 具体编码 | 80 | 110 |
Code Review | 代码复审 | 40 | 25 |
Test | 测试(自我测试,修改代码,提交修改) | 90 | 95 |
Reporting | 报告 | 90 | 80 |
Test Repor | 测试报告 | 95 | 90 |
Size Measurement | 计算工作量 | 35 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 40 | 30 |
合计 | 820 | 860 |