""" Integrate personalized learning pathway functionality into Gradio interface """ import gradio as gr import json from datetime import datetime from personalized_learning import ( UserProfilingSystem, LearningPathGenerator, AdaptiveLearningEngine ) # Initialize system components def initialize_personalized_learning(available_topics: list, client): """Initialize personalized learning system""" user_profiling = UserProfilingSystem() learning_path_generator = LearningPathGenerator(user_profiling, available_topics) adaptive_engine = AdaptiveLearningEngine(user_profiling, learning_path_generator) return user_profiling, learning_path_generator, adaptive_engine # Create personalized learning path tab def create_personalized_learning_tab(adaptive_engine, user_profiling, query_rag_model, generate_multiple_choice_questions, client): """Create personalized learning path tab""" with gr.TabItem("Personalized Learning Path"): gr.Markdown("## 🎯 Your Personalized Learning Journey") gr.Markdown("Get a customized learning path based on your knowledge profile and performance.") # User ID input with gr.Row(): user_id_input = gr.Textbox( label="User ID", placeholder="Enter your user ID (e.g., user_001)", value="default_user" ) load_profile_btn = gr.Button("Load My Profile") # User profile display with gr.Column(visible=False) as profile_container: profile_summary = gr.Markdown() with gr.Row(): with gr.Column(): gr.Markdown("### πŸ“Š Knowledge Profile") knowledge_level_display = gr.JSON() with gr.Column(): gr.Markdown("### πŸ“ˆ Learning Statistics") learning_stats = gr.JSON() # Learning path section with gr.Row(): focus_areas_input = gr.CheckboxGroup( label="Focus Areas (Optional)", choices=[], value=[], interactive=True ) generate_path_btn = gr.Button("Generate Learning Path", variant="primary") # Learning path visualization with gr.Column(visible=False) as path_container: gr.Markdown("### πŸ—ΊοΈ Your Learning Path") path_progress = gr.HTML() path_visualization = gr.HTML() # Current node information with gr.Row(): with gr.Column(): current_node_info = gr.Markdown() with gr.Column(): next_action_btn = gr.Button("Start This Node", variant="primary") skip_node_btn = gr.Button("Skip This Node") # Recommendations section with gr.Row(): with gr.Column(): gr.Markdown("### πŸ’‘ Recommendations") recommendations_display = gr.JSON() # Learning activity history with gr.Column(visible=False) as history_container: gr.Markdown("### πŸ“š Learning History") learning_history = gr.Dataframe( headers=["Date", "Topic", "Activity", "Score"], interactive=False ) # Handler functions def load_user_profile(user_id): """Load user profile""" if not user_id: return ( gr.update(visible=False), # profile_container "", # profile_summary {}, # knowledge_level_display {}, # learning_stats [], # focus_areas_input choices gr.update(visible=False) # path_container ) profile = user_profiling.get_or_create_profile(user_id) summary = user_profiling.get_profile_summary(user_id) # Generate summary text summary_text = f""" ### πŸ‘€ User Profile: {user_id} **Learning Style:** {summary['learning_style'].title()} **Learning Pace:** {summary['learning_pace'].title()} **Overall Progress:** {summary['overall_progress']:.1%} **Total Questions Asked:** {summary['total_questions']} **Total Tests Completed:** {summary['total_tests']} **Strong Areas:** {', '.join(summary['strong_areas']) if summary['strong_areas'] else 'None yet'} **Areas Needing Improvement:** {', '.join(summary['weak_areas']) if summary['weak_areas'] else 'None yet'} """ # Prepare knowledge level data knowledge_data = summary['knowledge_level'] if not knowledge_data: knowledge_data = {"No topics learned yet": 0.0} # Prepare statistics data stats_data = { "Total Questions": summary['total_questions'], "Total Tests": summary['total_tests'], "Preferred Topics": summary['preferred_topics'][:5] if summary['preferred_topics'] else [], "Overall Progress": f"{summary['overall_progress']:.1%}" } # Update focus areas options all_topics = list(set(list(knowledge_data.keys()) + summary['preferred_topics'] + summary['weak_areas'])) return ( gr.update(visible=True), summary_text, knowledge_data, stats_data, all_topics, gr.update(visible=False) ) def generate_learning_path(user_id, focus_areas): """Generate learning path""" if not user_id: return ( gr.update(visible=False), "", "", "", {}, gr.update(visible=False) ) path = adaptive_engine.create_or_update_path(user_id, focus_areas if focus_areas else None) # Generate path visualization HTML vis_data = adaptive_engine.get_path_visualization_data(user_id) # Create progress bar progress_html = f"""
{path.completion_percentage*100:.1f}% Complete

Total Nodes: {len(path.nodes)} | Completed: {sum(1 for n in path.nodes if n.status == 'completed')} | Estimated Time: {path.estimated_total_time} minutes

""" # Create path visualization path_html = "
" path_html += "

Learning Path Structure:

" path_html += "
" for i, node in enumerate(path.nodes): status_color = { "completed": "#4CAF50", "in_progress": "#2196F3", "pending": "#9E9E9E", "skipped": "#FF9800" }.get(node.status, "#9E9E9E") is_current = i == path.current_node_index highlight = "border: 3px solid #FF5722; padding: 10px;" if is_current else "padding: 10px;" path_html += f"""
{node.topic} - {node.bloom_level.title()} ({node.content_type})
Difficulty: {node.difficulty:.2f} | Time: {node.estimated_time} min
{node.status.title()}
""" path_html += "
" # Current node information if path.current_node_index < len(path.nodes): current_node = path.nodes[path.current_node_index] current_node_info = f""" ### Current Learning Node **Topic:** {current_node.topic} **Bloom Level:** {current_node.bloom_level.title()} **Content Type:** {current_node.content_type.title()} **Difficulty:** {current_node.difficulty:.2f} **Estimated Time:** {current_node.estimated_time} minutes **Status:** {current_node.status.title()} """ else: current_node_info = "### Learning Path Complete! πŸŽ‰" # Get recommendations recommendations = adaptive_engine.get_recommendations(user_id) return ( gr.update(visible=True), progress_html, path_html, current_node_info, recommendations, gr.update(visible=True) ) def start_current_node(user_id): """Start current node""" path = adaptive_engine.get_active_path(user_id) if not path or path.current_node_index >= len(path.nodes): return "No active node to start." current_node = path.nodes[path.current_node_index] return f"Starting learning node: {current_node.topic} - {current_node.bloom_level}" # Bind events load_profile_btn.click( load_user_profile, inputs=[user_id_input], outputs=[profile_container, profile_summary, knowledge_level_display, learning_stats, focus_areas_input, path_container] ) generate_path_btn.click( generate_learning_path, inputs=[user_id_input, focus_areas_input], outputs=[path_container, path_progress, path_visualization, current_node_info, recommendations_display, history_container] ) next_action_btn.click( start_current_node, inputs=[user_id_input], outputs=[] ) # Auto-load default user user_id_input.change( load_user_profile, inputs=[user_id_input], outputs=[profile_container, profile_summary, knowledge_level_display, learning_stats, focus_areas_input, path_container] ) return { "adaptive_engine": adaptive_engine, "user_profiling": user_profiling } # Integrate with existing testing functionality def integrate_with_testing(adaptive_engine, user_profiling, test_results, user_id): """Integrate test results into personalized learning system""" if not user_id or not test_results: return # Extract topic from test results (assuming test results contain topic information) topic = test_results[0].get('topic', 'unknown') if test_results else 'unknown' # Update user profile profile = user_profiling.update_from_test_results(user_id, topic, test_results) # Update learning path path = adaptive_engine.get_active_path(user_id) if path: # Calculate average score scores = [1.0 if r.get('is_correct', False) else 0.0 for r in test_results] avg_score = sum(scores) / len(scores) if scores else 0.5 # Find corresponding node and mark as completed for node in path.nodes: if node.topic == topic and node.status == "in_progress": adaptive_engine.complete_node(user_id, node.node_id, avg_score) break # Integrate with Q&A functionality def integrate_with_qa(user_profiling, user_id, question): """Integrate Q&A history into personalized learning system""" if not user_id or not question: return # Simple topic extraction (can be improved based on actual needs) topic = None if "distronic" in question.lower() or "distance" in question.lower(): topic = "DISTRONIC" elif "lane" in question.lower(): topic = "Lane Change Assist" elif "steering" in question.lower(): topic = "Steering Assist" elif "stop" in question.lower() or "go" in question.lower(): topic = "Stop-and-Go Assist" # Update user profile user_profiling.update_from_question(user_id, question, topic)