Spaces:
Runtime error
Runtime error
# ========== DEPENDENCY MANAGEMENT ========== | |
import sys | |
import subprocess | |
import importlib | |
from datetime import datetime | |
required_packages = { | |
'gradio': 'gradio>=3.0', | |
'pandas': 'pandas', | |
'PyPDF2': 'PyPDF2', | |
'transformers': 'transformers', | |
'pdfplumber': 'pdfplumber' | |
} | |
def check_and_install_packages(): | |
missing_packages = [] | |
for import_name, pkg_name in required_packages.items(): | |
try: | |
importlib.import_module(import_name) | |
except ImportError: | |
missing_packages.append(pkg_name) | |
if missing_packages: | |
print(f"Missing packages: {', '.join(missing_packages)}") | |
subprocess.check_call([sys.executable, "-m", "pip", "install", *missing_packages]) | |
check_and_install_packages() | |
# ========== MAIN IMPORTS ========== | |
import gradio as gr | |
import pandas as pd | |
import json | |
import os | |
import re | |
from PyPDF2 import PdfReader | |
from collections import defaultdict | |
from transformers import pipeline | |
from typing import List, Dict, Union | |
import pdfplumber | |
# ========== TRANSCRIPT PARSING ========== | |
class UniversalTranscriptParser: | |
def __init__(self): | |
self.patterns = { | |
'miami_dade': self._compile_miami_dade_patterns(), | |
'homeschool': self._compile_homeschool_patterns(), | |
'doral_academy': self._compile_doral_academy_patterns() | |
} | |
self.grade_level_map = { | |
'09': '9th Grade', '10': '10th Grade', '11': '11th Grade', '12': '12th Grade', | |
'07': '7th Grade', '08': '8th Grade', 'MA': 'Middle School' | |
} | |
def parse_transcript(self, text: str) -> Dict[str, Union[Dict, List[Dict]]]: | |
"""Determine transcript type and parse accordingly""" | |
transcript_type = self._identify_transcript_type(text) | |
if transcript_type == 'homeschool': | |
return self._parse_homeschool(text) | |
elif transcript_type == 'doral_academy': | |
return self._parse_doral_academy(text) | |
else: | |
return self._parse_miami_dade(text) | |
def _identify_transcript_type(self, text: str) -> str: | |
"""Identify which type of transcript we're processing""" | |
if re.search(r'Sample OFFICIAL HIGH SCHOOL TRANSCRIPT', text): | |
return 'homeschool' | |
elif re.search(r'DORAL ACADEMY HIGH SCHOOL', text): | |
return 'doral_academy' | |
return 'miami_dade' | |
def _parse_homeschool(self, text: str) -> Dict[str, Union[Dict, List[Dict]]]: | |
"""Parse homeschool transcript format""" | |
courses = [] | |
current_grade = None | |
current_year = None | |
# Extract student info | |
student_info = {} | |
name_match = re.search(r'Student Name:\s*(.+)\s*SSN:', text) | |
if name_match: | |
student_info['name'] = name_match.group(1).strip() | |
# Process each line | |
for line in text.split('\n'): | |
# Check for grade level header | |
grade_match = re.match(r'^\|?\s*(\d+th Grade)\s*\|.*(\d{4}-\d{4})', line) | |
if grade_match: | |
current_grade = grade_match.group(1) | |
current_year = grade_match.group(2) | |
continue | |
# Course line pattern | |
course_match = re.match( | |
r'^\|?\s*([^\|]+?)\s*\|\s*([A-Z][+*]?)\s*\|\s*([^\|]+)\s*\|\s*(\d+\.?\d*)\s*\|\s*(\d+)', | |
line | |
) | |
if course_match and current_grade: | |
course_name = course_match.group(1).strip() | |
# Clean course names that start with | or have extra spaces | |
course_name = re.sub(r'^\|?\s*', '', course_name) | |
courses.append({ | |
'name': course_name, | |
'grade_level': current_grade, | |
'school_year': current_year, | |
'grade': course_match.group(2), | |
'credit_type': course_match.group(3).strip(), | |
'credits': float(course_match.group(4)), | |
'quality_points': int(course_match.group(5)), | |
'transcript_type': 'homeschool' | |
}) | |
# Extract GPA information from homeschool transcript | |
gpa_data = {} | |
gpa_match = re.search(r'Cum\. GPA\s*\|\s*([\d\.]+)', text) | |
if gpa_match: | |
gpa_data['unweighted'] = gpa_match.group(1) | |
gpa_data['weighted'] = gpa_match.group(1) # Homeschool often has same weighted/unweighted | |
return { | |
'student_info': student_info, | |
'courses': {'All': courses}, # Homeschool doesn't separate by grade in same way | |
'gpa': gpa_data, | |
'grade_level': current_grade.replace('th Grade', '') if current_grade else "Unknown" | |
} | |
def _parse_doral_academy(self, text: str) -> Dict[str, Union[Dict, List[Dict]]]: | |
"""Parse Doral Academy specific format""" | |
courses = [] | |
# Extract student info | |
student_info = {} | |
name_match = re.search(r'LEGAL NAME:\s*([^\n]+)', text) | |
if name_match: | |
student_info['name'] = name_match.group(1).strip() | |
# Extract school year information | |
year_pattern = re.compile(r'YEAR:\s*(\d{4}-\d{4})\s*GRADE LEVEL:\s*(\d{2})', re.MULTILINE) | |
year_matches = year_pattern.finditer(text) | |
# Create mapping of grade levels to years | |
grade_year_map = {} | |
for match in year_matches: | |
grade_year_map[match.group(2)] = match.group(1) | |
# Course pattern for Doral Academy | |
course_pattern = re.compile( | |
r'(\d)\s+(\d{7})\s+([^\n]+?)\s+([A-Z]{2})\s+([A-Z])\s+([A-Z])\s+([A-Z])\s+(\d\.\d{2})\s+(\d\.\d{2})', | |
re.MULTILINE | |
) | |
courses_by_grade = defaultdict(list) | |
for match in course_pattern.finditer(text): | |
grade_level_num = match.group(1) | |
grade_level = self.grade_level_map.get(grade_level_num, f"Grade {grade_level_num}") | |
school_year = grade_year_map.get(grade_level_num, "Unknown") | |
course_info = { | |
'course_code': match.group(2), | |
'name': match.group(3).strip(), | |
'subject_area': match.group(4), | |
'grade': match.group(5), | |
'inclusion_status': match.group(6), | |
'credit_status': match.group(7), | |
'credits_attempted': float(match.group(8)), | |
'credits': float(match.group(9)), | |
'grade_level': grade_level, | |
'school_year': school_year, | |
'transcript_type': 'doral_academy' | |
} | |
courses_by_grade[grade_level_num].append(course_info) | |
# Extract GPA information from Doral Academy transcript | |
gpa_data = {} | |
unweighted_match = re.search(r'Un-weighted GPA\s*([\d\.]+)', text) | |
weighted_match = re.search(r'Weighted GPA\s*([\d\.]+)', text) | |
if unweighted_match: | |
gpa_data['unweighted'] = unweighted_match.group(1) | |
if weighted_match: | |
gpa_data['weighted'] = weighted_match.group(1) | |
# Extract current grade level | |
grade_level = "12" if re.search(r'GRADE LEVEL:\s*12', text) else "Unknown" | |
return { | |
'student_info': student_info, | |
'courses': dict(courses_by_grade), | |
'gpa': gpa_data, | |
'grade_level': grade_level | |
} | |
def _parse_miami_dade(self, text: str) -> Dict[str, Union[Dict, List[Dict]]]: | |
"""Parse standard Miami-Dade format""" | |
courses = [] | |
courses_by_grade = defaultdict(list) | |
# Extract student info | |
student_info = {} | |
name_match = re.search(r'0783977 - ([^,]+),\s*([^\n]+)', text) | |
if name_match: | |
student_info['name'] = f"{name_match.group(2)} {name_match.group(1)}" | |
# Course pattern for Miami-Dade | |
course_pattern = re.compile( | |
r'([A-Z]-[A-Za-z\s&]+)\s*\|\s*(\d{4}-\d{4})\s*\|\s*(\d{2})\s*\|\s*([A-Z0-9]+)\s*\|\s*([^\|]+)\s*\|\s*([^\|]+)\s*\|\s*([^\|]+)\s*\|\s*([A-Z]?)\s*\|\s*([A-Z]?)\s*\|\s*([^\|]+)', | |
re.MULTILINE | |
) | |
for match in course_pattern.finditer(text): | |
grade_level = self.grade_level_map.get(match.group(3), match.group(3)) | |
credits = match.group(10).strip() | |
course_info = { | |
'requirement_category': match.group(1).strip(), | |
'school_year': match.group(2), | |
'grade_level': grade_level if isinstance(grade_level, str) else f"Grade {match.group(3)}", | |
'course_code': match.group(4).strip(), | |
'name': match.group(5).strip(), | |
'term': match.group(6).strip(), | |
'district_number': match.group(7).strip(), | |
'grade': match.group(8), | |
'inclusion_status': match.group(9), | |
'credits': 0.0 if 'inProgress' in credits else float(credits.replace(' ', '')), | |
'transcript_type': 'miami_dade' | |
} | |
courses_by_grade[match.group(3)].append(course_info) | |
# Extract GPA information | |
gpa_data = { | |
'weighted': extract_gpa(text, 'Weighted GPA'), | |
'unweighted': extract_gpa(text, 'Un-weighted GPA') | |
} | |
# Extract current grade level | |
grade_level = re.search(r'Current Grade:\s*(\d+)', text).group(1) if re.search(r'Current Grade:\s*(\d+)', text) else "Unknown" | |
return { | |
'student_info': student_info, | |
'courses': dict(courses_by_grade), | |
'gpa': gpa_data, | |
'grade_level': grade_level | |
} | |
def _compile_miami_dade_patterns(self): | |
return { | |
'student': re.compile(r'Current Grade:\s*(\d+).*YOG\s*(\d{4})'), | |
'course': re.compile( | |
r'([A-Z]-[A-Za-z\s&]+)\s*\|\s*(\d{4}-\d{4})\s*\|\s*(\d{2})\s*\|\s*([A-Z0-9]+)\s*\|\s*([^\|]+)\s*\|\s*([^\|]+)\s*\|\s*([^\|]+)\s*\|\s*([A-Z]?)\s*\|\s*([A-Z]?)\s*\|\s*([^\|]+)', | |
re.MULTILINE | |
) | |
} | |
def _compile_homeschool_patterns(self): | |
return { | |
'student': re.compile(r'Student Name:\s*(.+)\s*SSN:'), | |
'course': re.compile( | |
r'^\|?\s*([^\|]+?)\s*\|\s*([A-Z][+*]?)\s*\|\s*([^\|]+)\s*\|\s*(\d+\.?\d*)\s*\|\s*(\d+)' | |
) | |
} | |
def _compile_doral_academy_patterns(self): | |
return { | |
'student': re.compile(r'LEGAL NAME:\s*([^\n]+)'), | |
'course': re.compile( | |
r'(\d)\s+(\d{7})\s+([^\n]+?)\s+([A-Z]{2})\s+([A-Z])\s+([A-Z])\s+([A-Z])\s+(\d\.\d{2})\s+(\d\.\d{2})', | |
re.MULTILINE | |
) | |
} | |
def extract_gpa(text, gpa_type): | |
pattern = rf'{gpa_type}\s*([\d\.]+)' | |
match = re.search(pattern, text) | |
return match.group(1) if match else "N/A" | |
def parse_transcript(file): | |
parser = UniversalTranscriptParser() | |
if file.name.endswith('.pdf'): | |
text = '' | |
with pdfplumber.open(file.name) as pdf: | |
for page in pdf.pages: | |
text += page.extract_text() or '' + '\n' | |
parsed_data = parser.parse_transcript(text) | |
# Only show GPA in the output | |
output_text = f"Transcript Processed Successfully!\n\n" | |
output_text += f"GPA Information:\n" | |
output_text += f"- Weighted: {parsed_data['gpa'].get('weighted', 'N/A')}\n" | |
output_text += f"- Unweighted: {parsed_data['gpa'].get('unweighted', 'N/A')}" | |
return output_text, parsed_data | |
else: | |
return "Unsupported file format (PDF only for transcript parsing)", None | |
# ========== LEARNING STYLE QUIZ ========== | |
learning_style_questions = [ | |
"When you study for a test, you prefer to:", | |
"When you need directions to a new place, you prefer:", | |
"When you learn a new skill, you prefer to:", | |
"When you're trying to concentrate, you:", | |
"When you meet new people, you remember them by:", | |
"When you're assembling furniture or a gadget, you:", | |
"When choosing a restaurant, you rely most on:", | |
"When you're in a waiting room, you typically:", | |
"When giving someone instructions, you tend to:", | |
"When you're trying to recall information, you:", | |
"When you're at a museum or exhibit, you:", | |
"When you're learning a new language, you prefer:", | |
"When you're taking notes in class, you:", | |
"When you're explaining something complex, you:", | |
"When you're at a party, you enjoy:", | |
"When you're trying to remember a phone number, you:", | |
"When you're relaxing, you prefer to:", | |
"When you're learning to use new software, you:", | |
"When you're giving a presentation, you rely on:", | |
"When you're solving a difficult problem, you:" | |
] | |
learning_style_options = [ | |
["Read the textbook (Reading/Writing)", "Listen to lectures (Auditory)", "Use diagrams/charts (Visual)", "Practice problems (Kinesthetic)"], | |
["Look at a map (Visual)", "Have someone tell you (Auditory)", "Write down directions (Reading/Writing)", "Try walking/driving there (Kinesthetic)"], | |
["Read instructions (Reading/Writing)", "Have someone show you (Visual)", "Listen to explanations (Auditory)", "Try it yourself (Kinesthetic)"], | |
["Need quiet (Reading/Writing)", "Need background noise (Auditory)", "Need to move around (Kinesthetic)", "Need visual stimulation (Visual)"], | |
["Their face (Visual)", "Their name (Auditory)", "What you talked about (Reading/Writing)", "What you did together (Kinesthetic)"], | |
["Read the instructions carefully (Reading/Writing)", "Look at the diagrams (Visual)", "Ask someone to explain (Auditory)", "Start putting pieces together (Kinesthetic)"], | |
["Online photos of the food (Visual)", "Recommendations from friends (Auditory)", "Reading the menu online (Reading/Writing)", "Remembering how it felt to eat there (Kinesthetic)"], | |
["Read magazines (Reading/Writing)", "Listen to music (Auditory)", "Watch TV (Visual)", "Fidget or move around (Kinesthetic)"], | |
["Write them down (Reading/Writing)", "Explain verbally (Auditory)", "Demonstrate (Visual)", "Guide them physically (Kinesthetic)"], | |
["See written words in your mind (Visual)", "Hear the information in your head (Auditory)", "Write it down to remember (Reading/Writing)", "Associate it with physical actions (Kinesthetic)"], | |
["Read all the descriptions (Reading/Writing)", "Listen to audio guides (Auditory)", "Look at the displays (Visual)", "Touch interactive exhibits (Kinesthetic)"], | |
["Study grammar rules (Reading/Writing)", "Listen to native speakers (Auditory)", "Use flashcards with images (Visual)", "Practice conversations (Kinesthetic)"], | |
["Write detailed paragraphs (Reading/Writing)", "Record the lecture (Auditory)", "Draw diagrams and charts (Visual)", "Doodle while listening (Kinesthetic)"], | |
["Write detailed steps (Reading/Writing)", "Explain verbally with examples (Auditory)", "Draw diagrams (Visual)", "Use physical objects to demonstrate (Kinesthetic)"], | |
["Conversations with people (Auditory)", "Watching others or the environment (Visual)", "Writing notes or texting (Reading/Writing)", "Dancing or physical activities (Kinesthetic)"], | |
["See the numbers in your mind (Visual)", "Say them aloud (Auditory)", "Write them down (Reading/Writing)", "Dial them on a keypad (Kinesthetic)"], | |
["Read a book (Reading/Writing)", "Listen to music (Auditory)", "Watch TV/movies (Visual)", "Do something physical (Kinesthetic)"], | |
["Read the manual (Reading/Writing)", "Ask someone to show you (Visual)", "Call tech support (Auditory)", "Experiment with the software (Kinesthetic)"], | |
["Detailed notes (Reading/Writing)", "Verbal explanations (Auditory)", "Visual slides (Visual)", "Physical demonstrations (Kinesthetic)"], | |
["Write out possible solutions (Reading/Writing)", "Talk through it with someone (Auditory)", "Draw diagrams (Visual)", "Build a model or prototype (Kinesthetic)"] | |
] | |
def learning_style_quiz(*answers): | |
scores = { | |
"Visual": 0, | |
"Auditory": 0, | |
"Reading/Writing": 0, | |
"Kinesthetic": 0 | |
} | |
for i, answer in enumerate(answers): | |
if answer == learning_style_options[i][0]: | |
scores["Reading/Writing"] += 1 | |
elif answer == learning_style_options[i][1]: | |
scores["Auditory"] += 1 | |
elif answer == learning_style_options[i][2]: | |
scores["Visual"] += 1 | |
elif answer == learning_style_options[i][3]: | |
scores["Kinesthetic"] += 1 | |
max_score = max(scores.values()) | |
total_questions = len(learning_style_questions) | |
# Calculate percentages | |
percentages = {style: (score/total_questions)*100 for style, score in scores.items()} | |
# Sort styles by score (descending) | |
sorted_styles = sorted(scores.items(), key=lambda x: x[1], reverse=True) | |
# Prepare detailed results | |
result = "Your Learning Style Results:\n\n" | |
for style, score in sorted_styles: | |
result += f"{style}: {score}/{total_questions} ({percentages[style]:.1f}%)\n" | |
result += "\n" | |
# Determine primary and secondary styles | |
primary_styles = [style for style, score in scores.items() if score == max_score] | |
if len(primary_styles) == 1: | |
result += f"Your primary learning style is: {primary_styles[0]}\n\n" | |
if primary_styles[0] == "Visual": | |
result += "Tips for Visual Learners:\n" | |
result += "- Use color coding in your notes\n" | |
result += "- Create mind maps and diagrams\n" | |
result += "- Watch educational videos\n" | |
result += "- Use flashcards with images\n" | |
elif primary_styles[0] == "Auditory": | |
result += "Tips for Auditory Learners:\n" | |
result += "- Record lectures and listen to them\n" | |
result += "- Participate in study groups\n" | |
result += "- Explain concepts out loud to yourself\n" | |
result += "- Use rhymes or songs to remember information\n" | |
elif primary_styles[0] == "Reading/Writing": | |
result += "Tips for Reading/Writing Learners:\n" | |
result += "- Write detailed notes\n" | |
result += "- Create summaries in your own words\n" | |
result += "- Read textbooks and articles\n" | |
result += "- Make lists to organize information\n" | |
else: # Kinesthetic | |
result += "Tips for Kinesthetic Learners:\n" | |
result += "- Use hands-on activities\n" | |
result += "- Take frequent movement breaks\n" | |
result += "- Create physical models\n" | |
result += "- Associate information with physical actions\n" | |
else: | |
result += f"You have multiple strong learning styles: {', '.join(primary_styles)}\n\n" | |
result += "You may benefit from combining different learning approaches.\n" | |
return result | |
# ========== SAVE STUDENT PROFILE ========== | |
def save_profile(name, age, interests, transcript, learning_style, | |
movie, movie_reason, show, show_reason, | |
book, book_reason, character, character_reason, blog): | |
# Convert age to int if it's a numpy number (from gradio Number input) | |
age = int(age) if age else 0 | |
favorites = { | |
"movie": movie, | |
"movie_reason": movie_reason, | |
"show": show, | |
"show_reason": show_reason, | |
"book": book, | |
"book_reason": book_reason, | |
"character": character, | |
"character_reason": character_reason | |
} | |
data = { | |
"name": name, | |
"age": age, | |
"interests": interests, | |
"transcript": transcript, | |
"learning_style": learning_style, | |
"favorites": favorites, | |
"blog": blog | |
} | |
os.makedirs("student_profiles", exist_ok=True) | |
json_path = os.path.join("student_profiles", f"{name.replace(' ', '_')}_profile.json") | |
with open(json_path, "w") as f: | |
json.dump(data, f, indent=2) | |
markdown_summary = f"""### Student Profile: {name} | |
**Age:** {age} | |
**Interests:** {interests} | |
**Learning Style:** {learning_style} | |
#### GPA Information: | |
- Weighted: {transcript['gpa'].get('weighted', 'N/A')} | |
- Unweighted: {transcript['gpa'].get('unweighted', 'N/A')} | |
#### Favorites: | |
- Movie: {favorites['movie']} ({favorites['movie_reason']}) | |
- Show: {favorites['show']} ({favorites['show_reason']}) | |
- Book: {favorites['book']} ({favorites['book_reason']}) | |
- Character: {favorites['character']} ({favorites['character_reason']}) | |
#### Blog: | |
{blog if blog else "_No blog provided_"} | |
""" | |
return markdown_summary | |
# ========== AI TEACHING ASSISTANT ========== | |
def load_profile(): | |
if not os.path.exists("student_profiles"): | |
return {} | |
files = [f for f in os.listdir("student_profiles") if f.endswith('.json')] | |
if files: | |
with open(os.path.join("student_profiles", files[0]), "r") as f: | |
return json.load(f) | |
return {} | |
def generate_response(message, history): | |
profile = load_profile() | |
if not profile: | |
return "Please complete and save your profile first using the previous tabs." | |
# Get profile data | |
learning_style = profile.get("learning_style", "") | |
transcript = profile.get("transcript", {}) | |
gpa = transcript.get("gpa", {}) | |
courses = [] | |
# Flatten all courses from all grades | |
if 'courses' in transcript: | |
if isinstance(transcript['courses'], dict): | |
for grade_courses in transcript['courses'].values(): | |
courses.extend(grade_courses) | |
elif isinstance(transcript['courses'], list): | |
courses = transcript['courses'] | |
# Common responses | |
greetings = ["hi", "hello", "hey"] | |
study_help = ["study", "learn", "prepare", "exam"] | |
grade_help = ["gpa", "grade point average", "grades"] | |
course_help = ["courses", "classes", "subjects"] | |
if any(greet in message.lower() for greet in greetings): | |
return f"Hello {profile.get('name', 'there')}! How can I help you today?" | |
elif any(word in message.lower() for word in grade_help): | |
return (f"Your GPA information:\n" | |
f"- Weighted: {gpa.get('weighted', 'N/A')}\n" | |
f"- Unweighted: {gpa.get('unweighted', 'N/A')}") | |
elif any(word in message.lower() for word in study_help): | |
# Analyze course performance to give personalized advice | |
strong_subjects = [c['name'] for c in courses if 'grade' in c and c['grade'] in ['A', 'A+', 'B+']] | |
weak_subjects = [c['name'] for c in courses if 'grade' in c and c['grade'] in ['D', 'F']] | |
response = "Here are some personalized study tips:\n" | |
if strong_subjects: | |
response += f"\nYou're doing well in: {', '.join(strong_subjects[:3])}\n" | |
response += "β Keep up the good work in these areas!\n" | |
if weak_subjects: | |
response += f"\nYou might want to focus more on: {', '.join(weak_subjects[:3])}\n" | |
response += "β Consider getting extra help or tutoring\n" | |
# Add learning style specific tips | |
if "Visual" in learning_style: | |
response += "\nVisual Learner Tip: Try creating diagrams or mind maps\n" | |
elif "Auditory" in learning_style: | |
response += "\nAuditory Learner Tip: Record yourself explaining concepts\n" | |
elif "Reading/Writing" in learning_style: | |
response += "\nReading/Writing Tip: Write summaries in your own words\n" | |
elif "Kinesthetic" in learning_style: | |
response += "\nKinesthetic Tip: Use physical objects to demonstrate concepts\n" | |
return response | |
elif any(word in message.lower() for word in course_help): | |
if not courses: | |
return "No course information available." | |
# Group by subject area | |
subjects = defaultdict(list) | |
for course in courses: | |
if 'name' in course: | |
# Extract first word as subject area | |
subject = course['name'].split()[0] | |
subjects[subject].append(course) | |
response = "Your course subjects:\n" | |
for subject, subject_courses in subjects.items(): | |
response += f"\n{subject} ({len(subject_courses)} courses)" | |
return response | |
elif "help" in message.lower(): | |
return ("I can help with:\n" | |
"- Your GPA information\n" | |
"- Personalized study tips\n" | |
"- Course information\n" | |
"- Learning style recommendations") | |
else: | |
return ("I'm your personalized teaching assistant. " | |
"Ask me about your GPA, courses, or study tips!") | |
# ========== GRADIO INTERFACE ========== | |
with gr.Blocks() as app: | |
with gr.Tab("Step 1: Upload Transcript"): | |
gr.Markdown("### Upload your transcript (PDF recommended)") | |
transcript_file = gr.File(label="Transcript file", file_types=[".pdf"]) | |
transcript_output = gr.Textbox(label="Transcript Results", lines=5) | |
transcript_data = gr.State() | |
transcript_file.change( | |
fn=parse_transcript, | |
inputs=transcript_file, | |
outputs=[transcript_output, transcript_data] | |
) | |
with gr.Tab("Step 2: Learning Style Quiz"): | |
gr.Markdown("### Learning Style Quiz (20 Questions)") | |
quiz_components = [] | |
for i, (question, options) in enumerate(zip(learning_style_questions, learning_style_options)): | |
quiz_components.append(gr.Radio(options, label=f"{i+1}. {question}")) | |
learning_output = gr.Textbox(label="Your Learning Style", lines=15) | |
gr.Button("Submit Quiz").click( | |
fn=learning_style_quiz, | |
inputs=quiz_components, | |
outputs=learning_output | |
) | |
with gr.Tab("Step 3: Personal Questions"): | |
name = gr.Textbox(label="What's your name?") | |
age = gr.Number(label="How old are you?", precision=0) | |
interests = gr.Textbox(label="What are your interests?") | |
movie = gr.Textbox(label="Favorite movie?") | |
movie_reason = gr.Textbox(label="Why do you like that movie?") | |
show = gr.Textbox(label="Favorite TV show?") | |
show_reason = gr.Textbox(label="Why do you like that show?") | |
book = gr.Textbox(label="Favorite book?") | |
book_reason = gr.Textbox(label="Why do you like that book?") | |
character = gr.Textbox(label="Favorite character?") | |
character_reason = gr.Textbox(label="Why do you like that character?") | |
blog_checkbox = gr.Checkbox(label="Do you want to write a blog?", value=False) | |
blog_text = gr.Textbox(label="Write your blog here", visible=False, lines=5) | |
blog_checkbox.change(lambda x: gr.update(visible=x), inputs=blog_checkbox, outputs=blog_text) | |
with gr.Tab("Step 4: Save & Review"): | |
output_summary = gr.Markdown() | |
save_btn = gr.Button("Save Profile") | |
save_btn.click( | |
fn=save_profile, | |
inputs=[name, age, interests, transcript_data, learning_output, | |
movie, movie_reason, show, show_reason, | |
book, book_reason, character, character_reason, blog_text], | |
outputs=output_summary | |
) | |
with gr.Tab("π€ AI Teaching Assistant"): | |
gr.Markdown("## Your Personalized Learning Assistant") | |
chatbot = gr.ChatInterface( | |
fn=generate_response, | |
examples=[ | |
"What's my GPA?", | |
"How should I study for my classes?", | |
"What subjects am I taking?" | |
] | |
) | |
if __name__ == "__main__": | |
app.launch() | |