Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -36,10 +36,15 @@ job_df["job_description"] = job_df["job_description"].fillna("")
|
|
36 |
bert_model = SentenceTransformer('paraphrase-MiniLM-L6-v2')
|
37 |
vectorizer = TfidfVectorizer()
|
38 |
|
39 |
-
# Pydantic
|
40 |
class ChallengeRequest(BaseModel):
|
41 |
-
skills: List[str]
|
42 |
-
difficulty: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
# Get coding challenges
|
45 |
def get_coding_challenges(categories: List[str], num_questions=5, difficulty: Optional[str] = None):
|
@@ -54,11 +59,47 @@ def get_coding_challenges(categories: List[str], num_questions=5, difficulty: Op
|
|
54 |
skill_challenges[category] = []
|
55 |
return skill_challenges
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
@app.get("/")
|
58 |
def read_root():
|
59 |
return {"message": "Skill Assessment API"}
|
60 |
|
61 |
-
#
|
62 |
@app.post("/challenges")
|
63 |
def get_user_challenges(request: ChallengeRequest):
|
64 |
skills = request.skills
|
@@ -80,6 +121,57 @@ def get_user_challenges(request: ChallengeRequest):
|
|
80 |
}
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
if __name__ == "__main__":
|
84 |
import uvicorn
|
85 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|
|
|
36 |
bert_model = SentenceTransformer('paraphrase-MiniLM-L6-v2')
|
37 |
vectorizer = TfidfVectorizer()
|
38 |
|
39 |
+
# Pydantic models for request bodies
|
40 |
class ChallengeRequest(BaseModel):
|
41 |
+
skills: List[str]
|
42 |
+
difficulty: Optional[str] = None
|
43 |
+
|
44 |
+
class AssessmentRequest(BaseModel):
|
45 |
+
name: str
|
46 |
+
skills: List[str]
|
47 |
+
answers: Optional[Dict[str, Dict[str, str]]] = None
|
48 |
|
49 |
# Get coding challenges
|
50 |
def get_coding_challenges(categories: List[str], num_questions=5, difficulty: Optional[str] = None):
|
|
|
59 |
skill_challenges[category] = []
|
60 |
return skill_challenges
|
61 |
|
62 |
+
# Evaluate coding answers
|
63 |
+
def evaluate_coding_with_time(user_code, correct_code, start_time):
|
64 |
+
end_time = time.time()
|
65 |
+
execution_time = end_time - start_time
|
66 |
+
vectorized = vectorizer.fit_transform([user_code, correct_code])
|
67 |
+
similarity = cosine_similarity(vectorized)[0][1] * 100
|
68 |
+
if execution_time > 120:
|
69 |
+
similarity -= (execution_time - 120) * 0.1
|
70 |
+
return round(max(similarity, 0), 2)
|
71 |
+
|
72 |
+
# Assign proficiency level
|
73 |
+
def get_proficiency_level(score):
|
74 |
+
if score >= 80:
|
75 |
+
return "Expert"
|
76 |
+
elif score >= 50:
|
77 |
+
return "Intermediate"
|
78 |
+
else:
|
79 |
+
return "Beginner"
|
80 |
+
|
81 |
+
# Recommend courses
|
82 |
+
def recommend_courses(weak_skills):
|
83 |
+
if not weak_skills:
|
84 |
+
return []
|
85 |
+
courses = course_df[course_df['skills'].str.contains('|'.join(weak_skills), case=False, na=False)]
|
86 |
+
return courses[['course_title', 'Organization']].head(5).to_dict(orient="records")
|
87 |
+
|
88 |
+
# Recommend jobs
|
89 |
+
def recommend_jobs(skills):
|
90 |
+
if not skills:
|
91 |
+
return []
|
92 |
+
job_df["job_embeddings"] = job_df["job_description"].apply(lambda x: bert_model.encode(str(x)))
|
93 |
+
user_embedding = bert_model.encode(" ".join(skills))
|
94 |
+
job_df["BERT_Similarity"] = job_df["job_embeddings"].apply(lambda x: cosine_similarity([x], [user_embedding])[0][0])
|
95 |
+
top_jobs = job_df.sort_values(by="BERT_Similarity", ascending=False).head(5)
|
96 |
+
return top_jobs[["job_title", "company", "location", "BERT_Similarity"]].to_dict(orient="records")
|
97 |
+
|
98 |
@app.get("/")
|
99 |
def read_root():
|
100 |
return {"message": "Skill Assessment API"}
|
101 |
|
102 |
+
# POST endpoint for fetching challenges
|
103 |
@app.post("/challenges")
|
104 |
def get_user_challenges(request: ChallengeRequest):
|
105 |
skills = request.skills
|
|
|
121 |
}
|
122 |
}
|
123 |
|
124 |
+
# POST endpoint for assessing answers
|
125 |
+
@app.post("/assess")
|
126 |
+
def assess_skills(user_input: AssessmentRequest):
|
127 |
+
user_name = user_input.name
|
128 |
+
user_skills = user_input.skills
|
129 |
+
|
130 |
+
if not user_skills:
|
131 |
+
raise HTTPException(status_code=400, detail="Skills list cannot be empty")
|
132 |
+
|
133 |
+
challenges = get_coding_challenges(user_skills)
|
134 |
+
|
135 |
+
user_scores = {}
|
136 |
+
for skill, challenge_list in challenges.items():
|
137 |
+
if not challenge_list:
|
138 |
+
user_scores[skill] = 0
|
139 |
+
continue
|
140 |
+
|
141 |
+
total_score = 0
|
142 |
+
num_questions = len(challenge_list)
|
143 |
+
|
144 |
+
if user_input.answers and skill in user_input.answers:
|
145 |
+
for challenge in challenge_list:
|
146 |
+
question = challenge["question"]
|
147 |
+
if question in user_input.answers[skill]:
|
148 |
+
start_time = time.time() - 10 # Simulate execution time
|
149 |
+
user_code = user_input.answers[skill][question]
|
150 |
+
correct_code = challenge["solutions"]
|
151 |
+
score = evaluate_coding_with_time(user_code, correct_code, start_time)
|
152 |
+
total_score += score
|
153 |
+
else:
|
154 |
+
total_score += 0
|
155 |
+
else:
|
156 |
+
total_score = 50 * num_questions # Default score for unattempted questions
|
157 |
+
|
158 |
+
user_scores[skill] = round(total_score / num_questions, 2)
|
159 |
+
|
160 |
+
proficiency_levels = {skill: get_proficiency_level(score) for skill, score in user_scores.items()}
|
161 |
+
weak_skills = [skill for skill, level in proficiency_levels.items() if level in ["Beginner", "Intermediate"]]
|
162 |
+
|
163 |
+
courses = recommend_courses(weak_skills)
|
164 |
+
jobs = recommend_jobs(user_skills)
|
165 |
+
|
166 |
+
return {
|
167 |
+
"name": user_name,
|
168 |
+
"skills": user_skills,
|
169 |
+
"scores": user_scores,
|
170 |
+
"proficiency_levels": proficiency_levels,
|
171 |
+
"recommended_courses": courses,
|
172 |
+
"recommended_jobs": jobs
|
173 |
+
}
|
174 |
+
|
175 |
if __name__ == "__main__":
|
176 |
import uvicorn
|
177 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|