\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Importance of giving a convenient period"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook aim to show easily how periods work in OpenFisca. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We need to initialize a **simulation**."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from openfisca_france import FranceTaxBenefitSystem\n",
"tax_benefit_system = FranceTaxBenefitSystem()\n",
"scenario = tax_benefit_system.new_scenario()\n",
"scenario.init_single_entity(\n",
" period = 2015,\n",
" parent1 = dict(\n",
" age = 30,\n",
" salaire_de_base = 50000,\n",
" ),\n",
" enfants = [\n",
" dict(age = 12),\n",
" dict(age = 18),\n",
" ],\n",
" )\n",
"simulation = scenario.new_simulation()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A simulation's variable is calculated for a specific period. \n",
"This specific time interval have to be given when calling a variable to avoid computation problem.\n",
"\n",
"### Variables with monthly formulas"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some variables are computed over the month. \n",
"For exemple the variable `allocation familiales`. \n",
"If called on an annual basis, an error is displayed : "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unable to compute variable af for period 2015 : af must be computed for a whole month. You can use the ADD option to sum af over the requested period, or change the requested period to \"period.first_month\".\n"
]
}
],
"source": [
"try:\n",
" simulation.calculate('af', '2015')\n",
"except Exception as e:\n",
" print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This assertion error : \n",
" \"`Requested period 2015 differs from 2015-01 returned by variable af`\" \n",
"means exactly the fact that `af` are computed for a month, therefore the variable returned value for `2015-01`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But when called on its period (monthly), the result of the variable's formula will be returned"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([129.99], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation.calculate('af', '2015-01') #calculate variable af for January 2015"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Variable with annual formulas"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Other formulas only works on a annual basis, thus a monthly call will not work, e.g irpp (impôt sur le revenu) :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unable to compute variable irpp for period 2015-01 : irpp must be computed for a whole year. You can use the DIVIDE option to get an estimate of irpp by dividing the yearly value by 12, or change the requested period to \"period.this_year\".\n"
]
}
],
"source": [
"try:\n",
" simulation.calculate('irpp', period = '2015-01')\n",
"except Exception as e:\n",
" print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It must be called on an annual basis :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([-2400.528], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation.calculate('irpp', period = '2015') #calculate variable irpp for 2015"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**WARNING** : this demonstration shows the necessity of being aware over which kind of period each measure you want to compute is based on.\n",
"\n",
"### How to know the definition period of a variable\n",
"\n",
"If you've forgotten over which kind of period (year or month) your variable is defined in the legislation, you may check in the [legislation explorer](https://fr.openfisca.org/legislation).\n",
"\n",
"The information is located in the code source.\n",
"\n",
"Example for the [irpp](https://fr.openfisca.org/legislation/irpp), a tax with annual definition, you will find the period at the end of the website page:\n",
"\n",
"![](irpp_period.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Solutions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Specific period calls insure that no errors are made by the user. \n",
"If a annual based variable is asked to be computed monthly, the software returns an error.\n",
"\n",
"But there is solutions to get the result of a given variable on another kind of period, a annual based variable over a month for example."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Calculate_add : small to larger period"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The calculate_add method has the same behavior as calculate, except that it sum all variables given their instant of calculus over a period lenght."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1559.88], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation.calculate_add(\"af\", \"2015\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This result is equivalent to do sum all monthly calculate over the period."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1559.88], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"annual_af = 0 #create annual_af equals to 0\n",
"for month in range(1,13): # [1,2,...,11,12]\n",
" annual_af += simulation.calculate(\"af\", '2015-{}'.format(month)) #add recursively af for all month in 2014\n",
"annual_af"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We thus see that annual_af is equal to simulation.calculate_add('af', \"2014\").\n",
"\n",
"We can test that :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ True])"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation.calculate_add('af','2015') == annual_af"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Calculate_divide : large to smaller period"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([-200.044], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation.calculate_divide(\"irpp\", \"2015-01\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([-200.044], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation.calculate(\"irpp\", \"2015\") / 12"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Concept of Period"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also use more exotic period by using the class periods. \n",
"\n",
"Actually when we do : `simulation.calculate('irpp','2015')`, the '2015' string is converted into an object period. \n",
"\n",
"A more explicit way to do this, is : `simulation.calculate('irpp', periods.period('2015'))`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Period((u'year', Instant((2015, 1, 1)), 1))"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from openfisca_core import periods # OpenFisca_core is the architecture of OpenFisca\n",
"periods.period('2015')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-2400.528]\n",
"[ True]\n"
]
}
],
"source": [
"print(simulation.calculate('irpp', periods.period('2015')))\n",
"print(simulation.calculate('irpp', periods.period('2015')) == simulation.calculate('irpp', 2015))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Definition\n",
"We can look at periods docstring to understand how it works :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Return a new period, aka a triple (unit, start_instant, size).\n",
"\n",
" >>> period(u'2014')\n",
" Period((YEAR, Instant((2014, 1, 1)), 1))\n",
" >>> period(u'year:2014')\n",
" Period((YEAR, Instant((2014, 1, 1)), 1))\n",
"\n",
" >>> period(u'2014-2')\n",
" Period((MONTH, Instant((2014, 2, 1)), 1))\n",
" >>> period(u'2014-02')\n",
" Period((MONTH, Instant((2014, 2, 1)), 1))\n",
" >>> period(u'month:2014-2')\n",
" Period((MONTH, Instant((2014, 2, 1)), 1))\n",
"\n",
" >>> period(u'year:2014-2')\n",
" Period((YEAR, Instant((2014, 2, 1)), 1))\n",
" \n"
]
}
],
"source": [
"print(periods.period.__doc__)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A `Period` object is initialized with three parameters:\n",
"- A unit : day, month and year\n",
"- A start instant : the date at which it starts\n",
"- And a size : the number of unit \n",
"\n",
"`periods.Period('day', periods.Instant((2014, 3, 01)), 32)` would be a period going from the first of March to the first of april"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('day', Instant((2014, 3, 1)), 32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"period = periods.Period(('day', periods.Instant((2014, 3, 1)), 32)) \n",
"period.unit, period.start, period.size"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Computing over several months"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we want to calculate the 'allocation familiales' from the April to July."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[519.18]\n"
]
}
],
"source": [
"af_april_to_july = simulation.calculate_add(\n",
" 'af', \n",
" period = periods.Period(('month', periods.Instant((2014, 3, 1)), 4))\n",
" )\n",
"print(af_april_to_july)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A simplificated version of period declaration exists with the symbol: `\":\"`.\n",
"\n",
"`month:year-month:n` means n months beginning at the month, year.\n",
"\n",
"Example with `af_april_to_july`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[519.96]\n"
]
}
],
"source": [
"af_april_to_july = simulation.calculate_add('af', period = periods.period(\"month:2014-04:4\"))\n",
"print(af_april_to_july)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A simplified instant declaration of instant also exists "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Instant((2014, 1, 1))"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"periods.instant(\"2014-01\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Computing over several years with identique scenario\n",
"\n",
"Computing over several years needs to rethink how we've declared the scenario: \n",
"the starting scenario has, as `period`, one year, `2015`, so it won't be able to compute anything outside this time interval.\n",
"\n",
"The idea is to change the period over which the scenario applies, using the syntax shown previously. \n",
"\n",
"**WARNING : handling the stretching of values ** \n",
"Doing that defines the other variables for the entire time interval including their values."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# We have to initialise a new scenario\n",
"scenario_over_years = tax_benefit_system.new_scenario()\n",
"scenario_over_years.init_single_entity(\n",
" period = 'year:2014:3', # three years starting in 2014\n",
" parent1 = dict(\n",
" date_naissance = 1975,\n",
" salaire_de_base = 50000 * 3, \n",
" # Multiplication by 3 is need so salaire de base is 50000 € for each of the three years\n",
" ),\n",
" enfants = [\n",
" dict(date_naissance = 2001),\n",
" dict(date_naissance = 1999),\n",
" ],\n",
" )\n",
"simulation_over_years = scenario_over_years.new_simulation()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**WARNING : handling the age** \n",
"We've changed the variable `age` to `date_naissance` in order that the individuals get older. If we've kept the `age` they would have the same age for the entire period.\n",
"\n",
"Now we can compute the `irpp` with the function previously used : `calculate_add`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([-4813.6865], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation_over_years.calculate_add('irpp', period = 'year:2014-01:2') # for 2014 and 2015"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It takes in consideration the legislation change between the two years. \n",
"Therefore it equals the sum of `irpp` for each year but not the double of `irpp` for one year."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-4813.6865]\n",
"[-4826.3174]\n"
]
}
],
"source": [
"print(simulation_over_years.calculate('irpp', '2015') + simulation_over_years.calculate('irpp', '2014'))\n",
"print(simulation_over_years.calculate_add('irpp', '2014') * 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These formulas are still working for variables defined on a monthly basis."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([324.97363], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation_over_years.calculate_add('af', 'month:2015-01:2')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Computing over several years changing scenario\n",
"\n",
"You might want to make evolve some given values over the years.\n",
"\n",
"The tool for it will be to use a Python dictionnary.\n",
"\n",
"For example, if you want to give a wage evolution :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"scenario_over_years = tax_benefit_system.new_scenario()\n",
"scenario_over_years.init_single_entity(\n",
" period = 'year:2014:3',\n",
" parent1 = dict(\n",
" date_naissance = 1975,\n",
" salaire_de_base = {\n",
" '2014': 50000, \n",
" '2015': 50500, \n",
" '2016': 51000\n",
" },\n",
" ),\n",
" enfants = [\n",
" dict(date_naissance = 2001),\n",
" dict(date_naissance = 1999),\n",
" ],\n",
" )\n",
"simulation_over_years = scenario_over_years.new_simulation()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([-7362.9565], dtype=float32)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"simulation_over_years.calculate_add('irpp', 'year:2014:3') # for 2014, 2015 and 2016"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Command line to get the Notebook's Table of Contents:*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 1
}