File size: 18,073 Bytes
4f4b439
 
 
 
352d473
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f9f18b4
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d41771
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75c603a
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34c5540
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34c5540
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c688a70
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5cb8fb6
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
c688a70
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c688a70
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473251f
4f4b439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d41771
35e8298
75c603a
51334e1
 
 
f9f18b4
 
 
51334e1
 
 
 
f9f18b4
35e8298
c688a70
a05bcb9
 
 
f9f18b4
5cb8fb6
51334e1
a05bcb9
f9f18b4
51334e1
c688a70
51334e1
c688a70
 
 
 
 
75c603a
f9f18b4
f73c0d1
c688a70
f73c0d1
75c603a
352d473
35e8298
5cb8fb6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    import streamlit as st
    import json
    from typing import Dict, List, Any
    import re

    def format_project_response(project: dict, indent_level: int = 0) -> str:
        """Format project details with proper indentation and spacing"""
        indent = "  " * indent_level
        
        response = [f"{indent}{project['name']}"]
        response.append(f"{indent}  {project['description']}")
        
        if 'skills_used' in project:
            response.append(f"{indent}  Technologies: {', '.join(project['skills_used'])}")
        
        if 'status' in project:
            status = project['status']
            if 'development' in status.lower() or 'progress' in status.lower():
                response.append(f"{indent}  Status: {status}")
                if 'confidentiality_note' in project:
                    response.append(f"{indent}  Note: {project['confidentiality_note']}")
        
        return '\n'.join(response) + '\n'

    def format_skills_response(skills: dict) -> str:
        """Format skills with proper hierarchy and spacing"""
        response = ["My Technical Expertise:\n"]
        
        categories = {
            'Machine Learning & AI': ['core', 'frameworks', 'focus_areas'],
            'Programming': ['primary', 'libraries', 'tools'],
            'Data & Analytics': ['databases', 'visualization', 'processing']
        }
        
        for category, subcategories in categories.items():
            response.append(f"• {category}")
            for subcat in subcategories:
                if subcat in skills['machine_learning']:
                    items = skills['machine_learning'][subcat]
                    response.append(f"  - {subcat.title()}: {', '.join(items)}")
            response.append("")  # Add spacing between categories
        
        return '\n'.join(response)

    def analyze_job_description(text: str, knowledge_base: dict) -> str:
        """Analyze job description and provide detailed alignment"""
        # Extract key requirements
        requirements = {
            'technical_tools': set(),
            'soft_skills': set(),
            'responsibilities': set()
        }
        
        # Common technical tools and skills
        tech_keywords = {
            'data science', 'analytics', 'visualization', 'tableau', 'python', 
            'machine learning', 'modeling', 'automation', 'sql', 'data analysis'
        }
        
        # Common soft skills
        soft_keywords = {
            'collaborate', 'communicate', 'analyze', 'design', 'implement',
            'produce insights', 'improve', 'support'
        }
        
        text_lower = text.lower()
        
        # Extract company name if present
        companies = ['rbc', 'shopify', 'google', 'microsoft', 'amazon']
        company_name = next((company.upper() for company in companies if company in text_lower), None)
        
        # Extract requirements
        for word in tech_keywords:
            if word in text_lower:
                requirements['technical_tools'].add(word)
        
        for word in soft_keywords:
            if word in text_lower:
                requirements['soft_skills'].add(word)
                
        # Build response
        response_parts = []
        
        # Company-specific introduction if applicable
        if company_name:
            response_parts.append(f"Here's how I align with {company_name}'s requirements:\n")
        else:
            response_parts.append("Based on the job requirements, here's how I align:\n")

        # Technical Skills Alignment
        response_parts.append("• Technical Skills Match:")
        my_relevant_skills = []
        if 'visualization' in requirements['technical_tools'] or 'tableau' in requirements['technical_tools']:
            my_relevant_skills.append("  - Proficient in Tableau and data visualization (used in multiple projects)")
        if 'data analysis' in requirements['technical_tools']:
            my_relevant_skills.append("  - Strong data analysis skills demonstrated in projects like LoanTap Credit Assessment")
        if 'machine learning' in requirements['technical_tools'] or 'modeling' in requirements['technical_tools']:
            my_relevant_skills.append("  - Experienced in building ML models from scratch (demonstrated in algorithm practice projects)")
        
        response_parts.extend(my_relevant_skills)
        response_parts.append("")
        
        # Business Understanding
        response_parts.append("• Business Acumen:")
        response_parts.append("  - Commerce background provides strong understanding of business requirements")
        response_parts.append("  - Experience in translating business needs into technical solutions")
        response_parts.append("  - Proven ability to communicate technical findings to business stakeholders")
        response_parts.append("")
        
        # Project Experience
        response_parts.append("• Relevant Project Experience:")
        relevant_projects = []
        if 'automation' in requirements['technical_tools']:
            relevant_projects.append("  - Developed AI-powered POS system with automated operations")
        if 'data analysis' in requirements['technical_tools']:
            relevant_projects.append("  - Built credit assessment model for LoanTap using comprehensive data analysis")
        if 'machine learning' in requirements['technical_tools']:
            relevant_projects.append("  - Created multiple ML models from scratch, including predictive analytics for Ola")
        
        response_parts.extend(relevant_projects)
        response_parts.append("")
        
        # Education and Additional Qualifications
        response_parts.append("• Additional Strengths:")
        response_parts.append("  - Currently pursuing advanced AI/ML education in Canada")
        response_parts.append("  - Strong foundation in both technical implementation and business analysis")
        response_parts.append("  - Experience in end-to-end project delivery and deployment")
        
        return '\n'.join(response_parts)

    def format_story_response(knowledge_base: dict) -> str:
        """Format background story with proper structure"""
        response_parts = ["My Journey from Commerce to ML/AI:\n"]
        
        # Education Background
        response_parts.append("• Education Background:")
        response_parts.append(f"  - Commerce degree from {knowledge_base['education']['undergraduate']['institution']}")
        response_parts.append(f"  - Currently at {knowledge_base['education']['postgraduate'][0]['institution']}")
        response_parts.append(f"  - Also enrolled at {knowledge_base['education']['postgraduate'][1]['institution']}")
        response_parts.append("")
        
        # Career Transition
        response_parts.append("• Career Transition:")
        transition = next((qa['answer'] for qa in knowledge_base['frequently_asked_questions'] 
                        if 'transition' in qa['question'].lower()), '')
        response_parts.append(f"  - {transition[:200]}...")
        response_parts.append("")
        
        # Current Focus
        response_parts.append("• Current Focus:")
        response_parts.append("  - Building practical ML projects")
        response_parts.append("  - Advancing AI/ML education in Canada")
        response_parts.append("")
        
        # Goals
        response_parts.append("• Future Goals:")
        response_parts.append("  - Secure ML Engineering role in Canada")
        response_parts.append("  - Develop innovative AI solutions")
        response_parts.append("  - Contribute to cutting-edge ML projects")
        
        return '\n'.join(response_parts)

    def format_standout_response() -> str:
        """Format response about standout qualities"""
        response_parts = ["What Makes Me Stand Out:\n"]
        response_parts.append("• Unique Background:")
        response_parts.append("  - Successfully transitioned from commerce to tech")
        response_parts.append("  - Blend of business acumen and technical expertise")
        response_parts.append("")
        
        response_parts.append("• Practical Experience:")
        response_parts.append("  - Built multiple ML projects from scratch")
        response_parts.append("  - Focus on real-world applications")
        response_parts.append("")
        
        response_parts.append("• Technical Depth:")
        response_parts.append("  - Strong foundation in ML/AI principles")
        response_parts.append("  - Experience with end-to-end project implementation")
        response_parts.append("")
        
        response_parts.append("• Innovation Focus:")
        response_parts.append("  - Developing novel solutions in ML/AI")
        response_parts.append("  - Emphasis on practical impact")
        
        return '\n'.join(response_parts)

    def add_relevant_links(response: str, query: str, knowledge_base: dict) -> str:
        """Add relevant links based on query context"""
        query_lower = query.lower()
        links = []
        
        if any(word in query_lower for word in ['project', 'portfolio', 'work']):
            links.append(f"\nView my complete portfolio: {knowledge_base['personal_details']['online_presence']['portfolio']}")
        
        if any(word in query_lower for word in ['background', 'experience', 'work']):
            links.append(f"\nConnect with me: {knowledge_base['personal_details']['online_presence']['linkedin']}")
        
        for post in knowledge_base['personal_details']['online_presence']['blog_posts']:
            if 'link' in post and any(word in query_lower for word in post['title'].lower().split()):
                links.append(f"\nRelated blog post: {post['link']}")
                break
        
        if links:
            response += '\n' + '\n'.join(links)
        
        return response

    def handle_market_conditions(knowledge_base: dict) -> str:
        """Handle market condition related queries with perspective"""
        market_outlook = knowledge_base['personal_details']['perspectives']['market_outlook']
        
        # Enhanced formatting for better readability
        response_parts = [
            "Here's my perspective on the current market situation:\n",
            f"• {market_outlook['job_market']}",
            f"\n• {market_outlook['value_proposition']}",
            f"\n• {market_outlook['strategy']}"
        ]
        
        return '\n'.join(response_parts)

    def handle_general_query(query: str, knowledge_base: dict) -> str:
        """Enhanced handling of general queries"""
        query_lower = query.lower()
        
        # Improved weather-related query detection
        if any(word in query_lower for word in ['weather', 'temperature', 'climate', 'cold', 'hot', 'warm']):
            return knowledge_base['personal_details']['common_queries']['weather']
        
        # Enhanced market-related query detection
        if any(phrase in query_lower for word in ['market', 'job market', 'jobs', 'opportunities', 'hiring']):
            return handle_market_conditions(knowledge_base)
        
        # More specific job fit query detection
        if any(phrase in query_lower for phrase in ['job description', 'job posting', 'job requirement', 'good fit']):
            return ("Please paste the job description you'd like me to analyze. I'll evaluate how my skills and experience align with the requirements.")
        
        # Default to personal summary
        return knowledge_base['personal_details']['professional_summary']

    def generate_response(query: str, knowledge_base: dict) -> str:
        """Enhanced response generation with improved pattern matching"""
        query_lower = query.lower()
        
        # Enhanced market conditions detection
        if any(word in query_lower for word in ['market', 'job market', 'hiring']) or \
        any(phrase in query_lower for phrase in ['market down', 'market conditions', 'current situation']):
            return handle_market_conditions(knowledge_base)
        
        # Enhanced job description analysis detection
        if ('job description' in query_lower or 'job posting' in query_lower) or \
        (len(query.split()) > 20 and any(word in query_lower for word in 
            ['requirements', 'qualifications', 'looking for', 'responsibilities', 'skills needed'])):
            if len(query.split()) < 20:
                return "Please paste the complete job description, and I'll analyze how well I match the requirements."
            return analyze_job_description(query, knowledge_base)
        
        # Enhanced weather query detection
        if any(word in query_lower for word in ['weather', 'temperature', 'climate', 'cold', 'hot', 'warm']):
            return handle_general_query(query, knowledge_base)
        
        # Existing handlers remain unchanged
        if any(word in query_lower for word in ['list', 'project', 'portfolio', 'built', 'created', 'developed']):
            response_parts = ["Here are my key projects:\n"]
            response_parts.append("Major Projects (In Development):")
            for project in knowledge_base['projects']['major_projects']:
                response_parts.append(format_project_response(project, indent_level=1))
            response_parts.append("Completed Algorithm Implementation Projects:")
            for project in knowledge_base['projects']['algorithm_practice_projects']:
                response_parts.append(format_project_response(project, indent_level=1))
            response = '\n'.join(response_parts)
            return add_relevant_links(response, query, knowledge_base)
        
        elif any(word in query_lower for word in ['background', 'journey', 'story', 'transition']):
            return format_story_response(knowledge_base)
        
        elif any(word in query_lower for word in ['skill', 'know', 'technology', 'stack']):
            return format_skills_response(knowledge_base['skills']['technical_skills'])
        
        elif any(word in query_lower for word in ['stand out', 'unique', 'different', 'special']):
            return format_standout_response()
        
        # General query handler for shorter queries
        elif len(query.split()) < 5:
            return handle_general_query(query, knowledge_base)
        
        # Default response
        return (f"I'm {knowledge_base['personal_details']['professional_summary']}\n\n"
                "You can ask me about:\n"
                "• My projects and portfolio\n"
                "• My journey from commerce to ML/AI\n"
                "• My technical skills and experience\n"
                "• My fit for ML/AI roles\n"
                "Or paste a job description to see how my profile matches!")

    def main():
        st.title("💬 Chat with Manyue's Portfolio")
        
        # Initialize session state
        if "messages" not in st.session_state:
            st.session_state.messages = []
        if "knowledge_base" not in st.session_state:
            try:
                with open('knowledge_base.json', 'r', encoding='utf-8') as f:
                    st.session_state.knowledge_base = json.load(f)
            except FileNotFoundError:
                st.error("Knowledge base file not found.")
                return
        
        # Display welcome message
        if "displayed_welcome" not in st.session_state:
            st.write("""
            Hi! I'm Manyue's AI assistant. I can tell you about:
            - My journey from commerce to ML/AI
            - My technical skills and projects
            - My fit for ML/AI roles
            - You can also paste job descriptions to see how my profile matches!
            """)
            st.session_state.displayed_welcome = True
        
        # Create two columns with adjusted ratios
        col1, col2 = st.columns([4, 1])
        
        with col1:
            # Display chat messages
            for message in st.session_state.messages:
                with st.chat_message(message["role"]):
                    st.markdown(message["content"])
            
            # Chat input
            if prompt := st.chat_input("Ask me anything or paste a job description..."):
            # Add user message
            st.session_state.messages.append({"role": "user", "content": prompt})
            
            try:
                # Generate and display response
                with st.chat_message("assistant"):
                    response = generate_response(prompt, st.session_state.knowledge_base)
                    st.markdown(response)
                    st.session_state.messages.append({"role": "assistant", "content": response})
            except Exception as e:
                st.error(f"An error occurred: {str(e)}")
            
            st.rerun()
    
    with col2:
        st.markdown("### Quick Questions")
        example_questions = [
            "Tell me about your ML projects",
            "What are your technical skills?",
            "What makes you stand out?",
            "What's your journey into ML?",
            "Paste a job description to see how I match!"
        ]
        
        for question in example_questions:
            if st.button(question, key=f"btn_{question}", use_container_width=True):
                st.session_state.messages.append({"role": "user", "content": question})
                try:
                    response = generate_response(question, st.session_state.knowledge_base)
                    st.session_state.messages.append({"role": "assistant", "content": response})
                except Exception as e:
                    st.error(f"An error occurred: {str(e)}")
                st.rerun()
        
        st.markdown("---")
        if st.button("Clear Chat", use_container_width=True):
            st.session_state.messages = []
            st.rerun()

if __name__ == "__main__":
    main()