Spaces:
Sleeping
Sleeping
Update llm_app_enhanced.py
#2
by
SreekarB
- opened
- llm_app_enhanced.py +184 -121
llm_app_enhanced.py
CHANGED
|
@@ -70,42 +70,81 @@ class CodePracticeAssistant:
|
|
| 70 |
# Check if we have curriculum content or need to use generic approach
|
| 71 |
if "No specific curriculum content found" in curriculum_content or "could not be retrieved" in curriculum_content:
|
| 72 |
# Use generic prompt without curriculum context
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
Problem Type: {problem_types.get(internal_type, internal_type)}
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
Requirements:
|
| 78 |
-
- Make it appropriate for
|
| 79 |
-
-
|
| 80 |
-
-
|
| 81 |
-
-
|
| 82 |
-
-
|
| 83 |
-
-
|
| 84 |
-
-
|
| 85 |
-
-
|
|
|
|
| 86 |
|
| 87 |
Format your response as:
|
| 88 |
-
PROBLEM: [
|
| 89 |
-
CODE: [
|
| 90 |
-
|
| 91 |
-
IMPORTANT:
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
```
|
| 100 |
-
|
| 101 |
-
Keep it concise but clear."""
|
| 102 |
else:
|
| 103 |
-
# Use curriculum-based prompt
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
Curriculum Context: {curriculum_content}
|
| 107 |
|
| 108 |
Problem Type: {problem_types.get(internal_type, internal_type)}
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
Requirements:
|
| 111 |
- Base the problem on the curriculum content provided above
|
|
@@ -114,34 +153,33 @@ Requirements:
|
|
| 114 |
- Make it appropriate for the skill level shown in the curriculum
|
| 115 |
- Include clear instructions that reference the curriculum concepts
|
| 116 |
- Provide a specific, focused problem that reinforces what they learned
|
| 117 |
-
-
|
| 118 |
-
-
|
| 119 |
-
-
|
| 120 |
-
-
|
| 121 |
-
-
|
| 122 |
-
-
|
|
|
|
| 123 |
|
| 124 |
Format your response as:
|
| 125 |
-
PROBLEM: [
|
| 126 |
-
CODE: [
|
| 127 |
|
| 128 |
-
IMPORTANT:
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
1 2 3 4 5
|
| 136 |
-
```
|
| 137 |
|
| 138 |
-
|
| 139 |
|
| 140 |
try:
|
| 141 |
response = self.anthropic_client.messages.create(
|
| 142 |
model="claude-3-5-haiku-20241022",
|
| 143 |
max_tokens=1000,
|
| 144 |
-
temperature=0.
|
| 145 |
messages=[{"role": "user", "content": prompt}]
|
| 146 |
)
|
| 147 |
|
|
@@ -185,7 +223,7 @@ Keep it concise but clear and aligned with the curriculum difficulty."""
|
|
| 185 |
return f"Curriculum content for '{topic}' could not be retrieved."
|
| 186 |
|
| 187 |
def analyze_student_code(self, topic, problem_type, problem_description, student_code):
|
| 188 |
-
"""Analyze student's code and provide
|
| 189 |
if not self.anthropic_client:
|
| 190 |
return "LLM not available. Please check your API key."
|
| 191 |
|
|
@@ -213,7 +251,7 @@ Keep it concise but clear and aligned with the curriculum difficulty."""
|
|
| 213 |
|
| 214 |
# Check if we have curriculum content or need to use generic approach
|
| 215 |
if "No specific curriculum content found" in curriculum_content or "could not be retrieved" in curriculum_content:
|
| 216 |
-
# Use generic analysis prompt
|
| 217 |
prompt = f"""You are a helpful programming tutor. Analyze this student's code and provide step-by-step guidance.
|
| 218 |
|
| 219 |
Problem Type: {problem_type}
|
|
@@ -232,7 +270,7 @@ Provide a CONCISE, step-by-step analysis:
|
|
| 232 |
|
| 233 |
IMPORTANT: Guide them to figure out the solution themselves. Don't provide complete working code unless they're completely stuck. Focus on hints and direction."""
|
| 234 |
else:
|
| 235 |
-
# Use curriculum-based analysis prompt
|
| 236 |
prompt = f"""You are a helpful programming tutor. Analyze this student's code and provide step-by-step guidance.
|
| 237 |
|
| 238 |
Curriculum Context: {curriculum_content}
|
|
@@ -247,16 +285,16 @@ Analysis Type: {analysis_types.get(internal_type, "General analysis")}
|
|
| 247 |
|
| 248 |
Provide a CONCISE, step-by-step analysis:
|
| 249 |
1. **What's Working** (1-2 sentences)
|
| 250 |
-
2. **Areas to Improve** (2-3 specific points
|
| 251 |
3. **Step-by-Step Solution** (guide them through the process, don't give complete code)
|
| 252 |
-
4. **Key Takeaway** (1 sentence
|
| 253 |
|
| 254 |
IMPORTANT: Guide them to figure out the solution themselves. Don't provide complete working code unless they're completely stuck. Focus on hints and direction based on curriculum concepts."""
|
| 255 |
|
| 256 |
try:
|
| 257 |
response = self.anthropic_client.messages.create(
|
| 258 |
model="claude-3-5-haiku-20241022",
|
| 259 |
-
max_tokens=
|
| 260 |
temperature=0.7,
|
| 261 |
messages=[{"role": "user", "content": prompt}]
|
| 262 |
)
|
|
@@ -385,18 +423,32 @@ Thanks! Slide number:"""
|
|
| 385 |
)
|
| 386 |
|
| 387 |
# Create answer generation prompt
|
| 388 |
-
answer_template = """
|
| 389 |
"{question}"
|
| 390 |
Here's what the curriculum slide says about it:
|
| 391 |
{slide_content}
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
-
|
| 395 |
-
-
|
| 396 |
-
-
|
| 397 |
-
-
|
| 398 |
-
|
| 399 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
|
| 401 |
self.answer_prompt = PromptTemplate(
|
| 402 |
input_variables=["question", "slide_content"],
|
|
@@ -525,7 +577,7 @@ Keep it brief and encouraging!"""
|
|
| 525 |
# Get LLM's answer
|
| 526 |
response = self.anthropic_client.messages.create(
|
| 527 |
model="claude-3-5-haiku-20241022",
|
| 528 |
-
max_tokens=
|
| 529 |
temperature=0.7,
|
| 530 |
messages=[{"role": "user", "content": prompt}]
|
| 531 |
)
|
|
@@ -606,50 +658,75 @@ def analyze_code(topic, problem_type, problem_description, student_code):
|
|
| 606 |
return terminal_output, analysis
|
| 607 |
|
| 608 |
def extract_topic_from_query(query):
|
| 609 |
-
"""Extract topic from chat query for practice"""
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
|
| 620 |
-
def
|
| 621 |
-
"""Generate practice problem and return
|
| 622 |
topic = extract_topic_from_query(query)
|
| 623 |
-
# Generate a problem for this topic
|
| 624 |
problem, code = practice_assistant.generate_practice_problem(topic, "Create Practice Problems")
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
font-size: 16px !important;
|
| 642 |
-
color: #666 !important;
|
| 643 |
-
}
|
| 644 |
-
.terminal-output {
|
| 645 |
-
font-family: 'Courier New', monospace !important;
|
| 646 |
-
font-size: 14px !important;
|
| 647 |
-
background-color: #f5f5f5 !important;
|
| 648 |
-
}
|
| 649 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 650 |
|
| 651 |
-
with gr.Blocks(title="Enhanced LLM Curriculum Assistant", theme=gr.themes.Soft(), css=custom_css) as demo:
|
| 652 |
-
gr.Markdown("# π€ Enhanced LLM Curriculum Assistant\nYour AI programming tutor with improved UX and accessibility!")
|
| 653 |
|
| 654 |
with gr.Tabs() as tabs:
|
| 655 |
# Tab 1: Chat Assistant
|
|
@@ -666,7 +743,7 @@ with gr.Blocks(title="Enhanced LLM Curriculum Assistant", theme=gr.themes.Soft()
|
|
| 666 |
lines=3
|
| 667 |
)
|
| 668 |
submit = gr.Button("π€ Ask AI", variant="primary", size="lg")
|
| 669 |
-
answer = gr.Markdown(label="LLM Generated Answer"
|
| 670 |
|
| 671 |
# Practice button
|
| 672 |
practice_btn = gr.Button("π» Practice This Topic", variant="secondary", size="lg", visible=False)
|
|
@@ -725,7 +802,7 @@ with gr.Blocks(title="Enhanced LLM Curriculum Assistant", theme=gr.themes.Soft()
|
|
| 725 |
generate_btn = gr.Button("π² Generate Problem", variant="primary", size="lg")
|
| 726 |
|
| 727 |
gr.Markdown("#### π Problem Description")
|
| 728 |
-
problem_description = gr.Markdown(label="Problem will appear here..."
|
| 729 |
|
| 730 |
gr.Markdown("#### π» Starter Code (if applicable)")
|
| 731 |
starter_code = gr.Code(
|
|
@@ -753,12 +830,11 @@ with gr.Blocks(title="Enhanced LLM Curriculum Assistant", theme=gr.themes.Soft()
|
|
| 753 |
label="Terminal Output",
|
| 754 |
lines=8,
|
| 755 |
value="# Code execution output will appear here...",
|
| 756 |
-
interactive=False
|
| 757 |
-
elem_classes=["terminal-output"]
|
| 758 |
)
|
| 759 |
|
| 760 |
gr.Markdown("#### π AI Analysis")
|
| 761 |
-
analysis_output = gr.Markdown(label="Analysis will appear here..."
|
| 762 |
|
| 763 |
# Event handlers for practice
|
| 764 |
generate_btn.click(
|
|
@@ -773,25 +849,12 @@ with gr.Blocks(title="Enhanced LLM Curriculum Assistant", theme=gr.themes.Soft()
|
|
| 773 |
outputs=[terminal_output, analysis_output]
|
| 774 |
)
|
| 775 |
|
| 776 |
-
# Practice button
|
| 777 |
-
def practice_with_navigation(query):
|
| 778 |
-
topic, problem, code = go_to_practice(query)
|
| 779 |
-
return topic, problem, code
|
| 780 |
-
|
| 781 |
practice_btn.click(
|
| 782 |
-
fn=
|
| 783 |
inputs=[question],
|
| 784 |
-
outputs=[topic_input, problem_description, starter_code]
|
| 785 |
-
)
|
| 786 |
-
|
| 787 |
-
# Add a separate event to switch tabs
|
| 788 |
-
def switch_to_practice():
|
| 789 |
-
return gr.update(selected=1)
|
| 790 |
-
|
| 791 |
-
practice_btn.click(
|
| 792 |
-
fn=switch_to_practice,
|
| 793 |
-
outputs=[tabs]
|
| 794 |
)
|
| 795 |
|
| 796 |
if __name__ == "__main__":
|
| 797 |
-
demo.launch()
|
|
|
|
| 70 |
# Check if we have curriculum content or need to use generic approach
|
| 71 |
if "No specific curriculum content found" in curriculum_content or "could not be retrieved" in curriculum_content:
|
| 72 |
# Use generic prompt without curriculum context
|
| 73 |
+
# Add randomization for diversity while keeping it simple
|
| 74 |
+
difficulty_levels = ["beginner", "intermediate", "challenging"]
|
| 75 |
+
problem_styles = [
|
| 76 |
+
"simple calculation", "basic input/output", "pattern printing",
|
| 77 |
+
"number games", "text processing", "list operations", "basic functions",
|
| 78 |
+
"simple loops", "conditional statements", "variable manipulation"
|
| 79 |
+
]
|
| 80 |
+
|
| 81 |
+
problem_contexts = [
|
| 82 |
+
"school project", "homework assignment", "classroom exercise", "practice problem",
|
| 83 |
+
"simple game", "basic calculator", "data collection", "text processing",
|
| 84 |
+
"number games", "pattern drawing", "simple simulation", "basic tools"
|
| 85 |
+
]
|
| 86 |
+
|
| 87 |
+
selected_difficulty = random.choice(difficulty_levels)
|
| 88 |
+
selected_style = random.choice(problem_styles)
|
| 89 |
+
selected_context = random.choice(problem_contexts)
|
| 90 |
+
|
| 91 |
+
prompt = f"""Create a SIMPLE and CLEAR programming practice problem for a student learning {topic}.
|
| 92 |
|
| 93 |
Problem Type: {problem_types.get(internal_type, internal_type)}
|
| 94 |
+
Difficulty: {selected_difficulty}
|
| 95 |
+
Style: {selected_style}
|
| 96 |
+
Context: {selected_context}
|
| 97 |
|
| 98 |
Requirements:
|
| 99 |
+
- Make it appropriate for {selected_difficulty} level
|
| 100 |
+
- Use a {selected_style} approach in a {selected_context} setting
|
| 101 |
+
- Keep instructions VERY SIMPLE and step-by-step
|
| 102 |
+
- Focus on ONE main concept at a time
|
| 103 |
+
- Make it engaging but not overwhelming
|
| 104 |
+
- ALWAYS include starter code that students can build upon
|
| 105 |
+
- Use simple, clear language suitable for beginners
|
| 106 |
+
- Avoid complex storylines or too many requirements
|
| 107 |
+
- Make it feel achievable and fun
|
| 108 |
|
| 109 |
Format your response as:
|
| 110 |
+
PROBLEM: [Simple, clear problem description with step-by-step instructions]
|
| 111 |
+
CODE: [Simple starter code (3-8 lines) that students can easily understand and modify]
|
| 112 |
+
|
| 113 |
+
IMPORTANT:
|
| 114 |
+
- Keep the problem structure VERY SIMPLE
|
| 115 |
+
- Use clear, direct language
|
| 116 |
+
- Focus on the core concept being learned
|
| 117 |
+
- Make it feel achievable for beginners
|
| 118 |
+
- The starter code should be easy to understand and modify
|
| 119 |
+
|
| 120 |
+
Create a problem that's engaging but simple enough for students just learning Python!"""
|
|
|
|
|
|
|
|
|
|
| 121 |
else:
|
| 122 |
+
# Use curriculum-based prompt with diversity
|
| 123 |
+
# Add randomization for diversity while keeping it simple
|
| 124 |
+
difficulty_levels = ["beginner", "intermediate", "challenging"]
|
| 125 |
+
problem_styles = [
|
| 126 |
+
"simple calculation", "basic input/output", "pattern printing",
|
| 127 |
+
"number games", "text processing", "list operations", "basic functions",
|
| 128 |
+
"simple loops", "conditional statements", "variable manipulation"
|
| 129 |
+
]
|
| 130 |
+
|
| 131 |
+
problem_contexts = [
|
| 132 |
+
"school project", "homework assignment", "classroom exercise", "practice problem",
|
| 133 |
+
"simple game", "basic calculator", "data collection", "text processing"
|
| 134 |
+
]
|
| 135 |
+
|
| 136 |
+
selected_difficulty = random.choice(difficulty_levels)
|
| 137 |
+
selected_style = random.choice(problem_styles)
|
| 138 |
+
selected_context = random.choice(problem_contexts)
|
| 139 |
+
|
| 140 |
+
prompt = f"""Create a SIMPLE and CLEAR programming practice problem for a student learning {topic}.
|
| 141 |
|
| 142 |
Curriculum Context: {curriculum_content}
|
| 143 |
|
| 144 |
Problem Type: {problem_types.get(internal_type, internal_type)}
|
| 145 |
+
Difficulty: {selected_difficulty}
|
| 146 |
+
Style: {selected_style}
|
| 147 |
+
Context: {selected_context}
|
| 148 |
|
| 149 |
Requirements:
|
| 150 |
- Base the problem on the curriculum content provided above
|
|
|
|
| 153 |
- Make it appropriate for the skill level shown in the curriculum
|
| 154 |
- Include clear instructions that reference the curriculum concepts
|
| 155 |
- Provide a specific, focused problem that reinforces what they learned
|
| 156 |
+
- Use a {selected_style} approach in a {selected_context} setting
|
| 157 |
+
- ALWAYS include starter code that students can build upon
|
| 158 |
+
- Keep instructions VERY SIMPLE and step-by-step
|
| 159 |
+
- Focus on ONE main concept at a time
|
| 160 |
+
- Use simple, clear language suitable for beginners
|
| 161 |
+
- Avoid complex storylines or too many requirements
|
| 162 |
+
- Make it feel achievable and fun
|
| 163 |
|
| 164 |
Format your response as:
|
| 165 |
+
PROBLEM: [Simple, clear problem description with step-by-step instructions]
|
| 166 |
+
CODE: [Simple starter code (3-8 lines) that students can easily understand and modify]
|
| 167 |
|
| 168 |
+
IMPORTANT:
|
| 169 |
+
- Keep the problem structure VERY SIMPLE
|
| 170 |
+
- Use clear, direct language
|
| 171 |
+
- Focus on the core concept being learned
|
| 172 |
+
- Make it feel achievable for beginners
|
| 173 |
+
- The starter code should be easy to understand and modify
|
| 174 |
+
- Align with curriculum concepts while keeping it simple
|
|
|
|
|
|
|
| 175 |
|
| 176 |
+
Create a problem that's engaging but simple enough for students just learning Python!"""
|
| 177 |
|
| 178 |
try:
|
| 179 |
response = self.anthropic_client.messages.create(
|
| 180 |
model="claude-3-5-haiku-20241022",
|
| 181 |
max_tokens=1000,
|
| 182 |
+
temperature=0.3, # Lower temperature for more structured, predictable problems
|
| 183 |
messages=[{"role": "user", "content": prompt}]
|
| 184 |
)
|
| 185 |
|
|
|
|
| 223 |
return f"Curriculum content for '{topic}' could not be retrieved."
|
| 224 |
|
| 225 |
def analyze_student_code(self, topic, problem_type, problem_description, student_code):
|
| 226 |
+
"""Analyze student's code and provide feedback based on curriculum"""
|
| 227 |
if not self.anthropic_client:
|
| 228 |
return "LLM not available. Please check your API key."
|
| 229 |
|
|
|
|
| 251 |
|
| 252 |
# Check if we have curriculum content or need to use generic approach
|
| 253 |
if "No specific curriculum content found" in curriculum_content or "could not be retrieved" in curriculum_content:
|
| 254 |
+
# Use generic analysis prompt - Tutor style
|
| 255 |
prompt = f"""You are a helpful programming tutor. Analyze this student's code and provide step-by-step guidance.
|
| 256 |
|
| 257 |
Problem Type: {problem_type}
|
|
|
|
| 270 |
|
| 271 |
IMPORTANT: Guide them to figure out the solution themselves. Don't provide complete working code unless they're completely stuck. Focus on hints and direction."""
|
| 272 |
else:
|
| 273 |
+
# Use curriculum-based analysis prompt - Tutor style
|
| 274 |
prompt = f"""You are a helpful programming tutor. Analyze this student's code and provide step-by-step guidance.
|
| 275 |
|
| 276 |
Curriculum Context: {curriculum_content}
|
|
|
|
| 285 |
|
| 286 |
Provide a CONCISE, step-by-step analysis:
|
| 287 |
1. **What's Working** (1-2 sentences)
|
| 288 |
+
2. **Areas to Improve** (2-3 specific points)
|
| 289 |
3. **Step-by-Step Solution** (guide them through the process, don't give complete code)
|
| 290 |
+
4. **Key Takeaway** (1 sentence)
|
| 291 |
|
| 292 |
IMPORTANT: Guide them to figure out the solution themselves. Don't provide complete working code unless they're completely stuck. Focus on hints and direction based on curriculum concepts."""
|
| 293 |
|
| 294 |
try:
|
| 295 |
response = self.anthropic_client.messages.create(
|
| 296 |
model="claude-3-5-haiku-20241022",
|
| 297 |
+
max_tokens=1500,
|
| 298 |
temperature=0.7,
|
| 299 |
messages=[{"role": "user", "content": prompt}]
|
| 300 |
)
|
|
|
|
| 423 |
)
|
| 424 |
|
| 425 |
# Create answer generation prompt
|
| 426 |
+
answer_template = """Hey there! I'm helping a student understand a programming concept. They asked:
|
| 427 |
"{question}"
|
| 428 |
Here's what the curriculum slide says about it:
|
| 429 |
{slide_content}
|
| 430 |
+
Could you help me explain this to them in a friendly, educational way? I'd like you to:
|
| 431 |
+
- Break it down in simple terms with comprehensive explanations
|
| 432 |
+
- Use examples if the slide has them, and add more examples if needed
|
| 433 |
+
- Make it step-by-step and easy to follow
|
| 434 |
+
- Add helpful context and real-world applications
|
| 435 |
+
- Use bullet points or lists to make it clear
|
| 436 |
+
- Make sure your answer directly addresses what they asked
|
| 437 |
+
- ALWAYS include practical code examples with explanations
|
| 438 |
+
- Show multiple variations of the concept
|
| 439 |
+
- Include common mistakes and how to avoid them
|
| 440 |
+
- Provide practice exercises or challenges
|
| 441 |
+
- Be comprehensive, detailed, and educational
|
| 442 |
+
- Make it engaging and interesting to read
|
| 443 |
+
|
| 444 |
+
Format your response with:
|
| 445 |
+
- Clear headings and sections
|
| 446 |
+
- Code examples in proper code blocks
|
| 447 |
+
- Step-by-step explanations
|
| 448 |
+
- Visual organization with bullet points
|
| 449 |
+
- Practical applications and use cases
|
| 450 |
+
|
| 451 |
+
Thanks for your help! Here's what I'd tell the student:"""
|
| 452 |
|
| 453 |
self.answer_prompt = PromptTemplate(
|
| 454 |
input_variables=["question", "slide_content"],
|
|
|
|
| 577 |
# Get LLM's answer
|
| 578 |
response = self.anthropic_client.messages.create(
|
| 579 |
model="claude-3-5-haiku-20241022",
|
| 580 |
+
max_tokens=2000,
|
| 581 |
temperature=0.7,
|
| 582 |
messages=[{"role": "user", "content": prompt}]
|
| 583 |
)
|
|
|
|
| 658 |
return terminal_output, analysis
|
| 659 |
|
| 660 |
def extract_topic_from_query(query):
|
| 661 |
+
"""Extract topic from chat query for practice using LLM"""
|
| 662 |
+
try:
|
| 663 |
+
# Use LLM for better topic extraction
|
| 664 |
+
prompt = f"""Extract the main programming topic from this student question.
|
| 665 |
+
Return ONLY the topic name, nothing else.
|
| 666 |
+
|
| 667 |
+
Question: "{query}"
|
| 668 |
+
|
| 669 |
+
Examples:
|
| 670 |
+
- "What are for loops?" β "for loops"
|
| 671 |
+
- "How do variables work in Python?" β "variables"
|
| 672 |
+
- "Can you explain functions?" β "functions"
|
| 673 |
+
- "What's the difference between lists and arrays?" β "lists and arrays"
|
| 674 |
+
- "How do I debug my code?" β "debugging"
|
| 675 |
+
|
| 676 |
+
Topic:"""
|
| 677 |
+
|
| 678 |
+
response = practice_assistant.anthropic_client.messages.create(
|
| 679 |
+
model="claude-3-5-haiku-20241022",
|
| 680 |
+
max_tokens=100,
|
| 681 |
+
temperature=0.1,
|
| 682 |
+
messages=[{"role": "user", "content": prompt}]
|
| 683 |
+
)
|
| 684 |
+
|
| 685 |
+
topic = response.content[0].text.strip()
|
| 686 |
+
return topic if topic else "programming basics"
|
| 687 |
+
|
| 688 |
+
except Exception as e:
|
| 689 |
+
print(f"Error in LLM topic extraction: {e}")
|
| 690 |
+
# Fallback to simple extraction
|
| 691 |
+
common_topics = ["for loops", "while loops", "functions", "variables", "arrays", "recursion", "debugging", "lists", "dictionaries", "classes", "objects", "strings", "file handling", "error handling", "modules", "packages"]
|
| 692 |
+
query_lower = query.lower()
|
| 693 |
+
|
| 694 |
+
for topic in common_topics:
|
| 695 |
+
if topic in query_lower:
|
| 696 |
+
return topic
|
| 697 |
+
|
| 698 |
+
return "programming basics" # Default topic
|
| 699 |
|
| 700 |
+
def generate_practice_for_topic(query):
|
| 701 |
+
"""Generate practice problem and return with navigation message"""
|
| 702 |
topic = extract_topic_from_query(query)
|
|
|
|
| 703 |
problem, code = practice_assistant.generate_practice_problem(topic, "Create Practice Problems")
|
| 704 |
+
|
| 705 |
+
# Create a message to guide user to practice tab
|
| 706 |
+
navigation_message = f"""
|
| 707 |
+
π― **Practice Problem Generated!**
|
| 708 |
+
|
| 709 |
+
I've created a practice problem for **{topic}** and loaded it into the Code Practice tab.
|
| 710 |
+
|
| 711 |
+
**To continue practicing:**
|
| 712 |
+
1. Click on the **"π» Code Practice"** tab above
|
| 713 |
+
2. You'll see the topic and problem already filled in
|
| 714 |
+
3. Write your solution and click "Analyze My Code"
|
| 715 |
+
|
| 716 |
+
**Topic:** {topic}
|
| 717 |
+
**Problem Type:** Create Practice Problems
|
| 718 |
+
|
| 719 |
+
Ready to practice? Switch to the Code Practice tab! π
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 720 |
"""
|
| 721 |
+
|
| 722 |
+
return navigation_message, topic, problem, code
|
| 723 |
+
|
| 724 |
+
|
| 725 |
+
|
| 726 |
+
with gr.Blocks(title="LLM Curriculum Assistant", theme=gr.themes.Soft()) as demo:
|
| 727 |
+
gr.Markdown("# π€ LLM Curriculum Assistant\nYour AI programming tutor with LLM-powered content selection and code practice!")
|
| 728 |
+
|
| 729 |
|
|
|
|
|
|
|
| 730 |
|
| 731 |
with gr.Tabs() as tabs:
|
| 732 |
# Tab 1: Chat Assistant
|
|
|
|
| 743 |
lines=3
|
| 744 |
)
|
| 745 |
submit = gr.Button("π€ Ask AI", variant="primary", size="lg")
|
| 746 |
+
answer = gr.Markdown(label="LLM Generated Answer")
|
| 747 |
|
| 748 |
# Practice button
|
| 749 |
practice_btn = gr.Button("π» Practice This Topic", variant="secondary", size="lg", visible=False)
|
|
|
|
| 802 |
generate_btn = gr.Button("π² Generate Problem", variant="primary", size="lg")
|
| 803 |
|
| 804 |
gr.Markdown("#### π Problem Description")
|
| 805 |
+
problem_description = gr.Markdown(label="Problem will appear here...")
|
| 806 |
|
| 807 |
gr.Markdown("#### π» Starter Code (if applicable)")
|
| 808 |
starter_code = gr.Code(
|
|
|
|
| 830 |
label="Terminal Output",
|
| 831 |
lines=8,
|
| 832 |
value="# Code execution output will appear here...",
|
| 833 |
+
interactive=False
|
|
|
|
| 834 |
)
|
| 835 |
|
| 836 |
gr.Markdown("#### π AI Analysis")
|
| 837 |
+
analysis_output = gr.Markdown(label="Analysis will appear here...")
|
| 838 |
|
| 839 |
# Event handlers for practice
|
| 840 |
generate_btn.click(
|
|
|
|
| 849 |
outputs=[terminal_output, analysis_output]
|
| 850 |
)
|
| 851 |
|
| 852 |
+
# Practice button - generate problem and show navigation message
|
|
|
|
|
|
|
|
|
|
|
|
|
| 853 |
practice_btn.click(
|
| 854 |
+
fn=generate_practice_for_topic,
|
| 855 |
inputs=[question],
|
| 856 |
+
outputs=[answer, topic_input, problem_description, starter_code]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 857 |
)
|
| 858 |
|
| 859 |
if __name__ == "__main__":
|
| 860 |
+
demo.launch()
|