File size: 7,236 Bytes
1d5a1b0
 
 
 
 
 
a6c95c9
1d5a1b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a6c95c9
1d5a1b0
 
 
9a20088
 
 
 
 
 
 
 
 
 
 
1d5a1b0
 
 
 
 
 
 
a97e196
1c96b69
a6c95c9
 
 
 
 
 
 
 
 
 
1c96b69
 
 
29859bc
 
 
 
 
 
 
 
 
 
1c96b69
 
64fb9b0
 
1c96b69
a6c95c9
ef2f775
8a19c8a
 
 
 
ed8a781
 
8a19c8a
ef2f775
64fb9b0
 
ef2f775
64fb9b0
1d5a1b0
a97e196
aa96e64
9a20088
 
 
ef2f775
9a20088
 
 
ef2f775
9a20088
 
 
ef2f775
9a20088
 
ef2f775
9a20088
 
aa96e64
9a20088
 
 
ef2f775
9a20088
 
ef2f775
9a20088
 
 
 
 
 
 
ef2f775
9a20088
 
 
 
 
ef2f775
9a20088
 
ef2f775
9a20088
 
aa96e64
a97e196
 
853030c
9a20088
 
aa96e64
9a20088
53b63a7
aa96e64
ef2f775
aa96e64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a20088
aa96e64
 
 
9a20088
aa96e64
 
 
9a20088
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
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 = {}
    name_match = re.search(r"Name[:\s]+([A-Z][a-z]+\s[A-Z][a-z]+)", transcript_text)
    if name_match:
        info['Name'] = name_match.group(1)
    gpa_match = re.findall(r'(GPA|Grade Point Average)[^\d]*(\d+\.\d+)', transcript_text, re.IGNORECASE)
    if gpa_match:
        if len(gpa_match) == 1:
            info['GPA'] = gpa_match[0][1]
        elif len(gpa_match) >= 2:
            info['Unweighted_GPA'] = gpa_match[0][1]
            info['Weighted_GPA'] = gpa_match[1][1]
    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
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)

# Save profile function
def save_profile(file, *inputs):
    try:
        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"])

        # Reset the inputs and clear the fields
        return f"βœ… Profile saved! Your learning style is: {learning_type}", *[gr.update(value="") for _ in inputs] + [gr.update(value=None) for _ in inputs]

    except Exception as e:
        return f"❌ Error: {str(e)}"

# 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])

if __name__ == '__main__':
    demo.launch()