Dannyar608 commited on
Commit
6f8fb84
·
verified ·
1 Parent(s): 431b892

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +211 -663
app.py CHANGED
@@ -3,28 +3,27 @@ import pandas as pd
3
  import json
4
  import os
5
  import re
6
- import hashlib
7
- from datetime import datetime
8
  from PyPDF2 import PdfReader
9
  from collections import defaultdict
10
- from transformers import pipeline
11
- from typing import Dict, List, Optional
12
 
13
- # Initialize NER model (will load only if transformers is available)
14
  try:
 
15
  ner_pipeline = pipeline("ner", model="dslim/bert-base-NER")
 
 
 
16
  except Exception as e:
17
- print(f"Could not load NER model: {e}")
18
  ner_pipeline = None
 
19
 
20
- # ========== IMPROVED TRANSCRIPT PARSING ==========
21
- def extract_gpa(text: str, gpa_type: str) -> str:
22
  pattern = rf'{gpa_type}\s*([\d\.]+)'
23
  match = re.search(pattern, text)
24
  return match.group(1) if match else "N/A"
25
 
26
- def extract_courses_from_table(text: str) -> Dict[str, List[Dict]]:
27
- # This pattern matches the course table rows in the transcript
28
  course_pattern = re.compile(
29
  r'(\d{4}-\d{4})\s*' # School year
30
  r'\|?\s*(\d+)\s*' # Grade level
@@ -41,7 +40,6 @@ def extract_courses_from_table(text: str) -> Dict[str, List[Dict]]:
41
  for match in re.finditer(course_pattern, text):
42
  year_range, grade_level, course_code, course_name, grade, credits = match.groups()
43
 
44
- # Clean up course name
45
  course_name = course_name.strip()
46
  if 'DE:' in course_name:
47
  course_name = course_name.replace('DE:', 'Dual Enrollment:')
@@ -61,56 +59,48 @@ def extract_courses_from_table(text: str) -> Dict[str, List[Dict]]:
61
 
62
  return courses_by_grade
63
 
64
- def parse_transcript(file) -> tuple:
65
- try:
66
- if file.name.endswith('.pdf'):
67
- text = ''
68
- reader = PdfReader(file)
69
- for page in reader.pages:
70
- text += page.extract_text() + '\n'
71
-
72
- # Extract GPA information
73
- gpa_data = {
74
- 'weighted': extract_gpa(text, 'Weighted GPA'),
75
- 'unweighted': extract_gpa(text, 'Un-weighted GPA')
76
- }
77
-
78
- # Extract current grade level
79
- grade_match = re.search(r'Current Grade:\s*(\d+)', text)
80
- grade_level = grade_match.group(1) if grade_match else "Unknown"
81
-
82
- # Extract all courses with grades and year taken
83
- courses_by_grade = extract_courses_from_table(text)
84
-
85
- # Prepare detailed output
86
- output_text = f"Student Transcript Summary\n{'='*40}\n"
87
- output_text += f"Current Grade Level: {grade_level}\n"
88
- output_text += f"Weighted GPA: {gpa_data['weighted']}\n"
89
- output_text += f"Unweighted GPA: {gpa_data['unweighted']}\n\n"
90
- output_text += "Course History:\n{'='*40}\n"
91
-
92
- # Sort grades numerically (09, 10, 11, 12)
93
- for grade in sorted(courses_by_grade.keys(), key=int):
94
- output_text += f"\nGrade {grade}:\n{'-'*30}\n"
95
- for course in courses_by_grade[grade]:
96
- output_text += f"- {course['name']}"
97
- if 'grade' in course and course['grade']:
98
- output_text += f" (Grade: {course['grade']})"
99
- if 'credits' in course:
100
- output_text += f" | Credits: {course['credits']}"
101
- output_text += f" | Year: {course['year']}\n"
102
-
103
- return output_text, {
104
- "gpa": gpa_data,
105
- "grade_level": grade_level,
106
- "courses": dict(courses_by_grade)
107
- }
108
- else:
109
- return "Unsupported file format (PDF only for transcript parsing)", None
110
- except Exception as e:
111
- return f"Error processing transcript: {str(e)}", None
112
 
113
- # ========== ENHANCED LEARNING STYLE QUIZ ==========
114
  learning_style_questions = [
115
  "When you study for a test, you prefer to:",
116
  "When you need directions to a new place, you prefer:",
@@ -157,7 +147,7 @@ learning_style_options = [
157
  ["Write out possible solutions (Reading/Writing)", "Talk through it with someone (Auditory)", "Draw diagrams (Visual)", "Build a model or prototype (Kinesthetic)"]
158
  ]
159
 
160
- def learning_style_quiz(*answers) -> str:
161
  scores = {
162
  "Visual": 0,
163
  "Auditory": 0,
@@ -178,157 +168,99 @@ def learning_style_quiz(*answers) -> str:
178
  max_score = max(scores.values())
179
  total_questions = len(learning_style_questions)
180
 
181
- # Calculate percentages
182
  percentages = {style: (score/total_questions)*100 for style, score in scores.items()}
183
 
184
- # Sort styles by score (descending)
185
  sorted_styles = sorted(scores.items(), key=lambda x: x[1], reverse=True)
186
 
187
- # Prepare detailed results
188
  result = "Your Learning Style Results:\n\n"
189
  for style, score in sorted_styles:
190
  result += f"{style}: {score}/{total_questions} ({percentages[style]:.1f}%)\n"
191
 
192
  result += "\n"
193
 
194
- # Determine primary and secondary styles
195
  primary_styles = [style for style, score in scores.items() if score == max_score]
196
 
197
  if len(primary_styles) == 1:
198
  result += f"Your primary learning style is: {primary_styles[0]}\n\n"
199
- # Add personalized tips based on primary style
200
  if primary_styles[0] == "Visual":
201
  result += "Tips for Visual Learners:\n"
202
  result += "- Use color coding in your notes\n"
203
  result += "- Create mind maps and diagrams\n"
204
  result += "- Watch educational videos\n"
205
  result += "- Use flashcards with images\n"
206
- result += "- Highlight key information in different colors\n"
207
  elif primary_styles[0] == "Auditory":
208
  result += "Tips for Auditory Learners:\n"
209
  result += "- Record lectures and listen to them\n"
210
  result += "- Participate in study groups\n"
211
  result += "- Explain concepts out loud to yourself\n"
212
  result += "- Use rhymes or songs to remember information\n"
213
- result += "- Listen to educational podcasts\n"
214
  elif primary_styles[0] == "Reading/Writing":
215
  result += "Tips for Reading/Writing Learners:\n"
216
  result += "- Write detailed notes\n"
217
  result += "- Create summaries in your own words\n"
218
  result += "- Read textbooks and articles\n"
219
  result += "- Make lists to organize information\n"
220
- result += "- Rewrite your notes to reinforce learning\n"
221
- else: # Kinesthetic
222
  result += "Tips for Kinesthetic Learners:\n"
223
  result += "- Use hands-on activities\n"
224
  result += "- Take frequent movement breaks\n"
225
  result += "- Create physical models\n"
226
  result += "- Associate information with physical actions\n"
227
- result += "- Study while walking or using a standing desk\n"
228
  else:
229
  result += f"You have multiple strong learning styles: {', '.join(primary_styles)}\n\n"
230
- result += "You may benefit from combining different learning approaches:\n"
231
- if "Visual" in primary_styles:
232
- result += "- Create visual representations of what you're learning\n"
233
- if "Auditory" in primary_styles:
234
- result += "- Discuss concepts with others or record yourself explaining them\n"
235
- if "Reading/Writing" in primary_styles:
236
- result += "- Write summaries and read additional materials\n"
237
- if "Kinesthetic" in primary_styles:
238
- result += "- Incorporate physical movement into your study sessions\n"
239
-
240
- # Add general study tips
241
- result += "\nAdditional Study Tips for All Learners:\n"
242
- result += "- Use the Pomodoro technique (25 min study, 5 min break)\n"
243
- result += "- Teach concepts to someone else to reinforce your understanding\n"
244
- result += "- Connect new information to what you already know\n"
245
- result += "- Get adequate sleep to consolidate memories\n"
246
 
247
  return result
248
 
249
- # ========== ENHANCED STUDENT PROFILE SYSTEM ==========
250
- def hash_sensitive_data(data: str) -> str:
251
- """Hash sensitive data for privacy protection"""
252
- return hashlib.sha256(data.encode()).hexdigest()
253
-
254
- def get_profile_list() -> List[str]:
255
- """Get list of available profiles"""
256
- if not os.path.exists("student_profiles"):
257
- return []
258
- return [f.replace("_profile.json", "").replace("_", " ")
259
- for f in os.listdir("student_profiles")
260
- if f.endswith('_profile.json')]
261
-
262
- def save_profile(name: str, age: int, interests: str, transcript: dict, learning_style: str,
263
- movie: str, movie_reason: str, show: str, show_reason: str,
264
- book: str, book_reason: str, character: str, character_reason: str,
265
- blog: str, goals: str, study_preferences: str) -> str:
266
- """Save student profile with enhanced features"""
267
- # Convert age to int if it's a numpy number (from gradio Number input)
268
  age = int(age) if age else 0
269
 
270
- # Create profile dictionary
271
- profile_data = {
 
 
 
 
 
 
 
 
 
 
272
  "name": name,
273
  "age": age,
274
  "interests": interests,
275
  "transcript": transcript,
276
  "learning_style": learning_style,
277
- "favorites": {
278
- "movie": movie,
279
- "movie_reason": movie_reason,
280
- "show": show,
281
- "show_reason": show_reason,
282
- "book": book,
283
- "book_reason": book_reason,
284
- "character": character,
285
- "character_reason": character_reason
286
- },
287
- "blog": blog,
288
- "goals": goals,
289
- "study_preferences": study_preferences,
290
- "last_updated": datetime.now().isoformat(),
291
- "security": {
292
- "name_hash": hash_sensitive_data(name),
293
- "interests_hash": hash_sensitive_data(interests)
294
- }
295
  }
296
 
297
- # Save to file
298
  os.makedirs("student_profiles", exist_ok=True)
299
- filename = f"{name.replace(' ', '_')}_profile.json"
300
- filepath = os.path.join("student_profiles", filename)
301
-
302
- with open(filepath, "w") as f:
303
- json.dump(profile_data, f, indent=2)
304
-
305
- return f"Profile saved successfully as {filename}"
306
 
307
- def load_profile(profile_name: str = None) -> Optional[Dict]:
308
- """Load student profile with error handling"""
309
- if not os.path.exists("student_profiles"):
310
- return None
311
-
312
- if profile_name is None:
313
- # Load the first profile if none specified
314
- files = [f for f in os.listdir("student_profiles") if f.endswith('.json')]
315
- if not files:
316
- return None
317
- filepath = os.path.join("student_profiles", files[0])
318
- else:
319
- # Load specific profile
320
- filename = f"{profile_name.replace(' ', '_')}_profile.json"
321
- filepath = os.path.join("student_profiles", filename)
322
-
323
- try:
324
- with open(filepath, "r") as f:
325
- return json.load(f)
326
- except (FileNotFoundError, json.JSONDecodeError) as e:
327
- print(f"Error loading profile: {e}")
328
- return None
329
 
330
- def transcript_display(transcript_dict: dict) -> str:
331
- """Format transcript data for display"""
332
  if not transcript_dict or "courses" not in transcript_dict:
333
  return "No course information available"
334
 
@@ -336,7 +268,6 @@ def transcript_display(transcript_dict: dict) -> str:
336
  courses_by_grade = transcript_dict["courses"]
337
 
338
  if isinstance(courses_by_grade, dict):
339
- # Sort grades numerically
340
  for grade in sorted(courses_by_grade.keys(), key=int):
341
  display += f"\n**Grade {grade}**\n"
342
  for course in courses_by_grade[grade]:
@@ -355,549 +286,166 @@ def transcript_display(transcript_dict: dict) -> str:
355
 
356
  return display
357
 
358
- def generate_profile_summary(profile: dict) -> str:
359
- """Generate markdown summary of profile"""
 
 
 
 
 
 
 
 
 
360
  if not profile:
361
- return "No profile data available"
362
 
363
- name = profile.get("name", "Unknown")
364
- age = profile.get("age", "Unknown")
365
- interests = profile.get("interests", "Not specified")
366
- learning_style = profile.get("learning_style", "Not determined")
367
- favorites = profile.get("favorites", {})
368
- blog = profile.get("blog", "")
369
- goals = profile.get("goals", "")
370
- study_preferences = profile.get("study_preferences", "")
371
 
372
- markdown = f"""## Student Profile: {name}
373
- **Age:** {age}
374
- **Interests:** {interests}
375
- **Learning Style:** {learning_style}
376
-
377
- ### Academic Information
378
- {transcript_display(profile.get("transcript", {}))}
379
-
380
- ### Goals
381
- {goals if goals else "_No goals specified_"}
382
-
383
- ### Study Preferences
384
- {study_preferences if study_preferences else "_No study preferences specified_"}
385
-
386
- ### Favorites
387
- - **Movie:** {favorites.get('movie', 'Not specified')} ({favorites.get('movie_reason', 'No reason given')})
388
- - **TV Show:** {favorites.get('show', 'Not specified')} ({favorites.get('show_reason', 'No reason given')})
389
- - **Book:** {favorites.get('book', 'Not specified')} ({favorites.get('book_reason', 'No reason given')})
390
- - **Character:** {favorites.get('character', 'Not specified')} ({favorites.get('character_reason', 'No reason given')})
391
-
392
- ### Personal Blog
393
- {blog if blog else "_No blog provided_"}
394
- """
395
- return markdown
396
-
397
- # ========== ENHANCED AI TEACHING ASSISTANT ==========
398
- class TeachingAssistant:
399
- def __init__(self):
400
- self.conversation_history = []
401
- self.current_profile = None
402
 
403
- def load_profile(self, profile_name: str = None) -> bool:
404
- """Load a student profile"""
405
- self.current_profile = load_profile(profile_name)
406
- if self.current_profile:
407
- self.conversation_history.append(
408
- (f"System: Loaded profile for {self.current_profile.get('name', 'unknown student')}", None)
409
- )
410
- return True
411
- return False
412
-
413
- def generate_response(self, message: str, history: List[tuple]) -> str:
414
- """Generate response based on message and history"""
415
- # Add to conversation history
416
- self.conversation_history.append((f"Student: {message}", None))
417
-
418
- if not self.current_profile:
419
- return "Please complete and save your profile first using the previous tabs."
420
-
421
- # Get profile data
422
- name = self.current_profile.get("name", "")
423
- learning_style = self.current_profile.get("learning_style", "")
424
- grade_level = self.current_profile.get("transcript", {}).get("grade_level", "unknown")
425
- gpa = self.current_profile.get("transcript", {}).get("gpa", {})
426
- interests = self.current_profile.get("interests", "")
427
- courses = self.current_profile.get("transcript", {}).get("courses", {})
428
- goals = self.current_profile.get("goals", "")
429
- study_preferences = self.current_profile.get("study_preferences", "")
430
-
431
- # Contextual understanding
432
- message_lower = message.lower()
433
-
434
- # Greetings
435
- if any(greet in message_lower for greet in ["hi", "hello", "hey"]):
436
- return f"Hello {name}! How can I help you with your learning today?"
437
-
438
- # Study help
439
- elif any(word in message_lower for word in ["study", "learn", "prepare", "exam"]):
440
- return self._generate_study_tips(learning_style, courses, study_preferences)
441
-
442
- # Grade help
443
- elif any(word in message_lower for word in ["grade", "gpa", "score"]):
444
- return self._generate_grade_info(gpa, grade_level)
445
-
446
- # Course help
447
- elif any(word in message_lower for word in ["course", "class", "schedule", "transcript"]):
448
- return self._generate_course_info(courses)
449
-
450
- # Goal tracking
451
- elif any(word in message_lower for word in ["goal", "target", "objective"]):
452
- return self._handle_goals(message, goals)
453
-
454
- # Resource recommendations
455
- elif any(word in message_lower for word in ["resource", "material", "book", "video"]):
456
- return self._recommend_resources(interests, learning_style)
457
-
458
- # General help
459
- elif "help" in message_lower:
460
- return self._generate_help_message()
461
-
462
- # Unknown query
463
- else:
464
- return ("I'm your personalized teaching assistant. I can help with:\n"
465
- "- Study strategies based on your learning style\n"
466
- "- Academic performance analysis\n"
467
- "- Course planning and recommendations\n"
468
- "- Goal setting and tracking\n\n"
469
- "Try asking about how to study for your classes or about your academic progress!")
470
 
471
- def _generate_study_tips(self, learning_style: str, courses: dict, study_preferences: str) -> str:
472
- """Generate personalized study tips"""
473
- response = "Here are personalized study recommendations:\n\n"
474
-
475
- # Learning style based tips
476
  if "Visual" in learning_style:
477
- response += ("**Visual Learner Tips:**\n"
478
- "- Create colorful mind maps\n"
479
- "- Use diagrams and charts\n"
480
- "- Watch educational videos\n"
481
- "- Highlight key information\n\n")
482
- if "Auditory" in learning_style:
483
- response += ("**Auditory Learner Tips:**\n"
484
- "- Record and listen to lectures\n"
485
- "- Participate in study groups\n"
486
- "- Explain concepts out loud\n"
487
- "- Use mnemonic devices\n\n")
488
- if "Reading/Writing" in learning_style:
489
- response += ("**Reading/Writing Learner Tips:**\n"
490
- "- Write detailed notes\n"
491
- "- Create summaries\n"
492
- "- Read additional materials\n"
493
- "- Make lists and outlines\n\n")
494
- if "Kinesthetic" in learning_style:
495
- response += ("**Kinesthetic Learner Tips:**\n"
496
- "- Use hands-on activities\n"
497
- "- Take movement breaks\n"
498
- "- Create physical models\n"
499
- "- Study while walking\n\n")
500
-
501
- # Course-specific tips
502
- if courses:
503
- response += "\n**Course-Specific Suggestions:**\n"
504
- for grade, course_list in courses.items():
505
- for course in course_list:
506
- course_name = course.get('name', '')
507
- if 'math' in course_name.lower():
508
- response += f"- For {course_name}: Practice problems daily\n"
509
- elif 'science' in course_name.lower():
510
- response += f"- For {course_name}: Focus on concepts and applications\n"
511
- elif 'history' in course_name.lower():
512
- response += f"- For {course_name}: Create timelines and context maps\n"
513
- elif 'english' in course_name.lower():
514
- response += f"- For {course_name}: Read actively and annotate texts\n"
515
-
516
- # Study preferences
517
- if study_preferences:
518
- response += f"\n**Your Study Preferences:**\n{study_preferences}\n"
519
-
520
- # General tips
521
- response += ("\n**General Study Strategies:**\n"
522
- "- Use the Pomodoro technique (25 min study, 5 min break)\n"
523
- "- Space out your study sessions\n"
524
- "- Test yourself regularly\n"
525
- "- Teach concepts to someone else\n")
526
-
527
- return response
528
-
529
- def _generate_grade_info(self, gpa: dict, grade_level: str) -> str:
530
- """Generate grade information response"""
531
- response = (f"Your Academic Performance Summary:\n"
532
- f"- Current Grade Level: {grade_level}\n"
533
- f"- Unweighted GPA: {gpa.get('unweighted', 'N/A')}\n"
534
- f"- Weighted GPA: {gpa.get('weighted', 'N/A')}\n\n")
535
-
536
- # Add improvement suggestions
537
- unweighted = float(gpa.get('unweighted', 0)) if gpa.get('unweighted', 'N/A') != 'N/A' else 0
538
- if unweighted < 2.0:
539
- response += ("**Recommendations for Improvement:**\n"
540
- "- Meet with teachers to identify weak areas\n"
541
- "- Establish a regular study schedule\n"
542
- "- Focus on foundational concepts\n")
543
- elif unweighted < 3.0:
544
- response += ("**Recommendations for Enhancement:**\n"
545
- "- Identify your strongest subjects to build confidence\n"
546
- "- Set specific grade improvement goals\n"
547
- "- Develop better study habits\n")
548
- elif unweighted < 3.5:
549
- response += ("**Recommendations for Advancement:**\n"
550
- "- Challenge yourself with honors/AP courses\n"
551
- "- Develop deeper understanding in your strongest areas\n"
552
- "- Focus on consistent performance\n")
553
  else:
554
- response += ("**Recommendations for Excellence:**\n"
555
- "- Pursue advanced coursework\n"
556
- "- Develop independent research projects\n"
557
- "- Mentor other students to reinforce your knowledge\n")
558
 
559
  return response
560
 
561
- def _generate_course_info(self, courses: dict) -> str:
562
- """Generate course information response"""
563
- if not courses:
564
- return "No course information available in your profile."
565
-
566
- response = "Your Course History:\n"
 
 
 
 
 
 
 
 
 
 
 
567
  for grade in sorted(courses.keys(), key=int):
568
- response += f"\n**Grade {grade}:**\n"
569
  for course in courses[grade]:
570
- response += f"- {course.get('name', 'Unknown')}"
571
  if 'grade' in course:
572
- response += f" (Grade: {course.get('grade', '')})"
573
  response += "\n"
574
-
575
- # Add recommendations
576
- response += "\n**Course Recommendations:**\n"
577
- highest_grade = max(courses.keys(), key=int) if courses else "0"
578
-
579
- if highest_grade == "09":
580
- response += "- Consider exploring different subjects to find your interests\n"
581
- response += "- Build strong foundational skills in math and language arts\n"
582
- elif highest_grade == "10":
583
- response += "- Start focusing on your academic strengths\n"
584
- response += "- Consider honors or AP courses in your strong subjects\n"
585
- elif highest_grade == "11":
586
- response += "- Focus on college preparatory courses\n"
587
- response += "- Consider AP or dual enrollment courses\n"
588
- elif highest_grade == "12":
589
- response += "- Complete any remaining graduation requirements\n"
590
- response += "- Consider advanced courses in your intended major\n"
591
-
592
  return response
593
 
594
- def _handle_goals(self, message: str, current_goals: str) -> str:
595
- """Handle goal-related queries"""
596
- if "set" in message.lower() or "new" in message.lower():
597
- return ("To set new goals, please update your profile with your academic goals. "
598
- "You can include:\n"
599
- "- Short-term goals (weekly/monthly)\n"
600
- "- Long-term goals (semester/yearly)\n"
601
- "- Career or college preparation goals\n")
602
- elif current_goals:
603
- return f"Your current goals:\n{current_goals}\n\nWould you like to update them?"
604
- else:
605
- return ("You haven't set any goals yet. Setting clear academic goals can help you "
606
- "stay focused and motivated. Would you like to set some goals now?")
607
 
608
- def _recommend_resources(self, interests: str, learning_style: str) -> str:
609
- """Recommend learning resources"""
610
- response = "Based on your profile, here are some resource recommendations:\n\n"
611
-
612
- # Interest-based recommendations
613
- if "science" in interests.lower():
614
- response += ("**Science Resources:**\n"
615
- "- Khan Academy Science courses\n"
616
- "- Crash Course YouTube channel\n"
617
- "- Science Journal app for experiments\n\n")
618
- if "math" in interests.lower():
619
- response += ("**Math Resources:**\n"
620
- "- Brilliant.org interactive math\n"
621
- "- 3Blue1Brown YouTube channel\n"
622
- "- Wolfram Alpha for problem solving\n\n")
623
- if "history" in interests.lower():
624
- response += ("**History Resources:**\n"
625
- "- Hardcore History podcast\n"
626
- "- Timeline apps for historical events\n"
627
- "- Historical fiction books\n\n")
628
- if "art" in interests.lower() or "music" in interests.lower():
629
- response += ("**Arts Resources:**\n"
630
- "- Skillshare art classes\n"
631
- "- Google Arts & Culture app\n"
632
- "- Local museum virtual tours\n\n")
633
-
634
- # Learning style based recommendations
635
- if "Visual" in learning_style:
636
- response += ("**Visual Learning Resources:**\n"
637
- "- MindMeister for mind mapping\n"
638
- "- Canva for creating visual notes\n"
639
- "- YouTube educational channels\n\n")
640
- if "Auditory" in learning_style:
641
- response += ("**Auditory Learning Resources:**\n"
642
- "- Audible for audiobooks\n"
643
- "- Podcasts like TED Talks Education\n"
644
- "- Text-to-speech tools\n\n")
645
- if "Reading/Writing" in learning_style:
646
- response += ("**Reading/Writing Resources:**\n"
647
- "- Evernote for note-taking\n"
648
- "- Project Gutenberg for free books\n"
649
- "- Grammarly for writing help\n\n")
650
- if "Kinesthetic" in learning_style:
651
- response += ("**Kinesthetic Learning Resources:**\n"
652
- "- Labster virtual labs\n"
653
- "- DIY science experiment kits\n"
654
- "- Standing desk or exercise ball chair\n\n")
655
-
656
- return response
657
-
658
- def _generate_help_message(self) -> str:
659
- """Generate help message with capabilities"""
660
- return ("""I can help you with:
661
- 1. **Study Strategies** - Get personalized study tips based on your learning style
662
- 2. **Academic Performance** - Check your GPA and get improvement suggestions
663
- 3. **Course Planning** - View your course history and get recommendations
664
- 4. **Goal Setting** - Set and track your academic goals
665
- 5. **Resource Recommendations** - Get suggested learning materials
666
-
667
- Try asking:
668
- - "How should I study for my math class?"
669
- - "What's my current GPA?"
670
- - "What courses should I take next year?"
671
- - "Can you recommend some science resources?"
672
- - "Help me set some academic goals"
673
- """)
674
-
675
- # Initialize teaching assistant
676
- assistant = TeachingAssistant()
677
 
678
  # ========== GRADIO INTERFACE ==========
679
- with gr.Blocks(title="Personalized Learning Assistant", theme=gr.themes.Soft()) as app:
680
- gr.Markdown("# 🎓 Personalized Learning Assistant")
681
- gr.Markdown("This tool helps students understand their learning style, track academic progress, and get personalized study recommendations.")
682
-
683
- with gr.Tab("📄 Step 1: Upload Transcript"):
684
- gr.Markdown("### Upload your academic transcript")
685
- gr.Markdown("For best results, upload a PDF of your official transcript.")
686
- with gr.Row():
687
- with gr.Column():
688
- transcript_file = gr.File(
689
- label="Transcript file",
690
- file_types=[".pdf"],
691
- info="PDF format recommended"
692
- )
693
- clear_btn = gr.Button("Clear")
694
- with gr.Column():
695
- transcript_output = gr.Textbox(
696
- label="Transcript Results",
697
- lines=20,
698
- interactive=False
699
- )
700
- transcript_data = gr.State()
701
-
702
  transcript_file.change(
703
  fn=parse_transcript,
704
  inputs=transcript_file,
705
  outputs=[transcript_output, transcript_data]
706
  )
707
- clear_btn.click(
708
- lambda: [None, "", None],
709
- outputs=[transcript_file, transcript_output, transcript_data]
710
- )
711
-
712
- with gr.Tab("📝 Step 2: Learning Style Quiz"):
713
- gr.Markdown("### Discover Your Learning Style")
714
- gr.Markdown("Complete this 20-question quiz to understand how you learn best.")
715
-
716
- with gr.Accordion("About Learning Styles", open=False):
717
- gr.Markdown("""
718
- **Visual Learners** prefer using images, diagrams, and spatial understanding.
719
- **Auditory Learners** learn best through listening and speaking.
720
- **Reading/Writing Learners** prefer information displayed as words.
721
- **Kinesthetic Learners** learn through movement and hands-on activities.
722
- """)
723
-
724
  quiz_components = []
725
- with gr.Column():
726
- for i, (question, options) in enumerate(zip(learning_style_questions, learning_style_options)):
727
- quiz_components.append(
728
- gr.Radio(
729
- options,
730
- label=f"{i+1}. {question}",
731
- interactive=True
732
- )
733
- )
734
-
735
- with gr.Row():
736
- submit_quiz = gr.Button("Submit Quiz", variant="primary")
737
- reset_quiz = gr.Button("Reset Quiz")
738
-
739
- learning_output = gr.Textbox(
740
- label="Your Learning Style Results",
741
- lines=15,
742
- interactive=False
743
- )
744
 
745
- submit_quiz.click(
 
746
  fn=learning_style_quiz,
747
  inputs=quiz_components,
748
  outputs=learning_output
749
  )
750
- reset_quiz.click(
751
- lambda: [None]*len(quiz_components),
752
- outputs=quiz_components
753
- )
754
-
755
- with gr.Tab("👤 Step 3: Personal Profile"):
756
- gr.Markdown("### Create Your Personal Profile")
757
- gr.Markdown("This information helps personalize your learning experience.")
758
-
759
- with gr.Row():
760
- with gr.Column():
761
- name = gr.Textbox(label="Full Name", placeholder="Enter your name")
762
- age = gr.Number(label="Age", precision=0, minimum=10, maximum=25)
763
- interests = gr.Textbox(
764
- label="Interests/Hobbies",
765
- placeholder="e.g., Science, Music, Sports"
766
- )
767
- goals = gr.Textbox(
768
- label="Academic Goals",
769
- placeholder="What do you want to achieve?",
770
- lines=3
771
- )
772
- study_preferences = gr.Textbox(
773
- label="Study Preferences",
774
- placeholder="When/where/how do you prefer to study?",
775
- lines=3
776
- )
777
-
778
- with gr.Column():
779
- gr.Markdown("#### Favorites")
780
- movie = gr.Textbox(label="Favorite Movie")
781
- movie_reason = gr.Textbox(label="Why do you like it?")
782
- show = gr.Textbox(label="Favorite TV Show")
783
- show_reason = gr.Textbox(label="Why do you like it?")
784
- book = gr.Textbox(label="Favorite Book")
785
- book_reason = gr.Textbox(label="Why do you like it?")
786
- character = gr.Textbox(label="Favorite Character (book/movie/show)")
787
- character_reason = gr.Textbox(label="Why do you like them?")
788
-
789
- with gr.Row():
790
- blog_checkbox = gr.Checkbox(label="Include a personal blog/journal entry?", value=False)
791
- blog_text = gr.Textbox(
792
- label="Your Blog/Journal",
793
- visible=False,
794
- lines=5,
795
- placeholder="Write about your learning experiences, challenges, or thoughts..."
796
- )
797
-
798
- blog_checkbox.change(
799
- lambda x: gr.update(visible=x),
800
- inputs=blog_checkbox,
801
- outputs=blog_text
802
- )
803
-
804
- with gr.Tab("💾 Step 4: Save & Review"):
805
- gr.Markdown("### Review and Save Your Profile")
806
-
807
- with gr.Row():
808
- profile_selector = gr.Dropdown(
809
- label="Select Profile to Load",
810
- choices=get_profile_list(),
811
- interactive=True,
812
- allow_custom_value=False
813
- )
814
- refresh_profiles = gr.Button("🔄 Refresh List")
815
-
816
- with gr.Row():
817
- save_btn = gr.Button("💾 Save Profile", variant="primary")
818
- load_btn = gr.Button("📂 Load Profile")
819
- clear_btn = gr.Button("🧹 Clear Form")
820
-
821
  output_summary = gr.Markdown()
822
-
823
- # Profile management functions
824
- refresh_profiles.click(
825
- lambda: gr.update(choices=get_profile_list()),
826
- outputs=profile_selector
827
- )
828
-
829
  save_btn.click(
830
  fn=save_profile,
831
- inputs=[
832
- name, age, interests, transcript_data, learning_output,
833
- movie, movie_reason, show, show_reason,
834
- book, book_reason, character, character_reason,
835
- blog_text, goals, study_preferences
836
- ],
837
  outputs=output_summary
838
- ).then(
839
- lambda: gr.update(choices=get_profile_list()),
840
- outputs=profile_selector
841
  )
842
-
843
- load_btn.click(
844
- fn=lambda name: generate_profile_summary(load_profile(name)),
845
- inputs=profile_selector,
846
- outputs=output_summary
847
- )
848
-
849
- clear_btn.click(
850
- lambda: [""]*15 + [None, False, ""],
851
- outputs=[
852
- name, age, interests, goals, study_preferences,
853
- movie, movie_reason, show, show_reason,
854
- book, book_reason, character, character_reason,
855
- blog_text, blog_checkbox, output_summary
856
- ]
857
- )
858
-
859
  with gr.Tab("🤖 AI Teaching Assistant"):
860
  gr.Markdown("## Your Personalized Learning Assistant")
861
- gr.Markdown("Chat with your AI assistant to get personalized learning advice based on your profile.")
862
-
863
- # Profile selection for assistant
864
- with gr.Row():
865
- assistant_profile_selector = gr.Dropdown(
866
- label="Select Your Profile",
867
- choices=get_profile_list(),
868
- interactive=True
869
- )
870
- load_assistant_profile = gr.Button("Load Profile")
871
- refresh_assistant_profiles = gr.Button("🔄 Refresh")
872
-
873
- # Chat interface
874
  chatbot = gr.ChatInterface(
875
- fn=assistant.generate_response,
876
  examples=[
877
- "How should I study for my next math test?",
878
- "What's my current GPA?",
879
  "Show me my course history",
880
- "Recommend some science resources",
881
- "Help me set academic goals"
882
- ],
883
- title="Chat with Your Teaching Assistant",
884
- retry_btn=None,
885
- undo_btn=None,
886
- clear_btn="Clear Chat"
887
- )
888
-
889
- # Profile management for assistant
890
- load_assistant_profile.click(
891
- fn=lambda name: assistant.load_profile(name) or f"Loaded profile for {name}",
892
- inputs=assistant_profile_selector,
893
- outputs=chatbot.chatbot
894
- )
895
-
896
- refresh_assistant_profiles.click(
897
- lambda: gr.update(choices=get_profile_list()),
898
- outputs=assistant_profile_selector
899
  )
900
 
901
- if __name__ == "__main__":
902
- app.launch()
903
-
 
3
  import json
4
  import os
5
  import re
 
 
6
  from PyPDF2 import PdfReader
7
  from collections import defaultdict
 
 
8
 
9
+ # ========== NER MODEL HANDLING FOR SPACES ==========
10
  try:
11
+ from transformers import pipeline
12
  ner_pipeline = pipeline("ner", model="dslim/bert-base-NER")
13
+ except ImportError:
14
+ ner_pipeline = None
15
+ print("NER model not available - continuing without it")
16
  except Exception as e:
 
17
  ner_pipeline = None
18
+ print(f"Could not load NER model: {e}")
19
 
20
+ # ========== TRANSCRIPT PARSING ==========
21
+ def extract_gpa(text, gpa_type):
22
  pattern = rf'{gpa_type}\s*([\d\.]+)'
23
  match = re.search(pattern, text)
24
  return match.group(1) if match else "N/A"
25
 
26
+ def extract_courses_from_table(text):
 
27
  course_pattern = re.compile(
28
  r'(\d{4}-\d{4})\s*' # School year
29
  r'\|?\s*(\d+)\s*' # Grade level
 
40
  for match in re.finditer(course_pattern, text):
41
  year_range, grade_level, course_code, course_name, grade, credits = match.groups()
42
 
 
43
  course_name = course_name.strip()
44
  if 'DE:' in course_name:
45
  course_name = course_name.replace('DE:', 'Dual Enrollment:')
 
59
 
60
  return courses_by_grade
61
 
62
+ def parse_transcript(file):
63
+ if file.name.endswith('.pdf'):
64
+ text = ''
65
+ reader = PdfReader(file)
66
+ for page in reader.pages:
67
+ text += page.extract_text() + '\n'
68
+
69
+ gpa_data = {
70
+ 'weighted': extract_gpa(text, 'Weighted GPA'),
71
+ 'unweighted': extract_gpa(text, 'Un-weighted GPA')
72
+ }
73
+
74
+ grade_match = re.search(r'Current Grade:\s*(\d+)', text)
75
+ grade_level = grade_match.group(1) if grade_match else "Unknown"
76
+
77
+ courses_by_grade = extract_courses_from_table(text)
78
+
79
+ output_text = f"Student Transcript Summary\n{'='*40}\n"
80
+ output_text += f"Current Grade Level: {grade_level}\n"
81
+ output_text += f"Weighted GPA: {gpa_data['weighted']}\n"
82
+ output_text += f"Unweighted GPA: {gpa_data['unweighted']}\n\n"
83
+ output_text += "Course History:\n{'='*40}\n"
84
+
85
+ for grade in sorted(courses_by_grade.keys(), key=int):
86
+ output_text += f"\nGrade {grade}:\n{'-'*30}\n"
87
+ for course in courses_by_grade[grade]:
88
+ output_text += f"- {course['name']}"
89
+ if 'grade' in course and course['grade']:
90
+ output_text += f" (Grade: {course['grade']})"
91
+ if 'credits' in course:
92
+ output_text += f" | Credits: {course['credits']}"
93
+ output_text += f" | Year: {course['year']}\n"
94
+
95
+ return output_text, {
96
+ "gpa": gpa_data,
97
+ "grade_level": grade_level,
98
+ "courses": dict(courses_by_grade)
99
+ }
100
+ else:
101
+ return "Unsupported file format (PDF only for transcript parsing)", None
 
 
 
 
 
 
 
 
102
 
103
+ # ========== LEARNING STYLE QUIZ ==========
104
  learning_style_questions = [
105
  "When you study for a test, you prefer to:",
106
  "When you need directions to a new place, you prefer:",
 
147
  ["Write out possible solutions (Reading/Writing)", "Talk through it with someone (Auditory)", "Draw diagrams (Visual)", "Build a model or prototype (Kinesthetic)"]
148
  ]
149
 
150
+ def learning_style_quiz(*answers):
151
  scores = {
152
  "Visual": 0,
153
  "Auditory": 0,
 
168
  max_score = max(scores.values())
169
  total_questions = len(learning_style_questions)
170
 
 
171
  percentages = {style: (score/total_questions)*100 for style, score in scores.items()}
172
 
 
173
  sorted_styles = sorted(scores.items(), key=lambda x: x[1], reverse=True)
174
 
 
175
  result = "Your Learning Style Results:\n\n"
176
  for style, score in sorted_styles:
177
  result += f"{style}: {score}/{total_questions} ({percentages[style]:.1f}%)\n"
178
 
179
  result += "\n"
180
 
 
181
  primary_styles = [style for style, score in scores.items() if score == max_score]
182
 
183
  if len(primary_styles) == 1:
184
  result += f"Your primary learning style is: {primary_styles[0]}\n\n"
 
185
  if primary_styles[0] == "Visual":
186
  result += "Tips for Visual Learners:\n"
187
  result += "- Use color coding in your notes\n"
188
  result += "- Create mind maps and diagrams\n"
189
  result += "- Watch educational videos\n"
190
  result += "- Use flashcards with images\n"
 
191
  elif primary_styles[0] == "Auditory":
192
  result += "Tips for Auditory Learners:\n"
193
  result += "- Record lectures and listen to them\n"
194
  result += "- Participate in study groups\n"
195
  result += "- Explain concepts out loud to yourself\n"
196
  result += "- Use rhymes or songs to remember information\n"
 
197
  elif primary_styles[0] == "Reading/Writing":
198
  result += "Tips for Reading/Writing Learners:\n"
199
  result += "- Write detailed notes\n"
200
  result += "- Create summaries in your own words\n"
201
  result += "- Read textbooks and articles\n"
202
  result += "- Make lists to organize information\n"
203
+ else:
 
204
  result += "Tips for Kinesthetic Learners:\n"
205
  result += "- Use hands-on activities\n"
206
  result += "- Take frequent movement breaks\n"
207
  result += "- Create physical models\n"
208
  result += "- Associate information with physical actions\n"
 
209
  else:
210
  result += f"You have multiple strong learning styles: {', '.join(primary_styles)}\n\n"
211
+ result += "You may benefit from combining different learning approaches.\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
  return result
214
 
215
+ # ========== PROFILE MANAGEMENT ==========
216
+ def save_profile(name, age, interests, transcript, learning_style,
217
+ movie, movie_reason, show, show_reason,
218
+ book, book_reason, character, character_reason, blog):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  age = int(age) if age else 0
220
 
221
+ favorites = {
222
+ "movie": movie,
223
+ "movie_reason": movie_reason,
224
+ "show": show,
225
+ "show_reason": show_reason,
226
+ "book": book,
227
+ "book_reason": book_reason,
228
+ "character": character,
229
+ "character_reason": character_reason
230
+ }
231
+
232
+ data = {
233
  "name": name,
234
  "age": age,
235
  "interests": interests,
236
  "transcript": transcript,
237
  "learning_style": learning_style,
238
+ "favorites": favorites,
239
+ "blog": blog
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  }
241
 
 
242
  os.makedirs("student_profiles", exist_ok=True)
243
+ json_path = os.path.join("student_profiles", f"{name.replace(' ', '_')}_profile.json")
244
+ with open(json_path, "w") as f:
245
+ json.dump(data, f, indent=2)
 
 
 
 
246
 
247
+ markdown_summary = f"""### Student Profile: {name}
248
+ **Age:** {age}
249
+ **Interests:** {interests}
250
+ **Learning Style:** {learning_style}
251
+ #### Transcript:
252
+ {transcript_display(transcript)}
253
+ #### Favorites:
254
+ - Movie: {favorites['movie']} ({favorites['movie_reason']})
255
+ - Show: {favorites['show']} ({favorites['show_reason']})
256
+ - Book: {favorites['book']} ({favorites['book_reason']})
257
+ - Character: {favorites['character']} ({favorites['character_reason']})
258
+ #### Blog:
259
+ {blog if blog else "_No blog provided_"}
260
+ """
261
+ return markdown_summary
 
 
 
 
 
 
 
262
 
263
+ def transcript_display(transcript_dict):
 
264
  if not transcript_dict or "courses" not in transcript_dict:
265
  return "No course information available"
266
 
 
268
  courses_by_grade = transcript_dict["courses"]
269
 
270
  if isinstance(courses_by_grade, dict):
 
271
  for grade in sorted(courses_by_grade.keys(), key=int):
272
  display += f"\n**Grade {grade}**\n"
273
  for course in courses_by_grade[grade]:
 
286
 
287
  return display
288
 
289
+ def load_profile():
290
+ if not os.path.exists("student_profiles"):
291
+ return {}
292
+ files = [f for f in os.listdir("student_profiles") if f.endswith('.json')]
293
+ if files:
294
+ with open(os.path.join("student_profiles", files[0]), "r") as f:
295
+ return json.load(f)
296
+ return {}
297
+
298
+ def generate_response(message, history):
299
+ profile = load_profile()
300
  if not profile:
301
+ return "Please complete and save your profile first using the previous tabs."
302
 
303
+ learning_style = profile.get("learning_style", "")
304
+ grade_level = profile.get("transcript", {}).get("grade_level", "unknown")
305
+ gpa = profile.get("transcript", {}).get("gpa", {})
306
+ interests = profile.get("interests", "")
307
+ courses = profile.get("transcript", {}).get("courses", {})
 
 
 
308
 
309
+ greetings = ["hi", "hello", "hey"]
310
+ study_help = ["study", "learn", "prepare", "exam"]
311
+ grade_help = ["grade", "gpa", "score"]
312
+ interest_help = ["interest", "hobby", "passion"]
313
+ course_help = ["courses", "classes", "transcript", "schedule"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
+ if any(greet in message.lower() for greet in greetings):
316
+ return f"Hello {profile.get('name', 'there')}! How can I help you today?"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
 
318
+ elif any(word in message.lower() for word in study_help):
 
 
 
 
319
  if "Visual" in learning_style:
320
+ response = ("Based on your visual learning style, I recommend:\n"
321
+ "- Creating mind maps or diagrams\n"
322
+ "- Using color-coded notes\n"
323
+ "- Watching educational videos")
324
+ elif "Auditory" in learning_style:
325
+ response = ("Based on your auditory learning style, I recommend:\n"
326
+ "- Recording lectures and listening to them\n"
327
+ "- Participating in study groups\n"
328
+ "- Explaining concepts out loud")
329
+ elif "Reading/Writing" in learning_style:
330
+ response = ("Based on your reading/writing learning style, I recommend:\n"
331
+ "- Writing detailed notes\n"
332
+ "- Creating summaries in your own words\n"
333
+ "- Reading textbooks and articles")
334
+ elif "Kinesthetic" in learning_style:
335
+ response = ("Based on your kinesthetic learning style, I recommend:\n"
336
+ "- Hands-on practice\n"
337
+ "- Creating physical models\n"
338
+ "- Taking frequent movement breaks")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  else:
340
+ response = ("Here are some general study tips:\n"
341
+ "- Break study sessions into 25-minute chunks\n"
342
+ "- Review material regularly\n"
343
+ "- Teach concepts to someone else")
344
 
345
  return response
346
 
347
+ elif any(word in message.lower() for word in grade_help):
348
+ return (f"Your GPA information:\n"
349
+ f"- Unweighted: {gpa.get('unweighted', 'N/A')}\n"
350
+ f"- Weighted: {gpa.get('weighted', 'N/A')}\n\n"
351
+ "To improve your grades, try:\n"
352
+ "- Setting specific goals\n"
353
+ "- Meeting with teachers\n"
354
+ "- Developing a study schedule")
355
+
356
+ elif any(word in message.lower() for word in interest_help):
357
+ return (f"I see you're interested in: {interests}\n\n"
358
+ "You might want to:\n"
359
+ "- Find clubs or activities related to these interests\n"
360
+ "- Explore career paths that align with them")
361
+
362
+ elif any(word in message.lower() for word in course_help):
363
+ response = "Here's a summary of your courses:\n"
364
  for grade in sorted(courses.keys(), key=int):
365
+ response += f"\nGrade {grade}:\n"
366
  for course in courses[grade]:
367
+ response += f"- {course['name']}"
368
  if 'grade' in course:
369
+ response += f" (Grade: {course['grade']})"
370
  response += "\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  return response
372
 
373
+ elif "help" in message.lower():
374
+ return ("I can help with:\n"
375
+ "- Study tips based on your learning style\n"
376
+ "- GPA and grade information\n"
377
+ "- Course history and schedules\n"
378
+ "- General academic advice\n\n"
379
+ "Try asking about study strategies or your grades!")
 
 
 
 
 
 
380
 
381
+ else:
382
+ return ("I'm your personalized teaching assistant. "
383
+ "I can help with study tips, grade information, and academic advice. "
384
+ "Try asking about how to study for your classes!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
 
386
  # ========== GRADIO INTERFACE ==========
387
+ with gr.Blocks() as app:
388
+ with gr.Tab("Step 1: Upload Transcript"):
389
+ gr.Markdown("### Upload your transcript (PDF recommended for best results)")
390
+ transcript_file = gr.File(label="Transcript file", file_types=[".pdf"])
391
+ transcript_output = gr.Textbox(label="Transcript Results", lines=20)
392
+ transcript_data = gr.State()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  transcript_file.change(
394
  fn=parse_transcript,
395
  inputs=transcript_file,
396
  outputs=[transcript_output, transcript_data]
397
  )
398
+
399
+ with gr.Tab("Step 2: Learning Style Quiz"):
400
+ gr.Markdown("### Learning Style Quiz (20 Questions)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  quiz_components = []
402
+ for i, (question, options) in enumerate(zip(learning_style_questions, learning_style_options)):
403
+ quiz_components.append(gr.Radio(options, label=f"{i+1}. {question}"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
 
405
+ learning_output = gr.Textbox(label="Your Learning Style", lines=15)
406
+ gr.Button("Submit Quiz").click(
407
  fn=learning_style_quiz,
408
  inputs=quiz_components,
409
  outputs=learning_output
410
  )
411
+
412
+ with gr.Tab("Step 3: Personal Questions"):
413
+ name = gr.Textbox(label="What's your name?")
414
+ age = gr.Number(label="How old are you?", precision=0)
415
+ interests = gr.Textbox(label="What are your interests?")
416
+ movie = gr.Textbox(label="Favorite movie?")
417
+ movie_reason = gr.Textbox(label="Why do you like that movie?")
418
+ show = gr.Textbox(label="Favorite TV show?")
419
+ show_reason = gr.Textbox(label="Why do you like that show?")
420
+ book = gr.Textbox(label="Favorite book?")
421
+ book_reason = gr.Textbox(label="Why do you like that book?")
422
+ character = gr.Textbox(label="Favorite character?")
423
+ character_reason = gr.Textbox(label="Why do you like that character?")
424
+ blog_checkbox = gr.Checkbox(label="Do you want to write a blog?", value=False)
425
+ blog_text = gr.Textbox(label="Write your blog here", visible=False, lines=5)
426
+ blog_checkbox.change(lambda x: gr.update(visible=x), inputs=blog_checkbox, outputs=blog_text)
427
+
428
+ with gr.Tab("Step 4: Save & Review"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  output_summary = gr.Markdown()
430
+ save_btn = gr.Button("Save Profile")
 
 
 
 
 
 
431
  save_btn.click(
432
  fn=save_profile,
433
+ inputs=[name, age, interests, transcript_data, learning_output,
434
+ movie, movie_reason, show, show_reason,
435
+ book, book_reason, character, character_reason, blog_text],
 
 
 
436
  outputs=output_summary
 
 
 
437
  )
438
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  with gr.Tab("🤖 AI Teaching Assistant"):
440
  gr.Markdown("## Your Personalized Learning Assistant")
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  chatbot = gr.ChatInterface(
442
+ fn=generate_response,
443
  examples=[
444
+ "How should I study for my next test?",
445
+ "What's my GPA information?",
446
  "Show me my course history",
447
+ "How can I improve my grades?"
448
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
  )
450
 
451
+ app.launch()