軟體工程第二次作業 3121002015 劉增榮

lzr。發表於2024-03-16

本專案已上傳至倉庫

這個作業屬於哪個課程 軟體工程2024-雙學位(廣東工業大學)
這個作業要求在哪裡 個人專案作業-論文查重
這個作業的目標 程式碼實現、效能分析、單元測試、異常處理說明、記錄PSP表格
其他參考文獻 ...

目錄
  • 本專案已上傳至倉庫
  • 1.需求
    • 題目:論文查重
  • 2.開發環境
  • 3.程式碼實現
    • 執行結果
  • 4.單元測試
    • 執行結果
  • 5.效能測試
  • 6.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

相關文章