Manyue-DataScientist commited on
Commit
2d41771
·
verified ·
1 Parent(s): 4e2008c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +208 -124
app.py CHANGED
@@ -6,82 +6,181 @@ 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
- 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,15 +188,15 @@ def generate_response(query: str, knowledge_base: dict) -> str:
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,52 +206,51 @@ def generate_response(query: str, knowledge_base: dict) -> str:
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("💬 Chat with Manyue's AI Assistant")
156
 
157
  # Initialize session state
158
  if "messages" not in st.session_state:
@@ -172,36 +270,34 @@ def main():
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
181
  col1, col2 = st.columns([3, 1])
182
 
183
  with col1:
184
- # Display existing messages
185
  for message in st.session_state.messages:
186
  with st.chat_message(message["role"]):
187
  st.markdown(message["content"])
188
 
189
- # Handle input - IMPORTANT: This needs to be outside any button handlers
190
  if prompt := st.chat_input("Ask me anything or paste a job description..."):
191
- with st.chat_message("user"):
192
- st.markdown(prompt)
193
-
194
- # Add user message to session state
195
  st.session_state.messages.append({"role": "user", "content": prompt})
196
 
197
- # Generate and display response
198
- with st.chat_message("assistant"):
199
- try:
200
  response = generate_response(prompt, st.session_state.knowledge_base)
201
  st.markdown(response)
202
  st.session_state.messages.append({"role": "assistant", "content": response})
203
- except Exception as e:
204
- st.error(f"An error occurred: {str(e)}")
 
 
205
 
206
  with col2:
207
  st.subheader("Quick Questions")
@@ -210,28 +306,16 @@ def main():
210
  "What are your technical skills?",
211
  "What makes you stand out?",
212
  "What's your journey into ML?",
213
- "Your view on the current market?"
214
  ]
215
 
216
- # Handle quick question buttons
217
  for question in example_questions:
218
- if st.button(question, key=f"btn_{question}"): # Add unique keys
219
- with st.chat_message("user"):
220
- st.markdown(question)
221
  st.session_state.messages.append({"role": "user", "content": question})
222
-
223
- with st.chat_message("assistant"):
224
- try:
225
- response = generate_response(question, st.session_state.knowledge_base)
226
- st.markdown(response)
227
- st.session_state.messages.append({"role": "assistant", "content": response})
228
- except Exception as e:
229
- st.error(f"An error occurred: {str(e)}")
230
-
231
  st.rerun()
232
 
233
  st.markdown("---")
234
- if st.button("Clear Chat", key="clear_chat"): # Add unique key
235
  st.session_state.messages = []
236
  st.rerun()
237
 
 
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
 
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
  # 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:
 
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})
290
 
291
+ try:
292
+ # Generate and display response
293
+ with st.chat_message("assistant"):
294
  response = generate_response(prompt, st.session_state.knowledge_base)
295
  st.markdown(response)
296
  st.session_state.messages.append({"role": "assistant", "content": response})
297
+ except Exception as e:
298
+ st.error(f"An error occurred: {str(e)}")
299
+
300
+ st.rerun()
301
 
302
  with col2:
303
  st.subheader("Quick Questions")
 
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:
313
+ if st.button(question):
 
 
314
  st.session_state.messages.append({"role": "user", "content": question})
 
 
 
 
 
 
 
 
 
315
  st.rerun()
316
 
317
  st.markdown("---")
318
+ if st.button("Clear Chat"):
319
  st.session_state.messages = []
320
  st.rerun()
321