LvMAC's picture
Update app.py
a166a35 verified
import gradio as gr
import pandas as pd
import numpy as np
import warnings
import os
warnings.filterwarnings('ignore')
# Import your original system
try:
from main_model_2 import ProductionCourseRecommendationSystem
print("βœ… Successfully imported from main_model_2.py")
SYSTEM_LOADED = True
except ImportError as e:
print(f"❌ Could not import system: {e}")
SYSTEM_LOADED = False
class CourseRecommendationWebApp:
def __init__(self):
print("πŸš€ Initializing Course Recommendation Web App...")
self.system_loaded = SYSTEM_LOADED
if self.system_loaded:
try:
self.system = ProductionCourseRecommendationSystem(device='cpu')
self.setup_original_system()
print("βœ… System initialized successfully")
except Exception as e:
print(f"❌ Error initializing system: {e}")
self.system_loaded = False
self.survey_questions = [
"How many hours can you dedicate to studying?",
"From Your previous semesters which course was your favorite?",
"If you had unlimited resources, what project topic would you work on?",
"What strategies do you naturally use to find solutions to a problem?",
"What profession do you want to be in the next five years?",
"List some of your strongest soft/technical skills?",
"List some of your weakest points about yourself?",
"What research areas do you find most motivating outside of your academic discipline?",
"What kind of course would you like the most?",
"How do you typically respond when you are under stress?"
]
def setup_original_system(self):
"""Setup your original system"""
try:
# Try different paths for data files
possible_paths = [
("course_data_cleaned.csv", "student_data_cleaned.csv"),
("./course_data_cleaned.csv", "./student_data_cleaned.csv")
]
for course_path, student_path in possible_paths:
try:
if os.path.exists(course_path):
self.system.course_data = pd.read_csv(course_path)
print(f"βœ… Loaded {len(self.system.course_data)} courses")
break
except Exception as e:
continue
if os.path.exists(student_path):
self.system.student_data = pd.read_csv(student_path)
print(f"βœ… Loaded {len(self.system.student_data)} student records")
# Initialize FAISS
if hasattr(self.system, '_create_enhanced_embeddings_and_faiss_index'):
self.system._create_enhanced_embeddings_and_faiss_index()
print("βœ… FAISS index created")
return True
except Exception as e:
print(f"❌ Setup error: {e}")
return False
def process_survey_responses(self, *responses):
"""Process survey responses and return text-only results"""
try:
print("πŸ”„ Starting survey processing...")
if not self.system_loaded:
return "❌ **System Error**: Original system not loaded."
if not hasattr(self.system, 'course_data') or self.system.course_data is None:
return "❌ **Data Error**: Course data not loaded."
# Simple validation
valid_responses = [r for r in responses if r and str(r).strip() and len(str(r).strip()) > 2]
if len(valid_responses) < 10:
return f"❌ **Validation Error**: Please answer all questions properly.\n\nCompleted: {len(valid_responses)}/10 questions\n\nMake sure each answer is at least 3 characters long."
print("βœ… Validation passed")
# Create student profile
student_profile = {}
for i, response in enumerate(responses, 1):
student_profile[f'Q{i}'] = str(response).strip() if response else "Not specified"
self.system.student_profile = student_profile
print("βœ… Student profile created")
# Run your original pipeline
print("πŸ”„ Running recommendation pipeline...")
# Step 1: Create student embedding
print("Step 1: Creating student embedding...")
student_embedding, _ = self.system.create_enhanced_student_profile()
if student_embedding is None:
return "❌ **Embedding Error**: Could not create student profile."
print("βœ… Student embedding created")
# Step 2: Similarity search
print("Step 2: Performing similarity search...")
similarity_scores, course_indices = self.system.advanced_similarity_search(student_embedding)
if len(similarity_scores) == 0:
return "❌ **Search Error**: No similar courses found."
print(f"βœ… Similarity search completed: {len(similarity_scores)} scores, {len(course_indices)} indices")
# Step 3: Behavioral metrics
print("Step 3: Calculating behavioral metrics...")
behavioral_metrics = self.system.calculate_advanced_behavioral_metrics()
if not behavioral_metrics:
return "❌ **Metrics Error**: Could not calculate behavioral metrics."
print("βœ… Behavioral metrics calculated")
# Step 4: Generate recommendations
print("Step 4: Generating recommendations...")
recommendations = self.system._generate_fallback_recommendations(
course_indices[:5], similarity_scores[:5], behavioral_metrics
)
if not recommendations:
return "❌ **Generation Error**: No recommendations generated."
print(f"βœ… Generated {len(recommendations)} recommendations")
# Step 5: Format results - TEXT ONLY (NO CHARTS)
print("Step 5: Formatting results...")
result_text = self.format_results_text_only(recommendations, behavioral_metrics)
print("βœ… Results formatted successfully")
return result_text
except Exception as e:
error_msg = f"❌ **Error**: {str(e)}"
print(f"Error in process_survey_responses: {e}")
return error_msg
def format_results_text_only(self, recommendations, behavioral_metrics):
"""Format recommendations as text only (no charts or visualizations)"""
try:
print("πŸ“ Creating text-only results...")
# Create comprehensive text output
result_text = "# 🎯 YOUR PERSONALIZED COURSE RECOMMENDATIONS\n"
result_text += "**Generated using your original AI system with advanced behavioral analysis**\n\n"
result_text += "---\n\n"
# Top 3 recommendations
for i, rec in enumerate(recommendations[:3], 1):
course = rec.get('course', {})
confidence = rec.get('confidence', 0)
avg_behavior = rec.get('avg_bhvr_score', 0)
base_confidence = rec.get('base_confidence', 0)
icon = "πŸ₯‡" if i == 1 else "πŸ₯ˆ" if i == 2 else "πŸ₯‰"
result_text += f"## {icon} Recommendation #{i}: {course.get('Course Name', 'Unknown Course')}\n\n"
# Scores
result_text += f"**πŸ“Š Performance Scores:**\n"
result_text += f"- Overall Confidence: **{confidence:.1f}%**\n"
result_text += f"- Behavioral Match: **{avg_behavior:.1f}%**\n"
result_text += f"- Similarity Score: **{base_confidence:.1f}%**\n\n"
# Course details
result_text += f"**πŸ“‹ Course Details:**\n"
result_text += f"- **Department:** {course.get('Department', 'N/A')}\n"
result_text += f"- **Type:** {course.get('Type', 'N/A')}\n"
result_text += f"- **Stress Level:** {course.get('Stress Level', 'N/A')}\n"
result_text += f"- **Skills Required:** {course.get('Skill Required', 'N/A')}\n"
result_text += f"- **Field Interest:** {course.get('Field Interest', 'N/A')}\n"
if 'Career Paths' in course and course.get('Career Paths'):
result_text += f"- **Career Paths:** {course.get('Career Paths', 'N/A')}\n"
if 'Industry Sectors' in course and course.get('Industry Sectors'):
result_text += f"- **Industry Sectors:** {course.get('Industry Sectors', 'N/A')}\n"
result_text += f"\n**πŸ“ Description:**\n{course.get('Description', 'N/A')}\n\n"
# Behavioral breakdown for ALL recommendations (not just top 1)
if recommendations and behavioral_metrics:
rec_idx = rec.get('index', 0)
result_text += f"**🧠 Detailed Behavioral Analysis:**\n"
metrics_info = [
('Stress Compatibility', 'stress_matching', 'How well the course stress level matches your stress tolerance'),
('Learning Style Match', 'type_matching', 'How well the course type matches your learning preferences'),
('Interest Alignment', 'description_matching', 'How well the course content aligns with your interests'),
('Skill Compatibility', 'skill_matching', 'How well your skills match the course requirements'),
('Field Match', 'field_matching', 'How well the course field matches your career and research interests')
]
for name, key, description in metrics_info:
if key in behavioral_metrics and rec_idx < len(behavioral_metrics[key]):
score = behavioral_metrics[key][rec_idx]
result_text += f"- **{name}:** {score:.1f}% - {description}\n"
result_text += "\n---\n\n"
# Summary
avg_confidence = np.mean([rec['confidence'] for rec in recommendations[:3]])
result_text += f"## πŸ“ˆ Analysis Summary\n\n"
result_text += f"- **Average Confidence:** {avg_confidence:.1f}%\n"
result_text += f"- **Courses Analyzed:** {len(self.system.course_data)}\n"
result_text += f"- **Analysis Method:** 5-Dimensional Behavioral + Semantic Similarity\n"
result_text += f"- **AI Components:** FAISS Vector Search + Behavioral Analysis Pipeline\n\n"
result_text += "**πŸŽ“ Your personalized recommendations are ready! These courses are selected based on your learning style, career goals, stress tolerance, and skill compatibility.**"
print("βœ… Text formatting completed successfully")
return result_text
except Exception as e:
error_msg = f"❌ **Formatting Error**: {str(e)}"
print(f"Error in format_results_text_only: {e}")
return error_msg
def create_interface(self):
"""Create Gradio interface - TEXT ONLY VERSION"""
with gr.Blocks(title="πŸŽ“ AI Course Recommendation System") as demo:
gr.Markdown("""
# πŸŽ“ AI Course Recommendation System
**Your Original System - Advanced AI Analysis**
*Get personalized course recommendations using your original AI system*
""")
if not self.system_loaded:
gr.Markdown("❌ **System Error**: Could not load main_model_2.py")
return demo
# System status
course_count = len(self.system.course_data) if hasattr(self.system, 'course_data') and self.system.course_data is not None else "Unknown"
gr.Markdown(f"""
**βœ… System Status:** Loaded and Ready
**πŸ“š Available Courses:** {course_count}
**πŸ€– AI Components:** FAISS + Behavioral Analysis + Semantic Matching
""")
gr.Markdown("## πŸ“ Complete All Questions")
gr.Markdown("*Provide detailed, thoughtful answers for the most accurate recommendations.*")
# Create input fields
inputs = []
for i, question in enumerate(self.survey_questions, 1):
inputs.append(
gr.Textbox(
label=f"Q{i}: {question}",
placeholder=f"Your detailed answer (minimum 3 characters)...",
lines=2,
max_lines=4
)
)
# Submit button
submit_btn = gr.Button("πŸš€ Generate AI Recommendations", variant="primary", size="lg")
# Results section
gr.Markdown("## 🎯 Your Personalized Recommendations")
output_text = gr.Markdown(f"""
**Ready for Analysis!**
Complete all 10 questions above to get your personalized course recommendations.
**Your System Features:**
- 🧠 5-dimensional behavioral analysis
- πŸ” Semantic similarity matching using SentenceTransformers
- πŸ“Š FAISS vector search with {course_count} courses
- 🎯 Your original AI pipeline
- πŸ“ˆ Advanced confidence scoring
""")
# Connect interface - TEXT ONLY, NO CHARTS
submit_btn.click(
fn=self.process_survey_responses,
inputs=inputs,
outputs=[output_text]
)
# Add example
gr.Examples(
examples=[[
"I can dedicate 6-8 hours daily for focused studying",
"Data Structures and Algorithms - I loved the logical problem-solving approach",
"An AI-powered educational platform that personalizes learning paths for students",
"I break complex problems into smaller components and test iteratively",
"Senior Machine Learning Engineer at a tech company leading AI research projects",
"Python programming, machine learning, data analysis, problem-solving, teamwork",
"Sometimes overthink problems, need to improve presentation skills",
"Explainable AI, computer vision in healthcare, NLP for education",
"Hands-on courses combining theory with practical projects and real applications",
"I stay organized, take breaks, discuss challenges with peers, maintain growth mindset"
]],
inputs=inputs,
label="πŸ“ Try this comprehensive example"
)
return demo
def main():
"""Main function"""
try:
print("πŸš€ Starting Course Recommendation System...")
app = CourseRecommendationWebApp()
if app.system_loaded:
demo = app.create_interface()
print("βœ… Interface created successfully!")
demo.launch(
share=False,
server_name="0.0.0.0",
server_port=7860,
show_error=True
)
else:
print("❌ Cannot start app - system not loaded")
except Exception as e:
print(f"❌ Fatal error: {e}")
if __name__ == "__main__":
main()