def score_and_explain(self, project: scoring_base.ScoringProject) \ -> scoring_base.ExplainedScore: """Compute a score for the given ScoringProject.""" close_jobs = self.get_close_jobs(project) search_since_nb_months = round(project.get_search_length_now()) score_modifier = 0 reasons: List[str] = [] if len(close_jobs.close_jobs) + len(close_jobs.evolution_jobs) < 2: return scoring_base.NULL_EXPLAINED_SCORE # TODO(cyrille): Make this more robust. force_in_stuck_market = None # TODO(cyrille): Rather use market_stress to avoid depending on diagnostic to be computed. if project.details.diagnostic.category_id == 'stuck-market': force_in_stuck_market = scoring_base.ExplainedScore(1, reasons) if project.get_user_age() >= 45: return force_in_stuck_market or scoring_base.NULL_EXPLAINED_SCORE if project.details.passionate_level >= project_pb2.PASSIONATING_JOB: score_modifier = -1 else: reasons.append(project.translate_string( "vous n'êtes pas trop attaché à votre métier")) if project.details.job_search_has_not_started or search_since_nb_months <= 1: return scoring_base.ExplainedScore(2 + score_modifier, reasons) reasons = [ project.translate_string('vous cherchez depuis {} mois') .format(search_since_nb_months)] if search_since_nb_months >= 12: return scoring_base.ExplainedScore(3, reasons) if search_since_nb_months >= 9: return scoring_base.ExplainedScore(2, reasons) if search_since_nb_months >= 6: return scoring_base.ExplainedScore(1, reasons) return force_in_stuck_market or scoring_base.NULL_EXPLAINED_SCORE
def score_and_explain(self, project: scoring_base.ScoringProject) \ -> scoring_base.ExplainedScore: """Compute a score for the given ScoringProject.""" reasons: List[str] = [] # For now we just match for people willing to move to the whole country. # There might be cases where we should be able to recommend to people who want to move to # their own region, but it would add complexity to find them. is_not_ready_to_move = project.details.area_type < geo_pb2.COUNTRY is_not_single = project.user_profile.family_situation != user_pb2.SINGLE has_advanced_degree = project.user_profile.highest_degree >= job_pb2.LICENCE_MAITRISE is_not_young = project.get_user_age() > 30 looks_only_for_cdi = project.details.employment_types == [job_pb2.CDI] if (is_not_ready_to_move or is_not_young or is_not_single or has_advanced_degree or looks_only_for_cdi): return scoring_base.NULL_EXPLAINED_SCORE reasons.append( project.translate_string( 'vous nous avez dit être prêt%eFeminine à déménager')) reasons.append( project.translate_string('vous êtes disponible familialement')) if len(self._get_seasonal_departements(project).departement_stats) > 1: reasons.append( project.translate_string( "il y a plus d'offres saisonnières par habitants dans d'autres villes" )) return scoring_base.ExplainedScore(2, reasons) return scoring_base.NULL_EXPLAINED_SCORE
def score_and_explain(self, project: scoring_base.ScoringProject) \ -> scoring_base.ExplainedScore: """Compute the score for a given project and explains it. Requirements are: - being between 16 and 30 y.o if having a handicap or between 16 and 25 otherwise - having low or no experience (intern maximum) """ age = project.get_user_age() seniority = project.details.seniority reasons: list[str] = [] if age < 16 or seniority > project_pb2.INTERN: return scoring_base.NULL_EXPLAINED_SCORE if project.user_profile.has_handicap and age <= 30: reasons = [ project.translate_static_string('vous avez entre 16 et 30 ans') ] if age <= 25: reasons = [ project.translate_static_string('vous avez entre 16 et 25 ans') ] if not reasons: return scoring_base.NULL_EXPLAINED_SCORE return scoring_base.ExplainedScore(2, reasons)
def score_and_explain(self, project: scoring_base.ScoringProject) \ -> scoring_base.ExplainedScore: """Compute the score for a given project and explains it.""" age = project.get_user_age() if age < 16 or age >= 25: return scoring_base.NULL_EXPLAINED_SCORE return _score_and_explain_after_filters(project)
def score(self, project: scoring_base.ScoringProject) -> float: # TODO(cyrille): Find a way to make sure they're really desillusioned. if project.get_search_length_now() < 3: # User is probably not disillusioned yet. return 0 if project.details.seniority < project_pb2.CARREER: return 0 return max(0, min(3, project.get_user_age() - 50))
def score_and_explain(self, project: scoring_base.ScoringProject) \ -> scoring_base.ExplainedScore: """Compute the score for a given project and explains it.""" age = project.get_user_age() if age < 16: return scoring_base.NULL_EXPLAINED_SCORE score, reasons = _score_and_explain_after_filters(project) if not score: return scoring_base.NULL_EXPLAINED_SCORE # We bring more value in the driving-license-euro and # driving-license-low-income so we show this one after (lower score). return scoring_base.ExplainedScore(max(1, score - 1), reasons)
def get_expanded_card_data(self, project: scoring_base.ScoringProject) \ -> driving_license_pb2.OneEuroProgram: """Retrieve data for the expanded card.""" banks = _PARTNER_BANKS.get_collection(project.database) all_schools = _PARTNER_SCHOOLS.get_collection(project.database) relevant_schools = scoring_base.filter_using_score( all_schools, lambda s: s.filters, project) # TODO(cyrille): Replace this once importer gets schools, and not only lists. user_specific_list = next( (school.link for school in relevant_schools if school.link), None) one_euro_program = driving_license_pb2.OneEuroProgram( partner_banks=banks) if project.get_user_age() <= 18: one_euro_program.mission_locale.CopyFrom( project.mission_locale_data()) if user_specific_list: one_euro_program.school_list_link = user_specific_list return one_euro_program
def score_and_explain(self, project: scoring_base.ScoringProject) \ -> scoring_base.ExplainedScore: """Compute the score for a given project and explains it. Requirements are: - not having a driving license (duh) - being older than 25 (we have other resources for younger people) And for this specific help from PE: - being registered as unemployed for more than 6 months - be sure that a license would really help to get a job (market tension) - not have too much allowances from PE """ # TODO(cyrille): Add tension market. age = project.get_user_age() # TODO(cyrille): Figure out in a notebook if junior salary from IMT would be more relevant. expected_salary = project.salary_estimation() if age < 25 or project.get_search_length_now( ) < 6 or expected_salary > 20000: return scoring_base.NULL_EXPLAINED_SCORE return _score_and_explain_after_filters(project)
def score_and_explain(self, project: scoring_base.ScoringProject) \ -> scoring_base.ExplainedScore: """Compute a score for the given ScoringProject.""" if project.details.previous_job_similarity != project_pb2.NEVER_DONE or \ project.get_user_age() > 25: return scoring_base.NULL_EXPLAINED_SCORE explanations: List[str] = [] score: float = 2 if project.details.network_estimate <= 2: explanations.append( project.translate_string( 'ça vous aide à développer votre réseau')) score += .5 if project.details.passionate_level >= project_pb2.PASSIONATING_JOB: explanations.append( project.translate_string('ça montre votre motivation')) score += .5 return scoring_base.ExplainedScore(score, explanations)
def score_to_hundred(self, project: scoring_base.ScoringProject) -> int: # rescale user age: <=18 -> 100, >=68 -> 0 return (68 - project.get_user_age()) * 2
def score(self, project: scoring_base.ScoringProject) -> float: # If seniority is unknown, it usually means that previous job similarity is NEVER_DONE. if project.details.seniority > project_pb2.INTERN: return 0 return max(0, min(3, (25 - project.get_user_age())))