# exercises
**Repository Path**: zhyuu/exercises
## Basic Information
- **Project Name**: exercises
- **Description**: No description available
- **Primary Language**: Python
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-01-16
- **Last Updated**: 2026-01-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 数学题生成引擎 - 使用文档
基于 FastAPI 的数学题生成引擎,支持数值范围、进位控制、智能重复控制、A4 打印适配等功能。
## 核心功能
✅ **四种运算**:加法、减法、乘法、除法(整除)
✅ **数值范围**:自定义操作数最小值和最大值
✅ **进位/借位控制**:加法进位、减法借位精确识别
✅ **智能重复控制**:两阶段策略,既保证多样性又允许充足题量
✅ **A4 完美适配**:三种排版模式,直接打印
✅ **PDF 导出**:一键生成可下载的 PDF 文件
✅ **友好 UI**:蓝紫色渐变设计,实时动态说明
## 快速开始
### 1. 安装依赖
```bash
pip install -r requirements.txt
```
### 2. 启动服务器
#### 方式 1:直接启动(本地开发)
```bash
python -m uvicorn main:app --reload --port 8000
```
#### 方式 2:使用 Docker 部署(生产环境推荐)
**快速启动(Docker Compose):**
```bash
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f
```
**手动启动(Docker 命令):**
```bash
# 构建镜像
docker build -t math-problem-generator .
# 运行容器
docker run -d -p 8000:8000 --name math-problem-generator math-problem-generator
```
📖 **完整部署指南**: 查看 [DOCKER_DEPLOY.md](DOCKER_DEPLOY.md)
服务器启动后,访问:
- 🌐 应用首页: http://localhost:8000/
- 📚 API 文档: http://localhost:8000/docs
- 📄 ReDoc 文档: http://localhost:8000/redoc
## API 端点
### 1. 生成数学题 `POST /generate`
生成指定数量的数学题。
**请求参数:**
|| 参数 | 类型 | 必填 | 说明 | 默认值 |
||------|------|------|------|--------|
|| `operation` | string | ✓ | 运算类型: `add`, `subtract`, `multiply`, `divide` | - |
|| `min_value` | int | - | 操作数最小值 (≥0) | 1 |
|| `max_value` | int | - | 操作数最大值 (≥1) | 100 |
|| `require_carry` | bool | - | 是否要求进位(仅加法有效) | null |
|| `require_borrow` | bool | - | 是否要求借位(仅减法有效) | null |
|| `allow_duplicate` | bool | - | 是否允许重复(默认 False)
✓: 允许重复但降低重复率
✗: 完全不重复 | false |
|| `count` | int | - | 生成题目数量 (1-100) | 1 |
**示例请求 1:不重复生成(默认)**
```json
{
"operation": "add",
"min_value": 10,
"max_value": 99,
"require_carry": true,
"count": 5
}
```
**示例请求 2:允许重复生成(小范围题目)**
```json
{
"operation": "add",
"min_value": 1,
"max_value": 5,
"allow_duplicate": true,
"count": 100
}
```
**响应示例:**
```json
{
"problems": [
{
"problem": "68 + 49",
"answer": 117,
"operand1": 68,
"operand2": 49,
"operation": "+",
"has_carry": true,
"has_borrow": null
}
],
"total": 5,
"session_total": 17,
"duplicate_count": 0
}
```
**响应字段说明:**
- `problems`: 生成的题目列表
- `total`: 本次生成的题目总数
- `session_total`: 当前会话已生成的不重复题目总数
- `duplicate_count`: 重复题目数量(仅 `allow_duplicate=true` 时有值)
### 2. 查看统计 `GET /stats`
获取当前会话已生成的题目总数。
**响应示例:**
```json
{
"total_generated": 17,
"message": "当前会话统计信息"
}
```
### 3. 清除历史 `POST /clear`
清除所有已生成的题目记录,允许重新生成相同的题目。
**响应示例:**
```json
{
"message": "历史记录已清除",
"cleared_count": 17
}
```
### 4. 生成 A4 练习题 `GET /worksheet/{layout_mode}`
生成 A4 打印练习题模板。
**路径参数:**
- `layout_mode`: 排版模式(`compact` | `standard` | `large`)
**查询参数:**
|| 参数 | 类型 | 必填 | 说明 | 默认值 |
||------|------|------|------|--------|
|| `operation` | string | - | 运算类型: `add`, `subtract`, `multiply`, `divide` | `add` |
|| `min_value` | int | - | 操作数最小值 | 1 |
|| `max_value` | int | - | 操作数最大值 | 100 |
|| `require_carry` | bool | - | 是否要求进位(仅加法) | null |
|| `require_borrow` | bool | - | 是否要求借位(仅减法) | null |
**排版模式:**
- `compact`: 紧凑模式 (~300题,小字号,适合刷题)
- `standard`: 标准模式 (~200题,中字号,日常练习)
- `large`: 大字模式 (~100题,大字号,视力友好)
**访问示例:**
```
http://localhost:8000/worksheet/standard?operation=add&min_value=10&max_value=99&require_carry=true
```
### 5. 生成自定义练习题 `GET /custom/worksheet`
生成自定义 A4 打印练习题,支持控制题目数量和重复选项。
**查询参数:**
|| 参数 | 类型 | 必填 | 说明 | 默认值 |
||------|------|------|------|--------|
|| `operation` | string | - | 运算类型: `add`, `subtract`, `multiply`, `divide` | `add` |
|| `min_value` | int | - | 操作数最小值 | 1 |
|| `max_value` | int | - | 操作数最大值 | 100 |
|| `require_carry` | bool | - | 是否要求进位(仅加法) | null |
|| `require_borrow` | bool | - | 是否要求借位(仅减法) | null |
|| `allow_duplicate` | bool | - | 是否允许重复(默认 False) | false |
|| `count` | int | - | 题目数量 (100/200/300) | 100 |
**访问示例:**
```
http://localhost:8000/custom/worksheet?operation=add&min_value=1&max_value=5&allow_duplicate=true&count=100
```
### 6. 导出 PDF `GET /worksheet/{layout_mode}/pdf`
生成并下载 PDF 格式的练习题文件。
**路径参数:**
- `layout_mode`: 排版模式(`compact` | `standard` | `large`)
**查询参数:**
与 `/worksheet/{layout_mode}` 相同
**访问示例:**
```
http://localhost:8000/worksheet/standard/pdf?operation=subtract&min_value=20&max_value=99&require_borrow=true
```
**文件名格式:**
```
math_{operation}_{mode}_{timestamp}.pdf
示例: math_addition_standard_20260117_143000.pdf
```
## 使用示例
### Python 示例
```python
import requests
# 生成带进位的加法题(不重复)
response = requests.post(
"http://localhost:8000/generate",
json={
"operation": "add",
"min_value": 10,
"max_value": 99,
"require_carry": True,
"count": 5
}
)
data = response.json()
print(f"生成 {data['total']} 道题")
print(f"重复题目: {data['duplicate_count']} 道")
for problem in data["problems"]:
print(f"{problem['problem']} = {problem['answer']}")
```
### 允许重复示例
```python
# 小范围题目(1-5),允许重复生成 100 题
response = requests.post(
"http://localhost:8000/generate",
json={
"operation": "add",
"min_value": 1,
"max_value": 5,
"allow_duplicate": True, # 允许重复
"count": 100
}
)
data = response.json()
print(f"生成 {data['total']} 道题,其中 {data['duplicate_count']} 道重复")
```
### JavaScript 示例
```javascript
fetch('http://localhost:8000/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
operation: 'multiply',
min_value: 2,
max_value: 12,
count: 5
})
})
.then(response => response.json())
.then(data => {
console.log(`生成 ${data.total} 道题`);
data.problems.forEach(problem => {
console.log(`${problem.problem} = ${problem.answer}`);
});
});
```
## 功能特性
### 1. 数值范围控制
通过 `min_value` 和 `max_value` 参数控制操作数的范围。
**重要说明**:数值范围指的是**操作数**(参与计算的数)的范围,不是最终结果。
| 运算 | 数值范围 1-10 | 数值范围 10-99 |
|------|-------------|-------------|
| 加法 | 结果 2~20 | 结果 20~198 |
| 减法 | 结果 0~10 | 结果 0~99 |
| 乘法 | 结果 1~100 | 结果 100~9801 |
| 除法 | 结果 1~10 | 结果 1~99 |
### 2. 进位控制(加法)
- `require_carry: true` - 只生成有进位的加法题
- `require_carry: false` - 只生成无进位的加法题
- `require_carry: null` - 不限制
```json
{
"operation": "add",
"min_value": 10,
"max_value": 99,
"require_carry": true,
"count": 5
}
```
### 3. 借位控制(减法)
- `require_borrow: true` - 只生成有借位的减法题
- `require_borrow: false` - 只生成无借位的减法题
- `require_borrow: null` - 不限制
```json
{
"operation": "subtract",
"min_value": 20,
"max_value": 99,
"require_borrow": true,
"count": 3
}
```
### 4. 智能重复控制
系统提供两种重复控制模式:
#### 模式 1:完全不重复(默认,`allow_duplicate=false`)
- 检查所有历史记录
- 确保同一会话不重复
- 适合大范围题目
#### 模式 2:允许重复但降低重复率(`allow_duplicate=true`)
采用**两阶段智能策略**:
| 阶段 | 策略 | 目的 |
|------|------|------|
| 前 100 次尝试 | 只接受不重复的题目 | 降低重复率 |
| 100 次后 | 允许重复生成 | 确保能生成足够题目 |
**实际效果:**
| 数值范围 | 生成数量 | 不勾选 | 勾选(重复率) |
|---------|---------|--------|----------------|
| 1-5 (25种) | 20 题 | ✅ 20题 (0%) | ✅ 20题 (0%) |
| 1-5 (25种) | 100 题 | ❌ 无法生成 | ✅ 100题 (~75%) |
| 1-20 (400种) | 100 题 | ✅ 100题 (0%) | ✅ 100题 (0%) |
| 1-20 (400种) | 300 题 | ✅ 300题 (0%) | ✅ 300题 (~3%) |
**使用建议:**
- 大范围题目(如 1-100):推荐**不勾选**
- 小范围题目(如 1-10):推荐**不勾选**
- 超小范围且需要大量题目(如 1-5 × 100题):建议**勾选**
### 5. 除法整除
除法运算会自动生成整除的题目,确保结果为整数。
**生成策略**:
- 先随机生成除数和商
- 计算被除数 = 除数 × 商
- 确保被除数不超过 `max_value × 10`
### 6. A4 打印模板
**三种排版模式:**
| 模式 | 题目数量 | 字号 | 列数 | 适用场景 |
|------|---------|------|------|---------|
| `compact` | ~300题 | 8pt | 6列 | 熟练刷题、大量练习 |
| `standard` | ~200题 | 10pt | 5列 | 日常练习、课后作业 |
| `large` | ~100题 | 13pt | 5列 | 幼小学生、视力保护 |
**页面功能:**
- ✅ 返回首页按钮
- ✅ 打印按钮
- ✅ 显示/隐藏答案(标准模式)
- ✅ 刷新重新生成
- ✅ 打印时自动隐藏控制面板
**打印设置:**
- 纸张:A4 (210mm × 297mm)
- 边距:10mm
- 方向:纵向
## 项目结构
```
exercises/
├── 核心代码
│ ├── main.py # FastAPI 应用入口
│ ├── generator.py # 数学题生成核心逻辑
│ └── models.py # Pydantic 数据模型
│
├── 依赖配置
│ └── requirements.txt # Python 依赖包
│
├── 模板文件
│ └── templates/
│ ├── index.html # 主页 UI 模板
│ ├── worksheet.html # 标准练习题页面
│ └── worksheet_custom.html # 自定义练习题页面
│
├── 文档文件
│ ├── README.md # 项目主文档(本文件)
│ ├── PDF_GUIDE.md # PDF 导出功能指南
│ ├── WORKSHEET_GUIDE.md # A4 打印模板指南
│ ├── DOCKER_DEPLOY.md # Docker 部署完整指南
│ ├── LICENSE # 许可证
│ ├── .gitignore # Git 配置
│ └── .dockerignore # Docker 构建忽略文件
│
└── Docker 部署
├── Dockerfile # Python 3.12 镜像构建文件
└── docker-compose.yml # Docker Compose 配置
```
## 技术栈
| 组件 | 技术 | 版本 | 说明 |
|------|------|------|------|
| Web 框架 | FastAPI | 0.109.0 | 高性能异步框架,自动 API 文档 |
| 服务器 | Uvicorn | 0.27.0 | ASGI 服务器,支持热重载 |
| 数据验证 | Pydantic | 2.5.3 | 类型安全的数据验证 |
| 模板引擎 | Jinja2 | 3.1.3 | HTML 模板渲染 |
| PDF 生成 | xhtml2pdf | 0.2.17 | HTML 转 PDF,纯 Python 实现 |
**特点:**
- ✅ 类型安全:完整的 Pydantic 模型验证
- ✅ 异步高性能:FastAPI + Uvicorn
- ✅ 自动文档:Swagger UI + ReDoc
- ✅ 跨平台:纯 Python 实现,无系统依赖
## 注意事项
### 1. 存储方式
- 当前实现使用**内存存储**
- 重启服务器会清除历史记录
- 如需持久化,可考虑 Redis/数据库
### 2. 生成限制
- 不允许重复时:小范围可能无法生成足够题目
- 允许重复时:采用两阶段策略,前 100 次尽量不重复
- 参数过严(如进位+小范围):可能影响生成效率
### 3. 除法范围
- 除法为保证整除,被除数可能超出 `max_value`
- 允许被除数达到 `max_value × 10`
- 确保有足够的题目可生成
### 4. 数值范围理解
- `min_value` 和 `max_value` 控制**操作数**范围
- 不是控制最终结果范围
- 示例:1-20 的加法,结果会在 2~40 之间
### 5. 打印兼容性
- 推荐使用现代浏览器(Chrome、Edge、Firefox)
- 打印时需启用"背景图形"
- PDF 导出依赖浏览器下载功能
## 扩展建议
### 1. 持久化存储
- 使用 Redis 存储已生成的题目
- 添加数据库支持(PostgreSQL/MongoDB)
- 支持多用户独立会话
### 2. 功能增强
- [ ] 支持混合运算模式
- [ ] 添加分数、小数运算
- [ ] 支持括号运算
- [ ] 添加题目难度分级(简单/中等/困难)
- [ ] 支持答案版 PDF 导出
- [ ] 添加题目收藏功能
- [ ] 支持自定义题干模板
### 3. 用户体验
- [ ] 添加用户认证系统
- [ ] 支持保存配置到本地
- [ ] 添加题目历史记录
- [ ] 支持导出为 Word/Excel
- [ ] 添加练习进度追踪
- [ ] 支持多语言界面
### 4. 性能优化
- [ ] 使用 Redis 缓存生成的题目
- [ ] 优化 PDF 生成速度
- [ ] 添加题目批量预生成
- [ ] 优化滑动窗口大小
### 5. 代码质量
- [ ] 添加单元测试(pytest)
- [ ] 添加集成测试
- [ ] 配置 pre-commit hooks
- [ ] 统一代码格式化(black)
- [ ] 添加类型检查(mypy)
- [ ] 配置 CI/CD 流程
## 常见问题
### Q: 如何生成"20以内的加法"?
A: 选择数值范围为 1-10,这样加法结果在 2~20 之间。
### Q: 为什么小范围生成大量题目会失败?
A: 小范围(如 1-5)组合数有限,不勾选"允许重复"无法生成足够题目。建议勾选该选项。
### Q: 允许重复会不会有很多重复题?
A: 采用两阶段智能策略,前 100 次尝试不重复,重复率通常控制在 5% 以下。
### Q: PDF 文件名为什么是英文?
A: 为避免浏览器编码问题,文件名使用英文,但内容和标题支持中文。
### Q: 打印时边框不显示?
A: 确保浏览器打印设置中启用了"背景图形"选项。
### Q: 如何查看答案?
A: 标准模式练习题页面右上角有"显示答案"按钮,可切换查看。
### Q: API 如何使用?
A: 访问 http://localhost:8000/docs 查看完整 API 文档和交互式测试界面。
## 快速链接
| 功能 | 链接 |
|------|------|
| 应用首页 | http://localhost:8000/ |
| API 文档 | http://localhost:8000/docs |
| ReDoc 文档 | http://localhost:8000/redoc |
| PDF 使用指南 | [PDF_GUIDE.md](PDF_GUIDE.md) |
| 打印模板指南 | [WORKSHEET_GUIDE.md](WORKSHEET_GUIDE.md) |
## 许可证
本项目采用 MIT 许可证,详见 [LICENSE](LICENSE) 文件。
---
**版本**: 1.1.0
**最后更新**: 2026-01-17