Spaces:
Runtime error
Runtime error
import gradio as gr | |
import pandas as pd | |
import PyPDF2 | |
import json | |
import re | |
# Parse uploaded transcript file | |
def parse_transcript(file): | |
if file.name.endswith('.csv'): | |
df = pd.read_csv(file.name) | |
elif file.name.endswith(('.xls', '.xlsx')): | |
df = pd.read_excel(file.name) | |
elif file.name.endswith('.pdf'): | |
reader = PyPDF2.PdfReader(file) | |
text = "" | |
for page in reader.pages: | |
text += page.extract_text() or "" | |
df = pd.DataFrame({'Transcript_Text': [text]}) | |
else: | |
raise ValueError("Unsupported file format. Use .csv, .xlsx, or .pdf") | |
return df | |
# Extract student info | |
def extract_transcript_info(df): | |
transcript_text = df['Transcript_Text'].iloc[0] if 'Transcript_Text' in df.columns else '' | |
info = {} | |
gpa_match = re.search(r'(GPA|Grade Point Average)[^\d]*(\d+\.\d+)', transcript_text, re.IGNORECASE) | |
if gpa_match: | |
info['GPA'] = gpa_match.group(2) | |
grade_match = re.search(r'Grade:?[\s]*(\d{1,2})', transcript_text, re.IGNORECASE) | |
if grade_match: | |
info['Grade_Level'] = grade_match.group(1) | |
courses = re.findall(r'(?i)\b([A-Z][a-zA-Z\s&/]+)\s+(\d{1,3})\b', transcript_text) | |
if courses: | |
info['Courses'] = list(set([c[0].strip() for c in courses])) | |
return info | |
# Learning style questions - from educationplanner.org | |
learning_style_questions = [ | |
"When you are learning something new, you prefer to:", | |
"When you are at home, you like to:", | |
"When you spell a word, you remember it by:", | |
"When you read, you:", | |
"When you write, you:", | |
"When you listen to music, you:", | |
"When you work at solving a problem, you:", | |
"When you give someone directions, you:", | |
"When you are concentrating, you:", | |
"When you meet someone new, you remember them by:" | |
] | |
learning_style_answers = [ | |
["Watch someone do it", "Listen to someone explain it", "Read about it"], | |
["Watch TV or play video games", "Listen to music or talk to people", "Read books or write stories"], | |
["Seeing the word in your mind", "Saying the word out loud", "Writing the word down"], | |
["See the action in your mind", "Hear the characters talk", "Focus on the written words"], | |
["Use diagrams or doodles", "Talk about ideas", "Write detailed notes"], | |
["Appreciate the rhythm and melodies", "Easily remember lyrics", "Analyze the lyrics"], | |
["Visualize the solution", "Discuss the problem", "Write out the steps"], | |
["Draw a map", "Give spoken directions", "Write directions"], | |
["Picture things", "Say things out loud", "Write or read quietly"], | |
["Remember faces", "Remember names or voices", "Remember what you wrote about them"] | |
] | |
style_count_map = {0: "visual", 1: "auditory", 2: "reading/writing"} | |
def learning_style_quiz(*answers): | |
scores = {'visual': 0, 'auditory': 0, 'reading/writing': 0} | |
for i, ans in enumerate(answers): | |
if i < len(learning_style_answers): | |
options = learning_style_answers[i] | |
if ans in options: | |
index = options.index(ans) | |
style = style_count_map[index] | |
scores[style] += 1 | |
max_score = max(scores.values()) | |
best_styles = [style.capitalize() for style, score in scores.items() if score == max_score] | |
return ", ".join(best_styles) | |
# PanoramaEd categories and multiple choice questions | |
get_to_know_categories = { | |
"All About Me": [ | |
("What’s your favorite way to spend a day off?", []), | |
("If you could only eat one food for the rest of your life, what would it be?", []), | |
("Do you have any pets? If so, what are their names?", []), | |
("If you could travel anywhere in the world, where would you go?", []), | |
("What’s your favorite holiday or tradition?", []), | |
("What are some of your favorite movies or shows?", []), | |
("Do you have a favorite book or book series? Why?", []), | |
("Who is a character from a show, book, or movie that you relate to? Why?", []), | |
("If you could be any fictional character, who would you be and why?", []) | |
], | |
"Hopes and Dreams": [ | |
("What do you want to be when you grow up?", []), | |
("What’s something you hope to achieve this year?", []), | |
("If you could change the world in one way, what would you do?", []), | |
("What are you most proud of?", []), | |
("What’s a big dream you have for your future?", []) | |
], | |
"School Life": [ | |
("What’s your favorite subject in school?", []), | |
("What’s something that makes learning easier for you?", []), | |
("Do you prefer working alone or in groups?", []), | |
("What helps you feel confident in class?", []), | |
("What’s something you’re good at in school?", []) | |
], | |
"Relationships": [ | |
("Who do you look up to and why?", []), | |
("Who is someone that makes you feel safe and supported?", []), | |
("Do you have a best friend? What do you like to do together?", []), | |
("What’s one thing you wish people knew about you?", []), | |
("What’s something kind you’ve done for someone else?", []) | |
] | |
} | |
# Generators for output summaries | |
def generate_learning_plan(info): | |
level = info.get("Grade_Level", "unknown") | |
courses = info.get("Courses", []) | |
gpa = info.get("GPA", "N/A") | |
return f""" | |
📘 **Personalized Learning Plan** | |
- Grade Level: {level} | |
- GPA: {gpa} | |
- Suggested Focus Areas: {', '.join(courses[:3]) if courses else 'N/A'} | |
- Goals: Strengthen key subjects, explore interests, and build study habits. | |
""" | |
def generate_learning_style_summary(style): | |
return f""" | |
🧠 **Learning Style Summary** | |
You are a **{style}** learner. That means you learn best through {"visual aids like charts and images" if "Visual" in style else "listening and verbal instruction" if "Auditory" in style else "reading and writing-based methods"}. | |
""" | |
def generate_motivation_section(responses): | |
hopes = [ans for q, ans in responses.items() if "hope" in q.lower() or "dream" in q.lower()] | |
return f""" | |
💡 **Motivational Summary** | |
Your dreams are powerful: {'; '.join(hopes) if hopes else 'You are filled with potential!'}. | |
Believe in yourself and keep moving forward. | |
""" | |
# Save all answers into profile | |
def save_profile(file, *inputs): | |
if not file: | |
return "⚠️ Please upload your transcript." | |
quiz_answers = inputs[:len(learning_style_questions)] | |
if any(ans is None for ans in quiz_answers): | |
return "⚠️ Please answer all the learning style questions." | |
blog_checkbox = inputs[len(learning_style_questions)] | |
blog_text = inputs[len(learning_style_questions)+1] | |
category_answers = inputs[len(learning_style_questions)+2:] | |
if any(ans.strip() == "" for ans in category_answers): | |
return "⚠️ Please complete all 'Get to Know You' sections before saving." | |
if blog_checkbox and blog_text.strip() == "": | |
return "⚠️ You checked the blog option but didn’t write anything. Please write your mini blog or uncheck the option." | |
df = parse_transcript(file) | |
transcript_info = extract_transcript_info(df) | |
learning_type = learning_style_quiz(*quiz_answers) | |
question_texts = [q for cat in get_to_know_categories.values() for q, _ in cat] | |
responses = dict(zip(question_texts, category_answers)) | |
profile = { | |
"transcript": df.to_dict(orient='records'), | |
"transcript_info": transcript_info, | |
"learning_style": learning_type, | |
"get_to_know_answers": responses, | |
"blog": blog_text if blog_checkbox else "[User chose to skip this section]" | |
} | |
summary = { | |
"Learning_Plan": generate_learning_plan(transcript_info), | |
"Style_Summary": generate_learning_style_summary(learning_type), | |
"Motivation": generate_motivation_section(responses) | |
} | |
with open("student_profile.json", "w") as f: | |
json.dump(profile, f, indent=4) | |
with open("student_summary.md", "w") as f: | |
f.write(summary["Learning_Plan"] + '\n' + summary["Style_Summary"] + '\n' + summary["Motivation"]) | |
return f"✅ Profile saved! Your learning style is: {learning_type}" | |
# Build Gradio UI | |
with gr.Blocks() as demo: | |
gr.Markdown("## 🎓 Personalized AI Student Assistant") | |
with gr.Row(): | |
file = gr.File(label="📄 Upload Your Transcript (.csv, .xlsx, .pdf)") | |
with gr.Column(): | |
gr.Markdown("### 🧠 Learning Style Discovery") | |
quiz_components = [] | |
for i, (question, options) in enumerate(zip(learning_style_questions, learning_style_answers)): | |
quiz_components.append(gr.Radio( | |
choices=options, | |
label=f"{i+1}. {question}" | |
)) | |
category_inputs = [] | |
for category, questions in get_to_know_categories.items(): | |
gr.Markdown(f"### 📘 {category}") | |
for q_text, _ in questions: | |
category_inputs.append(gr.Textbox(label=q_text)) | |
blog_checkbox = gr.Checkbox(label="📝 I'd like to write a mini blog about myself") | |
blog_text = gr.Textbox(lines=5, label="✍️ Mini Blog", visible=False) | |
blog_checkbox.change(fn=lambda x: gr.update(visible=x), inputs=blog_checkbox, outputs=blog_text) | |
submit = gr.Button("🗕️ Save My Profile") | |
output = gr.Textbox(label="Status") | |
submit.click(fn=save_profile, | |
inputs=[file, *quiz_components, blog_checkbox, blog_text, *category_inputs], | |
outputs=[output]) | |
# Assistant component functions | |
def load_student_profile(): | |
try: | |
with open("student_profile.json", "r") as f: | |
return json.load(f) | |
except FileNotFoundError: | |
return None | |
def generate_study_tips(learning_style): | |
tips = { | |
"Visual": [ | |
"Use color-coding in your notes", | |
"Create mind maps or diagrams", | |
"Watch educational videos", | |
"Use flashcards with images", | |
"Draw pictures to represent concepts" | |
], | |
"Auditory": [ | |
"Record lectures and listen to them", | |
"Explain concepts out loud to yourself", | |
"Participate in study groups", | |
"Use mnemonic devices with rhymes", | |
"Listen to educational podcasts" | |
], | |
"Reading/writing": [ | |
"Rewrite your notes in your own words", | |
"Create detailed outlines", | |
"Write summaries of what you learn", | |
"Read textbooks and articles", | |
"Keep a learning journal" | |
] | |
} | |
return tips.get(learning_style.split(", ")[0], [] | |
def generate_subject_specific_advice(courses): | |
advice = { | |
"Math": [ | |
"Practice problems daily", | |
"Focus on understanding concepts, not just memorization", | |
"Show all your work step-by-step", | |
"Relate math to real-world applications" | |
], | |
"Science": [ | |
"Conduct simple experiments at home", | |
"Create concept maps of scientific processes", | |
"Relate concepts to everyday phenomena", | |
"Watch science documentaries" | |
], | |
"English": [ | |
"Read diverse genres of literature", | |
"Keep a vocabulary journal", | |
"Practice writing in different styles", | |
"Analyze author's techniques" | |
], | |
"History": [ | |
"Create timelines of events", | |
"Connect historical events to current affairs", | |
"Watch historical films (and fact-check them)", | |
"Debate different historical perspectives" | |
] | |
} | |
default_advice = [ | |
"Break study sessions into 25-minute chunks", | |
"Review material regularly, not just before tests", | |
"Connect new information to what you already know", | |
"Teach the material to someone else" | |
] | |
course_advice = [] | |
for course in courses: | |
for subject in advice: | |
if subject.lower() in course.lower(): | |
course_advice.extend(advice[subject]) | |
return course_advice if course_advice else default_advice | |
def generate_personalized_message(responses): | |
hobbies = [ans for q, ans in responses.items() if "favorite way to spend" in q.lower()] | |
goals = [ans for q, ans in responses.items() if "want to be when" in q.lower() or "hope to achieve" in q.lower()] | |
messages = [] | |
if hobbies: | |
messages.append(f"I see you enjoy {hobbies[0].lower()}. Let's find ways to connect that to your learning!") | |
if goals: | |
messages.append(f"Your goal to {goals[0].lower()} is inspiring! Here's how we can work toward that:") | |
return "\n".join(messages) if messages else "I'm excited to help you achieve your learning goals!" | |
def assistant_response(message, history): | |
profile = load_student_profile() | |
if not profile: | |
return "Please complete and save your profile first using the previous tabs." | |
# Get profile data | |
learning_style = profile["learning_style"] | |
courses = profile["transcript_info"].get("Courses", []) | |
responses = profile["get_to_know_answers"] | |
# Generate personalized content | |
study_tips, _ = generate_study_tips(learning_style) | |
subject_advice = generate_subject_specific_advice(courses) | |
personal_message = generate_personalized_message(responses) | |
# Common responses | |
if "help" in message.lower() or "support" in message.lower(): | |
return f""" | |
{personal_message} | |
Here's how I can help: | |
1. Provide study tips matching your {learning_style} learning style | |
2. Offer subject-specific advice for {', '.join(courses[:3]) if courses else 'your courses'} | |
3. Answer questions about your learning plan | |
4. Help you stay motivated | |
What would you like to focus on today? | |
""" | |
elif "tip" in message.lower() or "advice" in message.lower(): | |
return f""" | |
📚 **Personalized Study Advice** | |
🎨 For your {learning_style} learning style: | |
{'\n'.join(f'- {tip}' for tip in study_tips)} | |
📖 Subject-specific tips: | |
{'\n'.join(f'- {advice}' for advice in subject_advice)} | |
""" | |
elif "plan" in message.lower() or "schedule" in message.lower(): | |
return """ | |
📅 **Suggested Study Schedule** | |
- Morning (30 min): Review previous material | |
- Afternoon (45 min): Practice new concepts | |
- Evening (20 min): Quick recap | |
- Weekend: Longer project work | |
Remember to take breaks every 25-30 minutes! | |
""" | |
elif "motiv" in message.lower(): | |
return f""" | |
💪 **Motivation Boost** | |
{personal_message} | |
Remember: | |
- Progress is more important than perfection | |
- Small steps add up to big achievements | |
- Your {learning_style} learning style is your superpower! | |
""" | |
else: | |
return f""" | |
{personal_message} | |
I'm your personalized learning assistant! Here are things I can help with: | |
- Study tips and techniques | |
- Learning plan advice | |
- Motivation and encouragement | |
- Answering questions about your progress | |
Try asking about: | |
- "How should I study for my classes?" | |
- "What's the best way to learn based on my style?" | |
- "Can you help me make a study plan?" | |
""" | |
# Add assistant tab to the interface | |
with gr.Tab("🤖 AI Teaching Assistant"): | |
gr.Markdown("## 🎓 Your Personalized Learning Assistant") | |
gr.Markdown("Chat with your AI assistant to get personalized learning support based on your profile.") | |
chatbot = gr.ChatInterface( | |
assistant_response, | |
examples=[ | |
"How should I study based on my learning style?", | |
"Give me study tips for my courses", | |
"Help me make a study plan", | |
"I need motivation" | |
] | |
) | |
if __name__ == '__main__': | |
demo.launch() |