# 统计工作区代码行数与重复代码检测工具 **Repository Path**: TQLlab/Statistics_code ## Basic Information - **Project Name**: 统计工作区代码行数与重复代码检测工具 - **Description**: 统计指定文件夹下所有Python文件的代码行数,并检测重复的代码片段。它会生成一个Markdown文件,展示每个文件的统计信息,按唯一代码行数降序排列,并高亮重要指标,如代码行数和相似度。 主要功能: - 扫描指定目录下的所有Python文件 - 统计每个文件的代码行数、注释行数、文档字符串行数、空行等 - 检测重复的代码片段并计算相似度(相似度阈值默认92%) - 结果以Markdown格式输出 - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2024-10-07 - **Last Updated**: 2024-10-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 统计工作区代码行数与重复代码检测工具 ## 软件架构 本工具用于扫描 Python 项目中的 `.py` 文件,统计代码行数、注释行数、空行数等信息,并检测重复的代码块。生成的报告文件按照代码行数降序排列,重复的代码块相似度高于 92% 时会高亮显示。报告文件以 Markdown 格式输出,方便阅读和分享。 该工具的功能模块包括: 1. **文件扫描模块** 2. **代码行数统计模块** 3. **重复代码检测模块** 4. **生成 Markdown 报告模块** 5. **进度条显示模块** 下面对每个功能的具体实现进行详细说明。 --- #### 1. 文件扫描模块 **功能描述**: - 该模块的作用是递归遍历指定目录及其子目录,找到所有 `.py` 文件,并将文件路径存储到列表中。最终所有的 Python 文件都会被收集起来,供后续模块进行处理。 **实现原理**: - 使用 `os.walk()` 函数递归遍历指定的目录。`os.walk()` 会返回当前路径、子目录列表以及文件名列表。通过遍历文件名列表,筛选出以 `.py` 结尾的文件。 **关键代码**: ```python import os def scan_python_files(root_directory): py_files = [] for dirpath, _, filenames in os.walk(root_directory): for filename in filenames: if filename.endswith(".py"): py_files.append(os.path.join(dirpath, filename)) return py_files ``` --- #### 2. 代码行数统计模块 **功能描述**: - 统计每个 Python 文件的代码行数、空行数、注释行数和文档字符串行数。注释行包括以 `#` 开头的单行注释,文档字符串包括多行注释(`"""` 或 `'''` 包含的注释)。 **实现原理**: - 文件逐行读取,每行去除首尾空格后,通过以下方式分类: - **空行**:如果经过 `strip()` 操作后为空字符串,则为空行。 - **注释行**:以 `#` 开头的行。 - **文档字符串**:检查是否是 `"""` 或 `'''` 的开头或结尾。文档字符串可能跨越多行,因此需要一个标志来跟踪文档字符串是否已打开。 **关键代码**: ```python def count_lines_in_file(file_path): with open(file_path, 'r', encoding='utf-8') as f: code_lines, empty_lines, comment_lines, docstring_lines = 0, 0, 0, 0 in_docstring = False for line in f: stripped_line = line.strip() if not stripped_line: empty_lines += 1 elif stripped_line.startswith("#"): comment_lines += 1 elif stripped_line.startswith('"""') or stripped_line.startswith("'''"): docstring_lines += 1 in_docstring = not in_docstring # 开始或结束文档字符串 elif in_docstring: docstring_lines += 1 else: code_lines += 1 return code_lines, empty_lines, comment_lines, docstring_lines ``` --- #### 3. 重复代码检测模块 **功能描述**: - 该模块通过将每个 Python 文件拆分为多个代码块(如类定义、函数定义等),然后比较代码块之间的相似度,找出重复代码。相似度使用 `difflib.SequenceMatcher` 进行计算,默认相似度阈值为 92%。 **实现原理**: - 将每个文件分割为若干代码块(例如类、函数等),并将代码块存储起来。 - 使用 `difflib.SequenceMatcher` 来比较两个代码块之间的相似度。相似度达到设定的阈值(92%)时,将这两个代码块认定为重复,并记录在报告中。 - 对于重复代码,换行符会被替换为空格,以确保在 Markdown 表格中格式显示正确。 **关键代码**: ```python import difflib def compute_similarity(code1, code2): sm = difflib.SequenceMatcher(None, code1, code2) return sm.ratio() def detect_duplicate_blocks(file_blocks, threshold=0.92): duplicate_blocks = [] for i, block1 in enumerate(file_blocks): for j, block2 in enumerate(file_blocks): if i != j: similarity = compute_similarity(block1, block2) if similarity >= threshold: duplicate_blocks.append((block1, block2, similarity)) return duplicate_blocks ``` --- #### 4. 生成 Markdown 报告模块 **功能描述**: - 将扫描结果(包括代码行数统计和重复代码块信息)以 Markdown 格式输出,并根据代码行数降序排列文件。同时,高亮显示重要的指标,如代码块的相似度。 **实现原理**: - 在处理完所有文件后,将每个文件的统计信息和重复代码块的相关数据整理成表格,并输出为 `.md` 文件。 - 文件名带有时间戳,以确保每次扫描结果不会覆盖之前的报告。 **关键代码**: ```python from datetime import datetime def save_results_to_md(stats, duplicate_blocks, output_directory): date_str = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") md_filename = f"{output_directory}/python_code_stats_{date_str}.md" with open(md_filename, 'w', encoding='utf-8') as f: f.write(f"# Python 项目代码统计报告\n\n") f.write(f"**生成时间**: {date_str}\n\n") # 文件统计结果 f.write("## 文件统计结果\n") f.write("| 文件名 | 代码行数 | 空行数 | 注释行数 | 文档字符串行数 | 总行数 |\n") f.write("|---|---:|---:|---:|---:|---:|\n") for stat in stats: f.write(f"| {stat['filename']} | {stat['code_lines']} | {stat['empty_lines']} | " f"{stat['comment_lines']} | {stat['docstring_lines']} | {stat['total_lines']} |\n") # 重复代码块信息 f.write("\n## 重复代码块信息\n") f.write("| 文件1 | 文件2 | 相似度 |\n") f.write("|---|---|---:|\n") for block1, block2, similarity in duplicate_blocks: f.write(f"| `{block1}` | `{block2}` | **{similarity:.2f}** |\n") print(f"报告已生成: {md_filename}") ``` --- #### 5. 进度条显示模块 **功能描述**: - 在文件扫描和统计过程中,向用户显示进度条,实时显示当前处理的文件数和进度百分比。 **实现原理**: - 使用 `tqdm` 库为文件扫描过程添加进度条显示。`tqdm` 会随着每个文件的处理自动更新进度条,方便用户了解进度。 **关键代码**: ```python from tqdm import tqdm def process_files_with_progress(files): for file in tqdm(files, desc="扫描文件"): # 处理每个文件的逻辑 process_file(file) ``` --- ### 总结 - **文件扫描模块**:递归遍历给定目录,找到所有 `.py` 文件。 - **代码行数统计模块**:统计每个文件的代码行数、空行数、注释行数和文档字符串行数。 - **重复代码检测模块**:使用 `difflib.SequenceMatcher` 比较代码块的相似度,检测重复代码。 - **生成 Markdown 报告模块**:将所有统计数据和重复代码信息输出为 Markdown 报告,方便查看。 - **进度条显示模块**:使用 `tqdm` 库显示文件扫描和处理的实时进度。 通过这些模块的协同工作,本工具能够快速、准确地对项目中的 Python 文件进行分析,帮助开发者发现潜在问题并优化代码结构。 ## 安装教程 ### 1. 克隆仓库 首先,您需要将本项目的代码克隆到您的本地环境中。 - 在命令行中执行以下命令: ```bash git clone https://gitee.com/your-username/python-code-stats.git ``` - 进入项目目录: ```bash cd python-code-stats ``` ### 2. 安装依赖环境 为了确保程序可以运行,您需要安装所需的 Python 依赖库。我们将这些依赖写入了 `requirements.txt` 文件,您可以使用 `pip` 命令批量安装。 - 执行以下命令安装依赖: ```bash pip install -r requirements.txt ``` 安装过程中,`pip` 将自动安装所需的第三方库 `tqdm`,以便在文件扫描时显示进度条。 ### 3. 配置 Python 环境 确保您的系统已经安装了 Python 3.6 或更高版本。如果没有 Python,可以前往 [Python 官方网站](https://www.python.org/)下载并安装。 - 检查 Python 版本: ```bash python --version ``` 确保 Python 版本在 3.6 以上即可正常使用本工具。 ## 使用说明 ### 1. 运行 Python 脚本 - 打开命令行窗口,进入到项目的目录: ```bash cd python-code-stats ``` - 执行以下命令运行程序: ```bash python origin_code.py ``` - 程序将会提示您输入要扫描的 Python 文件所在目录。请输入该目录的路径,然后按回车键开始扫描: ```bash Please enter the directory to scan: /path/to/your/python/project ``` **注意:** 请输入实际的 Python 项目路径,工具将自动扫描该目录下的所有 `.py` 文件。 ### 2. 查看进度 在扫描过程中,程序将显示扫描进度。`tqdm` 进度条会实时更新,告诉您正在处理的文件和进度百分比。 ### 3. 查看生成的报告 扫描完成后,工具将自动在当前目录下生成一个报告文件。报告文件以 `.md` 格式保存,并带有时间戳,文件名类似于: python_code_stats_2024-10-05_07-01-41.md 报告内容包括: - 每个文件的代码行数、空行数、注释行数、文档字符串行数,按代码行数降序排列。 - 重复的代码块信息,包含相似度高于 92% 的重复代码,并且高亮了相似度。 ### 报告内容示例 ``` # Summary **Date** : 2024-10-05 07:01:41 **Directory**: /home/user/python_project **Total**: 10 files, **350** unique code lines, **600** total lines (including duplicates) ## Files (sorted by Unique Code Lines) | Filename | Unique Code Lines | Empty Lines | Comment Lines | Docstring Lines | Total Lines | |---|---:|---:|---:|---:|---:| | /home/user/python_project/file1.py | **100** | 20 | 10 | 5 | 135 | | /home/user/python_project/file2.py | **80** | 15 | 8 | 3 | 106 | | ... | ... | ... | ... | ... | ... | ## Duplicate Code Blocks (Similarity >= 92%) | Files (filename and similar file) | Origin Code Block | Similar Code Block | Similarity | |---|---|---|---:| | /home/user/python_project/file1.py | `def example_function(): pass` | `def example_function(): return None` | **95.00** | | /home/user/python_project/file3.py | `class TestClass:` | `class DemoClass:` | **92.50** | ```