#!/usr/bin/env python3 """ ExamCraft: Demo with Visible Question Generation This version shows the actual questions being generated by the teacher AI, perfect for demonstrating the adaptive teaching capabilities! """ import json import os import random from typing import Any, Dict, Tuple class VisibleQuestionDemo: """ ExamCraft demo that shows the actual questions being generated. Great for video demonstrations! """ def __init__(self, profile_path: str = "example_profile.json"): # Load student profile if os.path.exists(profile_path): with open(profile_path, "r") as file: self.profile = json.load(file) else: self.profile = self._create_default_profile() # Initialize student metrics self.reset_student() # Question templates for realistic generation self.question_templates = { "vectors": { "easy": [ { "question": "What is the result when you add vectors (2,3) and (1,4)?", "options": { "A": "(3,7)", "B": "(2,12)", "C": "(1,1)", "D": "(3,1)", }, "correct": "A", "explanation": "Vector addition is component-wise: (2+1, 3+4) = (3,7)", }, { "question": "Which operation can you perform on vectors?", "options": { "A": "Addition", "B": "Scalar multiplication", "C": "Dot product", "D": "All of the above", }, "correct": "D", "explanation": "Vectors support addition, scalar multiplication, and dot product operations", }, ], "medium": [ { "question": "Calculate the dot product of vectors (3,4) and (1,2):", "options": {"A": "11", "B": "7", "C": "5", "D": "10"}, "correct": "A", "explanation": "Dot product: (3×1) + (4×2) = 3 + 8 = 11", }, { "question": "What is the magnitude of vector (3,4)?", "options": {"A": "5", "B": "7", "C": "3.5", "D": "4.5"}, "correct": "A", "explanation": "Magnitude = √(3² + 4²) = √(9 + 16) = √25 = 5", }, ], "hard": [ { "question": "If vectors u and v are orthogonal, what is u·v?", "options": {"A": "1", "B": "0", "C": "-1", "D": "Undefined"}, "correct": "B", "explanation": "Orthogonal vectors have dot product = 0 by definition", } ], }, "matrices": { "easy": [ { "question": "What is the result of [1 2] + [3 4]?", "options": { "A": "[4 6]", "B": "[3 8]", "C": "[1 2]", "D": "[2 4]", }, "correct": "A", "explanation": "Matrix addition: [1+3, 2+4] = [4, 6]", } ], "medium": [ { "question": "What is the determinant of [[2,1],[3,4]]?", "options": {"A": "5", "B": "8", "C": "11", "D": "7"}, "correct": "A", "explanation": "det = (2×4) - (1×3) = 8 - 3 = 5", } ], "hard": [ { "question": "A matrix is invertible if and only if:", "options": { "A": "It's square", "B": "Det ≠ 0", "C": "All entries > 0", "D": "It's symmetric", }, "correct": "B", "explanation": "A matrix is invertible iff its determinant is non-zero", } ], }, "linear_systems": { "easy": [ { "question": "A system with no solutions is called:", "options": { "A": "Consistent", "B": "Inconsistent", "C": "Homogeneous", "D": "Independent", }, "correct": "B", "explanation": "Inconsistent systems have no solutions", } ], "medium": [ { "question": "In Gaussian elimination, what creates a pivot?", "options": { "A": "Leading 1", "B": "Zero entry", "C": "Negative number", "D": "Largest element", }, "correct": "A", "explanation": "Pivots are the leading 1's in row echelon form", } ], "hard": [ { "question": ( "For what values of k does the system have infinitely many solutions?\n" "2x + 3y = 6\n4x + 6y = k" ), "options": { "A": "k = 6", "B": "k = 12", "C": "k = 0", "D": "k = 3", }, "correct": "B", "explanation": "The second equation must be a multiple of the first: k = 2×6 = 12", } ], }, "eigenvalues_eigenvectors": { "easy": [ { "question": "An eigenvector of matrix A satisfies:", "options": { "A": "Av = λv", "B": "Av = v", "C": "Av = 0", "D": "Av = I", }, "correct": "A", "explanation": "By definition: Av = λv where λ is the eigenvalue", } ], "medium": [ { "question": "To find eigenvalues, we solve:", "options": { "A": "det(A) = 0", "B": "det(A - λI) = 0", "C": "Av = 0", "D": "tr(A) = λ", }, "correct": "B", "explanation": "Eigenvalues satisfy the characteristic equation det(A - λI) = 0", } ], "hard": [ { "question": "The sum of eigenvalues equals:", "options": { "A": "Determinant", "B": "Trace", "C": "Rank", "D": "Nullity", }, "correct": "B", "explanation": "The sum of eigenvalues equals the trace of the matrix", } ], }, } # Track teaching session self.question_count = 0 self.session_history = [] def _create_default_profile(self) -> Dict[str, Any]: """Create default student profile.""" return { "student_id": "adaptive_learner_001", "target_grade": "11th grade", "learning_goal": "Master linear algebra concepts", "topics": [ {"name": "vectors", "proficiency": 0.45}, {"name": "matrices", "proficiency": 0.30}, {"name": "linear_systems", "proficiency": 0.25}, {"name": "eigenvalues_eigenvectors", "proficiency": 0.20}, ], } def reset_student(self): """Reset student to initial proficiency levels.""" self.student_metrics = {} for topic in self.profile["topics"]: self.student_metrics[topic["name"]] = topic["proficiency"] self.question_count = 0 self.session_history = [] def generate_question(self, topic: str, difficulty: str) -> Dict[str, Any]: """Generate a specific question for the topic and difficulty.""" # Get question templates for this topic/difficulty topic_questions = self.question_templates.get(topic, {}) difficulty_questions = topic_questions.get(difficulty, []) if difficulty_questions: # Select a random question from available templates question_data = random.choice(difficulty_questions) # Add metadata question_data.update( { "topic": topic, "difficulty": difficulty, "generated_by": "ExamCraft Teacher AI", } ) return question_data else: # Fallback question if no template available return { "topic": topic, "difficulty": difficulty, "question": f"Sample {difficulty} question about {topic}", "options": { "A": "Option A", "B": "Option B", "C": "Option C", "D": "Option D", }, "correct": "A", "explanation": f"This demonstrates {difficulty} level understanding of {topic}", "generated_by": "ExamCraft Teacher AI (fallback)", } def simulate_student_answer( self, question_data: Dict[str, Any] ) -> Tuple[str, bool]: """Simulate student answering the question.""" topic = question_data["topic"] difficulty = question_data["difficulty"] correct_answer = question_data["correct"] # Get student's current proficiency proficiency = self.student_metrics[topic] # Adjust success probability based on difficulty difficulty_modifiers = {"easy": 0.25, "medium": 0.0, "hard": -0.25} modifier = difficulty_modifiers.get(difficulty, 0.0) # Calculate success probability success_prob = max(0.15, min(0.90, proficiency + modifier)) # Determine if answer is correct is_correct = random.random() < success_prob if is_correct: student_answer = correct_answer else: # Choose random incorrect answer options = list(question_data["options"].keys()) options.remove(correct_answer) student_answer = random.choice(options) return student_answer, is_correct def update_student_learning(self, topic: str, is_correct: bool, difficulty: str): """Update student's proficiency based on learning.""" current_prof = self.student_metrics[topic] # Learning rate based on correctness and difficulty if is_correct: base_improvement = 0.05 else: # Student learns from mistakes with good explanations base_improvement = 0.03 # Difficulty affects learning difficulty_multipliers = {"easy": 0.7, "medium": 1.0, "hard": 1.3} multiplier = difficulty_multipliers.get(difficulty, 1.0) improvement = base_improvement * multiplier # Diminishing returns as proficiency increases diminishing_factor = (1.0 - current_prof) * 0.8 + 0.2 improvement *= diminishing_factor # Update proficiency new_prof = min(1.0, current_prof + improvement) self.student_metrics[topic] = new_prof def get_weakest_topic(self) -> str: """Find the topic where student is struggling most.""" return min(self.student_metrics.items(), key=lambda x: x[1])[0] def select_difficulty(self, topic: str) -> str: """Select appropriate difficulty based on student proficiency.""" proficiency = self.student_metrics[topic] if proficiency < 0.4: return "easy" elif proficiency < 0.7: return "medium" else: return "hard" def run_visual_demo(self, num_questions: int = 5): """Run a demo showing actual question generation.""" print("🎓 ExamCraft: Visual Question Generation Demo") print("=" * 60) # Show initial state print("\n📊 Initial Student Proficiency:") for topic, prof in self.student_metrics.items(): print(f" {topic.replace('_', ' ').title()}: {prof:.1%}") print(f"\n🎯 Teacher AI will generate {num_questions} adaptive questions") print("🧠 Watch how it targets weak areas and adapts difficulty!\n") for i in range(num_questions): print(f"\n{'='*20} Question {i+1} {'='*20}") # Teacher AI analyzes student and selects topic/difficulty target_topic = self.get_weakest_topic() difficulty = self.select_difficulty(target_topic) current_prof = self.student_metrics[target_topic] print("🤖 Teacher AI Analysis:") print( f" Weakest topic: {target_topic.replace('_', ' ').title()} ({current_prof:.1%})" ) print(f" Selected difficulty: {difficulty.upper()}") # Generate the actual question print("\n📝 Generated Question:") question_data = self.generate_question(target_topic, difficulty) print(f" Topic: {question_data['topic'].replace('_', ' ').title()}") print(f" Difficulty: {question_data['difficulty'].upper()}") print(f" Question: {question_data['question']}") print(" Options:") for option, text in question_data["options"].items(): print(f" {option}) {text}") # Student answers student_answer, is_correct = self.simulate_student_answer(question_data) correct_answer = question_data["correct"] print("\n👨‍🎓 Student Response:") answered_option = question_data["options"][student_answer] print(f" Answered: {student_answer}) {answered_option}") option_text = question_data["options"][correct_answer] print(f" Correct answer: {correct_answer}) {option_text}") result_icon = "✅ CORRECT" if is_correct else "❌ INCORRECT" print(f" Result: {result_icon}") # Show explanation print("\n💡 Teacher's Explanation:") print(f" {question_data['explanation']}") # Update student learning old_prof = current_prof self.update_student_learning(target_topic, is_correct, difficulty) new_prof = self.student_metrics[target_topic] print("\n📈 Learning Progress:") topic_title = target_topic.replace("_", " ").title() improvement = new_prof - old_prof print( f" {topic_title}: {old_prof:.1%} → {new_prof:.1%} (+{improvement:.1%})" ) # Track this interaction self.question_count += 1 self.session_history.append( { "question_num": i + 1, "topic": target_topic, "difficulty": difficulty, "question": question_data, "student_answer": student_answer, "is_correct": is_correct, "proficiency_before": old_prof, "proficiency_after": new_prof, } ) # Final summary print(f"\n{'='*60}") print("📋 TEACHING SESSION SUMMARY") print(f"✨ Questions generated: {self.question_count}") print("\n🏆 Final Student Proficiency:") for topic, prof in self.student_metrics.items(): original_prof = next( t["proficiency"] for t in self.profile["topics"] if t["name"] == topic ) improvement = prof - original_prof print( f" {topic.replace('_', ' ').title()}: {prof:.1%} (+{improvement:.1%})" ) print("\n🎯 Adaptive Teaching Demonstrated:") topics_targeted = set(item["topic"] for item in self.session_history) print(f" - Targeted {len(topics_targeted)} different topics") print(" - Difficulty adapted based on performance") print(" - Each question included detailed explanations") return self.session_history def main(): """Run the visual question generation demo.""" demo = VisibleQuestionDemo() print("🎬 ExamCraft: Question Generation Demo") print("Perfect for recording your hackathon video!\n") num_questions = 5 try: user_input = input( f"How many questions to generate? (default {num_questions}): " ).strip() if user_input: num_questions = int(user_input) except ValueError: pass # Run the demo demo.run_visual_demo(num_questions) print("\n🎥 This demo shows:") print("✓ Teacher AI analyzing student weaknesses") print("✓ Adaptive question generation with real content") print("✓ Student simulation and learning progression") print("✓ Detailed explanations and feedback") print("\nPerfect for your 1-minute hackathon demo video! 🚀") if __name__ == "__main__": main()