Spaces:
Runtime error
Runtime error
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() |