tahirsher commited on
Commit
2361c02
1 Parent(s): 884344e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +233 -85
app.py CHANGED
@@ -1,94 +1,242 @@
1
- import threading
2
- import time # Simulate a long task for demonstration
3
- from transformers import pipeline
4
- from datasets import load_dataset
5
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
6
 
7
- # Load datasets
8
- jobs_dataset = load_dataset("lukebarousse/data_jobs")["train"]
 
9
  universities_url = "https://www.4icu.org/top-universities-world/"
10
- courses_dataset = load_dataset("azrai99/coursera-course-dataset")["train"]
11
-
12
- # Function to handle long-running tasks with timeout
13
- def run_with_timeout(target_func, timeout, *args, **kwargs):
14
- result = [None]
15
- exception = [None]
16
-
17
- def wrapper():
18
- try:
19
- result[0] = target_func(*args, **kwargs)
20
- except Exception as e:
21
- exception[0] = e
22
-
23
- thread = threading.Thread(target=wrapper)
24
- thread.start()
25
- thread.join(timeout=timeout)
26
-
27
- if thread.is_alive():
28
- st.warning("The operation timed out. Please try again.")
29
- return None
30
- if exception[0]:
31
- raise exception[0]
32
- return result[0]
33
-
34
- # Load QA pipeline for Q&A session
35
- qa_pipeline = pipeline("question-answering", model="distilbert-base-uncased-distilled-squad")
36
-
37
- # Streamlit UI
38
- st.title("Intelligent Career & Course Recommendation System")
39
-
40
- # Profile setup
41
- st.subheader("Profile Setup")
42
- profile_data = {
43
- "name": st.text_input("Enter your name"),
44
- "interests": st.text_input("List your interests (comma-separated)"),
45
- "tech_skills": st.text_input("List your technical skills (comma-separated)"),
46
- }
47
-
48
- if st.button("Save Profile"):
49
- if profile_data["name"] and profile_data["interests"] and profile_data["tech_skills"]:
50
- st.session_state.profile_data = profile_data
51
- st.success("Profile saved successfully!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  else:
53
- st.warning("Please fill in all fields.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- # Q&A session after profile setup
56
  if "profile_data" in st.session_state:
57
- st.subheader("Q&A Session")
58
- question = st.text_input("Ask a question about your career or courses:")
59
-
60
- if st.button("Submit Question"):
61
- if question:
62
- # Filter context based on interests or skills
63
- relevant_jobs = [job for job in jobs_dataset if any(interest in job["job_title"].lower() for interest in [i.strip().lower() for i in st.session_state.profile_data["interests"].split(",")])]
64
- context = " ".join([job["job_description"] for job in relevant_jobs if "job_description" in job]) # Creating a context from relevant job descriptions
65
- if context:
66
- answer = run_with_timeout(qa_pipeline, timeout=10, question=question, context=context) # Using a longer timeout
 
 
 
 
 
 
 
 
 
 
 
67
  if answer:
68
- st.write(f"Answer: {answer['answer']}")
69
- else:
70
- st.warning("No relevant jobs found to answer your question.")
 
 
 
 
 
71
  else:
72
- st.warning("Please enter a question.")
 
 
 
 
73
 
74
- # Job and course recommendations based on interests and skills
75
- if "profile_data" in st.session_state:
76
- st.subheader("Career and Course Recommendations")
77
- interests = [interest.strip().lower() for interest in st.session_state.profile_data["interests"].split(",")]
78
- tech_skills = [skill.strip().lower() for skill in st.session_state.profile_data["tech_skills"].split(",")]
79
-
80
- # Job Recommendations
81
- st.write("### Job Recommendations:")
82
- for job in jobs_dataset:
83
- job_skills = job.get("job_skills", [])
84
- if job_skills is not None: # Check if job_skills is not None
85
- job_skills = [skill.lower() for skill in job_skills] # Lowercase the skills
86
- if any(skill in job_skills for skill in tech_skills):
87
- st.write(f"- **{job['job_title']}** at {job['company_name']}, Location: {job['job_location']}")
88
-
89
- # Course Recommendations
90
- st.write("### Course Recommendations:")
91
- for course in courses_dataset:
92
- course_skills = [skill.lower() for skill in course["Skills"]] if course["Skills"] is not None else []
93
- if any(interest in course["Title"].lower() for interest in interests):
94
- st.write(f"- **{course['Title']}** by {course['Organization']}. [Link to course]({course['course_url']})")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import pandas as pd
3
+ from transformers import pipeline
4
+ import time
5
+
6
+ # Load datasets from CSV files
7
+ @st.cache_resource
8
+ def load_csv_datasets():
9
+ jobs_data = pd.read_csv("job_descriptions.csv")
10
+ courses_data = pd.read_csv("courses_data.csv")
11
+ return jobs_data, courses_data
12
 
13
+ jobs_data, courses_data = load_csv_datasets()
14
+
15
+ # Constants
16
  universities_url = "https://www.4icu.org/top-universities-world/"
17
+
18
+ # Initialize the text generation pipeline
19
+ @st.cache_resource
20
+ def load_pipeline():
21
+ return pipeline("text2text-generation", model="google/flan-t5-large")
22
+
23
+ qa_pipeline = load_pipeline()
24
+
25
+ # Streamlit App Interface
26
+ st.markdown(
27
+ """
28
+ <div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
29
+ <h1 style="font-size: 29px; display: inline-block; margin-right: 10px;">
30
+ <img src="https://img.icons8.com/ios-filled/50/000000/graduation-cap.png" width="40" alt="Degree icon"/>
31
+ Confused about which career to pursue?
32
+ </h1>
33
+ <h2 style="font-size: 25px; display: inline-block; margin: 0;">Let CareerCompass help you decide in two simple steps</h2>
34
+ </div>
35
+ """,
36
+ unsafe_allow_html=True,
37
+ )
38
+
39
+ # Display the appropriate subheader based on profile data status
40
+ if "profile_data" not in st.session_state or not st.session_state.get("profile_data_saved", False):
41
+ st.markdown("<h3 style='font-size: 20px;'>Step 1: Find out profile questions on the left sidebar and follow the instructions.</h3>", unsafe_allow_html=True)
42
+
43
+ # Sidebar for Profile Setup
44
+ st.sidebar.header("Profile Setup")
45
+ educational_background = st.sidebar.selectbox("Educational Background", [
46
+ "Computer Science", "Engineering", "Business Administration", "Life Sciences",
47
+ "Social Sciences", "Arts and Humanities", "Mathematics", "Physical Sciences",
48
+ "Law", "Education", "Medical Sciences", "Other"
49
+ ])
50
+ interests = st.sidebar.text_input("Interests (e.g., AI, Data Science, Engineering)")
51
+ tech_skills = st.sidebar.text_area("Technical Skills (e.g., Python, SQL, Machine Learning)")
52
+ soft_skills = st.sidebar.text_area("Soft Skills (e.g., Communication, Teamwork)")
53
+
54
+ # Profile validation and saving
55
+ def are_profile_fields_filled():
56
+ return all([educational_background, interests.strip(), tech_skills.strip(), soft_skills.strip()])
57
+
58
+ if st.sidebar.button("Save Profile"):
59
+ if are_profile_fields_filled():
60
+ with st.spinner('Saving your profile...'):
61
+ time.sleep(2)
62
+ st.session_state.profile_data = {
63
+ "educational_background": educational_background,
64
+ "interests": interests,
65
+ "tech_skills": tech_skills,
66
+ "soft_skills": soft_skills
67
+ }
68
+ st.session_state.profile_data_saved = True # Set the profile data saved flag
69
+ st.session_state.question_index = 0 # Initialize question index
70
+ st.session_state.answers = {} # Initialize dictionary for answers
71
+ st.session_state.ask_additional_questions = None # Reset question flag
72
+ st.session_state.show_additional_question_buttons = True # Show buttons after profile save
73
+ st.sidebar.success("Profile saved successfully!")
74
+ st.markdown("<h2 style='font-size: 25px;'>Step 2: For more Accurate Analysis, Do you wish to provide more information?</h2>", unsafe_allow_html=True)
75
  else:
76
+ st.sidebar.error("Please fill in all the fields before saving your profile.")
77
+
78
+ # Button actions
79
+ if "show_additional_question_buttons" in st.session_state:
80
+ if st.session_state.show_additional_question_buttons:
81
+ col1, col2 = st.columns(2)
82
+ with col1:
83
+ if st.button("Yes, ask me more questions"):
84
+ st.session_state.ask_additional_questions = True
85
+ st.session_state.show_additional_question_buttons = False # Hide buttons after click
86
+ with col2:
87
+ if st.button("Skip and generate recommendations"):
88
+ st.session_state.ask_additional_questions = False
89
+ st.session_state.show_additional_question_buttons = False # Hide buttons after click
90
+
91
+ # Additional questions for more tailored recommendations
92
+ additional_questions = [
93
+ "What subjects do you enjoy learning about the most, and why?",
94
+ "What activities or hobbies do you find most engaging and meaningful outside of school?",
95
+ "Can you describe a perfect day in your dream career? What tasks would you be doing?",
96
+ "Are you more inclined towards working independently or as part of a team?",
97
+ "Do you prefer structured schedules or flexibility in your work?",
98
+ "What values are most important to you in a career (e.g., creativity, stability, helping others)?",
99
+ "How important is financial stability to you in your future career?",
100
+ "Are you interested in pursuing a career that involves working with people, technology, or the environment?",
101
+ "Would you prefer a career with a clear progression path or one with more entrepreneurial freedom?",
102
+ "What problems or challenges do you want to solve or address through your career?"
103
+ ]
104
 
105
+ # Display dynamic questions or proceed to generating recommendations
106
  if "profile_data" in st.session_state:
107
+ if st.session_state.get("ask_additional_questions") is True:
108
+ total_questions = len(additional_questions)
109
+ if "question_index" not in st.session_state:
110
+ st.session_state.question_index = 0
111
+
112
+ if st.session_state.question_index < total_questions:
113
+ question_number = st.session_state.question_index + 1
114
+ question = additional_questions[st.session_state.question_index]
115
+
116
+ # Display question number and question text
117
+ st.markdown(f"""### Question {question_number}:
118
+ {question}""")
119
+
120
+ answer = st.text_input("Your Answer", key=f"q{st.session_state.question_index}")
121
+
122
+ # Display progress bar with formatted text showing "current/total"
123
+ progress = (st.session_state.question_index + 1) / total_questions
124
+ st.progress(progress)
125
+ st.write(f"Progress: {question_number}/{total_questions}")
126
+
127
+ if st.button("Submit Answer", key=f"submit{st.session_state.question_index}"):
128
  if answer:
129
+ st.warning("Data saved successfully. click again to proceed")
130
+ # Save the answer and increment the question index
131
+ st.session_state.question_index += 1
132
+ st.session_state.answers[question] = answer
133
+
134
+ # No need to call a special function; the app will rerun automatically
135
+ else:
136
+ st.warning("Please enter an answer before submitting.")
137
  else:
138
+ st.success("All questions have been answered. Click below to generate your recommendations.")
139
+ if st.button("Generate Response"):
140
+ st.warning("Data saved successfully. click again to proceed")
141
+ st.session_state.profile_data.update(st.session_state.answers)
142
+ st.session_state.ask_additional_questions = False
143
 
144
+ elif st.session_state.get("ask_additional_questions") is False:
145
+ # Directly generate recommendations
146
+ st.header("Generating Recommendations")
147
+ with st.spinner('Generating recommendations...'):
148
+ time.sleep(2) # Simulate processing time
149
+
150
+ # Extracting user profile data
151
+ profile = st.session_state.profile_data
152
+ user_tech_skills = set(skill.strip().lower() for skill in profile["tech_skills"].split(","))
153
+ user_soft_skills = set(skill.strip().lower() for skill in profile["soft_skills"].split(","))
154
+ user_interests = set(interest.strip().lower() for interest in profile["interests"].split(","))
155
+ user_answers = st.session_state.get('answers', {})
156
+
157
+ # Job Recommendations using refined scoring logic
158
+ def match_job_criteria(row, profile, user_answers):
159
+ job_title = row['Job Title'].lower()
160
+ job_description = row['Job Description'].lower()
161
+ qualifications = row['Qualifications'].lower()
162
+ skills = row['skills'].lower()
163
+ role = row['Role'].lower()
164
+
165
+ educational_background = profile['educational_background'].lower()
166
+ tech_skills = set(skill.strip().lower() for skill in profile["tech_skills"].split(","))
167
+ soft_skills = set(skill.strip().lower() for skill in profile["soft_skills"].split(","))
168
+ interests = set(interest.strip().lower() for interest in profile["interests"].split(","))
169
+ user_answers_text = ' '.join(user_answers.values()).lower()
170
+
171
+ score = 0
172
+
173
+ if educational_background in qualifications or educational_background in job_description:
174
+ score += 2
175
+ if any(skill in skills for skill in tech_skills):
176
+ score += 3
177
+ if any(skill in job_description or role for skill in soft_skills):
178
+ score += 1
179
+ if any(interest in job_title or job_description for interest in interests):
180
+ score += 2
181
+ if any(answer in job_description or qualifications for answer in user_answers_text.split()):
182
+ score += 2
183
+
184
+ return score >= 5
185
+
186
+ # Get unique job recommendations
187
+ job_recommendations = jobs_data[jobs_data.apply(lambda row: match_job_criteria(row, profile, user_answers), axis=1)]
188
+ unique_jobs = job_recommendations.drop_duplicates(subset=['Job Title'])
189
+
190
+ # Display Job Recommendations in a table with bold job titles
191
+ st.subheader("Job Recommendations")
192
+ if not unique_jobs.empty:
193
+ job_list = unique_jobs.head(5)[['Job Title', 'Job Description']].reset_index(drop=True)
194
+ job_list['Job Title'] = job_list['Job Title'].apply(lambda x: f"<b>{x}</b>")
195
+ job_list_html = job_list.to_html(index=False, escape=False, justify='left').replace(
196
+ '<th>', '<th style="text-align: left; font-weight: bold;">')
197
+ st.markdown(job_list_html, unsafe_allow_html=True)
198
+ else:
199
+ st.write("No specific job recommendations found matching your profile.")
200
+ st.write("Here are some general job recommendations:")
201
+ fallback_jobs = jobs_data.drop_duplicates(subset=['Job Title']).head(3)
202
+ fallback_jobs['Job Title'] = fallback_jobs['Job Title'].apply(lambda x: f"<b>{x}</b>")
203
+ fallback_list_html = fallback_jobs[['Job Title', 'Job Description']].to_html(
204
+ index=False, escape=False, justify='left').replace(
205
+ '<th>', '<th style="text-align: left; font-weight: bold;">')
206
+ st.markdown(fallback_list_html, unsafe_allow_html=True)
207
+
208
+ # Course Recommendations using RAG technique
209
+ course_recommendations = courses_data[courses_data['Course Name'].apply(
210
+ lambda name: any(interest in name.lower() for interest in user_interests)
211
+ )]
212
+
213
+ # Display Course Recommendations
214
+ st.subheader("Recommended Courses")
215
+ if not course_recommendations.empty:
216
+ for _, row in course_recommendations.head(5).iterrows():
217
+ st.write(f"- [{row['Course Name']}]({row['Links']})")
218
+ else:
219
+ st.write("No specific course recommendations found matching your interests.")
220
+ st.write("Here are some general course recommendations aligned with your profile:")
221
+
222
+ fallback_courses = courses_data[
223
+ courses_data['Course Name'].apply(
224
+ lambda name: any(
225
+ word in name.lower() for word in profile["educational_background"].lower().split() +
226
+ [skill.lower() for skill in profile["tech_skills"].split(",")]
227
+ )
228
+ )
229
+ ]
230
+
231
+ if not fallback_courses.empty:
232
+ for _, row in fallback_courses.head(3).iterrows():
233
+ st.write(f"- [{row['Course Name']}]({row['Links']})")
234
+ else:
235
+ st.write("Consider exploring courses in fields related to your educational background or technical skills.")
236
+
237
+ # University Recommendations Section
238
+ st.header("Top Universities")
239
+ st.write("For further education, you can explore the top universities worldwide:")
240
+ st.write(f"[View Top Universities Rankings]({universities_url})")
241
+
242
+ st.write("Thank you for using the Career Counseling Application with RAG!")