一、結對探索
1.1 隊伍基本信息
結對編號:2526;隊伍名稱:開發小隊;
|
學號
|
姓名
|
作業博客鏈接
|
具體分工
|
|
102301425
|
石誠宇
|
前端開發、UI設計、原型設計
|
|
|
102301426
|
潘煒豪
|
後端開發、數據庫設計、API接口
|
1.2 描述結對的過程
我們是在課程項目分組時自願組隊,基於共同的興趣選擇開發課堂點名系統。結對過程採用了分工協作模式,前端使用Vue技術棧,後端使用Flask框架。我們通過定期會議溝通進度,使用Git進行版本控制,確保代碼同步和功能整合。
1.3 非擺拍的兩人在討論設計或結對編程過程的照片
二、原型設計
2.1 原型工具的選擇
我們選擇了墨刀作為原型設計工具。選擇這款工具的原因是:
- 界面簡潔易用,學習成本低
- 支持豐富的交互效果和組件庫
- 支持團隊協作和在線預覽
- 能夠快速構建高保真原型
2.2 遇到的困難與解決辦法
困難描述: 在原型設計階段,如何合理佈局各個功能模塊,確保用户體驗流暢是一個挑戰。特別是點名界面需要同時顯示學生信息、操作按鈕和積分規則,界面容易顯得擁擠。
解決嘗試: 我們嘗試了多種佈局方案,包括分欄佈局、標籤頁佈局和卡片式佈局。
是否解決: 最終採用了左右分欄佈局,左側顯示點名核心功能,右側顯示評分操作和記錄,既保證了功能完整性又確保了界面美觀。
有何收穫: 學會了從用户角度思考界面設計,理解了信息層級和視覺引導的重要性。
2.3 原型作品鏈接
2.4 原型界面圖片展示
首頁界面
功能説明:
- 支持Excel文件導入學生數據
- 支持手動添加單個學生
- 顯示學生完整信息列表
- 提供數據清空和刪除功能
點名界面
功能説明:
- 支持隨機點名和順序點名兩種模式
- 實時顯示當前被點名學生詳細信息
- 集成積分規則説明
- 顯示學生列表和統計信息
積分排名界面
功能説明:
- 按總積分降序顯示學生排名
- 展示統計信息卡片(總學生數、平均積分等)
- 提供積分排名可視化圖表
- 支持數據刷新
數據導出界面
功能説明:
- 導出學生積分清單為Excel格式
- 提供數據預覽功能
- 支持下載導入模板
- 實時顯示導出狀態
三、編程實現
3.1 開發工具庫的使用
前端技術棧:
- Vue 3 + Vite:現代化前端框架和構建工具
- Element Plus:企業級UI組件庫
- Axios:Promise-based HTTP客户端
- XLSX:Excel文件讀寫庫
- Vue Router:單頁面應用路由
後端技術棧:
- Flask:輕量級Python Web框架
- Flask-SQLAlchemy:ORM數據庫操作
- Flask-CORS:跨域請求處理
- Pandas:數據分析和處理
- OpenPyXL:Excel文件操作
- SQLite:輕量級數據庫
3.2 代碼組織與內部實現設計
前端類圖
後端類圖
3.3 説明算法的關鍵與關鍵實現部分流程圖
隨機點名算法流程圖:
text
開始
↓
獲取所有學生數據
↓
計算每個學生的權重:weight = 1 / (total_score + 1)
↓
計算總權重
↓
生成隨機數 random_val ∈ [0,1)
↓
遍歷學生列表,累加歸一化權重
↓
當累加權重 ≥ random_val 時選擇當前學生
↓
返回選中學生信息
結束
關鍵算法説明:
基於反比權重的概率選擇,確保積分高的學生被點概率低,實現公平點名。算法時間複雜度O(n),空間複雜度O(1)。
3.4 貼出重要的/有價值的代碼片段並解釋
python
# 權重隨機點名算法核心實現
def random_rollcall():
students = Student.query.all()
if not students:
return None
weighted_students = []
total_weight = 0
# 計算每個學生的權重(積分越高權重越低)
for student in students:
weight = 1 / (student.total_score + 1) # +1避免除零
weighted_students.append({
'student': student,
'weight': weight
})
total_weight += weight
# 基於權重進行隨機選擇
random_val = random.random()
current_weight = 0
for ws in weighted_students:
normalized_weight = ws['weight'] / total_weight
current_weight += normalized_weight
if random_val <= current_weight:
return ws['student']
# 浮點數精度問題備選方案
return random.choice(students)
javascript
// 前端積分記錄方法
async recordScore(scoreChange, questionType = '') {
if (!this.currentStudent) {
this.showNotification('請先選擇學生', 'warning')
return
}
try {
await rollcallAPI.recordRollcall({
student_id: this.currentStudent.student_id,
call_type: this.callMode,
question_type: questionType,
score_change: scoreChange
})
// 更新本地數據
this.currentStudent.total_score += scoreChange
if (this.callMode === 'random') {
this.currentStudent.random_count += 1
}
await this.loadStudents() // 刷新數據
await this.loadRecentRecords()
this.showNotification(
`${this.currentStudent.name} ${scoreChange > 0 ? '+' : ''}${scoreChange}分`,
'success'
)
} catch (error) {
console.error('記錄分數失敗:', error)
this.showNotification('記錄失敗', 'error')
}
}
3.5 性能分析與改進
性能分析:
通過測試發現,學生數量超過100人時,隨機點名算法的響應時間有所增加,主要瓶頸在於數據庫查詢和權重計算。
改進思路:
- 添加學生數據分頁查詢
- 對權重計算進行緩存優化
- 使用Redis緩存熱門數據
消耗最大的函數:
數據庫查詢操作和權重計算循環是性能消耗的主要部分。
3.6 單元測試
python
# 學生數據導入測試
def test_student_import_excel():
# 測試數據:模擬Excel文件內容
test_data = [
{'學號': '20241101', '姓名': '測試學生1', '專業': '計算機科學'},
{'學號': '20241102', '姓名': '測試學生2', '專業': '軟件工程'}
]
# 測試函數:驗證Excel導入功能
result = import_students_from_excel(test_data)
# 斷言驗證
assert result['status'] == 'success'
assert result['message'] == '成功導入 2 名學生'
assert Student.query.count() == 2
# 隨機點名算法測試
def test_random_rollcall_algorithm():
# 準備測試數據
students = [
Student(total_score=0), # 高概率
Student(total_score=10), # 中概率
Student(total_score=50) # 低概率
]
# 測試算法分佈
selection_count = {0: 0, 1: 0, 2: 0}
for _ in range(1000):
selected = random_rollcall(students)
selection_count[students.index(selected)] += 1
# 驗證概率分佈合理性
assert selection_count[0] > selection_count[2] # 低積分學生被點次數更多
3.7 貼出代碼commit記錄
四、總結反思
4.1 本次任務的PSP表格
|
PSP2.1
|
Personal Software Process Stages
|
預估耗時(分鐘)
|
實際耗時(分鐘)
|
|
Planning
|
計劃
|
60
|
45
|
|
Estimate
|
估計這個任務需要多少時間
|
90
|
75
|
|
Development
|
開發
|
600
|
720
|
|
Analysis
|
需求分析(包括學習新技術)
|
120
|
90
|
|
Design Spec
|
生成設計文檔
|
60
|
45
|
|
Design Review
|
設計複審
|
30
|
25
|
|
Coding Standard
|
代碼規範
|
30
|
20
|
|
Design
|
具體設計
|
90
|
75
|
|
Coding
|
具體編碼
|
300
|
360
|
|
Code Review
|
代碼複審
|
60
|
50
|
|
Test
|
測試(自我測試,修改代碼,提交修改)
|
60
|
55
|
|
Reporting
|
報告
|
90
|
75
|
|
Test Report
|
測試報告
|
30
|
25
|
|
Size Measurement
|
計算工作量
|
15
|
10
|
|
Postmortem & Process Improvement Plan
|
事後總結,並提出過程改進計劃
|
30
|
25
|
|
合計 |
1565 |
1695 |
4.2 學習進度條
|
第N周
|
新增代碼(行)
|
累計代碼(行)
|
本週學習耗時(小時)
|
累計學習耗時(小時)
|
重要成長
|
|
1
|
600
|
600
|
8
|
8
|
掌握Vue 3組合式API、Flask基礎開發、項目環境搭建
|
|
2
|
800
|
1400
|
12
|
20
|
深入理解前後端數據交互、Excel文件處理、權重算法
|
|
3
|
400
|
1800
|
6
|
26
|
掌握性能優化、單元測試、項目部署和文檔編寫
|
4.3 最初想象中的產品形態、原型設計作品、軟件開發成果三者的差距如何?
理想與現實的差距分析:
- 功能完整性:最初設想的進階功能(如點名轉移權、隨機事件等)由於時間限制未能實現,但核心功能完整且穩定。
- 用户體驗:原型設計中的部分複雜交互在開發過程中進行了簡化,更注重功能的實用性和穩定性。
- 技術實現:在權重算法實現上比預期更加複雜,需要處理邊界情況和性能優化。
- 界面美觀度:實際開發界面相比原型設計更加簡潔,但功能佈局更加合理。
造成差距的因素:
- 時間約束:開發週期有限,需要優先保證核心功能
- 技術挑戰:某些技術方案的實施難度超出預期
- 需求優先級:根據實際使用場景調整了功能優先級
- 用户體驗:在開發過程中根據測試反饋優化了交互設計
4.4 評價你的隊友
石誠宇(前端開發)值得學習的地方:
對前端技術有深入研究,能夠快速解決複雜的前端問題,代碼規範整潔,對用户體驗有很好的理解。
石誠宇需要改進的地方:
在項目初期對後端接口理解不夠深入,導致部分前後端對接需要額外溝通時間。
潘煒豪(後端開發)值得學習的地方:
數據庫設計能力突出,API接口設計合理規範,對系統架構有整體把握,代碼健壯性強。
潘煒豪需要改進的地方:
在文檔編寫和代碼註釋方面可以更加詳細,便於團隊協作和理解。
4.5 結對編程作業心得體會
石誠宇心得體會:
通過本次結對編程項目,我深刻體會到了前後端分離開發模式的優勢。最大的收穫是學會了如何與後端工程師有效協作,理解API設計的重要性。在開發隨機點名界面時,如何平衡功能豐富性和界面簡潔性是一個挑戰,通過多次迭代優化最終找到了平衡點。這次經歷讓我對完整的Web開發流程有了更深入的理解,也為今後的項目開發積累了寶貴經驗。
潘煒豪心得體會:
這次結對編程讓我認識到團隊協作中溝通的重要性。在開發權重隨機點名算法時,我們遇到了概率分佈不均衡的問題,通過與隊友的深入討論和多次測試,最終優化了算法實現。最大的感悟是:一個好的系統不僅要有完善的功能,更要有良好的可維護性和擴展性。通過這個項目,我提升了對數據庫設計、API規範和系統架構的理解,這些經驗對未來的軟件開發工作具有重要意義。