基於AI編程導師,添加智能練習生成和個性化學習路徑功能。

1. 智能練習生成器

# exercise_generator.py
import random
from typing import List, Dict
from enum import Enum

class Difficulty(Enum):
    BEGINNER = "beginner"
    INTERMEDIATE = "intermediate" 
    ADVANCED = "advanced"

class ExerciseGenerator:
    def __init__(self):
        self.exercise_templates = self._load_exercise_templates()
    
    def generate_exercise(self, topic: str, difficulty: Difficulty, user_level: int) -> Dict:
        """生成個性化練習"""
        base_exercise = self._get_base_exercise(topic, difficulty)
        personalized_exercise = self._personalize_exercise(base_exercise, user_level)
        
        return {
            "title": personalized_exercise["title"],
            "description": personalized_exercise["description"],
            "starter_code": personalized_exercise["starter_code"],
            "test_cases": personalized_exercise["test_cases"],
            "hints": personalized_exercise["hints"],
            "learning_objectives": personalized_exercise["learning_objectives"]
        }
    
    def _personalize_exercise(self, exercise: Dict, user_level: int) -> Dict:
        """根據用户水平個性化練習"""
        personalized = exercise.copy()
        
        # 調整難度
        if user_level < 3:  # 新手
            personalized["hints"].append("嘗試先寫出偽代碼")
            personalized["starter_code"] = self._add_more_scaffolding(exercise["starter_code"])
        elif user_level > 7:  # 高級
            personalized["description"] = self._add_complexity(exercise["description"])
            personalized["test_cases"] = self._add_edge_cases(exercise["test_cases"])
        
        return personalized

# 使用示例
generator = ExerciseGenerator()
exercise = generator.generate_exercise("函數", Difficulty.BEGINNER, 2)

2. 學習進度追蹤

# progress_tracker.py
from datetime import datetime, timedelta
from typing import Dict, List
import json

class ProgressTracker:
    def __init__(self):
        self.user_progress = {}
    
    def record_exercise_attempt(self, user_id: str, exercise_id: str, 
                              success: bool, time_taken: int, code_quality: float):
        """記錄練習嘗試"""
        if user_id not in self.user_progress:
            self.user_progress[user_id] = {
                "completed_exercises": [],
                "strengths": [],
                "weaknesses": [],
                "learning_trends": [],
                "weekly_goals": []
            }
        
        attempt = {
            "exercise_id": exercise_id,
            "timestamp": datetime.now(),
            "success": success,
            "time_taken": time_taken,
            "code_quality": code_quality
        }
        
        self.user_progress[user_id]["completed_exercises"].append(attempt)
        self._update_skills_assessment(user_id, exercise_id, success, code_quality)
    
    def get_recommendations(self, user_id: str) -> List[Dict]:
        """獲取學習建議"""
        if user_id not in self.user_progress:
            return []
        
        progress = self.user_progress[user_id]
        weaknesses = progress["weaknesses"]
        
        recommendations = []
        for weakness in weaknesses[:3]:  # 專注前3個薄弱點
            recommendations.append({
                "topic": weakness,
                "exercise_type": "practice",
                "priority": "high",
                "reason": f"需要加強{weakness}方面的練習"
            })
        
        return recommendations

# 使用示例
tracker = ProgressTracker()
tracker.record_exercise_attempt("user123", "ex1", True, 300, 0.8)
recommendations = tracker.get_recommendations("user123")

3. 增強的Web界面

# app.py - 新增路由
@app.route('/generate-exercise', methods=['POST'])
def generate_exercise():
    data = request.json
    topic = data.get('topic', 'python基礎')
    difficulty = data.get('difficulty', 'beginner')
    user_level = data.get('user_level', 1)
    
    exercise = generator.generate_exercise(topic, Difficulty(difficulty), user_level)
    return jsonify(exercise)

@app.route('/record-progress', methods=['POST'])
def record_progress():
    data = request.json
    tracker.record_exercise_attempt(
        data['user_id'],
        data['exercise_id'],
        data['success'],
        data['time_taken'],
        data['code_quality']
    )
    return jsonify({"status": "recorded"})

@app.route('/recommendations/<user_id>')
def get_recommendations(user_id):
    recommendations = tracker.get_recommendations(user_id)
    return jsonify(recommendations)

4. 更新的前端界面

<!-- 新增練習生成區域 -->
<div class="exercise-generator">
    <h3>智能練習</h3>
    <select id="topicSelect">
        <option value="函數">函數</option>
        <option value="循環">循環</option>
        <option value="數據結構">數據結構</option>
    </select>
    <select id="difficultySelect">
        <option value="beginner">初級</option>
        <option value="intermediate">中級</option>
        <option value="advanced">高級</option>
    </select>
    <button onclick="generateExercise()">生成練習</button>
    
    <div id="exerciseArea" style="display:none;">
        <h4 id="exerciseTitle"></h4>
        <p id="exerciseDesc"></p>
        <textarea id="exerciseCode"></textarea>
        <button onclick="submitExercise()">提交答案</button>
        <div id="exerciseFeedback"></div>
    </div>
</div>

<!-- 新增進度展示 -->
<div class="progress-panel">
    <h3>學習進度</h3>
    <div id="progressStats">
        <p>已完成練習: <span id="completedCount">0</span></p>
        <p>平均代碼質量: <span id="avgQuality">0%</span></p>
    </div>
    <div id="recommendations"></div>
</div>

<script>
async function generateExercise() {
    const topic = document.getElementById('topicSelect').value;
    const difficulty = document.getElementById('difficultySelect').value;
    
    const response = await fetch('/generate-exercise', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({topic, difficulty, user_level: 2})
    });
    
    const exercise = await response.json();
    displayExercise(exercise);
}

function displayExercise(exercise) {
    document.getElementById('exerciseTitle').textContent = exercise.title;
    document.getElementById('exerciseDesc').textContent = exercise.description;
    document.getElementById('exerciseCode').value = exercise.starter_code;
    document.getElementById('exerciseArea').style.display = 'block';
}

async function submitExercise() {
    const code = document.getElementById('exerciseCode').value;
    // 這裏可以添加代碼分析和測試邏輯
    document.getElementById('exerciseFeedback').innerHTML = 
        '<p>✅ 練習提交成功!正在分析你的代碼...</p>';
}
</script>

5. 數據持久化

# database.py
import sqlite3
from contextlib import contextmanager

class Database:
    def __init__(self, db_path="coding_tutor.db"):
        self.db_path = db_path
        self._init_db()
    
    def _init_db(self):
        with self._get_connection() as conn:
            conn.execute('''
                CREATE TABLE IF NOT EXISTS user_progress (
                    user_id TEXT,
                    exercise_id TEXT,
                    success BOOLEAN,
                    time_taken INTEGER,
                    code_quality REAL,
                    timestamp DATETIME
                )
            ''')
    
    @contextmanager
    def _get_connection(self):
        conn = sqlite3.connect(self.db_path)
        try:
            yield conn
            conn.commit()
        finally:
            conn.close()

# 在ProgressTracker中使用數據庫
class PersistentProgressTracker(ProgressTracker):
    def __init__(self):
        super().__init__()
        self.db = Database()

這個增強版本提供了:

  • 🎯 個性化練習生成
  • 📊 學習進度追蹤
  • 💡 智能學習建議
  • 💾 數據持久化存儲
  • 🎨 改進的用户界面

讓編程學習更加系統化和個性化!