def formula(commune, period, parameters): population_dgf = commune("population_dgf", period) revenu_par_habitant = commune("revenu_par_habitant", period) revenu_par_habitant_strate = commune("revenu_par_habitant_moyen", period) potentiel_financier_par_habitant = commune( "potentiel_financier_par_habitant", period) potentiel_financier_par_habitant_strate = commune( "potentiel_financier_par_habitant_moyen", period) dsr_eligible_fraction_bourg_centre = commune( "dsr_eligible_fraction_bourg_centre", period) dsr_eligible_fraction_perequation = commune( "dsr_eligible_fraction_perequation", period) limite_population = parameters( period).dotation_solidarite_rurale.seuil_nombre_habitants parametres_poids = parameters( period ).dotation_solidarite_rurale.cible.eligibilite.indice_synthetique poids_revenu = parametres_poids.poids_revenu poids_pot_fin = parametres_poids.poids_potentiel_financier return ( (population_dgf < limite_population) * (dsr_eligible_fraction_bourg_centre | dsr_eligible_fraction_perequation) * (poids_pot_fin * safe_divide(potentiel_financier_par_habitant_strate, potentiel_financier_par_habitant, 0) + poids_revenu * safe_divide(revenu_par_habitant_strate, revenu_par_habitant, 0)))
def formula(commune, period, parameters): potentiel_financier = commune('potentiel_financier', period) outre_mer = commune('outre_mer', period) potentiel_financier_par_habitant = commune( 'potentiel_financier_par_hectare', period) dsr_eligible_fraction_cible = commune("dsr_eligible_fraction_cible", period) population_dgf = commune('population_dgf', period) # oui le taille_max_commune est le même que pour le seuil d'éligibilité, notre paramétrisation est ainsi taille_max_commune = parameters( period).dotation_solidarite_rurale.seuil_nombre_habitants superficie = commune('superficie', period) communes_moins_10000 = (~outre_mer) * (population_dgf < taille_max_commune) pot_fin_par_hectare_10000 = safe_divide( np.sum(communes_moins_10000 * potentiel_financier), np.sum(communes_moins_10000 * superficie)) facteur_pot_fin = max_( 0, safe_divide((2 * pot_fin_par_hectare_10000 - potentiel_financier_par_habitant), pot_fin_par_hectare_10000, 0)) return dsr_eligible_fraction_cible * population_dgf * facteur_pot_fin
def formula(commune, period, parameters): potentiel_financier_par_habitant = commune( 'potentiel_financier_par_habitant', period) potentiel_financier_par_habitant_strate = commune( 'potentiel_financier_par_habitant_moyen', period) effort_fiscal = commune('effort_fiscal', period) dsr_eligible_fraction_cible = commune("dsr_eligible_fraction_cible", period) population_dgf = commune('population_dgf', period) plafond_effort_fiscal = parameters( period ).dotation_solidarite_rurale.attribution.plafond_effort_fiscal facteur_pot_fin = max_( 0, 2 - safe_divide(potentiel_financier_par_habitant, potentiel_financier_par_habitant_strate, 2)) facteur_effort_fiscal = np.minimum(plafond_effort_fiscal, effort_fiscal) return dsr_eligible_fraction_cible * population_dgf * facteur_pot_fin * facteur_effort_fiscal
def formula(commune, period, parameters): plancher_dgcl_population_dgf_majoree = 500 plafond_dgcl_population_dgf_majoree = 200000 facteur_du_coefficient_logarithmique = 1 / (log10(plafond_dgcl_population_dgf_majoree / plancher_dgcl_population_dgf_majoree)) # le fameux 0.38431089 population_majoree_dgf = commune('population_dgf_majoree', period) population_majoree_dgf_an_dernier = commune('population_dgf_majoree', period.last_year) evolution_population = population_majoree_dgf - population_majoree_dgf_an_dernier facteur_minimum = parameters(period).dotation_forfaitaire.montant_minimum_par_habitant facteur_maximum = parameters(period).dotation_forfaitaire.montant_maximum_par_habitant dotation_supp_par_habitant = facteur_minimum + (facteur_maximum - facteur_minimum) * max_(0, min_(1, facteur_du_coefficient_logarithmique * log10(safe_divide(population_majoree_dgf, plancher_dgcl_population_dgf_majoree, 1)))) return dotation_supp_par_habitant * evolution_population
def formula_2019_01(commune, period, parameters): dsu_montant_total = commune('dsu_montant_total', period) dsu_an_precedent = commune('dsu_montant_total', period.last_year) montants_an_precedent = commune('dsu_montant_eligible', period.last_year) dsu_eligible = commune('dsu_eligible', period) total_a_distribuer = commune('dsu_montant_total_eligibles', period) rang_indice_synthetique_dsu_seuil_bas = commune('rang_indice_synthetique_dsu_seuil_bas', period) rang_indice_synthetique_dsu_seuil_haut = commune('rang_indice_synthetique_dsu_seuil_haut', period) nombre_elig_seuil_bas = commune('dsu_nombre_communes_eligibles_seuil_bas', period) nombre_elig_seuil_haut = commune('dsu_nombre_communes_eligibles_seuil_haut', period) effort_fiscal = commune('effort_fiscal', period) population_insee = commune('population_insee', period) population_qpv = commune('population_qpv', period) population_zfu = commune('population_zfu', period) population_dgf = commune('population_dgf', period) indice_synthetique_dsu = commune('indice_synthetique_dsu', period) facteur_classement_max = parameters(period).dotation_solidarite_urbaine.attribution.facteur_classement_max facteur_classement_min = parameters(period).dotation_solidarite_urbaine.attribution.facteur_classement_min poids_quartiers_prioritaires_ville = parameters(period).dotation_solidarite_urbaine.attribution.poids_quartiers_prioritaires_ville poids_zone_franche_urbaine = parameters(period).dotation_solidarite_urbaine.attribution.poids_zone_franche_urbaine plafond_effort_fiscal = parameters(period).dotation_solidarite_urbaine.attribution.plafond_effort_fiscal augmentation_max = parameters(period).dotation_solidarite_urbaine.attribution.augmentation_max seuil_bas = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_bas_nombre_habitants seuil_haut = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_haut_nombre_habitants pourcentage_augmentation_dsu = dsu_montant_total / dsu_an_precedent - 1 eligible_groupe_haut = dsu_eligible * (seuil_haut <= population_dgf) eligible_groupe_bas = dsu_eligible * (seuil_bas <= population_dgf) * (seuil_haut > population_dgf) toujours_eligible_groupe_bas = eligible_groupe_bas * (montants_an_precedent > 0) toujours_eligible_groupe_haut = eligible_groupe_haut * (montants_an_precedent > 0) nouvellement_eligible_groupe_bas = eligible_groupe_bas * (montants_an_precedent == 0) nouvellement_eligible_groupe_haut = eligible_groupe_haut * (montants_an_precedent == 0) toujours_eligible = toujours_eligible_groupe_bas | toujours_eligible_groupe_haut # Détermination des scores facteur_classement_seuil_bas = np.where(rang_indice_synthetique_dsu_seuil_bas <= nombre_elig_seuil_bas, (facteur_classement_min - facteur_classement_max) * safe_divide((rang_indice_synthetique_dsu_seuil_bas - 1), (nombre_elig_seuil_bas - 1), 0) + facteur_classement_max, 0) facteur_classement_seuil_haut = np.where(rang_indice_synthetique_dsu_seuil_haut <= nombre_elig_seuil_haut, (facteur_classement_min - facteur_classement_max) * safe_divide((rang_indice_synthetique_dsu_seuil_haut - 1), (nombre_elig_seuil_haut - 1), 0) + facteur_classement_max, 0) facteur_classement = facteur_classement_seuil_bas + facteur_classement_seuil_haut facteur_effort_fiscal = min_(effort_fiscal, plafond_effort_fiscal) facteur_qpv = (1 + np.where(population_insee > 0, poids_quartiers_prioritaires_ville * population_qpv / population_insee, 0)) facteur_zfu = (1 + np.where(population_insee > 0, poids_zone_franche_urbaine * population_zfu / population_insee, 0)) score_attribution = indice_synthetique_dsu * population_dgf * facteur_classement * facteur_effort_fiscal * facteur_qpv * facteur_zfu score_anciens_eligibles_groupe_haut = (score_attribution * toujours_eligible_groupe_haut) score_nouveaux_eligibles_groupe_haut = (score_attribution * nouvellement_eligible_groupe_haut) score_anciens_eligibles_groupe_bas = (score_attribution * toujours_eligible_groupe_bas) score_nouveaux_eligibles_groupe_bas = (score_attribution * nouvellement_eligible_groupe_bas) # clef de répartition groupe haut/groupe bas total_pop_eligible_augmentation_groupe_bas = (toujours_eligible_groupe_bas * population_dgf).sum() total_pop_eligible_augmentation_groupe_haut = (toujours_eligible_groupe_haut * population_dgf).sum() total_pop_eligible_augmentation = total_pop_eligible_augmentation_groupe_haut + total_pop_eligible_augmentation_groupe_bas # s'il n'y a pas de population, on répartit selon la population totale des groupes (non spécifié par la loi) if not total_pop_eligible_augmentation: total_pop_eligible_augmentation_groupe_bas = (eligible_groupe_bas * population_dgf).sum() total_pop_eligible_augmentation_groupe_haut = (eligible_groupe_haut * population_dgf).sum() total_pop_eligible_augmentation = total_pop_eligible_augmentation_groupe_haut + total_pop_eligible_augmentation_groupe_bas part_augmentation_groupe_bas = total_pop_eligible_augmentation_groupe_bas / total_pop_eligible_augmentation part_augmentation_groupe_haut = 1 - part_augmentation_groupe_bas # clef de répartition : on attribue une valeur des points d'augmentation égale au pourcentage # d'augmentation de la DSU rapport_valeur_point = pourcentage_augmentation_dsu # Le rapport valeur point dépend # probablement du groupe, mais on ignore les détails de son calcul total_points_groupe_bas = (score_anciens_eligibles_groupe_bas * rapport_valeur_point + score_nouveaux_eligibles_groupe_bas).sum() total_points_groupe_haut = (score_anciens_eligibles_groupe_haut * rapport_valeur_point + score_nouveaux_eligibles_groupe_haut).sum() # Détermination de la valeur du point montant_garanti_eligible = (toujours_eligible * montants_an_precedent).sum() valeur_point_groupe_bas = (total_a_distribuer - montant_garanti_eligible) * part_augmentation_groupe_bas / total_points_groupe_bas if total_points_groupe_bas else 0 valeur_point_groupe_haut = (total_a_distribuer - montant_garanti_eligible) * part_augmentation_groupe_haut / total_points_groupe_haut if total_points_groupe_haut else 0 montant_toujours_eligible_groupe_bas = (min_(valeur_point_groupe_bas * rapport_valeur_point * score_attribution, augmentation_max) + montants_an_precedent) * toujours_eligible_groupe_bas montant_toujours_eligible_groupe_haut = (min_(valeur_point_groupe_haut * rapport_valeur_point * score_attribution, augmentation_max) + montants_an_precedent) * toujours_eligible_groupe_haut montant_nouvellement_eligible_groupe_bas = valeur_point_groupe_bas * score_attribution * nouvellement_eligible_groupe_bas montant_nouvellement_eligible_groupe_haut = valeur_point_groupe_haut * score_attribution * nouvellement_eligible_groupe_haut return montant_toujours_eligible_groupe_bas + montant_toujours_eligible_groupe_haut + montant_nouvellement_eligible_groupe_bas + montant_nouvellement_eligible_groupe_haut
def formula(commune, period, parameters): population_dgf = commune("population_dgf", period) outre_mer = commune('outre_mer', period) potentiel_financier = commune('potentiel_financier', period) potentiel_financier_par_habitant = commune('potentiel_financier_par_habitant', period) nombre_logements = commune('nombre_logements', period) nombre_logements_sociaux = commune('nombre_logements_sociaux', period) nombre_aides_au_logement = commune('nombre_beneficiaires_aides_au_logement', period) revenu = commune('revenu_total', period) population_insee = commune('population_insee', period) revenu_par_habitant = commune('revenu_par_habitant', period) seuil_bas = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_bas_nombre_habitants seuil_haut = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_haut_nombre_habitants ratio_max_pot_fin = parameters(period).dotation_solidarite_urbaine.eligibilite.seuil_rapport_potentiel_financier poids_pot_fin = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_potentiel_financier poids_logements_sociaux = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_logements_sociaux poids_aides_au_logement = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_aides_au_logement poids_revenu = parameters(period).dotation_solidarite_urbaine.eligibilite.indice_synthetique.poids_revenu groupe_bas = (~outre_mer) * (seuil_bas <= population_dgf) * (seuil_haut > population_dgf) groupe_haut = (~outre_mer) * (seuil_haut <= population_dgf) pot_fin_bas = (np.sum(groupe_bas * potentiel_financier) / np.sum(groupe_bas * population_dgf)) if np.sum(groupe_bas * population_dgf) > 0 else 0 pot_fin_haut = (np.sum(groupe_haut * potentiel_financier) / np.sum(groupe_haut * population_dgf)) if np.sum(groupe_haut * population_dgf) > 0 else 0 # Retrait des communes au potentiel financier trop élevé, les communes restantes ont droit à un indice synthétique groupe_bas_score_positif = groupe_bas * (potentiel_financier_par_habitant < ratio_max_pot_fin * pot_fin_bas) groupe_haut_score_positif = groupe_haut * (potentiel_financier_par_habitant < ratio_max_pot_fin * pot_fin_haut) # Calcul des ratios moyens nécessaires au calcul de l'indice synthétique part_logements_sociaux_bas = (np.sum(groupe_bas * nombre_logements_sociaux) / np.sum(groupe_bas * nombre_logements)) if np.sum(groupe_bas * nombre_logements) > 0 else 0 part_logements_sociaux_haut = (np.sum(groupe_haut * nombre_logements_sociaux) / np.sum(groupe_haut * nombre_logements)) if np.sum(groupe_haut * nombre_logements) > 0 else 0 part_aides_logement_bas = (np.sum(groupe_bas * nombre_aides_au_logement) / np.sum(groupe_bas * nombre_logements)) if np.sum(groupe_bas * nombre_logements) > 0 else 0 part_aides_logement_haut = (np.sum(groupe_haut * nombre_aides_au_logement) / np.sum(groupe_haut * nombre_logements)) if np.sum(groupe_haut * nombre_logements) > 0 else 0 revenu_moyen_bas = (np.sum(groupe_bas * revenu) / np.sum(groupe_bas * population_insee)) if np.sum(groupe_bas * population_insee) > 0 else 0 revenu_moyen_haut = (np.sum(groupe_haut * revenu) / np.sum(groupe_haut * population_insee)) if np.sum(groupe_haut * population_insee) > 0 else 0 part_logements_sociaux_commune = safe_divide(nombre_logements_sociaux, nombre_logements) part_aides_logement_commune = safe_divide(nombre_aides_au_logement, nombre_logements) indice_synthetique_bas = groupe_bas_score_positif * ( poids_pot_fin * safe_divide(pot_fin_bas, potentiel_financier_par_habitant) + poids_logements_sociaux * safe_divide(part_logements_sociaux_commune, part_logements_sociaux_bas) + poids_aides_au_logement * safe_divide(part_aides_logement_commune, part_aides_logement_bas) + poids_revenu * safe_divide(revenu_moyen_bas, revenu_par_habitant) ) indice_synthetique_haut = groupe_haut_score_positif * ( poids_pot_fin * safe_divide(pot_fin_haut, potentiel_financier_par_habitant) + poids_logements_sociaux * safe_divide(part_logements_sociaux_commune, part_logements_sociaux_haut) + poids_aides_au_logement * safe_divide(part_aides_logement_commune, part_aides_logement_haut) + poids_revenu * safe_divide(revenu_moyen_haut, revenu_par_habitant) ) return indice_synthetique_bas + indice_synthetique_haut
def test_safe_divide(): a = np.array([1, 1, 0, 0, -1]) b = np.array([1, 0, 2, 0, -1]) assert all(safe_divide(a, b) == [1, 0, 0, 0, 1]) assert all(safe_divide(a, b, 12) == [1, 12, 0, 12, 1])