import gradio as gr import pandas as pd import json import os import re from PyPDF2 import PdfReader from collections import defaultdict # ========== TRANSCRIPT PARSING FUNCTIONS ========== def parse_transcript(file): if file.name.endswith('.pdf'): text = '' reader = PdfReader(file) for page in reader.pages: page_text = page.extract_text() if page_text: text += page_text + '\n' # Grade level extraction grade_match = re.search(r'(Grade|Year)[\s:]*(\d+|Freshman|Sophomore|Junior|Senior)', text, re.IGNORECASE) grade_level = grade_match.group(2) if grade_match else "Unknown" # GPA extraction gpa_data = {'weighted': "N/A", 'unweighted': "N/A"} gpa_patterns = [ r'Weighted GPA[\s:]*(\d\.\d{1,2})', r'GPA \(Weighted\)[\s:]*(\d\.\d{1,2})', r'Unweighted GPA[\s:]*(\d\.\d{1,2})', r'GPA \(Unweighted\)[\s:]*(\d\.\d{1,2})', r'GPA[\s:]*(\d\.\d{1,2})' ] for pattern in gpa_patterns: for match in re.finditer(pattern, text, re.IGNORECASE): gpa_value = match.group(1) if 'weighted' in pattern.lower(): gpa_data['weighted'] = gpa_value elif 'unweighted' in pattern.lower(): gpa_data['unweighted'] = gpa_value else: if gpa_data['unweighted'] == "N/A": gpa_data['unweighted'] = gpa_value if gpa_data['weighted'] == "N/A": gpa_data['weighted'] = gpa_value output_text = f"Grade Level: {grade_level}\n\n" if gpa_data['weighted'] != "N/A" or gpa_data['unweighted'] != "N/A": output_text += "GPA Information:\n" if gpa_data['unweighted'] != "N/A": output_text += f"- Unweighted GPA: {gpa_data['unweighted']}\n" if gpa_data['weighted'] != "N/A": output_text += f"- Weighted GPA: {gpa_data['weighted']}\n" else: output_text += "No GPA information found\n" return output_text, { "gpa": gpa_data, "grade_level": grade_level } else: return "Currently only PDF transcripts are supported", 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:" ] 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)"] ] 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()) dominant_styles = [style for style, score in scores.items() if score == max_score] if len(dominant_styles) == 1: return f"Your primary learning style is: {dominant_styles[0]}" else: return f"You have multiple strong learning styles: {', '.join(dominant_styles)}" # ========== PROFILE MANAGEMENT ========== def save_profile(name, age, interests, transcript, learning_style, favorites, blog): 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) return "Profile saved successfully!" def load_profile(): 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 {} # ========== RULE-BASED TEACHING ASSISTANT ========== def generate_response(message, history, profile_data): # Get learning style from profile learning_style = profile_data.get("learning_style", "") # Common responses greetings = ["hi", "hello", "hey"] study_help = ["study", "learn", "prepare"] grade_help = ["grade", "gpa", "score"] if any(greet in message.lower() for greet in greetings): return f"Hello {profile_data.get('name', 'there')}! How can I help you today?" elif any(word in message.lower() for word in study_help): if "Visual" in learning_style: return ("Based on your visual learning style, I recommend:\n" "- Creating mind maps or diagrams\n" "- Using color-coded notes\n" "- Watching educational videos") elif "Auditory" in learning_style: return ("Based on your auditory learning style, I recommend:\n" "- Recording lectures and listening to them\n" "- Participating in study groups\n" "- Explaining concepts out loud") elif "Reading/Writing" in learning_style: return ("Based on your reading/writing learning style, I recommend:\n" "- Writing detailed notes\n" "- Creating summaries in your own words\n" "- Reading textbooks and articles") elif "Kinesthetic" in learning_style: return ("Based on your kinesthetic learning style, I recommend:\n" "- Hands-on practice\n" "- Creating physical models\n" "- Taking frequent movement breaks") else: return ("Here are some general study tips:\n" "- Break study sessions into 25-minute chunks\n" "- Review material regularly\n" "- Teach concepts to someone else") elif any(word in message.lower() for word in grade_help): gpa = profile_data.get("transcript", {}).get("gpa", {}) return (f"Your GPA information:\n" f"- Unweighted: {gpa.get('unweighted', 'N/A')}\n" f"- Weighted: {gpa.get('weighted', 'N/A')}\n\n" "To improve your grades, try:\n" "- Setting specific goals\n" "- Meeting with teachers\n" "- Developing a study schedule") elif "help" in message.lower(): return ("I can help with:\n" "- Study tips based on your learning style\n" "- GPA and grade information\n" "- General academic advice\n\n" "Try asking about study strategies or your grades!") else: return ("I'm your personalized teaching assistant. " "I can help with study tips, grade information, and academic advice. " "Try asking about how to study for your classes!") # ========== GRADIO INTERFACE ========== with gr.Blocks() as app: # Profile tabs with gr.Tab("Step 1: Upload Transcript"): transcript_file = gr.File(label="Upload your transcript (PDF)") transcript_output = gr.Textbox(label="Transcript Output") transcript_data = gr.State() transcript_file.change(parse_transcript, inputs=transcript_file, outputs=[transcript_output, transcript_data]) with gr.Tab("Step 2: Learning Style Quiz"): 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="Learning Style Result") gr.Button("Submit Quiz").click( 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?") 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 Profile"): save_btn = gr.Button("Save Profile") save_output = gr.Textbox(label="Save Status") save_btn.click( save_profile, inputs=[name, age, interests, transcript_data, learning_output, {"movie": movie, "movie_reason": movie_reason, "show": show, "show_reason": show_reason, "book": book, "book_reason": book_reason, "character": character, "character_reason": character_reason}, blog_text], outputs=save_output ) # AI Teaching Assistant Tab with gr.Tab("🤖 Teaching Assistant"): gr.Markdown("## Your Personalized Learning Assistant") chatbot = gr.ChatInterface( fn=lambda message, history: generate_response(message, history, load_profile()), examples=[ "How should I study for my next test?", "What's my GPA information?", "Help me with study strategies", "How can I improve my grades?" ] ) app.launch()