Created
March 7, 2022 06:49
-
-
Save MaxGhenis/f14b2395ceb828d22d0dc07df033246b to your computer and use it in GitHub Desktop.
OpenFisca US tutorial.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "OpenFisca US tutorial.ipynb", | |
"provenance": [], | |
"collapsed_sections": [], | |
"authorship_tag": "ABX9TyPy/H63ylH8aOYzZbGoPx7n", | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
}, | |
"language_info": { | |
"name": "python" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/MaxGhenis/f14b2395ceb828d22d0dc07df033246b/openfisca-us-tutorial.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# OpenFisca US tutorial\n", | |
"\n", | |
"OpenFisca US is [PolicyEngine](https://policyengine.org)'s open source tax and benefit microsimulation model.\n", | |
"\n", | |
"This tutorial will teach you how to construct a household, calculate variables, and simulate a range of scenarios, using California's SNAP program as a case study. \n", | |
"\n", | |
"*See https://openfisca.us for full documentation.*\n", | |
"\n", | |
"## Installation\n", | |
"\n", | |
"OpenFisca US is available on PyPI." | |
], | |
"metadata": { | |
"id": "WSwNepc-Tuui" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 1000 | |
}, | |
"id": "_wQ1Ld9hEMvC", | |
"outputId": "f3689413-ca41-4c5f-ba31-4fbc4cacd2eb" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Collecting openfisca-us\n", | |
" Downloading OpenFisca_US-0.37.1-py3-none-any.whl (376 kB)\n", | |
"\u001b[K |████████████████████████████████| 376 kB 3.7 MB/s \n", | |
"\u001b[?25hRequirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from openfisca-us) (4.63.0)\n", | |
"Collecting microdf-python\n", | |
" Downloading microdf_python-0.3.0-py3-none-any.whl (26 kB)\n", | |
"Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from openfisca-us) (1.3.5)\n", | |
"Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from openfisca-us) (2.23.0)\n", | |
"Collecting OpenFisca-Core[web-api]>=35.0.0\n", | |
" Downloading OpenFisca_Core-35.7.8-py3-none-any.whl (214 kB)\n", | |
"\u001b[K |████████████████████████████████| 214 kB 9.2 MB/s \n", | |
"\u001b[?25hCollecting openfisca-us-data>=0.1.2\n", | |
" Downloading openfisca_us_data-0.1.4-py3-none-any.whl (15 kB)\n", | |
"Collecting OpenFisca-Tools<1.0.0,>=0.3.0\n", | |
" Downloading OpenFisca_Tools-0.5.0-py3-none-any.whl (17 kB)\n", | |
"Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from openfisca-us) (3.13)\n", | |
"Collecting pytest<6.0.0,>=4.4.1\n", | |
" Downloading pytest-5.4.3-py3-none-any.whl (248 kB)\n", | |
"\u001b[K |████████████████████████████████| 248 kB 44.1 MB/s \n", | |
"\u001b[?25hRequirement already satisfied: typing-extensions==3.10.0.2 in /usr/local/lib/python3.7/dist-packages (from OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (3.10.0.2)\n", | |
"Collecting nptyping==1.4.4\n", | |
" Downloading nptyping-1.4.4-py3-none-any.whl (31 kB)\n", | |
"Collecting dpath<3.0.0,>=1.5.0\n", | |
" Downloading dpath-2.0.6-py3-none-any.whl (15 kB)\n", | |
"Requirement already satisfied: numexpr<=3.0,>=2.7.0 in /usr/local/lib/python3.7/dist-packages (from OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (2.8.1)\n", | |
"Requirement already satisfied: psutil<6.0.0,>=5.4.7 in /usr/local/lib/python3.7/dist-packages (from OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (5.4.8)\n", | |
"Collecting sortedcontainers==2.2.2\n", | |
" Downloading sortedcontainers-2.2.2-py2.py3-none-any.whl (29 kB)\n", | |
"Collecting numpy<1.21,>=1.11\n", | |
" Downloading numpy-1.20.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (15.3 MB)\n", | |
"\u001b[K |████████████████████████████████| 15.3 MB 26.4 MB/s \n", | |
"\u001b[?25hRequirement already satisfied: markupsafe==2.0.1 in /usr/local/lib/python3.7/dist-packages (from OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (2.0.1)\n", | |
"Requirement already satisfied: flask==1.1.4 in /usr/local/lib/python3.7/dist-packages (from OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (1.1.4)\n", | |
"Collecting flask-cors==3.0.10\n", | |
" Downloading Flask_Cors-3.0.10-py2.py3-none-any.whl (14 kB)\n", | |
"Requirement already satisfied: werkzeug<2.0.0,>=1.0.0 in /usr/local/lib/python3.7/dist-packages (from OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (1.0.1)\n", | |
"Collecting gunicorn<21.0.0,>=20.0.0\n", | |
" Downloading gunicorn-20.1.0-py3-none-any.whl (79 kB)\n", | |
"\u001b[K |████████████████████████████████| 79 kB 4.4 MB/s \n", | |
"\u001b[?25hRequirement already satisfied: Jinja2<3.0,>=2.10.1 in /usr/local/lib/python3.7/dist-packages (from flask==1.1.4->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (2.11.3)\n", | |
"Requirement already satisfied: click<8.0,>=5.1 in /usr/local/lib/python3.7/dist-packages (from flask==1.1.4->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (7.1.2)\n", | |
"Requirement already satisfied: itsdangerous<2.0,>=0.24 in /usr/local/lib/python3.7/dist-packages (from flask==1.1.4->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (1.1.0)\n", | |
"Requirement already satisfied: Six in /usr/local/lib/python3.7/dist-packages (from flask-cors==3.0.10->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (1.15.0)\n", | |
"Collecting typish>=1.7.0\n", | |
" Downloading typish-1.9.3-py3-none-any.whl (45 kB)\n", | |
"\u001b[K |████████████████████████████████| 45 kB 2.5 MB/s \n", | |
"\u001b[?25hRequirement already satisfied: setuptools>=3.0 in /usr/local/lib/python3.7/dist-packages (from gunicorn<21.0.0,>=20.0.0->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (57.4.0)\n", | |
"Requirement already satisfied: packaging in /usr/local/lib/python3.7/dist-packages (from numexpr<=3.0,>=2.7.0->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (21.3)\n", | |
"Requirement already satisfied: wheel in /usr/local/lib/python3.7/dist-packages (from OpenFisca-Tools<1.0.0,>=0.3.0->openfisca-us) (0.37.1)\n", | |
"Requirement already satisfied: h5py in /usr/local/lib/python3.7/dist-packages (from openfisca-us-data>=0.1.2->openfisca-us) (3.1.0)\n", | |
"Collecting synthimpute\n", | |
" Downloading synthimpute-0.1-py3-none-any.whl (8.8 kB)\n", | |
"Collecting pytest-dependency\n", | |
" Downloading pytest-dependency-0.5.1.tar.gz (27 kB)\n", | |
"Requirement already satisfied: pathlib in /usr/local/lib/python3.7/dist-packages (from openfisca-us-data>=0.1.2->openfisca-us) (1.0.1)\n", | |
"Requirement already satisfied: tables in /usr/local/lib/python3.7/dist-packages (from openfisca-us-data>=0.1.2->openfisca-us) (3.7.0)\n", | |
"Requirement already satisfied: wcwidth in /usr/local/lib/python3.7/dist-packages (from pytest<6.0.0,>=4.4.1->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (0.2.5)\n", | |
"Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.7/dist-packages (from pytest<6.0.0,>=4.4.1->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (21.4.0)\n", | |
"Requirement already satisfied: importlib-metadata>=0.12 in /usr/local/lib/python3.7/dist-packages (from pytest<6.0.0,>=4.4.1->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (4.11.2)\n", | |
"Requirement already satisfied: more-itertools>=4.0.0 in /usr/local/lib/python3.7/dist-packages (from pytest<6.0.0,>=4.4.1->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (8.12.0)\n", | |
"Collecting pluggy<1.0,>=0.12\n", | |
" Downloading pluggy-0.13.1-py2.py3-none-any.whl (18 kB)\n", | |
"Requirement already satisfied: py>=1.5.0 in /usr/local/lib/python3.7/dist-packages (from pytest<6.0.0,>=4.4.1->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (1.11.0)\n", | |
"Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=0.12->pytest<6.0.0,>=4.4.1->OpenFisca-Core[web-api]>=35.0.0->openfisca-us) (3.7.0)\n", | |
"Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py->openfisca-us-data>=0.1.2->openfisca-us) (1.5.2)\n", | |
"Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from microdf-python->openfisca-us) (3.2.2)\n", | |
"Collecting matplotlib-label-lines\n", | |
" Downloading matplotlib_label_lines-0.5.1-py3-none-any.whl (12 kB)\n", | |
"Requirement already satisfied: seaborn in /usr/local/lib/python3.7/dist-packages (from microdf-python->openfisca-us) (0.11.2)\n", | |
"Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->microdf-python->openfisca-us) (3.0.7)\n", | |
"Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->microdf-python->openfisca-us) (2.8.2)\n", | |
"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->microdf-python->openfisca-us) (0.11.0)\n", | |
"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->microdf-python->openfisca-us) (1.3.2)\n", | |
"Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas->openfisca-us) (2018.9)\n", | |
"Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->openfisca-us) (1.24.3)\n", | |
"Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->openfisca-us) (2021.10.8)\n", | |
"Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->openfisca-us) (2.10)\n", | |
"Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->openfisca-us) (3.0.4)\n", | |
"Requirement already satisfied: scipy>=1.0 in /usr/local/lib/python3.7/dist-packages (from seaborn->microdf-python->openfisca-us) (1.4.1)\n", | |
"Requirement already satisfied: statsmodels in /usr/local/lib/python3.7/dist-packages (from synthimpute->openfisca-us-data>=0.1.2->openfisca-us) (0.10.2)\n", | |
"Requirement already satisfied: scikit-learn in /usr/local/lib/python3.7/dist-packages (from synthimpute->openfisca-us-data>=0.1.2->openfisca-us) (1.0.2)\n", | |
"Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn->synthimpute->openfisca-us-data>=0.1.2->openfisca-us) (3.1.0)\n", | |
"Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn->synthimpute->openfisca-us-data>=0.1.2->openfisca-us) (1.1.0)\n", | |
"Requirement already satisfied: patsy>=0.4.0 in /usr/local/lib/python3.7/dist-packages (from statsmodels->synthimpute->openfisca-us-data>=0.1.2->openfisca-us) (0.5.2)\n", | |
"Building wheels for collected packages: pytest-dependency\n", | |
" Building wheel for pytest-dependency (setup.py) ... \u001b[?25l\u001b[?25hdone\n", | |
" Created wheel for pytest-dependency: filename=pytest_dependency-0.5.1-py3-none-any.whl size=8218 sha256=e6e9e7e71a9c2246cf6c4264594e29abb95262ffb69f60cfb7dbfbdb234db376\n", | |
" Stored in directory: /root/.cache/pip/wheels/7e/72/eb/c96a0b4b22f42d092914ba8fe7b4c639443ef02b529dbbefcf\n", | |
"Successfully built pytest-dependency\n", | |
"Installing collected packages: numpy, typish, pluggy, sortedcontainers, pytest, nptyping, matplotlib-label-lines, dpath, synthimpute, pytest-dependency, OpenFisca-Core, microdf-python, gunicorn, flask-cors, openfisca-us-data, OpenFisca-Tools, openfisca-us\n", | |
" Attempting uninstall: numpy\n", | |
" Found existing installation: numpy 1.21.5\n", | |
" Uninstalling numpy-1.21.5:\n", | |
" Successfully uninstalled numpy-1.21.5\n", | |
" Attempting uninstall: pluggy\n", | |
" Found existing installation: pluggy 0.7.1\n", | |
" Uninstalling pluggy-0.7.1:\n", | |
" Successfully uninstalled pluggy-0.7.1\n", | |
" Attempting uninstall: sortedcontainers\n", | |
" Found existing installation: sortedcontainers 2.4.0\n", | |
" Uninstalling sortedcontainers-2.4.0:\n", | |
" Successfully uninstalled sortedcontainers-2.4.0\n", | |
" Attempting uninstall: pytest\n", | |
" Found existing installation: pytest 3.6.4\n", | |
" Uninstalling pytest-3.6.4:\n", | |
" Successfully uninstalled pytest-3.6.4\n", | |
"\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", | |
"tensorflow 2.8.0 requires tf-estimator-nightly==2.8.0.dev2021122109, which is not installed.\n", | |
"datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\n", | |
"albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.2.9 which is incompatible.\u001b[0m\n", | |
"Successfully installed OpenFisca-Core-35.7.8 OpenFisca-Tools-0.5.0 dpath-2.0.6 flask-cors-3.0.10 gunicorn-20.1.0 matplotlib-label-lines-0.5.1 microdf-python-0.3.0 nptyping-1.4.4 numpy-1.20.3 openfisca-us-0.37.1 openfisca-us-data-0.1.4 pluggy-0.13.1 pytest-5.4.3 pytest-dependency-0.5.1 sortedcontainers-2.2.2 synthimpute-0.1 typish-1.9.3\n" | |
] | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"application/vnd.colab-display-data+json": { | |
"pip_warning": { | |
"packages": [ | |
"numpy" | |
] | |
} | |
} | |
}, | |
"metadata": {} | |
} | |
], | |
"source": [ | |
"!pip install openfisca-us" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Constructing households\n", | |
"\n", | |
"To calculate taxes and benefits, first define the household via:\n", | |
"1. The `IndividualSim` constructor.\n", | |
"2. The `add_person` method.\n", | |
"\n", | |
"Let's start with a single person with \\$1,000 monthly employment income (inputs and outputs are all annual)." | |
], | |
"metadata": { | |
"id": "_uvPNJyRPd3q" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from openfisca_us import IndividualSim\n", | |
"\n", | |
"sim = IndividualSim(year=2022)\n", | |
"sim.add_person(name=\"person\", employment_income=1000 * 12)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "P5NsStTGEQjI", | |
"outputId": "92ba1dca-c5ac-40a7-8e6d-ffa2bfbb3b0a" | |
}, | |
"execution_count": 2, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"/usr/local/lib/python3.7/dist-packages/openfisca_core/parameters/config.py:17: LibYAMLWarning: libyaml is not installed in your environment. This can make OpenFisca slower to start. Once you have installed libyaml, run 'pip uninstall pyyaml && pip install pyyaml --no-cache-dir' so that it is used in your Python environment.\n", | |
"\n", | |
" warnings.warn(\" \".join(message), LibYAMLWarning)\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Calculating variables\n", | |
"\n", | |
"Now we can calculate any variables in the [`openfisca_us/variables` folder](https://github.com/PolicyEngine/openfisca-us/tree/master/openfisca_us/variables) via the `calc` method.\n", | |
"\n", | |
"For example, let's recover `employment_income`:" | |
], | |
"metadata": { | |
"id": "1RTLMDrwRC33" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"sim.calc(\"employment_income\")" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "2f04mTDDRlIH", | |
"outputId": "613d933b-e0cd-44e5-f3bd-808805216435" | |
}, | |
"execution_count": 3, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"array([12000.], dtype=float32)" | |
] | |
}, | |
"metadata": {}, | |
"execution_count": 3 | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"**Exercise 1: Calculate SNAP**\n", | |
"\n", | |
"Calculate three SNAP-related variables:\n", | |
"1. `snap_normal_allotment`, which they would receive outside of Covid.\n", | |
"2. `snap_emergency_allotment`, which bumps up eligible households to the maximum allotment during the pandemic.\n", | |
"3. `snap`, which sums the two.\n", | |
"\n", | |
"Print them as monthly amounts." | |
], | |
"metadata": { | |
"id": "lpDCSx4oR6cR" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Write your solution here." | |
], | |
"metadata": { | |
"id": "qhUZ2jU0RBPl" | |
}, | |
"execution_count": 4, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Households with multiple people\n", | |
"\n", | |
"To create households with multiple people, we need to assign them to a household unit.\n", | |
"US tax and benefit programs group people in different ways, and SNAP uses a *SPM unit*, or a group of people that cohabit and share resources (SPM stands for the Supplemental Poverty Measure).\n", | |
"\n", | |
"Let's now model a two-person household, still with \\$1,000 monthly employment income, and group them with the `add_spm_unit` method.\n", | |
"This also enables us to add SPM-unit-level characteristics, like housing costs (which affect SNAP benefits)." | |
], | |
"metadata": { | |
"id": "9GHwdDfrTd8F" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"sim = IndividualSim(year=2022)\n", | |
"sim.add_person(name=\"parent\", employment_income=1000 * 12)\n", | |
"sim.add_person(name=\"child\")\n", | |
"sim.add_spm_unit(\n", | |
" name=\"spm_unit\", members=[\"parent\", \"child\"], housing_cost=600 * 12\n", | |
")" | |
], | |
"metadata": { | |
"id": "6q3mH6bLa8IA" | |
}, | |
"execution_count": 5, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Now let's recalculate SNAP." | |
], | |
"metadata": { | |
"id": "UytFo1Kabas2" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"print(\n", | |
" \"SNAP normal allotment: \",\n", | |
" round(sim.calc(\"snap_normal_allotment\")[0] / 12),\n", | |
")\n", | |
"print(\n", | |
" \"SNAP emergency allotment: \",\n", | |
" round(sim.calc(\"snap_emergency_allotment\")[0] / 12),\n", | |
")\n", | |
"print(\"Total SNAP: \", round(sim.calc(\"snap\")[0] / 12))" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "EMcis19qbfyy", | |
"outputId": "9c6faba5-bb99-4f3d-e824-fea7453021d9" | |
}, | |
"execution_count": 6, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"SNAP normal allotment: 354\n", | |
"SNAP emergency allotment: 105\n", | |
"Total SNAP: 459\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"**Exercise 2: Customize a household**\n", | |
"\n", | |
"Create a new household with a different number of people, or different income or housing costs.\n", | |
"Recalculate SNAP." | |
], | |
"metadata": { | |
"id": "ey1n_m0ybjTw" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Write your solution here." | |
], | |
"metadata": { | |
"id": "lMLmzrqybyYy" | |
}, | |
"execution_count": 7, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Scenario analysis\n", | |
"\n", | |
"Suppose we want to explore a range of inputs, rather than manually specifying one or two.\n", | |
"We can apply techniques like list comprehension, but openfisca-us makes it easier with the `vary` method.\n", | |
"\n", | |
"When we call `sim.vary`, subsequent `calc` calls calculate over the range of inputs specified in `vary`.\n", | |
"\n", | |
"Let's vary employment income, going up to \\$3,000 per month in increments of \\$10 per month." | |
], | |
"metadata": { | |
"id": "pkPuMdkJb01b" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"sim.vary(\"employment_income\", max=3000 * 12, step=10 * 12)" | |
], | |
"metadata": { | |
"id": "xXkUlKRZcpCb" | |
}, | |
"execution_count": 8, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Now when we call `calc`, we get an array rather than a scalar. Let's start by recovering employment income again." | |
], | |
"metadata": { | |
"id": "l5dyC7fAcsQl" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"sim.calc(\"employment_income\")" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "2H9VdE3hfX4t", | |
"outputId": "c93d2ca8-3027-4ab3-d537-2529529375d2" | |
}, | |
"execution_count": 9, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"array([[ 0., 120., 240., 360., 480., 600., 720., 840.,\n", | |
" 960., 1080., 1200., 1320., 1440., 1560., 1680., 1800.,\n", | |
" 1920., 2040., 2160., 2280., 2400., 2520., 2640., 2760.,\n", | |
" 2880., 3000., 3120., 3240., 3360., 3480., 3600., 3720.,\n", | |
" 3840., 3960., 4080., 4200., 4320., 4440., 4560., 4680.,\n", | |
" 4800., 4920., 5040., 5160., 5280., 5400., 5520., 5640.,\n", | |
" 5760., 5880., 6000., 6120., 6240., 6360., 6480., 6600.,\n", | |
" 6720., 6840., 6960., 7080., 7200., 7320., 7440., 7560.,\n", | |
" 7680., 7800., 7920., 8040., 8160., 8280., 8400., 8520.,\n", | |
" 8640., 8760., 8880., 9000., 9120., 9240., 9360., 9480.,\n", | |
" 9600., 9720., 9840., 9960., 10080., 10200., 10320., 10440.,\n", | |
" 10560., 10680., 10800., 10920., 11040., 11160., 11280., 11400.,\n", | |
" 11520., 11640., 11760., 11880., 12000., 12120., 12240., 12360.,\n", | |
" 12480., 12600., 12720., 12840., 12960., 13080., 13200., 13320.,\n", | |
" 13440., 13560., 13680., 13800., 13920., 14040., 14160., 14280.,\n", | |
" 14400., 14520., 14640., 14760., 14880., 15000., 15120., 15240.,\n", | |
" 15360., 15480., 15600., 15720., 15840., 15960., 16080., 16200.,\n", | |
" 16320., 16440., 16560., 16680., 16800., 16920., 17040., 17160.,\n", | |
" 17280., 17400., 17520., 17640., 17760., 17880., 18000., 18120.,\n", | |
" 18240., 18360., 18480., 18600., 18720., 18840., 18960., 19080.,\n", | |
" 19200., 19320., 19440., 19560., 19680., 19800., 19920., 20040.,\n", | |
" 20160., 20280., 20400., 20520., 20640., 20760., 20880., 21000.,\n", | |
" 21120., 21240., 21360., 21480., 21600., 21720., 21840., 21960.,\n", | |
" 22080., 22200., 22320., 22440., 22560., 22680., 22800., 22920.,\n", | |
" 23040., 23160., 23280., 23400., 23520., 23640., 23760., 23880.,\n", | |
" 24000., 24120., 24240., 24360., 24480., 24600., 24720., 24840.,\n", | |
" 24960., 25080., 25200., 25320., 25440., 25560., 25680., 25800.,\n", | |
" 25920., 26040., 26160., 26280., 26400., 26520., 26640., 26760.,\n", | |
" 26880., 27000., 27120., 27240., 27360., 27480., 27600., 27720.,\n", | |
" 27840., 27960., 28080., 28200., 28320., 28440., 28560., 28680.,\n", | |
" 28800., 28920., 29040., 29160., 29280., 29400., 29520., 29640.,\n", | |
" 29760., 29880., 30000., 30120., 30240., 30360., 30480., 30600.,\n", | |
" 30720., 30840., 30960., 31080., 31200., 31320., 31440., 31560.,\n", | |
" 31680., 31800., 31920., 32040., 32160., 32280., 32400., 32520.,\n", | |
" 32640., 32760., 32880., 33000., 33120., 33240., 33360., 33480.,\n", | |
" 33600., 33720., 33840., 33960., 34080., 34200., 34320., 34440.,\n", | |
" 34560., 34680., 34800., 34920., 35040., 35160., 35280., 35400.,\n", | |
" 35520., 35640., 35760., 35880., 36000.],\n", | |
" [ 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0., 0., 0., 0.,\n", | |
" 0., 0., 0., 0., 0.]], dtype=float32)" | |
] | |
}, | |
"metadata": {}, | |
"execution_count": 9 | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Since `employment_income` is person-level, `calc` returns a two-row array. `vary` varies the first person's variable by default, so the child's income stays fixed at zero.\n", | |
"\n", | |
"### Calculating SNAP as income varies\n", | |
"\n", | |
"Now we can calculate normal SNAP allotments.\n", | |
"Each value corresponds to the varied employment income above.\n", | |
"\n", | |
"For example, at \\$0 employment income, the household will get \\$5,508 in annual benefits.\n", | |
"At \\$3,000 monthly employment income, they are not eligible for any SNAP benefits.\n", | |
"Since `snap_normal_allotment` is at the SPM unit level, `calc` now returns a one-row array." | |
], | |
"metadata": { | |
"id": "KRzYPtrhfZRV" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"sim.calc(\"snap_normal_allotment\")" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "fgR_DjJPcwxA", | |
"outputId": "8ffc5666-0bc9-4281-b0a8-a6ef1594481c" | |
}, | |
"execution_count": 10, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"array([[5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5508. ,\n", | |
" 5508. , 5508. , 5508. , 5508. , 5508. , 5502.6 ,\n", | |
" 5459.4 , 5416.2 , 5373. , 5329.8 , 5286.6 , 5243.4 ,\n", | |
" 5200.2 , 5157. , 5113.8 , 5070.6 , 5027.4 , 4984.2 ,\n", | |
" 4941. , 4897.8 , 4854.6 , 4811.4 , 4768.2 , 4725. ,\n", | |
" 4681.8 , 4638.6 , 4595.4 , 4552.2 , 4509. , 4465.8 ,\n", | |
" 4422.6 , 4379.4 , 4336.2 , 4293. , 4249.8 , 4206.6 ,\n", | |
" 4163.4 , 4120.2 , 4077. , 4033.7998, 3990.6 , 3947.4 ,\n", | |
" 3904.2 , 3861. , 3817.7998, 3774.6 , 3731.4 , 3688.2 ,\n", | |
" 3645. , 3601.7998, 3558.6 , 3515.4 , 3472.2 , 3429. ,\n", | |
" 3385.7998, 3342.5999, 3299.4 , 3256.2 , 3213. , 3169.7998,\n", | |
" 3126.5999, 3083.4 , 3040.2 , 2997. , 2953.7998, 2910.5999,\n", | |
" 2867.4 , 2824.2 , 2781. , 2737.7998, 2694.5999, 2651.4 ,\n", | |
" 2608.2 , 2565. , 2521.7998, 2478.5999, 2435.4 , 2392.2 ,\n", | |
" 2348.9998, 2305.7998, 2262.5999, 2219.4 , 2176.2 , 2132.9998,\n", | |
" 2089.7998, 2046.5999, 2003.3999, 1960.2 , 1916.9998, 1873.7998,\n", | |
" 1830.5999, 1787.3999, 1744.2 , 1700.9998, 1657.7998, 1614.5999,\n", | |
" 1571.3999, 1528.2 , 1484.9998, 1441.7998, 1398.5996, 1355.3999,\n", | |
" 1312.1997, 1269. , 1225.7998, 1184.3999, 1155.5996, 1126.7998,\n", | |
" 1098. , 1069.1997, 1040.3999, 1011.5996, 982.7998, 954. ,\n", | |
" 925.1997, 896.3999, 867.5996, 838.7998, 810. , 781.1997,\n", | |
" 752.3999, 723.5996, 694.7998, 666. , 637.1997, 608.3999,\n", | |
" 579.5996, 550.7998, 522. , 493.1997, 464.3999, 435.5996,\n", | |
" 406.7998, 378. , 349.1997, 320.3999, 291.5996, 262.7998,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 240. , 240. , 240. ,\n", | |
" 240. , 240. , 240. , 0. , 0. , 0. ,\n", | |
" 0. , 0. , 0. , 0. , 0. , 0. ,\n", | |
" 0. ]], dtype=float32)" | |
] | |
}, | |
"metadata": {}, | |
"execution_count": 10 | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"**Exercise 3: Visualization**\n", | |
"\n", | |
"Use your preferred data visualization library to create a plot of employment income on the x axis and normal (non-Covid) SNAP benefits on the y axis.\n", | |
"\n", | |
"*Hint: `IndividualSim.calc` returns a list of all households' values. Since we're only working with one household, extract the first with `calc(x)[0]`.*" | |
], | |
"metadata": { | |
"id": "75v5UVbAb7dU" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Write your solution here." | |
], | |
"metadata": { | |
"id": "y2mz3743LfNS" | |
}, | |
"execution_count": 11, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Learn more\n", | |
"\n", | |
"Visit [openfisca.us](https://openfisca.us) for examples of other programs, calculating marginal tax rates, and more." | |
], | |
"metadata": { | |
"id": "qBEWQxKycI5i" | |
} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment