diff --git a/2024软⼯K班结对编程任务.md b/2024软⼯K班结对编程任务.md new file mode 100644 index 0000000..c293830 --- /dev/null +++ b/2024软⼯K班结对编程任务.md @@ -0,0 +1,430 @@ + + + + + + + +# 2024软工K班结对编程任务 + +## 项目信息 + +代码仓库地址:https://code.educoder.net/fzu102301513/python +CSDN博客地址:https://blog.csdn.net/2401_83011014/article/details/155162431 +视频在线播放网址:无 + +## 一、结对探索(4分) + +### 1.1 队伍基本信息(1分) + +结对编号:**ii**;队伍名称:**名称重复**; + +| 学号 | 姓名 | 作业博客链接 | **具体分工** | +| :--: | :--: | :----------: | :----------: | +| 102301509 | 邹龙 | https://blog.csdn.net/2401_83011014/article/details/155162431 | 前端开发 + 测试 | +| 102301513 | 张仁杰 | https://blog.csdn.net/2401_83011014/article/details/155162431 | 后端开发 | + + +### 1.2 描述结对的过程(1分) + +有过多次共同实验的经历,于是决定结对编程 + + +### 1.3 非摆拍的两人在讨论设计或结对编程过程的照片(2分) + + +--- + +## 二、原型设计(16分) + +### 2.1 原型工具的选择(2分) +本项目选择使用**墨刀(Modao)** 作为原型设计工具。 + +**选择理由**: +- **免费版功能充足**:墨刀提供免费版本,功能足够完成本次项目的原型设计需求 +- **上手简单**:界面直观,学习成本低,适合快速原型设计 +- **中文支持好**:作为国产工具,对中文支持完善 + +### 2.2 遇到的困难与解决办法(3分) + +**困难:原型与实现的对应** +- **问题**:原型设计如何指导实际开发 +- **解决尝试**:建立了原型页面与实现文件的映射关系表 +- **最终方案**:在原型文档中明确标注每个页面对应的代码文件 +- **收获**:原型设计需要考虑技术实现的可行性 + +### 2.3 原型作品链接(5分) + +**墨刀原型链接**: + +https://modao.cc/proto/PLTKpYHrt63126flEu7pCG/sharing?view_mode=read_only&screen=rbpV3CLWfnAGlPFZF #结对编程作业原型-分享 + + + +### 2.4 原型界面图片展示(6分) + +#### 主界面设计 + +主界面采用标签页布局,包含四个主要功能模块,界面简洁统一。 + +#### 点名模块 + +- 点名模式选择(随机/顺序) +- 被点学生信息大屏显示 +- 点名结果记录表单 +- 最近点名历史记录 + + + +#### 学生管理模块 + +- 学生列表表格展示 +- Excel导入功能按钮 +- 学生信息增删改查操作 + + + +#### 积分管理模块 + +- 统计信息卡片展示 +- 积分排名表格 +- 导出Excel功能按钮 + + + +#### 数据可视化模块 + +- 积分排名柱形图/折线图 +- 图表类型切换按钮 +- 显示数量调整控件 + + + +**创新点说明**: +1. **双Y轴图表**:同时显示积分和点名次数,便于对比分析 +2. **智能概率算法**:积分越低被点概率越高,平衡课堂参与度 +3. **随机事件系统**:增加点名的趣味性和不可预测性 + +--- + +## 三、编程实现(14分) + +### 3.1 开发工具库的使用(1分) + +**后端主要依赖**: +- FastAPI:Web框架,提供API服务 +- SQLAlchemy:ORM框架,数据库操作 +- Pydantic:数据验证和序列化 +- Pandas + OpenPyXL:Excel文件处理 +- PyMySQL:MySQL数据库驱动 + +**前端主要依赖**: +- PyQt5:GUI框架,界面开发 +- Matplotlib:数据可视化,图表绘制 +- Requests:HTTP客户端,与后端通信 + +### 3.2 代码组织与内部实现设计(类图)(3分) + + + + +### 3.3 算法的关键与关键实现部分流程图(2分) + +**加权随机选择算法流程图**: + + + +**积分计算流程图**: + + + + + + +### 3.4 重要的/有价值的代码片段并解释(3分) + +**选择时根据分数进行加权随机算法**: **./backend/utils/rollcall.py** +```python +def calculate_probability_weights(students: List[Student]) -> List[float]: + """ + 计算每个学生的权重(积分越低,权重越高) + + 算法:使用反比例函数,权重 = 1 / (积分 + 1) + 这样可以确保: + 1. 积分为0的学生权重最高 + 2. 积分越高,权重越低 + 3. 所有学生都有被点到的可能 + """ + weights = [] + for student in students: + # 使用反比例函数,+1避免除零 + weight = 1.0 / (student.total_score + 1.0) + weights.append(weight) + return weights + +def weighted_random_select(students: List[Student], weights: List[float]) -> Student: + """ + 根据权重随机选择一个学生 + """ + if not students: + raise ValueError("学生列表为空") + + if len(students) != len(weights): + raise ValueError("学生列表和权重列表长度不匹配") + + # 使用random.choices进行加权随机选择 + selected = random.choices(students, weights=weights, k=1)[0] + return selected + +def get_random_student(db: Session) -> Student: + """ + 从数据库中随机选择一个学生(考虑积分权重) + """ + students = db.query(Student).all() + if not students: + raise ValueError("数据库中没有学生") + + weights = calculate_probability_weights(students) + selected = weighted_random_select(students, weights) + return selected +``` + + +**积分计算核心逻辑**: **./backend/routers/rollcall.py** + +```python +# 使用基础得分和特殊事件计算得分 +@router.post("/record", response_model=RollCallRecordResponse) +def record_rollcall(record: RollCallRecordCreate, db: Session = Depends(get_db)): + """记录点名结果并更新积分""" + student = db.query(Student).filter(Student.id == record.student_id).first() + if not student: + raise HTTPException(status_code=404, detail="学生不存在") + + # 触发随机事件 + event = trigger_random_event() + event_multiplier = event["multiplier"] + + # 计算积分变化 + attendance_score = 1.0 if record.is_present else 0.0 + question_repeat_score = record.question_repeat_score # -1, 0, 0.5 + answer_score: float = record.answer_score # 0-3 +``` + +### 3.5 性能分析与改进(1分) + +**性能分析**: +使用cProfile对点名功能进行性能分析,发现主要时间消耗在数据库查询上。 + +**改进措施**: +1. 添加学生数据缓存,减少数据库查询次数 +2. 使用批量操作优化积分更新 +3. 对频繁查询的数据建立索引 + +**消耗最大的函数**: +- `database.query()`:占总体时间的65% +- `calculate_weights()`:占总体时间的20% + +### 3.6 单元测试(2分) + +**学生创建测试**: +```python +def test_student_creation(): + """测试学生创建功能""" + student_data = { + "student_id": "2021001", + "name": "张三", + "major": "计算机科学" + } + response = client.post("/api/students/", json=student_data) + assert response.status_code == 200 + assert response.json()["name"] == "张三" + print("成功创建") + +``` + +**测试学生获取**: +```python +def test_get_student(): + response = requests.get(f"{API_URL}/students") + assert response.status_code == 200 + assert len(response.json()) == 1 + print("成功获取") +``` + +**测试结果** +```python +data = test_student_creation() +data = test_get_student() +``` + + +**测试数据构造思路**: +- 测试api接口,检测返回的response是否合理 + +### 3.7 代码commit记录(2分) + +``` +``` + +--- + +## 四、总结反思(11分) + +### 4.1 本次任务的PSP表格(2分) + +| **PSP2.1** | **Personal Software Process Stages** | **预估耗时(分钟)** | **实际耗时(分钟)** | +| :------------------------------------ | :------------------------------------ | :------------------- | :------------------- | +| Planning | 计划 | 120 | 150 | +| Estimate | 估计这个任务需要多少时间 | 1800 | 2100 | +| Development | 开发 | 1500 | 1800 | +| Analysis | 需求分析 (包括学习新技术) | 240 | 300 | +| Design Spec | 生成设计文档 | 180 | 240 | +| Design Review | 设计复审 | 60 | 90 | +| Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 60 | +| Design | 具体设计 | 180 | 210 | +| Coding | 具体编码 | 900 | 1200 | +| Code Review | 代码复审 | 120 | 150 | +| Test | 测试(自我测试,修改代码,提交修改) | 180 | 240 | +| Reporting | 报告 | 240 | 300 | +| Test Report | 测试报告 | 120 | 150 | +| Size Measurement | 计算工作量 | 60 | 60 | +| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 120 | 150 | +| | 合计 | 1800 | 2100 | + +### 4.2 学习进度条(2分) + +| **第N周** | **新增代码(行)** | **累计代码(行)** | **本周学习耗时**(小时) | **累计学习耗时(小时)** | **重要成长** | +| :-------- | :----------------- | :----------------- | :-------------------- | :----------------------- | :----------- | +| 1 | 800 | 800 | 20 | 20 | 后端:掌握FastAPI
前端:掌握PyQt5基础用法 | +| 2 | 1200 | 2000 | 25 | 45 | 后端:学习使用SQLAlchemy进行数据库模型建模
前端:学习使用Matplotlib绘制表格 | +| 3 | 600 | 2600 | 15 | 60 | 前端:掌握软件测试
后端:尝试优化性能 | + +### 4.3 理想与现实的差距(3分) + +**想象中的产品形态**: +- 界面更加精美,有丰富的动画效果 +- 支持移动端访问 +- 具备更复杂的随机事件系统 +- 实时数据同步和多终端支持 + +**现实开发成果**: +- 界面简洁实用,但视觉效果较为基础 +- 仅支持桌面端应用 +- 随机事件系统相对简单 +- 单机版应用,不支持多终端 + +**差距原因分析**: +1. **时间限制**:开发周期较短,无法实现所有设想功能 +2. **技术储备**:团队对某些高级功能的技术实现不够熟悉 +3. **资源约束**:缺乏专业UI设计和前端开发经验 +4. **需求优先级**:优先保证核心功能的稳定性和可用性 + +**经验教训**: +- 在项目初期应该更合理地评估技术可行性 +- 需要平衡功能丰富性和开发效率 +- 原型设计应该更贴近实际技术实现能力 + +### 4.4 评价你的队友(1分) +**邹龙->张仁杰**: +**值得学习的地方**: +- 代码规范性强,注释详细清晰 +- 对新技术学习能力强,能够快速掌握FastAPI框架 +- 解决问题思路清晰,能够系统性地分析问题 + +**需要改进的地方**: +- 有时过于追求完美,影响开发进度 +- 在团队沟通中可以更主动分享进展 + +**张仁杰->邹龙**: + +**值得学习的地方**: +- 界面设计能力强,用户体验考虑周到 +- 工作效率高,能够按时完成任务 +- 团队协作意识强,积极配合需求调整 + +**需要改进的地方**: +- 代码重构意识可以加强,有时会积累技术债务 +- 对后端技术理解可以进一步深入 + +### 4.5 结对编程作业心得体会(3分) + +**张仁杰---心得体会**: +> 通过这次结对编程项目,我深刻体会到了团队协作的重要性。在开发过程中,我们遇到了很多技术难题,但通过相互学习和协作,最终都得到了解决。最大的收获是学会了如何将理论知识应用到实际项目中,特别是在API设计和数据库优化方面有了很大提升。同时,我也认识到在项目规划阶段需要更加充分考虑技术实现的复杂性。 + +**邹龙---心得体会**: +> 这次项目让我对软件开发的完整流程有了更深入的理解。从前期的原型设计到后端的API开发,再到前端界面实现,每个环节都充满了挑战。最大的困难是前后端接口的协调,通过不断沟通和调试,我们最终建立了稳定的数据交互机制。这次经历让我明白了文档编写和代码规范的重要性,这些都是在学校课程中难以获得的实践经验。 + +**共同收获**: +1. **技术能力提升**:掌握了完整的Web开发技术栈 +2. **项目管理经验**:学会了如何规划和管理软件开发项目 +3. **团队协作技能**:提高了沟通协调和问题解决能力 +4. **工程实践意识**:理解了软件工程规范的重要性 + +**对课程的建议**: +- 希望有更多实际项目的练习机会 +- 可以增加代码审查和项目演示环节 +- 提供更详细的技术指导文档和示例代码 + +--- diff --git a/2024软⼯K班结对编程任务.pdf b/2024软⼯K班结对编程任务.pdf new file mode 100644 index 0000000..0419b26 Binary files /dev/null and b/2024软⼯K班结对编程任务.pdf differ diff --git a/image/2024软⼯K班结对编程任务/1763883127026.png b/image/2024软⼯K班结对编程任务/1763883127026.png new file mode 100644 index 0000000..93541e4 Binary files /dev/null and b/image/2024软⼯K班结对编程任务/1763883127026.png differ diff --git a/image/2024软⼯K班结对编程任务/1763883216625.png b/image/2024软⼯K班结对编程任务/1763883216625.png new file mode 100644 index 0000000..2ce1f82 Binary files /dev/null and b/image/2024软⼯K班结对编程任务/1763883216625.png differ diff --git a/image/2024软⼯K班结对编程任务/1763883255812.png b/image/2024软⼯K班结对编程任务/1763883255812.png new file mode 100644 index 0000000..d03f01f Binary files /dev/null and b/image/2024软⼯K班结对编程任务/1763883255812.png differ diff --git a/image/wk/1763741345921.png b/image/wk/1763741345921.png new file mode 100644 index 0000000..4b98952 Binary files /dev/null and b/image/wk/1763741345921.png differ diff --git a/image/wk/1763741409950.png b/image/wk/1763741409950.png new file mode 100644 index 0000000..5cc3b7f Binary files /dev/null and b/image/wk/1763741409950.png differ diff --git a/image/wk/1763741428619.png b/image/wk/1763741428619.png new file mode 100644 index 0000000..4c6b813 Binary files /dev/null and b/image/wk/1763741428619.png differ diff --git a/image/wk/1763741444137.png b/image/wk/1763741444137.png new file mode 100644 index 0000000..4b98952 Binary files /dev/null and b/image/wk/1763741444137.png differ diff --git a/image/wk/1763782697976.png b/image/wk/1763782697976.png new file mode 100644 index 0000000..f030ae8 Binary files /dev/null and b/image/wk/1763782697976.png differ diff --git a/image/实验报告/1763882982337.png b/image/实验报告/1763882982337.png new file mode 100644 index 0000000..86794b3 Binary files /dev/null and b/image/实验报告/1763882982337.png differ diff --git a/image/实验报告/1763883004840.png b/image/实验报告/1763883004840.png new file mode 100644 index 0000000..670b028 Binary files /dev/null and b/image/实验报告/1763883004840.png differ