Update llm_app_enhanced.py

#2
by SreekarB - opened
Files changed (1) hide show
  1. 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
- prompt = f"""Create a programming practice problem for a student learning {topic}.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  Problem Type: {problem_types.get(internal_type, internal_type)}
 
 
 
76
 
77
  Requirements:
78
- - Make it appropriate for beginners to intermediate level
79
- - Include clear instructions that guide the student
80
- - Provide a specific, focused problem that requires thinking
81
- - If it's a debug problem, include the buggy code
82
- - If it's an optimization problem, provide the original code
83
- - Make it engaging and educational
84
- - DO NOT give away the solution or complete answer in the problem statement
85
- - Focus on what they need to accomplish, not how to do it
 
86
 
87
  Format your response as:
88
- PROBLEM: [The problem description and requirements]
89
- CODE: [Any starter code if applicable, or "Write your code here:"]
90
-
91
- IMPORTANT: If you include example outputs, format them as code blocks like this:
92
- ```
93
- Example Output:
94
- 1
95
- 1 2
96
- 1 2 3
97
- 1 2 3 4
98
- 1 2 3 4 5
99
- ```
100
-
101
- Keep it concise but clear."""
102
  else:
103
- # Use curriculum-based prompt
104
- prompt = f"""Create a programming practice problem for a student learning {topic}.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- - If it's a debug problem, include the buggy code
118
- - If it's an optimization problem, provide the original code
119
- - Make it engaging and educational
120
- - DO NOT give away the solution or complete answer in the problem statement
121
- - Focus on what they need to accomplish, not how to do it
122
- - Guide them to think through the problem themselves
 
123
 
124
  Format your response as:
125
- PROBLEM: [The problem description and requirements]
126
- CODE: [Any starter code if applicable, or "Write your code here:"]
127
 
128
- IMPORTANT: If you include example outputs, format them as code blocks like this:
129
- ```
130
- Example Output:
131
- 1
132
- 1 2
133
- 1 2 3
134
- 1 2 3 4
135
- 1 2 3 4 5
136
- ```
137
 
138
- Keep it concise but clear and aligned with the curriculum difficulty."""
139
 
140
  try:
141
  response = self.anthropic_client.messages.create(
142
  model="claude-3-5-haiku-20241022",
143
  max_tokens=1000,
144
- temperature=0.7,
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 step-by-step tutoring feedback"""
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 based on curriculum)
251
  3. **Step-by-Step Solution** (guide them through the process, don't give complete code)
252
- 4. **Key Takeaway** (1 sentence about the concept)
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=800,
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 = """You are a helpful programming tutor. The student asked:
389
  "{question}"
390
  Here's what the curriculum slide says about it:
391
  {slide_content}
392
-
393
- Provide a CONCISE, friendly explanation (2-3 sentences max):
394
- - Answer their specific question
395
- - Use simple, clear language
396
- - Reference the curriculum content
397
- - End with a helpful tip or suggestion
398
-
399
- Keep it brief and encouraging!"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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=800,
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
- # Simple topic extraction - could be improved with LLM
611
- common_topics = ["for loops", "while loops", "functions", "variables", "arrays", "recursion", "debugging", "lists", "dictionaries", "classes", "objects"]
612
- query_lower = query.lower()
613
-
614
- for topic in common_topics:
615
- if topic in query_lower:
616
- return topic
617
-
618
- return "programming basics" # Default topic
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
619
 
620
- def go_to_practice(query):
621
- """Generate practice problem and return topic for navigation"""
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
- return topic, problem, code
626
-
627
- # Custom CSS for better accessibility and styling
628
- custom_css = """
629
- .gradio-container {
630
- font-size: 16px !important;
631
- }
632
- .markdown-text {
633
- font-size: 18px !important;
634
- line-height: 1.6 !important;
635
- }
636
- .problem-description {
637
- font-size: 18px !important;
638
- font-weight: bold !important;
639
- }
640
- .requirements {
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", elem_classes=["markdown-text"])
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...", elem_classes=["problem-description"])
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...", elem_classes=["markdown-text"])
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 from chat - populate topic and generate problem
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=practice_with_navigation,
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()