Spaces:
Sleeping
Sleeping
File size: 7,295 Bytes
89ecbe8 2db43b3 89ecbe8 4972689 89ecbe8 22d1c60 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 22d1c60 4972689 89ecbe8 22d1c60 89ecbe8 22d1c60 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 4972689 89ecbe8 2db43b3 89ecbe8 4972689 2db43b3 22d1c60 4972689 |
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 |
import json
import re
import logging
from datetime import datetime
from typing import Dict, List, Any
logger = logging.getLogger(__name__)
class SimpleScoringAgent:
def calculate_scores(self, candidat_data: Dict[str, Any]) -> Dict[str, List[Dict[str, Any]]]:
if not candidat_data or not isinstance(candidat_data, dict):
return {"analyse_competences": []}
skills_data = candidat_data.get("compétences", {})
skills_list = self._extract_skills_list(skills_data)
if not skills_list:
return {"analyse_competences": []}
skill_analysis = []
for skill in skills_list:
level = self._determine_skill_level(skill, candidat_data)
skill_analysis.append({
"skill": skill,
"level": level
})
return {"analyse_competences": skill_analysis}
def _extract_skills_list(self, skills_data: Dict[str, Any]) -> List[str]:
"""Extrait la liste des compétences"""
skills_list = []
if isinstance(skills_data, dict):
skills_list.extend(skills_data.get("hard_skills", []))
skills_list.extend(skills_data.get("soft_skills", []))
elif isinstance(skills_data, list):
skills_list = [item.get("nom") for item in skills_data if item.get("nom")]
return [skill for skill in skills_list if skill and isinstance(skill, str) and skill.strip()]
def _determine_skill_level(self, skill: str, candidat_data: Dict[str, Any]) -> str:
"""Détermine le niveau d'une compétence selon des règles simples"""
frequency = self._count_skill_mentions(skill, candidat_data)
max_duration = self._get_max_duration_for_skill(skill, candidat_data)
has_pro_experience = self._has_professional_experience(skill, candidat_data)
# Règles simples de classification
if has_pro_experience and max_duration >= 3.0:
return "expert"
elif has_pro_experience and max_duration >= 1.0:
return "avance"
elif frequency >= 3 or max_duration >= 0.5:
return "intermediaire"
else:
return "debutant"
def _count_skill_mentions(self, skill: str, candidat_data: Dict[str, Any]) -> int:
"""Compte le nombre de mentions de la compétence"""
skill_lower = skill.lower()
total_mentions = 0
# Recherche dans toutes les sections
all_text = self._get_all_text_content(candidat_data).lower()
total_mentions = all_text.count(skill_lower)
return total_mentions
def _get_max_duration_for_skill(self, skill: str, candidat_data: Dict[str, Any]) -> float:
"""Trouve la durée maximum d'utilisation de la compétence"""
skill_lower = skill.lower()
max_duration = 0.0
experiences_key = "expériences" if "expériences" in candidat_data else "experiences_professionnelles"
experiences = candidat_data.get(experiences_key, [])
if not isinstance(experiences, list):
return 0.0
for exp in experiences:
if not isinstance(exp, dict):
continue
exp_text = json.dumps(exp, ensure_ascii=False).lower()
if skill_lower in exp_text:
duration = self._calculate_experience_duration(exp)
max_duration = max(max_duration, duration)
return max_duration
def _has_professional_experience(self, skill: str, candidat_data: Dict[str, Any]) -> bool:
"""Vérifie si la compétence a été utilisée en contexte professionnel"""
skill_lower = skill.lower()
experiences_key = "expériences" if "expériences" in candidat_data else "experiences_professionnelles"
experiences = candidat_data.get(experiences_key, [])
if not isinstance(experiences, list):
return False
for exp in experiences:
if not isinstance(exp, dict):
continue
exp_text = json.dumps(exp, ensure_ascii=False).lower()
if skill_lower in exp_text:
return True
return False
def _get_all_text_content(self, candidat_data: Dict[str, Any]) -> str:
"""Récupère tout le contenu textuel du CV"""
all_content = []
# Expériences
experiences_key = "expériences" if "expériences" in candidat_data else "experiences_professionnelles"
for exp in candidat_data.get(experiences_key, []):
if isinstance(exp, dict):
all_content.append(json.dumps(exp, ensure_ascii=False))
# Projets
projects = candidat_data.get("projets", {})
if isinstance(projects, dict):
for project_type in ["professional", "personal"]:
for project in projects.get(project_type, []):
if isinstance(project, dict):
all_content.append(json.dumps(project, ensure_ascii=False))
# Formations
for formation in candidat_data.get("formations", []):
if isinstance(formation, dict):
all_content.append(json.dumps(formation, ensure_ascii=False))
return " ".join(all_content)
def _calculate_experience_duration(self, exp: Dict[str, Any]) -> float:
"""Calcule la durée d'une expérience en années"""
start_date_str = exp.get("date_debut", exp.get("start_date", ""))
end_date_str = exp.get("date_fin", exp.get("end_date", ""))
if not isinstance(start_date_str, str):
start_date_str = str(start_date_str) if start_date_str else ""
if not isinstance(end_date_str, str):
end_date_str = str(end_date_str) if end_date_str else ""
return self._calculate_duration_in_years(start_date_str, end_date_str)
def _calculate_duration_in_years(self, start_date_str: str, end_date_str: str) -> float:
"""Calcule la durée entre deux dates en années"""
start_date = self._parse_date(start_date_str)
end_date = self._parse_date(end_date_str)
if start_date and end_date:
if end_date < start_date:
return 0.0
return (end_date - start_date).days / 365.25
return 0.0
def _parse_date(self, date_str: str) -> datetime:
"""Parse une date de manière simple"""
if not date_str or not isinstance(date_str, str):
return None
date_str_lower = date_str.lower().strip()
if date_str_lower in ["aujourd'hui", "maintenant", "en cours", "current", "présent", "actuellement"]:
return datetime.now()
# Extraction simple de l'année
year_match = re.search(r'\b(20\d{2}|19\d{2})\b', date_str)
if year_match:
year = int(year_match.group(1))
return datetime(year, 1, 1)
return None
# Alias pour maintenir la compatibilité
ScoringAgent = SimpleScoringAgent
ImprovedScoringAgent = SimpleScoringAgent |