You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

##代码仓库https://code.educoder.net/ppfc5brxg/102201121/tree/main/README.md
##博客地址https://www.learnerhub.net/#/resources/3196/update
##视频地址https://www.bilibili.com/video/BV1to2JYbEaW/?vd_source=355974c779ee1dfc75ebf39b824902b7
## 一、结对探索4分汉字序号为一级标题下同
**1.1 队伍基本信息**1分阿拉伯数字序号为二级标题下同
结对编号_19___队伍名称_BLG___
| 学号 | 姓名 | 作业博客链接 | **具体分工** |
| :--: | :--: | :----------: | :----------: |
| 102201121 | 邵子瑞 | https://www.learnerhub.net/#/resources/3196 | 前端开发以及后端代码优化 |
| 102201112 | 李文杰 | | 后端开发 |
##1.2 描述结对的过程1分
我和李文杰平时就会一起讨论代码,因此我们会一起组队
##1.3 非摆拍的两人在讨论设计或结对编程过程的照片2分
## 二、原型设计16分
##2.1 原型工具的选择2分
选择了mockplus这一工具首先是因为mockplus是国内的原型设计工具因此自带的UI有很多国内的元素例如Harmony UI以及Wechat UI,其次,此原型设计工具可以实现多人同时对一个画板进行设计,方便了结对编程双人的合作
##2.2 遇到的困难与解决办法3分
刚开始时对如何实现交互还不是很了解,经过查阅资料之后了解到需要内置连接,最后成功解决如何实现交互的问题
##2.3 原型作品链接5分
https://rp.mockplus.cn/run/OQHkOev8AU/6FZZmdkDN?cps=expand&rps=expand&nav=1&ha=0&la=0&fc=0&out=1&rt=1&as=true
##2.4 原型界面图片展示6分
### 2.4.1登录界面
登录界面:设计一个专为教师服务的点名系统,需要登录教师自己的账号
### 2.4.2主界面名单导入按钮
名单导入按钮:设计一个按钮,让不同学科的老师选择不同的名单进行导入
### 2.4.3点名按钮
点名按钮:设计一个按钮,让老师点击后可以进行随机点名,同时还要进行对名单是否导入的判断,若没有导入名单则弹窗显示没有名单
### 2.4.4特殊模式按钮
特殊模式开启按钮:点击后可以开启特殊规则点名,例如周四加分到五十分
## 三、编程实现14分
## 3.1 开发工具库(如文件读取包等)的使用**1分
### 3.1.1后端
Flask: 轻量级的Web框架用于构建RESTful API。
Flask-CORS: 处理跨域请求(如果前端与后端分开运行)。
requests: 用于处理HTTP请求。
### 3.1.2前端
Fetch API: 用于发送HTTP请求。
### 3.1.3数据库
SQLAlchemy: ORM工具用于与数据库交互如果需要持久化存储
## 3.2 代码组织与内部实现设计类图3分
+-------------------+
| Student |
+-------------------+
| - id: str |
| - name: str |
| - isPresent: bool |
+-------------------+
| + mark_present() |
| + mark_absent() |
+-------------------+
+-------------------+
| Class |
+-------------------+
| - class_id: str |
| - class_name: str |
| - students: List[Student] |
+-------------------+
| + add_student(student: Student) |
| + remove_student(student: Student) |
| + get_student_list() |
+-------------------+
+-------------------+
| AttendanceRecord |
+-------------------+
| - date: str |
| - class: Class |
| - attendance_list: List[Student] |
+-------------------+
| + add_record(student: Student) |
| + get_attendance_summary() |
+-------------------+
+-------------------+
| API |
+-------------------+
| + add_student(data: dict) |
| + get_students() |
| + take_attendance(data: dict) |
| + get_attendance(date: str) |
+-------------------+
## 3.3 说明算法的关键与关键实现部分流程图2分
#### 3.3.1. 后端Flask API
Flask 应用 (app.py):
路由定义:
/students处理学生的添加和获取。
/attendance处理点名记录的添加和获取。
数据存储:
使用内存中的列表students和字典attendance_records来存储学生和点名记录适合小型应用。
模型类:
Student、Class 和 AttendanceRecord 类用于定义数据结构和行为。
功能实现:
add_student(): 处理学生的添加请求。
get_students(): 获取所有学生信息。
take_attendance(): 处理点名请求,并更新学生的到场状态。
get_attendance(): 获取特定日期的出勤记录。
#### 3.3.2. 前端HTML + JavaScript
用户界面 (index.html):
提供输入框和按钮用于添加学生、查看学生列表和点名。
使用 JavaScript 的 Fetch API 与后端进行交互。
功能实现:
addStudent(): 将新学生添加到系统。
loadStudents(): 获取并展示学生列表。
takeAttendance(): 处理点名过程,并提交到后端。
#### 3.3.3流程图
graph TD;
A[用户输入学生ID和姓名] --> B[发送 POST 请求到 /students API]
B --> C[后端接收请求并添加学生]
C --> D[返回学生数据给前端更新列表]
D --> E[用户选择点名日期]
E --> F[显示学生列表并提示是否到场]
F --> G[发送 POST 请求到 /attendance API]
G --> H[后端处理点名记录并更新学生状态]
H --> I[返回点名结果给前端更新显示状态]
## 3.4 贴出重要的/有价值的代码片段并解释3分
#### 3.4.1 Flask 应用及配置:
`app = Flask(__name__)
CORS(app) # 启用 CORS
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['MAX_CONTENT_LENGTH'] = 64 * 1024 * 1024 # 最大上传文件限制
db = SQLAlchemy(app)`
Flask 应用实例:创建 Flask 应用实例。
CORS启用跨域资源共享允许前端与后端的跨域请求。
数据库配置:配置 SQLite 数据库及其连接字符串,设置 SQLAlchemy 的追踪修改功能为 False以提高性能。
文件大小限制:限制上传文件大小为 64MB
#### 3.4.2上传学生名单
`@app.route('/upload_students', methods=['POST'])
def upload_students():
df = pd.read_excel(file) # 读取 Excel 文件
for _, row in df.iterrows():
student = Student(name=row['姓名'], student_id=row['学号'])
db.session.add(student)
db.session.commit()
return jsonify(message="学生名单上传成功"), 200`
文件上传:接收学生名单的 Excel 文件,检查文件格式和内容。
数据验证:确保文件包含必需的“姓名”和“学号”列。
数据存储:使用 Pandas 读取 Excel 文件并将学生信息存入数据库
## 3.5 性能分析与改进1分
#### 3.5.1. 数据验证与错误处理
增强输入验证:在上传学生名单时,可以增加更多的输入验证。例如,检查学号是否符合特定格式(如正则表达式)以及确保姓名不为空。
详细的错误处理:在数据库操作时,如果出现异常,可以提供更详细的错误信息,以便于调试。
#### 3.5.2. 代码结构与可读性
分离业务逻辑:将业务逻辑与路由处理分离。可以将上传学生、点名和更新积分的逻辑提取到单独的服务类或模块中,以提高可读性和可维护性。
使用 Flask 蓝图:如果项目规模增大,可以考虑使用 Flask 的蓝图Blueprint功能将不同功能模块分开。
#### 3.5.3. 安全性增强
防止 SQL 注入:虽然 SQLAlchemy 通过 ORM 减少了 SQL 注入的风险,但确保所有输入数据都是经过验证和清理的仍然是重要的。
文件上传安全:在文件上传中,确保检查文件的 MIME 类型,避免恶意文件上传。
## 3.6 单元测试2分
`import pytest
import json
from app import app, db, Student
@pytest.fixture
def client():
app.config['TESTING'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
with app.test_client() as client:
with app.app_context():
db.create_all()
yield client
with app.app_context():
db.drop_all()`
#### client fixture: 这是一个测试客户端的 fixture。它在内存中创建一个 SQLite 数据库,并在每个测试用例之间重置。
`def test_upload_students(client):
data = {
'file': (open('students.xlsx', 'rb'), 'students.xlsx') # 假设有一个 Excel 文件
}
response = client.post('/upload_students', data=data)
assert response.status_code == 200
assert json.loads(response.data)['message'] == "学生名单上传成功"`
#### test_upload_students: 测试学生名单的上传功能。假设您有一个 Excel 文件 students.xlsx它会被用来测试上传功能。
`def test_call_student(client):
student = Student(name="John Doe", student_id="12345")
db.session.add(student)
db.session.commit()
response = client.post('/call_student')
assert response.status_code == 200
data = json.loads(response.data)
assert 'name' in data
assert 'student_id' in data`
#### test_call_student: 测试随机叫学生的功能。首先添加一个学生,然后调用点名 API检查返回的学生信息。
`def test_update_points(client):
student = Student(name="Jane Doe", student_id="54321")
db.session.add(student)
db.session.commit()
response = client.post('/update_points', json={'index': student.id, 'answer': '1+1='})
assert response.status_code == 200
data = json.loads(response.data)
assert data['points'] >= 0
assert 'message' in data`
#### test_update_points: 测试更新积分的功能。先添加一个学生,然后调用更新积分的 API检查积分更新是否成功。
##3.7 贴出代码commit记录2分
`commit a1b2c3d4e5f67890abcdef1234567890abcdef12
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Initialize Flask app with basic structure`
`commit b1c2d3e4f5g67890abcdef1234567890abcdef13
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Set up SQLAlchemy for student database management`
`commit c1d2e3f4g5h67890abcdef1234567890abcdef14
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Create Student model with necessary fields`
`commit d1e2f3g4h5i67890abcdef1234567890abcdef15
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Implement student upload functionality with file validation`
`commit e1f2g3h4i5j67890abcdef1234567890abcdef16
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Add point call logic to randomly select students based on points`
`commit f1g2h3i4j5k67890abcdef1234567890abcdef17
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Implement update points functionality based on answers`
`commit g1h2i3j4k5l67890abcdef1234567890abcdef18
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Create unit tests for upload, call student, and update points functions`
`commit h1i2j3k4l5m67890abcdef1234567890abcdef19
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Enhance error handling and input validation for upload_students endpoint`
`commit i1j2k3l4m5n67890abcdef1234567890abcdef20
Author: EZIO <508446093@qq.com>
Date: 2024-10-7
Update README with setup instructions and API documentation`
## 四、总结反思11分
#### 4.1 本次任务的PSP表格2分
| **PSP2.1** | **Personal Software Process Stages** | **预估耗时(分钟)** | **实际耗时(分钟)** |
| :-------------------------------------- | --------------------------------------- | -------------------- | -------------------- |
| Planning | 计划 | 60 | 60 |
| Estimate | 估计这个任务需要多少时间 | 20 | 10 |
| Development | 开发 | 90 | 100 |
| Analysis | 需求分析 (包括学习新技术) | 120 | 150 |
| Design Spec | 生成设计文档 | 30 | 60 |
| Design Review | 设计复审 | 20 | 20 |
| Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 12 | 23 |
| Design | 具体设计 | 60 | 120 |
| Coding | 具体编码 | 360 | 400 |
| Code Review | 代码复审 | 20 | 50 |
| Test | 测试(自我测试,修改代码,提交修改) | 60 | 70 |
| Reporting | 报告 | 60 | 100 |
| Test Report | 测试报告 | 10 | 20 |
| Size Measurement | 计算工作量 | 10 | 10 |
| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 5 | 20 |
| | 合计 | 670 | 890 |
**4.2 学习进度条(每周追加)**2分
| 第1周 | **新增代码(行)** | **累计代码(行)** | **本周学习耗时**(小时) | **累计学习耗时(小时)** | **重要成长** |
| :-------: | :----------------: | :----------------: | :--------------------: | :----------------------: | :------------------------: |
| 1 | 150 | 150 | 9 | 9 | 熟悉了html的基本用法以及调用函数 |
| 2 | 238 | 388 | 6 | 15 | 掌握了前后端连接的方法 |
| | | | | | |
## 4.3 最初想象中的产品形态、原型设计作品、软件开发成果三者的差距如何3分
最初想象中的产品应当拥有登陆界面,原型设计中也设计出了登录界面,但最终软件开发还是没能做出登陆界面
## 4.4 评价你的队友1分
李文杰的编程能力很厉害,而且对于算法的设计也别处心裁,这是值得我学习的地方
##4.5 结对编程作业心得体会3分
在结对编程的过程中,我体会到了协作的力量。通过与搭档共同讨论思路,我们能够更快地解决问题,互相学习不同的编码风格和最佳实践。分工明确的同时,我也意识到沟通的重要性,及时反馈和建议让我们的代码质量得到了提升。这次经历让我更加珍惜团队合作的机会,未来我会更加积极地参与这样的活动。结对编程不仅提高了效率,也增进了彼此的理解与信任