mirror of
https://github.com/CatalaLang/catala.git
synced 2024-09-20 00:41:05 +03:00
Initial writeup of Python calling to housing benefits
This commit is contained in:
parent
e53f6b6087
commit
431a0b99c1
@ -50,136 +50,102 @@ function run_computation_AF(log) {
|
||||
|
||||
function run_computation_AL(log) {
|
||||
var result = Law.computeAidesAuLogement({
|
||||
dateCouranteIn: "2022-01-01",
|
||||
menageIn: {
|
||||
prestationsRecues: [
|
||||
{ kind: "AllocationSoutienEnfantHandicape", payload: null },
|
||||
{ kind: "ComplementFamilial", payload: null },
|
||||
{ kind: "AllocationsFamiliales", payload: null },
|
||||
"menageIn": {
|
||||
"prestationsRecues": [],
|
||||
"logement": {
|
||||
"residencePrincipale": true,
|
||||
"estEhpadOuMaisonAutonomieL31312Asf": false,
|
||||
"modeOccupation": {
|
||||
"kind": "Locataire",
|
||||
"payload": {
|
||||
"bailleur": {
|
||||
"kind": "BailleurPrive"
|
||||
},
|
||||
"beneficiaireAideAdulteOuEnfantHandicapes": false,
|
||||
"logementEstChambre": false,
|
||||
"colocation": false,
|
||||
"ageesOuHandicapAdultesHebergeesOnereuxParticuliers": false,
|
||||
"reductionLoyerSolidarite": 0,
|
||||
"logementMeubleD8422": false,
|
||||
"changementLogementD8424": {
|
||||
"kind": "PasDeChangement",
|
||||
"payload": null
|
||||
},
|
||||
"loyerPrincipal": 450
|
||||
}
|
||||
},
|
||||
"proprietaire": {
|
||||
"kind": "Autre",
|
||||
"payload": null
|
||||
},
|
||||
"loueOuSousLoueADesTiers": {
|
||||
"kind": "Non"
|
||||
},
|
||||
"usufruit": {
|
||||
"kind": "Autre",
|
||||
"payload": null
|
||||
},
|
||||
"logementDecentL89462": true,
|
||||
"zone": {
|
||||
"kind": "Zone2"
|
||||
},
|
||||
"surfaceMCarres": 65
|
||||
},
|
||||
"personnesACharge": [
|
||||
{
|
||||
"kind": "EnfantACharge",
|
||||
"payload": {
|
||||
"beneficieTitrePersonnelAidePersonnelleLogement": false,
|
||||
"aDejaOuvertDroitAuxAllocationsFamiliales": true,
|
||||
"remunerationMensuelle": 0,
|
||||
"obligationScolaire": {
|
||||
"kind": "Pendant"
|
||||
},
|
||||
"situationGardeAlternee": {
|
||||
"kind": "PasDeGardeAlternee"
|
||||
},
|
||||
"dateDeNaissance": "2015-01-01",
|
||||
"identifiant": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "EnfantACharge",
|
||||
"payload": {
|
||||
"beneficieTitrePersonnelAidePersonnelleLogement": false,
|
||||
"aDejaOuvertDroitAuxAllocationsFamiliales": true,
|
||||
"remunerationMensuelle": 0,
|
||||
"obligationScolaire": {
|
||||
"kind": "Pendant"
|
||||
},
|
||||
"situationGardeAlternee": {
|
||||
"kind": "PasDeGardeAlternee"
|
||||
},
|
||||
"dateDeNaissance": "2016-01-01",
|
||||
"identifiant": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
situationFamiliale: {
|
||||
kind: "Maries",
|
||||
payload: "2010-11-26",
|
||||
"nombreAutresOccupantsLogement": 0,
|
||||
"situationFamiliale": {
|
||||
"kind": "Concubins",
|
||||
"payload": null
|
||||
},
|
||||
personnesACharge: [
|
||||
{
|
||||
kind: "EnfantACharge",
|
||||
payload: {
|
||||
beneficieTitrePersonnelAidePersonnelleLogement: false,
|
||||
priseEnCharge: { kind: "EffectiveEtPermanente", payload: null },
|
||||
age: 19,
|
||||
identifiant: 0,
|
||||
aDejaOuvertDroitAuxAllocationsFamiliales: true,
|
||||
dateDeNaissance: "2003-01-01",
|
||||
remunerationMensuelle: 0,
|
||||
obligationScolaire: { kind: "Apres", payload: null },
|
||||
situationGardeAlternee: {
|
||||
kind: "GardeAlterneeCoefficientPriseEnCharge",
|
||||
payload: 0.5,
|
||||
"conditionRattacheFoyerFiscalParentIfi": false,
|
||||
"nombreEnfantsANaitreApresTroisiemeMoisGrossesse": 0,
|
||||
},
|
||||
"demandeurIn": {
|
||||
"nationalite": {
|
||||
"kind": "Francaise"
|
||||
},
|
||||
"patrimoine": {
|
||||
"produisantRevenuPeriodeR82233R8224": 0,
|
||||
"neProduisantPasRevenuPeriodeR82233R8224": 0
|
||||
},
|
||||
{
|
||||
kind: "EnfantACharge",
|
||||
payload: {
|
||||
beneficieTitrePersonnelAidePersonnelleLogement: false,
|
||||
priseEnCharge: { kind: "EffectiveEtPermanente", payload: null },
|
||||
age: 11,
|
||||
identifiant: 1,
|
||||
aDejaOuvertDroitAuxAllocationsFamiliales: true,
|
||||
dateDeNaissance: "2011-01-01",
|
||||
remunerationMensuelle: 0,
|
||||
obligationScolaire: { kind: "Pendant", payload: null },
|
||||
situationGardeAlternee: {
|
||||
kind: "PasDeGardeAlternee",
|
||||
payload: null,
|
||||
"personneHebergeeCentreSoinLL162223SecuriteSociale": false,
|
||||
"dateNaissance": "1992-01-01"
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "EnfantACharge",
|
||||
payload: {
|
||||
beneficieTitrePersonnelAidePersonnelleLogement: false,
|
||||
priseEnCharge: { kind: "EffectiveEtPermanente", payload: null },
|
||||
age: 8,
|
||||
identifiant: 2,
|
||||
aDejaOuvertDroitAuxAllocationsFamiliales: true,
|
||||
dateDeNaissance: "2014-01-01",
|
||||
remunerationMensuelle: 0,
|
||||
obligationScolaire: { kind: "Pendant", payload: null },
|
||||
situationGardeAlternee: {
|
||||
kind: "PasDeGardeAlternee",
|
||||
payload: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
logement: {
|
||||
zone: { kind: "Zone1", payload: null },
|
||||
residencePrincipale: true,
|
||||
estEhpadOuMaisonAutonomieL31312Asf: false,
|
||||
modeOccupation: {
|
||||
kind: "Locataire",
|
||||
payload: {
|
||||
bailleur: {
|
||||
typeBailleur: { kind: "BailleurPrive", payload: null },
|
||||
respecteConventionTitreV: true,
|
||||
respecteConventionTitreII: true,
|
||||
construitAmelioreConditionsL83114: false,
|
||||
acquisitionAidesEtatPretTitreIIOuLivreIII: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
proprietaire: { kind: "Autre", payload: null },
|
||||
loueOuSousLoueADesTiers: { kind: "Non", payload: null },
|
||||
usufruit: { kind: "Autre", payload: null },
|
||||
logementDecentL89462: true,
|
||||
loyersL8233: 700,
|
||||
surfaceMCarres: 80,
|
||||
estAncienL8312: false,
|
||||
situeCommuneDesequilibreL8312: false,
|
||||
},
|
||||
nombreAutresOccupantsLogement: 1,
|
||||
conditionRattacheFoyerFiscalParentIfi: false,
|
||||
nombreEnfantsANaitreApresTroisiemeMoisGrossesse: 0,
|
||||
enfantANaitreApresQuatriemeMoisGrossesse: false,
|
||||
dateNaissanceTroisiemeEnfantOuDernierSiPlus: {
|
||||
kind: "PlusDeTroisEnfants",
|
||||
payload: {
|
||||
kind: "DateDeNaissance",
|
||||
payload: "2014-09-15",
|
||||
},
|
||||
},
|
||||
},
|
||||
demandeurIn: {
|
||||
personneHebergeeCentreSoinLL162223SecuriteSociale: false,
|
||||
satisfaitConditionsL5122CodeSecuriteSociale: true,
|
||||
ageDemandeur: 52,
|
||||
dateNaissance: "1970-05-02",
|
||||
contratDeTravail: { kind: "CDI", payload: null },
|
||||
nationalite: { kind: "Francaise", payload: null },
|
||||
patrimoine: {
|
||||
produisantRevenuPeriodeR82233R8224: 0,
|
||||
neProduisantPasRevenuPeriodeR82233R8224: 0,
|
||||
},
|
||||
},
|
||||
informationsCalculIn: {
|
||||
kind: "InfosLocatif",
|
||||
payload: {
|
||||
loyerPrincipal: 1700,
|
||||
beneficiaireAideAdulteOuEnfantHandicapes: false,
|
||||
logementEstChambre: false,
|
||||
colocation: false,
|
||||
ageesOuHandicapAdultesHebergeesOnereuxParticuliers: false,
|
||||
reductionLoyerSolidarite: 0,
|
||||
logementMeubleD8422: false,
|
||||
changementLogementD8424: {
|
||||
kind: "PasDeChangement",
|
||||
payload: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
ressourcesMenagePrisesEnCompteIn: 20000,
|
||||
"dateCouranteIn": "2022-05-01",
|
||||
"ressourcesMenagePrisesEnCompteIn": 11500
|
||||
});
|
||||
if (log) {
|
||||
console.log(
|
||||
|
@ -1,8 +1,10 @@
|
||||
#!python3
|
||||
|
||||
from datetime import date
|
||||
from src.allocations_familiales import PriseEnCharge_Code, Collectivite_Code
|
||||
from src.api import allocations_familiales, Enfant
|
||||
from tkinter import N
|
||||
from src.aides_logement import ModeOccupation_Code, Nationalite_Code, PrestationRecue_Code, SituationFamiliale_Code, SituationGardeAlternee_Code, SituationObligationScolaire_Code, TypeBailleur_Code, ZoneDHabitation_Code
|
||||
from src.allocations_familiales import PriseEnCharge_Code, Collectivite_Code, SituationObligationScolaire
|
||||
from src.api import EnfantAPL, InfosLocation, aides_logement, allocations_familiales, Enfant
|
||||
from catala.runtime import LogEvent, LogEventCode, reset_log, retrieve_log
|
||||
import timeit
|
||||
import argparse
|
||||
@ -33,6 +35,67 @@ def call_allocations_familiales() -> float:
|
||||
)
|
||||
|
||||
|
||||
def call_aides_logement() -> float:
|
||||
return aides_logement(
|
||||
date_courante=date(2022, 1, 1),
|
||||
ressources_menage_prises_en_compte=11_500.0,
|
||||
date_naissance_demandeur=date(1992, 1, 1),
|
||||
nationalite_demandeur=Nationalite_Code.Francaise,
|
||||
patrimoine_produisant_revenu=0.0,
|
||||
patrimoine_ne_produisant_pas_revenu=0.0,
|
||||
personne_hebergee_centre_soins=False,
|
||||
personne_rattache_foyer_fiscal_parent_ifi=False,
|
||||
nombre_autres_occupants_logement_hors_menage=0,
|
||||
enfant_a_naitre_apres_quatrieme_mois_grossesse=False,
|
||||
situation_familiale=SituationFamiliale_Code.Concubins,
|
||||
date_mariage=None,
|
||||
prestations_recues=[],
|
||||
residence_principale=True,
|
||||
logement_est_maison_de_retraite=False,
|
||||
surface_logement_m_carres=65,
|
||||
zone=ZoneDHabitation_Code.Zone1,
|
||||
parts_logement_propriete_famille=None,
|
||||
parts_logement_usufruits_famille=None,
|
||||
date_naissance_et_conformite_sous_locataire_tiers=None,
|
||||
mode_occupation=ModeOccupation_Code.Locataire,
|
||||
personnes_a_charge=[
|
||||
EnfantAPL(
|
||||
identifiant=1,
|
||||
beneficie_titre_personnel_aide_personnelle_logement=False,
|
||||
a_deja_ouvert_droit_aux_allocations_familiales=True,
|
||||
date_de_naissance=date(2015, 1, 1),
|
||||
remuneration_mensuelle=0.0,
|
||||
obligation_scolaire=SituationObligationScolaire_Code.Pendant,
|
||||
situation_garde_alternee=SituationGardeAlternee_Code.PasDeGardeAlternee,
|
||||
coefficient_garde_alternee=None
|
||||
),
|
||||
EnfantAPL(
|
||||
identifiant=2,
|
||||
beneficie_titre_personnel_aide_personnelle_logement=False,
|
||||
a_deja_ouvert_droit_aux_allocations_familiales=True,
|
||||
date_de_naissance=date(2016, 1, 1),
|
||||
remuneration_mensuelle=0.0,
|
||||
obligation_scolaire=SituationObligationScolaire_Code.Pendant,
|
||||
situation_garde_alternee=SituationGardeAlternee_Code.PasDeGardeAlternee,
|
||||
coefficient_garde_alternee=None)
|
||||
],
|
||||
logement_est_decent=True,
|
||||
infos_specifiques=InfosLocation(
|
||||
loyer_principal=450,
|
||||
beneficiaire_aide_adulte_ou_enfant_handicapes=False,
|
||||
colocation=False,
|
||||
logement_est_chambre=False,
|
||||
agees_ou_handicap_adultes_hebergees_onereux_particuliers=False,
|
||||
logement_meuble_d842_2=False,
|
||||
ancien_loyer_et_apl_relogement=None,
|
||||
type_bailleur=TypeBailleur_Code.BailleurPrive,
|
||||
bailleur_conventionne=None,
|
||||
reduction_loyer_solidarite=None
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
|
||||
def benchmark_iteration():
|
||||
money_given = call_allocations_familiales()
|
||||
assert (money_given == 99.46)
|
||||
|
@ -1,5 +1,9 @@
|
||||
from abc import ABC
|
||||
from catala.runtime import *
|
||||
from .allocations_familiales import Collectivite, Collectivite_Code, InterfaceAllocationsFamilialesIn, PriseEnCharge, interface_allocations_familiales, PriseEnCharge_Code, EnfantEntree, InterfaceAllocationsFamilialesIn
|
||||
from .aides_logement import AutrePersonneACharge, CategorieEquivalenceLoyerAllocationLogementFoyer, CategorieEquivalenceLoyerAllocationLogementFoyer_Code, ChangementLogementD8424, ChangementLogementD8424_Code, ConventionANHA, ConventionBailleurSocial, EnfantACharge, InfosChangementLogementD8424, Location, Logement, LogementFoyer, LoueOuSousLoueADesTiers, LoueOuSousLoueADesTiers_Code, Menage, ModeOccupation, ModeOccupation_Code, Nationalite, Nationalite_Code, NeufOuAncien, NeufOuAncien_Code, ParentOuAutre, ParentOuAutre_Code, Parente, Parente_Code, Patrimoine, PersonneACharge, PersonneSousLocation, PrestationRecue, PrestationRecue_Code, Pret, Proprietaire, SituationFamiliale, SituationFamiliale_Code, SituationGardeAlternee_Code, SituationObligationScolaire_Code, TitulairePret, TitulairePret_Code, TypeBailleur, TypeBailleur_Code, TypeLogementFoyer, TypeLogementFoyer_Code, TypePret, TypePret_Code, TypeTravauxLogementD83215, TypeTravauxLogementD83215_Code, TypeTravauxLogementR8425, TypeTravauxLogementR8425_Code, ZoneDHabitation, ZoneDHabitation_Code, calculette_aides_au_logement_garde_alternee, CalculetteAidesAuLogementGardeAlterneeIn, ressources_aides_personnelle_logement, Demandeur, PersonneACharge_Code, SituationObligationScolaire, SituationGardeAlternee
|
||||
|
||||
# Allocations familiales
|
||||
|
||||
|
||||
class Enfant:
|
||||
@ -51,3 +55,308 @@ def allocations_familiales(
|
||||
i_avait_enfant_a_charge_avant_1er_janvier_2012_in=avait_enfant_a_charge_avant_1er_janvier_2012
|
||||
))
|
||||
return money_to_float(out.i_montant_verse_out)
|
||||
|
||||
# Aides au logement
|
||||
|
||||
|
||||
class PersonneAChargeAPL(ABC):
|
||||
pass
|
||||
|
||||
|
||||
class EnfantAPL(PersonneAChargeAPL):
|
||||
def __init__(self, identifiant: int, beneficie_titre_personnel_aide_personnelle_logement: bool,
|
||||
a_deja_ouvert_droit_aux_allocations_familiales: bool,
|
||||
date_de_naissance: datetime.date,
|
||||
remuneration_mensuelle: float,
|
||||
obligation_scolaire: SituationObligationScolaire_Code,
|
||||
situation_garde_alternee: SituationGardeAlternee_Code,
|
||||
coefficient_garde_alternee: Optional[float]):
|
||||
self.identifiant = identifiant
|
||||
self.beneficie_titre_personnel_aide_personnelle_logement = beneficie_titre_personnel_aide_personnelle_logement
|
||||
self.a_deja_ouvert_droit_aux_allocations_familiales = a_deja_ouvert_droit_aux_allocations_familiales
|
||||
self.date_de_naissance = date_de_naissance,
|
||||
self.remuneration_mensuelle = remuneration_mensuelle
|
||||
self.obligation_scolaire = obligation_scolaire
|
||||
self.situation_garde_alternee = situation_garde_alternee
|
||||
self.coefficient_garde_alternee = coefficient_garde_alternee
|
||||
|
||||
|
||||
class ParentAPL(PersonneAChargeAPL):
|
||||
def __init__(self, date_naissance: datetime.date,
|
||||
ressources: float, ascendant_descendant_collateral_deuxieme_troisieme_degre: bool,
|
||||
parente: Parente_Code,
|
||||
incapacite_80_pourcent_ou_restriction_emploi: bool,
|
||||
beneficiaire_l161_19_l351_8_l643_3_secu: bool,
|
||||
titulaire_allocation_personne_agee: bool):
|
||||
self.date_naissance = date_naissance
|
||||
self.ressources = ressources
|
||||
self.ascendant_descendant_collateral_deuxieme_troisieme_degre = ascendant_descendant_collateral_deuxieme_troisieme_degre
|
||||
self.parente = parente
|
||||
self.incapacite_80_pourcent_ou_restriction_emploi = incapacite_80_pourcent_ou_restriction_emploi
|
||||
self.beneficiaire_l161_19_l351_8_l643_3_secu = beneficiaire_l161_19_l351_8_l643_3_secu
|
||||
self.titulaire_allocation_personne_agee = titulaire_allocation_personne_agee
|
||||
|
||||
|
||||
class InfosSpecifiques(ABC):
|
||||
pass
|
||||
|
||||
|
||||
class InfosLocation(InfosSpecifiques):
|
||||
def __init__(self,
|
||||
loyer_principal: float,
|
||||
beneficiaire_aide_adulte_ou_enfant_handicapes: bool,
|
||||
logement_est_chambre: bool,
|
||||
colocation: bool,
|
||||
agees_ou_handicap_adultes_hebergees_onereux_particuliers: bool,
|
||||
logement_meuble_d842_2: bool,
|
||||
ancien_loyer_et_apl_relogement: Optional[Tuple[float, float]],
|
||||
type_bailleur: TypeBailleur_Code,
|
||||
bailleur_conventionne: Optional[bool],
|
||||
reduction_loyer_solidarite: Optional[float]):
|
||||
self.loyer_principal = loyer_principal
|
||||
self.beneficiaire_aide_adulte_ou_enfant_handicapes = beneficiaire_aide_adulte_ou_enfant_handicapes
|
||||
self.logement_est_chambre = logement_est_chambre
|
||||
self.colocation = colocation
|
||||
self.agees_ou_handicap_adultes_hebergees_onereux_particuliers = agees_ou_handicap_adultes_hebergees_onereux_particuliers
|
||||
self.logement_meuble_d842_2 = logement_meuble_d842_2
|
||||
self.ancien_loyer_et_apl_relogement = ancien_loyer_et_apl_relogement
|
||||
self.type_bailleur = type_bailleur
|
||||
self.bailleur_conventionne = bailleur_conventionne
|
||||
self.reduction_loyer_solidarite = reduction_loyer_solidarite
|
||||
|
||||
|
||||
class InfosLogementFoyer(InfosSpecifiques):
|
||||
def __init__(self,
|
||||
type: TypeLogementFoyer_Code,
|
||||
remplit_conditions_r832_21: bool,
|
||||
conventionne_livre_III_titre_V_chap_III: bool,
|
||||
date_conventionnement: datetime.date,
|
||||
construit_application_loi_1957_12_III: bool,
|
||||
redevance: float,
|
||||
categorie_equivalence_loyer_d842_16: CategorieEquivalenceLoyerAllocationLogementFoyer_Code):
|
||||
self.type = type
|
||||
self.remplit_conditions_r832_21 = remplit_conditions_r832_21
|
||||
self.conventionne_livre_III_titre_V_chap_III = conventionne_livre_III_titre_V_chap_III
|
||||
self.date_conventionnement = date_conventionnement
|
||||
self.construit_application_loi_1957_12_III = construit_application_loi_1957_12_III
|
||||
self.redevance = redevance
|
||||
self.categorie_equivalence_loyer_d842_16 = categorie_equivalence_loyer_d842_16
|
||||
|
||||
|
||||
class InfosAccessionPropriete(InfosSpecifiques):
|
||||
def __init__(self,
|
||||
logement_situe_commune_desequilibre_l831_2: bool,
|
||||
mensualite_principale: float,
|
||||
charges_mensuelles_pret: float,
|
||||
date_entree_logement: datetime.date,
|
||||
local_habite_premiere_fois_beneficiaire: bool,
|
||||
copropriete: bool,
|
||||
situation_r822_11_13_17: bool,
|
||||
type_travaux_logement_d832_15: TypeTravauxLogementD83215_Code,
|
||||
type_travaux_logement_r842_5: TypeTravauxLogementR8425_Code,
|
||||
anciennete_logement: NeufOuAncien_Code,
|
||||
ameliore_par_occupant: Optional[bool],
|
||||
type_pret: TypePret_Code,
|
||||
date_signature_pret: datetime.date,
|
||||
titulaire_pret: TitulairePret_Code):
|
||||
self.logement_situe_commune_desequilibre_l831_2 = logement_situe_commune_desequilibre_l831_2
|
||||
self.mensualite_principale = mensualite_principale
|
||||
self.charges_mensuelles_pret = charges_mensuelles_pret
|
||||
self.date_entree_logement = date_entree_logement
|
||||
self.local_habite_premiere_fois_beneficiaire = local_habite_premiere_fois_beneficiaire
|
||||
self.copropriete = copropriete
|
||||
self.situation_r822_11_13_17 = situation_r822_11_13_17
|
||||
self.type_travaux_logement_d832_15 = type_travaux_logement_d832_15
|
||||
self.type_travaux_logement_r842_5 = type_travaux_logement_r842_5
|
||||
self.anciennete_logement = anciennete_logement
|
||||
self.ameliore_par_occupant = ameliore_par_occupant
|
||||
self.type_pret = type_pret
|
||||
self.date_signature_pret = date_signature_pret
|
||||
self.titulaire_pret = titulaire_pret
|
||||
|
||||
|
||||
def aides_logement(
|
||||
date_courante: datetime.date,
|
||||
ressources_menage_prises_en_compte: float,
|
||||
date_naissance_demandeur: datetime.date,
|
||||
nationalite_demandeur: Nationalite_Code,
|
||||
patrimoine_produisant_revenu: float,
|
||||
patrimoine_ne_produisant_pas_revenu: float,
|
||||
personne_hebergee_centre_soins: bool,
|
||||
personne_rattache_foyer_fiscal_parent_ifi: bool,
|
||||
nombre_autres_occupants_logement_hors_menage: int,
|
||||
enfant_a_naitre_apres_quatrieme_mois_grossesse: bool,
|
||||
situation_familiale: SituationFamiliale_Code,
|
||||
date_mariage: Optional[datetime.date],
|
||||
prestations_recues: List[PrestationRecue_Code],
|
||||
residence_principale: bool,
|
||||
logement_est_maison_de_retraite: bool,
|
||||
logement_est_decent: bool,
|
||||
surface_logement_m_carres: int,
|
||||
zone: ZoneDHabitation_Code,
|
||||
parts_logement_propriete_famille: Optional[float],
|
||||
parts_logement_usufruits_famille: Optional[float],
|
||||
date_naissance_et_conformite_sous_locataire_tiers: Optional[Tuple[datetime.date, bool]],
|
||||
mode_occupation: ModeOccupation_Code,
|
||||
infos_specifiques: InfosSpecifiques,
|
||||
personnes_a_charge: List[PersonneAChargeAPL],
|
||||
):
|
||||
out = calculette_aides_au_logement_garde_alternee(CalculetteAidesAuLogementGardeAlterneeIn(
|
||||
menage_in=Menage(
|
||||
prestations_recues=[PrestationRecue(
|
||||
code=presta, value=Unit()) for presta in prestations_recues],
|
||||
logement=Logement(
|
||||
residence_principale=residence_principale,
|
||||
est_ehpad_ou_maison_autonomie_l313_12_asf=logement_est_maison_de_retraite,
|
||||
mode_occupation=ModeOccupation(
|
||||
code=mode_occupation,
|
||||
value=(Location(
|
||||
loyer_principal=money_of_decimal(
|
||||
decimal_of_float(infos_specifiques.loyer_principal)),
|
||||
beneficiaire_aide_adulte_ou_enfant_handicapes=infos_specifiques.beneficiaire_aide_adulte_ou_enfant_handicapes,
|
||||
logement_est_chambre=infos_specifiques.logement_est_chambre,
|
||||
colocation=infos_specifiques.colocation,
|
||||
agees_ou_handicap_adultes_hebergees_onereux_particuliers=infos_specifiques.agees_ou_handicap_adultes_hebergees_onereux_particuliers,
|
||||
logement_meuble_d842_2=infos_specifiques.logement_meuble_d842_2,
|
||||
changement_logement_d842_4=ChangementLogementD8424(
|
||||
code=ChangementLogementD8424_Code.PasDeChangement if infos_specifiques.ancien_loyer_et_apl_relogement is None else
|
||||
ChangementLogementD8424_Code.Changement,
|
||||
value=Unit() if infos_specifiques.ancien_loyer_et_apl_relogement is None else
|
||||
InfosChangementLogementD8424(ancien_loyer_principal=money_of_decimal(decimal_of_float(infos_specifiques.ancien_loyer_et_apl_relogement[0])),
|
||||
ancienne_allocation_logement=money_of_decimal(decimal_of_float(infos_specifiques.ancien_loyer_et_apl_relogement[1])))
|
||||
),
|
||||
bailleur=TypeBailleur(
|
||||
code=infos_specifiques.type_bailleur,
|
||||
value=Unit() if infos_specifiques.type_bailleur == TypeBailleur_Code.BailleurPrive else (
|
||||
ConventionBailleurSocial(
|
||||
conventionne_livre_III_titre_V_chap_III=False if infos_specifiques.bailleur_conventionne is None else infos_specifiques.bailleur_conventionne,
|
||||
reduction_loyer_solidarite_percue=money_of_decimal(decimal_of_float(0.0 if infos_specifiques.reduction_loyer_solidarite is None else infos_specifiques.reduction_loyer_solidarite)))
|
||||
) if infos_specifiques.type_bailleur == TypeBailleur_Code.BailleurSocial else (
|
||||
ConventionANHA(
|
||||
conventionne_livre_III_titre_II_chap_I_sec_3=False if infos_specifiques.bailleur_conventionne is None else infos_specifiques.bailleur_conventionne)
|
||||
if infos_specifiques.type_bailleur == TypeBailleur_Code.BailleurPriveAvecConventionnementSocial else
|
||||
None # type: ignore
|
||||
))
|
||||
) if isinstance(infos_specifiques, InfosLocation) else
|
||||
(LogementFoyer(
|
||||
type=TypeLogementFoyer(
|
||||
code=infos_specifiques.type, value=Unit()),
|
||||
remplit_conditions_r832_21=infos_specifiques.remplit_conditions_r832_21,
|
||||
conventionne_livre_III_titre_V_chap_III=infos_specifiques.conventionne_livre_III_titre_V_chap_III,
|
||||
date_conventionnement=date_of_datetime(
|
||||
infos_specifiques.date_conventionnement),
|
||||
construit_application_loi_1957_12_III=infos_specifiques.construit_application_loi_1957_12_III,
|
||||
redevance=money_of_decimal(
|
||||
decimal_of_float(infos_specifiques.redevance)),
|
||||
categorie_equivalence_loyer_d842_16=CategorieEquivalenceLoyerAllocationLogementFoyer(
|
||||
code=infos_specifiques.categorie_equivalence_loyer_d842_16,
|
||||
value=Unit()
|
||||
)
|
||||
) if isinstance(infos_specifiques, InfosLogementFoyer) else
|
||||
(Proprietaire(
|
||||
logement_situe_commune_desequilibre_l831_2=infos_specifiques.logement_situe_commune_desequilibre_l831_2,
|
||||
mensualite_principale=money_of_decimal(
|
||||
decimal_of_float(infos_specifiques.mensualite_principale)),
|
||||
charges_mensuelles_pret=money_of_decimal(
|
||||
decimal_of_float(infos_specifiques.charges_mensuelles_pret)),
|
||||
date_entree_logement=date_of_datetime(
|
||||
infos_specifiques.date_entree_logement),
|
||||
local_habite_premiere_fois_beneficiaire=infos_specifiques.local_habite_premiere_fois_beneficiaire,
|
||||
copropriete=infos_specifiques.copropriete,
|
||||
situation_r822_11_13_17=infos_specifiques.situation_r822_11_13_17,
|
||||
type_travaux_logement_d832_15=TypeTravauxLogementD83215(
|
||||
code=infos_specifiques.type_travaux_logement_d832_15, value=Unit()),
|
||||
type_travaux_logement_r842_5=TypeTravauxLogementR8425(
|
||||
code=infos_specifiques.type_travaux_logement_r842_5,
|
||||
value=Unit()
|
||||
),
|
||||
anciennete_logement=NeufOuAncien(code=infos_specifiques.anciennete_logement,
|
||||
value=Unit() if infos_specifiques.ameliore_par_occupant is None else infos_specifiques.ameliore_par_occupant),
|
||||
pret=Pret(
|
||||
type_pret=TypePret(
|
||||
code=infos_specifiques.type_pret, value=Unit()),
|
||||
date_signature=date_of_datetime(
|
||||
infos_specifiques.date_signature_pret),
|
||||
titulaire_pret=TitulairePret(
|
||||
code=infos_specifiques.titulaire_pret, value=Unit())
|
||||
)
|
||||
) if isinstance(infos_specifiques, InfosAccessionPropriete)
|
||||
else None # type: ignore
|
||||
)))
|
||||
),
|
||||
proprietaire=ParentOuAutre(
|
||||
code=ParentOuAutre_Code.Autre if parts_logement_propriete_famille is None else ParentOuAutre_Code.DemandeurOuConjointOuParentOuViaPartsSocietes,
|
||||
value=Unit() if parts_logement_propriete_famille is None else parts_logement_propriete_famille),
|
||||
usufruit=ParentOuAutre(
|
||||
code=ParentOuAutre_Code.Autre if parts_logement_usufruits_famille is None else ParentOuAutre_Code.DemandeurOuConjointOuParentOuViaPartsSocietes,
|
||||
value=Unit() if parts_logement_usufruits_famille is None else parts_logement_usufruits_famille),
|
||||
loue_ou_sous_loue_a_des_tiers=LoueOuSousLoueADesTiers(
|
||||
code=LoueOuSousLoueADesTiers_Code.Non if date_naissance_et_conformite_sous_locataire_tiers is None else LoueOuSousLoueADesTiers_Code.Oui,
|
||||
value=Unit() if date_naissance_et_conformite_sous_locataire_tiers is None else PersonneSousLocation(
|
||||
date_naissance_personne_sous_location=date_of_datetime(date_naissance_et_conformite_sous_locataire_tiers[
|
||||
0]),
|
||||
conforme_article_l442_1=date_naissance_et_conformite_sous_locataire_tiers[
|
||||
1]
|
||||
)
|
||||
),
|
||||
logement_decent_l89_462=logement_est_decent,
|
||||
surface_m_carres=integer_of_int(surface_logement_m_carres),
|
||||
zone=ZoneDHabitation(code=zone, value=Unit())
|
||||
),
|
||||
personnes_a_charge=[
|
||||
(PersonneACharge(code=PersonneACharge_Code.EnfantACharge,
|
||||
value=EnfantACharge(
|
||||
identifiant=integer_of_int(
|
||||
personne_a_charge.identifiant),
|
||||
beneficie_titre_personnel_aide_personnelle_logement=personne_a_charge.beneficie_titre_personnel_aide_personnelle_logement,
|
||||
a_deja_ouvert_droit_aux_allocations_familiales=personne_a_charge.a_deja_ouvert_droit_aux_allocations_familiales,
|
||||
date_de_naissance=date_of_datetime(
|
||||
personne_a_charge.date_de_naissance[0]),
|
||||
remuneration_mensuelle=money_of_decimal(
|
||||
decimal_of_float(personne_a_charge.remuneration_mensuelle)),
|
||||
obligation_scolaire=SituationObligationScolaire(
|
||||
code=personne_a_charge.obligation_scolaire, value=Unit()),
|
||||
situation_garde_alternee=SituationGardeAlternee(code=personne_a_charge.situation_garde_alternee,
|
||||
value=Unit() if personne_a_charge.coefficient_garde_alternee is None else personne_a_charge.coefficient_garde_alternee)
|
||||
))
|
||||
if isinstance(personne_a_charge, EnfantAPL)
|
||||
else (PersonneACharge(
|
||||
code=PersonneACharge_Code.AutrePersonneACharge,
|
||||
value=AutrePersonneACharge(
|
||||
date_naissance=date_of_datetime(
|
||||
personne_a_charge.date_naissance),
|
||||
ressources=money_of_decimal(
|
||||
decimal_of_float(personne_a_charge.ressources)),
|
||||
ascendant_descendant_collateral_deuxieme_troisieme_degre=personne_a_charge.ascendant_descendant_collateral_deuxieme_troisieme_degre,
|
||||
incapacite_80_pourcent_ou_restriction_emploi=personne_a_charge.incapacite_80_pourcent_ou_restriction_emploi,
|
||||
beneficiaire_l161_19_l351_8_l643_3_secu=personne_a_charge.beneficiaire_l161_19_l351_8_l643_3_secu,
|
||||
titulaire_allocation_personne_agee=personne_a_charge.titulaire_allocation_personne_agee,
|
||||
parente=Parente(
|
||||
code=personne_a_charge.parente, value=Unit())
|
||||
)) if isinstance(personne_a_charge, ParentAPL)
|
||||
else None # type: ignore
|
||||
)) for personne_a_charge in personnes_a_charge],
|
||||
nombre_autres_occupants_logement=integer_of_int(
|
||||
nombre_autres_occupants_logement_hors_menage),
|
||||
situation_familiale=SituationFamiliale(
|
||||
code=situation_familiale,
|
||||
value=Unit() if date_mariage is None else date_of_datetime(date_mariage)
|
||||
),
|
||||
condition_rattache_foyer_fiscal_parent_ifi=personne_rattache_foyer_fiscal_parent_ifi,
|
||||
enfant_a_naitre_apres_quatrieme_mois_grossesse=enfant_a_naitre_apres_quatrieme_mois_grossesse
|
||||
),
|
||||
demandeur_in=Demandeur(
|
||||
date_naissance=date_of_datetime(date_naissance_demandeur),
|
||||
nationalite=Nationalite(code=nationalite_demandeur, value=Unit()),
|
||||
patrimoine=Patrimoine(
|
||||
produisant_revenu_periode_r822_3_3_r822_4=money_of_decimal(decimal_of_float(
|
||||
patrimoine_produisant_revenu)),
|
||||
ne_produisant_pas_revenu_periode_r822_3_3_r822_4=money_of_decimal(decimal_of_float(
|
||||
patrimoine_ne_produisant_pas_revenu))
|
||||
),
|
||||
personne_hebergee_centre_soin_l_L162_22_3_securite_sociale=personne_hebergee_centre_soins,
|
||||
),
|
||||
date_courante_in=date_of_datetime(date_courante),
|
||||
ressources_menage_prises_en_compte_in=money_of_decimal(
|
||||
decimal_of_float(ressources_menage_prises_en_compte)),
|
||||
))
|
||||
|
@ -1,681 +0,0 @@
|
||||
"""
|
||||
.. module:: catala_runtime
|
||||
:platform: Unix, Windows
|
||||
:synopsis: The Python bindings for the functions used in the generated Catala code
|
||||
:noindex:
|
||||
|
||||
.. moduleauthor:: Denis Merigoux <denis.merigoux@inria.fr>
|
||||
"""
|
||||
|
||||
# This file should be in sync with compiler/runtime.{ml, mli} !
|
||||
|
||||
from this import d
|
||||
from gmpy2 import log2, mpz, mpq, mpfr, t_divmod, f_div, sign # type: ignore
|
||||
import datetime
|
||||
import calendar
|
||||
import dateutil.relativedelta
|
||||
from typing import NewType, List, Callable, Tuple, Optional, TypeVar, Iterable, Union, Any
|
||||
from functools import reduce
|
||||
from enum import Enum
|
||||
import copy
|
||||
|
||||
Alpha = TypeVar('Alpha')
|
||||
Beta = TypeVar('Beta')
|
||||
|
||||
# ============
|
||||
# Type classes
|
||||
# ============
|
||||
|
||||
|
||||
class Integer:
|
||||
def __init__(self, value: Union[str, int]) -> None:
|
||||
self.value = mpz(value)
|
||||
|
||||
def __add__(self, other: 'Integer') -> 'Integer':
|
||||
return Integer(self.value + other.value)
|
||||
|
||||
def __sub__(self, other: 'Integer') -> 'Integer':
|
||||
return Integer(self.value - other.value)
|
||||
|
||||
def __mul__(self, other: 'Integer') -> 'Integer':
|
||||
return Integer(self.value * other.value)
|
||||
|
||||
def __truediv__(self, other: 'Integer') -> 'Integer':
|
||||
return Integer(self.value // other.value)
|
||||
|
||||
def __neg__(self: 'Integer') -> 'Integer':
|
||||
return Integer(- self.value)
|
||||
|
||||
def __lt__(self, other: 'Integer') -> bool:
|
||||
return self.value < other.value
|
||||
|
||||
def __le__(self, other: 'Integer') -> bool:
|
||||
return self.value <= other.value
|
||||
|
||||
def __gt__(self, other: 'Integer') -> bool:
|
||||
return self.value > other.value
|
||||
|
||||
def __ge__(self, other: 'Integer') -> bool:
|
||||
return self.value >= other.value
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if isinstance(other, Integer):
|
||||
return self.value != other.value
|
||||
else:
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, Integer):
|
||||
return self.value == other.value
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value.__str__()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Integer({self.value.__repr__()})"
|
||||
|
||||
|
||||
class Decimal:
|
||||
def __init__(self, value: Union[str, int, float]) -> None:
|
||||
self.value = mpq(value)
|
||||
|
||||
def __add__(self, other: 'Decimal') -> 'Decimal':
|
||||
return Decimal(self.value + other.value)
|
||||
|
||||
def __sub__(self, other: 'Decimal') -> 'Decimal':
|
||||
return Decimal(self.value - other.value)
|
||||
|
||||
def __mul__(self, other: 'Decimal') -> 'Decimal':
|
||||
return Decimal(self.value * other.value)
|
||||
|
||||
def __truediv__(self, other: 'Decimal') -> 'Decimal':
|
||||
return Decimal(self.value / other.value)
|
||||
|
||||
def __neg__(self: 'Decimal') -> 'Decimal':
|
||||
return Decimal(- self.value)
|
||||
|
||||
def __lt__(self, other: 'Decimal') -> bool:
|
||||
return self.value < other.value
|
||||
|
||||
def __le__(self, other: 'Decimal') -> bool:
|
||||
return self.value <= other.value
|
||||
|
||||
def __gt__(self, other: 'Decimal') -> bool:
|
||||
return self.value > other.value
|
||||
|
||||
def __ge__(self, other: 'Decimal') -> bool:
|
||||
return self.value >= other.value
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if isinstance(other, Decimal):
|
||||
return self.value != other.value
|
||||
else:
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, Decimal):
|
||||
return self.value == other.value
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "{}".format(mpfr(self.value))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Decimal({self.value.__repr__()})"
|
||||
|
||||
|
||||
class Money:
|
||||
def __init__(self, value: Integer) -> None:
|
||||
self.value = value
|
||||
|
||||
def __add__(self, other: 'Money') -> 'Money':
|
||||
return Money(self.value + other.value)
|
||||
|
||||
def __sub__(self, other: 'Money') -> 'Money':
|
||||
return Money(self.value - other.value)
|
||||
|
||||
def __mul__(self, other: Decimal) -> 'Money':
|
||||
cents = self.value.value
|
||||
coeff = other.value
|
||||
# TODO: change, does not work with negative values. Must divide the
|
||||
# absolute values and then multiply by the resulting sign.
|
||||
rat_result = self.value.value * other.value
|
||||
out = Money(Integer(rat_result))
|
||||
res, remainder = t_divmod(rat_result.numerator, rat_result.denominator)
|
||||
if 2 * remainder >= rat_result.denominator:
|
||||
return Money(Integer(res + 1))
|
||||
else:
|
||||
return Money(Integer(res))
|
||||
|
||||
def __truediv__(self, other: 'Money') -> Decimal:
|
||||
return Decimal(mpq(self.value.value / other.value.value))
|
||||
|
||||
def __neg__(self: 'Money') -> 'Money':
|
||||
return Money(- self.value)
|
||||
|
||||
def __lt__(self, other: 'Money') -> bool:
|
||||
return self.value < other.value
|
||||
|
||||
def __le__(self, other: 'Money') -> bool:
|
||||
return self.value <= other.value
|
||||
|
||||
def __gt__(self, other: 'Money') -> bool:
|
||||
return self.value > other.value
|
||||
|
||||
def __ge__(self, other: 'Money') -> bool:
|
||||
return self.value >= other.value
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if isinstance(other, Money):
|
||||
return self.value != other.value
|
||||
else:
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, Money):
|
||||
return self.value == other.value
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "${:.2}".format(self.value.value / 100)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Money({self.value.__repr__()})"
|
||||
|
||||
|
||||
class Date:
|
||||
def __init__(self, value: datetime.date) -> None:
|
||||
self.value = value
|
||||
|
||||
def __add__(self, other: 'Duration') -> 'Date':
|
||||
return Date(self.value + other.value)
|
||||
|
||||
def __sub__(self, other: 'Date') -> 'Duration':
|
||||
return Duration(dateutil.relativedelta.relativedelta(self.value, other.value))
|
||||
|
||||
def __lt__(self, other: 'Date') -> bool:
|
||||
return self.value < other.value
|
||||
|
||||
def __le__(self, other: 'Date') -> bool:
|
||||
return self.value <= other.value
|
||||
|
||||
def __gt__(self, other: 'Date') -> bool:
|
||||
return self.value > other.value
|
||||
|
||||
def __ge__(self, other: 'Date') -> bool:
|
||||
return self.value >= other.value
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if isinstance(other, Date):
|
||||
return self.value != other.value
|
||||
else:
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, Date):
|
||||
return self.value == other.value
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value.__str__()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Date({self.value.__repr__()})"
|
||||
|
||||
|
||||
class Duration:
|
||||
def __init__(self, value: dateutil.relativedelta.relativedelta) -> None:
|
||||
self.value = value
|
||||
|
||||
def __add__(self, other: 'Duration') -> 'Duration':
|
||||
return Duration(self.value + other.value)
|
||||
|
||||
def __sub__(self, other: 'Duration') -> 'Duration':
|
||||
return Duration(self.value - other.value)
|
||||
|
||||
def __neg__(self: 'Duration') -> 'Duration':
|
||||
return Duration(- self.value)
|
||||
|
||||
def __truediv__(self, other: 'Duration') -> Decimal:
|
||||
x = self.value.normalized()
|
||||
y = other.value.normalized()
|
||||
if (x.years != 0 or y.years != 0 or x.months != 0 or y.months != 0):
|
||||
raise Exception("Can only divide durations expressed in days")
|
||||
else:
|
||||
return Decimal(x.days / y.days)
|
||||
|
||||
def __mul__(self: 'Duration', rhs: Integer) -> 'Duration':
|
||||
return Duration(
|
||||
dateutil.relativedelta.relativedelta(years=self.value.years * rhs.value,
|
||||
months=self.value.months * rhs.value,
|
||||
days=self.value.days * rhs.value))
|
||||
|
||||
def __lt__(self, other: 'Duration') -> bool:
|
||||
x = self.value.normalized()
|
||||
y = other.value.normalized()
|
||||
if (x.years != 0 or y.years != 0 or x.months != 0 or y.months != 0):
|
||||
raise Exception("Can only compare durations expressed in days")
|
||||
else:
|
||||
return x.days < y.days
|
||||
|
||||
def __le__(self, other: 'Duration') -> bool:
|
||||
x = self.value.normalized()
|
||||
y = other.value.normalized()
|
||||
if (x.years != 0 or y.years != 0 or x.months != 0 or y.months != 0):
|
||||
raise Exception("Can only compare durations expressed in days")
|
||||
else:
|
||||
return x.days <= y.days
|
||||
|
||||
def __gt__(self, other: 'Duration') -> bool:
|
||||
x = self.value.normalized()
|
||||
y = other.value.normalized()
|
||||
if (x.years != 0 or y.years != 0 or x.months != 0 or y.months != 0):
|
||||
raise Exception("Can only compare durations expressed in days")
|
||||
else:
|
||||
return x.days > y.days
|
||||
|
||||
def __ge__(self, other: 'Duration') -> bool:
|
||||
x = self.value.normalized()
|
||||
y = other.value.normalized()
|
||||
if (x.years != 0 or y.years != 0 or x.months != 0 or y.months != 0):
|
||||
raise Exception("Can only compare durations expressed in days")
|
||||
else:
|
||||
return x.days >= y.days
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if isinstance(other, Duration):
|
||||
return self.value != other.value
|
||||
else:
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, Duration):
|
||||
return self.value == other.value
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value.__str__()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Duration({self.value.__repr__()})"
|
||||
|
||||
|
||||
class Unit:
|
||||
def __init__(self) -> None:
|
||||
...
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, Unit):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if isinstance(other, Unit):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "()"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "Unit()"
|
||||
|
||||
|
||||
class SourcePosition:
|
||||
def __init__(self,
|
||||
filename: str,
|
||||
start_line: int,
|
||||
start_column: int,
|
||||
end_line: int,
|
||||
end_column: int,
|
||||
law_headings: List[str]) -> None:
|
||||
self.filename = filename
|
||||
self.start_line = start_line
|
||||
self.start_column = start_column
|
||||
self.end_line = end_line
|
||||
self.end_column = end_column
|
||||
self.law_headings = law_headings
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "in file {}, from {}:{} to {}:{}".format(
|
||||
self.filename, self.start_line, self.start_column, self.end_line, self.end_column)
|
||||
|
||||
# ==========
|
||||
# Exceptions
|
||||
# ==========
|
||||
|
||||
|
||||
class EmptyError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AssertionFailed(Exception):
|
||||
def __init__(self, source_position: SourcePosition) -> None:
|
||||
self.source_position = SourcePosition
|
||||
|
||||
|
||||
class ConflictError(Exception):
|
||||
def __init__(self, source_position: SourcePosition) -> None:
|
||||
self.source_position = SourcePosition
|
||||
|
||||
|
||||
class NoValueProvided(Exception):
|
||||
def __init__(self, source_position: SourcePosition) -> None:
|
||||
self.source_position = SourcePosition
|
||||
|
||||
|
||||
class AssertionFailure(Exception):
|
||||
def __init__(self, source_position: SourcePosition) -> None:
|
||||
self.source_position = SourcePosition
|
||||
|
||||
|
||||
# ============================
|
||||
# Constructors and conversions
|
||||
# ============================
|
||||
|
||||
# -----
|
||||
# Money
|
||||
# -----
|
||||
|
||||
|
||||
def money_of_cents_string(v: str) -> Money:
|
||||
return Money(Integer(v))
|
||||
|
||||
|
||||
def money_of_units_int(v: int) -> Money:
|
||||
return Money(Integer(v) * Integer(100))
|
||||
|
||||
|
||||
def money_of_cents_integer(v: Integer) -> Money:
|
||||
return Money(v)
|
||||
|
||||
|
||||
def money_to_float(m: Money) -> float:
|
||||
return float(mpfr(mpq(m.value.value, 100)))
|
||||
|
||||
|
||||
def money_to_string(m: Money) -> str:
|
||||
return str(money_to_float(m))
|
||||
|
||||
|
||||
def money_to_cents(m: Money) -> Integer:
|
||||
return m.value
|
||||
|
||||
|
||||
def money_round(m: Money) -> Money:
|
||||
res, remainder = t_divmod(m, 100)
|
||||
if remainder < 50:
|
||||
return res * 100
|
||||
else:
|
||||
return (res + sign(res)) * 100
|
||||
|
||||
|
||||
def money_of_decimal(m: Decimal) -> Money:
|
||||
"""
|
||||
Warning: rounds to nearest cent.
|
||||
"""
|
||||
return Money(mpz(m.value))
|
||||
|
||||
# --------
|
||||
# Decimals
|
||||
# --------
|
||||
|
||||
|
||||
def decimal_of_string(d: str) -> Decimal:
|
||||
return Decimal(d)
|
||||
|
||||
|
||||
def decimal_to_float(d: Decimal) -> float:
|
||||
return float(mpfr(d.value))
|
||||
|
||||
|
||||
def decimal_of_float(d: float) -> Decimal:
|
||||
return Decimal(d)
|
||||
|
||||
|
||||
def decimal_of_integer(d: Integer) -> Decimal:
|
||||
return Decimal(d.value)
|
||||
|
||||
|
||||
def decimal_to_string(precision: int, i: Decimal) -> str:
|
||||
return "{1:.{0}}".format(precision, mpfr(i.value, precision * 10 // 2))
|
||||
|
||||
|
||||
def decimal_round(q: Decimal) -> Decimal:
|
||||
# Implements the workaround by
|
||||
# https://gmplib.org/list-archives/gmp-discuss/2009-May/003767.html *)
|
||||
return f_div(2*q.numerator + q.denominator, 2*q.denominator) # type:ignore
|
||||
|
||||
|
||||
def decimal_of_money(m: Money) -> Decimal:
|
||||
return Decimal(f_div(mpq(m.value), mpq(100)))
|
||||
|
||||
# --------
|
||||
# Integers
|
||||
# --------
|
||||
|
||||
|
||||
def integer_of_string(s: str) -> Integer:
|
||||
return Integer(s)
|
||||
|
||||
|
||||
def integer_to_string(d: Integer) -> str:
|
||||
return str(d.value)
|
||||
|
||||
|
||||
def integer_of_int(d: int) -> Integer:
|
||||
return Integer(d)
|
||||
|
||||
|
||||
def integer_to_int(d: Integer) -> int:
|
||||
return int(d.value)
|
||||
|
||||
|
||||
def integer_exponentiation(i: Integer, e: int) -> Integer:
|
||||
return i ** e # type: ignore
|
||||
|
||||
|
||||
def integer_log2(i: Integer) -> int:
|
||||
return int(log2(i.value))
|
||||
|
||||
# -----
|
||||
# Dates
|
||||
# -----
|
||||
|
||||
|
||||
def day_of_month_of_date(d: Date) -> Integer:
|
||||
return integer_of_int(d.value.day)
|
||||
|
||||
|
||||
def month_number_of_date(d: Date) -> Integer:
|
||||
return integer_of_int(d.value.month)
|
||||
|
||||
|
||||
def year_of_date(d: Date) -> Integer:
|
||||
return integer_of_int(d.value.year)
|
||||
|
||||
|
||||
def date_to_string(d: Date) -> str:
|
||||
return "{}".format(d.value)
|
||||
|
||||
|
||||
def date_of_numbers(year: int, month: int, day: int) -> Date:
|
||||
# The datetime.date does not take year=0 as an entry, we trick it into
|
||||
# 1 in that case because year=0 cases don't care about the actual year
|
||||
return Date(datetime.date(year if year != 0 else 1, month, day))
|
||||
|
||||
|
||||
def date_of_datetime(d: datetime.date) -> Date:
|
||||
return Date(d)
|
||||
|
||||
|
||||
def first_day_of_month(d: Date) -> Date:
|
||||
return Date(datetime.date(d.value.year, d.value.month, 1))
|
||||
|
||||
|
||||
def last_day_of_month(d: Date) -> Date:
|
||||
return Date(datetime.date(d.value.year, d.value.month, calendar.monthrange(d.value.year, d.value.month)[1]))
|
||||
|
||||
# ---------
|
||||
# Durations
|
||||
# ---------
|
||||
|
||||
|
||||
def duration_of_numbers(years: int, months: int, days: int) -> Duration:
|
||||
return Duration(dateutil.relativedelta.relativedelta(years=years, months=months, days=days))
|
||||
|
||||
|
||||
def duration_to_years_months_days(d: Duration) -> Tuple[int, int, int]:
|
||||
return (d.value.years, d.value.months, d.value.days) # type: ignore
|
||||
|
||||
|
||||
def duration_to_string(s: Duration) -> str:
|
||||
return "{}".format(s.value)
|
||||
|
||||
# -----
|
||||
# Lists
|
||||
# -----
|
||||
|
||||
|
||||
def list_fold_left(f: Callable[[Alpha, Beta], Alpha], init: Alpha, l: List[Beta]) -> Alpha:
|
||||
return reduce(f, l, init)
|
||||
|
||||
|
||||
def list_filter(f: Callable[[Alpha], bool], l: List[Alpha]) -> List[Alpha]:
|
||||
return [i for i in l if f(i)]
|
||||
|
||||
|
||||
def list_map(f: Callable[[Alpha], Beta], l: List[Alpha]) -> List[Beta]:
|
||||
return [f(i) for i in l]
|
||||
|
||||
|
||||
def list_length(l: List[Alpha]) -> Integer:
|
||||
return Integer(len(l))
|
||||
|
||||
# ========
|
||||
# Defaults
|
||||
# ========
|
||||
|
||||
|
||||
def handle_default(
|
||||
pos: SourcePosition,
|
||||
exceptions: List[Callable[[Unit], Alpha]],
|
||||
just: Callable[[Unit], Alpha],
|
||||
cons: Callable[[Unit], Alpha]
|
||||
) -> Alpha:
|
||||
acc: Optional[Alpha] = None
|
||||
for exception in exceptions:
|
||||
new_val: Optional[Alpha]
|
||||
try:
|
||||
new_val = exception(Unit())
|
||||
except EmptyError:
|
||||
new_val = None
|
||||
if acc is None:
|
||||
acc = new_val
|
||||
elif not (acc is None) and new_val is None:
|
||||
pass # acc stays the same
|
||||
elif not (acc is None) and not (new_val is None):
|
||||
raise ConflictError(pos)
|
||||
if acc is None:
|
||||
if just(Unit()):
|
||||
return cons(Unit())
|
||||
else:
|
||||
raise EmptyError
|
||||
else:
|
||||
return acc
|
||||
|
||||
|
||||
def handle_default_opt(
|
||||
pos: SourcePosition,
|
||||
exceptions: List[Optional[Any]],
|
||||
just: Optional[bool],
|
||||
cons: Optional[Alpha]
|
||||
) -> Optional[Alpha]:
|
||||
acc: Optional[Alpha] = None
|
||||
for exception in exceptions:
|
||||
if acc is None:
|
||||
acc = exception
|
||||
elif not (acc is None) and exception is None:
|
||||
pass # acc stays the same
|
||||
elif not (acc is None) and not (exception is None):
|
||||
raise ConflictError(pos)
|
||||
if acc is None:
|
||||
if just is None:
|
||||
return None
|
||||
else:
|
||||
if just:
|
||||
return cons
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return acc
|
||||
|
||||
|
||||
def no_input() -> Callable[[Unit], Alpha]:
|
||||
def closure(_: Unit):
|
||||
raise EmptyError
|
||||
return closure
|
||||
|
||||
|
||||
# This value is used for the Python code generation to trump mypy and forcing
|
||||
# it to accept dead code. Indeed, when raising an exception during a variable
|
||||
# definition, mypy complains that the later dead code will not know what
|
||||
# this variable was. So we give this variable a dead value.
|
||||
dead_value: Any = 0
|
||||
|
||||
# =======
|
||||
# Logging
|
||||
# =======
|
||||
|
||||
|
||||
class LogEventCode(Enum):
|
||||
VariableDefinition = 0
|
||||
BeginCall = 1
|
||||
EndCall = 2
|
||||
DecisionTaken = 3
|
||||
|
||||
|
||||
class LogEvent:
|
||||
def __init__(self, code: LogEventCode, payload: Union[List[str], SourcePosition, Tuple[List[str], Alpha]]) -> None:
|
||||
self.code = code
|
||||
self.payload = payload
|
||||
|
||||
|
||||
log: List[LogEvent] = []
|
||||
|
||||
|
||||
def reset_log():
|
||||
log = []
|
||||
|
||||
|
||||
def retrieve_log() -> List[LogEvent]:
|
||||
return log
|
||||
|
||||
|
||||
def log_variable_definition(headings: List[str], value: Alpha) -> Alpha:
|
||||
log.append(LogEvent(LogEventCode.VariableDefinition,
|
||||
(headings, copy.deepcopy(value))))
|
||||
return value
|
||||
|
||||
|
||||
def log_begin_call(headings: List[str], f: Callable[[Alpha], Beta], value: Alpha) -> Beta:
|
||||
log.append(LogEvent(LogEventCode.BeginCall, headings))
|
||||
return f(value)
|
||||
|
||||
|
||||
def log_end_call(headings: List[str], value: Alpha) -> Alpha:
|
||||
log.append(LogEvent(LogEventCode.EndCall, headings))
|
||||
return value
|
||||
|
||||
|
||||
def log_decision_taken(pos: SourcePosition, value: bool) -> bool:
|
||||
log.append(LogEvent(LogEventCode.DecisionTaken, pos))
|
||||
return value
|
Loading…
Reference in New Issue
Block a user