mirror of
https://github.com/NousResearch/atropos.git
synced 2026-04-19 12:57:58 +00:00
475 lines
18 KiB
Python
475 lines
18 KiB
Python
#!/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()
|