软件工程第二次作业 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
posted @ 2024-03-16 17:39  lzr。  阅读(39)  评论(0编辑  收藏  举报