File size: 15,638 Bytes
328b44a
1d5a1b0
 
 
 
 
a6c95c9
1d5a1b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a6c95c9
1d5a1b0
 
 
7c9f1a1
9a20088
7c9f1a1
9a20088
1d5a1b0
 
 
 
 
 
 
7c9f1a1
1c96b69
a6c95c9
 
 
 
 
 
 
 
 
 
1c96b69
 
 
29859bc
 
 
 
 
 
 
 
 
 
1c96b69
 
64fb9b0
 
1c96b69
a6c95c9
ef2f775
8a19c8a
 
 
 
ed8a781
 
8a19c8a
ef2f775
64fb9b0
 
ef2f775
64fb9b0
1d5a1b0
7c9f1a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aa96e64
7c9f1a1
 
ef2f775
7c9f1a1
 
 
ef2f775
7c9f1a1
 
 
ef2f775
7c9f1a1
 
ef2f775
7c9f1a1
 
aa96e64
7c9f1a1
 
 
ef2f775
7c9f1a1
 
ef2f775
7c9f1a1
 
 
 
 
 
 
ef2f775
7c9f1a1
 
 
 
 
ef2f775
7c9f1a1
 
ef2f775
7c9f1a1
 
aa96e64
2af3bb3
aa96e64
9a20088
53b63a7
aa96e64
ef2f775
aa96e64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a20088
aa96e64
 
 
9a20088
aa96e64
 
 
9a20088
373d965
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d5a1b0
373d965
 
 
 
 
 
 
 
 
 
 
 
 
1d5a1b0
9a20088
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
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()