Manyue-DataScientist commited on
Commit
79da7a3
·
verified ·
1 Parent(s): 543a68b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -203
app.py CHANGED
@@ -6,181 +6,82 @@ import re
6
  def format_project_response(project: dict, indent_level: int = 0) -> str:
7
  """Format project details with proper indentation and spacing"""
8
  indent = " " * indent_level
 
9
 
10
- response = [f"{indent}• {project['name']}"]
11
- response.append(f"{indent} {project['description']}")
 
12
 
 
13
  if 'skills_used' in project:
14
- response.append(f"{indent} Technologies: {', '.join(project['skills_used'])}")
15
 
 
16
  if 'status' in project:
17
  status = project['status']
18
  if 'development' in status.lower() or 'progress' in status.lower():
19
- response.append(f"{indent} Status: {status}")
20
  if 'confidentiality_note' in project:
21
  response.append(f"{indent} Note: {project['confidentiality_note']}")
22
 
23
- return '\n'.join(response) + '\n' # Add extra newline for spacing
24
 
25
- def format_skills_response(skills: dict) -> str:
26
- """Format skills with proper hierarchy and spacing"""
27
- response = ["My Technical Expertise:\n"]
28
-
29
- categories = {
30
- 'Machine Learning & AI': ['core', 'frameworks', 'focus_areas'],
31
- 'Programming': ['primary', 'libraries', 'tools'],
32
- 'Data & Analytics': ['databases', 'visualization', 'processing']
33
- }
34
-
35
- for category, subcategories in categories.items():
36
- response.append(f"• {category}")
37
- for subcat in subcategories:
38
- if subcat in skills['machine_learning']:
39
- items = skills['machine_learning'][subcat]
40
- response.append(f" - {subcat.title()}: {', '.join(items)}")
41
- response.append("") # Add spacing between categories
42
-
43
- return '\n'.join(response)
44
-
45
- def analyze_job_description(text: str, knowledge_base: dict) -> str:
46
- """Analyze job description and provide detailed alignment"""
47
- # Extract key requirements
48
- requirements = {
49
- 'technical_tools': set(),
50
- 'soft_skills': set(),
51
- 'responsibilities': set()
52
- }
53
 
54
- # Common technical tools and skills
55
  tech_keywords = {
56
- 'data science', 'analytics', 'visualization', 'tableau', 'python',
57
- 'machine learning', 'modeling', 'automation', 'sql', 'data analysis'
 
 
 
58
  }
59
 
60
- # Common soft skills
61
- soft_keywords = {
62
- 'collaborate', 'communicate', 'analyze', 'design', 'implement',
63
- 'produce insights', 'improve', 'support'
 
 
 
64
  }
65
 
66
- text_lower = text.lower()
67
-
68
- # Extract company name if present
69
- companies = ['rbc', 'shopify', 'google', 'microsoft', 'amazon']
70
- company_name = next((company.upper() for company in companies if company in text_lower), None)
71
-
72
- # Extract requirements
73
- for word in tech_keywords:
74
- if word in text_lower:
75
- requirements['technical_tools'].add(word)
76
-
77
- for word in soft_keywords:
78
- if word in text_lower:
79
- requirements['soft_skills'].add(word)
80
-
81
- # Build response
82
- response_parts = []
83
 
84
- # Company-specific introduction if applicable
85
- if company_name:
86
- response_parts.append(f"Here's how I align with {company_name}'s requirements:\n")
87
- else:
88
- response_parts.append("Based on the job requirements, here's how I align:\n")
89
 
90
- # Technical Skills Alignment
91
- response_parts.append(" Technical Skills Match:")
92
- my_relevant_skills = []
93
- if 'visualization' in requirements['technical_tools'] or 'tableau' in requirements['technical_tools']:
94
- my_relevant_skills.append(" - Proficient in Tableau and data visualization (used in multiple projects)")
95
- if 'data analysis' in requirements['technical_tools']:
96
- my_relevant_skills.append(" - Strong data analysis skills demonstrated in projects like LoanTap Credit Assessment")
97
- if 'machine learning' in requirements['technical_tools'] or 'modeling' in requirements['technical_tools']:
98
- my_relevant_skills.append(" - Experienced in building ML models from scratch (demonstrated in algorithm practice projects)")
99
-
100
- response_parts.extend(my_relevant_skills)
101
- response_parts.append("") # Add spacing
102
-
103
- # Business Understanding
104
- response_parts.append("• Business Acumen:")
105
- response_parts.append(" - Commerce background provides strong understanding of business requirements")
106
- response_parts.append(" - Experience in translating business needs into technical solutions")
107
- response_parts.append(" - Proven ability to communicate technical findings to business stakeholders")
108
- response_parts.append("") # Add spacing
109
-
110
- # Project Experience
111
- response_parts.append("• Relevant Project Experience:")
112
- relevant_projects = []
113
- if 'automation' in requirements['technical_tools']:
114
- relevant_projects.append(" - Developed AI-powered POS system with automated operations")
115
- if 'data analysis' in requirements['technical_tools']:
116
- relevant_projects.append(" - Built credit assessment model for LoanTap using comprehensive data analysis")
117
- if 'machine learning' in requirements['technical_tools']:
118
- relevant_projects.append(" - Created multiple ML models from scratch, including predictive analytics for Ola")
119
-
120
- response_parts.extend(relevant_projects)
121
- response_parts.append("") # Add spacing
122
-
123
- # Education and Additional Qualifications
124
- response_parts.append("• Additional Strengths:")
125
- response_parts.append(" - Currently pursuing advanced AI/ML education in Canada")
126
- response_parts.append(" - Strong foundation in both technical implementation and business analysis")
127
- response_parts.append(" - Experience in end-to-end project delivery and deployment")
128
-
129
- return '\n'.join(response_parts)
130
-
131
- def format_story_response(knowledge_base: dict) -> str:
132
- """Format background story with proper structure"""
133
- response_parts = ["My Journey from Commerce to ML/AI:\n"]
134
-
135
- # Education Background
136
- response_parts.append("• Education Background:")
137
- response_parts.append(f" - Commerce degree from {knowledge_base['education']['undergraduate']['institution']}")
138
- response_parts.append(f" - Currently at {knowledge_base['education']['postgraduate'][0]['institution']}")
139
- response_parts.append(f" - Also enrolled at {knowledge_base['education']['postgraduate'][1]['institution']}")
140
- response_parts.append("") # Add spacing
141
-
142
- # Career Transition
143
- response_parts.append("• Career Transition:")
144
- transition = next((qa['answer'] for qa in knowledge_base['frequently_asked_questions']
145
- if 'transition' in qa['question'].lower()), '')
146
- response_parts.append(f" - {transition[:200]}...") # Truncate for readability
147
- response_parts.append("") # Add spacing
148
-
149
- # Current Focus
150
- response_parts.append("• Current Focus:")
151
- response_parts.append(" - Building practical ML projects")
152
- response_parts.append(" - Advancing AI/ML education in Canada")
153
- response_parts.append("") # Add spacing
154
-
155
- # Goals
156
- response_parts.append("• Future Goals:")
157
- response_parts.append(" - Secure ML Engineering role in Canada")
158
- response_parts.append(" - Develop innovative AI solutions")
159
- response_parts.append(" - Contribute to cutting-edge ML projects")
160
-
161
- return '\n'.join(response_parts)
162
-
163
- def add_relevant_links(response: str, query: str, knowledge_base: dict) -> str:
164
- """Add relevant links based on query context"""
165
  query_lower = query.lower()
166
- links = []
167
-
168
- # Add links strategically based on context
169
- if any(word in query_lower for word in ['project', 'portfolio', 'work']):
170
- links.append(f"\nView my complete portfolio: {knowledge_base['personal_details']['online_presence']['portfolio']}")
171
-
172
- if any(word in query_lower for word in ['background', 'experience', 'work']):
173
- links.append(f"\nConnect with me: {knowledge_base['personal_details']['online_presence']['linkedin']}")
174
-
175
- for post in knowledge_base['personal_details']['online_presence']['blog_posts']:
176
- if 'link' in post and any(word in query_lower for word in post['title'].lower().split()):
177
- links.append(f"\nRelated blog post: {post['link']}")
178
- break
179
-
180
- if links:
181
- response += '\n' + '\n'.join(links)
182
-
183
- return response
 
 
 
 
 
184
 
185
  def generate_response(query: str, knowledge_base: dict) -> str:
186
  """Generate enhanced responses using the knowledge base"""
@@ -188,15 +89,15 @@ def generate_response(query: str, knowledge_base: dict) -> str:
188
 
189
  # Handle project listing requests
190
  if any(word in query_lower for word in ['list', 'project', 'portfolio', 'built', 'created', 'developed']):
191
- response_parts = ["Here are my key projects:\n"]
192
 
193
  # Major Projects (under development)
194
- response_parts.append("Major Projects (In Development):")
195
  for project in knowledge_base['projects']['major_projects']:
196
  response_parts.append(format_project_response(project, indent_level=1))
197
 
198
  # Algorithm Implementation Projects
199
- response_parts.append("Completed Algorithm Implementation Projects:")
200
  for project in knowledge_base['projects']['algorithm_practice_projects']:
201
  response_parts.append(format_project_response(project, indent_level=1))
202
 
@@ -206,51 +107,52 @@ def generate_response(query: str, knowledge_base: dict) -> str:
206
  # Handle job description analysis
207
  elif len(query.split()) > 20 and any(phrase in query_lower for phrase in
208
  ['requirements', 'qualifications', 'looking for', 'job description']):
209
- return analyze_job_description(query, knowledge_base)
210
-
211
- # Handle background/story queries
212
- elif any(word in query_lower for word in ['background', 'journey', 'story', 'transition']):
213
- return format_story_response(knowledge_base)
214
-
215
- # Handle skill-specific queries
216
- elif any(word in query_lower for word in ['skill', 'know', 'technology', 'stack']):
217
- return format_skills_response(knowledge_base['skills']['technical_skills'])
218
-
219
- # Handle standout/unique qualities queries
220
- elif any(word in query_lower for word in ['stand out', 'unique', 'different', 'special']):
221
- response_parts = ["What Makes Me Stand Out:\n"]
222
- response_parts.append("• Unique Background:")
223
- response_parts.append(" - Successfully transitioned from commerce to tech")
224
- response_parts.append(" - Blend of business acumen and technical expertise")
225
- response_parts.append("")
226
 
227
- response_parts.append("• Practical Experience:")
228
- response_parts.append(" - Built multiple ML projects from scratch")
229
- response_parts.append(" - Focus on real-world applications")
230
- response_parts.append("")
231
 
232
- response_parts.append("• Technical Depth:")
233
- response_parts.append(" - Strong foundation in ML/AI principles")
234
- response_parts.append(" - Experience with end-to-end project implementation")
235
- response_parts.append("")
 
 
 
236
 
237
- response_parts.append("• Innovation Focus:")
238
- response_parts.append(" - Developing novel solutions in ML/AI")
239
- response_parts.append(" - Emphasis on practical impact")
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
  return '\n'.join(response_parts)
242
 
 
 
 
 
 
 
 
 
243
  # Default response
244
- return (f"I'm {knowledge_base['personal_details']['professional_summary']}\n\n"
245
- "You can ask me about:\n"
246
- "• My projects and portfolio\n"
247
- "• My journey from commerce to ML/AI\n"
248
- "• My technical skills and experience\n"
249
- "• My fit for ML/AI roles\n"
250
- "Or paste a job description to see how my profile matches!")
251
 
252
  def main():
253
- st.title("💬 Chat with Manyue's Portfolio")
254
 
255
  # Initialize session state
256
  if "messages" not in st.session_state:
@@ -266,24 +168,27 @@ def main():
266
  # Display welcome message
267
  if "displayed_welcome" not in st.session_state:
268
  st.write("""
269
- Hi! I'm Manyue's AI assistant. I can tell you about:
270
  - My journey from commerce to ML/AI
271
  - My technical skills and projects
272
  - My fit for ML/AI roles
 
273
  - You can also paste job descriptions to see how my profile matches!
274
  """)
275
  st.session_state.displayed_welcome = True
276
-
277
- # Create two columns
278
  col1, col2 = st.columns([3, 1])
279
 
280
  with col1:
281
- # Display chat messages
282
- for message in st.session_state.messages:
283
- with st.chat_message(message["role"]):
284
- st.markdown(message["content"])
 
 
285
 
286
- # Chat input
287
  if prompt := st.chat_input("Ask me anything or paste a job description..."):
288
  # Add user message
289
  st.session_state.messages.append({"role": "user", "content": prompt})
@@ -306,7 +211,7 @@ def main():
306
  "What are your technical skills?",
307
  "What makes you stand out?",
308
  "What's your journey into ML?",
309
- "Paste a job description to see how I match!"
310
  ]
311
 
312
  for question in example_questions:
 
6
  def format_project_response(project: dict, indent_level: int = 0) -> str:
7
  """Format project details with proper indentation and spacing"""
8
  indent = " " * indent_level
9
+ response = [f"\n{indent}• {project['name']}:"]
10
 
11
+ # Add description with proper indentation
12
+ description_lines = project['description'].split('. ')
13
+ response.extend([f"{indent} {line.strip()}." for line in description_lines])
14
 
15
+ # Add technologies with proper line break
16
  if 'skills_used' in project:
17
+ response.append(f"\n{indent} Technologies: {', '.join(project['skills_used'])}")
18
 
19
+ # Add status and notes
20
  if 'status' in project:
21
  status = project['status']
22
  if 'development' in status.lower() or 'progress' in status.lower():
23
+ response.append(f"\n{indent} Status: {status}")
24
  if 'confidentiality_note' in project:
25
  response.append(f"{indent} Note: {project['confidentiality_note']}")
26
 
27
+ return '\n'.join(response) + '\n'
28
 
29
+ def analyze_job_requirements(text: str, knowledge_base: dict) -> Dict[str, List[str]]:
30
+ """Analyze job requirements and match with skills"""
31
+ text_lower = text.lower()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ # Common ML/AI related keywords
34
  tech_keywords = {
35
+ 'machine learning': ['ml', 'machine learning', 'deep learning', 'neural networks'],
36
+ 'data science': ['data science', 'data analysis', 'analytics', 'statistics'],
37
+ 'programming': ['python', 'sql', 'programming', 'coding'],
38
+ 'tools': ['tableau', 'powerbi', 'visualization', 'git'],
39
+ 'cloud': ['aws', 'azure', 'cloud', 'deployment']
40
  }
41
 
42
+ # Extract matches from knowledge base
43
+ matches = {category: [] for category in tech_keywords}
44
+ my_skills = {
45
+ skill.lower()
46
+ for skill_type in knowledge_base['skills']['technical_skills'].values()
47
+ for skill_list in skill_type.values()
48
+ for skill in skill_list
49
  }
50
 
51
+ # Find matching skills in each category
52
+ for category, keywords in tech_keywords.items():
53
+ for keyword in keywords:
54
+ if keyword in text_lower and any(skill in keyword or keyword in skill for skill in my_skills):
55
+ matches[category].append(keyword)
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ return matches
 
 
 
 
58
 
59
+ def handle_perspective_query(query: str, knowledge_base: dict) -> str:
60
+ """Handle philosophical or perspective-based queries"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  query_lower = query.lower()
62
+ perspectives = knowledge_base.get('perspectives', {})
63
+
64
+ # Market-related queries
65
+ if any(word in query_lower for word in ['market', 'opportunity', 'job', 'hiring']):
66
+ if any(word in query_lower for word in ['down', 'bad', 'difficult', 'tough']):
67
+ response_parts = [
68
+ "• My Perspective on the Current Market:",
69
+ f" {perspectives['market_outlook']['job_market']}",
70
+ "",
71
+ "• My Strategic Approach:",
72
+ f" {perspectives['market_outlook']['strategy']}",
73
+ "",
74
+ "• My Unique Value Proposition:",
75
+ f" {perspectives['market_outlook']['value_proposition']}"
76
+ ]
77
+ return '\n'.join(response_parts)
78
+
79
+ # Learning and growth queries
80
+ elif any(word in query_lower for word in ['learn', 'study', 'growth']):
81
+ return f"• My Learning Philosophy:\n {perspectives['learning_philosophy']}"
82
+
83
+ # Handle non-portfolio queries gracefully
84
+ return knowledge_base['common_queries']['general']
85
 
86
  def generate_response(query: str, knowledge_base: dict) -> str:
87
  """Generate enhanced responses using the knowledge base"""
 
89
 
90
  # Handle project listing requests
91
  if any(word in query_lower for word in ['list', 'project', 'portfolio', 'built', 'created', 'developed']):
92
+ response_parts = ["Here are my key projects:"]
93
 
94
  # Major Projects (under development)
95
+ response_parts.append("\nMajor Projects (In Development):")
96
  for project in knowledge_base['projects']['major_projects']:
97
  response_parts.append(format_project_response(project, indent_level=1))
98
 
99
  # Algorithm Implementation Projects
100
+ response_parts.append("\nCompleted Algorithm Implementation Projects:")
101
  for project in knowledge_base['projects']['algorithm_practice_projects']:
102
  response_parts.append(format_project_response(project, indent_level=1))
103
 
 
107
  # Handle job description analysis
108
  elif len(query.split()) > 20 and any(phrase in query_lower for phrase in
109
  ['requirements', 'qualifications', 'looking for', 'job description']):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
+ matches = analyze_job_requirements(query, knowledge_base)
112
+ relevant_projects = find_relevant_projects(query, knowledge_base['projects']['major_projects'])
113
+
114
+ response_parts = ["Based on the job requirements, here's how my profile aligns:\n"]
115
 
116
+ # Technical Skills Match
117
+ if any(matches.values()):
118
+ response_parts.append(" Technical Skills Alignment:")
119
+ for category, skills in matches.items():
120
+ if skills:
121
+ response_parts.append(f" - Strong {category} skills: {', '.join(skills)}")
122
+ response_parts.append("")
123
 
124
+ # Project Experience
125
+ if relevant_projects:
126
+ response_parts.append(" Relevant Project Experience:")
127
+ for project in relevant_projects:
128
+ desc = f" - {project['name']}: {project['description']}"
129
+ response_parts.append(desc)
130
+ response_parts.append("")
131
+
132
+ # Education and Background
133
+ response_parts.extend([
134
+ "• Education and Background:",
135
+ " - Advanced AI/ML education in Canada",
136
+ " - Unique commerce background providing business perspective",
137
+ " - Strong foundation in practical ML implementation",
138
+ ""
139
+ ])
140
 
141
  return '\n'.join(response_parts)
142
 
143
+ # Handle perspective/philosophical queries
144
+ elif any(word in query_lower for word in ['market', 'think', 'believe', 'opinion', 'weather']):
145
+ return handle_perspective_query(query, knowledge_base)
146
+
147
+ # Handle story/background queries
148
+ elif any(word in query_lower for word in ['background', 'journey', 'story', 'transition']):
149
+ return format_story_response(knowledge_base)
150
+
151
  # Default response
152
+ return format_default_response(knowledge_base)
 
 
 
 
 
 
153
 
154
  def main():
155
+ st.title("🤖 Meet Rini - AI-Powered Insights on Manyue's World")
156
 
157
  # Initialize session state
158
  if "messages" not in st.session_state:
 
168
  # Display welcome message
169
  if "displayed_welcome" not in st.session_state:
170
  st.write("""
171
+ Hi there! I'm Rini, Manyue's AI-powered assistant. I'm here to represent Manyue and share insights about:
172
  - My journey from commerce to ML/AI
173
  - My technical skills and projects
174
  - My fit for ML/AI roles
175
+ - My perspective on the tech industry
176
  - You can also paste job descriptions to see how my profile matches!
177
  """)
178
  st.session_state.displayed_welcome = True
179
+
180
+ # Create two columns with chat history in scrollable container
181
  col1, col2 = st.columns([3, 1])
182
 
183
  with col1:
184
+ # Chat container for better scrolling
185
+ chat_container = st.container()
186
+ with chat_container:
187
+ for message in st.session_state.messages:
188
+ with st.chat_message(message["role"]):
189
+ st.markdown(message["content"])
190
 
191
+ # Chat input at bottom
192
  if prompt := st.chat_input("Ask me anything or paste a job description..."):
193
  # Add user message
194
  st.session_state.messages.append({"role": "user", "content": prompt})
 
211
  "What are your technical skills?",
212
  "What makes you stand out?",
213
  "What's your journey into ML?",
214
+ "Your view on the current market?"
215
  ]
216
 
217
  for question in example_questions: