Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -1022,7 +1022,7 @@ class ProfileManager:
|
|
1022 |
transcript: Dict, learning_style: str,
|
1023 |
movie: str, movie_reason: str, show: str, show_reason: str,
|
1024 |
book: str, book_reason: str, character: str, character_reason: str,
|
1025 |
-
blog: str
|
1026 |
"""Save student profile with validation."""
|
1027 |
try:
|
1028 |
# Validate required fields
|
@@ -1151,19 +1151,19 @@ class ProfileManager:
|
|
1151 |
"""Generate markdown summary of the profile."""
|
1152 |
transcript = data.get("transcript", {})
|
1153 |
favorites = data.get("favorites", {})
|
1154 |
-
learning_style = data.get("learning_style", "Not assessed")
|
1155 |
|
1156 |
-
# Extract just the learning style name
|
1157 |
-
|
1158 |
-
if "Your primary learning style is" in
|
1159 |
-
|
1160 |
-
|
|
|
1161 |
|
1162 |
markdown = f"""## Student Profile: {data['name']}
|
1163 |
### Basic Information
|
1164 |
- **Age:** {data['age']}
|
1165 |
- **Interests:** {data.get('interests', 'Not specified')}
|
1166 |
-
- **Learning Style:** {
|
1167 |
### Academic Information
|
1168 |
{self._format_transcript(transcript)}
|
1169 |
### Favorites
|
@@ -1182,52 +1182,13 @@ class ProfileManager:
|
|
1182 |
|
1183 |
def _format_transcript(self, transcript: Dict) -> str:
|
1184 |
"""Format transcript data for display."""
|
1185 |
-
if not transcript:
|
1186 |
return "_No transcript information available_"
|
1187 |
|
1188 |
-
display = ""
|
|
|
1189 |
|
1190 |
-
|
1191 |
-
if "student_info" in transcript:
|
1192 |
-
# Structured transcript format
|
1193 |
-
student = transcript.get("student_info", {})
|
1194 |
-
display += f"**Name:** {student.get('name', 'Unknown')}\n"
|
1195 |
-
display += f"**Student ID:** {student.get('id', 'Unknown')}\n"
|
1196 |
-
display += f"**Current Grade:** {student.get('current_grade', 'Unknown')}\n"
|
1197 |
-
display += f"**Graduation Year:** {student.get('graduation_year', 'Unknown')}\n"
|
1198 |
-
|
1199 |
-
if 'unweighted_gpa' in student and 'weighted_gpa' in student:
|
1200 |
-
display += f"**Unweighted GPA:** {student['unweighted_gpa']}\n"
|
1201 |
-
display += f"**Weighted GPA:** {student['weighted_gpa']}\n"
|
1202 |
-
elif 'gpa' in student:
|
1203 |
-
display += f"**GPA:** {student['gpa']}\n"
|
1204 |
-
|
1205 |
-
if 'total_credits' in student:
|
1206 |
-
display += f"**Total Credits Earned:** {student['total_credits']}\n"
|
1207 |
-
if 'community_service_hours' in student:
|
1208 |
-
display += f"**Community Service Hours:** {student['community_service_hours']}\n"
|
1209 |
-
|
1210 |
-
# Course History
|
1211 |
-
if "course_history" in transcript:
|
1212 |
-
display += "\n## Course History\n"
|
1213 |
-
courses_by_year = defaultdict(list)
|
1214 |
-
for course in transcript["course_history"]:
|
1215 |
-
year_key = course.get("school_year", course.get("completion_date", "Unknown"))
|
1216 |
-
courses_by_year[year_key].append(course)
|
1217 |
-
|
1218 |
-
for year in sorted(courses_by_year.keys()):
|
1219 |
-
display += f"\n### {year}\n"
|
1220 |
-
for course in courses_by_year[year]:
|
1221 |
-
display += f"- **{course.get('course_code', '')} {course.get('description', 'Unnamed course')}**\n"
|
1222 |
-
display += f" Subject: {course.get('subject', 'N/A')} | "
|
1223 |
-
display += f"Grade: {course.get('grade', 'N/A')} | "
|
1224 |
-
display += f"Credits: {course.get('credits', 'N/A')}\n"
|
1225 |
-
|
1226 |
-
elif "courses" in transcript:
|
1227 |
-
# Simple course format
|
1228 |
-
display += "\n## Course History\n"
|
1229 |
-
courses_by_grade = transcript["courses"]
|
1230 |
-
|
1231 |
for grade in sorted(courses_by_grade.keys(), key=lambda x: int(x) if x.isdigit() else x):
|
1232 |
display += f"\n**Grade {grade}**\n"
|
1233 |
for course in courses_by_grade[grade]:
|
@@ -1237,14 +1198,259 @@ class ProfileManager:
|
|
1237 |
if 'credits' in course:
|
1238 |
display += f" | Credits: {course['credits']}"
|
1239 |
display += f" | Year: {course.get('year', 'N/A')}\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1240 |
|
1241 |
-
|
1242 |
-
gpa = transcript['gpa']
|
1243 |
-
display += "\n**GPA**\n"
|
1244 |
-
display += f"- Unweighted: {gpa.get('unweighted', 'N/A')}\n"
|
1245 |
-
display += f"- Weighted: {gpa.get('weighted', 'N/A')}\n"
|
1246 |
|
1247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1248 |
|
1249 |
# ========== GRADIO INTERFACE ==========
|
1250 |
def create_interface():
|
@@ -1274,7 +1480,6 @@ def create_interface():
|
|
1274 |
.quiz-question { margin-bottom: 15px; padding: 15px; background: #f5f5f5; border-radius: 5px; }
|
1275 |
.quiz-results { margin-top: 20px; padding: 20px; background: #e8f5e9; border-radius: 8px; }
|
1276 |
.error-message { color: #d32f2f; background-color: #ffebee; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
1277 |
-
.blog-textbox { margin-top: 15px; }
|
1278 |
|
1279 |
/* Dark mode support */
|
1280 |
.dark .tab-content { background-color: #2d2d2d !important; border-color: #444 !important; }
|
@@ -1368,8 +1573,6 @@ def create_interface():
|
|
1368 |
error_msg = f"❌ Error: {str(e)}"
|
1369 |
if "PDF" in str(e):
|
1370 |
error_msg += "\n\nTIPS FOR PDF FILES:\n1. Try opening and re-saving the PDF\n2. Ensure it's not password protected\n3. Try converting to an image"
|
1371 |
-
elif "image" in str(e).lower():
|
1372 |
-
error_msg += "\n\nTIPS FOR IMAGE FILES:\n1. Ensure the image is clear and well-lit\n2. Try cropping to just the transcript area\n3. Avoid blurry or low-resolution images"
|
1373 |
return (
|
1374 |
error_msg,
|
1375 |
None,
|
@@ -1481,14 +1684,6 @@ def create_interface():
|
|
1481 |
placeholder="e.g., Science, Music, Sports, Art..."
|
1482 |
)
|
1483 |
|
1484 |
-
# Add the blog textbox here
|
1485 |
-
blog = gr.Textbox(
|
1486 |
-
label="Personal Blog (Optional)",
|
1487 |
-
placeholder="Share your thoughts, goals, or anything you'd like to remember...",
|
1488 |
-
lines=4,
|
1489 |
-
elem_classes="blog-textbox"
|
1490 |
-
)
|
1491 |
-
|
1492 |
save_personal_btn = gr.Button("Save Information", variant="primary")
|
1493 |
save_confirmation = gr.HTML(visible=False)
|
1494 |
|
@@ -1503,8 +1698,16 @@ def create_interface():
|
|
1503 |
book_reason = gr.Textbox(label="Why do you like it?", lines=2)
|
1504 |
character = gr.Textbox(label="Favorite Character (from any story)")
|
1505 |
character_reason = gr.Textbox(label="Why do you like them?", lines=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1506 |
|
1507 |
-
def save_personal_info(name, age, interests, current_tab_status
|
1508 |
try:
|
1509 |
name = validate_name(name)
|
1510 |
age = validate_age(age)
|
@@ -1530,7 +1733,7 @@ def create_interface():
|
|
1530 |
|
1531 |
save_personal_btn.click(
|
1532 |
fn=save_personal_info,
|
1533 |
-
inputs=[name, age, interests, tab_completed
|
1534 |
outputs=[tab_completed, step3, step4, save_confirmation, nav_message]
|
1535 |
)
|
1536 |
|
@@ -1633,12 +1836,12 @@ def create_interface():
|
|
1633 |
)
|
1634 |
|
1635 |
clear_btn.click(
|
1636 |
-
fn=lambda: [gr.update(value="") for _ in range(
|
1637 |
outputs=[
|
1638 |
name, age, interests,
|
1639 |
movie, movie_reason, show, show_reason,
|
1640 |
book, book_reason, character, character_reason,
|
1641 |
-
|
1642 |
]
|
1643 |
)
|
1644 |
|
|
|
1022 |
transcript: Dict, learning_style: str,
|
1023 |
movie: str, movie_reason: str, show: str, show_reason: str,
|
1024 |
book: str, book_reason: str, character: str, character_reason: str,
|
1025 |
+
blog: str) -> str:
|
1026 |
"""Save student profile with validation."""
|
1027 |
try:
|
1028 |
# Validate required fields
|
|
|
1151 |
"""Generate markdown summary of the profile."""
|
1152 |
transcript = data.get("transcript", {})
|
1153 |
favorites = data.get("favorites", {})
|
|
|
1154 |
|
1155 |
+
# Extract just the learning style name
|
1156 |
+
learning_style = data.get("learning_style", "")
|
1157 |
+
if "Your primary learning style is:" in learning_style:
|
1158 |
+
style_match = re.search(r"Your primary learning style is: \*\*(.*?)\*\*", learning_style)
|
1159 |
+
if style_match:
|
1160 |
+
learning_style = style_match.group(1)
|
1161 |
|
1162 |
markdown = f"""## Student Profile: {data['name']}
|
1163 |
### Basic Information
|
1164 |
- **Age:** {data['age']}
|
1165 |
- **Interests:** {data.get('interests', 'Not specified')}
|
1166 |
+
- **Learning Style:** {learning_style}
|
1167 |
### Academic Information
|
1168 |
{self._format_transcript(transcript)}
|
1169 |
### Favorites
|
|
|
1182 |
|
1183 |
def _format_transcript(self, transcript: Dict) -> str:
|
1184 |
"""Format transcript data for display."""
|
1185 |
+
if not transcript or "courses" not in transcript:
|
1186 |
return "_No transcript information available_"
|
1187 |
|
1188 |
+
display = "#### Course History\n"
|
1189 |
+
courses_by_grade = transcript["courses"]
|
1190 |
|
1191 |
+
if isinstance(courses_by_grade, dict):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1192 |
for grade in sorted(courses_by_grade.keys(), key=lambda x: int(x) if x.isdigit() else x):
|
1193 |
display += f"\n**Grade {grade}**\n"
|
1194 |
for course in courses_by_grade[grade]:
|
|
|
1198 |
if 'credits' in course:
|
1199 |
display += f" | Credits: {course['credits']}"
|
1200 |
display += f" | Year: {course.get('year', 'N/A')}\n"
|
1201 |
+
|
1202 |
+
if 'gpa' in transcript:
|
1203 |
+
gpa = transcript['gpa']
|
1204 |
+
display += "\n**GPA**\n"
|
1205 |
+
display += f"- Unweighted: {gpa.get('unweighted', 'N/A')}\n"
|
1206 |
+
display += f"- Weighted: {gpa.get('weighted', 'N/A')}\n"
|
1207 |
+
|
1208 |
+
return display
|
1209 |
+
|
1210 |
+
# Initialize profile manager
|
1211 |
+
profile_manager = ProfileManager()
|
1212 |
+
|
1213 |
+
# ========== AI TEACHING ASSISTANT ==========
|
1214 |
+
class TeachingAssistant:
|
1215 |
+
def __init__(self):
|
1216 |
+
self.context_history = []
|
1217 |
+
self.max_context_length = 5 # Keep last 5 exchanges for context
|
1218 |
+
|
1219 |
+
async def generate_response(self, message: str, history: List[List[Union[str, None]]], session_token: str) -> str:
|
1220 |
+
"""Generate personalized response based on student profile and context."""
|
1221 |
+
try:
|
1222 |
+
# Load profile with session token
|
1223 |
+
profile = profile_manager.load_profile(session_token=session_token)
|
1224 |
+
if not profile:
|
1225 |
+
return "Please complete and save your profile first using the previous tabs."
|
1226 |
+
|
1227 |
+
# Update context history
|
1228 |
+
self._update_context(message, history)
|
1229 |
+
|
1230 |
+
# Extract profile information
|
1231 |
+
name = profile.get("name", "there")
|
1232 |
+
learning_style = profile.get("learning_style", "")
|
1233 |
+
grade_level = profile.get("transcript", {}).get("grade_level", "unknown")
|
1234 |
+
gpa = profile.get("transcript", {}).get("gpa", {})
|
1235 |
+
interests = profile.get("interests", "")
|
1236 |
+
courses = profile.get("transcript", {}).get("courses", {})
|
1237 |
+
favorites = profile.get("favorites", {})
|
1238 |
+
|
1239 |
+
# Process message with context
|
1240 |
+
response = await self._process_message(message, profile)
|
1241 |
+
|
1242 |
+
# Add follow-up suggestions
|
1243 |
+
if "study" in message.lower() or "learn" in message.lower():
|
1244 |
+
response += "\n\nWould you like me to suggest a study schedule based on your courses?"
|
1245 |
+
elif "course" in message.lower() or "class" in message.lower():
|
1246 |
+
response += "\n\nWould you like help finding resources for any of these courses?"
|
1247 |
|
1248 |
+
return response
|
|
|
|
|
|
|
|
|
1249 |
|
1250 |
+
except Exception as e:
|
1251 |
+
logging.error(f"Error generating response: {str(e)}")
|
1252 |
+
return "I encountered an error processing your request. Please try again."
|
1253 |
+
|
1254 |
+
def _update_context(self, message: str, history: List[List[Union[str, None]]]) -> None:
|
1255 |
+
"""Maintain conversation context."""
|
1256 |
+
self.context_history.append({"role": "user", "content": message})
|
1257 |
+
if history:
|
1258 |
+
for h in history[-self.max_context_length:]:
|
1259 |
+
if h[0]: # User message
|
1260 |
+
self.context_history.append({"role": "user", "content": h[0]})
|
1261 |
+
if h[1]: # Assistant message
|
1262 |
+
self.context_history.append({"role": "assistant", "content": h[1]})
|
1263 |
+
|
1264 |
+
# Trim to maintain max context length
|
1265 |
+
self.context_history = self.context_history[-(self.max_context_length*2):]
|
1266 |
+
|
1267 |
+
async def _process_message(self, message: str, profile: Dict) -> str:
|
1268 |
+
"""Process user message with profile context."""
|
1269 |
+
message_lower = message.lower()
|
1270 |
+
|
1271 |
+
# Greetings
|
1272 |
+
if any(greet in message_lower for greet in ["hi", "hello", "hey", "greetings"]):
|
1273 |
+
return f"Hello {profile.get('name', 'there')}! How can I help you with your learning today?"
|
1274 |
+
|
1275 |
+
# Study help
|
1276 |
+
study_words = ["study", "learn", "prepare", "exam", "test", "homework"]
|
1277 |
+
if any(word in message_lower for word in study_words):
|
1278 |
+
return self._generate_study_advice(profile)
|
1279 |
+
|
1280 |
+
# Grade help
|
1281 |
+
grade_words = ["grade", "gpa", "score", "marks", "results"]
|
1282 |
+
if any(word in message_lower for word in grade_words):
|
1283 |
+
return self._generate_grade_advice(profile)
|
1284 |
+
|
1285 |
+
# Interest help
|
1286 |
+
interest_words = ["interest", "hobby", "passion", "extracurricular"]
|
1287 |
+
if any(word in message_lower for word in interest_words):
|
1288 |
+
return self._generate_interest_advice(profile)
|
1289 |
+
|
1290 |
+
# Course help
|
1291 |
+
course_words = ["courses", "classes", "transcript", "schedule", "subject"]
|
1292 |
+
if any(word in message_lower for word in course_words):
|
1293 |
+
return self._generate_course_advice(profile)
|
1294 |
+
|
1295 |
+
# Favorites
|
1296 |
+
favorite_words = ["movie", "show", "book", "character", "favorite"]
|
1297 |
+
if any(word in message_lower for word in favorite_words):
|
1298 |
+
return self._generate_favorites_response(profile)
|
1299 |
+
|
1300 |
+
# General help
|
1301 |
+
if "help" in message_lower:
|
1302 |
+
return self._generate_help_response()
|
1303 |
+
|
1304 |
+
# Default response
|
1305 |
+
return ("I'm your personalized teaching assistant. I can help with study tips, "
|
1306 |
+
"grade information, course advice, and more. Try asking about how to "
|
1307 |
+
"study effectively or about your course history.")
|
1308 |
+
|
1309 |
+
def _generate_study_advice(self, profile: Dict) -> str:
|
1310 |
+
"""Generate study advice based on learning style."""
|
1311 |
+
learning_style = profile.get("learning_style", "")
|
1312 |
+
response = ""
|
1313 |
+
|
1314 |
+
if "Visual" in learning_style:
|
1315 |
+
response = ("Based on your visual learning style, I recommend:\n"
|
1316 |
+
"- Creating colorful mind maps or diagrams\n"
|
1317 |
+
"- Using highlighters to color-code your notes\n"
|
1318 |
+
"- Watching educational videos on the topics\n"
|
1319 |
+
"- Creating flashcards with images\n\n")
|
1320 |
+
elif "Auditory" in learning_style:
|
1321 |
+
response = ("Based on your auditory learning style, I recommend:\n"
|
1322 |
+
"- Recording your notes and listening to them\n"
|
1323 |
+
"- Participating in study groups to discuss concepts\n"
|
1324 |
+
"- Explaining the material out loud to yourself\n"
|
1325 |
+
"- Finding podcasts or audio lectures on the topics\n\n")
|
1326 |
+
elif "Reading/Writing" in learning_style:
|
1327 |
+
response = ("Based on your reading/writing learning style, I recommend:\n"
|
1328 |
+
"- Writing detailed summaries in your own words\n"
|
1329 |
+
"- Creating organized outlines of the material\n"
|
1330 |
+
"- Reading additional textbooks or articles\n"
|
1331 |
+
"- Rewriting your notes to reinforce learning\n\n")
|
1332 |
+
elif "Kinesthetic" in learning_style:
|
1333 |
+
response = ("Based on your kinesthetic learning style, I recommend:\n"
|
1334 |
+
"- Creating physical models or demonstrations\n"
|
1335 |
+
"- Using hands-on activities to learn concepts\n"
|
1336 |
+
"- Taking frequent movement breaks while studying\n"
|
1337 |
+
"- Associating information with physical actions\n\n")
|
1338 |
+
else:
|
1339 |
+
response = ("Here are some general study tips:\n"
|
1340 |
+
"- Use the Pomodoro technique (25 min study, 5 min break)\n"
|
1341 |
+
"- Space out your study sessions over time\n"
|
1342 |
+
"- Test yourself with practice questions\n"
|
1343 |
+
"- Teach the material to someone else\n\n")
|
1344 |
+
|
1345 |
+
# Add time management advice
|
1346 |
+
response += ("**Time Management Tips**:\n"
|
1347 |
+
"- Create a study schedule and stick to it\n"
|
1348 |
+
"- Prioritize difficult subjects when you're most alert\n"
|
1349 |
+
"- Break large tasks into smaller, manageable chunks\n"
|
1350 |
+
"- Set specific goals for each study session")
|
1351 |
+
|
1352 |
+
return response
|
1353 |
+
|
1354 |
+
def _generate_grade_advice(self, profile: Dict) -> str:
|
1355 |
+
"""Generate response about grades and GPA."""
|
1356 |
+
gpa = profile.get("transcript", {}).get("gpa", {})
|
1357 |
+
courses = profile.get("transcript", {}).get("courses", {})
|
1358 |
+
|
1359 |
+
response = (f"Your GPA information:\n"
|
1360 |
+
f"- Unweighted: {gpa.get('unweighted', 'N/A')}\n"
|
1361 |
+
f"- Weighted: {gpa.get('weighted', 'N/A')}\n\n")
|
1362 |
+
|
1363 |
+
# Identify any failing grades
|
1364 |
+
weak_subjects = []
|
1365 |
+
for grade_level, course_list in courses.items():
|
1366 |
+
for course in course_list:
|
1367 |
+
if course.get('grade', '').upper() in ['D', 'F']:
|
1368 |
+
weak_subjects.append(f"{course.get('code', '')} {course.get('name', 'Unknown course')}")
|
1369 |
+
|
1370 |
+
if weak_subjects:
|
1371 |
+
response += ("**Areas for Improvement**:\n"
|
1372 |
+
f"You might want to focus on these subjects: {', '.join(weak_subjects)}\n\n")
|
1373 |
+
|
1374 |
+
response += ("**Grade Improvement Strategies**:\n"
|
1375 |
+
"- Meet with your teachers to discuss your performance\n"
|
1376 |
+
"- Identify specific areas where you lost points\n"
|
1377 |
+
"- Create a targeted study plan for weak areas\n"
|
1378 |
+
"- Practice with past exams or sample questions")
|
1379 |
+
|
1380 |
+
return response
|
1381 |
+
|
1382 |
+
def _generate_interest_advice(self, profile: Dict) -> str:
|
1383 |
+
"""Generate response based on student interests."""
|
1384 |
+
interests = profile.get("interests", "")
|
1385 |
+
response = f"I see you're interested in: {interests}\n\n"
|
1386 |
+
|
1387 |
+
response += ("**Suggestions**:\n"
|
1388 |
+
"- Look for clubs or extracurricular activities related to these interests\n"
|
1389 |
+
"- Explore career paths that align with these interests\n"
|
1390 |
+
"- Find online communities or forums about these topics\n"
|
1391 |
+
"- Consider projects or independent study in these areas")
|
1392 |
+
|
1393 |
+
return response
|
1394 |
+
|
1395 |
+
def _generate_course_advice(self, profile: Dict) -> str:
|
1396 |
+
"""Generate response about courses."""
|
1397 |
+
courses = profile.get("transcript", {}).get("courses", {})
|
1398 |
+
grade_level = profile.get("transcript", {}).get("grade_level", "unknown")
|
1399 |
+
|
1400 |
+
response = "Here's a summary of your courses:\n"
|
1401 |
+
for grade in sorted(courses.keys(), key=lambda x: int(x) if x.isdigit() else x):
|
1402 |
+
response += f"\n**Grade {grade}**:\n"
|
1403 |
+
for course in courses[grade]:
|
1404 |
+
response += f"- {course.get('code', '')} {course.get('name', 'Unnamed course')}"
|
1405 |
+
if 'grade' in course:
|
1406 |
+
response += f" (Grade: {course['grade']})"
|
1407 |
+
response += "\n"
|
1408 |
+
|
1409 |
+
response += f"\nAs a grade {grade_level} student, you might want to:\n"
|
1410 |
+
if grade_level in ["9", "10"]:
|
1411 |
+
response += ("- Focus on building strong foundational skills\n"
|
1412 |
+
"- Explore different subjects to find your interests\n"
|
1413 |
+
"- Start thinking about college/career requirements")
|
1414 |
+
elif grade_level in ["11", "12"]:
|
1415 |
+
response += ("- Focus on courses relevant to your college/career goals\n"
|
1416 |
+
"- Consider taking AP or advanced courses if available\n"
|
1417 |
+
"- Ensure you're meeting graduation requirements")
|
1418 |
+
|
1419 |
+
return response
|
1420 |
+
|
1421 |
+
def _generate_favorites_response(self, profile: Dict) -> str:
|
1422 |
+
"""Generate response about favorite items."""
|
1423 |
+
favorites = profile.get("favorites", {})
|
1424 |
+
response = "I see you enjoy:\n"
|
1425 |
+
|
1426 |
+
if favorites.get('movie'):
|
1427 |
+
response += f"- Movie: {favorites['movie']} ({favorites.get('movie_reason', 'no reason provided')})\n"
|
1428 |
+
if favorites.get('show'):
|
1429 |
+
response += f"- TV Show: {favorites['show']} ({favorites.get('show_reason', 'no reason provided')})\n"
|
1430 |
+
if favorites.get('book'):
|
1431 |
+
response += f"- Book: {favorites['book']} ({favorites.get('book_reason', 'no reason provided')})\n"
|
1432 |
+
if favorites.get('character'):
|
1433 |
+
response += f"- Character: {favorites['character']} ({favorites.get('character_reason', 'no reason provided')})\n"
|
1434 |
+
|
1435 |
+
response += "\nThese preferences suggest you might enjoy:\n"
|
1436 |
+
response += "- Similar books/movies in the same genre\n"
|
1437 |
+
response += "- Creative projects related to these stories\n"
|
1438 |
+
response += "- Analyzing themes or characters in your schoolwork"
|
1439 |
+
|
1440 |
+
return response
|
1441 |
+
|
1442 |
+
def _generate_help_response(self) -> str:
|
1443 |
+
"""Generate help response with available commands."""
|
1444 |
+
return ("""I can help with:
|
1445 |
+
- **Study tips**: "How should I study for math?"
|
1446 |
+
- **Grade information**: "What's my GPA?"
|
1447 |
+
- **Course advice**: "Show me my course history"
|
1448 |
+
- **Interest suggestions**: "What clubs match my interests?"
|
1449 |
+
- **General advice**: "How can I improve my grades?"
|
1450 |
+
Try asking about any of these topics!""")
|
1451 |
+
|
1452 |
+
# Initialize teaching assistant
|
1453 |
+
teaching_assistant = TeachingAssistant()
|
1454 |
|
1455 |
# ========== GRADIO INTERFACE ==========
|
1456 |
def create_interface():
|
|
|
1480 |
.quiz-question { margin-bottom: 15px; padding: 15px; background: #f5f5f5; border-radius: 5px; }
|
1481 |
.quiz-results { margin-top: 20px; padding: 20px; background: #e8f5e9; border-radius: 8px; }
|
1482 |
.error-message { color: #d32f2f; background-color: #ffebee; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
|
1483 |
|
1484 |
/* Dark mode support */
|
1485 |
.dark .tab-content { background-color: #2d2d2d !important; border-color: #444 !important; }
|
|
|
1573 |
error_msg = f"❌ Error: {str(e)}"
|
1574 |
if "PDF" in str(e):
|
1575 |
error_msg += "\n\nTIPS FOR PDF FILES:\n1. Try opening and re-saving the PDF\n2. Ensure it's not password protected\n3. Try converting to an image"
|
|
|
|
|
1576 |
return (
|
1577 |
error_msg,
|
1578 |
None,
|
|
|
1684 |
placeholder="e.g., Science, Music, Sports, Art..."
|
1685 |
)
|
1686 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1687 |
save_personal_btn = gr.Button("Save Information", variant="primary")
|
1688 |
save_confirmation = gr.HTML(visible=False)
|
1689 |
|
|
|
1698 |
book_reason = gr.Textbox(label="Why do you like it?", lines=2)
|
1699 |
character = gr.Textbox(label="Favorite Character (from any story)")
|
1700 |
character_reason = gr.Textbox(label="Why do you like them?", lines=2)
|
1701 |
+
|
1702 |
+
# Added blog section
|
1703 |
+
with gr.Accordion("Personal Blog (Optional)", open=False):
|
1704 |
+
blog = gr.Textbox(
|
1705 |
+
label="Share your thoughts",
|
1706 |
+
placeholder="Write something about yourself, your goals, or anything you'd like to share...",
|
1707 |
+
lines=5
|
1708 |
+
)
|
1709 |
|
1710 |
+
def save_personal_info(name, age, interests, current_tab_status):
|
1711 |
try:
|
1712 |
name = validate_name(name)
|
1713 |
age = validate_age(age)
|
|
|
1733 |
|
1734 |
save_personal_btn.click(
|
1735 |
fn=save_personal_info,
|
1736 |
+
inputs=[name, age, interests, tab_completed],
|
1737 |
outputs=[tab_completed, step3, step4, save_confirmation, nav_message]
|
1738 |
)
|
1739 |
|
|
|
1836 |
)
|
1837 |
|
1838 |
clear_btn.click(
|
1839 |
+
fn=lambda: [gr.update(value="") for _ in range(12)],
|
1840 |
outputs=[
|
1841 |
name, age, interests,
|
1842 |
movie, movie_reason, show, show_reason,
|
1843 |
book, book_reason, character, character_reason,
|
1844 |
+
output_summary
|
1845 |
]
|
1846 |
)
|
1847 |
|