Skip to content

Instantly share code, notes, and snippets.

@Morendil
Last active July 15, 2021 10:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Morendil/39421e1c81eae680e1bd77a6d452a72e to your computer and use it in GitHub Desktop.
Save Morendil/39421e1c81eae680e1bd77a6d452a72e to your computer and use it in GitHub Desktop.

OpenFisca et "métaprogrammation"

rfr = individu.foyer_fiscal('rfr', period.n_2)

L'appel ci-dessus est à peu près équivalent à

simulation = individu.simulation
rfr = simulation.calculate('rfr', period.n_2)
rfr = simulation.populations['foyer_fiscal'].project(rfr)

L'opération de projection est à la base assez simple…

Prenons par exemple un vecteur de 5 individus, les variables invididuelles étant disons age=[10,30,5,8,45]; il se répartit en deux foyers fiscaux, la population des foyers fiscaux est un vecteur avec par exemple rfr=[40000,60000]. Un vecteur "pivot" affecte chaque individu à un foyer fiscal: members_entity_id=[0,0,0,1,1].

Dans ce cas projeter revient à prendre rfr[members_entity_id] => [40000,40000,40000,60000,60000] soit "pour chaque individu le RFR du foyer fiscal auquel il appartient".

Dans les coulisses c'est plus compliqué, il y a de la magie pour éviter de manipuler explicitement l'instance de Simulation.

individu est de type Population

Sa création se fait dans TaxBenefitSystem::instantiate_entities

L'instance appartient à Simulation: une Simulation, une instance de Population ou GroupPopulation pour chaque instance de Entity

individu.foyer_fiscal déclenche Population::__getattr__

La valeur renvoyée est de type EntityToPersonProjector (appelons-la projector), nouvellement instanciée en lui fournissant un paramètre de type Population obtenu par lookup dans la Simulation (simulation.populations['foyer_fiscal']), la population dite "de référence", appelons-la reference

individu.foyer_fiscal(*args) se résoud donc en projector(*args)

Ce dernier appel déclenche Projector::__call__

Celui-ci va à son tour invoquer Population::call via reference(*args); puis postérieurement, appeler Projector::transform sur le vecteur résultat, qui pour l'essentiel effectue un appel à Population::project

Population:__call__ quant à lui est un wrapper pour Simulation::calculate()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment