# 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