将develop分支的内容合并到main分支中 #4

Merged
pijtbanfl merged 3 commits from develop into main 5 months ago

@ -4,7 +4,7 @@
本项目是一个基于Java开发的中小学数学卷子自动生成系统支持小学、初中、高中三个学段的数学题目生成。系统采用面向对象设计遵循Google Java Style Guide规范具有完整的用户认证、题目生成、查重和文件管理功能。
**【人工修改】** 本项目在大模型生成基础代码后,经过人工增强优化,在原有功能基础上新增了多项功能改进,包括文件夹结构优化、题目质量提升、用户界面体验优化等,所有修改都已在代码中明确标识。
**【人工修改】** 本项目在大模型生成基础代码后,经过人工优化(主要是老师要求的操作数范围和自己对操作界面的优化进行修改),在原有功能基础上新增了多项功能改进,包括文件夹结构优化、题目质量提升、用户界面体验优化等,所有修改都已在代码中明确标识。
## 功能特性
@ -17,8 +17,8 @@
- **小学题目**:只能有+,-,*,/和()运算符
- **初中题目**:题目中至少有一个平方或开根号的运算符
- **高中题目**题目中至少有一个sin,cos或tan的运算符
- 操作数范围1-5个取值范围1-100
- 题目数量10-30道题
- **操作数范围**1-5个小学题目至少2个取值范围1-100
- **题目数量**10-30道题
#### 难度要求详细说明(附表-2
| 年级 | 难度要求 | 备注 |
@ -30,7 +30,7 @@
### 🔄 年级切换功能
- 支持"切换为XX"命令XX为小学、初中、高中
- 实时切换出题模式
- 切换后自动显示新的操作菜单
- 切换后按回车自动显示新的操作菜单
### 🔍 题目查重功能
- 自动检测历史题目,避免重复
@ -41,79 +41,48 @@
- **【人工修改】** 采用三级文件夹结构:`paper/用户名/年级/`
- 文件名格式:`年-月-日-时-分-秒.txt`
- 题目格式:带题号,题目间空行分隔
- **【人工修改】** 试卷集中管理,按年级分类存储
- 试卷集中管理,按年级分类存储(原来是只按用户名存储)
## 【人工修改】功能增强说明
### 🚀 人工修改概述
本项目在大模型生成基础代码后,经过人工增强优化,在原有功能基础上进行了以下重要改进:
在原有功能基础上进行了以下重要改进:
### 🐛 Bug修复
### 🔧 人工修改功能详解
**资源泄漏修复**
- **【人工修改】** 修复了Scanner资源泄漏问题确保程序退出时正确关闭资源
**Bug修复内容**
- **【人工修改】** 修复了Scanner资源泄漏问题添加了shutdown hook确保资源正确关闭
## 🔧 人工修改功能详解
### 1. 📁 文件夹结构优化
- **修改位置**`MathQuestionGenerator.java` 第272-298行
#### 1. 📁 文件夹结构优化
- **修改位置**`MathQuestionGenerator.java` 第367行createUserDirectory方法
- **修改前**:文件直接保存在用户名文件夹中,如 `张三1/2025-01-27-14-30-25.txt`
- **修改后**:采用三级文件夹结构 `paper/用户名/年级/`,如 `paper/张三1/小学/2025-01-27-14-30-25.txt`
- **功能**创建paper文件夹结构试卷集中管理
- **效果**:文件按年级分类存储,结构更清晰,便于管理
- **代码标识**:使用 `// 【人工修改】` 注释标识
### 2. 🎯 小学题目质量提升
- **修改位置**多个文件中的常量定义和方法实现
- **修改前**:小学题目可能出现单操作数,如 `24`(无效题目)
#### 2. 🎯 小学题目质量提升
- **修改位置**`PrimaryQuestionGenerator.java` 第12行getMinOperandCount方法
- **修改前**:小学题目可能出现单操作数,如 `24`无效题目在老师没有说明之前AI所设计
- **修改后**小学题目最少2个操作数`24 + 15`(有效题目)
- **功能**小学题目最少2个操作数防止出现无效题目
- **功能**重写getMinOperandCount方法确保小学题目至少有2个操作数
- **效果**:不再出现单纯的数字,确保题目有效性
- **代码标识**:使用 `// 【人工修改】` 注释标识
### 3. 🔧 初中题目格式修复
- **修改位置**`JuniorQuestionGenerator.java` 第16-34行
- **修改前**:初中题目可能不完整,如 `24²``√36`(缺少运算符)
- **修改后**:初中题目格式完整,如 `24² + 15``√36 × 8 - 12`(完整表达式)
- **功能**:修复平方和开方运算后缺少运算符的问题
- **效果**:确保初中题目格式完整,符合数学表达式规范
- **代码标识**:使用 `// 【人工修改】` 注释标识
### 4. 🎨 用户界面体验优化
- **修改位置**`MathQuestionGenerator.java` 第196-213行
- **修改前**:生成题目后或输入错误后,用户看不到操作菜单,需要重新输入
- **修改后**:生成题目后和输入错误后自动重新显示操作菜单
- **功能**:生成题目后和输入错误后重新显示操作菜单
- **效果**:用户始终能看到可用的操作选项,界面体验更友好
- **代码标识**:使用 `// 【人工修改】` 注释标识
### 5. 🎯 界面交互体验优化
- **修改位置**`MathQuestionGenerator.java` 第245-278行、第485-501行、第199-236行
#### 3. 🎨 用户界面体验优化
- **修改位置**`MathQuestionGenerator.java` 第133行添加exit选项
- **修改前**:只能通过用户名密码登录,没有退出选项
- **修改后**:支持输入'exit'退出程序,提供更好的用户控制
- **功能**:添加退出选项,提升用户体验
- **效果**:用户可以选择退出程序,操作更灵活
#### 4. 🎯 界面交互体验优化
- **修改位置**`MathQuestionGenerator.java` 第176行、第238行、第253行、第331行、第341行、第578行等
- **修改前**:切换模式或生成试卷后直接显示界面,界面切换突兀
- **修改后**:切换模式或生成试卷后要求按回车键继续,界面切换更自然
- **功能**:在关键操作后添加"按回车键继续"提示,提升用户体验
- **效果**:用户有时间阅读操作结果,界面切换更自然流畅
- **代码标识**:使用 `// 【人工修改】` 注释标识
### 6. 📊 去重功能增强
- **修改位置**`MathQuestionGenerator.java` 第363-392行
- **修改前**:所有年级的历史题目混合在一起,去重可能跨年级干扰
- **修改后**:按年级分别加载历史题目,去重功能更精确
- **功能**:从对应的年级文件夹加载历史题目
- **效果**:去重功能按年级分别进行,更加精确
- **代码标识**:使用 `// 【人工修改】` 注释标识
### 7. 🐛 Bug1修复Scanner资源泄漏
- **修改位置**`MathQuestionGenerator.java` 第43-52行
- **修改前**Scanner资源没有正确关闭可能导致资源泄漏
- **修改后**添加shutdown hook确保Scanner资源在程序退出时正确关闭
- **功能**:修复资源泄漏问题,符合头歌质量分析要求
- **效果**:确保程序退出时正确释放系统资源,避免内存泄漏
- **代码标识**:使用 `// 【人工修改】` 注释标识
**所有修改都使用 `// 【人工修改】` 注释标识,便于识别和追踪。**
## 技术架构
@ -124,7 +93,7 @@
### 📁 项目结构
```
project/src/
src/
├── MathQuestionGenerator.java # 主程序类
├── QuestionGenerator.java # 题目生成器接口
├── AbstractQuestionGenerator.java # 抽象题目生成器
@ -159,20 +128,68 @@ project/src/
## 使用说明
### 编译JAR文件
#### 方法1使用javac和jar命令推荐
**步骤1编译Java源文件**
```bash
# 创建输出目录
mkdir -p out/production/project
# 编译所有Java文件
javac -d out/production/project -encoding UTF-8 src/*.java
```
**步骤2创建MANIFEST.MF文件**
```bash
# 创建MANIFEST.MF文件Windows PowerShell
New-Item -ItemType File -Name "MANIFEST.MF" -Value "Manifest-Version: 1.0`nMain-Class: MathQuestionGenerator`n"
# 或者使用文本编辑器手动创建MANIFEST.MF文件内容如下
# Manifest-Version: 1.0
# Main-Class: MathQuestionGenerator
```
**步骤3打包为JAR文件**
```bash
# 创建JAR文件只包含src文件夹的内容
jar cfm MathQuestionGenerator.jar MANIFEST.MF -C out/production/project .
```
**完整示例**
```bash
# 在项目根目录下执行以下命令
mkdir -p out/production/project
javac -d out/production/project -encoding UTF-8 src/*.java
New-Item -ItemType File -Name "MANIFEST.MF" -Value "Manifest-Version: 1.0`nMain-Class: MathQuestionGenerator`n"
jar cfm MathQuestionGenerator.jar MANIFEST.MF -C out/production/project .
java -jar MathQuestionGenerator.jar
```
#### 方法2使用IDE如IntelliJ IDEA
1. **打开项目**在IDE中打开src文件夹
2. **构建项目**Build → Build Project
3. **创建JAR**File → Project Structure → Artifacts → JAR → From modules with dependencies
4. **设置主类**选择MathQuestionGenerator作为Main Class
5. **构建JAR**Build → Build Artifacts
### 启动程序
```bash
java -cp project/src MathQuestionGenerator
java -jar MathQuestionGenerator.jar
```
### 操作流程
1. **登录**:输入用户名和密码(用空格隔开),或输入'exit'退出程序
2. **查看菜单**:系统显示当前可进行的操作
3. **生成题目**输入数字10-30生成指定数量的题目
4. **切换年级**:输入"切换为XX"切换到其他年级
3. **生成题目**输入数字10-30生成指定数量的题目,生成完成后按回车键继续
4. **切换年级**:输入"切换为XX"切换到其他年级,切换完成后按回车键继续
5. **退出登录**:输入"-1"退出当前用户
6. **完全退出**:在登录界面输入'exit'完全退出程序
### 操作示例
```
=== 用户登录 ===
请输入用户名和密码(用空格隔开),或输入 'exit' 退出程序:
@ -190,7 +207,17 @@ java -cp project/src MathQuestionGenerator
4. 输入 '切换为高中':切换到高中出题模式
5. 输入 '-1':退出当前用户,重新登录
请输入操作:
请输入操作:> 15
生成15道小学题目成功
文件已保存到paper/张三1/小学/2025-01-27-14-30-25.txt
按回车键继续...
[按回车键后显示菜单]
=== 操作菜单 ===
当前选择为小学出题
...
```
## 题目示例
@ -216,6 +243,32 @@ java -cp project/src MathQuestionGenerator
3. cos(0) + sin(30) × 4
```
## 📸 实际操作演示
### 登录界面
![登录界面](images/login_screen.png)
*图1程序启动后的登录界面支持用户名密码登录或输入'exit'退出*
### 操作菜单
![操作菜单](images/operation_menu.png)
*图2登录成功后的操作菜单显示当前年级和可用操作*
### 题目生成
![题目生成](images/question_generation.png)
*图3生成题目过程显示题目数量和保存位置*
### 年级切换
![年级切换](images/grade_switch.png)
*图4年级切换功能演示支持小学、初中、高中模式切换*
### 文件输出
![文件输出](images/file_output.png)
*图5生成的文件结构采用三级文件夹管理*
### 题目示例展示(此为小学题目)
![题目示例](images/question_examples.png)
*图6题目示例展示*
## 代码规范
### 📋 Google Java Style Guide合规性
@ -233,66 +286,9 @@ java -cp project/src MathQuestionGenerator
- 完整的异常处理
- 资源自动管理try-with-resources
## 评分标准符合性
## 📊 评分标准符合性
根据项目评分标准,本系统完全符合要求:
| 评分类型 | 要求 | 实现状态 |
|---------|------|----------|
| 登录 | 文字提示、错误处理 | ✅ 完全符合 |
| 出题 | 年级要求、题号、换行、切换提示 | ✅ 完全符合 |
| 查重 | 去重功能、历史题目检测 | ✅ 完全符合 |
| 切换 | 年级切换、错误处理、异常处理 | ✅ 完全符合 |
| 保存 | 文件格式、路径管理 | ✅ 完全符合 |
| 代码规范 | Google Java Style Guide | ✅ 完全符合 |
| 设计合理 | 接口抽象类、类数量、方法长度 | ✅ 完全符合 |
## 开发环境
- **Java版本**JDK 8+我是JDK21
- **编译工具**javac
- **运行环境**JRE 8+
- **操作系统**Windows/Linux/macOS我是Windows
## 编译和运行
### 编译所有文件
```bash
javac project/src/*.java
```
### 运行程序
```bash
java -cp project/src MathQuestionGenerator
```
## 文件输出
**【人工修改】** 程序采用三级文件夹结构,所有试卷统一存放在 `paper` 文件夹中:
```
project/
├── paper/ # 【人工修改】试卷集中存放文件夹
│ ├── 张三1/ # 用户文件夹
│ │ ├── 小学/ # 【人工修改】年级子文件夹
│ │ │ ├── 2025-01-27-14-30-25.txt
│ │ │ └── 2025-01-27-15-45-12.txt
│ │ ├── 初中/
│ │ │ └── 2025-01-27-16-20-30.txt
│ │ └── 高中/
│ │ └── 2025-01-27-17-10-45.txt
│ ├── 李四1/
│ │ ├── 小学/
│ │ ├── 初中/
│ │ └── 高中/
│ └── 王五1/
│ ├── 小学/
│ ├── 初中/
│ └── 高中/
└── src/ # 源代码文件
```
## 📊 评分要求对照
### 功能要求对照
| 评分项目 | 要求 | 实现状态 | 说明 |
|---------|------|---------|------|
@ -304,10 +300,48 @@ project/
| **查重功能** | 有查重功能 | ✅ 已实现 | 完整的题目去重机制 |
| **切换功能** | 有切换功能 | ✅ 已实现 | 支持小学/初中/高中模式切换 |
| **保存功能** | 使用相对路径 | ✅ 已实现 | 文件保存在paper文件夹中 |
### 代码质量要求
| 评分项目 | 要求 | 实现状态 | 说明 |
|---------|------|---------|------|
| **代码规范** | 符合Google规范 | ✅ 已实现 | 完全符合Google Java Style Guide |
| **设计合理性** | 有接口和抽象类 | ✅ 已实现 | 使用策略模式、模板方法模式 |
| **设计合理性** | 方法≤40行 | ✅ 已实现 | 所有方法都符合行数限制 |
| **Bug修复** | 资源泄漏 | ✅ 已实现 | 修复了Scanner资源泄漏问题 |
| **Bug修复** | 资源泄漏 | ✅ 已实现 | 修复了输入流读取问题 |
## 开发环境
- **Java版本**JDK 21推荐JDK 8+
- **编译工具**javac
- **运行环境**JRE 21推荐JRE 8+
- **操作系统**Windows 11推荐Windows 10+、macOS 10.14+、Ubuntu 18.04+
- **开发工具**IntelliJ IDEA可选
- **命令行工具**PowerShell/CMD使用命令行工具运行代码如果遇到文字乱码或文字无法输入的问题建议查看 ⚠️ 可能遇到的问题 部分)
## 文件输出
**【人工修改】** 程序采用三级文件夹结构,所有试卷统一存放在 `paper` 文件夹中:
```
paper/ # 试卷集中存放文件夹(运行时生成)
├── 张三1/ # 用户文件夹
│ ├── 小学/ # 年级子文件夹
│ │ ├── 2025-01-27-14-30-25.txt
│ │ └── 2025-01-27-15-45-12.txt
│ ├── 初中/
│ │ └── 2025-01-27-16-20-30.txt
│ └── 高中/
│ └── 2025-01-27-17-10-45.txt
├── 李四1/
│ ├── 小学/
│ ├── 初中/
│ └── 高中/
└── 王五1/
├── 小学/
├── 初中/
└── 高中/
```
## 项目特色
@ -320,14 +354,14 @@ project/
- 完全符合Google Java Style Guide
- 完整的文档注释
- 健壮的错误处理
- **【人工修改】** 修复了Scanner资源泄漏问题
- **【人工修改】** 所有修改都使用 `// 【人工修改】` 标识
- 修复了输入流读取问题
- 所有人工修改都使用 `// 【人工修改】` 标识
### 🚀 用户体验
- 直观的操作界面
- 清晰的功能提示
- 友好的错误信息
- **【人工修改】** 生成题目后自动显示操作菜单
- **【人工修改】** 生成题目后要求按回车键继续,界面切换更自然
- **【人工修改】** 支持'exit'命令退出程序
### 📊 功能完整
@ -335,7 +369,6 @@ project/
- 支持多种操作模式
- 完整的文件管理
- **【人工修改】** 三级文件夹结构,试卷集中管理
- **【人工修改】** 修复了资源泄漏问题,符合头歌质量分析要求
## ⚠️ 可能遇到的问题(主要是我自己写代码调试的时候遇到的,应该也就这一个比较容易遇到)
@ -347,7 +380,7 @@ project/
**解决方案**
#### 方法1修改控制台编码应该是可以的我没有成功
#### 方法1修改控制台编码应该是可以的因为是暂时性的,我没有试过
```cmd
# 在CMD中运行
chcp 65001
@ -386,6 +419,8 @@ chcp
## 作者信息
- **班级**软件2301
- **姓名**:王麒晟
- **项目类型**:个人项目
- **开发语言**Java
- **设计模式**:策略模式、模板方法模式、工厂模式
@ -393,21 +428,8 @@ chcp
- **项目状态**:完成,符合评分要求
- **【人工修改】** 经过人工增强优化,功能更加完善
## 【人工修改】代码标识说明
本项目中的所有人工修改都使用 `// 【人工修改】` 注释进行标识,包括:
1. **文件夹结构优化**`MathQuestionGenerator.java` 第272-298行
2. **小学题目质量提升**:多个文件中的常量定义和方法实现
3. **初中题目格式修复**`JuniorQuestionGenerator.java` 第16-34行
4. **用户界面体验优化**`MathQuestionGenerator.java` 第196-213行
5. **去重功能增强**`MathQuestionGenerator.java` 第363-392行
6. **Bug1修复Scanner资源泄漏**`MathQuestionGenerator.java` 第43-52行
7. **抽象类方法优化**`AbstractQuestionGenerator.java` 第29-41行
8. **小学生成器重写**`PrimaryQuestionGenerator.java` 第8-12行
所有修改都已在代码中明确标识,便于识别和追踪。
---
*本项目完全符合软件工程导论个人项目的所有要求,经过人工增强优化后功能更加完善。*
*本项目完全符合软件工程导论个人项目的所有要求,经过人工增强优化后功能更加完善。*

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -1,18 +1,9 @@
// 【人工修复】删除未使用的导入消除IDEA警告
// 修改前import java.util.Random; 从未使用IDEA显示警告
// 修改后:删除未使用的导入,简化代码
/**
*
*/
public abstract class AbstractQuestionGenerator implements QuestionGenerator {
protected static final String[] BASIC_OPERATORS = {"+", "-", "×", "÷"};
// 【人工修复】删除未使用的方法消除IDEA警告
// 修改前generateOperands和generateOperandCount方法从未使用IDEA显示警告
// 修改后:删除这些未使用的方法,简化代码结构
// 注意这些方法原本是为了提供通用功能但在得知小学操作数至少为2时实际实现中每个子类都有自己的逻辑故删掉
static final String[] BASIC_OPERATORS = {"+", "-", "×", "÷"};
/**
*

@ -12,10 +12,7 @@ public class JuniorQuestionGenerator extends AbstractQuestionGenerator {
// 初中题目:题目中至少有一个平方或开根号的运算符,严格按照附表-2要求
int pos = random.nextInt(operands.length);
boolean useSquare = random.nextBoolean();
// 【人工修改】修复初中题目生成逻辑,确保平方和开方后有正确的运算符和操作数
// 修改前:初中题目可能不完整,如"24²"或"√36"(缺少运算符)
// 修改后:初中题目格式完整,如"24² + 15"或"√36 × 8 - 12"(完整表达式)
if (useSquare) {
// 平方运算
question.append(operands[pos]).append("²");
@ -25,10 +22,7 @@ public class JuniorQuestionGenerator extends AbstractQuestionGenerator {
operands[pos] = sqrtBase * sqrtBase; // 生成完全平方数
question.append("√").append(operands[pos]);
}
// 【人工修改】修复剩余部分添加逻辑,确保平方/开方后有运算符和操作数
// 修改前:复杂的条件判断,可能导致运算符缺失
// 修改后:简化逻辑,确保所有剩余操作数都有运算符
for (int i = 0; i < operands.length; i++) {
if (i != pos) {
// 添加运算符和操作数

@ -38,17 +38,10 @@ public class MathQuestionGenerator {
// 当前登录用户
private static User currentUser = null;
private static final Scanner scanner = new Scanner(System.in);
private static final Scanner scanner = new Scanner(System.in, java.nio.charset.StandardCharsets.UTF_8);
// 【人工修改】添加程序退出时的资源清理
// 修改前Scanner资源没有正确关闭可能导致资源泄漏
// 修改后添加shutdown hook确保Scanner资源正确关闭
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (scanner != null) {
scanner.close();
}
}));
Runtime.getRuntime().addShutdownHook(new Thread(scanner::close));
}
static {
@ -92,9 +85,6 @@ public class MathQuestionGenerator {
public static void main(String[] args) {
showWelcomeMessage();
// 【人工修复】修复while循环警告简化循环逻辑
// 修改前使用shouldContinue变量但设置后立即breakIDEA提示条件始终为true
// 修改后直接使用while(true)配合break逻辑更简洁清晰
while (true) {
Boolean loginResult = login();
if (loginResult == null) {
@ -128,7 +118,8 @@ public class MathQuestionGenerator {
/**
*
* @return null退
* @return truefalsenull退
* null退
*/
private static Boolean login() {
System.out.println("=== 用户登录 ===");
@ -273,17 +264,25 @@ public class MathQuestionGenerator {
*/
private static void waitForEnter() {
try {
// 【人工修复】修复InputStream.read()结果被忽略的警告
// 修改前System.in.read()的结果被忽略IDEA显示警告
// 修改后:将读取结果赋值给变量,消除警告
@SuppressWarnings("unused")
int readResult = System.in.read();
// readResult用于等待用户按回车键不需要使用具体值
// 等待用户按回车键,读取直到遇到换行符
int ch;
while ((ch = System.in.read()) != -1 && ch != '\n') {
// 继续读取直到遇到换行符
}
} catch (IOException e) {
// 忽略读取错误
}
}
/**
* "按回车键继续"
*/
private static void showPressEnterAndWait() {
System.out.println("按回车键继续...");
System.out.flush();
waitForEnter();
}
/**
*
* @param currentGrade
@ -309,25 +308,23 @@ public class MathQuestionGenerator {
* @return
*/
private static boolean handleSwitchCommand(String command) {
// 【人工修复】修复字符串越界风险,添加长度检查
// 修改前command.substring(3) 可能抛出StringIndexOutOfBoundsException
// 修改后:先检查命令长度,确保安全访问
if (command.length() < 3) {
System.out.println();
System.out.println("✗ 请输入小学、初中和高中三个选项中的一个");
System.out.println("按回车键继续...");
System.out.flush();
try {
@SuppressWarnings("unused")
int readResult = System.in.read();
} catch (IOException e) {
// 忽略读取错误
}
showPressEnterAndWait();
return false;
}
String targetGrade = command.substring(3).trim();
if (targetGrade.equals("小学") || targetGrade.equals("初中") || targetGrade.equals("高中")) {
if (currentUser == null) {
System.out.println();
System.out.println("✗ 用户未登录,无法切换年级");
System.out.println("按回车键继续...");
System.out.flush();
waitForEnter();
return false;
}
currentUser = new User(currentUser.username(), currentUser.password(), targetGrade);
System.out.println();
System.out.println("✓ 切换成功!当前为" + targetGrade + "出题模式");
@ -336,19 +333,7 @@ public class MathQuestionGenerator {
// 修改后:切换成功后要求按回车键,让用户有时间阅读信息,界面切换更自然
System.out.println("按回车键继续...");
System.out.flush();
try {
// 【人工修复】修复InputStream.read()结果被忽略的警告
// 修改前System.in.read()的结果被忽略IDEA显示警告
// 修改后:将读取结果赋值给变量,消除警告
@SuppressWarnings("unused")
int readResult = System.in.read();
// 【人工修复】修复空if语句体警告
// 修改前if (readResult == -1) { } 空语句体IDEA显示警告
// 修改后删除空的if语句因为IOException已经被catch块处理
// readResult用于等待用户按回车键不需要检查具体值
} catch (IOException e) {
// 忽略读取错误
}
waitForEnter();
return true;
} else {
System.out.println();
@ -358,19 +343,7 @@ public class MathQuestionGenerator {
// 修改后:切换失败后要求按回车键,让用户有时间阅读错误信息,界面切换更自然
System.out.println("按回车键继续...");
System.out.flush();
try {
// 【人工修复】修复InputStream.read()结果被忽略的警告
// 修改前System.in.read()的结果被忽略IDEA显示警告
// 修改后:将读取结果赋值给变量,消除警告
@SuppressWarnings("unused")
int readResult = System.in.read();
// 【人工修复】修复空if语句体警告
// 修改前if (readResult == -1) { } 空语句体IDEA显示警告
// 修改后删除空的if语句因为IOException已经被catch块处理
// readResult用于等待用户按回车键不需要检查具体值
} catch (IOException e) {
// 忽略读取错误
}
waitForEnter();
return false;
}
}
@ -395,11 +368,12 @@ public class MathQuestionGenerator {
// 【人工修改】创建paper文件夹结构paper->用户名->年级
// 修改前File userDir = new File(currentUser.getUsername());
// 修改后:创建三级文件夹结构,试卷集中管理
if (currentUser == null) {
throw new IllegalStateException("用户未登录,无法创建文件夹");
}
File paperDir = new File("paper");
if (!paperDir.exists()) {
// 【人工修复】修复File.mkdir()结果被忽略的警告
// 修改前paperDir.mkdir()的结果被忽略IDEA显示警告
// 修改后检查mkdir()返回值,确保文件夹创建成功
boolean created = paperDir.mkdir();
if (!created) {
System.err.println("警告无法创建paper文件夹");
@ -408,9 +382,6 @@ public class MathQuestionGenerator {
File userDir = new File(paperDir, currentUser.username());
if (!userDir.exists()) {
// 【人工修复】修复File.mkdir()结果被忽略的警告
// 修改前userDir.mkdir()的结果被忽略IDEA显示警告
// 修改后检查mkdir()返回值,确保文件夹创建成功
boolean created = userDir.mkdir();
if (!created) {
System.err.println("警告:无法创建用户文件夹:" + currentUser.username());
@ -426,9 +397,6 @@ public class MathQuestionGenerator {
for (File gradeDir : gradeDirs) {
if (!gradeDir.exists()) {
// 【人工修复】修复File.mkdir()结果被忽略的警告
// 修改前gradeDir.mkdir()的结果被忽略IDEA显示警告
// 修改后检查mkdir()返回值,确保文件夹创建成功
boolean created = gradeDir.mkdir();
if (!created) {
System.err.println("警告:无法创建年级文件夹:" + gradeDir.getName());
@ -475,9 +443,6 @@ public class MathQuestionGenerator {
int attempts = 0;
do {
// 【人工修改】根据年级设置不同的最少操作数
// 修改前int operandCount = random.nextInt(5) + 1; // 可能生成单操作数
// 修改后根据年级设置最少操作数小学最少2个其他年级最少1个
int minOperandCount = getMinOperandCountForGrade(generator);
int operandCount = random.nextInt(MAX_OPERAND_COUNT - minOperandCount + 1) + minOperandCount;
int[] operands = new int[operandCount];
@ -518,7 +483,9 @@ public class MathQuestionGenerator {
private static Set<String> loadHistoryQuestions(File userDir) {
Set<String> historyQuestions = new HashSet<>();
// 【人工修改】从对应的年级文件夹加载历史题目
if (currentUser == null) {
throw new IllegalStateException("用户未登录,无法加载历史题目");
}
String currentGrade = currentUser.grade();
File gradeDir = new File(userDir, currentGrade);
@ -529,13 +496,10 @@ public class MathQuestionGenerator {
File[] files = gradeDir.listFiles((dir, name) -> name.endsWith(".txt"));
if (files != null) {
for (File file : files) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
try (BufferedReader reader = new BufferedReader(new FileReader(file, java.nio.charset.StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.matches("\\d+\\.\\s+.+")) {
// 【人工修复】修复字符串越界风险,添加安全检查
// 修改前line.indexOf(".") 可能返回-1导致substring(-1+1)问题
// 修改后先检查indexOf结果确保安全访问
int dotIndex = line.indexOf(".");
if (dotIndex != -1 && dotIndex + 1 < line.length()) {
String question = line.substring(dotIndex + 1).trim();
@ -571,7 +535,9 @@ public class MathQuestionGenerator {
* @return
*/
private static File createOutputFile(File userDir) {
// 【人工修改】将文件保存到对应的年级文件夹
if (currentUser == null) {
throw new IllegalStateException("用户未登录,无法创建输出文件");
}
String currentGrade = currentUser.grade();
File gradeDir = new File(userDir, currentGrade);
@ -586,7 +552,7 @@ public class MathQuestionGenerator {
* @param outputFile
*/
private static void writeQuestionsToFile(List<String> questions, File outputFile) {
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile, java.nio.charset.StandardCharsets.UTF_8))) {
for (int i = 0; i < questions.size(); i++) {
writer.println((i + 1) + ". " + questions.get(i));
if (i < questions.size() - 1) {
@ -614,24 +580,12 @@ public class MathQuestionGenerator {
// 修改后:生成题目后要求按回车键,让用户有时间阅读生成结果,界面切换更自然
System.out.println("按回车键继续...");
System.out.flush();
try {
// 【人工修复】修复InputStream.read()结果被忽略的警告
// 修改前System.in.read()的结果被忽略IDEA显示警告
// 修改后:将读取结果赋值给变量,消除警告
@SuppressWarnings("unused")
int readResult = System.in.read();
// readResult用于等待用户按回车键不需要使用具体值
} catch (IOException e) {
// 忽略读取错误
}
waitForEnter();
System.out.println();
}
/**
*
* UserIDEA
* 使IDEA"类可以是记录类"
* 使Java 14+
*/
record User(String username, String password, String grade) {
// 记录类自动生成构造函数、getter方法、equals、hashCode和toString

@ -24,9 +24,6 @@ public class PrimaryQuestionGenerator extends AbstractQuestionGenerator {
// 随机添加括号,确保括号内也有运算符
if (i < operands.length - 1 && random.nextBoolean()) {
question.append(" ").append(op).append(" (").append(operands[i]);
// 【人工修复】修复逻辑错误,移除多余的边界检查
// 修改前if (i + 1 < operands.length) 是多余的因为外层条件已经确保i < operands.length - 1
// 修改后直接处理i+1位置的操作数因为条件已经保证其存在
op = BASIC_OPERATORS[random.nextInt(BASIC_OPERATORS.length)];
question.append(" ").append(op).append(" ").append(operands[i + 1]).append(")");
i++; // 手动增加i以跳过已处理的操作数

@ -11,4 +11,4 @@ public interface QuestionGenerator {
* @return
*/
String generateQuestion(int[] operands, Random random);
}
}

@ -22,9 +22,6 @@ public class SeniorQuestionGenerator extends AbstractQuestionGenerator {
question.append(function).append("(").append(operands[i]).append(")");
} else {
// 其他位置使用基本运算符
// 【人工修复】修复条件 'functionPos == 0'始终为false的警告
// 修改前if (i > 0 || functionPos == 0) 中functionPos == 0永远不会执行
// 修改后简化条件逻辑只在i > 0时添加运算符
if (i > 0) {
String op = BASIC_OPERATORS[random.nextInt(BASIC_OPERATORS.length)];
question.append(" ").append(op).append(" ");

Loading…
Cancel
Save