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) -> str:
|
1026 |
"""Save student profile with validation."""
|
1027 |
try:
|
1028 |
# Validate required fields
|
@@ -1153,11 +1153,17 @@ class ProfileManager:
|
|
1153 |
favorites = data.get("favorites", {})
|
1154 |
learning_style = data.get("learning_style", "Not assessed")
|
1155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1156 |
markdown = f"""## Student Profile: {data['name']}
|
1157 |
### Basic Information
|
1158 |
- **Age:** {data['age']}
|
1159 |
- **Interests:** {data.get('interests', 'Not specified')}
|
1160 |
-
- **Learning Style:** {
|
1161 |
### Academic Information
|
1162 |
{self._format_transcript(transcript)}
|
1163 |
### Favorites
|
@@ -1176,13 +1182,52 @@ class ProfileManager:
|
|
1176 |
|
1177 |
def _format_transcript(self, transcript: Dict) -> str:
|
1178 |
"""Format transcript data for display."""
|
1179 |
-
if not transcript
|
1180 |
return "_No transcript information available_"
|
1181 |
|
1182 |
-
display = "
|
1183 |
-
courses_by_grade = transcript["courses"]
|
1184 |
|
1185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1186 |
for grade in sorted(courses_by_grade.keys(), key=lambda x: int(x) if x.isdigit() else x):
|
1187 |
display += f"\n**Grade {grade}**\n"
|
1188 |
for course in courses_by_grade[grade]:
|
@@ -1192,259 +1237,14 @@ class ProfileManager:
|
|
1192 |
if 'credits' in course:
|
1193 |
display += f" | Credits: {course['credits']}"
|
1194 |
display += f" | Year: {course.get('year', 'N/A')}\n"
|
1195 |
-
|
1196 |
-
if 'gpa' in transcript:
|
1197 |
-
gpa = transcript['gpa']
|
1198 |
-
display += "\n**GPA**\n"
|
1199 |
-
display += f"- Unweighted: {gpa.get('unweighted', 'N/A')}\n"
|
1200 |
-
display += f"- Weighted: {gpa.get('weighted', 'N/A')}\n"
|
1201 |
-
|
1202 |
-
return display
|
1203 |
-
|
1204 |
-
# Initialize profile manager
|
1205 |
-
profile_manager = ProfileManager()
|
1206 |
-
|
1207 |
-
# ========== AI TEACHING ASSISTANT ==========
|
1208 |
-
class TeachingAssistant:
|
1209 |
-
def __init__(self):
|
1210 |
-
self.context_history = []
|
1211 |
-
self.max_context_length = 5 # Keep last 5 exchanges for context
|
1212 |
-
|
1213 |
-
async def generate_response(self, message: str, history: List[List[Union[str, None]]], session_token: str) -> str:
|
1214 |
-
"""Generate personalized response based on student profile and context."""
|
1215 |
-
try:
|
1216 |
-
# Load profile with session token
|
1217 |
-
profile = profile_manager.load_profile(session_token=session_token)
|
1218 |
-
if not profile:
|
1219 |
-
return "Please complete and save your profile first using the previous tabs."
|
1220 |
-
|
1221 |
-
# Update context history
|
1222 |
-
self._update_context(message, history)
|
1223 |
-
|
1224 |
-
# Extract profile information
|
1225 |
-
name = profile.get("name", "there")
|
1226 |
-
learning_style = profile.get("learning_style", "")
|
1227 |
-
grade_level = profile.get("transcript", {}).get("grade_level", "unknown")
|
1228 |
-
gpa = profile.get("transcript", {}).get("gpa", {})
|
1229 |
-
interests = profile.get("interests", "")
|
1230 |
-
courses = profile.get("transcript", {}).get("courses", {})
|
1231 |
-
favorites = profile.get("favorites", {})
|
1232 |
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
response += "\n\nWould you like me to suggest a study schedule based on your courses?"
|
1239 |
-
elif "course" in message.lower() or "class" in message.lower():
|
1240 |
-
response += "\n\nWould you like help finding resources for any of these courses?"
|
1241 |
-
|
1242 |
-
return response
|
1243 |
|
1244 |
-
|
1245 |
-
logging.error(f"Error generating response: {str(e)}")
|
1246 |
-
return "I encountered an error processing your request. Please try again."
|
1247 |
-
|
1248 |
-
def _update_context(self, message: str, history: List[List[Union[str, None]]]) -> None:
|
1249 |
-
"""Maintain conversation context."""
|
1250 |
-
self.context_history.append({"role": "user", "content": message})
|
1251 |
-
if history:
|
1252 |
-
for h in history[-self.max_context_length:]:
|
1253 |
-
if h[0]: # User message
|
1254 |
-
self.context_history.append({"role": "user", "content": h[0]})
|
1255 |
-
if h[1]: # Assistant message
|
1256 |
-
self.context_history.append({"role": "assistant", "content": h[1]})
|
1257 |
-
|
1258 |
-
# Trim to maintain max context length
|
1259 |
-
self.context_history = self.context_history[-(self.max_context_length*2):]
|
1260 |
-
|
1261 |
-
async def _process_message(self, message: str, profile: Dict) -> str:
|
1262 |
-
"""Process user message with profile context."""
|
1263 |
-
message_lower = message.lower()
|
1264 |
-
|
1265 |
-
# Greetings
|
1266 |
-
if any(greet in message_lower for greet in ["hi", "hello", "hey", "greetings"]):
|
1267 |
-
return f"Hello {profile.get('name', 'there')}! How can I help you with your learning today?"
|
1268 |
-
|
1269 |
-
# Study help
|
1270 |
-
study_words = ["study", "learn", "prepare", "exam", "test", "homework"]
|
1271 |
-
if any(word in message_lower for word in study_words):
|
1272 |
-
return self._generate_study_advice(profile)
|
1273 |
-
|
1274 |
-
# Grade help
|
1275 |
-
grade_words = ["grade", "gpa", "score", "marks", "results"]
|
1276 |
-
if any(word in message_lower for word in grade_words):
|
1277 |
-
return self._generate_grade_advice(profile)
|
1278 |
-
|
1279 |
-
# Interest help
|
1280 |
-
interest_words = ["interest", "hobby", "passion", "extracurricular"]
|
1281 |
-
if any(word in message_lower for word in interest_words):
|
1282 |
-
return self._generate_interest_advice(profile)
|
1283 |
-
|
1284 |
-
# Course help
|
1285 |
-
course_words = ["courses", "classes", "transcript", "schedule", "subject"]
|
1286 |
-
if any(word in message_lower for word in course_words):
|
1287 |
-
return self._generate_course_advice(profile)
|
1288 |
-
|
1289 |
-
# Favorites
|
1290 |
-
favorite_words = ["movie", "show", "book", "character", "favorite"]
|
1291 |
-
if any(word in message_lower for word in favorite_words):
|
1292 |
-
return self._generate_favorites_response(profile)
|
1293 |
-
|
1294 |
-
# General help
|
1295 |
-
if "help" in message_lower:
|
1296 |
-
return self._generate_help_response()
|
1297 |
-
|
1298 |
-
# Default response
|
1299 |
-
return ("I'm your personalized teaching assistant. I can help with study tips, "
|
1300 |
-
"grade information, course advice, and more. Try asking about how to "
|
1301 |
-
"study effectively or about your course history.")
|
1302 |
-
|
1303 |
-
def _generate_study_advice(self, profile: Dict) -> str:
|
1304 |
-
"""Generate study advice based on learning style."""
|
1305 |
-
learning_style = profile.get("learning_style", "")
|
1306 |
-
response = ""
|
1307 |
-
|
1308 |
-
if "Visual" in learning_style:
|
1309 |
-
response = ("Based on your visual learning style, I recommend:\n"
|
1310 |
-
"- Creating colorful mind maps or diagrams\n"
|
1311 |
-
"- Using highlighters to color-code your notes\n"
|
1312 |
-
"- Watching educational videos on the topics\n"
|
1313 |
-
"- Creating flashcards with images\n\n")
|
1314 |
-
elif "Auditory" in learning_style:
|
1315 |
-
response = ("Based on your auditory learning style, I recommend:\n"
|
1316 |
-
"- Recording your notes and listening to them\n"
|
1317 |
-
"- Participating in study groups to discuss concepts\n"
|
1318 |
-
"- Explaining the material out loud to yourself\n"
|
1319 |
-
"- Finding podcasts or audio lectures on the topics\n\n")
|
1320 |
-
elif "Reading/Writing" in learning_style:
|
1321 |
-
response = ("Based on your reading/writing learning style, I recommend:\n"
|
1322 |
-
"- Writing detailed summaries in your own words\n"
|
1323 |
-
"- Creating organized outlines of the material\n"
|
1324 |
-
"- Reading additional textbooks or articles\n"
|
1325 |
-
"- Rewriting your notes to reinforce learning\n\n")
|
1326 |
-
elif "Kinesthetic" in learning_style:
|
1327 |
-
response = ("Based on your kinesthetic learning style, I recommend:\n"
|
1328 |
-
"- Creating physical models or demonstrations\n"
|
1329 |
-
"- Using hands-on activities to learn concepts\n"
|
1330 |
-
"- Taking frequent movement breaks while studying\n"
|
1331 |
-
"- Associating information with physical actions\n\n")
|
1332 |
-
else:
|
1333 |
-
response = ("Here are some general study tips:\n"
|
1334 |
-
"- Use the Pomodoro technique (25 min study, 5 min break)\n"
|
1335 |
-
"- Space out your study sessions over time\n"
|
1336 |
-
"- Test yourself with practice questions\n"
|
1337 |
-
"- Teach the material to someone else\n\n")
|
1338 |
-
|
1339 |
-
# Add time management advice
|
1340 |
-
response += ("**Time Management Tips**:\n"
|
1341 |
-
"- Create a study schedule and stick to it\n"
|
1342 |
-
"- Prioritize difficult subjects when you're most alert\n"
|
1343 |
-
"- Break large tasks into smaller, manageable chunks\n"
|
1344 |
-
"- Set specific goals for each study session")
|
1345 |
-
|
1346 |
-
return response
|
1347 |
-
|
1348 |
-
def _generate_grade_advice(self, profile: Dict) -> str:
|
1349 |
-
"""Generate response about grades and GPA."""
|
1350 |
-
gpa = profile.get("transcript", {}).get("gpa", {})
|
1351 |
-
courses = profile.get("transcript", {}).get("courses", {})
|
1352 |
-
|
1353 |
-
response = (f"Your GPA information:\n"
|
1354 |
-
f"- Unweighted: {gpa.get('unweighted', 'N/A')}\n"
|
1355 |
-
f"- Weighted: {gpa.get('weighted', 'N/A')}\n\n")
|
1356 |
-
|
1357 |
-
# Identify any failing grades
|
1358 |
-
weak_subjects = []
|
1359 |
-
for grade_level, course_list in courses.items():
|
1360 |
-
for course in course_list:
|
1361 |
-
if course.get('grade', '').upper() in ['D', 'F']:
|
1362 |
-
weak_subjects.append(f"{course.get('code', '')} {course.get('name', 'Unknown course')}")
|
1363 |
-
|
1364 |
-
if weak_subjects:
|
1365 |
-
response += ("**Areas for Improvement**:\n"
|
1366 |
-
f"You might want to focus on these subjects: {', '.join(weak_subjects)}\n\n")
|
1367 |
-
|
1368 |
-
response += ("**Grade Improvement Strategies**:\n"
|
1369 |
-
"- Meet with your teachers to discuss your performance\n"
|
1370 |
-
"- Identify specific areas where you lost points\n"
|
1371 |
-
"- Create a targeted study plan for weak areas\n"
|
1372 |
-
"- Practice with past exams or sample questions")
|
1373 |
-
|
1374 |
-
return response
|
1375 |
-
|
1376 |
-
def _generate_interest_advice(self, profile: Dict) -> str:
|
1377 |
-
"""Generate response based on student interests."""
|
1378 |
-
interests = profile.get("interests", "")
|
1379 |
-
response = f"I see you're interested in: {interests}\n\n"
|
1380 |
-
|
1381 |
-
response += ("**Suggestions**:\n"
|
1382 |
-
"- Look for clubs or extracurricular activities related to these interests\n"
|
1383 |
-
"- Explore career paths that align with these interests\n"
|
1384 |
-
"- Find online communities or forums about these topics\n"
|
1385 |
-
"- Consider projects or independent study in these areas")
|
1386 |
-
|
1387 |
-
return response
|
1388 |
-
|
1389 |
-
def _generate_course_advice(self, profile: Dict) -> str:
|
1390 |
-
"""Generate response about courses."""
|
1391 |
-
courses = profile.get("transcript", {}).get("courses", {})
|
1392 |
-
grade_level = profile.get("transcript", {}).get("grade_level", "unknown")
|
1393 |
-
|
1394 |
-
response = "Here's a summary of your courses:\n"
|
1395 |
-
for grade in sorted(courses.keys(), key=lambda x: int(x) if x.isdigit() else x):
|
1396 |
-
response += f"\n**Grade {grade}**:\n"
|
1397 |
-
for course in courses[grade]:
|
1398 |
-
response += f"- {course.get('code', '')} {course.get('name', 'Unnamed course')}"
|
1399 |
-
if 'grade' in course:
|
1400 |
-
response += f" (Grade: {course['grade']})"
|
1401 |
-
response += "\n"
|
1402 |
-
|
1403 |
-
response += f"\nAs a grade {grade_level} student, you might want to:\n"
|
1404 |
-
if grade_level in ["9", "10"]:
|
1405 |
-
response += ("- Focus on building strong foundational skills\n"
|
1406 |
-
"- Explore different subjects to find your interests\n"
|
1407 |
-
"- Start thinking about college/career requirements")
|
1408 |
-
elif grade_level in ["11", "12"]:
|
1409 |
-
response += ("- Focus on courses relevant to your college/career goals\n"
|
1410 |
-
"- Consider taking AP or advanced courses if available\n"
|
1411 |
-
"- Ensure you're meeting graduation requirements")
|
1412 |
-
|
1413 |
-
return response
|
1414 |
-
|
1415 |
-
def _generate_favorites_response(self, profile: Dict) -> str:
|
1416 |
-
"""Generate response about favorite items."""
|
1417 |
-
favorites = profile.get("favorites", {})
|
1418 |
-
response = "I see you enjoy:\n"
|
1419 |
-
|
1420 |
-
if favorites.get('movie'):
|
1421 |
-
response += f"- Movie: {favorites['movie']} ({favorites.get('movie_reason', 'no reason provided')})\n"
|
1422 |
-
if favorites.get('show'):
|
1423 |
-
response += f"- TV Show: {favorites['show']} ({favorites.get('show_reason', 'no reason provided')})\n"
|
1424 |
-
if favorites.get('book'):
|
1425 |
-
response += f"- Book: {favorites['book']} ({favorites.get('book_reason', 'no reason provided')})\n"
|
1426 |
-
if favorites.get('character'):
|
1427 |
-
response += f"- Character: {favorites['character']} ({favorites.get('character_reason', 'no reason provided')})\n"
|
1428 |
-
|
1429 |
-
response += "\nThese preferences suggest you might enjoy:\n"
|
1430 |
-
response += "- Similar books/movies in the same genre\n"
|
1431 |
-
response += "- Creative projects related to these stories\n"
|
1432 |
-
response += "- Analyzing themes or characters in your schoolwork"
|
1433 |
-
|
1434 |
-
return response
|
1435 |
-
|
1436 |
-
def _generate_help_response(self) -> str:
|
1437 |
-
"""Generate help response with available commands."""
|
1438 |
-
return ("""I can help with:
|
1439 |
-
- **Study tips**: "How should I study for math?"
|
1440 |
-
- **Grade information**: "What's my GPA?"
|
1441 |
-
- **Course advice**: "Show me my course history"
|
1442 |
-
- **Interest suggestions**: "What clubs match my interests?"
|
1443 |
-
- **General advice**: "How can I improve my grades?"
|
1444 |
-
Try asking about any of these topics!""")
|
1445 |
-
|
1446 |
-
# Initialize teaching assistant
|
1447 |
-
teaching_assistant = TeachingAssistant()
|
1448 |
|
1449 |
# ========== GRADIO INTERFACE ==========
|
1450 |
def create_interface():
|
@@ -1474,6 +1274,7 @@ def create_interface():
|
|
1474 |
.quiz-question { margin-bottom: 15px; padding: 15px; background: #f5f5f5; border-radius: 5px; }
|
1475 |
.quiz-results { margin-top: 20px; padding: 20px; background: #e8f5e9; border-radius: 8px; }
|
1476 |
.error-message { color: #d32f2f; background-color: #ffebee; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
|
1477 |
|
1478 |
/* Dark mode support */
|
1479 |
.dark .tab-content { background-color: #2d2d2d !important; border-color: #444 !important; }
|
@@ -1567,6 +1368,8 @@ def create_interface():
|
|
1567 |
error_msg = f"❌ Error: {str(e)}"
|
1568 |
if "PDF" in str(e):
|
1569 |
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"
|
|
|
|
|
1570 |
return (
|
1571 |
error_msg,
|
1572 |
None,
|
@@ -1678,6 +1481,14 @@ def create_interface():
|
|
1678 |
placeholder="e.g., Science, Music, Sports, Art..."
|
1679 |
)
|
1680 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1681 |
save_personal_btn = gr.Button("Save Information", variant="primary")
|
1682 |
save_confirmation = gr.HTML(visible=False)
|
1683 |
|
@@ -1693,7 +1504,7 @@ def create_interface():
|
|
1693 |
character = gr.Textbox(label="Favorite Character (from any story)")
|
1694 |
character_reason = gr.Textbox(label="Why do you like them?", lines=2)
|
1695 |
|
1696 |
-
def save_personal_info(name, age, interests, current_tab_status):
|
1697 |
try:
|
1698 |
name = validate_name(name)
|
1699 |
age = validate_age(age)
|
@@ -1719,7 +1530,7 @@ def create_interface():
|
|
1719 |
|
1720 |
save_personal_btn.click(
|
1721 |
fn=save_personal_info,
|
1722 |
-
inputs=[name, age, interests, tab_completed],
|
1723 |
outputs=[tab_completed, step3, step4, save_confirmation, nav_message]
|
1724 |
)
|
1725 |
|
@@ -1746,7 +1557,6 @@ def create_interface():
|
|
1746 |
"Your profile summary will appear here after saving.",
|
1747 |
label="Profile Summary"
|
1748 |
)
|
1749 |
-
blog = gr.Textbox(label="Personal Blog", visible=False)
|
1750 |
|
1751 |
def save_profile_and_update(name, age, interests, transcript_data, learning_style,
|
1752 |
movie, movie_reason, show, show_reason,
|
@@ -1823,12 +1633,12 @@ def create_interface():
|
|
1823 |
)
|
1824 |
|
1825 |
clear_btn.click(
|
1826 |
-
fn=lambda: [gr.update(value="") for _ in range(
|
1827 |
outputs=[
|
1828 |
name, age, interests,
|
1829 |
movie, movie_reason, show, show_reason,
|
1830 |
book, book_reason, character, character_reason,
|
1831 |
-
output_summary
|
1832 |
]
|
1833 |
)
|
1834 |
|
|
|
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
|
|
|
1153 |
favorites = data.get("favorites", {})
|
1154 |
learning_style = data.get("learning_style", "Not assessed")
|
1155 |
|
1156 |
+
# Extract just the learning style name (remove any markdown formatting)
|
1157 |
+
learning_style_name = learning_style.split("##")[0].strip()
|
1158 |
+
if "Your primary learning style is" in learning_style_name:
|
1159 |
+
learning_style_name = learning_style_name.split("Your primary learning style is")[1].strip()
|
1160 |
+
learning_style_name = learning_style_name.split("\n")[0].strip()
|
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_name}
|
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:
|
1186 |
return "_No transcript information available_"
|
1187 |
|
1188 |
+
display = ""
|
|
|
1189 |
|
1190 |
+
# Handle different transcript formats
|
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 |
if 'credits' in course:
|
1238 |
display += f" | Credits: {course['credits']}"
|
1239 |
display += f" | Year: {course.get('year', 'N/A')}\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1240 |
|
1241 |
+
if 'gpa' in transcript:
|
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 |
+
return display if display else "_No transcript information available_"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1248 |
|
1249 |
# ========== GRADIO INTERFACE ==========
|
1250 |
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 |
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 |
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 |
|
|
|
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, blog=""):
|
1508 |
try:
|
1509 |
name = validate_name(name)
|
1510 |
age = validate_age(age)
|
|
|
1530 |
|
1531 |
save_personal_btn.click(
|
1532 |
fn=save_personal_info,
|
1533 |
+
inputs=[name, age, interests, tab_completed, blog],
|
1534 |
outputs=[tab_completed, step3, step4, save_confirmation, nav_message]
|
1535 |
)
|
1536 |
|
|
|
1557 |
"Your profile summary will appear here after saving.",
|
1558 |
label="Profile Summary"
|
1559 |
)
|
|
|
1560 |
|
1561 |
def save_profile_and_update(name, age, interests, transcript_data, learning_style,
|
1562 |
movie, movie_reason, show, show_reason,
|
|
|
1633 |
)
|
1634 |
|
1635 |
clear_btn.click(
|
1636 |
+
fn=lambda: [gr.update(value="") for _ in range(14)], # Updated to include blog
|
1637 |
outputs=[
|
1638 |
name, age, interests,
|
1639 |
movie, movie_reason, show, show_reason,
|
1640 |
book, book_reason, character, character_reason,
|
1641 |
+
blog, output_summary
|
1642 |
]
|
1643 |
)
|
1644 |
|