个人项目
作业要求
| 这个作业属于哪个课程 | 软件工程 |
|---|---|
| 这个作业要求在哪里 | 个人项目 |
| 这个作业的目标 | 按时提交一个论文查重的项目 |
GitHub链接
https://github.com/fangzhixiang/fangzhixiang/tree/main
PSP表格
| psp2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 15 | 15 |
| · Estimate | · 估计这个任务需要多少时间 | 10 | 20 |
| Development | 开发 | 100 | 150 |
| · Analysis | · 需求分析 (包括学习新技术) | 20 | 20 |
| · Design Spec | · 生成设计文档 | 20 | 25 |
| · Design Review | · 设计复审 | 10 | 15 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
| · Design | · 具体设计 | 50 | 45 |
| · Coding | · 具体编码 | 10 | 10 |
| · Code Review | · 代码复审 | 10 | 10 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 50 | 40 |
| Reporting | 报告 | 30 | 30 |
| · Test Report | · 测试报告 | 30 | 30 |
| · Size Measurement | · 计算工作量 | 10 | 10 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 10 | 10 |
| · 合计 | 385 | 440 |
需求分析
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
- 原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
- 抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
- 从命令行参数给出:论文原文的文件的绝对路径。
- 从命令行参数给出:抄袭版论文的文件的绝对路径。
- 从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
接口的设计与实现过程
这个程序有四个函数:
文件读取函数
以读的方式打开,如果文件不存在则打印File not found。
def read_file(file_path):
try:
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read()
return text
except FileNotFoundError:
print(f"File not found: {file_path}")
sys.exit(1)
清除函数
清除文本文件中的标点符号,将大写字母转换为小写字母,提高查重准确性。
def clean_text(text):
# 去除标点符号和特殊字符
text = re.sub(f"[{string.punctuation}]", '', text)
# 将文本转换为小写字母
text = text.lower()
return text
计算相似度函数
def calculate_similarity(original_text, plagiarized_text):
# 使用difflib库的SequenceMatcher来计算相似性
original_text = clean_text(original_text)
plagiarized_text = clean_text(plagiarized_text)
similarity = difflib.SequenceMatcher(None, original_text, plagiarized_text).ratio()
return round(similarity, 2) # 保留两位小数
主函数
主函数判断输入参数个数,不满足四个则报错,将参数信息转换为文件路径,计算相似度之后输出结果并存储在答案文件中。
def 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 = read_file(original_file_path)
plagiarized_text = read_file(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:.2f}\n")
print("similarity is:"f"{similarity:.2f}\n")
运行脚本
if __name__ == '__main__':
unittest.main()
性能分析
pycharm生成的性能分析图如下:

覆盖率

单元测试代码
import unittest
from main import read_file, clean_text, calculate_similarity
class MyTestCase(unittest.TestCase):
#测试read_file函数
def test_read_file(self):
# 创建一个临时文本文件供测试使用
with open('temp.txt', 'w', encoding='utf-8') as temp_file:
temp_file.write('This is a test text.')
# 测试文件存在的情况
content = read_file('temp.txt')
self.assertEqual(content, 'This is a test text.')
# 测试文件不存在的情况
with self.assertRaises(SystemExit):
content = read_file('nonexistent_file.txt')
#测试clean_text函数
def test_clean_text(self):
input_text = "Hello, World! This is a test text."
expected_output = "hello world this is a test text"
cleaned_text = clean_text(input_text)
self.assertEqual(cleaned_text, expected_output)
#测试caculate_similarity函数
def test_calculate_similarity(self):
original_text = "This is the original text."
plagiarized_text = "This Is The Original Text."
similarity = calculate_similarity(original_text, plagiarized_text)
self.assertAlmostEqual(similarity, 1.0, places=2)
if __name__ == '__main__':
unittest.main()
异常处理说明
处理文件路径异常
try:
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read()
return text
except FileNotFoundError:
print(f"File not found: {file_path}")
sys.exit(1)
处理输入参数异常
if len(sys.argv) != 4:
print("Usage: python plagiarism_checker.py <original_file_path> <plagiarized_file_path> <output_file_path>")
sys.exit(1)
后续优化
1、文件内容统一化更加准确,在大小写和标点符号基础上增加如空格消除等功能。
2、命令行参数输入错误分类。
浙公网安备 33010602011771号