diff --git a/or_kicker_credit_analysis.ipynb b/or_kicker_credit_analysis.ipynb new file mode 100644 index 0000000..f2f6791 --- /dev/null +++ b/or_kicker_credit_analysis.ipynb @@ -0,0 +1,631 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Oregon Kicker Credit Analysis (2024)\n", + "\n", + "This notebook analyzes the impact of applying the 2025 Oregon kicker rate to tax year 2024:\n", + "- **Baseline**: Current law for 2024 (0% kicker rate)\n", + "- **Reform**: 2025 kicker rate (9.86%) applied to 2024\n", + "\n", + "The Oregon kicker is a tax refund provided to taxpayers when state revenues exceed forecasts.\n", + "\n", + "**Note**: Since the kicker is based on prior-year tax liability (`or_tax_before_credits_in_prior_year`), which is an input variable not present in the dataset, we inject current-year tax as a proxy to enable the analysis." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from policyengine_us import Microsimulation\n", + "from policyengine_core.reforms import Reform\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup Simulations\n", + "\n", + "The baseline is current law for 2024 (0% kicker), while the reform applies the 2025 kicker rate." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Calculated OR tax before credits for 2024:\n", + " Mean: $6478.82\n", + " Max: $43349792.00\n" + ] + } + ], + "source": [ + "DATASET = \"hf://policyengine/policyengine-us-data/states/OR.h5\"\n", + "YEAR = 2024\n", + "KICKER_RATE_2025 = 0.09863 # 9.86%\n", + "\n", + "# Step 1: Run initial simulation to get current-year tax before credits\n", + "# (used as proxy for prior-year tax)\n", + "initial_sim = Microsimulation(dataset=DATASET)\n", + "tax_before_credits = initial_sim.calculate(\"or_income_tax_before_credits\", period=YEAR)\n", + "\n", + "print(f\"Calculated OR tax before credits for {YEAR}:\")\n", + "print(f\" Mean: ${tax_before_credits.mean():.2f}\")\n", + "print(f\" Max: ${tax_before_credits.max():.2f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Baseline kicker percent for 2024: 0.00%\n", + "Reform kicker percent for 2024: 9.86%\n" + ] + } + ], + "source": [ + "# Step 2: Create simulations with prior-year tax injected\n", + "# Reform that applies the 2025 kicker rate to 2024\n", + "kicker_reform = Reform.from_dict({\n", + " \"gov.states.or.tax.income.credits.kicker.percent\": {\n", + " \"2024-01-01.2100-12-31\": KICKER_RATE_2025\n", + " }\n", + "}, country_id=\"us\")\n", + "\n", + "# Baseline: Current law for 2024 (0% kicker)\n", + "baseline = Microsimulation(dataset=DATASET)\n", + "\n", + "# Reform: 2025 kicker rate (9.86%) applied to 2024\n", + "reformed = Microsimulation(reform=kicker_reform, dataset=DATASET)\n", + "\n", + "# Inject prior-year tax values (using current year as proxy)\n", + "baseline.set_input(\"or_tax_before_credits_in_prior_year\", YEAR, tax_before_credits.values)\n", + "reformed.set_input(\"or_tax_before_credits_in_prior_year\", YEAR, tax_before_credits.values)\n", + "\n", + "# Check the kicker percent parameters\n", + "params_baseline = baseline.tax_benefit_system.parameters\n", + "params_reformed = reformed.tax_benefit_system.parameters\n", + "kicker_param_baseline = getattr(getattr(getattr(getattr(getattr(getattr(params_baseline.gov.states, \"or\"), \"tax\"), \"income\"), \"credits\"), \"kicker\"), \"percent\")\n", + "kicker_param_reformed = getattr(getattr(getattr(getattr(getattr(getattr(params_reformed.gov.states, \"or\"), \"tax\"), \"income\"), \"credits\"), \"kicker\"), \"percent\")\n", + "print(f\"Baseline kicker percent for {YEAR}: {kicker_param_baseline(f'{YEAR}-01-01') * 100:.2f}%\")\n", + "print(f\"Reform kicker percent for {YEAR}: {kicker_param_reformed(f'{YEAR}-01-01') * 100:.2f}%\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Household Net Income Impact" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "ename": "MemoryError", + "evalue": "Unable to allocate 2.88 MiB for an array with shape (44451,) and data type 2\u001b[0m reformed_income \u001b[38;5;241m=\u001b[39m \u001b[43mreformed\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhousehold_net_income\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mYEAR\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 4\u001b[0m income_change \u001b[38;5;241m=\u001b[39m reformed_income \u001b[38;5;241m-\u001b[39m baseline_income\n\u001b[0;32m 6\u001b[0m \u001b[38;5;66;03m# MicroSeries already has weights, so just use .sum() directly\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:946\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 944\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[0;32m 945\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mvariables:\n\u001b[1;32m--> 946\u001b[0m values \u001b[38;5;241m=\u001b[39m values \u001b[38;5;241m+\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 947\u001b[0m \u001b[43m \u001b[49m\u001b[43madded_variable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvariable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mentity\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkey\u001b[49m\n\u001b[0;32m 948\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 949\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 950\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:946\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 944\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[0;32m 945\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mvariables:\n\u001b[1;32m--> 946\u001b[0m values \u001b[38;5;241m=\u001b[39m values \u001b[38;5;241m+\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 947\u001b[0m \u001b[43m \u001b[49m\u001b[43madded_variable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvariable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mentity\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkey\u001b[49m\n\u001b[0;32m 948\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 949\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 950\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + " \u001b[1;31m[... skipping similar frames: Simulation._calculate at line 721 (1 times), Microsimulation.calculate at line 54 (1 times), Simulation.calculate at line 491 (1 times)]\u001b[0m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:946\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 944\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[0;32m 945\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mvariables:\n\u001b[1;32m--> 946\u001b[0m values \u001b[38;5;241m=\u001b[39m values \u001b[38;5;241m+\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 947\u001b[0m \u001b[43m \u001b[49m\u001b[43madded_variable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvariable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mentity\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkey\u001b[49m\n\u001b[0;32m 948\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 949\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 950\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\credits\\ctc\\refundable\\refundable_ctc.py:34\u001b[0m, in \u001b[0;36mrefundable_ctc.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 31\u001b[0m maximum_refundable_ctc \u001b[38;5;241m=\u001b[39m min_(maximum_amount, total_ctc)\n\u001b[0;32m 33\u001b[0m phase_in \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mctc_phase_in\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m---> 34\u001b[0m limiting_tax \u001b[38;5;241m=\u001b[39m \u001b[43mtax_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mctc_limiting_tax_liability\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 35\u001b[0m ctc_capped_by_tax \u001b[38;5;241m=\u001b[39m min_(total_ctc, limiting_tax)\n\u001b[0;32m 36\u001b[0m ctc_capped_by_increased_tax \u001b[38;5;241m=\u001b[39m min_(total_ctc, limiting_tax \u001b[38;5;241m+\u001b[39m phase_in)\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmembers(variable_name, period, options))\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 38\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\population.py:142\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate_divide(\n\u001b[0;32m 139\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[0;32m 140\u001b[0m )\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcalculate_kwargs\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\credits\\ctc\\refundable\\ctc_limiting_tax_liability.py:16\u001b[0m, in \u001b[0;36mctc_limiting_tax_liability.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 14\u001b[0m no_salt_branch \u001b[38;5;241m=\u001b[39m simulation\u001b[38;5;241m.\u001b[39mget_branch(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mno_salt\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 15\u001b[0m no_salt_branch\u001b[38;5;241m.\u001b[39mset_input(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msalt_deduction\u001b[39m\u001b[38;5;124m\"\u001b[39m, period, np\u001b[38;5;241m.\u001b[39mzeros(tax_unit\u001b[38;5;241m.\u001b[39mcount))\n\u001b[1;32m---> 16\u001b[0m tax_liability_before_credits \u001b[38;5;241m=\u001b[39m \u001b[43mno_salt_branch\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 17\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mincome_tax_before_credits\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\n\u001b[0;32m 18\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 19\u001b[0m non_refundable_credits \u001b[38;5;241m=\u001b[39m parameters(period)\u001b[38;5;241m.\u001b[39mgov\u001b[38;5;241m.\u001b[39mirs\u001b[38;5;241m.\u001b[39mcredits\u001b[38;5;241m.\u001b[39mnon_refundable\n\u001b[0;32m 20\u001b[0m non_refundable_credits_ex_ctc \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m 21\u001b[0m x \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;129;01min\u001b[39;00m non_refundable_credits \u001b[38;5;28;01mif\u001b[39;00m x \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnon_refundable_ctc\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 22\u001b[0m ]\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:946\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 944\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[0;32m 945\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mvariables:\n\u001b[1;32m--> 946\u001b[0m values \u001b[38;5;241m=\u001b[39m values \u001b[38;5;241m+\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 947\u001b[0m \u001b[43m \u001b[49m\u001b[43madded_variable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvariable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mentity\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkey\u001b[49m\n\u001b[0;32m 948\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 949\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 950\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\tax\\federal_income\\before_credits\\income_tax_main_rates.py:14\u001b[0m, in \u001b[0;36mincome_tax_main_rates.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mformula\u001b[39m(tax_unit, period, parameters):\n\u001b[0;32m 13\u001b[0m \u001b[38;5;66;03m# compute taxable income that is taxed at the main rates\u001b[39;00m\n\u001b[1;32m---> 14\u001b[0m full_taxable_income \u001b[38;5;241m=\u001b[39m \u001b[43mtax_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtaxable_income\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 15\u001b[0m cg_exclusion \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcapital_gains_excluded_from_taxable_income\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[0;32m 16\u001b[0m taxinc \u001b[38;5;241m=\u001b[39m max_(\u001b[38;5;241m0\u001b[39m, full_taxable_income \u001b[38;5;241m-\u001b[39m cg_exclusion)\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmembers(variable_name, period, options))\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 38\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\population.py:142\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate_divide(\n\u001b[0;32m 139\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[0;32m 140\u001b[0m )\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcalculate_kwargs\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\income\\taxable_income\\taxable_income.py:14\u001b[0m, in \u001b[0;36mtaxable_income.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 12\u001b[0m agi \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124madjusted_gross_income\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[0;32m 13\u001b[0m exemptions \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mexemptions\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m---> 14\u001b[0m deductions \u001b[38;5;241m=\u001b[39m \u001b[43mtax_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtaxable_income_deductions\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 15\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m max_(\u001b[38;5;241m0\u001b[39m, agi \u001b[38;5;241m-\u001b[39m exemptions \u001b[38;5;241m-\u001b[39m deductions)\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmembers(variable_name, period, options))\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 38\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\population.py:142\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate_divide(\n\u001b[0;32m 139\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[0;32m 140\u001b[0m )\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcalculate_kwargs\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\income\\taxable_income\\deductions\\taxable_income_deductions.py:12\u001b[0m, in \u001b[0;36mtaxable_income_deductions.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mformula\u001b[39m(tax_unit, period, parameters):\n\u001b[1;32m---> 12\u001b[0m itemizes \u001b[38;5;241m=\u001b[39m \u001b[43mtax_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtax_unit_itemizes\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 13\u001b[0m deductions_if_itemizing \u001b[38;5;241m=\u001b[39m tax_unit(\n\u001b[0;32m 14\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtaxable_income_deductions_if_itemizing\u001b[39m\u001b[38;5;124m\"\u001b[39m, period\n\u001b[0;32m 15\u001b[0m )\n\u001b[0;32m 16\u001b[0m deductions_if_not_itemizing \u001b[38;5;241m=\u001b[39m tax_unit(\n\u001b[0;32m 17\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtaxable_income_deductions_if_not_itemizing\u001b[39m\u001b[38;5;124m\"\u001b[39m, period\n\u001b[0;32m 18\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmembers(variable_name, period, options))\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 38\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\population.py:142\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate_divide(\n\u001b[0;32m 139\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[0;32m 140\u001b[0m )\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcalculate_kwargs\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\income\\taxable_income\\deductions\\tax_unit_itemizes.py:17\u001b[0m, in \u001b[0;36mtax_unit_itemizes.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 14\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m parameters(period)\u001b[38;5;241m.\u001b[39mgov\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mbranch_to_determine_itemization:\n\u001b[0;32m 15\u001b[0m \u001b[38;5;66;03m# determine federal itemization behavior by comparing tax liability\u001b[39;00m\n\u001b[0;32m 16\u001b[0m tax_liability_if_itemizing \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtax_liability_if_itemizing\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m---> 17\u001b[0m tax_liability_if_not_itemizing \u001b[38;5;241m=\u001b[39m \u001b[43mtax_unit\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtax_liability_if_not_itemizing\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\n\u001b[0;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 20\u001b[0m state_standard_deduction \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstate_standard_deduction\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[0;32m 21\u001b[0m state_itemized_deductions \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstate_itemized_deductions\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmembers(variable_name, period, options))\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 38\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\population.py:142\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate_divide(\n\u001b[0;32m 139\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[0;32m 140\u001b[0m )\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcalculate_kwargs\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\income\\taxable_income\\deductions\\tax_liability_if_not_itemizing.py:20\u001b[0m, in \u001b[0;36mtax_liability_if_not_itemizing.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 14\u001b[0m non_itemized_branch \u001b[38;5;241m=\u001b[39m simulation\u001b[38;5;241m.\u001b[39mget_branch(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnot_itemizing\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 15\u001b[0m non_itemized_branch\u001b[38;5;241m.\u001b[39mset_input(\n\u001b[0;32m 16\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtax_unit_itemizes\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 17\u001b[0m period,\n\u001b[0;32m 18\u001b[0m np\u001b[38;5;241m.\u001b[39mzeros((tax_unit\u001b[38;5;241m.\u001b[39mcount,), dtype\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mbool\u001b[39m),\n\u001b[0;32m 19\u001b[0m )\n\u001b[1;32m---> 20\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mnon_itemized_branch\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mincome_tax\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\tax\\federal_income\\income_tax.py:18\u001b[0m, in \u001b[0;36mincome_tax.formula\u001b[1;34m(person, period, parameters)\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;241m0\u001b[39m\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 18\u001b[0m added_components \u001b[38;5;241m=\u001b[39m \u001b[43madd\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[43mperson\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mincome_tax_before_refundable_credits\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 21\u001b[0m subtracted_components \u001b[38;5;241m=\u001b[39m add(\n\u001b[0;32m 22\u001b[0m person, period, [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mincome_tax_refundable_credits\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 23\u001b[0m )\n\u001b[0;32m 24\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m added_components \u001b[38;5;241m-\u001b[39m subtracted_components\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\commons\\formulas.py:232\u001b[0m, in \u001b[0;36madd\u001b[1;34m(entity, period, variables, options)\u001b[0m\n\u001b[0;32m 212\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21madd\u001b[39m(\n\u001b[0;32m 213\u001b[0m entity: Population,\n\u001b[0;32m 214\u001b[0m period: Period,\n\u001b[0;32m 215\u001b[0m variables: List[\u001b[38;5;28mstr\u001b[39m],\n\u001b[0;32m 216\u001b[0m options: List[\u001b[38;5;28mstr\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m 217\u001b[0m ):\n\u001b[0;32m 218\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Sums a list of variables.\u001b[39;00m\n\u001b[0;32m 219\u001b[0m \n\u001b[0;32m 220\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 230\u001b[0m \u001b[38;5;124;03m ArrayLike: The result of the operation.\u001b[39;00m\n\u001b[0;32m 231\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 232\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfor_each_variable\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 233\u001b[0m \u001b[43m \u001b[49m\u001b[43mentity\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvariables\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43magg_func\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43madd\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\n\u001b[0;32m 234\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\commons\\formulas.py:188\u001b[0m, in \u001b[0;36mfor_each_variable\u001b[1;34m(entity, period, variables, agg_func, group_agg_func, options)\u001b[0m\n\u001b[0;32m 186\u001b[0m variable_entity \u001b[38;5;241m=\u001b[39m entity\u001b[38;5;241m.\u001b[39mentity\u001b[38;5;241m.\u001b[39mget_variable(variable)\u001b[38;5;241m.\u001b[39mentity\n\u001b[0;32m 187\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mkey \u001b[38;5;241m==\u001b[39m entity\u001b[38;5;241m.\u001b[39mentity\u001b[38;5;241m.\u001b[39mkey:\n\u001b[1;32m--> 188\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[43mentity\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 189\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mis_person:\n\u001b[0;32m 190\u001b[0m values \u001b[38;5;241m=\u001b[39m group_agg_func(\n\u001b[0;32m 191\u001b[0m entity\u001b[38;5;241m.\u001b[39mmembers(variable, period, options\u001b[38;5;241m=\u001b[39moptions)\n\u001b[0;32m 192\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmembers(variable_name, period, options))\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 38\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\population.py:142\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate_divide(\n\u001b[0;32m 139\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[0;32m 140\u001b[0m )\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcalculate_kwargs\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\tax\\federal_income\\income_tax_before_refundable_credits.py:18\u001b[0m, in \u001b[0;36mincome_tax_before_refundable_credits.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;241m0\u001b[39m\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 18\u001b[0m added_components \u001b[38;5;241m=\u001b[39m \u001b[43madd\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[43mtax_unit\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 21\u001b[0m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\n\u001b[0;32m 22\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mincome_tax_before_credits\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 23\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnet_investment_income_tax\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 24\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrecapture_of_investment_credit\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 25\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43munreported_payroll_tax\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 26\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mqualified_retirement_penalty\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 27\u001b[0m \u001b[43m \u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 28\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 29\u001b[0m subtracted_components \u001b[38;5;241m=\u001b[39m add(\n\u001b[0;32m 30\u001b[0m tax_unit, period, [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mincome_tax_capped_non_refundable_credits\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 31\u001b[0m )\n\u001b[0;32m 32\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m added_components \u001b[38;5;241m-\u001b[39m subtracted_components\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\commons\\formulas.py:232\u001b[0m, in \u001b[0;36madd\u001b[1;34m(entity, period, variables, options)\u001b[0m\n\u001b[0;32m 212\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21madd\u001b[39m(\n\u001b[0;32m 213\u001b[0m entity: Population,\n\u001b[0;32m 214\u001b[0m period: Period,\n\u001b[0;32m 215\u001b[0m variables: List[\u001b[38;5;28mstr\u001b[39m],\n\u001b[0;32m 216\u001b[0m options: List[\u001b[38;5;28mstr\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m 217\u001b[0m ):\n\u001b[0;32m 218\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Sums a list of variables.\u001b[39;00m\n\u001b[0;32m 219\u001b[0m \n\u001b[0;32m 220\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 230\u001b[0m \u001b[38;5;124;03m ArrayLike: The result of the operation.\u001b[39;00m\n\u001b[0;32m 231\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 232\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfor_each_variable\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 233\u001b[0m \u001b[43m \u001b[49m\u001b[43mentity\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvariables\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43magg_func\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43madd\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\n\u001b[0;32m 234\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\commons\\formulas.py:188\u001b[0m, in \u001b[0;36mfor_each_variable\u001b[1;34m(entity, period, variables, agg_func, group_agg_func, options)\u001b[0m\n\u001b[0;32m 186\u001b[0m variable_entity \u001b[38;5;241m=\u001b[39m entity\u001b[38;5;241m.\u001b[39mentity\u001b[38;5;241m.\u001b[39mget_variable(variable)\u001b[38;5;241m.\u001b[39mentity\n\u001b[0;32m 187\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mkey \u001b[38;5;241m==\u001b[39m entity\u001b[38;5;241m.\u001b[39mentity\u001b[38;5;241m.\u001b[39mkey:\n\u001b[1;32m--> 188\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[43mentity\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 189\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mis_person:\n\u001b[0;32m 190\u001b[0m values \u001b[38;5;241m=\u001b[39m group_agg_func(\n\u001b[0;32m 191\u001b[0m entity\u001b[38;5;241m.\u001b[39mmembers(variable, period, options\u001b[38;5;241m=\u001b[39moptions)\n\u001b[0;32m 192\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmembers(variable_name, period, options))\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 38\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\populations\\population.py:142\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[1;34m(self, variable_name, period, options)\u001b[0m\n\u001b[0;32m 138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate_divide(\n\u001b[0;32m 139\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[0;32m 140\u001b[0m )\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msimulation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcalculate_kwargs\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:946\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 944\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[0;32m 945\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mvariables:\n\u001b[1;32m--> 946\u001b[0m values \u001b[38;5;241m=\u001b[39m values \u001b[38;5;241m+\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 947\u001b[0m \u001b[43m \u001b[49m\u001b[43madded_variable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvariable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mentity\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkey\u001b[49m\n\u001b[0;32m 948\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 949\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 950\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m period \u001b[38;5;241m=\u001b[39m get_period(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_calculation_period)\n\u001b[1;32m---> 54\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecode_enums\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:491\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[1;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[0;32m 488\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;28mhash\u001b[39m(variable_name \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(period)) \u001b[38;5;241m%\u001b[39m \u001b[38;5;241m1000000\u001b[39m)\n\u001b[0;32m 490\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 491\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, EnumArray) \u001b[38;5;129;01mand\u001b[39;00m decode_enums:\n\u001b[0;32m 493\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:721\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[1;34m(self, variable_name, period)\u001b[0m\n\u001b[0;32m 719\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_for_cycle(variable\u001b[38;5;241m.\u001b[39mname, period)\n\u001b[1;32m--> 721\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_formula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[0;32m 724\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m array \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 725\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\simulations\\simulation.py:1011\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[1;34m(self, variable, population, period)\u001b[0m\n\u001b[0;32m 1009\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1011\u001b[0m array \u001b[38;5;241m=\u001b[39m \u001b[43mformula\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpopulation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters_at\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[1;32m~\\PolicyEngine\\policyengine-us\\policyengine_us\\variables\\gov\\irs\\tax\\federal_income\\capital_gains\\capital_gains_tax.py:28\u001b[0m, in \u001b[0;36mcapital_gains_tax.formula\u001b[1;34m(tax_unit, period, parameters)\u001b[0m\n\u001b[0;32m 24\u001b[0m income_less_ancg \u001b[38;5;241m=\u001b[39m max_(\u001b[38;5;241m0\u001b[39m, taxable_income \u001b[38;5;241m-\u001b[39m adjusted_net_cg)\n\u001b[0;32m 26\u001b[0m filing_status \u001b[38;5;241m=\u001b[39m tax_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfiling_status\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m---> 28\u001b[0m first_threshold \u001b[38;5;241m=\u001b[39m \u001b[43mcg\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mthresholds\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m1\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m[\u001b[49m\u001b[43mfiling_status\u001b[49m\u001b[43m]\u001b[49m\n\u001b[0;32m 29\u001b[0m second_threshold \u001b[38;5;241m=\u001b[39m cg\u001b[38;5;241m.\u001b[39mthresholds[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m2\u001b[39m\u001b[38;5;124m\"\u001b[39m][filing_status]\n\u001b[0;32m 31\u001b[0m income_ordinarily_under_second_rate \u001b[38;5;241m=\u001b[39m clip(taxable_income, \u001b[38;5;241m0\u001b[39m, first_threshold)\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\parameters\\parameter_node_at_instant.py:62\u001b[0m, in \u001b[0;36mParameterNodeAtInstant.__getitem__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 60\u001b[0m key \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39masarray(key)\n\u001b[0;32m 61\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(key, numpy\u001b[38;5;241m.\u001b[39mndarray):\n\u001b[1;32m---> 62\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mparameters\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mVectorialParameterNodeAtInstant\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbuild_from_node\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 63\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\n\u001b[0;32m 64\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\n\u001b[0;32m 65\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_children[key]\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\policyengine_core\\parameters\\vectorial_parameter_node_at_instant.py:214\u001b[0m, in \u001b[0;36mVectorialParameterNodeAtInstant.__getitem__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 212\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(key, EnumArray):\n\u001b[0;32m 213\u001b[0m enum \u001b[38;5;241m=\u001b[39m key\u001b[38;5;241m.\u001b[39mpossible_values\n\u001b[1;32m--> 214\u001b[0m key \u001b[38;5;241m=\u001b[39m \u001b[43mnumpy\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mselect\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 215\u001b[0m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m==\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mitem\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mindex\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mitem\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43menum\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 216\u001b[0m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mitem\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mitem\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43menum\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 217\u001b[0m \u001b[43m \u001b[49m\u001b[43mdefault\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43munknown\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 218\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 219\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 220\u001b[0m key \u001b[38;5;241m=\u001b[39m key\u001b[38;5;241m.\u001b[39mastype(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstr\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\numpy\\lib\\_function_base_impl.py:907\u001b[0m, in \u001b[0;36mselect\u001b[1;34m(condlist, choicelist, default)\u001b[0m\n\u001b[0;32m 904\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 905\u001b[0m result_shape \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mbroadcast_arrays(condlist[\u001b[38;5;241m0\u001b[39m], choicelist[\u001b[38;5;241m0\u001b[39m])[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39mshape\n\u001b[1;32m--> 907\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfull\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult_shape\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mchoicelist\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 909\u001b[0m \u001b[38;5;66;03m# Use np.copyto to burn each choicelist array onto result, using the\u001b[39;00m\n\u001b[0;32m 910\u001b[0m \u001b[38;5;66;03m# corresponding condlist as a boolean mask. This is done in reverse\u001b[39;00m\n\u001b[0;32m 911\u001b[0m \u001b[38;5;66;03m# order since the first choice should take precedence.\u001b[39;00m\n\u001b[0;32m 912\u001b[0m choicelist \u001b[38;5;241m=\u001b[39m choicelist[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m2\u001b[39m::\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]\n", + "File \u001b[1;32mc:\\Users\\dtsax\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\numpy\\_core\\numeric.py:385\u001b[0m, in \u001b[0;36mfull\u001b[1;34m(shape, fill_value, dtype, order, device, like)\u001b[0m\n\u001b[0;32m 383\u001b[0m fill_value \u001b[38;5;241m=\u001b[39m asarray(fill_value)\n\u001b[0;32m 384\u001b[0m dtype \u001b[38;5;241m=\u001b[39m fill_value\u001b[38;5;241m.\u001b[39mdtype\n\u001b[1;32m--> 385\u001b[0m a \u001b[38;5;241m=\u001b[39m empty(shape, dtype, order, device\u001b[38;5;241m=\u001b[39mdevice)\n\u001b[0;32m 386\u001b[0m multiarray\u001b[38;5;241m.\u001b[39mcopyto(a, fill_value, casting\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124munsafe\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m 387\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m a\n", + "\u001b[1;31mMemoryError\u001b[0m: Unable to allocate 2.88 MiB for an array with shape (44451,) and data type 0\n", + "num_recipients = recipients.sum() # Weighted count\n", + "\n", + "if num_recipients > 0:\n", + " avg_kicker = kicker_credit[recipients].mean()\n", + " print(f\"Average kicker credit (among recipients): ${avg_kicker:.2f}\")\n", + " print(f\"Number of tax units receiving kicker: {num_recipients / 1e6:.2f} million\")\n", + "else:\n", + " print(\"No tax units received the kicker credit in this year.\")\n", + " print(\"This is expected if the kicker percent is 0% for the analysis year.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Distributional Analysis by Income Decile" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DecileTotal Change ($B)Avg Change per HH ($)Households (M)
010.00232012.4026480.187061
120.01079754.7753760.197117
230.01599492.1410320.173586
340.021655129.9348740.166657
450.031404223.1601140.140725
560.045777356.0266670.128577
670.049882490.3472070.101728
780.067396746.7376250.090253
890.1017491154.9691380.088097
9100.7445537101.1225110.104850
\n", + "
" + ], + "text/plain": [ + " Decile Total Change ($B) Avg Change per HH ($) Households (M)\n", + "0 1 0.002320 12.402648 0.187061\n", + "1 2 0.010797 54.775376 0.197117\n", + "2 3 0.015994 92.141032 0.173586\n", + "3 4 0.021655 129.934874 0.166657\n", + "4 5 0.031404 223.160114 0.140725\n", + "5 6 0.045777 356.026667 0.128577\n", + "6 7 0.049882 490.347207 0.101728\n", + "7 8 0.067396 746.737625 0.090253\n", + "8 9 0.101749 1154.969138 0.088097\n", + "9 10 0.744553 7101.122511 0.104850" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Get household-level data for distributional analysis\n", + "income_decile = baseline.calculate(\"household_income_decile\", period=YEAR)\n", + "\n", + "# Calculate change by decile\n", + "decile_data = []\n", + "for decile in range(1, 11):\n", + " mask = income_decile == decile\n", + " decile_change = income_change[mask].sum()\n", + " decile_hh_count = mask.sum() # Weighted count\n", + " avg_change = income_change[mask].mean() if mask.any() else 0\n", + " decile_data.append({\n", + " \"Decile\": decile,\n", + " \"Total Change ($B)\": decile_change / 1e9,\n", + " \"Avg Change per HH ($)\": avg_change,\n", + " \"Households (M)\": decile_hh_count / 1e6\n", + " })\n", + "\n", + "decile_df = pd.DataFrame(decile_data)\n", + "decile_df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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XFKkSCGdOnVyVxsBAAD8woABAyRlypQyZswY6devn1mXNWtWE0d16dLF280DAADwv6TU66+/Lk2aNDH1pBo2bCjlypUzAZYO57t27ZocOHBANm3aJD/99JMphv7ZZ5/FfMsBAAB8TEBAgL3upl6sU5qkAgAAwFMmpdq3by8tWrSQb775RhYvXizTp0+XGzdu2IMvnXWvTp06sm3bNilcuHBkdgkAABCrkYwCAABwU02pxIkTm8SULkqTUnfv3pV06dJJwoQJI7sbAACAWKd06dLmQt2T7Ny50yPtAQAAiNWFznUony4AAABxXePGje2/22w2GT58uHTs2FHSpk3r1XYBAAD4MmbfAwAAiKZBgwY53dZC5127dpW8efN6rU0AAAC+Lp63GwAAAAAAAIC4h6QUAAAAAAAAPI6kFAAAAAAAAPyjptT169fl22+/lWPHjkmvXr1MEU+dTSZTpkySLVs297cSAADAh02cONHp9qNHj2Tu3LmSPn16p/VdunTxcMsAAABiUVLq77//llq1apmZ906ePClBQUEmKbV06VI5ffq0zJ8/P2ZaCgAA4KPGjRvndDtz5syyYMECp3UBAQEkpQAAAKKTlOrevbu0adNGRo0aJSlTprSvr1evnrz11ltR3R0AAIDfO3HihLebAAAAEPtrSm3btk06dOgQZr0O27tw4YK72gUAAAAAAIBYLMpJqcSJE0twcHCY9UeOHJEMGTK4q10AAAAAAACIxaKclGrUqJEMGTJEHj58aK+PoLWk+vTpI02aNImJNgIAAAAAACCuJ6XGjBkjt27dkowZM8rdu3elWrVqkj9/flNf6tNPP42ZVgIAAAAAACBuJ6V01r21a9fKjz/+aKY/7ty5s/z000/y22+/SfLkyWOmlQAAAD7u0aNHZhbiixcvun3fI0aMML3TP/jgA/u6e/fuSadOnSRdunSSIkUK02M99HNrb/b69etLsmTJzAXFXr16mXY62rBhg5QpU8aUaNALjXPnznV7+wEAANwy+56lSpUqZgEAAIBIggQJpGPHjnLw4EG37lcnmfniiy+kRIkSTuu7desmK1eulG+++cZcNNQLha+++qr88ccf5v7Hjx+bhFTmzJll8+bNcv78eWnVqpUkTJhQhg0bZp81ULfRdi9cuFDWrVsnb7/9tmTJkkXq1Knj1uMAAACIdlJKe0e5olfv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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axes = plt.subplots(1, 2, figsize=(12, 5))\n", + "\n", + "# Total change by decile\n", + "axes[0].bar(decile_df[\"Decile\"], decile_df[\"Total Change ($B)\"], color=\"steelblue\")\n", + "axes[0].set_xlabel(\"Income Decile\")\n", + "axes[0].set_ylabel(\"Total Change ($B)\")\n", + "axes[0].set_title(\"Total Income Change by Decile\")\n", + "axes[0].set_xticks(range(1, 11))\n", + "\n", + "# Average change by decile\n", + "axes[1].bar(decile_df[\"Decile\"], decile_df[\"Avg Change per HH ($)\"], color=\"darkgreen\")\n", + "axes[1].set_xlabel(\"Income Decile\")\n", + "axes[1].set_ylabel(\"Average Change per Household ($)\")\n", + "axes[1].set_title(\"Average Income Change by Decile\")\n", + "axes[1].set_xticks(range(1, 11))\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Winners and Losers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Households gaining from kicker credit: 69.2%\n", + "Households losing from kicker credit: 0.0%\n", + "Households unchanged: 30.8%\n", + "\n", + "Average gain among winners: $1119.70\n" + ] + } + ], + "source": [ + "winners = income_change > 1 # Gain more than $1\n", + "losers = income_change < -1 # Lose more than $1\n", + "unchanged = ~winners & ~losers\n", + "\n", + "total_hh = winners.sum() + losers.sum() + unchanged.sum() # Weighted total\n", + "\n", + "print(f\"Households gaining from kicker credit: {winners.sum() / total_hh * 100:.1f}%\")\n", + "print(f\"Households losing from kicker credit: {losers.sum() / total_hh * 100:.1f}%\")\n", + "print(f\"Households unchanged: {unchanged.sum() / total_hh * 100:.1f}%\")\n", + "\n", + "if winners.any():\n", + " print(f\"\\nAverage gain among winners: ${income_change[winners].mean():.2f}\")\n", + "if losers.any():\n", + " print(f\"Average loss among losers: ${income_change[losers].mean():.2f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Poverty Impact" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Baseline poverty rate (no kicker): 42.95%\n", + "Reformed poverty rate (with kicker): 42.80%\n", + "Change in poverty rate: -0.15 pp\n" + ] + } + ], + "source": [ + "baseline_poverty = baseline.calculate(\"in_poverty\", period=YEAR)\n", + "reformed_poverty = reformed.calculate(\"in_poverty\", period=YEAR)\n", + "\n", + "# MicroSeries .mean() gives weighted mean\n", + "baseline_poverty_rate = baseline_poverty.mean() * 100\n", + "reformed_poverty_rate = reformed_poverty.mean() * 100\n", + "\n", + "print(f\"Baseline poverty rate (no kicker): {baseline_poverty_rate:.2f}%\")\n", + "print(f\"Reformed poverty rate (with kicker): {reformed_poverty_rate:.2f}%\")\n", + "print(f\"Change in poverty rate: {reformed_poverty_rate - baseline_poverty_rate:.2f} pp\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"=\" * 50)\n", + "print(\"Oregon Kicker Credit Impact Summary (2024)\")\n", + "print(\"=\" * 50)\n", + "print(f\"\\nApplying 2025 kicker rate ({KICKER_RATE_2025*100:.2f}%) to 2024\")\n", + "print(f\"\\nFiscal Impact:\")\n", + "print(f\" Cost to state revenue: ${-revenue_change / 1e9:.2f} billion\")\n", + "print(f\"\\nDistributional Impact:\")\n", + "print(f\" Total benefit to households: ${total_income_change / 1e9:.2f} billion\")\n", + "print(f\" Share of households benefiting: {winners.sum() / total_hh * 100:.1f}%\")\n", + "print(f\"\\nPoverty Impact:\")\n", + "print(f\" Change in poverty rate: {reformed_poverty_rate - baseline_poverty_rate:.2f} pp\")" + ] + } + ], + "metadata": { + "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.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/or_kicker_credit_analysis_test.ipynb b/or_kicker_credit_analysis_test.ipynb new file mode 100644 index 0000000..f641be5 --- /dev/null +++ b/or_kicker_credit_analysis_test.ipynb @@ -0,0 +1,561 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Oregon Kicker Credit Analysis (2024) - TEST Dataset\n", + "\n", + "This notebook analyzes the impact of applying the 2025 Oregon kicker rate to tax year 2024:\n", + "- **Baseline**: Current law for 2024 (0% kicker rate)\n", + "- **Reform**: 2025 kicker rate (9.86%) applied to 2024\n", + "\n", + "The Oregon kicker is a tax refund provided to taxpayers when state revenues exceed forecasts.\n", + "\n", + "**Note**: Since the kicker is based on prior-year tax liability (`or_tax_before_credits_in_prior_year`), which is an input variable not present in the dataset, we inject current-year tax as a proxy to enable the analysis.\n", + "\n", + "**Dataset:** `hf://policyengine/test/mar/OR.h5`" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from policyengine_us import Microsimulation\n", + "from policyengine_core.reforms import Reform\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup Simulations\n", + "\n", + "The baseline is current law for 2024 (0% kicker), while the reform applies the 2025 kicker rate." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Calculated OR tax before credits for 2024:\n", + " Mean: $6258.89\n", + " Max: $168331344.00\n" + ] + } + ], + "source": [ + "DATASET = \"hf://policyengine/test/mar/OR.h5\"\n", + "YEAR = 2024\n", + "KICKER_RATE_2025 = 0.09863 # 9.86%\n", + "\n", + "# Step 1: Run initial simulation to get current-year tax before credits\n", + "# (used as proxy for prior-year tax)\n", + "initial_sim = Microsimulation(dataset=DATASET)\n", + "tax_before_credits = initial_sim.calculate(\"or_income_tax_before_credits\", period=YEAR)\n", + "\n", + "print(f\"Calculated OR tax before credits for {YEAR}:\")\n", + "print(f\" Mean: ${tax_before_credits.mean():.2f}\")\n", + "print(f\" Max: ${tax_before_credits.max():.2f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Baseline kicker percent for 2024: 0.00%\n", + "Reform kicker percent for 2024: 9.86%\n" + ] + } + ], + "source": [ + "# Step 2: Create simulations with prior-year tax injected\n", + "# Reform that applies the 2025 kicker rate to 2024\n", + "kicker_reform = Reform.from_dict({\n", + " \"gov.states.or.tax.income.credits.kicker.percent\": {\n", + " \"2024-01-01.2100-12-31\": KICKER_RATE_2025\n", + " }\n", + "}, country_id=\"us\")\n", + "\n", + "# Baseline: Current law for 2024 (0% kicker)\n", + "baseline = Microsimulation(dataset=DATASET)\n", + "\n", + "# Reform: 2025 kicker rate (9.86%) applied to 2024\n", + "reformed = Microsimulation(reform=kicker_reform, dataset=DATASET)\n", + "\n", + "# Inject prior-year tax values (using current year as proxy)\n", + "baseline.set_input(\"or_tax_before_credits_in_prior_year\", YEAR, tax_before_credits.values)\n", + "reformed.set_input(\"or_tax_before_credits_in_prior_year\", YEAR, tax_before_credits.values)\n", + "\n", + "# Check the kicker percent parameters\n", + "params_baseline = baseline.tax_benefit_system.parameters\n", + "params_reformed = reformed.tax_benefit_system.parameters\n", + "kicker_param_baseline = getattr(getattr(getattr(getattr(getattr(getattr(params_baseline.gov.states, \"or\"), \"tax\"), \"income\"), \"credits\"), \"kicker\"), \"percent\")\n", + "kicker_param_reformed = getattr(getattr(getattr(getattr(getattr(getattr(params_reformed.gov.states, \"or\"), \"tax\"), \"income\"), \"credits\"), \"kicker\"), \"percent\")\n", + "print(f\"Baseline kicker percent for {YEAR}: {kicker_param_baseline(f'{YEAR}-01-01') * 100:.2f}%\")\n", + "print(f\"Reform kicker percent for {YEAR}: {kicker_param_reformed(f'{YEAR}-01-01') * 100:.2f}%\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Household Net Income Impact" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total change in household net income: $1.53 billion\n" + ] + } + ], + "source": [ + "baseline_income = baseline.calculate(\"household_net_income\", period=YEAR)\n", + "reformed_income = reformed.calculate(\"household_net_income\", period=YEAR)\n", + "\n", + "income_change = reformed_income - baseline_income\n", + "\n", + "# MicroSeries already has weights, so just use .sum() directly\n", + "total_income_change = income_change.sum()\n", + "print(f\"Total change in household net income: ${total_income_change / 1e9:.2f} billion\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Budgetary Impact" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Baseline state income tax revenue (no kicker): $14.50 billion\n", + "Reformed state income tax revenue (current law): $12.97 billion\n", + "Revenue change (cost of kicker credit): $-1.53 billion\n" + ] + } + ], + "source": [ + "baseline_state_tax = baseline.calculate(\"or_income_tax\", period=YEAR)\n", + "reformed_state_tax = reformed.calculate(\"or_income_tax\", period=YEAR)\n", + "\n", + "# MicroSeries already has weights\n", + "baseline_revenue = baseline_state_tax.sum()\n", + "reformed_revenue = reformed_state_tax.sum()\n", + "revenue_change = reformed_revenue - baseline_revenue\n", + "\n", + "print(f\"Baseline state income tax revenue (no kicker): ${baseline_revenue / 1e9:.2f} billion\")\n", + "print(f\"Reformed state income tax revenue (current law): ${reformed_revenue / 1e9:.2f} billion\")\n", + "print(f\"Revenue change (cost of kicker credit): ${revenue_change / 1e9:.2f} billion\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Kicker Credit Amount" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total kicker credit claimed: $1.53 billion\n", + "Average kicker credit (among recipients): $799.00\n", + "Number of tax units receiving kicker: 1.91 million\n" + ] + } + ], + "source": [ + "# Calculate the kicker credit directly\n", + "kicker_credit = reformed.calculate(\"or_kicker\", period=YEAR)\n", + "total_kicker = kicker_credit.sum()\n", + "\n", + "print(f\"Total kicker credit claimed: ${total_kicker / 1e9:.2f} billion\")\n", + "\n", + "# Handle case where there are no recipients\n", + "recipients = kicker_credit > 0\n", + "num_recipients = recipients.sum() # Weighted count\n", + "\n", + "if num_recipients > 0:\n", + " avg_kicker = kicker_credit[recipients].mean()\n", + " print(f\"Average kicker credit (among recipients): ${avg_kicker:.2f}\")\n", + " print(f\"Number of tax units receiving kicker: {num_recipients / 1e6:.2f} million\")\n", + "else:\n", + " print(\"No tax units received the kicker credit in this year.\")\n", + " print(\"This is expected if the kicker percent is 0% for the analysis year.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Distributional Analysis by Income Decile" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DecileTotal Change ($B)Avg Change per HH ($)Households (M)
010.00451426.1496840.172614
120.01791983.9196780.213530
230.032382182.1211310.177803
340.045437263.5297390.172416
450.061947389.9966970.158839
560.083110552.9044960.150315
670.103007722.5210960.142566
780.1396811015.7776770.137511
890.1836021448.3781420.126764
9100.8280066017.1034330.137609
\n", + "
" + ], + "text/plain": [ + " Decile Total Change ($B) Avg Change per HH ($) Households (M)\n", + "0 1 0.004514 26.149684 0.172614\n", + "1 2 0.017919 83.919678 0.213530\n", + "2 3 0.032382 182.121131 0.177803\n", + "3 4 0.045437 263.529739 0.172416\n", + "4 5 0.061947 389.996697 0.158839\n", + "5 6 0.083110 552.904496 0.150315\n", + "6 7 0.103007 722.521096 0.142566\n", + "7 8 0.139681 1015.777677 0.137511\n", + "8 9 0.183602 1448.378142 0.126764\n", + "9 10 0.828006 6017.103433 0.137609" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Get household-level data for distributional analysis\n", + "income_decile = baseline.calculate(\"household_income_decile\", period=YEAR)\n", + "\n", + "# Calculate change by decile\n", + "decile_data = []\n", + "for decile in range(1, 11):\n", + " mask = income_decile == decile\n", + " decile_change = income_change[mask].sum()\n", + " decile_hh_count = mask.sum() # Weighted count\n", + " avg_change = income_change[mask].mean() if mask.any() else 0\n", + " decile_data.append({\n", + " \"Decile\": decile,\n", + " \"Total Change ($B)\": decile_change / 1e9,\n", + " \"Avg Change per HH ($)\": avg_change,\n", + " \"Households (M)\": decile_hh_count / 1e6\n", + " })\n", + "\n", + "decile_df = pd.DataFrame(decile_data)\n", + "decile_df" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAHqCAYAAADVi/1VAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAgPRJREFUeJzt3Qm8jOX///HPsW/ZskuWkiXZI1qkRCWlVJQiSRQla6kQCilCKVFoj0obRRKVKCElWbIUZc++b/N/vK/f/57vnHPmHGed5ZzX8/G4nTP33HPPdc+Mua/zuT/X54rx+Xw+AwAAAAAAAEIoSyifDAAAAAAAABCCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSQBDz58+3mJgY9xNp75577rF8+fJZRvbUU0+5z9CuXbssMxxnoHLlyrn3OC2dPn3aqlWrZs8884xFk//++8/y5s1rX3zxRbibAgBAPH/99Zc7jz///POWkekYu3XrZhmdjlN9M8+UKVPcOr3PaWnatGlWuHBhO3jwoEWTxx57zOrXrx/uZiAOglKIGPrCTMqSlEDR0KFD7ZNPPkn3Nntf9EuWLEn354oGR48etRdeeMF92RcoUMBy5cplF1xwgesErF27NtzNy5CuvPJK//+NLFmyWP78+a1SpUp2991325w5cyyjeO+992zz5s3+DmVyvi+8DndCy/Dhw2MFv9588033GVZn66yzznKf4Xbt2tmPP/7oD7ol5bn1/XD22WfbfffdZ/379w/bawcgY3n55Zfddwx/WMWn7+cbbrgh3M2IGMuXL7e77rrLypQpYzlz5nTntSZNmtjkyZPt1KlT4W5ehr2o7S16zYsXL+76avrbZOfOnZYR6LMzcOBAe+ihh9xFZu8C5ZkWvQ6iC5cJbaO/HQKpD9ehQwc777zz3H0lSpSwK664wj1/4N9iZ1r03SCPPPKI/frrr/bZZ5+F4ZVDQrIleA8QYm+99Vas2/rDUH9Ux11fpUqVM+5LX/y33nqrtWzZMs3bieCUEXTttdfa0qVLXYfwzjvvdCeqNWvW2Pvvv28TJkyw48ePh7uZGdI555xjw4YNc78fOnTI1q1bZ9OnT7e3337bbr/9dvcze/bs6fLcTz75pLvqlN6ee+45a9OmjQt2Jvf74siRI+73O+64w66//vp4+65Vq5b/94cfftjGjRtnN910k7Vt29ayZcvmPsNffvmlVahQwS655BIbPXp0rCuDyoJS0EwB2SJFivjXN2zY0P3s0qWLjR071r755hu76qqr0uw1AZA5vfPOO+4PrMWLF7vv+/PPPz/cTUIEeu2119z5R0ERXaiqWLGiHThwwObOnWsdO3a0rVu32uOPPx7uZmZI6ktcfPHFLnijQNTChQtdEGXUqFEuwyg9+wLq86jvkp4+//xz1ze6//773e1bbrkl1veQ+kgPPPCA3Xzzze4+jz6LHgXs9BmNK2vWrP7f9f2m1zF37tx27733uu89fW6XLVtmzz77rA0aNMgFqOL2/XQxsF69ev72iTdCQ0Et9fGUGXjjjTem2WuCVPIBEapr166+lH5E8+bN62vfvn2Kn3vevHnuufUzMZMnT3bb/fzzz77Mrnnz5r4sWbL4Pvzww3j3HT161NerVy//bb03eo8ysoEDB7rPxs6dO9P1eRo1auS78MIL460/efKk78EHH3Rt6Nu3ry+UypYtm6r/f3EtW7bMHcfXX3+dou+LjRs3uvuee+65RJ9n27ZtvpiYGF+nTp3i3Xf69Gnf9u3bgz5O+9X+9TwJqVatmu/uu+9O9PkB4Ew2bNjgvm+mT5/uK1q0qO+pp54KeRtOnTrlO3LkiC8S6fyj/khmt2jRIl/WrFl9l112mW///v3x7le/VX3Y5Jwjo52OUX2F9OT9/fDBBx/Eu2/58uW+YsWK+QoWLOjbsmWLL1S8v1US66Mk14033ug+WwlR31fPqb5wMEn9O0D92GzZsvn++uuvePcl1CdLyt+B+ltF/b3169efsQ0IDYbvIaooC6RXr17+NGQNU1Kk+//ONf9HKZra7o033vCnbHr1bf7++2978MEH3eMUddfQmttuuy1Nx1l79ZL+/fdfl6ml34sWLWq9e/eOlyqtoUJjxoyxiy66yKWkajtlGwUOBzx58qQNGTLEpa3qmHWVQFe2jh07FjRlXanDdevWdcen/XrDHZU54z1PnTp17JdffonX9tWrV7sMM6V3azvtJynprT/99JPNnDnTXXlr1apVvPvV7mC1CpLyGulxyjjRe6VjUts//PDDBGsFaNimag/pOS+88EKbNWtWvG2910jHqNf11VdfDVobSZRlpOfUc+t1UbaOhpElJ4NM2UoaVqdj6N69uxvm6GnUqJHVqFEj6GP1OW3WrJmlhK40KTunatWq9tJLL9m+fftSdFx6b5VdVKhQIVcbqXr16u4z60nodYtr7969LmXa+7+rK2q6yqX/A2ei9zRHjhzualh62rhxo/suufTSS+Pdp2MsVqxYivd9zTXXuCuLgd9VAJCSLCl9Hzdv3tydr3Xbc+LECfd9rqEuce3fv9+d83Se9agfoewNfR/re1nfz3379o3Xv/DOr3ounVe1rXduTeo5Wtkbyh5RNqmGRStDQX2AuPVvROuVFaGsCu9cPmnSpFTXS1LGtteXUvbFzz//HLQfpHO2+iQ6Hp2Hn3jiiVjbqP903XXXufO6+i9XX321f3i3xxtStGDBAnfc2l/BggWtc+fOLmtc50QNC9d7qUWve9zzg86PyszV8eu90+uhx+/Zs+eMx60MEj2/3jO93nGpDxSs9uOZXqPffvvNPU6Zw95QKr1Xqp8YyOsbKNNF2+vYlemsz+bhw4fD+tnQa6L31esPf/fdd/775s2b5573448/jve4d9991923aNEiSwn19fR+6r1Xvywlx6X+o14TlRVQ+0uWLOkykdavX+/fJtjrFowywC+//HLXt9Prru+UlStXnvFxaoP+/2sYaHrTcWk0QNmyZePdl5o+mdf2Tz/9NFXtQ9ohKIWooZO1TlQaIqPAjVJgdVLp06eP9ezZ07+dUjj1ha4vWv2uRSdx0clVKbT6A1x/sCutWWnMGuMc9ySZGgqsKJigTpo6Qgo8jBw50p3sAymI4/2hrj/QNQxKJ5nAzo1SUAcMGGC1a9d2x659aaiWjiEunfw1bK5FixZuG3Vc9LtOwD169HB1BdRR0Ze8Ol2BAQGdiDQ0adWqVa4daq9OVAoaBTs5B/ICV0oPT+vXSAEQDa8aPHiwG5aplGQFEhUEi0udPwUd9dqMGDHCnTgVJAvsLKkzqc+P1um10HugfQerQaai2uo0KuVdnze9V/q8KDiiTkVS6HVWO/R+KLijz11gOrFeM3Xyfv/991iP02dVdbj0nqWUAlMasqbPtl6b5B6XhsNp3R9//OGCaXp/GjdubDNmzEhWO/T8en8VCNPz6jVQ4Kdfv36x/u8mRP9nFWhM7RBEtUNBwriLAr/idXo++OCDNP0+EHV89dompcMHAAnR+Vx/hCpQr+/3P//80x840HekhsvofBZ3uLzWKdjk9R10/lefSudf9RNefPFFd75XP6N169bxnlfDj9WP0H06L3v1WZJ6jlZgQs+h86D6Owr46I/guLZv3+76Il9//bULhGn/CprpXK0/6FNKAQUNA1d/8Omnn3bBKr2OCuR5dC5WnS4da6dOndxz6zXRBQWPvsPVv1RNGgWSVC9QFzTUj9RFnLhUc0fvkfober3Vx9Fj9JqrH6TX7LLLLnNtizsESW1VH1fnS7VFAR29/+o7BbY7Lp2/vHP6ueeem6avkfoFGzZscG3R+6nPk0o06H0NdtFFfSANGVQfSL8rWKfXIlyfjW+//db1edS30mdWfUH1Cb0+mN5H9ckDg70erVPArkGDBpZSCiTr+L766qtkH5c+L7r4rNdPfQr1ydQ300XHuH3IM9FnTa+xgqp6zfWZVF9Pn8UzXahXmQ59v+jvktQK1idTAN2jfpkumOr/ZFpSgFTv5Q8//JCm+0UqhCgjC0i2uMNxPvnkE3f76aefjrXdrbfe6lIw161bd8a0zcOHDwdNcdZ+33zzzTQZvqfn1brBgwfH2rZWrVq+OnXq+G9/8803bruHH3446FAhL9VX29x3332x7u/du7dbr30Epqxr3cKFC/3rZs+e7dblzp3b9/fff/vXv/rqq/GO7+qrr/ZddNFFbqhdYDsaNmzoq1ixYqKvw8033+z2t2fPHl9SJPU1CvaeHT9+3A2Fuuqqq2Kt1/5y5MgR63Pw66+/uvUvvviif12LFi18efLk8f3777/+dX/++adLDw78vClVWKnvzzzzTKznWbFihds27vqEhu8pxTmQN6RObZO9e/f6cuXK5Xv00UdjbafPhT7HBw8eTNHwPc/HH3/snm/MmDHJOi4N/ytfvrz7XMV9X73PZ+BxJjZ8b8iQIe5Y1q5dG2u7xx57zLVl06ZNiR7jOeec42vVqlWi2yRl+F5Ci74DPO3atXPrChUq5D7Xzz//vG/VqlWJPndShu/p/6W2mTp1aqL7AoCELFmyxH2PzJkzx/9drO/H7t27xzvvf/7557Eee/311/sqVKjgv/3WW2+5Iffff/99rO3Gjx/vHv/DDz/41+m2tl25cmW8NiXlHL106VK3j0ceeSTWtvfcc0+8IT4dO3b0lSxZ0rdr165Y27Zp08ZXoECBoP24xIbved//Z599tm/37t3+9Z9++mm81+mKK67wnXXWWbH6S3HPeS1btnR9jcBhPxqKpcfp8XH7h82aNYv1+AYNGrg+a5cuXfzrdL7V+6jzuUfvix7/zjvvxGrLrFmzgq4P5PV9Aj8XiUnOaxTs9X/vvffcdt999128vsG9994ba1udV/U84fhseOd8/T/y6L1WH0zt8vTr18+XM2dO1z/z7Nixw/WREhqOlpThe54aNWq4PkZyj2vSpElu36NGjYq3z8DPWNzXLe7wvQMHDrghhHFLFaiEgZ4vWAmDQK+99prbn/qNqRm+l1CfTP9nPL///rv7G0bra9as6T7T+nvw0KFDqS7j0rRpU1+VKlUS3QahQ6YUooaKCSvzQym+gTScT9/BSkM9E12d8OjKj66Q6GqE0opVNC8tKQsrkK6s6eqS56OPPnIptt7sEYG84VDeNPJxs0l0zBL3SqSGagVewfFm5lFBxcCrZd56rz27d+92VyG8K1re1Qq9Proip6t8Si1OiHdVI1iKeGpeo7jvmTK/dEVI2wV7v5SOqysfHg01U3q9t09dZdKVKF35LFWqlH87fQaUih9Iwx11JVmvSeAVHKWqK8NIKd5J0bVr13hXTQPfW12tUcFFFcr2rjKqnVOnTnXtVLZaaniFHfW+Jue4lFGmq7+6oqj/H4GSMlwvkDKP9J5piELgc+r90rEGps4Ho8+hHptaylDTVd64i/7feDQjkdLqy5cv7zIENdRFxdI1PCOx/wNn4rVfxw0AKaFMDQ3vUcaq912szCVlqnhD33W+1zAonUMCz536rgvMgNL3sr7bKleuHOt72SvAHPccp2zXwO/K5JyjvaF+ymQOdj706ByovpGyiPR7YLvUF9G+U9pX07EHnkfURvH6BypGrXORhlDFzS7yznl6jZXhonOzhq95NIRKWerKSA7M8hBluwSeM9X/0rFpvUd9Ww2nC+z/6P1R/0BDvwNfB2XI6LyeWB8kpX2yM71Gcd9vZYGrTcrykWDvTbB+ns7pXhtD/dlQH1mvoUfvtfpgs2fP9v8fUka3sgoDh6Hq/5OyqlOTve7R++f1yZJzXNpO/7fjvjbJ7Zfpu0CZ28q0DHw+fQ71+TxT/9YbfZDafplGhgTrkwXOiKxhjN4Mksrg8rIX9T04ceLEVD2/1ydFZGD2PUQN1YNSICHuSdabjU/3n4nGrSuFWH946g/MwFTjuDV3UsOrDxX3yy+wDoCG0Ol4VP8hITqmLFmyxJtZRwEEBQriHnPcjpQ3U5lSkYOt99qjYX96LZS+m9DU9Tt27LDSpUsHvU+BH9FJNm4AIzWvkWiomNLIdVIKrHMR7AQcLE09cJ86Bn0Ggs1UFHedAnF6TRSoCSapQ8niPl5BM72ngenR6gCpw/P999+7dHsFzpTOnZzhkAnxZonz/t8k9bi8+gQaNpdaek4Ni4j7fnv0vpxJWtRi0jGfqQaC3hsFErWo46XU7vHjx7ugt4Yp6D1KCa/9yQ3oAYDoD2YFnxSQ0gUDj/6I1DAeDddq2rSpGz6nYesaiqVzpsoZ6GKELsQFBqX0vazh+kn9XlagPpiknKO9vkzcfcQ97yowpD+WNcQt7lD+hNqVVHH7B94f1F7/wAu8JHbOU/s0NE6lI+JSX1QXfDTUSH9Ip6RfFtj/0fujfmlCdXMSex0C+2Rp+Rp5FzE1fEyfxbhtCNaPTmyfameoPxvB+j6qz6T3Vc+h/rUCtaqnpSCwFzzU7wq+pcVMl+qXeX2y5ByX+mX67KV2Zj19tiShGQC9z09698sUBEtKXSq9PxpuqO9ADTHUd45KdOhCoz43Ka1tpfbTJ4scBKWQqejqggJSyv7Q1RJ1AvSFpD82k1JwOakCpzNNC0n90kzoeRNa751QvGNXVkhChbUTOxHrBC4rVqzwX1lLaVsDKQCgGgwK1Lz88svuaqSCJnoP1eFO6j5TcuLUa6LXXcGIYPv1MpDS4r3Ua66rPqq5pGPVT3WM0qKIpFdnwHv/0uu4EqPn1NVe1d9IqMORGNUdS0ph17Sm59XnT4vqTKgWhTrQwQpunonXfl3lBIDkUjazpkJXMEBLXPqjWUEpUZ9GE3joe15ZBZqCXufpwEk19L2syU9UVzCYuEGTwAyZlJ6jz8Triygron379kG3UQZ0SqRl/yAtnjfY+sC26LVQQCpYbSNJKJjone8VuFCfLC3aGtguZVmrzqNqXdWsWdP1GdRW1WUK1o9Oq9c9PT8bwehioeo1/fPPPy7YqlqvcYuTp4SCw6oX6gU/Q31cgc+pQI/6mnGdKeilvpHXr1ER8lDRZ0nfWVr0N5wC9Pr/kdK+stpPnyxyEJRC1NAfgsog0ZWfwGwpzZTi3X+mII5ScfWlr6uKgenHSS1anZaUMaN0YV11SihbSsekk4euangZYaIsGrU5JX8cB+OloaszmZIvd6+wuoIpSQ1KJYVSlZVRpddJV3s96vCmhDp42p8yw+KKu07vjzpNugpzpqBJYvTeBV4B1PPoPfWKxHonWqX+qwCoCk6qIK2KrKY2uKmrSvrDIE+ePK54ZXKOyxsGqaBWaoNj2peuDKZ0P/pjKjAzIBw0tEJBKf1RmJL/d177A/8fA0BS6Y8vncPGjRsX7z5lQmm4sbI6FTxSkEgBImXg6rtfAa24M8jpe1nFujU0OaXZAkk9R3t9GX0PBmaqxD3vKtCi/p3OXaGY2StYPyixgtFqn86na9asiXef+qLK+IkbzEspvT/q86rIebCAYGLURmXB6H1X5lZatUl/xCsjT5lSmoAnbuZNSoT6sxGsrQoS6TULDPQpsKvSGSqtoAx79Y+DTQCQXPo7RPvzLgAn57j0mVAxfQW2UjPxi9e/0/dJSl5L70K03jMFiMLVJxP1yVJK7U9o9muEHjWlEDU0K4e+tONeqdBMMepQBdYEUh2eYIEm/ZEf9+qMZvzwxpGHktLr1Za4s5CI10Yds8SdVcS7shlsdpKU0IlJmSC6shrsC17pxYnRFQtdJXvttdeCzmKnWToCp6FOKr1fem8D3x8Newv2HEndn07AevyWLVtidX7i1iTTjDPaXu9P3M+Mbsed/jghcf+A0OdN4taw0lA9dfg0640COKmtW6DXTPXXNDxDP7107KQel2ZVUeDKm7447nbJoSurmkJZf7jEpX17s98l9vnSHwpxpylPa9u2bXOp4cE+v+qIBxtKm1SarUaZmYHDOgAgKfRHrAJPmnlLs3fFXTRjly7YeTPh6rtK6zVrnLIh9B0b9w9qfS+rjEGwuix6vkOHDqXZOdr7A1zZVMHOh4H7U99Iwa5gwaEz9UVSQ8EBBfMmTZpkmzZtCnrOU/uUjaZp5AOH4OtCoS4AKQCY1KFPZ6L3R6/rkCFD4t2n9/NMF1NVr1TtVt/CG8Yf95z0xhtvJKtN3oWyuH2A1MyKGOrPhvoigbWnFLTT+6n3NfBCoDJo1E/TxVYFhNXHTW1WjYLAGqmhIYxevdHkHJe2Uw2kYBlbyemX6TXX51QzPwabxfFMr6Vqcmn2zyVLllh6UzZmsDZ6dVmDDaVNCg011XDIhg0bprqNSBtkSiFqKBtHqZq62qfOgKLbKjipk4m+5AMLXOsLU1eYFLxR3Sb9ca26C+rQqYOmPw5VsFMnJ23npaKGko5FnYWxY8e6Kzde6rO+gHWfOpk6RmV2aZy5OiAqNLp48WLXkVBKvlfsNC0oeKIOla56KEtHVw3V0dJrpPRlnUwT8+abb7qTuoIeeq909VXBQR2bhhoo2KWpp5NDQTe9h3ptlEmkcfVqpwIDqlGUEk899ZT73Ojq4wMPPOAPdCqVWjUxPPo8qU5Gv3793OdNr7euZunKiq5Iayx7UgJt2l7DG3QMei3VwdGxxL06oym11Qav+GxyptrVyVX7FdVFUJBNf8DohKurfYGd2qQel/6oeeWVV9x7qRR9Tf+sK++6GqwpsYMFmBKiNH/9saT/f5r6Wf8/9QePhhboqqHakVhnT0VIdQzKVPKGp6SEOqLe6xTIm+JZn/N69eq5K8z6/CqtXZ85XSn1OpMp7ZSqeKdeS+oXAEgufX8q6KRzSTCqdaOgiv549oJP+qk/7BWc0Hk9bpam+h8a1qdC1CpsrHOizof6jtd6fcd72QipPUfrO19/UCt4oQsfaq++z5WhIoHfiypyrPaoz6a+iPpqyijX97f6a/o9vag/pn6Qzr9evRqdnzSpjNc/0PlT3+faTsW5NdRJF/R00UR1btKK+nu6SKUsdD23zn3KjlGfSv0EFXxW4DEh+mNb74XaqMwWvd/KRNLnaP78+e4zpWNJDgUyFLjTcSpQoDqj6k+lJpM51J8N9bMUlNHFOmX3ecGwYBeINYTPe42DBQcTo768RmLo/5RXn1Kvuf7+UF8rcNhcUo9L7VFfWxlc+ltAIxPUl9I2ep/VV0rq+6j+nT4T+qyrn6jvDwVj9VnXd0FiQxWVHanPo5538ODBllIKrgbrk8nNN9/s/obQ6AEFUPW3hTeMUa+LXgeNMlG/LCXUdgXykvqaIQRCONMfkCzBpnjXNKY9evTwlSpVypc9e3ZfxYoV3XTsgVOhyurVq93UvN40ot60oJravkOHDr4iRYr48uXL56Yd1bZxp7D3pnTVz8R406z+/PPP/nXaj6YijcubHjeQpgFW+ytXruymGC5atKjvuuuuc1Pkek6cOOEbNGiQr3z58u6Yy5Qp46arPXr0aKLTIHv0nHotg03/q+cOpCmO27Vr5ytRooR7rtKlS/tuuOEG34cffuhLCk1b+/zzz/suvvhi9/rqmPQePfTQQ75169al6DV6/fXX3T40Pa9eJ73mwbYLdpze6xJ3Wti5c+f6atWq5dp33nnnuelte/Xq5aYFjuujjz7yXXbZZa69WtQGPc+aNWsSfS28Nv7xxx++W2+91U0XrSmAu3Xr5jty5EjQx4wYMcI9ZujQob6k0hTSgVPp6nXX63XXXXf5vvrqqwQfl9TjWrBgge+aa65x7dd21atX97344ovxjvNMr7n+7+pze/7557vXXf8HGzZs6D4vmkL8TPS8mjY5Od8XcT/vCS1eW/fv3+8bM2aM+17Q9Nz6P6Dj1hTeEydOjPc949H/o8DpluNatWqVu//rr78+43ECQFwtWrRw56fEpkG/55573HeWN628vq/UX9B3z9NPPx30MfruffbZZ30XXnihO8fqHFWnTh3X59i3b98Zz6/JOUer7dpH4cKF3XmqZcuW7nyj7YYPHx5r2+3bt7tt1X4dk/okV199tW/ChAlnfK3i9oUS6u94xxV3ynpNQX/zzTf7ChYs6F7zSpUq+fr37x9rm2XLlrnzhI4jT548vsaNG/sWLlx4xv6heK/Nzp07Y61PqF+kY9Z7ov6szkcXXXSRr2/fvr4tW7b4kkL9yTvvvNPfb9Z7rNfyjTfe8J06dSrZr9E///zjf30KFCjgu+2221xb4m6X0HF6r0vg+TJUnw3vc/z222/7P7PqCybU1z927Jh7vXScCfXb4vL+fvAWtVF9e/1N8swzz/h27NgR9HFJPS71s5944gn/3wTaTn1M9d8DjzPwvQj2mntt1edYx6fPuvrD+h5ZsmTJGY9z+vTpvpiYGN+mTZuC3q/3Pdj/r8DPe2L9Mq+tP/zwg3tdqlWr5tqpYz733HNdOwOPOS79X4rbDw3UunVr1wdG5IjRP6EIfgFAJFPGkDKAUlMbIbV05bNHjx7uymywmQQzM2U4Kt1dV/KSOsNjpNCVPE01rqt9ZEoBwP9RBpCyhJUt0bZt23A3BxEkEj4byuTRaAtlOb/++uthaUOkUgaYMro0zDS5WWThplINyoLUKA4ypSIHNaUAZDqqlxFIgSiNT1ddrXDR9QF1epSyT0AqPnVK9boEK/IbyZS2r1prGiZBQApAZhX3vCsasqWh4hoShswrUj8bqo2m+koaNofYVAtLQ/fUJwtWsyyS6bOlIc0EpCILmVIAMh3VRlJtI9XN+vvvv93YetWD+OWXX2LN/hIKqgegOgOqJ6CCs6qRllDdEAAAopFq9ihbVLUwVYdJk4toUe0m1WRC5hVpnw3NcKeaaMoAUh3JwMLoANIHQSkAmY6KdisIpBReFbpUkWvNQpKc4uJpRUP1lEasIWkqVPnMM8+EvA0AAKQnFQdX8EEznCqzQpmvKrSsyWsUiEDmFWmfDV201LBBTfIyZcoUVxwdQPoiKAUAAAAAAICQo6YUAAAAAAAAQo6gFAAAAAAAAEIu0w3iPn36tG3ZssXOOussZkICAACOqhkcOHDATQGuWZ+QdPStAABASvtWmS4opU5TmTJlwt0MAAAQgTZv3mznnHNOuJsRVehbAQCAlPatMl1QSlfxvBcmf/784W4OAACIAPv373eBFa+fgKSjbwUAAFLat8p0QSkvrVydJjpOAAAgEMPPko++FQAASGnfiqIJAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAABHo33//tbvuusvOPvtsy507t1100UW2ZMkS//0+n88GDBhgJUuWdPc3adLE/vzzz1j72L17t7Vt29by589vBQsWtI4dO9rBgwdjbfPbb7/Z5Zdfbrly5bIyZcrYiBEjQnaMAAAgcyMoBQAAEGH27Nljl156qWXPnt2+/PJL++OPP2zkyJFWqFAh/zYKHo0dO9bGjx9vP/30k+XNm9eaNWtmR48e9W+jgNTKlSttzpw5NmPGDPvuu+/s/vvv99+/f/9+a9q0qZUtW9aWLl1qzz33nD311FM2YcKEkB8zAADIfGJ8usyWiajzVaBAAdu3b5+7aggAABBp/YPHHnvMfvjhB/v++++D3q/uW6lSpaxXr17Wu3dvt05tL168uE2ZMsXatGljq1atsqpVq9rPP/9sdevWddvMmjXLrr/+evvnn3/c41955RV74oknbNu2bZYjRw7/c3/yySe2evXqqHztAABA+CW1f0CmFAAAQIT57LPPXCDptttus2LFilmtWrVs4sSJ/vs3btzoAkkasudRx69+/fq2aNEid1s/NWTPC0iJts+SJYvLrPK2ueKKK/wBKVG21Zo1a1y2FgAAQHrKlq57BwAAUafZkJkWiWb3b26ZxYYNG1wWU8+ePe3xxx932U4PP/ywCx61b9/eBaREmVGBdNu7Tz8V0AqULVs2K1y4cKxtypcvH28f3n2BwwU9x44dc0vglVAAAJCwmE4xFol8E8M/cI6gFAAAQIQ5ffq0y3AaOnSou61Mqd9//93Vj1JQKpyGDRtmgwYNCmsbAABAxsDwPQAAgAijGfVUDypQlSpVbNOmTe73EiVKuJ/bt2+PtY1ue/fp544dO2Ldf/LkSTcjX+A2wfYR+Bxx9evXz9WH8JbNmzen8mgBAEBmRVAKAAAgwmjmPdV1CrR27Vo3S55oyJ2CRnPnzo01jE61oho0aOBu6+fevXvdrHqeb775xmVhqfaUt41m5Dtx4oR/G83UV6lSpaBD9yRnzpyuYGngAgAAkBIEpQAAACJMjx497Mcff3TD99atW2fvvvuuTZgwwbp27eruj4mJsUceecSefvppVxR9xYoV1q5dOzejXsuWLf2ZVddee6116tTJFi9e7Gbz69atm5uZT9vJnXfe6epUdezY0VauXGlTp061MWPGuFpWAAAA6Y2aUgAAABHm4osvto8//tgNlRs8eLDLjBo9erS1bdvWv03fvn3t0KFDdv/997uMqMsuu8xmzZpluXLl8m/zzjvvuEDU1Vdf7Wbda9WqlY0dOzbWjH1fffWVC3bVqVPHihQpYgMGDHD7BAAASG8xPp8v/OXWQ0ip7eqAqQYC6eYAAMSXGWffo3+Qcrx2AAAkLjPOvrc/if0Dhu8BAAAAAAAg5MIelBo3bpyVK1fOpZqr6KZqHiRGqesqvpk7d24rU6aMq7lw9OjRkLUXAAAAAAAAUR6UUjFNFdIcOHCgLVu2zGrUqGHNmjWLN32xR0U+H3vsMbf9qlWr7PXXX3f7ePzxx0PedgAAAAAAAERpUGrUqFFuRpgOHTpY1apVbfz48ZYnTx6bNGlS0O0XLlzopkjWTDHKrmratKndcccdZ8yuAgAAAAAAQGQJW1Dq+PHjtnTpUmvSpMn/GpMli7u9aNGioI9p2LChe4wXhNqwYYN98cUXdv3114es3QAAAAAAAEi9bBYmu3btslOnTlnx4sVjrdft1atXB32MMqT0OE15rEkDT548aV26dEl0+N6xY8fcElgBHgAAAAAAAJm80HlyzJ8/34YOHWovv/yyq0E1ffp0mzlzpg0ZMiTBxwwbNsxNQ+gtKo4OAAAAAACATJopVaRIEcuaNatt37491nrdLlGiRNDH9O/f3+6++26777773O2LLrrIDh06ZPfff7898cQTbvhfXP369XPF1AMzpQhMAQAAAAAAZNJMqRw5clidOnVs7ty5/nWnT592txs0aBD0MYcPH44XeFJgSzScL5icOXNa/vz5Yy0AAAAAAADIpJlSogym9u3bW926da1evXo2evRol/mk2fikXbt2Vrp0aTcET1q0aOFm7KtVq5bVr1/f1q1b57KntN4LTgEAAAAAACDyhTUo1bp1a9u5c6cNGDDAtm3bZjVr1rRZs2b5i59v2rQpVmbUk08+aTExMe7nv//+a0WLFnUBqWeeeSaMRwEAAAAAAIDkivElNO4tg1JNKRU837dvH0P5AAAIotmQmRaJZvdvnm77pn+Qcrx2AAAkLqZTjEUi30Rf2PsHUTX7HgAAAAAAADIGglIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAAyJxBqXHjxlm5cuUsV65cVr9+fVu8eHGC21555ZUWExMTb2nevHlI2wwAAAAAAIAoDkpNnTrVevbsaQMHDrRly5ZZjRo1rFmzZrZjx46g20+fPt22bt3qX37//XfLmjWr3XbbbSFvOwAAAAAAAKI0KDVq1Cjr1KmTdejQwapWrWrjx4+3PHny2KRJk4JuX7hwYStRooR/mTNnjtueoBQAAAAAAED0CGtQ6vjx47Z06VJr0qTJ/xqUJYu7vWjRoiTt4/XXX7c2bdpY3rx5g95/7Ngx279/f6wFAAAAAAAAmTgotWvXLjt16pQVL1481nrd3rZt2xkfr9pTGr533333JbjNsGHDrECBAv6lTJkyadJ2AAAAAAAARPHwvdRQltRFF11k9erVS3Cbfv362b59+/zL5s2bQ9pGAACAlHjqqafiTexSuXJl//1Hjx61rl272tlnn2358uWzVq1a2fbt22PtY9OmTW4yGJU6KFasmPXp08dOnjwZa5v58+db7dq1LWfOnHb++efblClTQnaMAAAgcwtrUKpIkSKuSHncDpRuq15UYg4dOmTvv/++dezYMdHt1MHKnz9/rAUAACAaXHjhhbEmeFmwYIH/vh49etjnn39uH3zwgX377be2ZcsWu+WWW/z3KxtdASmVS1i4cKG98cYbLuA0YMAA/zYbN2502zRu3NiWL19ujzzyiMtAnz17dsiPFQAAZD5hDUrlyJHD6tSpY3PnzvWvO336tLvdoEGDRB+rDpjqRd11110haCkAAEDoZcuWLdYEL7qgJ8r+Vsa4Joy56qqrXH9q8uTJLvj0448/um2++uor++OPP+ztt9+2mjVr2nXXXWdDhgyxcePGuUCVaIKZ8uXL28iRI61KlSrWrVs3u/XWW+2FF14I63EDAIDMIezD93r27GkTJ050V+9WrVplDzzwgMuC0mx80q5dOzcELy51xFq2bOlS1gEAAMJN/ZiBAwe6INF5551nJUuWtOrVq1v79u3t3XffdRfTkuvPP/+0UqVKWYUKFaxt27ZuOJ5oopgTJ07EmixGQ/vOPfdc/2Qx+qkyB4G1O5s1a+YmfVm5cqV/m8B9eNskdcIZAACA1MhmYda6dWvbuXOnSyVXcXNdyZs1a5a/A6XOl2bkC7RmzRqXvq4rgAAAAOG0bNky69u3r+ubXHrppVa/fn27+eabLXfu3LZ79243KcsTTzxhDz30kNtOQ+RUXuBMtB8Nt6tUqZIbujdo0CC7/PLL3f7UZ1LGecGCBROcLEY/g00m492X2DYKXB05csQdQ1wKrgUG2JjZGAAARG1QSpQqriUYFd+MS50zn88XgpYBAAAkTgXGVUD8ww8/jBckCqTsozFjxrihco8//vgZ96vhdh5lXClIVbZsWZs2bVrQYFGoaGZjBcgAAAAyRFAKAAAgWq1du9ayZ89+xu1UL1OLht2lhAJeF1xwga1bt86uueYaVxdq7969sQJhgZPF6OfixYtj7cObXCZwm2ATzmhimIQCXyqroPILgZlSZcqUSdExAQCAzC3sNaUAAACiWVICUqnZ3nPw4EFbv369q1WlwubaT+BkMSpvoLIH3mQx+rlixQrbsWOHf5s5c+a4gFPVqlX92wTuw9smsQlnmNkYAACkFYJSAAAA6eTrr792xc8///zzZD+2d+/e9u2339pff/3lZtVTnaqsWbPaHXfcYQUKFLCOHTu6jKV58+a5wueaJEbBpEsuucQ9vmnTpi74dPfdd9uvv/5qs2fPtieffNK6du3qr2nVpUsX27Bhg6t1tXr1anv55Zfd8MAePXqk+WsBAAAQF0EpAACANPDggw9a//79/bc/+ugju/baa23mzJluYpdRo0Yla3///POPC0Cplubtt9/uZhz+8ccfrWjRou7+F154wW644QZX0+qKK65wQ/GmT5/uf7wCWDNmzHA/Fay666673KzGgwcP9m9Tvnx51z5lR9WoUcPVu3rttdfcDHwAAADpLcaXySqGq+6Bri7u27ePdHMAAIJoNmSmRaLZ/ZtHdP+gSpUqNnbsWFfvSTQT30033eSykBQs0k/Vg8po6FsBAJC4mE4xFol8E31h7x9Q6BwAACAVvJnoVM/p008/dbPs6Zrfzz//7LKPlJl09OhRd7+XpTRgwIAwtxoAACD8CEoBAACkwj333ON+jh8/3mVJ1axZ077//ns3nO6xxx5zAapDhw65LCptm8mS1AEAABJEUAoAACAVypYt636qwPhzzz3nCom/+OKLrjD5ueee6+5T1pTqN3m3AQAAQKFzAACANKHC4zExMXb//fdb4cKF3ax7nldffdVatGgR1vYBAABEGjKlAAAA0kC5cuXcsL1gNKMdAAAAYiNTCgAAAAAAACFHUAoAACAVhg8fbkeOHEnStj/99JPNnDkz3dsEAAAQDQhKAQAApMIff/zhCpg/+OCD9uWXX9rOnTv99508edJ+++03e/nll61hw4bWunVrO+uss8LaXgAAgEhBTSkAAIBUePPNN+3XX3+1l156ye68807bv3+/Zc2a1XLmzGmHDx9229SqVcvuu+8+u+eeeyxXrlzhbjIAAEBEICgFAACQSjVq1LCJEye6WfaUGfX333+7IX1FihSxmjVrup8AAACIjaAUAABAGsmSJYsLQmkBAABA4qgpBQAAAAAAgJAjKAUAAAAAAICQIygFAAAAAACAkCMoBQAAAAAAgJAjKAUAAAAAAICQY/Y9AACAVLjllluSvO306dPTtS0AAADRhEwpAACAVChQoIB/yZ8/v82dO9eWLFniv3/p0qVune4HAADA/5ApBQAAkAqTJ0/2//7oo4/a7bffbuPHj7esWbO6dadOnbIHH3zQBawAAADwP2RKAQAApJFJkyZZ7969/QEp0e89e/Z09wEAAOB/CEoBAACkkZMnT9rq1avjrde606dPh6VNAAAAkYrhewAAAGmkQ4cO1rFjR1u/fr3Vq1fPrfvpp59s+PDh7j4AAAD8D0EpAACANPL8889biRIlbOTIkbZ161a3rmTJktanTx/r1atXuJsHAAAQUQhKAQAApJEsWbJY37593bJ//363jgLnAAAAwRGUAgAASAcEowAAABJHUAoAACAVatWqZTExMUnadtmyZeneHgAAgGhBUAoAACAVWrZsGe4mAAAARCWCUgAAAKkwcODAcDcBAAAgKhGUAgAASGNLly61VatWud8vvPBCN8QPAAAAsRGUAgAASCM7duywNm3a2Pz5861gwYJu3d69e61x48b2/vvvW9GiRcPdRAAAgIiRJdwNGDdunJUrV85y5cpl9evXt8WLFye6vTp2Xbt2tZIlS1rOnDntggsusC+++CJk7QUAAEjIQw89ZAcOHLCVK1fa7t273fL777/b/v377eGHHw538wAAACJKWDOlpk6daj179rTx48e7gNTo0aOtWbNmtmbNGitWrFi87Y8fP27XXHONu+/DDz+00qVL299//+2/EgkAABBOs2bNsq+//tqqVKniX1e1alV3Ea5p06ZhbRsAAECkCWtQatSoUdapUyfr0KGDu63g1MyZM23SpEn22GOPxdte63XFceHChZY9e3a3TllWAAAAkeD06dP+PkogrdN9AAAAiIDhe8p6UhHQJk2a/K8xWbK424sWLQr6mM8++8waNGjghu8VL17cqlWrZkOHDrVTp06FsOUAAADBXXXVVda9e3fbsmWLf92///5rPXr0sKuvvjqsbQMAAIg0YcuU2rVrlwsmKbgUSLdXr14d9DEbNmywb775xtq2bevqSK1bt84efPBBO3HiRILTMR87dswtHtV0AAAASA8vvfSS3XjjjS6Tu0yZMm7d5s2b3YW0t99+O9zNAwAAiChRNfue0t5VT2rChAmWNWtWq1Onjrv6+NxzzyUYlBo2bJgNGjQo5G0FAACZjwJRy5Ytc3WlvItsqi8VmBkOAACAMAelihQp4gJL27dvj7Vet0uUKBH0MZpxTzUZ9DiPOnrbtm1zwwFz5MgR7zH9+vVzxdQDM6W8K5cAAABpLSYmxk3MogUAAAARGJRSAEmZTnPnzrWWLVv6M6F0u1u3bkEfc+mll9q7777rtlP9KVm7dq0LVgULSEnOnDndAgAAEArqy2jZsWNHvOLmmrQFAAAAYS50Lspgmjhxor3xxhu2atUqe+CBB+zQoUP+2fjatWvnMp08ul+z76mAqIJRmqlPhc5V+BwAACDcVDKgadOmLiil+pl79uyJtQAAACBCakq1bt3adu7caQMGDHBD8GrWrGmzZs3yFz/ftGmTPyNKNOxu9uzZbgab6tWrW+nSpV2A6tFHHw3jUQAAAPyf8ePH25QpU+zuu+8Od1MAAAAiXtgLnWuoXkLD9ebPnx9vXYMGDezHH38MQcsAAACSRzUuGzZsGO5mAAAARIWwDt8DAADISO677z5X/xIAAABRkCkFAAAQzQJn+VVh8wkTJtjXX3/tSg1o1uBAo0aNCkMLAQAAIhNBKQAAgFT45ZdfYt1WjUz5/fffY62PiYkJabsAAAAiHUEpAACAVJg3b164mwAAABCVqCkFAACQxtatW+dmDD5y5Ii77fP5wt0kAACAiENQCgAAII38999/dvXVV9sFF1xg119/vW3dutWt79ixo/Xq1SvczQMAAIgoBKUAAADSSI8ePVxx802bNlmePHn861u3bm2zZs0Ka9sAAAAiDTWlAAAA0shXX33lhu2dc845sdZXrFjR/v7777C1CwAAIBKRKQUAAJBGDh06FCtDyrN7927LmTNnWNoEAAAQqQhKAQAApJHLL7/c3nzzTf/tmJgYO336tI0YMcIaN24c1rYBAABEGobvAQAApBEFn1TofMmSJXb8+HHr27evrVy50mVK/fDDD+FuHgAAQPQGpfbu3Wsff/yxff/9964uwuHDh61o0aJWq1Yta9asmTVs2DD9WgoAABDhqlWrZmvXrrWXXnrJzjrrLDt48KDdcsst1rVrVytZsmS4mwcAABB9w/e2bNli9913n+tMPf3003bkyBGrWbOmuxKoQp7z5s2za665xqpWrWpTp05N/1YDAABEqAIFCtgTTzxh06ZNsy+++ML1nVIbkBo+fLgbCvjII4/41x09etQFu84++2zLly+ftWrVyrZv3x7rcZoFsHnz5q7OVbFixaxPnz528uTJWNvMnz/fateu7WpenX/++TZlypRUtRUAACBNM6WUCdW+fXtbunSpCzwFo0DVJ598YqNHj7bNmzdb7969k9wIAACAjGDWrFkuQHTZZZe52+PGjbOJEye6/pN+L1SoULL3+fPPP9urr75q1atXj7W+R48eNnPmTPvggw9cIKxbt24uK8sbJnjq1CkXkCpRooQtXLjQtm7dau3atbPs2bPb0KFD3TYbN25023Tp0sXeeecdmzt3rv9CpLLgAQAAwp4p9ccff7gaCQkFpCR37tx2xx132KJFi6xDhw5p2UYAAICooEyk/fv3u99XrFhhPXv2tOuvv94Ff/R7cmn4X9u2bV1gKzCgtW/fPnv99ddt1KhRdtVVV1mdOnVs8uTJLvj0448/um2++uor14d7++23XYb7ddddZ0OGDHHBMdW7kvHjx1v58uVt5MiRVqVKFRfYuvXWW+2FF15Is9cEAAAgVUEppYUnR3K3BwAAyAgUfPIu4n300UfWokULl5WkQNCXX36Z7P1peJ4ymZo0aRJrvbLXT5w4EWt95cqV7dxzz3UXCEU/L7roIitevLh/G2U/KWim4uveNnH3rW28fQAAAETU7Hv//fefP+ikYXq6cqehezfeeKObBhkAACCzypEjh5sIRr7++ms3XE4KFy7sz6BKqvfff9+WLVvmhu/FtW3bNvdcBQsWjLVeASjd520TGJDy7vfuS2wbtVX9O2XCx3Xs2DG3eJJ7XAAAAMnKlPJS0MuVK+eKZOpK3PLly+3iiy926d0TJkywxo0bu5pSAAAAmZVqSWmYnobJLV682GU5iWbk0+QwSaULf927d3d1nnLlymWRZNiwYa6GlbeUKVMm3E0CAAAZPSjVt29flwL+3Xff2ZVXXmk33HCD62ippsGePXusc+fObmYYAACAzOqll16ybNmy2YcffmivvPKKlS5d2q3X0L1rr702yfvR8LwdO3a4WfG0Py3ffvutjR071v2ubCbVhdq7d2+sx2n2PRU2F/2MOxufd/tM2+TPnz9olpT069fP9f+8RQE0AACAdB2+p9Txb775xs38UqNGDZcd9eCDD1qWLP8X13rooYfskksuSVEjAAAAMgLVdJoxY0a89cktHH711Ve7LPVAmkhG2eqPPvqoy07SLHqaLa9Vq1bu/jVr1timTZusQYMG7rZ+PvPMMy64pUx3mTNnjgs4eXWvtM0XX3wR63m0jbePYHLmzOkWAACAkAWldu/e7b+qpqmO8+bNG2sWGP1+4MCBVDcIAAAgWikodKagVVKcddZZVq1atVjr1PdSXU9vfceOHd1QQdWrUqBJFwgVTPIuEjZt2tQFn+6++243i7LqRz355JOueLoXVOrSpYvL7lJG/L333usuQE6bNs1mzpyZwlcAAAAgnQqdx8TEJHobAAAgM1P9zcT6R6dOnUqz51L2lTLWlSmlwuOaNe/ll1/23581a1aXtfXAAw+4YJWCWu3bt7fBgwf7tylfvrwLQPXo0cPGjBnj6l699tprbl8AAAARFZS65557/FfWjh496q6uqYMjgbOwAAAAZEa//PJLrNsnTpxw60aNGuWG0qXG/PnzY91WAfRx48a5JSFly5aNNzwvLtUKjdtuAACAiApK6cpaoLvuuiveNt60xwAAAJmR6m7GVbduXStVqpQ999xzdsstt4SlXQAAAFEdlJo8eXL6tgQAACCDqlSpkps0BgAAACkcvgcAAICE7d+/P9Ztn89nW7dutaeeesoqVqwYtnYBAABEfVBKUwofP37cFcGUkydPuk7W999/71LThwwZYnny5EmvtgIAAES0ggULxit0rsBUmTJl7P333w9buwAAAKI+KNWpUyerV6+ePfHEE+62aiNMnDjRTTX86aef2sGDB+3VV19Nr7YCAABEtHnz5sW6rdnxihYtaueff75ly0aCOgAAQKBk9Y5+++03e/TRR/2333rrLRs7dqy1bt3a7rjjDmvRogVBKQAAkGk1atQo3E0AAADIWEGpDh06uJ9btmxxUxorO0rD+NasWWMff/yxzZ49206fPu2G9917771u20mTJqVvywEAACLQ+vXrbfTo0bZq1Sp3u2rVqta9e3c777zzwt00AACA6AtKeTPvfffdd9axY0e77rrrbOrUqbZixQp/fYT//vvPPvvsM4JRAAAg09KFuhtvvNFq1qxpl156qVv3ww8/2IUXXmiff/65XXPNNeFuIgAAQHQO32vevLnLhFJn65NPPrG+ffv671u8eLG7EggAAJBZPfbYY9ajRw8bPnx4vPUqgUBQCgAAIIVBqREjRliBAgVs+fLlrsOlxfPTTz9Zly5dkrM7AACADEVD9qZNmxZvvS7qaUgfAAAAUhiUypUrlw0ZMiTofU899VRydgUAAJDhaKY9XbyrWLFirPVaV6xYsbC1CwAAIBIxNzEAAEAa6dSpk91///22YcMGa9iwob+m1LPPPms9e/YMd/MAAACiLyh17bXXukyoSy65JNHtDhw4YC+//LLly5fPunbtmlZtBAAAiAr9+/e3s846y0aOHGn9+vVz60qVKuX6UQ8//HC4mwcAABBRsiRlo9tuu81atWrlCpmrSOcHH3zgrvotXbrUvv76axs7dqzdfvvtVrJkSVu2bJm1aNEiWY0YN26clStXzg0PrF+/viuanpApU6ZYTExMrEWPAwAACDf1S1Rz859//rF9+/a5Rb93797d3QcAAIBkZkp17NjR7rrrLheMmjp1qk2YMMF1skQdLAWrmjVrZj///LNVqVLFkkP7Uzr7+PHjXUBKRUC1rzVr1iRYeyF//vzufg+dPAAAEGmUMQUAAIA0qCmVM2dOF5jSIgpKHTlyxM4++2zLnj27pdSoUaNc/YUOHTq42wpOzZw50yZNmuSmTw5GQagSJUqk+DkBAADSUq1atZJ0kUwZ5QAAAEhlofMCBQq4JTWOHz/uhgB6NRckS5Ys1qRJE1u0aFGCjzt48KCVLVvWTp8+bbVr17ahQ4fahRdeGHTbY8eOucWzf//+VLUZAAAgrpYtW/p/9/l8NmzYMOvSpYsVLlw4rO0CAACIZGGdfW/Xrl126tQpK168eKz1ur169eqgj6lUqZLLoqpevbrL1nr++efd7DYrV660c845J9726hQOGjQo3Y4BAABg4MCBsW6r0LnqSFWoUCFsbQIAAMgQhc4jSYMGDaxdu3ZWs2ZNa9SokU2fPt2KFi1qr776atDtlYXlFRrVsnnz5pC3GQAAAAAAABGUKVWkSBHLmjWrbd++PdZ63U5qzSjVs1Idh3Xr1iVYC0sLAAAAAAAAIkdYM6Vy5MhhderUsblz5/rXqU6UbisjKik0/G/FihVWsmTJdGwpAAAAAAAAwp4ptXfvXvvwww9t/fr11qdPH1fEU7PJqBZU6dKlk7Wvnj17Wvv27a1u3bpWr149Gz16tB06dMg/G5+G6mmfqg0lgwcPtksuucTOP/98147nnnvO/v77b7vvvvtScigAAACpNnbs2Fi3T548aVOmTHFZ4YEefvjhELcMAAAgAwWlfvvtNzc7nmbe++uvv6xTp04uKKXaTps2bbI333wzWftr3bq17dy50wYMGGDbtm1ztaJmzZrlL36ufWpGPs+ePXvcc2rbQoUKuUyrhQsXWtWqVZN7KAAAAGnihRdeiHVbZQjeeuutWOtiYmIISgEAAASI8Wne4mRQQKp27do2YsQIO+uss+zXX391M8soMHTnnXe6QFUk279/vwuoqeh5/vz5w90cAAAiTrMhMy0Sze7fPN32Tf8g5XjtAABIXEynGItEvonJCgelS/8g2TWlfv75Z+vcuXO89Rpip+wlAAAAAAAA4EySHZTSTHaKeMW1du1aK1q0aHJ3BwAAAAAAgEwo2UGpG2+80RUbP3HihL8+guo+Pfroo9aqVav0aCMAAAAAAAAye1Bq5MiRdvDgQStWrJgdOXLEGjVq5GbCU32pZ555Jn1aCQAAAAAAgMw9+54KVc2ZM8cWLFjgZuJTgEqFz1UAHQAAILM6efKkvfvuu9asWTP/LMIAAABIw6CU57LLLnMLAAAAzLJly2ZdunSxVatWhbspAAAAGTMoNXbs2KDrVVsqV65cbijfFVdcYVmzZk2L9gEAAESNevXq2fLly61s2bLhbgoAAEDGC0q98MILtnPnTjt8+LAVKlTIrduzZ4/lyZPH8uXLZzt27LAKFSrYvHnzrEyZMunRZgAAgIj04IMPWs+ePW3z5s1Wp04dy5s3b6z7q1evHra2AQAARH2h86FDh9rFF19sf/75p/33339uWbt2rdWvX9/GjBnjZuIrUaKE9ejRI31aDAAAEKHatGljGzdutIcfftguvfRSq1mzptWqVcv/EwAAAKnIlHryySfto48+svPOO8+/TkP2nn/+eWvVqpVt2LDBRowY4X4HAADITBSQAgAAQDoFpbZu3epml4lL67Zt2+Z+L1WqlB04cCC5uwYAAIhq1JICAABIx+F7jRs3ts6dO9svv/ziX6ffH3jgAbvqqqvc7RUrVlj58uWTu2sAAICo99Zbb7mhe7pI9/fff7t1o0ePtk8//TTcTQMAAIjuoNTrr79uhQsXdsU7c+bM6Za6deu6dbpPVPB85MiR6dFeAACAiPXKK6+4QufXX3+97d27106dOuXWFyxY0AWmAAAAkIrheypiPmfOHFu9erUrcC6VKlVyS2A2FQAAQGbz4osv2sSJE61ly5Y2fPhw/3pdwOvdu3dY2wYAABD1QSlP5cqV3QIAAID/FToPNsueMssPHToUljYBAABkmKCU0tCnTJlic+fOtR07dtjp06dj3f/NN9+kZfsAAACihmpqLl++PF7B81mzZlmVKlXC1i4AAIAMEZTq3r27C0o1b97cqlWrZjExMenTMgAAgCijelJdu3a1o0ePms/ns8WLF9t7771nw4YNs9deey3czQMAAIjuoNT7779v06ZNcwU8AQAA8D/33Xef5c6d25588kk7fPiw3XnnnW4WvjFjxlibNm3C3TwAAIDoDkrlyJHDzj///PRpDQAAQJRr27atWxSUOnjwoBUrVizcTQIAAIhIWZL7gF69ermrfUpJBwAAQHyqu7l06VJbs2aN7dy5M9zNAQAAyBiZUgsWLLB58+bZl19+aRdeeKFlz5491v3Tp09Py/YBAABEjQMHDtiDDz7o6kh5k8FkzZrVWrdubePGjbMCBQqEu4kAAADRmylVsGBBu/nmm61Ro0ZWpEgR17kKXAAAADJzTamffvrJZs6caXv37nXLjBkzbMmSJda5c+dwNw8AACC6M6UmT56cPi0BAACIcgpAzZ492y677DL/umbNmtnEiRPt2muvDWvbAAAAoj5TCgAAAMGdffbZQTPHta5QoUJhaRMAAECGyZSSDz/80KZNm2abNm2y48ePx7pv2bJladU2AACAqPLkk09az5497a233rISJUq4ddu2bbM+ffpY//79w908AACA6M6UGjt2rHXo0MGKFy9uv/zyi9WrV89dFdywYYNdd9116dNKAACAKPDKK6/Yjz/+aOeee66df/75btHvCxcutFdffdVq167tXwAAADK7ZGdKvfzyyzZhwgS74447bMqUKda3b1+rUKGCDRgwwHbv3p0+rQQAAIgCLVu2DHcTAAAAMm5QSkP2GjZs6H7PnTu3m/pY7r77brvkkkvspZdeSvtWAgAARIGBAweGuwkAAAAZd/ie6iN4GVFKR1eKumzcuNF8Pl/atxAAAAAAAAAZTrKDUldddZV99tln7nfVlurRo4ddc8011rp1a7v55pvTo40AAACZsj5V9erVLX/+/G5p0KCBffnll/77jx49al27dnW1PfPly2etWrWy7du3x8twb968ueXJk8eKFSvmCq6fPHky1jbz5893Na5y5szpamCpPAMAAEBEDt9TPanTp0+7372OkIp33njjjda5c+f0aCMAAECmc84559jw4cOtYsWKLhv9jTfesJtuuslNNHPhhRe6C4MzZ860Dz74wAoUKGDdunWzW265xX744Qf3+FOnTrmAlLLc1VfbunWrtWvXzrJnz25Dhw71Z7prmy5dutg777xjc+fOtfvuu89KlixpzZo1C/MrAAAAMroYXyYbc7d//37Xcdu3b5+76ggAAGJrNmSmRaLZ/ZtbZu8fFC5c2J577jm79dZbrWjRovbuu++632X16tVWpUoVW7RokavzqayqG264wbZs2eJmTZbx48fbo48+ajt37rQcOXK43xXY+v333/3P0aZNG9u7d6/NmjUrQ712AACES0ynGItEvonpFw5Kav8g2ZlSoo7K4sWLbceOHf6sKY+uwAEAAGRmx48fd1lI5513nmXLlqLuVizKelJG1KFDh9wwvqVLl9qJEyesSZMm/m0qV67s6n16QSn9vOiii/wBKVH20wMPPGArV660WrVquW0C9+Ft88gjj6S6zQAAAGeS7F7S559/bm3btrWDBw+6aFdMzP8ifvqdoBQAAMisDh8+bA899JAbaidr1661ChUquHWlS5e2xx57LFn7W7FihQtCqX6U6kZ9/PHHVrVqVVu+fLnLdCpYsGCs7RWA2rZtm/tdPwMDUt793n2JbaOrm0eOHHEzLcd17Ngxt3i0LQAAQEgKnffq1cvuvfdeF5RSxtSePXv8izcrHwAAQGbUr18/+/XXX13x8Fy5cvnXKxtp6tSpyd5fpUqVXADqp59+chlO7du3tz/++MPCadiwYS4d31vKlCkT1vYAAIBMFJT6999/7eGHH3azuKSVcePGWbly5VznrX79+m5oYFK8//77LjurZcuWadYWAACAlPrkk0/spZdesssuuyxWNrkKk69fvz7Z+1M2lGbEq1OnjgsG1ahRw8aMGeOKl2uIoC4QBtLse7pP9DPubHze7TNto2z4YFlSXuBN9SG8ZfPmzck+LgAAgBQFpVRnYMmSJWn26umqYc+ePW3gwIG2bNky19nSc6heVWL++usv6927t11++eVp1hYAAIDUUAHxYsWKxVuvWlCBQaqUUi1PDZ1TkEqz6Gm2PM+aNWts06ZNbrif6KeG/wX2qebMmeMCThoC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AKRjptRVV11le/fujbd+//797j4AAAAAAAAgzYNS8+fPt+PHj8dbf/ToUfv++++TuzsAAIAMY/v27Xb33XdbqVKlLFu2bG4GvsAFAAAAKRi+99tvv/l//+OPP2zbtm3+26dOnXLp6aVLl07q7gAAADKce+65x824179/f1dbKiYmJtxNAgAAiP6gVM2aNV3HSkuwYXq5c+e2F198Ma3bBwAAEDUWLFjgMsfVbwIAAEAaBaU2btxoPp/PKlSoYIsXL7aiRYv678uRI4cr5klaOgAAyMzKlCnj+ksAAABIw6BU2bJl3c/Tp08n9SEAAACZyujRo+2xxx6zV1991cqVKxfu5gAAAGSMoFSg9evXu07XqlWr3O2qVata9+7d7bzzzkvr9gEAAES0QoUKxaoddejQIdcnypMnj2XPnj3Wtrt37w5DCwEAADJIUGr27Nl24403uloJl156qVv3ww8/2IUXXmiff/65XXPNNenRTgAAgIikC3UAAAAIQVBKKek9evSw4cOHx1v/6KOPEpQCAACZSvv27cPdBAAAgKiUJbkP0JC9jh07xlt/77332h9//JFW7QIAAIgaW7Zssd69e9v+/fvj3bdv3z7r06ePbd++PSxtAwAAyDBBKc26t3z58njrtU4z8AEAAGQ2o0aNcgGp/Pnzx7uvQIECduDAAbcNAAAAUhCUGjx4sB0+fNg6depk999/vz377LP2/fffu0VD+Tp37uzuAwAAyGxmzZpl7dq1S/B+3TdjxoyQtgkAACDD1JQaNGiQdenSxfr3729nnXWWjRw50vr16+fuK1WqlD311FP28MMPp2dbAQAAItLGjRvt3HPPTfD+c845x/7666+QtgkAACDDBKV8Pp/7qSmPVehci1LRRUEqAACAzCp37twu6JRQYEr3aRsAAACksKaUAlKBFIwiIAUAADK7+vXr21tvvZXg/W+++abVq1cvpG0CAADIUEGpCy64wAoXLpzokhLjxo2zcuXKWa5cuVynbvHixQluO336dKtbt64VLFjQ8ubNazVr1ky0EwgAAJDeNPPe5MmT3c/AWfb0e69evWzKlCnuPgAAAKRg+J5XV0ozyKSlqVOnWs+ePW38+PEuIDV69Ghr1qyZrVmzJuhsfgp8PfHEE1a5cmXLkSOHKxraoUMHt60eBwAAEGqNGzd2F9m6d+9uL7zwgpuFTxnm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fO2119y+AAAA0hNBKQAAgDSydetWO3nyZLz1WufNdleqVCk7cODAGfel4XtnojpV48aNc0tCypYtG294XlwKfP3yyy9nfD4AAIC0xPA9AACANNK4cWPr3LlzrACPflem0lVXXeVur1ixIl59KAAAgMyIoBQAAEAaef31161w4cKuCLlXELxu3bpune4TFTwfOXJkuJsKAAAQdgzfAwAASCMqYq6Z61QwXAXOpVKlSm4JzKYCAAAAQSkAAIA0V7lyZbcAAAAgYQSlAAAA0tA///xjn332mW3atMmOHz8e675Ro0aFrV0AAACRhqAUAABAGpk7d67deOONVqFCBTeEr1q1avbXX3+5mfRq164d7uYBAABEFAqdAwAApJF+/fpZ79693Qx7uXLlso8++sg2b95sjRo1sttuuy3czQMAAIgoBKUAAADSyKpVq6xdu3bu92zZstmRI0fcbHuDBw+2Z599NtzNAwAAiCgEpQAAANJI3rx5/XWkSpYsaevXr/fft2vXrjC2DAAAIPJQUwoAACCNXHLJJbZgwQKrUqWKXX/99darVy83lG/69OnuPgAAAPwPQSkAAIA0otn1Dh486H4fNGiQ+33q1KlWsWJFZt4DAACIg6AUAABAGjh16pT9888/Vr16df9QvvHjx4e7WQAAABGLmlIAAABpIGvWrNa0aVPbs2dPuJsCAAAQFQhKAQAApJFq1arZhg0bwt0MAACAqEBQCgAAII08/fTT1rt3b5sxY4Zt3brV9u/fH2sBAADA/1BTCgAAII1oxj258cYbLSYmxr/e5/O526o7BQAAgP9DUAoAACCNzJs3L9xNAAAAiBoEpQAAANJIo0aNwt0EAACAqEFNKQAAgDT0/fff21133WUNGza0f//916176623bMGCBeFuGgAAQEQhKAUAAJBGPvroI2vWrJnlzp3bli1bZseOHXPr9+3bZ0OHDg138wAAACIKQSkAAIA0nH1v/PjxNnHiRMuePbt//aWXXuqCVAAAAPgfglIAAABpZM2aNXbFFVfEW1+gQAHbu3dvWNoEAAAQqQhKAQAApJESJUrYunXr4q1XPakKFSqEpU0AAACRiqAUAABAGunUqZN1797dfvrpJ4uJibEtW7bYO++8Y71797YHHngg3M0DAACIKBERlBo3bpyVK1fOcuXKZfXr17fFixcnuK1qNFx++eVWqFAhtzRp0iTR7QEAAELlscceszvvvNOuvvpqO3jwoBvKd99991nnzp3toYceCnfzAAAAIkrYg1JTp061nj172sCBA10B0Bo1arhZa3bs2BF0+/nz59sdd9xh8+bNs0WLFlmZMmWsadOm/imXAQAAwkXZUU888YTt3r3bfv/9d/vxxx9t586dNmTIkHA3DQAAIOKEPSg1atQol+reoUMHq1q1qpuxJk+ePDZp0qSg2ysF/sEHH7SaNWta5cqV7bXXXrPTp0/b3LlzQ952AACAQG+//bYdPnzYcuTI4fo19erVs3z58oW7WQAAABEprEGp48eP29KlS90QPH+DsmRxt5UFlRTq+J04ccIKFy6cji0FAAA4sx49elixYsXcEL4vvvjCTp06Fe4mAQAARKywBqV27drlOmvFixePtV63t23blqR9PProo1aqVKlYga1Ax44ds/3798daAAAA0sPWrVvt/fffd8P4br/9ditZsqR17drVFi5cGO6mAQAARJxsFsWGDx/uOn6qM6Ui6cEMGzbMBg0aFPK2AQCAzCdbtmx2ww03uEXZ3B9//LG9++671rhxYzvnnHNs/fr14W4iAABRJ6ZTjEUi30RfuJsQ9cKaKVWkSBHLmjWrbd++PdZ63S5RokSij33++eddUOqrr76y6tWrJ7hdv379bN++ff5l8+bNadZ+AACAhKhGpiZvue6666xixYr2119/hbtJAAAAESWsQSkVAa1Tp06sIuVe0fIGDRok+LgRI0a4WWxmzZpldevWTfQ5cubMafnz54+1AAAApBdlSGliluuvv95Kly5to0ePtptvvtlWrlwZ7qYBAABElLAP3+vZs6e1b9/eBZc0Q406bocOHXKz8Um7du1ch07D8OTZZ5+1AQMGuFT4cuXK+WtPaWYbZrcBAADh1KZNG5sxY4bLklJNqf79+yd6oQ0AACAzC3tQqnXr1rZz504XaFKAqWbNmi4Dyit+vmnTJjcjn+eVV15xs/bdeuutsfYzcOBAe+qpp0LefgAAAI/KEkybNs0N29PvgX7//XerVq1a2NoGAAAQacIelJJu3bq5JRgVMQ9EPQYAABCpNGwv0IEDB+y9996z1157zZYuXepmHQYAAEAE1JQCAADIiL777jtXnqBkyZJucparrrrKfvzxx3A3CwAAIKJERKYUAAAZSbMhMy0Sze7fPNxNyNBUhmDKlCn2+uuv2/79+11NqWPHjtknn3xiVatWDXfzAAAAIg6ZUgAAAKnUokULq1Spkv32229u0pYtW7bYiy++GO5mAQAARDQypQAAAFLpyy+/tIcfftgeeOABq1ixYribAwAAEBXIlAIAAEilBQsWuKLmderUsfr169tLL71ku3btCnezAAAAIhpBKQAAgFS65JJLbOLEibZ161br3Lmzvf/++1aqVCk7ffq0zZkzxwWsAAAAEBtBKQAAgDSSN29eu/fee13m1IoVK6xXr142fPhwK1asmN14443hbh4AAEBEISgFAACQDlT4fMSIEfbPP//Ye++9F+7mAAAARByCUgAAAOkoa9as1rJlS/vss8/C3RQAAICIQlAKAAAAAAAAIUdQCgAAAAAAACFHUAoAAAAAAAAhR1AKAAAAAAAAIUdQCgAAAAAAACFHUAoAAAAAAAAhR1AKAAAAAAAAIUdQCgAAAAAAACFHUAoAAAAAAAAhR1AKAAAgAn333XfWokULK1WqlMXExNgnn3wS636fz2cDBgywkiVLWu7cua1Jkyb2559/xtpm9+7d1rZtW8ufP78VLFjQOnbsaAcPHoy1zW+//WaXX3655cqVy8qUKWMjRowIyfEBAAAQlAIAAIhAhw4dsho1ati4ceOC3q/g0dixY238+PH2008/Wd68ea1Zs2Z29OhR/zYKSK1cudLmzJljM2bMcIGu+++/33///v37rWnTpla2bFlbunSpPffcc/bUU0/ZhAkTQnKMAAAgc8sW7gYAAAAgvuuuu84twShLavTo0fbkk0/aTTfd5Na9+eabVrx4cZdR1aZNG1u1apXNmjXLfv75Z6tbt67b5sUXX7Trr7/enn/+eZeB9c4779jx48dt0qRJliNHDrvwwgtt+fLlNmrUqFjBKwAAgPRAphQAAECU2bhxo23bts0N2fMUKFDA6tevb4sWLXK39VND9ryAlGj7LFmyuMwqb5srrrjCBaQ8yrZas2aN7dmzJ6THBAAAMh8ypQAAEaXZkJkWqWb3bx7uJgCOAlKizKhAuu3dp5/FihWLdX+2bNmscOHCsbYpX758vH149xUqVCjecx87dswtgUMAAQCRK6ZTjEUq30RfuJuAMCNTCgAAAEk2bNgwl5XlLSqODgAAkBIEpQAAAKJMiRIl3M/t27fHWq/b3n36uWPHjlj3nzx5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Gpxzzjmus7F06VJ3orvqqqvspptuspUrV1q00Rftq6++6jqC0ebCCy+0rVu3+pcFCxZYtNizZ49deumllj17dtfp/uOPP2zkyJFWqFAhi5bPTeBrr//HEi2znj777LPuD6CXXnrJVq1a5W6PGDHCXnzxRYsW9913n3vd33rrLVuxYoX7DlVnQx3yaDxv6fUfO3asjR8/3n766SfLmzevNWvWzI4ePRrytiJzom8VXvStIgN9q/ChbxV+9K0imGbfQ+TSW/Txxx/7otmOHTvccXz77be+aFWoUCHfa6+95osmBw4c8FWsWNE3Z84cX6NGjXzdu3f3RYuBAwf6atSo4YtWjz76qO+yyy7zZRT67Jx33nm+06dP+6JB8+bNfffee2+sdbfccouvbdu2vmhw+PBhX9asWX0zZsyItb527dq+J554whdt5y19bkqUKOF77rnn/Ov27t3ry5kzp++9994LUyuRmdG3igz0rUKLvlVkoW8VWvStIhuZUkh3+/btcz8LFy5s0Uapqu+//76LVCvVPJroimrz5s3dFYBopPRTpatWqFDB2rZta5s2bbJo8dlnn1ndunXd1S8Ns6hVq5ZNnDjRotHx48ft7bfftnvvvdelDkcDpWPPnTvX1q5d627/+uuv7mrwddddZ9Hg5MmT7rsnV65csdYrNTuarmp7Nm7caNu2bYv1XVSgQAGrX7++LVq0KKxtA6IVfavwoG8VPvStwou+VWTZmMH6VtnC3QBkbKdPn3Zjd5VuW61aNYsWSulUR0npj/ny5bOPP/7YqlatatFCnb1ly5ZF9DjpxOgLdcqUKVapUiWX4jxo0CC7/PLL7ffff3f1NCLdhg0bXIpzz5497fHHH3fvw8MPP2w5cuSw9u3bWzTR+PW9e/faPffcY9Hiscces/3797taGVmzZnWdkGeeecZ1wKOBPuP6/lGthipVqljx4sXtvffec52M888/36KNOk2i4wik2959AJKOvlV40LcKL/pW4UXfKrJsy2B9K4JSSPcrSjrZRVsEWifs5cuXuyuRH374oTvZqZ5DNHSeNm/ebN27d3djpuNeDYgWgVddVLNBHSkVJZw2bZp17NjRouEPBl3NGzp0qLutq3n6f6Ax39HWcXr99dfd+6Erq9FCn5N33nnH3n33XVc/Q/+X9QecjiFaXn/VO9AV1NKlS7vOX+3ate2OO+5w9VgAZG70rUKPvlX40bcKL/pWSE8M30O66datm82YMcPmzZvnClxGE111UdS8Tp06bsYbFZkbM2aMRQN9se7YscN90WbLls0t6vSpEJ5+15WNaFOwYEG74IILbN26dRYNNAtG3E62rspEU5q8/P333/b111+7wpDRpE+fPu6KXps2bdzMPHfffbf16NHD/V+OFprVRv9vDx486P4YWrx4sStsrCEX0aZEiRLu5/bt22Ot123vPgBJQ98qPOhbhR99q/CibxVZSmSwvhVBKaQ51WJTp0lp2d98842bOjTa6erMsWPHLBpcffXVLkVeVzC8RVeWlF6r33VlINro5LF+/XrXIYkGGlIRd6pujcHXFcloMnnyZFe3QfUzosnhw4ctS5bYpzd97vX/ONpoJhV97jXr0OzZs91sVdFG5wB1kFSLwqMhAJopJtrqyQDhQt8qvOhbhR99q/CibxVZymewvhXD9yL0JBF41UKFzHTCUzHLc88916IhrVypnZ9++qkbv+uNa1XxNRWTi3T9+vVzKbV6rQ8cOOCOZf78+e5LKxroNY9bY0JfvmeffXbU1J7o3bu3tWjRwnU0tmzZYgMHDnQnPqXYRgNdOVJBSKWY33777e5KzIQJE9wSLdTJUMdJKdm6ChxN9NlRnQP9H1aK+S+//GKjRo1yKdvRQt83+iNUw110PtAVStVx6NChg0XjeUsp/k8//bRVrFjRdaT69+/vUv5btmwZ1nYj86BvFV70rcKPvlX40bcKL/pWESzc0/8hvnnz5rlpH+Mu7du390WDYG3XMnnyZF800HSnZcuW9eXIkcNXtGhR39VXX+376quvfNEs2qYtbt26ta9kyZLuPShdurS7vW7dOl80+fzzz33VqlVzU7NWrlzZN2HCBF80mT17tvt/u2bNGl+02b9/v/u8n3vuub5cuXL5KlSo4Kb7PXbsmC9aTJ061bVb/wc05W/Xrl3dVL/Ret7S1MX9+/f3FS9e3P2f0PdqNH62EL3oW4UXfavwo28VfvStwou+VeSK0T/hDowBAAAAAAAgc6GmFAAAAAAAAEKOoBQAAAAAAABCjqAUAAAAAAAAQo6gFAAAAAAAAEKOoBQAAAAAAABCjqAUAAAAAAAAQo6gFAAAAAAAAEKOoBQAAAAAAABCjqAUAESAe+65x1q2bOm/feWVV9ojjzwS1jYBAABEK/pWQHQgKAUgTU/4GcmUKVMsJibGLVmzZrVChQpZ/fr1bfDgwbZv3740fa4xY8a45wMAAJkbfau0Qd8KiA4EpQAgEfnz57etW7faP//8YwsXLrT777/f3nzzTatZs6Zt2bIlzZ6nQIECVrBgwTTbHwAAQCSibwUgEEEpAGlKqdEPP/yw9e3b1woXLmwlSpSwp556KtY2e/futc6dO1vx4sUtV65cVq1aNZsxY4b//o8++sguvPBCy5kzp5UrV85GjhwZ6/Fa9/TTT1u7du0sX758VrZsWfvss89s586ddtNNN7l11atXtyVLlsR63IIFC+zyyy+33LlzW5kyZVw7Dx06lOjx6EqejqFkyZJWpUoV69ixo+tAHTx40B2j5/Tp0zZs2DArX76823+NGjXsww8/jLWvlStX2g033OA6Y2eddZZry/r165N0VfTYsWPWu3dvK126tOXNm9ddVZw/f36ibQcAANGPvhV9KyAjIygFIM298cYb7uT+008/2YgRI1xK9pw5c/wdjOuuu85++OEHe/vtt+2PP/6w4cOHuxRuWbp0qd1+++3Wpk0bW7Fihet09e/fP1769QsvvGCXXnqp/fLLL9a8eXO7++67XUfqrrvusmXLltl5553nbvt8Pre9OijXXnuttWrVyn777TebOnWq60h169Yt2cdXrFgxa9u2reusnTp1yq1Tp0lX+caPH+86SD169HBt+fbbb939//77r11xxRWuM/jNN9+447z33nvt5MmTSXpOtXPRokX2/vvvu/bfdttt7nj+/PPPZLcfAABEF/pW9K2ADMsHAKnQvn1730033eS/3ahRI99ll10Wa5uLL77Y9+ijj7rfZ8+e7cuSJYtvzZo1Qfd35513+q655ppY6/r06eOrWrWq/3bZsmV9d911l//21q1b1Tvy9e/f379u0aJFbp3uk44dO/ruv//+WPv9/vvvXVuOHDkStC2TJ0/2FShQIOh9r7zyitv/9u3bfUePHvXlyZPHt3Dhwljb6DnvuOMO93u/fv185cuX9x0/fjzJr2P37t3d73///bcva9asvn///TfWY66++mq3XwAAkHHQt6JvBWQm2cIdFAOQ8Si9O5DSs3fs2OF+X758uZ1zzjl2wQUXBH3sqlWrXJp4IF21Gz16tLty5l31C3wOparLRRddFG+dnlcp4r/++qu7CvbOO+/4t9GVPl1d3Lhxo0sfTw7vKqFS0NetW2eHDx+2a665JtY2x48ft1q1avmPWynl2bNnt+TSVU0de9zXTGnnZ599drL3BwAAogt9q/9D3wrIeAhKAUhzcTsH6lyogyKqCZDWz6H9J7TOe17VKVCtBdU6iOvcc89N9vOrg6f6Beq4bNiwwa2bOXOmq0sQSCnlqT1utV0dRqWlex1Hj2o8AACAjI2+1f/QtwIyFoJSAEJKV+E028ratWuDXtHTVTXVRAik29o2bqchOWrXru1qLJx//vmWWrpC+O6777rimVmyZLGqVau6DtKmTZusUaNGCR636kGcOHEi2Vf0dEVQV/P0vLoiCAAA4KFvRd8KiGYUOgcQUupYqCilimKqQKfSu7/88kubNWuWu79Xr142d+5cGzJkiOtcqbPx0ksvudlRUuPRRx91M7uoqKXSvVXE8tNPPz1jMU6lkm/bts1NXawreJMmTbKGDRu6aYZVRFQ024vapwKcaq8Kf6og6Isvvuhui55n//79rsioZq7R87/11lu2Zs2aM7ZdnUYV/1Rx0enTp7vXbPHixa4AqK4gAgCAzIu+FX0rIJqRKQUg5DQtsToad9xxh5s2WFfYvE6IrrpNmzbNBgwY4DpPqpmgGWY0rW9q6GqaZmt54okn3BUxdYg0i0zr1q0TfZw6O2qDUtaVUl6pUiVr3769de/e3d32qK1FixZ1nRmlnBcsWNAdy+OPP+7uVyq6Zobp06eP6zzqymTNmjVdTYekmDx5spuqWR1LzTZTpEgRu+SSS9w0yAAAIHOjb0XfCohWMap2Hu5GAAAAAAAAIHNh+B4AAAAAAABCjqAUAAAAAAAAQo6gFAAAAAAAAEKOoBQAAAAAAABCjqAUAAAAAAAAQo6gFAAAAAAAAEKOoBQAAAAAAABCjqAUAAAAAAAAQo6gFAAAAAAAAEKOoBQAAAAAAABCjqAUAAAAAAAAQo6gFAAAAAAAACzU/h95Awg08SEc2gAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axes = plt.subplots(1, 2, figsize=(12, 5))\n", + "\n", + "# Total change by decile\n", + "axes[0].bar(decile_df[\"Decile\"], decile_df[\"Total Change ($B)\"], color=\"steelblue\")\n", + "axes[0].set_xlabel(\"Income Decile\")\n", + "axes[0].set_ylabel(\"Total Change ($B)\")\n", + "axes[0].set_title(\"Total Income Change by Decile (TEST)\")\n", + "axes[0].set_xticks(range(1, 11))\n", + "\n", + "# Average change by decile\n", + "axes[1].bar(decile_df[\"Decile\"], decile_df[\"Avg Change per HH ($)\"], color=\"darkgreen\")\n", + "axes[1].set_xlabel(\"Income Decile\")\n", + "axes[1].set_ylabel(\"Average Change per Household ($)\")\n", + "axes[1].set_title(\"Average Income Change by Decile (TEST)\")\n", + "axes[1].set_xticks(range(1, 11))\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Winners and Losers" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Households gaining from kicker credit: 84.2%\n", + "Households losing from kicker credit: 0.0%\n", + "Households unchanged: 15.8%\n", + "\n", + "Average gain among winners: $1104.22\n" + ] + } + ], + "source": [ + "winners = income_change > 1 # Gain more than $1\n", + "losers = income_change < -1 # Lose more than $1\n", + "unchanged = ~winners & ~losers\n", + "\n", + "total_hh = winners.sum() + losers.sum() + unchanged.sum() # Weighted total\n", + "\n", + "print(f\"Households gaining from kicker credit: {winners.sum() / total_hh * 100:.1f}%\")\n", + "print(f\"Households losing from kicker credit: {losers.sum() / total_hh * 100:.1f}%\")\n", + "print(f\"Households unchanged: {unchanged.sum() / total_hh * 100:.1f}%\")\n", + "\n", + "if winners.any():\n", + " print(f\"\\nAverage gain among winners: ${income_change[winners].mean():.2f}\")\n", + "if losers.any():\n", + " print(f\"Average loss among losers: ${income_change[losers].mean():.2f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Poverty Impact" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Baseline poverty rate (no kicker): 25.92%\n", + "Reformed poverty rate (with kicker): 25.70%\n", + "Change in poverty rate: -0.22 pp\n" + ] + } + ], + "source": [ + "baseline_poverty = baseline.calculate(\"in_poverty\", period=YEAR)\n", + "reformed_poverty = reformed.calculate(\"in_poverty\", period=YEAR)\n", + "\n", + "# MicroSeries .mean() gives weighted mean\n", + "baseline_poverty_rate = baseline_poverty.mean() * 100\n", + "reformed_poverty_rate = reformed_poverty.mean() * 100\n", + "\n", + "print(f\"Baseline poverty rate (no kicker): {baseline_poverty_rate:.2f}%\")\n", + "print(f\"Reformed poverty rate (with kicker): {reformed_poverty_rate:.2f}%\")\n", + "print(f\"Change in poverty rate: {reformed_poverty_rate - baseline_poverty_rate:.2f} pp\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================================\n", + "Oregon Kicker Credit Impact Summary (2024) - TEST\n", + "==================================================\n", + "\n", + "Applying 2025 kicker rate (9.86%) to 2024\n", + "\n", + "Fiscal Impact:\n", + " Cost to state revenue: $1.53 billion\n", + "\n", + "Distributional Impact:\n", + " Total benefit to households: $1.53 billion\n", + " Share of households benefiting: 84.2%\n", + "\n", + "Poverty Impact:\n", + " Change in poverty rate: -0.22 pp\n" + ] + } + ], + "source": [ + "print(\"=\" * 50)\n", + "print(\"Oregon Kicker Credit Impact Summary (2024) - TEST\")\n", + "print(\"=\" * 50)\n", + "print(f\"\\nApplying 2025 kicker rate ({KICKER_RATE_2025*100:.2f}%) to 2024\")\n", + "print(f\"\\nFiscal Impact:\")\n", + "print(f\" Cost to state revenue: ${-revenue_change / 1e9:.2f} billion\")\n", + "print(f\"\\nDistributional Impact:\")\n", + "print(f\" Total benefit to households: ${total_income_change / 1e9:.2f} billion\")\n", + "print(f\" Share of households benefiting: {winners.sum() / total_hh * 100:.1f}%\")\n", + "print(f\"\\nPoverty Impact:\")\n", + "print(f\" Change in poverty rate: {reformed_poverty_rate - baseline_poverty_rate:.2f} pp\")" + ] + } + ], + "metadata": { + "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.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/us/searchlight_institute/reform_1_10year_budgetary_impact.csv b/us/searchlight_institute/reform_1_10year_budgetary_impact.csv new file mode 100644 index 0000000..a377871 --- /dev/null +++ b/us/searchlight_institute/reform_1_10year_budgetary_impact.csv @@ -0,0 +1,11 @@ +Year,Budgetary Impact +2026,-154164001783.69482 +2027,-157864084761.3623 +2028,-164597276521.37793 +2029,-167287528290.4707 +2030,-175556385052.03516 +2031,-169573356121.84375 +2032,-176599302199.34863 +2033,-178463440201.4834 +2034,-177017552448.71387 +2035,-180123710118.63232 diff --git a/us/searchlight_institute/reform_1_analysis.ipynb b/us/searchlight_institute/reform_1_analysis.ipynb new file mode 100644 index 0000000..376a558 --- /dev/null +++ b/us/searchlight_institute/reform_1_analysis.ipynb @@ -0,0 +1,2648 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Searchlight Institute Tax Reform Analysis\n", + "\n", + "This notebook analyzes the comprehensive impact of the Searchlight Institute tax reform proposal:\n", + "- Full aggregate impacts for 2026 (deciles, poverty, winners/losers, income brackets)\n", + "- 10-year federal budgetary impact (2026-2035)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from policyengine_us import Microsimulation\n", + "from policyengine_core.reforms import Reform\n", + "import pandas as pd\n", + "import numpy as np\n", + "import plotly.graph_objects as go\n", + "from policyengine_core.charts import format_fig\n", + "import csv" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Searchlight Institute Tax Reform\n", + "# - AFA CTC reforms\n", + "# - EITC eligibility and amount changes\n", + "# - EITC joint bonus set equal to phase-out start values\n", + "\n", + "REFORM_DICT = {\n", + " \"gov.contrib.congress.afa.in_effect\": {\n", + " \"2026-01-01.2100-12-31\": True\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.amount.base\": {\n", + " \"2026-01-01.2026-12-31\": 3600,\n", + " \"2027-01-01.2027-12-31\": 3720,\n", + " \"2028-01-01.2028-12-31\": 3840,\n", + " \"2029-01-01.2029-12-31\": 3960,\n", + " \"2030-01-01.2031-12-31\": 4080,\n", + " \"2032-01-01.2032-12-31\": 4200,\n", + " \"2033-01-01.2034-12-31\": 4320,\n", + " \"2035-01-01.2035-12-31\": 4440\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.max\": {\n", + " \"2026-01-01.2100-12-31\": 200\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.min\": {\n", + " \"2026-01-01.2100-12-31\": 19\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.min_student\": {\n", + " \"2026-01-01.2100-12-31\": 24\n", + " },\n", + " \"gov.irs.credits.eitc.max[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 1502,\n", + " \"2027-01-01.2027-12-31\": 1577,\n", + " \"2028-01-01.2028-12-31\": 1610,\n", + " \"2029-01-01.2029-12-31\": 1645,\n", + " \"2030-01-01.2030-12-31\": 1678,\n", + " \"2031-01-01.2031-12-31\": 1712,\n", + " \"2032-01-01.2032-12-31\": 1746,\n", + " \"2033-01-01.2033-12-31\": 1779,\n", + " \"2034-01-01.2034-12-31\": 1815,\n", + " \"2035-01-01.2035-12-31\": 1851\n", + " },\n", + " \"gov.irs.credits.eitc.phase_in_rate[0].amount\": {\n", + " \"2026-01-01.2100-12-31\": 0.153\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.rate[0].amount\": {\n", + " \"2026-01-01.2100-12-31\": 0.153\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.start[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 11610,\n", + " \"2027-01-01.2027-12-31\": 12190,\n", + " \"2028-01-01.2028-12-31\": 12440,\n", + " \"2029-01-01.2029-12-31\": 12710,\n", + " \"2030-01-01.2030-12-31\": 12970,\n", + " \"2031-01-01.2031-12-31\": 13230,\n", + " \"2032-01-01.2032-12-31\": 13490,\n", + " \"2033-01-01.2033-12-31\": 13750,\n", + " \"2034-01-01.2034-12-31\": 14030,\n", + " \"2035-01-01.2035-12-31\": 14300\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.joint_bonus[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 11610,\n", + " \"2027-01-01.2027-12-31\": 12190,\n", + " \"2028-01-01.2028-12-31\": 12440,\n", + " \"2029-01-01.2029-12-31\": 12710,\n", + " \"2030-01-01.2030-12-31\": 12970,\n", + " \"2031-01-01.2031-12-31\": 13230,\n", + " \"2032-01-01.2032-12-31\": 13490,\n", + " \"2033-01-01.2033-12-31\": 13750,\n", + " \"2034-01-01.2034-12-31\": 14030,\n", + " \"2035-01-01.2035-12-31\": 14300\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.JOINT\": {\n", + " \"2026-01-01.2026-12-31\": 150000,\n", + " \"2027-01-01.2028-12-31\": 155000,\n", + " \"2029-01-01.2029-12-31\": 160000,\n", + " \"2030-01-01.2031-12-31\": 165000,\n", + " \"2032-01-01.2033-12-31\": 170000,\n", + " \"2034-01-01.2034-12-31\": 175000,\n", + " \"2035-01-01.2035-12-31\": 180000\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.SINGLE\": {\n", + " \"2026-01-01.2027-12-31\": 112500,\n", + " \"2028-01-01.2029-12-31\": 117500,\n", + " \"2030-01-01.2031-12-31\": 122500,\n", + " \"2032-01-01.2033-12-31\": 127500,\n", + " \"2034-01-01.2035-12-31\": 132500\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.SURVIVING_SPOUSE\": {\n", + " \"2026-01-01.2026-12-31\": 150000,\n", + " \"2027-01-01.2028-12-31\": 155000,\n", + " \"2029-01-01.2029-12-31\": 160000,\n", + " \"2030-01-01.2031-12-31\": 165000,\n", + " \"2032-01-01.2033-12-31\": 170000,\n", + " \"2034-01-01.2034-12-31\": 175000,\n", + " \"2035-01-01.2035-12-31\": 180000\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.HEAD_OF_HOUSEHOLD\": {\n", + " \"2026-01-01.2027-12-31\": 112500,\n", + " \"2028-01-01.2029-12-31\": 117500,\n", + " \"2030-01-01.2031-12-31\": 122500,\n", + " \"2032-01-01.2033-12-31\": 127500,\n", + " \"2034-01-01.2035-12-31\": 132500\n", + " }\n", + "}\n", + "\n", + "searchlight_reform = Reform.from_dict(REFORM_DICT, country_id=\"us\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comprehensive 2026 Impact Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Intra-decile bounds and labels\n", + "_INTRA_BOUNDS = [-np.inf, -0.05, -1e-3, 1e-3, 0.05, np.inf]\n", + "_INTRA_LABELS = [\n", + " \"Lose more than 5%\",\n", + " \"Lose less than 5%\",\n", + " \"No change\",\n", + " \"Gain less than 5%\",\n", + " \"Gain more than 5%\",\n", + "]\n", + "\n", + "DATASET = \"hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5\"\n", + "\n", + "\n", + "def _poverty_metrics(baseline_rate, reform_rate):\n", + " \"\"\"Return rate change and percent change for a poverty metric.\"\"\"\n", + " rate_change = reform_rate - baseline_rate\n", + " percent_change = (\n", + " rate_change / baseline_rate * 100\n", + " if baseline_rate > 0\n", + " else 0.0\n", + " )\n", + " return rate_change, percent_change\n", + "\n", + "\n", + "def calculate_aggregate_impact(reform, year: int = 2026) -> dict:\n", + " sim_baseline = Microsimulation(dataset=DATASET)\n", + " sim_reform = Microsimulation(reform=reform, dataset=DATASET)\n", + "\n", + " # ===== FISCAL IMPACT =====\n", + " tax_baseline = sim_baseline.calculate(\n", + " \"income_tax\", period=year, map_to=\"household\"\n", + " )\n", + " tax_reform = sim_reform.calculate(\n", + " \"income_tax\", period=year, map_to=\"household\"\n", + " )\n", + " income_change = tax_baseline - tax_reform\n", + " tax_revenue_impact = float(-income_change.sum())\n", + "\n", + " # Total households\n", + " total_households = float((income_change * 0 + 1).sum())\n", + "\n", + " # ===== WINNERS / LOSERS =====\n", + " winners = float((income_change > 1).sum())\n", + " losers = float((income_change < -1).sum())\n", + " beneficiaries = float((income_change > 0).sum())\n", + "\n", + " affected = abs(income_change) > 1\n", + " affected_count = float(affected.sum())\n", + "\n", + " household_weight_early = sim_reform.calculate(\n", + " \"household_weight\", period=year\n", + " )\n", + " affected_mask = np.array(affected).astype(bool)\n", + " change_arr_early = np.array(income_change)\n", + " weight_arr_early = np.array(household_weight_early)\n", + " avg_benefit = (\n", + " float(np.average(\n", + " change_arr_early[affected_mask],\n", + " weights=weight_arr_early[affected_mask],\n", + " ))\n", + " if affected_count > 0\n", + " else 0.0\n", + " )\n", + "\n", + " winners_rate = winners / total_households * 100\n", + " losers_rate = losers / total_households * 100\n", + "\n", + " # ===== INCOME DECILE ANALYSIS =====\n", + " decile = sim_baseline.calculate(\n", + " \"household_income_decile\", period=year, map_to=\"household\"\n", + " )\n", + " baseline_net_income = sim_baseline.calculate(\n", + " \"household_net_income\", period=year, map_to=\"household\"\n", + " )\n", + "\n", + " decile_average = {}\n", + " decile_relative = {}\n", + " for d in range(1, 11):\n", + " dmask = decile == d\n", + " d_count = float(dmask.sum())\n", + " if d_count > 0:\n", + " d_change_sum = float(income_change[dmask].sum())\n", + " decile_average[str(d)] = d_change_sum / d_count\n", + " d_baseline_sum = float(baseline_net_income[dmask].sum())\n", + " decile_relative[str(d)] = (\n", + " d_change_sum / d_baseline_sum\n", + " if d_baseline_sum != 0\n", + " else 0.0\n", + " )\n", + " else:\n", + " decile_average[str(d)] = 0.0\n", + " decile_relative[str(d)] = 0.0\n", + "\n", + " # Intra-decile\n", + " household_weight = sim_reform.calculate(\n", + " \"household_weight\", period=year\n", + " )\n", + " people_per_hh = sim_baseline.calculate(\n", + " \"household_count_people\", period=year, map_to=\"household\"\n", + " )\n", + " capped_baseline = np.maximum(np.array(baseline_net_income), 1)\n", + " rel_change_arr = np.array(income_change) / capped_baseline\n", + "\n", + " decile_arr = np.array(decile)\n", + " weight_arr = np.array(household_weight)\n", + " people_weighted = np.array(people_per_hh) * weight_arr\n", + "\n", + " intra_decile_deciles = {label: [] for label in _INTRA_LABELS}\n", + " for d in range(1, 11):\n", + " dmask = decile_arr == d\n", + " d_people = people_weighted[dmask]\n", + " d_total_people = d_people.sum()\n", + " d_rel = rel_change_arr[dmask]\n", + "\n", + " for lower, upper, label in zip(\n", + " _INTRA_BOUNDS[:-1], _INTRA_BOUNDS[1:], _INTRA_LABELS\n", + " ):\n", + " in_group = (d_rel > lower) & (d_rel <= upper)\n", + " proportion = (\n", + " float(d_people[in_group].sum() / d_total_people)\n", + " if d_total_people > 0\n", + " else 0.0\n", + " )\n", + " intra_decile_deciles[label].append(proportion)\n", + "\n", + " intra_decile_all = {\n", + " label: sum(intra_decile_deciles[label]) / 10\n", + " for label in _INTRA_LABELS\n", + " }\n", + "\n", + " # ===== POVERTY IMPACT =====\n", + " pov_bl = sim_baseline.calculate(\n", + " \"in_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " pov_rf = sim_reform.calculate(\n", + " \"in_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " poverty_baseline_rate = float(pov_bl.mean() * 100)\n", + " poverty_reform_rate = float(pov_rf.mean() * 100)\n", + " poverty_rate_change, poverty_percent_change = _poverty_metrics(\n", + " poverty_baseline_rate, poverty_reform_rate\n", + " )\n", + "\n", + " # Child/deep poverty\n", + " age_arr = np.array(sim_baseline.calculate(\"age\", period=year))\n", + " is_child = age_arr < 18\n", + " pw_arr = np.array(sim_baseline.calculate(\"person_weight\", period=year))\n", + " child_w = pw_arr[is_child]\n", + " total_child_w = child_w.sum()\n", + "\n", + " pov_bl_arr = np.array(pov_bl).astype(bool)\n", + " pov_rf_arr = np.array(pov_rf).astype(bool)\n", + "\n", + " def _child_rate(arr):\n", + " return float(\n", + " (arr[is_child] * child_w).sum() / total_child_w * 100\n", + " ) if total_child_w > 0 else 0.0\n", + "\n", + " child_poverty_baseline_rate = _child_rate(pov_bl_arr)\n", + " child_poverty_reform_rate = _child_rate(pov_rf_arr)\n", + " child_poverty_rate_change, child_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " child_poverty_baseline_rate, child_poverty_reform_rate\n", + " )\n", + " )\n", + "\n", + " deep_bl = sim_baseline.calculate(\n", + " \"in_deep_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " deep_rf = sim_reform.calculate(\n", + " \"in_deep_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " deep_poverty_baseline_rate = float(deep_bl.mean() * 100)\n", + " deep_poverty_reform_rate = float(deep_rf.mean() * 100)\n", + " deep_poverty_rate_change, deep_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " deep_poverty_baseline_rate, deep_poverty_reform_rate\n", + " )\n", + " )\n", + "\n", + " deep_bl_arr = np.array(deep_bl).astype(bool)\n", + " deep_rf_arr = np.array(deep_rf).astype(bool)\n", + " deep_child_poverty_baseline_rate = _child_rate(deep_bl_arr)\n", + " deep_child_poverty_reform_rate = _child_rate(deep_rf_arr)\n", + " deep_child_poverty_rate_change, deep_child_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " deep_child_poverty_baseline_rate,\n", + " deep_child_poverty_reform_rate,\n", + " )\n", + " )\n", + "\n", + " # ===== INCOME BRACKET BREAKDOWN =====\n", + " agi = sim_reform.calculate(\n", + " \"adjusted_gross_income\", period=year, map_to=\"household\"\n", + " )\n", + " agi_arr = np.array(agi)\n", + " change_arr = np.array(income_change)\n", + " affected_mask = np.abs(change_arr) > 1\n", + "\n", + " income_brackets = [\n", + " (0, 50_000, \"Under $50k\"),\n", + " (50_000, 100_000, \"$50k-$100k\"),\n", + " (100_000, 200_000, \"$100k-$200k\"),\n", + " (200_000, 500_000, \"$200k-$500k\"),\n", + " (500_000, 1_000_000, \"$500k-$1M\"),\n", + " (1_000_000, 2_000_000, \"$1M-$2M\"),\n", + " (2_000_000, float(\"inf\"), \"Over $2M\"),\n", + " ]\n", + "\n", + " by_income_bracket = []\n", + " for min_inc, max_inc, label in income_brackets:\n", + " mask = (\n", + " (agi_arr >= min_inc)\n", + " & (agi_arr < max_inc)\n", + " & affected_mask\n", + " )\n", + " bracket_affected = float(weight_arr[mask].sum())\n", + " if bracket_affected > 0:\n", + " bracket_cost = float(\n", + " (change_arr[mask] * weight_arr[mask]).sum()\n", + " )\n", + " bracket_avg = float(\n", + " np.average(change_arr[mask], weights=weight_arr[mask])\n", + " )\n", + " else:\n", + " bracket_cost = 0.0\n", + " bracket_avg = 0.0\n", + " by_income_bracket.append({\n", + " \"bracket\": label,\n", + " \"beneficiaries\": bracket_affected,\n", + " \"total_cost\": bracket_cost,\n", + " \"avg_benefit\": bracket_avg,\n", + " })\n", + "\n", + " return {\n", + " \"budget\": {\n", + " \"budgetary_impact\": tax_revenue_impact,\n", + " \"tax_revenue_impact\": tax_revenue_impact,\n", + " \"benefit_spending_impact\": 0.0,\n", + " \"households\": total_households,\n", + " },\n", + " \"decile\": {\n", + " \"average\": decile_average,\n", + " \"relative\": decile_relative,\n", + " },\n", + " \"intra_decile\": {\n", + " \"all\": intra_decile_all,\n", + " \"deciles\": intra_decile_deciles,\n", + " },\n", + " \"total_cost\": -tax_revenue_impact,\n", + " \"beneficiaries\": beneficiaries,\n", + " \"avg_benefit\": avg_benefit,\n", + " \"winners\": winners,\n", + " \"losers\": losers,\n", + " \"winners_rate\": winners_rate,\n", + " \"losers_rate\": losers_rate,\n", + " \"poverty_baseline_rate\": poverty_baseline_rate,\n", + " \"poverty_reform_rate\": poverty_reform_rate,\n", + " \"poverty_rate_change\": poverty_rate_change,\n", + " \"poverty_percent_change\": poverty_percent_change,\n", + " \"child_poverty_baseline_rate\": child_poverty_baseline_rate,\n", + " \"child_poverty_reform_rate\": child_poverty_reform_rate,\n", + " \"child_poverty_rate_change\": child_poverty_rate_change,\n", + " \"child_poverty_percent_change\": child_poverty_percent_change,\n", + " \"deep_poverty_baseline_rate\": deep_poverty_baseline_rate,\n", + " \"deep_poverty_reform_rate\": deep_poverty_reform_rate,\n", + " \"deep_poverty_rate_change\": deep_poverty_rate_change,\n", + " \"deep_poverty_percent_change\": deep_poverty_percent_change,\n", + " \"deep_child_poverty_baseline_rate\": deep_child_poverty_baseline_rate,\n", + " \"deep_child_poverty_reform_rate\": deep_child_poverty_reform_rate,\n", + " \"deep_child_poverty_rate_change\": deep_child_poverty_rate_change,\n", + " \"deep_child_poverty_percent_change\": deep_child_poverty_percent_change,\n", + " \"by_income_bracket\": by_income_bracket,\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": "# Calculate comprehensive 2026 impacts\nprint(\"Calculating comprehensive 2026 impacts...\")\nimpact_2026 = calculate_aggregate_impact(searchlight_reform, year=2026)\nprint(\"Done!\")\n\n# Export 2026 impact to CSV immediately\ndef export_2026_impact_to_csv(impact, filename):\n \"\"\"Export the 2026 impact results to a CSV file.\"\"\"\n rows = [\n [\"Metric\", \"Value\"],\n [\"Budgetary Impact ($)\", impact['budget']['budgetary_impact']],\n [\"Total Cost ($)\", impact['total_cost']],\n [\"Total Households\", impact['budget']['households']],\n [\"Winners\", impact['winners']],\n [\"Winners Rate (%)\", impact['winners_rate']],\n [\"Losers\", impact['losers']],\n [\"Losers Rate (%)\", impact['losers_rate']],\n [\"Beneficiaries\", impact['beneficiaries']],\n [\"Average Benefit ($)\", impact['avg_benefit']],\n [\"Poverty Baseline Rate (%)\", impact['poverty_baseline_rate']],\n [\"Poverty Reform Rate (%)\", impact['poverty_reform_rate']],\n [\"Poverty Rate Change (pp)\", impact['poverty_rate_change']],\n [\"Poverty Percent Change (%)\", impact['poverty_percent_change']],\n [\"Child Poverty Baseline Rate (%)\", impact['child_poverty_baseline_rate']],\n [\"Child Poverty Reform Rate (%)\", impact['child_poverty_reform_rate']],\n [\"Child Poverty Rate Change (pp)\", impact['child_poverty_rate_change']],\n [\"Child Poverty Percent Change (%)\", impact['child_poverty_percent_change']],\n [\"Deep Poverty Baseline Rate (%)\", impact['deep_poverty_baseline_rate']],\n [\"Deep Poverty Reform Rate (%)\", impact['deep_poverty_reform_rate']],\n [\"Deep Poverty Rate Change (pp)\", impact['deep_poverty_rate_change']],\n [\"Deep Poverty Percent Change (%)\", impact['deep_poverty_percent_change']],\n [\"Deep Child Poverty Baseline Rate (%)\", impact['deep_child_poverty_baseline_rate']],\n [\"Deep Child Poverty Reform Rate (%)\", impact['deep_child_poverty_reform_rate']],\n [\"Deep Child Poverty Rate Change (pp)\", impact['deep_child_poverty_rate_change']],\n [\"Deep Child Poverty Percent Change (%)\", impact['deep_child_poverty_percent_change']],\n ]\n \n # Add decile data\n for d in range(1, 11):\n rows.append([f\"Decile {d} Average Change ($)\", impact['decile']['average'][str(d)]])\n rows.append([f\"Decile {d} Relative Change\", impact['decile']['relative'][str(d)]])\n \n # Add income bracket data\n for bracket in impact['by_income_bracket']:\n rows.append([f\"Bracket {bracket['bracket']} Beneficiaries\", bracket['beneficiaries']])\n rows.append([f\"Bracket {bracket['bracket']} Total Cost ($)\", bracket['total_cost']])\n rows.append([f\"Bracket {bracket['bracket']} Avg Benefit ($)\", bracket['avg_benefit']])\n \n with open(filename, 'w', newline='') as f:\n writer = csv.writer(f)\n writer.writerows(rows)\n \n print(f\"2026 impact saved to {filename}\")\n\nexport_2026_impact_to_csv(impact_2026, \"reform_1_impact_2026.csv\")" + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "============================================================\n", + "BUDGET SUMMARY (2026)\n", + "============================================================\n", + "Budgetary Impact: $-154.16 billion\n", + "Total Cost: $154.16 billion\n", + "Total Households: 147,829,631\n" + ] + } + ], + "source": [ + "# Display budget summary\n", + "print(\"=\" * 60)\n", + "print(\"BUDGET SUMMARY (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"Budgetary Impact: ${impact_2026['budget']['budgetary_impact'] / 1e9:.2f} billion\")\n", + "print(f\"Total Cost: ${impact_2026['total_cost'] / 1e9:.2f} billion\")\n", + "print(f\"Total Households: {impact_2026['budget']['households']:,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "WINNERS / LOSERS (2026)\n", + "============================================================\n", + "Winners: 47,269,974 (32.0%)\n", + "Losers: 4,503,176 (3.0%)\n", + "Beneficiaries: 47,272,404\n", + "Average Benefit (affected): $2,977.68\n" + ] + } + ], + "source": [ + "# Display winners/losers\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"WINNERS / LOSERS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"Winners: {impact_2026['winners']:,.0f} ({impact_2026['winners_rate']:.1f}%)\")\n", + "print(f\"Losers: {impact_2026['losers']:,.0f} ({impact_2026['losers_rate']:.1f}%)\")\n", + "print(f\"Beneficiaries: {impact_2026['beneficiaries']:,.0f}\")\n", + "print(f\"Average Benefit (affected): ${impact_2026['avg_benefit']:,.2f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "POVERTY IMPACTS (2026)\n", + "============================================================\n", + "\n", + "Overall Poverty:\n", + " Baseline: 23.33%\n", + " Reform: 21.48%\n", + " Change: -1.85pp (-7.9%)\n", + "\n", + "Child Poverty:\n", + " Baseline: 22.00%\n", + " Reform: 16.98%\n", + " Change: -5.02pp (-22.8%)\n", + "\n", + "Deep Poverty:\n", + " Baseline: 8.70%\n", + " Reform: 7.36%\n", + " Change: -1.35pp (-15.5%)\n", + "\n", + "Deep Child Poverty:\n", + " Baseline: 8.56%\n", + " Reform: 5.33%\n", + " Change: -3.23pp (-37.7%)\n" + ] + } + ], + "source": [ + "# Display poverty impacts\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"POVERTY IMPACTS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"\\nOverall Poverty:\")\n", + "print(f\" Baseline: {impact_2026['poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['poverty_rate_change']:+.2f}pp ({impact_2026['poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nChild Poverty:\")\n", + "print(f\" Baseline: {impact_2026['child_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['child_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['child_poverty_rate_change']:+.2f}pp ({impact_2026['child_poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nDeep Poverty:\")\n", + "print(f\" Baseline: {impact_2026['deep_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['deep_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['deep_poverty_rate_change']:+.2f}pp ({impact_2026['deep_poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nDeep Child Poverty:\")\n", + "print(f\" Baseline: {impact_2026['deep_child_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['deep_child_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['deep_child_poverty_rate_change']:+.2f}pp ({impact_2026['deep_child_poverty_percent_change']:+.1f}%)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "DECILE ANALYSIS (2026)\n", + "============================================================\n", + "Decile Avg Change Relative Change\n", + "---------------------------------------------\n", + "1 $ 929 8.06%\n", + "2 $ 1,014 3.79%\n", + "3 $ 905 2.26%\n", + "4 $ 1,425 2.63%\n", + "5 $ 1,896 2.69%\n", + "6 $ 1,187 1.37%\n", + "7 $ 1,189 1.07%\n", + "8 $ 1,155 0.79%\n", + "9 $ 517 0.26%\n", + "10 $ 202 0.03%\n" + ] + } + ], + "source": [ + "# Display decile analysis\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"DECILE ANALYSIS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"{'Decile':<10} {'Avg Change':>15} {'Relative Change':>18}\")\n", + "print(\"-\" * 45)\n", + "for d in range(1, 11):\n", + " avg = impact_2026['decile']['average'][str(d)]\n", + " rel = impact_2026['decile']['relative'][str(d)] * 100\n", + " print(f\"{d:<10} ${avg:>14,.0f} {rel:>17.2f}%\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "INCOME BRACKET BREAKDOWN (2026)\n", + "============================================================\n", + "Bracket Beneficiaries Total Cost Avg Benefit\n", + "------------------------------------------------------------\n", + "Under $50k 21,366,040 $ 74.28B $ 3,477\n", + "$50k-$100k 12,473,454 $ 41.58B $ 3,333\n", + "$100k-$200k 11,142,482 $ 31.15B $ 2,796\n", + "$200k-$500k 5,445,492 $ 2.53B $ 465\n", + "$500k-$1M 335,220 $ 0.72B $ 2,143\n", + "$1M-$2M 31,084 $ 0.05B $ 1,747\n", + "Over $2M 8,306 $ 0.01B $ 1,203\n" + ] + } + ], + "source": [ + "# Display income bracket breakdown\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"INCOME BRACKET BREAKDOWN (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"{'Bracket':<15} {'Beneficiaries':>15} {'Total Cost':>15} {'Avg Benefit':>12}\")\n", + "print(\"-\" * 60)\n", + "for bracket in impact_2026['by_income_bracket']:\n", + " print(f\"{bracket['bracket']:<15} {bracket['beneficiaries']:>15,.0f} ${bracket['total_cost']/1e9:>13.2f}B ${bracket['avg_benefit']:>10,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "marker": { + "color": "#105293" + }, + "text": [ + "$929", + "$1,014", + "$905", + "$1,425", + "$1,896", + "$1,187", + "$1,189", + "$1,155", + "$517", + "$202" + ], + "textposition": "auto", + "type": "bar", + "x": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "y": [ + 928.6588902691982, + 1013.860060164923, + 905.2904728398725, + 1424.6851236296905, + 1895.8465136209072, + 1186.772328990473, + 1188.95953156828, + 1155.0580162318406, + 516.8394540088157, + 202.37838338438473 + ] + } + ], + "layout": { + "font": { + "color": "black", + "family": "Roboto Serif" + }, + "height": 600, + "images": [ + { + "sizex": 0.15, + "sizey": 0.15, + "source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png", + "x": 1.1, + "xanchor": "right", + "xref": "paper", + "y": -0.15, + "yanchor": "bottom", + "yref": "paper" + } + ], + "modebar": { + "bgcolor": "rgba(0,0,0,0)", + "color": "rgba(0,0,0,0)" + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Average Income Change by Decile (2026)" + }, + "width": 800, + "xaxis": { + "tickmode": "linear", + "title": { + "text": "Income Decile" + } + }, + "yaxis": { + "title": { + "text": "Average Change ($)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Create decile bar chart\n", + "deciles = list(range(1, 11))\n", + "avg_changes = [impact_2026['decile']['average'][str(d)] for d in deciles]\n", + "\n", + "fig = go.Figure(\n", + " go.Bar(\n", + " x=deciles,\n", + " y=avg_changes,\n", + " text=[f\"${v:,.0f}\" for v in avg_changes],\n", + " textposition=\"auto\",\n", + " marker_color=\"#105293\",\n", + " )\n", + ")\n", + "\n", + "fig.update_layout(\n", + " title=\"Average Income Change by Decile (2026)\",\n", + " xaxis_title=\"Income Decile\",\n", + " yaxis_title=\"Average Change ($)\",\n", + " xaxis=dict(tickmode=\"linear\"),\n", + ")\n", + "\n", + "format_fig(fig).show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 10-Year Federal Budgetary Impact (2026-2035)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def calculate_budgetary_impact(reform, year):\n", + " \"\"\"Calculate just the federal income tax budgetary impact for a single year.\"\"\"\n", + " baseline = Microsimulation(dataset=DATASET)\n", + " reformed = Microsimulation(reform=reform, dataset=DATASET)\n", + " \n", + " baseline_income_tax = baseline.calculate(\"income_tax\", period=year).sum()\n", + " reformed_income_tax = reformed.calculate(\"income_tax\", period=year).sum()\n", + " \n", + " # Budgetary impact: negative means costs money (reform reduces tax revenue)\n", + " impact = reformed_income_tax - baseline_income_tax\n", + " return float(impact)\n", + "\n", + "\n", + "def calculate_ten_year_projection(reform, csv_filename=\"reform_1_10year_budgetary_impact.csv\"):\n", + " results = []\n", + "\n", + " with open(csv_filename, \"w\", newline=\"\") as csvfile:\n", + " csvwriter = csv.writer(csvfile)\n", + " csvwriter.writerow([\"Year\", \"Budgetary Impact\"])\n", + "\n", + " for year in range(2026, 2036):\n", + " print(f\"Computing budgetary impact for year {year}...\")\n", + " impact = calculate_budgetary_impact(reform, year)\n", + " results.append({\"Year\": year, \"Budgetary Impact\": impact})\n", + "\n", + " csvwriter.writerow([year, impact])\n", + " print(f\"Year {year} completed. Impact: ${impact/1e9:.2f} billion\")\n", + "\n", + " print(f\"All calculations complete. Results saved to '{csv_filename}'\")\n", + " return pd.DataFrame(results)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting 10-year budgetary impact calculation...\n", + "Computing budgetary impact for year 2026...\n", + "Year 2026 completed. Impact: $-154.16 billion\n", + "Computing budgetary impact for year 2027...\n", + "Year 2027 completed. Impact: $-157.86 billion\n", + "Computing budgetary impact for year 2028...\n", + "Year 2028 completed. Impact: $-164.60 billion\n", + "Computing budgetary impact for year 2029...\n", + "Year 2029 completed. Impact: $-167.29 billion\n", + "Computing budgetary impact for year 2030...\n", + "Year 2030 completed. Impact: $-175.56 billion\n", + "Computing budgetary impact for year 2031...\n", + "Year 2031 completed. Impact: $-169.57 billion\n", + "Computing budgetary impact for year 2032...\n", + "Year 2032 completed. Impact: $-176.60 billion\n", + "Computing budgetary impact for year 2033...\n", + "Year 2033 completed. Impact: $-178.46 billion\n", + "Computing budgetary impact for year 2034...\n", + "Year 2034 completed. Impact: $-177.02 billion\n", + "Computing budgetary impact for year 2035...\n", + "Year 2035 completed. Impact: $-180.12 billion\n", + "All calculations complete. Results saved to 'reform_1_10year_budgetary_impact.csv'\n", + "\n", + "Calculation complete. Summary of results:\n", + " Year Budgetary Impact\n", + "0 2026 -1.541640e+11\n", + "1 2027 -1.578641e+11\n", + "2 2028 -1.645973e+11\n", + "3 2029 -1.672875e+11\n", + "4 2030 -1.755564e+11\n", + "5 2031 -1.695734e+11\n", + "6 2032 -1.765993e+11\n", + "7 2033 -1.784634e+11\n", + "8 2034 -1.770176e+11\n", + "9 2035 -1.801237e+11\n", + "\n", + "10-Year Total: $-1701.25 billion\n" + ] + } + ], + "source": [ + "# Calculate 10-year projection\n", + "print(\"Starting 10-year budgetary impact calculation...\")\n", + "df_projection = calculate_ten_year_projection(searchlight_reform)\n", + "print(\"\\nCalculation complete. Summary of results:\")\n", + "print(df_projection)\n", + "print(f\"\\n10-Year Total: ${df_projection['Budgetary Impact'].sum() / 1e9:.2f} billion\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "marker": { + "color": "#105293" + }, + "text": [ + "$-154.2B", + "$-157.9B", + "$-164.6B", + "$-167.3B", + "$-175.6B", + "$-169.6B", + "$-176.6B", + "$-178.5B", + "$-177.0B", + "$-180.1B" + ], + "textposition": "auto", + "type": "bar", + "x": [ + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032, + 2033, + 2034, + 2035 + ], + "y": [ + -154.2, + -157.9, + -164.6, + -167.3, + -175.6, + -169.6, + -176.6, + -178.5, + -177, + -180.1 + ] + } + ], + "layout": { + "font": { + "color": "black", + "family": "Roboto Serif" + }, + "height": 600, + "images": [ + { + "sizex": 0.15, + "sizey": 0.15, + "source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png", + "x": 1.1, + "xanchor": "right", + "xref": "paper", + "y": -0.15, + "yanchor": "bottom", + "yref": "paper" + } + ], + "modebar": { + "bgcolor": "rgba(0,0,0,0)", + "color": "rgba(0,0,0,0)" + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "10-Year Federal Budgetary Impact of Searchlight Institute Tax Reform" + }, + "width": 800, + "xaxis": { + "tickmode": "linear", + "title": { + "text": "Year" + } + }, + "yaxis": { + "title": { + "text": "Budgetary Impact (Billions $)" + }, + "zeroline": true, + "zerolinecolor": "Black", + "zerolinewidth": 2 + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Create 10-year bar chart\n", + "fig = go.Figure(\n", + " go.Bar(\n", + " x=df_projection[\"Year\"],\n", + " y=(df_projection[\"Budgetary Impact\"] / 1e9).round(1),\n", + " text=(df_projection[\"Budgetary Impact\"] / 1e9)\n", + " .round(1)\n", + " .apply(lambda x: f\"${x:.1f}B\"),\n", + " textposition=\"auto\",\n", + " marker_color=\"#105293\",\n", + " )\n", + ")\n", + "\n", + "fig.update_layout(\n", + " title=\"10-Year Federal Budgetary Impact of Searchlight Institute Tax Reform\",\n", + " xaxis_title=\"Year\",\n", + " yaxis_title=\"Budgetary Impact (Billions $)\",\n", + " xaxis=dict(tickmode=\"linear\"),\n", + " yaxis=dict(zeroline=True, zerolinewidth=2, zerolinecolor=\"Black\"),\n", + ")\n", + "\n", + "format_fig(fig).show()" + ] + } + ], + "metadata": { + "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.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file diff --git a/us/searchlight_institute/reform_1_impact_2026.csv b/us/searchlight_institute/reform_1_impact_2026.csv new file mode 100644 index 0000000..9d258b7 --- /dev/null +++ b/us/searchlight_institute/reform_1_impact_2026.csv @@ -0,0 +1,67 @@ +Metric,Value +Budgetary Impact ($),-154164001783.69482 +Total Cost ($),154164001783.69482 +Total Households,147829631.20700648 +Winners,47269974.12108015 +Winners Rate (%),31.97598054945277 +Losers,4503176.1464319825 +Losers Rate (%),3.046193181748634 +Beneficiaries,47272404.40269636 +Average Benefit ($),2977.682461745086 +Poverty Baseline Rate (%),23.33367114033999 +Poverty Reform Rate (%),21.48264999239379 +Poverty Rate Change (pp),-1.8510211479462022 +Poverty Percent Change (%),-7.932832929774595 +Child Poverty Baseline Rate (%),21.99616050720215 +Child Poverty Reform Rate (%),16.97791862487793 +Child Poverty Rate Change (pp),-5.018241882324219 +Child Poverty Percent Change (%),-22.81417195824293 +Deep Poverty Baseline Rate (%),8.704698989314954 +Deep Poverty Reform Rate (%),7.359397582463532 +Deep Poverty Rate Change (pp),-1.345301406851422 +Deep Poverty Percent Change (%),-15.454887164998857 +Deep Child Poverty Baseline Rate (%),8.560979843139648 +Deep Child Poverty Reform Rate (%),5.333736896514893 +Deep Child Poverty Rate Change (pp),-3.227242946624756 +Deep Child Poverty Percent Change (%),-37.69712119122568 +Decile 1 Average Change ($),928.6588902691982 +Decile 1 Relative Change,0.08058464997765222 +Decile 2 Average Change ($),1013.860060164923 +Decile 2 Relative Change,0.03788473652062977 +Decile 3 Average Change ($),905.2904728398725 +Decile 3 Relative Change,0.022557856462306153 +Decile 4 Average Change ($),1424.6851236296905 +Decile 4 Relative Change,0.026272045978258943 +Decile 5 Average Change ($),1895.8465136209072 +Decile 5 Relative Change,0.026900278418685853 +Decile 6 Average Change ($),1186.772328990473 +Decile 6 Relative Change,0.013732198136512103 +Decile 7 Average Change ($),1188.95953156828 +Decile 7 Relative Change,0.01074242836086731 +Decile 8 Average Change ($),1155.0580162318406 +Decile 8 Relative Change,0.007910681803679423 +Decile 9 Average Change ($),516.8394540088157 +Decile 9 Relative Change,0.0026322721443851798 +Decile 10 Average Change ($),202.37838338438473 +Decile 10 Relative Change,0.0003007086056034714 +Bracket Under $50k Beneficiaries,21366040.0 +Bracket Under $50k Total Cost ($),74282020327.1552 +Bracket Under $50k Avg Benefit ($),3476.6397280520423 +Bracket $50k-$100k Beneficiaries,12473454.0 +Bracket $50k-$100k Total Cost ($),41576957126.07248 +Bracket $50k-$100k Avg Benefit ($),3333.2353940170988 +Bracket $100k-$200k Beneficiaries,11142482.0 +Bracket $100k-$200k Total Cost ($),31149494526.677044 +Bracket $100k-$200k Avg Benefit ($),2795.5615572901925 +Bracket $200k-$500k Beneficiaries,5445492.5 +Bracket $200k-$500k Total Cost ($),2531703154.8642535 +Bracket $200k-$500k Avg Benefit ($),464.9172064614434 +Bracket $500k-$1M Beneficiaries,335220.34375 +Bracket $500k-$1M Total Cost ($),718364347.578026 +Bracket $500k-$1M Avg Benefit ($),2142.9616745581297 +Bracket $1M-$2M Beneficiaries,31083.828125 +Bracket $1M-$2M Total Cost ($),54299420.781647265 +Bracket $1M-$2M Avg Benefit ($),1746.87052193152 +Bracket Over $2M Beneficiaries,8306.05078125 +Bracket Over $2M Total Cost ($),9991288.998794517 +Bracket Over $2M Avg Benefit ($),1202.892847495311 diff --git a/us/searchlight_institute/reform_2_10year_budgetary_impact.csv b/us/searchlight_institute/reform_2_10year_budgetary_impact.csv new file mode 100644 index 0000000..76ba2a4 --- /dev/null +++ b/us/searchlight_institute/reform_2_10year_budgetary_impact.csv @@ -0,0 +1,11 @@ +Year,Budgetary Impact +2026,-113443058010.38525 +2027,-116917420275.06738 +2028,-115483459551.44727 +2029,-118023403343.2334 +2030,-117954640627.83398 +2031,-120339708164.2998 +2032,-119068772615.61719 +2033,-121038947456.34717 +2034,-127727125431.44092 +2035,-122594164546.56543 diff --git a/us/searchlight_institute/reform_2_analysis.ipynb b/us/searchlight_institute/reform_2_analysis.ipynb new file mode 100644 index 0000000..1a96365 --- /dev/null +++ b/us/searchlight_institute/reform_2_analysis.ipynb @@ -0,0 +1,2752 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Searchlight Institute Tax Reform Analysis - Reform 2\n", + "\n", + "This notebook analyzes the comprehensive impact of the Searchlight Institute tax reform proposal (Reform 2):\n", + "- Full aggregate impacts for 2026 (deciles, poverty, winners/losers, income brackets)\n", + "- 10-year federal budgetary impact (2026-2035)\n", + "\n", + "**CTC Amounts:** $3,000 (2026) to $3,600 (2035)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from policyengine_us import Microsimulation\n", + "from policyengine_core.reforms import Reform\n", + "import pandas as pd\n", + "import numpy as np\n", + "import plotly.graph_objects as go\n", + "from policyengine_core.charts import format_fig\n", + "import csv" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Searchlight Institute Tax Reform - Reform 2\n", + "# - AFA CTC reforms (lower CTC amounts)\n", + "# - EITC eligibility and amount changes\n", + "# - EITC joint bonus set equal to phase-out start values\n", + "\n", + "REFORM_DICT = {\n", + " \"gov.contrib.congress.afa.in_effect\": {\n", + " \"2026-01-01.2100-12-31\": True\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.amount.base\": {\n", + " \"2026-01-01.2026-12-31\": 3000,\n", + " \"2027-01-01.2028-12-31\": 3120,\n", + " \"2029-01-01.2030-12-31\": 3240,\n", + " \"2031-01-01.2032-12-31\": 3360,\n", + " \"2033-01-01.2033-12-31\": 3480,\n", + " \"2034-01-01.2035-12-31\": 3600\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.max\": {\n", + " \"2026-01-01.2100-12-31\": 200\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.min\": {\n", + " \"2026-01-01.2100-12-31\": 19\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.min_student\": {\n", + " \"2026-01-01.2100-12-31\": 24\n", + " },\n", + " \"gov.irs.credits.eitc.max[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 1502,\n", + " \"2027-01-01.2027-12-31\": 1577,\n", + " \"2028-01-01.2028-12-31\": 1610,\n", + " \"2029-01-01.2029-12-31\": 1645,\n", + " \"2030-01-01.2030-12-31\": 1678,\n", + " \"2031-01-01.2031-12-31\": 1712,\n", + " \"2032-01-01.2032-12-31\": 1746,\n", + " \"2033-01-01.2033-12-31\": 1779,\n", + " \"2034-01-01.2034-12-31\": 1815,\n", + " \"2035-01-01.2035-12-31\": 1851\n", + " },\n", + " \"gov.irs.credits.eitc.phase_in_rate[0].amount\": {\n", + " \"2026-01-01.2100-12-31\": 0.153\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.rate[0].amount\": {\n", + " \"2026-01-01.2100-12-31\": 0.153\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.start[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 11610,\n", + " \"2027-01-01.2027-12-31\": 12190,\n", + " \"2028-01-01.2028-12-31\": 12440,\n", + " \"2029-01-01.2029-12-31\": 12710,\n", + " \"2030-01-01.2030-12-31\": 12970,\n", + " \"2031-01-01.2031-12-31\": 13230,\n", + " \"2032-01-01.2032-12-31\": 13490,\n", + " \"2033-01-01.2033-12-31\": 13750,\n", + " \"2034-01-01.2034-12-31\": 14030,\n", + " \"2035-01-01.2035-12-31\": 14300\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.joint_bonus[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 11610,\n", + " \"2027-01-01.2027-12-31\": 12190,\n", + " \"2028-01-01.2028-12-31\": 12440,\n", + " \"2029-01-01.2029-12-31\": 12710,\n", + " \"2030-01-01.2030-12-31\": 12970,\n", + " \"2031-01-01.2031-12-31\": 13230,\n", + " \"2032-01-01.2032-12-31\": 13490,\n", + " \"2033-01-01.2033-12-31\": 13750,\n", + " \"2034-01-01.2034-12-31\": 14030,\n", + " \"2035-01-01.2035-12-31\": 14300\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.JOINT\": {\n", + " \"2026-01-01.2026-12-31\": 150000,\n", + " \"2027-01-01.2028-12-31\": 155000,\n", + " \"2029-01-01.2029-12-31\": 160000,\n", + " \"2030-01-01.2031-12-31\": 165000,\n", + " \"2032-01-01.2033-12-31\": 170000,\n", + " \"2034-01-01.2034-12-31\": 175000,\n", + " \"2035-01-01.2035-12-31\": 180000\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.SINGLE\": {\n", + " \"2026-01-01.2027-12-31\": 112500,\n", + " \"2028-01-01.2029-12-31\": 117500,\n", + " \"2030-01-01.2031-12-31\": 122500,\n", + " \"2032-01-01.2033-12-31\": 127500,\n", + " \"2034-01-01.2035-12-31\": 132500\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.SURVIVING_SPOUSE\": {\n", + " \"2026-01-01.2026-12-31\": 150000,\n", + " \"2027-01-01.2028-12-31\": 155000,\n", + " \"2029-01-01.2029-12-31\": 160000,\n", + " \"2030-01-01.2031-12-31\": 165000,\n", + " \"2032-01-01.2033-12-31\": 170000,\n", + " \"2034-01-01.2034-12-31\": 175000,\n", + " \"2035-01-01.2035-12-31\": 180000\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.HEAD_OF_HOUSEHOLD\": {\n", + " \"2026-01-01.2027-12-31\": 112500,\n", + " \"2028-01-01.2029-12-31\": 117500,\n", + " \"2030-01-01.2031-12-31\": 122500,\n", + " \"2032-01-01.2033-12-31\": 127500,\n", + " \"2034-01-01.2035-12-31\": 132500\n", + " }\n", + "}\n", + "\n", + "searchlight_reform = Reform.from_dict(REFORM_DICT, country_id=\"us\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comprehensive 2026 Impact Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Intra-decile bounds and labels\n", + "_INTRA_BOUNDS = [-np.inf, -0.05, -1e-3, 1e-3, 0.05, np.inf]\n", + "_INTRA_LABELS = [\n", + " \"Lose more than 5%\",\n", + " \"Lose less than 5%\",\n", + " \"No change\",\n", + " \"Gain less than 5%\",\n", + " \"Gain more than 5%\",\n", + "]\n", + "\n", + "DATASET = \"hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5\"\n", + "\n", + "\n", + "def _poverty_metrics(baseline_rate, reform_rate):\n", + " \"\"\"Return rate change and percent change for a poverty metric.\"\"\"\n", + " rate_change = reform_rate - baseline_rate\n", + " percent_change = (\n", + " rate_change / baseline_rate * 100\n", + " if baseline_rate > 0\n", + " else 0.0\n", + " )\n", + " return rate_change, percent_change\n", + "\n", + "\n", + "def calculate_aggregate_impact(reform, year: int = 2026) -> dict:\n", + " sim_baseline = Microsimulation(dataset=DATASET)\n", + " sim_reform = Microsimulation(reform=reform, dataset=DATASET)\n", + "\n", + " # ===== FISCAL IMPACT =====\n", + " tax_baseline = sim_baseline.calculate(\n", + " \"income_tax\", period=year, map_to=\"household\"\n", + " )\n", + " tax_reform = sim_reform.calculate(\n", + " \"income_tax\", period=year, map_to=\"household\"\n", + " )\n", + " income_change = tax_baseline - tax_reform\n", + " tax_revenue_impact = float(-income_change.sum())\n", + "\n", + " # Total households\n", + " total_households = float((income_change * 0 + 1).sum())\n", + "\n", + " # ===== WINNERS / LOSERS =====\n", + " winners = float((income_change > 1).sum())\n", + " losers = float((income_change < -1).sum())\n", + " beneficiaries = float((income_change > 0).sum())\n", + "\n", + " affected = abs(income_change) > 1\n", + " affected_count = float(affected.sum())\n", + "\n", + " household_weight_early = sim_reform.calculate(\n", + " \"household_weight\", period=year\n", + " )\n", + " affected_mask = np.array(affected).astype(bool)\n", + " change_arr_early = np.array(income_change)\n", + " weight_arr_early = np.array(household_weight_early)\n", + " avg_benefit = (\n", + " float(np.average(\n", + " change_arr_early[affected_mask],\n", + " weights=weight_arr_early[affected_mask],\n", + " ))\n", + " if affected_count > 0\n", + " else 0.0\n", + " )\n", + "\n", + " winners_rate = winners / total_households * 100\n", + " losers_rate = losers / total_households * 100\n", + "\n", + " # ===== INCOME DECILE ANALYSIS =====\n", + " decile = sim_baseline.calculate(\n", + " \"household_income_decile\", period=year, map_to=\"household\"\n", + " )\n", + " baseline_net_income = sim_baseline.calculate(\n", + " \"household_net_income\", period=year, map_to=\"household\"\n", + " )\n", + "\n", + " decile_average = {}\n", + " decile_relative = {}\n", + " for d in range(1, 11):\n", + " dmask = decile == d\n", + " d_count = float(dmask.sum())\n", + " if d_count > 0:\n", + " d_change_sum = float(income_change[dmask].sum())\n", + " decile_average[str(d)] = d_change_sum / d_count\n", + " d_baseline_sum = float(baseline_net_income[dmask].sum())\n", + " decile_relative[str(d)] = (\n", + " d_change_sum / d_baseline_sum\n", + " if d_baseline_sum != 0\n", + " else 0.0\n", + " )\n", + " else:\n", + " decile_average[str(d)] = 0.0\n", + " decile_relative[str(d)] = 0.0\n", + "\n", + " # Intra-decile\n", + " household_weight = sim_reform.calculate(\n", + " \"household_weight\", period=year\n", + " )\n", + " people_per_hh = sim_baseline.calculate(\n", + " \"household_count_people\", period=year, map_to=\"household\"\n", + " )\n", + " capped_baseline = np.maximum(np.array(baseline_net_income), 1)\n", + " rel_change_arr = np.array(income_change) / capped_baseline\n", + "\n", + " decile_arr = np.array(decile)\n", + " weight_arr = np.array(household_weight)\n", + " people_weighted = np.array(people_per_hh) * weight_arr\n", + "\n", + " intra_decile_deciles = {label: [] for label in _INTRA_LABELS}\n", + " for d in range(1, 11):\n", + " dmask = decile_arr == d\n", + " d_people = people_weighted[dmask]\n", + " d_total_people = d_people.sum()\n", + " d_rel = rel_change_arr[dmask]\n", + "\n", + " for lower, upper, label in zip(\n", + " _INTRA_BOUNDS[:-1], _INTRA_BOUNDS[1:], _INTRA_LABELS\n", + " ):\n", + " in_group = (d_rel > lower) & (d_rel <= upper)\n", + " proportion = (\n", + " float(d_people[in_group].sum() / d_total_people)\n", + " if d_total_people > 0\n", + " else 0.0\n", + " )\n", + " intra_decile_deciles[label].append(proportion)\n", + "\n", + " intra_decile_all = {\n", + " label: sum(intra_decile_deciles[label]) / 10\n", + " for label in _INTRA_LABELS\n", + " }\n", + "\n", + " # ===== POVERTY IMPACT =====\n", + " pov_bl = sim_baseline.calculate(\n", + " \"in_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " pov_rf = sim_reform.calculate(\n", + " \"in_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " poverty_baseline_rate = float(pov_bl.mean() * 100)\n", + " poverty_reform_rate = float(pov_rf.mean() * 100)\n", + " poverty_rate_change, poverty_percent_change = _poverty_metrics(\n", + " poverty_baseline_rate, poverty_reform_rate\n", + " )\n", + "\n", + " # Child/deep poverty\n", + " age_arr = np.array(sim_baseline.calculate(\"age\", period=year))\n", + " is_child = age_arr < 18\n", + " pw_arr = np.array(sim_baseline.calculate(\"person_weight\", period=year))\n", + " child_w = pw_arr[is_child]\n", + " total_child_w = child_w.sum()\n", + "\n", + " pov_bl_arr = np.array(pov_bl).astype(bool)\n", + " pov_rf_arr = np.array(pov_rf).astype(bool)\n", + "\n", + " def _child_rate(arr):\n", + " return float(\n", + " (arr[is_child] * child_w).sum() / total_child_w * 100\n", + " ) if total_child_w > 0 else 0.0\n", + "\n", + " child_poverty_baseline_rate = _child_rate(pov_bl_arr)\n", + " child_poverty_reform_rate = _child_rate(pov_rf_arr)\n", + " child_poverty_rate_change, child_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " child_poverty_baseline_rate, child_poverty_reform_rate\n", + " )\n", + " )\n", + "\n", + " deep_bl = sim_baseline.calculate(\n", + " \"in_deep_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " deep_rf = sim_reform.calculate(\n", + " \"in_deep_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " deep_poverty_baseline_rate = float(deep_bl.mean() * 100)\n", + " deep_poverty_reform_rate = float(deep_rf.mean() * 100)\n", + " deep_poverty_rate_change, deep_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " deep_poverty_baseline_rate, deep_poverty_reform_rate\n", + " )\n", + " )\n", + "\n", + " deep_bl_arr = np.array(deep_bl).astype(bool)\n", + " deep_rf_arr = np.array(deep_rf).astype(bool)\n", + " deep_child_poverty_baseline_rate = _child_rate(deep_bl_arr)\n", + " deep_child_poverty_reform_rate = _child_rate(deep_rf_arr)\n", + " deep_child_poverty_rate_change, deep_child_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " deep_child_poverty_baseline_rate,\n", + " deep_child_poverty_reform_rate,\n", + " )\n", + " )\n", + "\n", + " # ===== INCOME BRACKET BREAKDOWN =====\n", + " agi = sim_reform.calculate(\n", + " \"adjusted_gross_income\", period=year, map_to=\"household\"\n", + " )\n", + " agi_arr = np.array(agi)\n", + " change_arr = np.array(income_change)\n", + " affected_mask = np.abs(change_arr) > 1\n", + "\n", + " income_brackets = [\n", + " (0, 50_000, \"Under $50k\"),\n", + " (50_000, 100_000, \"$50k-$100k\"),\n", + " (100_000, 200_000, \"$100k-$200k\"),\n", + " (200_000, 500_000, \"$200k-$500k\"),\n", + " (500_000, 1_000_000, \"$500k-$1M\"),\n", + " (1_000_000, 2_000_000, \"$1M-$2M\"),\n", + " (2_000_000, float(\"inf\"), \"Over $2M\"),\n", + " ]\n", + "\n", + " by_income_bracket = []\n", + " for min_inc, max_inc, label in income_brackets:\n", + " mask = (\n", + " (agi_arr >= min_inc)\n", + " & (agi_arr < max_inc)\n", + " & affected_mask\n", + " )\n", + " bracket_affected = float(weight_arr[mask].sum())\n", + " if bracket_affected > 0:\n", + " bracket_cost = float(\n", + " (change_arr[mask] * weight_arr[mask]).sum()\n", + " )\n", + " bracket_avg = float(\n", + " np.average(change_arr[mask], weights=weight_arr[mask])\n", + " )\n", + " else:\n", + " bracket_cost = 0.0\n", + " bracket_avg = 0.0\n", + " by_income_bracket.append({\n", + " \"bracket\": label,\n", + " \"beneficiaries\": bracket_affected,\n", + " \"total_cost\": bracket_cost,\n", + " \"avg_benefit\": bracket_avg,\n", + " })\n", + "\n", + " return {\n", + " \"budget\": {\n", + " \"budgetary_impact\": tax_revenue_impact,\n", + " \"tax_revenue_impact\": tax_revenue_impact,\n", + " \"benefit_spending_impact\": 0.0,\n", + " \"households\": total_households,\n", + " },\n", + " \"decile\": {\n", + " \"average\": decile_average,\n", + " \"relative\": decile_relative,\n", + " },\n", + " \"intra_decile\": {\n", + " \"all\": intra_decile_all,\n", + " \"deciles\": intra_decile_deciles,\n", + " },\n", + " \"total_cost\": -tax_revenue_impact,\n", + " \"beneficiaries\": beneficiaries,\n", + " \"avg_benefit\": avg_benefit,\n", + " \"winners\": winners,\n", + " \"losers\": losers,\n", + " \"winners_rate\": winners_rate,\n", + " \"losers_rate\": losers_rate,\n", + " \"poverty_baseline_rate\": poverty_baseline_rate,\n", + " \"poverty_reform_rate\": poverty_reform_rate,\n", + " \"poverty_rate_change\": poverty_rate_change,\n", + " \"poverty_percent_change\": poverty_percent_change,\n", + " \"child_poverty_baseline_rate\": child_poverty_baseline_rate,\n", + " \"child_poverty_reform_rate\": child_poverty_reform_rate,\n", + " \"child_poverty_rate_change\": child_poverty_rate_change,\n", + " \"child_poverty_percent_change\": child_poverty_percent_change,\n", + " \"deep_poverty_baseline_rate\": deep_poverty_baseline_rate,\n", + " \"deep_poverty_reform_rate\": deep_poverty_reform_rate,\n", + " \"deep_poverty_rate_change\": deep_poverty_rate_change,\n", + " \"deep_poverty_percent_change\": deep_poverty_percent_change,\n", + " \"deep_child_poverty_baseline_rate\": deep_child_poverty_baseline_rate,\n", + " \"deep_child_poverty_reform_rate\": deep_child_poverty_reform_rate,\n", + " \"deep_child_poverty_rate_change\": deep_child_poverty_rate_change,\n", + " \"deep_child_poverty_percent_change\": deep_child_poverty_percent_change,\n", + " \"by_income_bracket\": by_income_bracket,\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Calculating comprehensive 2026 impacts...\n", + "Done!\n", + "2026 impact saved to reform_2_impact_2026.csv\n" + ] + } + ], + "source": [ + "# Calculate comprehensive 2026 impacts\n", + "print(\"Calculating comprehensive 2026 impacts...\")\n", + "impact_2026 = calculate_aggregate_impact(searchlight_reform, year=2026)\n", + "print(\"Done!\")\n", + "\n", + "# Export 2026 impact to CSV immediately\n", + "def export_2026_impact_to_csv(impact, filename):\n", + " \"\"\"Export the 2026 impact results to a CSV file.\"\"\"\n", + " rows = [\n", + " [\"Metric\", \"Value\"],\n", + " [\"Budgetary Impact ($)\", impact['budget']['budgetary_impact']],\n", + " [\"Total Cost ($)\", impact['total_cost']],\n", + " [\"Total Households\", impact['budget']['households']],\n", + " [\"Winners\", impact['winners']],\n", + " [\"Winners Rate (%)\", impact['winners_rate']],\n", + " [\"Losers\", impact['losers']],\n", + " [\"Losers Rate (%)\", impact['losers_rate']],\n", + " [\"Beneficiaries\", impact['beneficiaries']],\n", + " [\"Average Benefit ($)\", impact['avg_benefit']],\n", + " [\"Poverty Baseline Rate (%)\", impact['poverty_baseline_rate']],\n", + " [\"Poverty Reform Rate (%)\", impact['poverty_reform_rate']],\n", + " [\"Poverty Rate Change (pp)\", impact['poverty_rate_change']],\n", + " [\"Poverty Percent Change (%)\", impact['poverty_percent_change']],\n", + " [\"Child Poverty Baseline Rate (%)\", impact['child_poverty_baseline_rate']],\n", + " [\"Child Poverty Reform Rate (%)\", impact['child_poverty_reform_rate']],\n", + " [\"Child Poverty Rate Change (pp)\", impact['child_poverty_rate_change']],\n", + " [\"Child Poverty Percent Change (%)\", impact['child_poverty_percent_change']],\n", + " [\"Deep Poverty Baseline Rate (%)\", impact['deep_poverty_baseline_rate']],\n", + " [\"Deep Poverty Reform Rate (%)\", impact['deep_poverty_reform_rate']],\n", + " [\"Deep Poverty Rate Change (pp)\", impact['deep_poverty_rate_change']],\n", + " [\"Deep Poverty Percent Change (%)\", impact['deep_poverty_percent_change']],\n", + " [\"Deep Child Poverty Baseline Rate (%)\", impact['deep_child_poverty_baseline_rate']],\n", + " [\"Deep Child Poverty Reform Rate (%)\", impact['deep_child_poverty_reform_rate']],\n", + " [\"Deep Child Poverty Rate Change (pp)\", impact['deep_child_poverty_rate_change']],\n", + " [\"Deep Child Poverty Percent Change (%)\", impact['deep_child_poverty_percent_change']],\n", + " ]\n", + " \n", + " # Add decile data\n", + " for d in range(1, 11):\n", + " rows.append([f\"Decile {d} Average Change ($)\", impact['decile']['average'][str(d)]])\n", + " rows.append([f\"Decile {d} Relative Change\", impact['decile']['relative'][str(d)]])\n", + " \n", + " # Add income bracket data\n", + " for bracket in impact['by_income_bracket']:\n", + " rows.append([f\"Bracket {bracket['bracket']} Beneficiaries\", bracket['beneficiaries']])\n", + " rows.append([f\"Bracket {bracket['bracket']} Total Cost ($)\", bracket['total_cost']])\n", + " rows.append([f\"Bracket {bracket['bracket']} Avg Benefit ($)\", bracket['avg_benefit']])\n", + " \n", + " with open(filename, 'w', newline='') as f:\n", + " writer = csv.writer(f)\n", + " writer.writerows(rows)\n", + " \n", + " print(f\"2026 impact saved to {filename}\")\n", + "\n", + "export_2026_impact_to_csv(impact_2026, \"reform_2_impact_2026.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "============================================================\n", + "BUDGET SUMMARY (2026) - Reform 2\n", + "============================================================\n", + "Budgetary Impact: $-113.44 billion\n", + "Total Cost: $113.44 billion\n", + "Total Households: 147,829,631\n" + ] + } + ], + "source": [ + "# Display budget summary\n", + "print(\"=\" * 60)\n", + "print(\"BUDGET SUMMARY (2026) - Reform 2\")\n", + "print(\"=\" * 60)\n", + "print(f\"Budgetary Impact: ${impact_2026['budget']['budgetary_impact'] / 1e9:.2f} billion\")\n", + "print(f\"Total Cost: ${impact_2026['total_cost'] / 1e9:.2f} billion\")\n", + "print(f\"Total Households: {impact_2026['budget']['households']:,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "WINNERS / LOSERS (2026)\n", + "============================================================\n", + "Winners: 46,577,942 (31.5%)\n", + "Losers: 5,164,542 (3.5%)\n", + "Beneficiaries: 46,580,372\n", + "Average Benefit (affected): $2,192.45\n" + ] + } + ], + "source": [ + "# Display winners/losers\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"WINNERS / LOSERS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"Winners: {impact_2026['winners']:,.0f} ({impact_2026['winners_rate']:.1f}%)\")\n", + "print(f\"Losers: {impact_2026['losers']:,.0f} ({impact_2026['losers_rate']:.1f}%)\")\n", + "print(f\"Beneficiaries: {impact_2026['beneficiaries']:,.0f}\")\n", + "print(f\"Average Benefit (affected): ${impact_2026['avg_benefit']:,.2f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "POVERTY IMPACTS (2026)\n", + "============================================================\n", + "\n", + "Overall Poverty:\n", + " Baseline: 23.33%\n", + " Reform: 21.58%\n", + " Change: -1.76pp (-7.5%)\n", + "\n", + "Child Poverty:\n", + " Baseline: 22.00%\n", + " Reform: 17.24%\n", + " Change: -4.76pp (-21.6%)\n", + "\n", + "Deep Poverty:\n", + " Baseline: 8.70%\n", + " Reform: 7.46%\n", + " Change: -1.24pp (-14.3%)\n", + "\n", + "Deep Child Poverty:\n", + " Baseline: 8.56%\n", + " Reform: 5.57%\n", + " Change: -2.99pp (-35.0%)\n" + ] + } + ], + "source": [ + "# Display poverty impacts\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"POVERTY IMPACTS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"\\nOverall Poverty:\")\n", + "print(f\" Baseline: {impact_2026['poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['poverty_rate_change']:+.2f}pp ({impact_2026['poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nChild Poverty:\")\n", + "print(f\" Baseline: {impact_2026['child_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['child_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['child_poverty_rate_change']:+.2f}pp ({impact_2026['child_poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nDeep Poverty:\")\n", + "print(f\" Baseline: {impact_2026['deep_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['deep_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['deep_poverty_rate_change']:+.2f}pp ({impact_2026['deep_poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nDeep Child Poverty:\")\n", + "print(f\" Baseline: {impact_2026['deep_child_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['deep_child_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['deep_child_poverty_rate_change']:+.2f}pp ({impact_2026['deep_child_poverty_percent_change']:+.1f}%)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "DECILE ANALYSIS (2026)\n", + "============================================================\n", + "Decile Avg Change Relative Change\n", + "---------------------------------------------\n", + "1 $ 781 6.78%\n", + "2 $ 820 3.06%\n", + "3 $ 716 1.78%\n", + "4 $ 1,091 2.01%\n", + "5 $ 1,369 1.94%\n", + "6 $ 839 0.97%\n", + "7 $ 785 0.71%\n", + "8 $ 724 0.50%\n", + "9 $ 287 0.15%\n", + "10 $ 128 0.02%\n" + ] + } + ], + "source": [ + "# Display decile analysis\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"DECILE ANALYSIS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"{'Decile':<10} {'Avg Change':>15} {'Relative Change':>18}\")\n", + "print(\"-\" * 45)\n", + "for d in range(1, 11):\n", + " avg = impact_2026['decile']['average'][str(d)]\n", + " rel = impact_2026['decile']['relative'][str(d)] * 100\n", + " print(f\"{d:<10} ${avg:>14,.0f} {rel:>17.2f}%\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "INCOME BRACKET BREAKDOWN (2026)\n", + "============================================================\n", + "Bracket Beneficiaries Total Cost Avg Benefit\n", + "------------------------------------------------------------\n", + "Under $50k 21,366,040 $ 59.49B $ 2,784\n", + "$50k-$100k 12,473,454 $ 29.25B $ 2,345\n", + "$100k-$200k 11,142,482 $ 20.05B $ 1,799\n", + "$200k-$500k 5,414,826 $ 0.93B $ 171\n", + "$500k-$1M 335,220 $ 0.57B $ 1,707\n", + "$1M-$2M 31,084 $ 0.03B $ 1,045\n", + "Over $2M 8,306 $ 0.01B $ 1,042\n" + ] + } + ], + "source": [ + "# Display income bracket breakdown\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"INCOME BRACKET BREAKDOWN (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"{'Bracket':<15} {'Beneficiaries':>15} {'Total Cost':>15} {'Avg Benefit':>12}\")\n", + "print(\"-\" * 60)\n", + "for bracket in impact_2026['by_income_bracket']:\n", + " print(f\"{bracket['bracket']:<15} {bracket['beneficiaries']:>15,.0f} ${bracket['total_cost']/1e9:>13.2f}B ${bracket['avg_benefit']:>10,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "marker": { + "color": "#105293" + }, + "text": [ + "$781", + "$820", + "$716", + "$1,091", + "$1,369", + "$839", + "$785", + "$724", + "$287", + "$128" + ], + "textposition": "auto", + "type": "bar", + "x": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "y": [ + 780.7994376313029, + 819.7589977614161, + 716.0136011089401, + 1090.7765528530292, + 1368.5481380089811, + 839.4528537162716, + 784.6251589674583, + 724.3633889757866, + 287.24881202593866, + 127.73573753264132 + ] + } + ], + "layout": { + "font": { + "color": "black", + "family": "Roboto Serif" + }, + "height": 600, + "images": [ + { + "sizex": 0.15, + "sizey": 0.15, + "source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png", + "x": 1.1, + "xanchor": "right", + "xref": "paper", + "y": -0.15, + "yanchor": "bottom", + "yref": "paper" + } + ], + "modebar": { + "bgcolor": "rgba(0,0,0,0)", + "color": "rgba(0,0,0,0)" + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Average Income Change by Decile (2026) - Reform 2" + }, + "width": 800, + "xaxis": { + "tickmode": "linear", + "title": { + "text": "Income Decile" + } + }, + "yaxis": { + "title": { + "text": "Average Change ($)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Create decile bar chart\n", + "deciles = list(range(1, 11))\n", + "avg_changes = [impact_2026['decile']['average'][str(d)] for d in deciles]\n", + "\n", + "fig = go.Figure(\n", + " go.Bar(\n", + " x=deciles,\n", + " y=avg_changes,\n", + " text=[f\"${v:,.0f}\" for v in avg_changes],\n", + " textposition=\"auto\",\n", + " marker_color=\"#105293\",\n", + " )\n", + ")\n", + "\n", + "fig.update_layout(\n", + " title=\"Average Income Change by Decile (2026) - Reform 2\",\n", + " xaxis_title=\"Income Decile\",\n", + " yaxis_title=\"Average Change ($)\",\n", + " xaxis=dict(tickmode=\"linear\"),\n", + ")\n", + "\n", + "format_fig(fig).show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 10-Year Federal Budgetary Impact (2026-2035)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def calculate_budgetary_impact(reform, year):\n", + " \"\"\"Calculate just the federal income tax budgetary impact for a single year.\"\"\"\n", + " baseline = Microsimulation(dataset=DATASET)\n", + " reformed = Microsimulation(reform=reform, dataset=DATASET)\n", + " \n", + " baseline_income_tax = baseline.calculate(\"income_tax\", period=year).sum()\n", + " reformed_income_tax = reformed.calculate(\"income_tax\", period=year).sum()\n", + " \n", + " # Budgetary impact: negative means costs money (reform reduces tax revenue)\n", + " impact = reformed_income_tax - baseline_income_tax\n", + " return float(impact)\n", + "\n", + "\n", + "def calculate_ten_year_projection(reform, csv_filename=\"reform_2_10year_budgetary_impact.csv\"):\n", + " results = []\n", + "\n", + " with open(csv_filename, \"w\", newline=\"\") as csvfile:\n", + " csvwriter = csv.writer(csvfile)\n", + " csvwriter.writerow([\"Year\", \"Budgetary Impact\"])\n", + "\n", + " for year in range(2026, 2036):\n", + " print(f\"Computing budgetary impact for year {year}...\")\n", + " impact = calculate_budgetary_impact(reform, year)\n", + " results.append({\"Year\": year, \"Budgetary Impact\": impact})\n", + "\n", + " csvwriter.writerow([year, impact])\n", + " print(f\"Year {year} completed. Impact: ${impact/1e9:.2f} billion\")\n", + "\n", + " print(f\"All calculations complete. Results saved to '{csv_filename}'\")\n", + " return pd.DataFrame(results)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting 10-year budgetary impact calculation...\n", + "Computing budgetary impact for year 2026...\n", + "Year 2026 completed. Impact: $-113.44 billion\n", + "Computing budgetary impact for year 2027...\n", + "Year 2027 completed. Impact: $-116.92 billion\n", + "Computing budgetary impact for year 2028...\n", + "Year 2028 completed. Impact: $-115.48 billion\n", + "Computing budgetary impact for year 2029...\n", + "Year 2029 completed. Impact: $-118.02 billion\n", + "Computing budgetary impact for year 2030...\n", + "Year 2030 completed. Impact: $-117.95 billion\n", + "Computing budgetary impact for year 2031...\n", + "Year 2031 completed. Impact: $-120.34 billion\n", + "Computing budgetary impact for year 2032...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Xet Storage is enabled for this repo, but the 'hf_xet' package is not installed. Falling back to regular HTTP download. For better performance, install the package with: `pip install huggingface_hub[hf_xet]` or `pip install hf_xet`\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6627d772c8d94732a64c67cf41681bf2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "enhanced_cps_2024.h5: 0%| | 0.00/111M [00:00here for more info. \n", + "\u001b[1;31mView Jupyter log for further details." + ] + } + ], + "source": [ + "# Create 10-year bar chart\n", + "fig = go.Figure(\n", + " go.Bar(\n", + " x=df_projection[\"Year\"],\n", + " y=(df_projection[\"Budgetary Impact\"] / 1e9).round(1),\n", + " text=(df_projection[\"Budgetary Impact\"] / 1e9)\n", + " .round(1)\n", + " .apply(lambda x: f\"${x:.1f}B\"),\n", + " textposition=\"auto\",\n", + " marker_color=\"#105293\",\n", + " )\n", + ")\n", + "\n", + "fig.update_layout(\n", + " title=\"10-Year Federal Budgetary Impact - Reform 2\",\n", + " xaxis_title=\"Year\",\n", + " yaxis_title=\"Budgetary Impact (Billions $)\",\n", + " xaxis=dict(tickmode=\"linear\"),\n", + " yaxis=dict(zeroline=True, zerolinewidth=2, zerolinecolor=\"Black\"),\n", + ")\n", + "\n", + "format_fig(fig).show()" + ] + } + ], + "metadata": { + "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.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/us/searchlight_institute/reform_2_impact_2026.csv b/us/searchlight_institute/reform_2_impact_2026.csv new file mode 100644 index 0000000..daa9606 --- /dev/null +++ b/us/searchlight_institute/reform_2_impact_2026.csv @@ -0,0 +1,67 @@ +Metric,Value +Budgetary Impact ($),-113443058010.38493 +Total Cost ($),113443058010.38493 +Total Households,147829631.20700648 +Winners,46577941.902932726 +Winners Rate (%),31.507852331518997 +Losers,5164541.787064761 +Losers Rate (%),3.4935768593191106 +Beneficiaries,46580372.18454894 +Average Benefit ($),2192.4548200511676 +Poverty Baseline Rate (%),23.33367114033999 +Poverty Reform Rate (%),21.57605948274563 +Poverty Rate Change (pp),-1.75761165759436 +Poverty Percent Change (%),-7.532512338171019 +Child Poverty Baseline Rate (%),21.99616050720215 +Child Poverty Reform Rate (%),17.2364559173584 +Child Poverty Rate Change (pp),-4.75970458984375 +Child Poverty Percent Change (%),-21.638797317765032 +Deep Poverty Baseline Rate (%),8.704698989314954 +Deep Poverty Reform Rate (%),7.460981816878894 +Deep Poverty Rate Change (pp),-1.2437171724360603 +Deep Poverty Percent Change (%),-14.287882601830656 +Deep Child Poverty Baseline Rate (%),8.560979843139648 +Deep Child Poverty Reform Rate (%),5.567295074462891 +Deep Child Poverty Rate Change (pp),-2.993684768676758 +Deep Child Poverty Percent Change (%),-34.96895009133505 +Decile 1 Average Change ($),780.7994376313029 +Decile 1 Relative Change,0.0677541022258743 +Decile 2 Average Change ($),819.7589977614161 +Decile 2 Relative Change,0.030631795117321114 +Decile 3 Average Change ($),716.0136011089401 +Decile 3 Relative Change,0.017841491237841976 +Decile 4 Average Change ($),1090.7765528530292 +Decile 4 Relative Change,0.020114572176869443 +Decile 5 Average Change ($),1368.5481380089811 +Decile 5 Relative Change,0.019418410550284183 +Decile 6 Average Change ($),839.4528537162716 +Decile 6 Relative Change,0.009713348240347195 +Decile 7 Average Change ($),784.6251589674583 +Decile 7 Relative Change,0.007089206433480698 +Decile 8 Average Change ($),724.3633889757866 +Decile 8 Relative Change,0.004960970098381759 +Decile 9 Average Change ($),287.24881202593866 +Decile 9 Relative Change,0.001462963093353001 +Decile 10 Average Change ($),127.73573753264132 +Decile 10 Relative Change,0.00018979910243781178 +Bracket Under $50k Beneficiaries,21366040.0 +Bracket Under $50k Total Cost ($),59492600050.05449 +Bracket Under $50k Avg Benefit ($),2784.4468412165434 +Bracket $50k-$100k Beneficiaries,12473454.0 +Bracket $50k-$100k Total Cost ($),29245329235.191666 +Bracket $50k-$100k Avg Benefit ($),2344.6056001845836 +Bracket $100k-$200k Beneficiaries,11142482.0 +Bracket $100k-$200k Total Cost ($),20046131295.71265 +Bracket $100k-$200k Avg Benefit ($),1799.072340473846 +Bracket $200k-$500k Beneficiaries,5414826.0 +Bracket $200k-$500k Total Cost ($),927273512.4944108 +Bracket $200k-$500k Avg Benefit ($),171.2471514309523 +Bracket $500k-$1M Beneficiaries,335220.34375 +Bracket $500k-$1M Total Cost ($),572336491.7657435 +Bracket $500k-$1M Avg Benefit ($),1707.344150555614 +Bracket $1M-$2M Beneficiaries,31083.828125 +Bracket $1M-$2M Total Cost ($),32489950.99534661 +Bracket $1M-$2M Avg Benefit ($),1045.236520680412 +Bracket Over $2M Beneficiaries,8306.05078125 +Bracket Over $2M Total Cost ($),8653355.63597258 +Bracket Over $2M Avg Benefit ($),1041.8134839859545 diff --git a/us/searchlight_institute/reform_3_10year_budgetary_impact.csv b/us/searchlight_institute/reform_3_10year_budgetary_impact.csv new file mode 100644 index 0000000..02b07d5 --- /dev/null +++ b/us/searchlight_institute/reform_3_10year_budgetary_impact.csv @@ -0,0 +1,11 @@ +Year,Budgetary Impact +2026,-93467799629.98828 +2027,-96810364950.26514 +2028,-95475415012.12012 +2029,-97888295578.53516 +2030,-97841598248.82227 +2031,-100265266755.81348 +2032,-99055159267.96533 +2033,-101078701297.22852 +2034,-99763416803.51074 +2035,-102655575125.43213 diff --git a/us/searchlight_institute/reform_3_analysis.ipynb b/us/searchlight_institute/reform_3_analysis.ipynb new file mode 100644 index 0000000..ecc3367 --- /dev/null +++ b/us/searchlight_institute/reform_3_analysis.ipynb @@ -0,0 +1,2768 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Searchlight Institute Tax Reform Analysis - Reform 3\n", + "\n", + "This notebook analyzes the comprehensive impact of the Searchlight Institute tax reform proposal (Reform 3):\n", + "- Full aggregate impacts for 2026 (deciles, poverty, winners/losers, income brackets)\n", + "- 10-year federal budgetary impact (2026-2035)\n", + "\n", + "**CTC Amounts:** $2,700 (2026) to $3,240 (2035)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from policyengine_us import Microsimulation\n", + "from policyengine_core.reforms import Reform\n", + "import pandas as pd\n", + "import numpy as np\n", + "import plotly.graph_objects as go\n", + "from policyengine_core.charts import format_fig\n", + "import csv" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Searchlight Institute Tax Reform - Reform 3\n", + "# - AFA CTC reforms (lowest CTC amounts)\n", + "# - EITC eligibility and amount changes\n", + "# - EITC joint bonus set equal to phase-out start values\n", + "\n", + "REFORM_DICT = {\n", + " \"gov.contrib.congress.afa.in_effect\": {\n", + " \"2026-01-01.2100-12-31\": True\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.amount.base\": {\n", + " \"2026-01-01.2026-12-31\": 2700,\n", + " \"2027-01-01.2028-12-31\": 2820,\n", + " \"2029-01-01.2030-12-31\": 2940,\n", + " \"2031-01-01.2032-12-31\": 3060,\n", + " \"2033-01-01.2034-12-31\": 3180,\n", + " \"2035-01-01.2035-12-31\": 3300\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.max\": {\n", + " \"2026-01-01.2100-12-31\": 200\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.min\": {\n", + " \"2026-01-01.2100-12-31\": 19\n", + " },\n", + " \"gov.irs.credits.eitc.eligibility.age.min_student\": {\n", + " \"2026-01-01.2100-12-31\": 24\n", + " },\n", + " \"gov.irs.credits.eitc.max[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 1502,\n", + " \"2027-01-01.2027-12-31\": 1577,\n", + " \"2028-01-01.2028-12-31\": 1610,\n", + " \"2029-01-01.2029-12-31\": 1645,\n", + " \"2030-01-01.2030-12-31\": 1678,\n", + " \"2031-01-01.2031-12-31\": 1712,\n", + " \"2032-01-01.2032-12-31\": 1746,\n", + " \"2033-01-01.2033-12-31\": 1779,\n", + " \"2034-01-01.2034-12-31\": 1815,\n", + " \"2035-01-01.2035-12-31\": 1851\n", + " },\n", + " \"gov.irs.credits.eitc.phase_in_rate[0].amount\": {\n", + " \"2026-01-01.2100-12-31\": 0.153\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.rate[0].amount\": {\n", + " \"2026-01-01.2100-12-31\": 0.153\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.start[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 11610,\n", + " \"2027-01-01.2027-12-31\": 12190,\n", + " \"2028-01-01.2028-12-31\": 12440,\n", + " \"2029-01-01.2029-12-31\": 12710,\n", + " \"2030-01-01.2030-12-31\": 12970,\n", + " \"2031-01-01.2031-12-31\": 13230,\n", + " \"2032-01-01.2032-12-31\": 13490,\n", + " \"2033-01-01.2033-12-31\": 13750,\n", + " \"2034-01-01.2034-12-31\": 14030,\n", + " \"2035-01-01.2035-12-31\": 14300\n", + " },\n", + " \"gov.irs.credits.eitc.phase_out.joint_bonus[0].amount\": {\n", + " \"2026-01-01.2026-12-31\": 11610,\n", + " \"2027-01-01.2027-12-31\": 12190,\n", + " \"2028-01-01.2028-12-31\": 12440,\n", + " \"2029-01-01.2029-12-31\": 12710,\n", + " \"2030-01-01.2030-12-31\": 12970,\n", + " \"2031-01-01.2031-12-31\": 13230,\n", + " \"2032-01-01.2032-12-31\": 13490,\n", + " \"2033-01-01.2033-12-31\": 13750,\n", + " \"2034-01-01.2034-12-31\": 14030,\n", + " \"2035-01-01.2035-12-31\": 14300\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.JOINT\": {\n", + " \"2026-01-01.2026-12-31\": 150000,\n", + " \"2027-01-01.2028-12-31\": 155000,\n", + " \"2029-01-01.2029-12-31\": 160000,\n", + " \"2030-01-01.2031-12-31\": 165000,\n", + " \"2032-01-01.2033-12-31\": 170000,\n", + " \"2034-01-01.2034-12-31\": 175000,\n", + " \"2035-01-01.2035-12-31\": 180000\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.SINGLE\": {\n", + " \"2026-01-01.2027-12-31\": 112500,\n", + " \"2028-01-01.2029-12-31\": 117500,\n", + " \"2030-01-01.2031-12-31\": 122500,\n", + " \"2032-01-01.2033-12-31\": 127500,\n", + " \"2034-01-01.2035-12-31\": 132500\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.SURVIVING_SPOUSE\": {\n", + " \"2026-01-01.2026-12-31\": 150000,\n", + " \"2027-01-01.2028-12-31\": 155000,\n", + " \"2029-01-01.2029-12-31\": 160000,\n", + " \"2030-01-01.2031-12-31\": 165000,\n", + " \"2032-01-01.2033-12-31\": 170000,\n", + " \"2034-01-01.2034-12-31\": 175000,\n", + " \"2035-01-01.2035-12-31\": 180000\n", + " },\n", + " \"gov.contrib.congress.afa.ctc.phase_out.threshold.lower.HEAD_OF_HOUSEHOLD\": {\n", + " \"2026-01-01.2027-12-31\": 112500,\n", + " \"2028-01-01.2029-12-31\": 117500,\n", + " \"2030-01-01.2031-12-31\": 122500,\n", + " \"2032-01-01.2033-12-31\": 127500,\n", + " \"2034-01-01.2035-12-31\": 132500\n", + " }\n", + "}\n", + "\n", + "searchlight_reform = Reform.from_dict(REFORM_DICT, country_id=\"us\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comprehensive 2026 Impact Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Intra-decile bounds and labels\n", + "_INTRA_BOUNDS = [-np.inf, -0.05, -1e-3, 1e-3, 0.05, np.inf]\n", + "_INTRA_LABELS = [\n", + " \"Lose more than 5%\",\n", + " \"Lose less than 5%\",\n", + " \"No change\",\n", + " \"Gain less than 5%\",\n", + " \"Gain more than 5%\",\n", + "]\n", + "\n", + "DATASET = \"hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5\"\n", + "\n", + "\n", + "def _poverty_metrics(baseline_rate, reform_rate):\n", + " \"\"\"Return rate change and percent change for a poverty metric.\"\"\"\n", + " rate_change = reform_rate - baseline_rate\n", + " percent_change = (\n", + " rate_change / baseline_rate * 100\n", + " if baseline_rate > 0\n", + " else 0.0\n", + " )\n", + " return rate_change, percent_change\n", + "\n", + "\n", + "def calculate_aggregate_impact(reform, year: int = 2026) -> dict:\n", + " sim_baseline = Microsimulation(dataset=DATASET)\n", + " sim_reform = Microsimulation(reform=reform, dataset=DATASET)\n", + "\n", + " # ===== FISCAL IMPACT =====\n", + " tax_baseline = sim_baseline.calculate(\n", + " \"income_tax\", period=year, map_to=\"household\"\n", + " )\n", + " tax_reform = sim_reform.calculate(\n", + " \"income_tax\", period=year, map_to=\"household\"\n", + " )\n", + " income_change = tax_baseline - tax_reform\n", + " tax_revenue_impact = float(-income_change.sum())\n", + "\n", + " # Total households\n", + " total_households = float((income_change * 0 + 1).sum())\n", + "\n", + " # ===== WINNERS / LOSERS =====\n", + " winners = float((income_change > 1).sum())\n", + " losers = float((income_change < -1).sum())\n", + " beneficiaries = float((income_change > 0).sum())\n", + "\n", + " affected = abs(income_change) > 1\n", + " affected_count = float(affected.sum())\n", + "\n", + " household_weight_early = sim_reform.calculate(\n", + " \"household_weight\", period=year\n", + " )\n", + " affected_mask = np.array(affected).astype(bool)\n", + " change_arr_early = np.array(income_change)\n", + " weight_arr_early = np.array(household_weight_early)\n", + " avg_benefit = (\n", + " float(np.average(\n", + " change_arr_early[affected_mask],\n", + " weights=weight_arr_early[affected_mask],\n", + " ))\n", + " if affected_count > 0\n", + " else 0.0\n", + " )\n", + "\n", + " winners_rate = winners / total_households * 100\n", + " losers_rate = losers / total_households * 100\n", + "\n", + " # ===== INCOME DECILE ANALYSIS =====\n", + " decile = sim_baseline.calculate(\n", + " \"household_income_decile\", period=year, map_to=\"household\"\n", + " )\n", + " baseline_net_income = sim_baseline.calculate(\n", + " \"household_net_income\", period=year, map_to=\"household\"\n", + " )\n", + "\n", + " decile_average = {}\n", + " decile_relative = {}\n", + " for d in range(1, 11):\n", + " dmask = decile == d\n", + " d_count = float(dmask.sum())\n", + " if d_count > 0:\n", + " d_change_sum = float(income_change[dmask].sum())\n", + " decile_average[str(d)] = d_change_sum / d_count\n", + " d_baseline_sum = float(baseline_net_income[dmask].sum())\n", + " decile_relative[str(d)] = (\n", + " d_change_sum / d_baseline_sum\n", + " if d_baseline_sum != 0\n", + " else 0.0\n", + " )\n", + " else:\n", + " decile_average[str(d)] = 0.0\n", + " decile_relative[str(d)] = 0.0\n", + "\n", + " # Intra-decile\n", + " household_weight = sim_reform.calculate(\n", + " \"household_weight\", period=year\n", + " )\n", + " people_per_hh = sim_baseline.calculate(\n", + " \"household_count_people\", period=year, map_to=\"household\"\n", + " )\n", + " capped_baseline = np.maximum(np.array(baseline_net_income), 1)\n", + " rel_change_arr = np.array(income_change) / capped_baseline\n", + "\n", + " decile_arr = np.array(decile)\n", + " weight_arr = np.array(household_weight)\n", + " people_weighted = np.array(people_per_hh) * weight_arr\n", + "\n", + " intra_decile_deciles = {label: [] for label in _INTRA_LABELS}\n", + " for d in range(1, 11):\n", + " dmask = decile_arr == d\n", + " d_people = people_weighted[dmask]\n", + " d_total_people = d_people.sum()\n", + " d_rel = rel_change_arr[dmask]\n", + "\n", + " for lower, upper, label in zip(\n", + " _INTRA_BOUNDS[:-1], _INTRA_BOUNDS[1:], _INTRA_LABELS\n", + " ):\n", + " in_group = (d_rel > lower) & (d_rel <= upper)\n", + " proportion = (\n", + " float(d_people[in_group].sum() / d_total_people)\n", + " if d_total_people > 0\n", + " else 0.0\n", + " )\n", + " intra_decile_deciles[label].append(proportion)\n", + "\n", + " intra_decile_all = {\n", + " label: sum(intra_decile_deciles[label]) / 10\n", + " for label in _INTRA_LABELS\n", + " }\n", + "\n", + " # ===== POVERTY IMPACT =====\n", + " pov_bl = sim_baseline.calculate(\n", + " \"in_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " pov_rf = sim_reform.calculate(\n", + " \"in_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " poverty_baseline_rate = float(pov_bl.mean() * 100)\n", + " poverty_reform_rate = float(pov_rf.mean() * 100)\n", + " poverty_rate_change, poverty_percent_change = _poverty_metrics(\n", + " poverty_baseline_rate, poverty_reform_rate\n", + " )\n", + "\n", + " # Child/deep poverty\n", + " age_arr = np.array(sim_baseline.calculate(\"age\", period=year))\n", + " is_child = age_arr < 18\n", + " pw_arr = np.array(sim_baseline.calculate(\"person_weight\", period=year))\n", + " child_w = pw_arr[is_child]\n", + " total_child_w = child_w.sum()\n", + "\n", + " pov_bl_arr = np.array(pov_bl).astype(bool)\n", + " pov_rf_arr = np.array(pov_rf).astype(bool)\n", + "\n", + " def _child_rate(arr):\n", + " return float(\n", + " (arr[is_child] * child_w).sum() / total_child_w * 100\n", + " ) if total_child_w > 0 else 0.0\n", + "\n", + " child_poverty_baseline_rate = _child_rate(pov_bl_arr)\n", + " child_poverty_reform_rate = _child_rate(pov_rf_arr)\n", + " child_poverty_rate_change, child_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " child_poverty_baseline_rate, child_poverty_reform_rate\n", + " )\n", + " )\n", + "\n", + " deep_bl = sim_baseline.calculate(\n", + " \"in_deep_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " deep_rf = sim_reform.calculate(\n", + " \"in_deep_poverty\", period=year, map_to=\"person\"\n", + " )\n", + " deep_poverty_baseline_rate = float(deep_bl.mean() * 100)\n", + " deep_poverty_reform_rate = float(deep_rf.mean() * 100)\n", + " deep_poverty_rate_change, deep_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " deep_poverty_baseline_rate, deep_poverty_reform_rate\n", + " )\n", + " )\n", + "\n", + " deep_bl_arr = np.array(deep_bl).astype(bool)\n", + " deep_rf_arr = np.array(deep_rf).astype(bool)\n", + " deep_child_poverty_baseline_rate = _child_rate(deep_bl_arr)\n", + " deep_child_poverty_reform_rate = _child_rate(deep_rf_arr)\n", + " deep_child_poverty_rate_change, deep_child_poverty_percent_change = (\n", + " _poverty_metrics(\n", + " deep_child_poverty_baseline_rate,\n", + " deep_child_poverty_reform_rate,\n", + " )\n", + " )\n", + "\n", + " # ===== INCOME BRACKET BREAKDOWN =====\n", + " agi = sim_reform.calculate(\n", + " \"adjusted_gross_income\", period=year, map_to=\"household\"\n", + " )\n", + " agi_arr = np.array(agi)\n", + " change_arr = np.array(income_change)\n", + " affected_mask = np.abs(change_arr) > 1\n", + "\n", + " income_brackets = [\n", + " (0, 50_000, \"Under $50k\"),\n", + " (50_000, 100_000, \"$50k-$100k\"),\n", + " (100_000, 200_000, \"$100k-$200k\"),\n", + " (200_000, 500_000, \"$200k-$500k\"),\n", + " (500_000, 1_000_000, \"$500k-$1M\"),\n", + " (1_000_000, 2_000_000, \"$1M-$2M\"),\n", + " (2_000_000, float(\"inf\"), \"Over $2M\"),\n", + " ]\n", + "\n", + " by_income_bracket = []\n", + " for min_inc, max_inc, label in income_brackets:\n", + " mask = (\n", + " (agi_arr >= min_inc)\n", + " & (agi_arr < max_inc)\n", + " & affected_mask\n", + " )\n", + " bracket_affected = float(weight_arr[mask].sum())\n", + " if bracket_affected > 0:\n", + " bracket_cost = float(\n", + " (change_arr[mask] * weight_arr[mask]).sum()\n", + " )\n", + " bracket_avg = float(\n", + " np.average(change_arr[mask], weights=weight_arr[mask])\n", + " )\n", + " else:\n", + " bracket_cost = 0.0\n", + " bracket_avg = 0.0\n", + " by_income_bracket.append({\n", + " \"bracket\": label,\n", + " \"beneficiaries\": bracket_affected,\n", + " \"total_cost\": bracket_cost,\n", + " \"avg_benefit\": bracket_avg,\n", + " })\n", + "\n", + " return {\n", + " \"budget\": {\n", + " \"budgetary_impact\": tax_revenue_impact,\n", + " \"tax_revenue_impact\": tax_revenue_impact,\n", + " \"benefit_spending_impact\": 0.0,\n", + " \"households\": total_households,\n", + " },\n", + " \"decile\": {\n", + " \"average\": decile_average,\n", + " \"relative\": decile_relative,\n", + " },\n", + " \"intra_decile\": {\n", + " \"all\": intra_decile_all,\n", + " \"deciles\": intra_decile_deciles,\n", + " },\n", + " \"total_cost\": -tax_revenue_impact,\n", + " \"beneficiaries\": beneficiaries,\n", + " \"avg_benefit\": avg_benefit,\n", + " \"winners\": winners,\n", + " \"losers\": losers,\n", + " \"winners_rate\": winners_rate,\n", + " \"losers_rate\": losers_rate,\n", + " \"poverty_baseline_rate\": poverty_baseline_rate,\n", + " \"poverty_reform_rate\": poverty_reform_rate,\n", + " \"poverty_rate_change\": poverty_rate_change,\n", + " \"poverty_percent_change\": poverty_percent_change,\n", + " \"child_poverty_baseline_rate\": child_poverty_baseline_rate,\n", + " \"child_poverty_reform_rate\": child_poverty_reform_rate,\n", + " \"child_poverty_rate_change\": child_poverty_rate_change,\n", + " \"child_poverty_percent_change\": child_poverty_percent_change,\n", + " \"deep_poverty_baseline_rate\": deep_poverty_baseline_rate,\n", + " \"deep_poverty_reform_rate\": deep_poverty_reform_rate,\n", + " \"deep_poverty_rate_change\": deep_poverty_rate_change,\n", + " \"deep_poverty_percent_change\": deep_poverty_percent_change,\n", + " \"deep_child_poverty_baseline_rate\": deep_child_poverty_baseline_rate,\n", + " \"deep_child_poverty_reform_rate\": deep_child_poverty_reform_rate,\n", + " \"deep_child_poverty_rate_change\": deep_child_poverty_rate_change,\n", + " \"deep_child_poverty_percent_change\": deep_child_poverty_percent_change,\n", + " \"by_income_bracket\": by_income_bracket,\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Calculating comprehensive 2026 impacts...\n", + "Done!\n", + "2026 impact saved to reform_3_impact_2026.csv\n" + ] + } + ], + "source": [ + "# Calculate comprehensive 2026 impacts\n", + "print(\"Calculating comprehensive 2026 impacts...\")\n", + "impact_2026 = calculate_aggregate_impact(searchlight_reform, year=2026)\n", + "print(\"Done!\")\n", + "\n", + "# Export 2026 impact to CSV immediately\n", + "def export_2026_impact_to_csv(impact, filename):\n", + " \"\"\"Export the 2026 impact results to a CSV file.\"\"\"\n", + " rows = [\n", + " [\"Metric\", \"Value\"],\n", + " [\"Budgetary Impact ($)\", impact['budget']['budgetary_impact']],\n", + " [\"Total Cost ($)\", impact['total_cost']],\n", + " [\"Total Households\", impact['budget']['households']],\n", + " [\"Winners\", impact['winners']],\n", + " [\"Winners Rate (%)\", impact['winners_rate']],\n", + " [\"Losers\", impact['losers']],\n", + " [\"Losers Rate (%)\", impact['losers_rate']],\n", + " [\"Beneficiaries\", impact['beneficiaries']],\n", + " [\"Average Benefit ($)\", impact['avg_benefit']],\n", + " [\"Poverty Baseline Rate (%)\", impact['poverty_baseline_rate']],\n", + " [\"Poverty Reform Rate (%)\", impact['poverty_reform_rate']],\n", + " [\"Poverty Rate Change (pp)\", impact['poverty_rate_change']],\n", + " [\"Poverty Percent Change (%)\", impact['poverty_percent_change']],\n", + " [\"Child Poverty Baseline Rate (%)\", impact['child_poverty_baseline_rate']],\n", + " [\"Child Poverty Reform Rate (%)\", impact['child_poverty_reform_rate']],\n", + " [\"Child Poverty Rate Change (pp)\", impact['child_poverty_rate_change']],\n", + " [\"Child Poverty Percent Change (%)\", impact['child_poverty_percent_change']],\n", + " [\"Deep Poverty Baseline Rate (%)\", impact['deep_poverty_baseline_rate']],\n", + " [\"Deep Poverty Reform Rate (%)\", impact['deep_poverty_reform_rate']],\n", + " [\"Deep Poverty Rate Change (pp)\", impact['deep_poverty_rate_change']],\n", + " [\"Deep Poverty Percent Change (%)\", impact['deep_poverty_percent_change']],\n", + " [\"Deep Child Poverty Baseline Rate (%)\", impact['deep_child_poverty_baseline_rate']],\n", + " [\"Deep Child Poverty Reform Rate (%)\", impact['deep_child_poverty_reform_rate']],\n", + " [\"Deep Child Poverty Rate Change (pp)\", impact['deep_child_poverty_rate_change']],\n", + " [\"Deep Child Poverty Percent Change (%)\", impact['deep_child_poverty_percent_change']],\n", + " ]\n", + " \n", + " # Add decile data\n", + " for d in range(1, 11):\n", + " rows.append([f\"Decile {d} Average Change ($)\", impact['decile']['average'][str(d)]])\n", + " rows.append([f\"Decile {d} Relative Change\", impact['decile']['relative'][str(d)]])\n", + " \n", + " # Add income bracket data\n", + " for bracket in impact['by_income_bracket']:\n", + " rows.append([f\"Bracket {bracket['bracket']} Beneficiaries\", bracket['beneficiaries']])\n", + " rows.append([f\"Bracket {bracket['bracket']} Total Cost ($)\", bracket['total_cost']])\n", + " rows.append([f\"Bracket {bracket['bracket']} Avg Benefit ($)\", bracket['avg_benefit']])\n", + " \n", + " with open(filename, 'w', newline='') as f:\n", + " writer = csv.writer(f)\n", + " writer.writerows(rows)\n", + " \n", + " print(f\"2026 impact saved to {filename}\")\n", + "\n", + "export_2026_impact_to_csv(impact_2026, \"reform_3_impact_2026.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "============================================================\n", + "BUDGET SUMMARY (2026) - Reform 3\n", + "============================================================\n", + "Budgetary Impact: $-93.47 billion\n", + "Total Cost: $93.47 billion\n", + "Total Households: 147,829,631\n" + ] + } + ], + "source": [ + "# Display budget summary\n", + "print(\"=\" * 60)\n", + "print(\"BUDGET SUMMARY (2026) - Reform 3\")\n", + "print(\"=\" * 60)\n", + "print(f\"Budgetary Impact: ${impact_2026['budget']['budgetary_impact'] / 1e9:.2f} billion\")\n", + "print(f\"Total Cost: ${impact_2026['total_cost'] / 1e9:.2f} billion\")\n", + "print(f\"Total Households: {impact_2026['budget']['households']:,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "WINNERS / LOSERS (2026)\n", + "============================================================\n", + "Winners: 45,912,148 (31.1%)\n", + "Losers: 5,854,870 (4.0%)\n", + "Beneficiaries: 45,919,433\n", + "Average Benefit (affected): $1,805.55\n" + ] + } + ], + "source": [ + "# Display winners/losers\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"WINNERS / LOSERS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"Winners: {impact_2026['winners']:,.0f} ({impact_2026['winners_rate']:.1f}%)\")\n", + "print(f\"Losers: {impact_2026['losers']:,.0f} ({impact_2026['losers_rate']:.1f}%)\")\n", + "print(f\"Beneficiaries: {impact_2026['beneficiaries']:,.0f}\")\n", + "print(f\"Average Benefit (affected): ${impact_2026['avg_benefit']:,.2f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "POVERTY IMPACTS (2026)\n", + "============================================================\n", + "\n", + "Overall Poverty:\n", + " Baseline: 23.33%\n", + " Reform: 21.68%\n", + " Change: -1.65pp (-7.1%)\n", + "\n", + "Child Poverty:\n", + " Baseline: 22.00%\n", + " Reform: 17.52%\n", + " Change: -4.47pp (-20.3%)\n", + "\n", + "Deep Poverty:\n", + " Baseline: 8.70%\n", + " Reform: 7.49%\n", + " Change: -1.21pp (-13.9%)\n", + "\n", + "Deep Child Poverty:\n", + " Baseline: 8.56%\n", + " Reform: 5.61%\n", + " Change: -2.95pp (-34.5%)\n" + ] + } + ], + "source": [ + "# Display poverty impacts\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"POVERTY IMPACTS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"\\nOverall Poverty:\")\n", + "print(f\" Baseline: {impact_2026['poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['poverty_rate_change']:+.2f}pp ({impact_2026['poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nChild Poverty:\")\n", + "print(f\" Baseline: {impact_2026['child_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['child_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['child_poverty_rate_change']:+.2f}pp ({impact_2026['child_poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nDeep Poverty:\")\n", + "print(f\" Baseline: {impact_2026['deep_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['deep_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['deep_poverty_rate_change']:+.2f}pp ({impact_2026['deep_poverty_percent_change']:+.1f}%)\")\n", + "\n", + "print(f\"\\nDeep Child Poverty:\")\n", + "print(f\" Baseline: {impact_2026['deep_child_poverty_baseline_rate']:.2f}%\")\n", + "print(f\" Reform: {impact_2026['deep_child_poverty_reform_rate']:.2f}%\")\n", + "print(f\" Change: {impact_2026['deep_child_poverty_rate_change']:+.2f}pp ({impact_2026['deep_child_poverty_percent_change']:+.1f}%)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "DECILE ANALYSIS (2026)\n", + "============================================================\n", + "Decile Avg Change Relative Change\n", + "---------------------------------------------\n", + "1 $ 707 6.13%\n", + "2 $ 723 2.70%\n", + "3 $ 621 1.55%\n", + "4 $ 924 1.70%\n", + "5 $ 1,105 1.57%\n", + "6 $ 666 0.77%\n", + "7 $ 583 0.53%\n", + "8 $ 513 0.35%\n", + "9 $ 197 0.10%\n", + "10 $ 94 0.01%\n" + ] + } + ], + "source": [ + "# Display decile analysis\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"DECILE ANALYSIS (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"{'Decile':<10} {'Avg Change':>15} {'Relative Change':>18}\")\n", + "print(\"-\" * 45)\n", + "for d in range(1, 11):\n", + " avg = impact_2026['decile']['average'][str(d)]\n", + " rel = impact_2026['decile']['relative'][str(d)] * 100\n", + " print(f\"{d:<10} ${avg:>14,.0f} {rel:>17.2f}%\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "INCOME BRACKET BREAKDOWN (2026)\n", + "============================================================\n", + "Bracket Beneficiaries Total Cost Avg Benefit\n", + "------------------------------------------------------------\n", + "Under $50k 21,366,040 $ 52.10B $ 2,438\n", + "$50k-$100k 12,473,454 $ 23.08B $ 1,850\n", + "$100k-$200k 11,135,840 $ 14.62B $ 1,313\n", + "$200k-$500k 5,446,002 $ 0.39B $ 71\n", + "$500k-$1M 335,220 $ 0.50B $ 1,490\n", + "$1M-$2M 31,084 $ 0.02B $ 694\n", + "Over $2M 8,306 $ 0.01B $ 961\n" + ] + } + ], + "source": [ + "# Display income bracket breakdown\n", + "print(\"\\n\" + \"=\" * 60)\n", + "print(\"INCOME BRACKET BREAKDOWN (2026)\")\n", + "print(\"=\" * 60)\n", + "print(f\"{'Bracket':<15} {'Beneficiaries':>15} {'Total Cost':>15} {'Avg Benefit':>12}\")\n", + "print(\"-\" * 60)\n", + "for bracket in impact_2026['by_income_bracket']:\n", + " print(f\"{bracket['bracket']:<15} {bracket['beneficiaries']:>15,.0f} ${bracket['total_cost']/1e9:>13.2f}B ${bracket['avg_benefit']:>10,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "marker": { + "color": "#105293" + }, + "text": [ + "$707", + "$723", + "$621", + "$924", + "$1,105", + "$666", + "$583", + "$513", + "$197", + "$94" + ], + "textposition": "auto", + "type": "bar", + "x": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "y": [ + 706.8697119537609, + 722.7084659535038, + 621.3751652670277, + 923.8222663846096, + 1104.8989530609172, + 665.7931151242624, + 582.9788289699934, + 513.3678010209588, + 197.21083161046175, + 93.91950050668866 + ] + } + ], + "layout": { + "font": { + "color": "black", + "family": "Roboto Serif" + }, + "height": 600, + "images": [ + { + "sizex": 0.15, + "sizey": 0.15, + "source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png", + "x": 1.1, + "xanchor": "right", + "xref": "paper", + "y": -0.15, + "yanchor": "bottom", + "yref": "paper" + } + ], + "modebar": { + "bgcolor": "rgba(0,0,0,0)", + "color": "rgba(0,0,0,0)" + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Average Income Change by Decile (2026) - Reform 3" + }, + "width": 800, + "xaxis": { + "tickmode": "linear", + "title": { + "text": "Income Decile" + } + }, + "yaxis": { + "title": { + "text": "Average Change ($)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Create decile bar chart\n", + "deciles = list(range(1, 11))\n", + "avg_changes = [impact_2026['decile']['average'][str(d)] for d in deciles]\n", + "\n", + "fig = go.Figure(\n", + " go.Bar(\n", + " x=deciles,\n", + " y=avg_changes,\n", + " text=[f\"${v:,.0f}\" for v in avg_changes],\n", + " textposition=\"auto\",\n", + " marker_color=\"#105293\",\n", + " )\n", + ")\n", + "\n", + "fig.update_layout(\n", + " title=\"Average Income Change by Decile (2026) - Reform 3\",\n", + " xaxis_title=\"Income Decile\",\n", + " yaxis_title=\"Average Change ($)\",\n", + " xaxis=dict(tickmode=\"linear\"),\n", + ")\n", + "\n", + "format_fig(fig).show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 10-Year Federal Budgetary Impact (2026-2035)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def calculate_budgetary_impact(reform, year):\n", + " \"\"\"Calculate just the federal income tax budgetary impact for a single year.\"\"\"\n", + " baseline = Microsimulation(dataset=DATASET)\n", + " reformed = Microsimulation(reform=reform, dataset=DATASET)\n", + " \n", + " baseline_income_tax = baseline.calculate(\"income_tax\", period=year).sum()\n", + " reformed_income_tax = reformed.calculate(\"income_tax\", period=year).sum()\n", + " \n", + " # Budgetary impact: negative means costs money (reform reduces tax revenue)\n", + " impact = reformed_income_tax - baseline_income_tax\n", + " return float(impact)\n", + "\n", + "\n", + "def calculate_ten_year_projection(reform, csv_filename=\"reform_3_10year_budgetary_impact.csv\"):\n", + " results = []\n", + "\n", + " with open(csv_filename, \"w\", newline=\"\") as csvfile:\n", + " csvwriter = csv.writer(csvfile)\n", + " csvwriter.writerow([\"Year\", \"Budgetary Impact\"])\n", + "\n", + " for year in range(2026, 2036):\n", + " print(f\"Computing budgetary impact for year {year}...\")\n", + " impact = calculate_budgetary_impact(reform, year)\n", + " results.append({\"Year\": year, \"Budgetary Impact\": impact})\n", + "\n", + " csvwriter.writerow([year, impact])\n", + " print(f\"Year {year} completed. Impact: ${impact/1e9:.2f} billion\")\n", + "\n", + " print(f\"All calculations complete. Results saved to '{csv_filename}'\")\n", + " return pd.DataFrame(results)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Xet Storage is enabled for this repo, but the 'hf_xet' package is not installed. Falling back to regular HTTP download. For better performance, install the package with: `pip install huggingface_hub[hf_xet]` or `pip install hf_xet`\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting 10-year budgetary impact calculation...\n", + "Computing budgetary impact for year 2026...\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "88fec242b41e4a8081ec0dea015d08f1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "enhanced_cps_2024.h5: 0%| | 0.00/111M [00:00 0]['household_weight'].sum()\n", + "households_with_1_child = children_per_household[children_per_household['is_child'] == 1]['household_weight'].sum()\n", + "households_with_2_children = children_per_household[children_per_household['is_child'] == 2]['household_weight'].sum()\n", + "households_with_3plus_children = children_per_household[children_per_household['is_child'] >= 3]['household_weight'].sum()\n", + "\n", + "print(f\"\\nHouseholds with children (weighted):\")\n", + "print(f\" Total households with children: {total_households_with_children:,.0f}\")\n", + "print(f\" Households with 1 child: {households_with_1_child:,.0f}\")\n", + "print(f\" Households with 2 children: {households_with_2_children:,.0f}\")\n", + "print(f\" Households with 3+ children: {households_with_3plus_children:,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Children by age:\n", + " Total children under 18: 882,828\n", + " Children under 6: 250,611\n", + " Children under 3: 106,289\n" + ] + } + ], + "source": [ + "# Check children by age groups\n", + "df = pd.DataFrame({\n", + " \"household_id\": sim.calculate(\"household_id\", map_to=\"person\"),\n", + " \"tax_unit_id\": sim.calculate(\"tax_unit_id\", map_to=\"person\"),\n", + " \"person_id\": sim.calculate(\"person_id\", map_to=\"person\"),\n", + " \"age\": sim.calculate(\"age\", map_to=\"person\"),\n", + " \"person_weight\": sim.calculate(\"person_weight\", map_to=\"person\")\n", + "})\n", + "\n", + "# Filter for children and apply weights\n", + "children_under_18_df = df[df['age'] < 18]\n", + "children_under_6_df = df[df['age'] < 6]\n", + "children_under_3_df = df[df['age'] < 3]\n", + "\n", + "# Calculate weighted totals\n", + "total_children = children_under_18_df['person_weight'].sum()\n", + "children_under_6 = children_under_6_df['person_weight'].sum()\n", + "children_under_3 = children_under_3_df['person_weight'].sum()\n", + "\n", + "print(f\"\\nChildren by age:\")\n", + "print(f\" Total children under 18: {total_children:,.0f}\")\n", + "print(f\" Children under 6: {children_under_6:,.0f}\")\n", + "print(f\" Children under 3: {children_under_3:,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Poverty Rate:\n", + " Overall poverty rate: 35.24%\n", + " Persons in poverty: 1,499,212\n" + ] + } + ], + "source": [ + "# Poverty rate\n", + "person_in_poverty = sim.calculate(\"person_in_poverty\", period=2025)\n", + "poverty_rate = person_in_poverty.mean() * 100\n", + "\n", + "print(f\"\\nPoverty Rate:\")\n", + "print(f\" Overall poverty rate: {poverty_rate:.2f}%\")\n", + "print(f\" Persons in poverty: {person_in_poverty.sum():,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "OR DATASET SUMMARY - WEIGHTED (Population Estimates)\n", + "============================================================\n", + " Metric Value\n", + " Household count (weighted) 1,421,300\n", + " Person count (weighted) 4,254,669\n", + " Median household income $45,327\n", + " Per capita income $20,320\n", + "Total households with children 430,918\n", + " Households with 1 child 176,598\n", + " Households with 2 children 126,902\n", + " Households with 3+ children 127,418\n", + " Total children under 18 882,828\n", + " Children under 6 250,611\n", + " Children under 3 106,289\n", + " Poverty rate 35.24%\n", + " Persons in poverty 1,499,212\n", + "============================================================\n", + "\n", + "Summary saved to: or_dataset_summary_weighted.csv\n" + ] + } + ], + "source": [ + "# Create weighted summary table\n", + "weighted_summary_data = {\n", + " 'Metric': [\n", + " 'Household count (weighted)',\n", + " 'Person count (weighted)',\n", + " 'Median household income',\n", + " 'Per capita income',\n", + " 'Total households with children',\n", + " 'Households with 1 child',\n", + " 'Households with 2 children',\n", + " 'Households with 3+ children',\n", + " 'Total children under 18',\n", + " 'Children under 6',\n", + " 'Children under 3',\n", + " 'Poverty rate',\n", + " 'Persons in poverty'\n", + " ],\n", + " 'Value': [\n", + " f\"{household_count.sum():,.0f}\",\n", + " f\"{person_count.sum():,.0f}\",\n", + " f\"${household_net_income.median():,.0f}\",\n", + " f\"${per_capita_income:,.0f}\",\n", + " f\"{total_households_with_children:,.0f}\",\n", + " f\"{households_with_1_child:,.0f}\",\n", + " f\"{households_with_2_children:,.0f}\",\n", + " f\"{households_with_3plus_children:,.0f}\",\n", + " f\"{total_children:,.0f}\",\n", + " f\"{children_under_6:,.0f}\",\n", + " f\"{children_under_3:,.0f}\",\n", + " f\"{poverty_rate:.2f}%\",\n", + " f\"{person_in_poverty.sum():,.0f}\"\n", + " ]\n", + "}\n", + "\n", + "weighted_df = pd.DataFrame(weighted_summary_data)\n", + "\n", + "print(\"\\n\" + \"=\"*60)\n", + "print(\"OR DATASET SUMMARY - WEIGHTED (Population Estimates)\")\n", + "print(\"=\"*60)\n", + "print(weighted_df.to_string(index=False))\n", + "print(\"=\"*60)\n", + "\n", + "# Save table\n", + "weighted_df.to_csv('or_dataset_summary_weighted.csv', index=False)\n", + "print(\"\\nSummary saved to: or_dataset_summary_weighted.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "======================================================================\n", + "HOUSEHOLDS WITH $0 INCOME\n", + "======================================================================\n", + "Household count: 174,584\n", + "Percentage of all households: 12.28%\n", + "======================================================================\n" + ] + } + ], + "source": [ + "# Households with $0 income\n", + "agi_hh = np.array(sim.calculate(\"adjusted_gross_income\", period=2025, map_to=\"household\"))\n", + "weights = np.array(sim.calculate(\"household_weight\", period=2025))\n", + "\n", + "zero_income_mask = agi_hh == 0\n", + "zero_income_count = weights[zero_income_mask].sum()\n", + "total_households = weights.sum()\n", + "\n", + "print(\"\\n\" + \"=\"*70)\n", + "print(\"HOUSEHOLDS WITH $0 INCOME\")\n", + "print(\"=\"*70)\n", + "print(f\"Household count: {zero_income_count:,.0f}\")\n", + "print(f\"Percentage of all households: {zero_income_count / total_households * 100:.2f}%\")\n", + "print(\"=\"*70)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "Oregon Income Levels or Income Distribution\n", + "============================================================\n", + "Households 1,421,300 100%\n", + "------------------------------------------------------------\n", + "Less than $10,000 143,114 10%\n", + "$10,000 to $14,999 64,845 5%\n", + "$15,000 to $19,999 79,061 6%\n", + "$20,000 to $24,999 81,193 6%\n", + "$25,000 to $29,999 84,881 6%\n", + "$30,000 to $34,999 90,474 6%\n", + "$35,000 to $39,999 76,529 5%\n", + "$40,000 to $44,999 86,980 6%\n", + "$45,000 to $49,999 66,037 5%\n", + "$50,000 to $59,999 141,424 10%\n", + "$60,000 to $74,999 149,455 11%\n", + "$75,000 to $99,999 119,919 8%\n", + "$100,000 to $124,999 67,285 5%\n", + "$125,000 to $149,999 34,898 2%\n", + "$150,000 to $199,999 46,917 3%\n", + "$200,000 or more 88,287 6%\n", + "============================================================\n" + ] + } + ], + "source": [ + "# Income distribution by Census-style brackets\n", + "hh_income = np.array(sim.calculate(\"household_net_income\", period=2025))\n", + "weights = np.array(sim.calculate(\"household_weight\", period=2025))\n", + "total_households = weights.sum()\n", + "\n", + "income_brackets = [\n", + " (None, 10000, \"Less than $10,000\"),\n", + " (10000, 15000, \"$10,000 to $14,999\"),\n", + " (15000, 20000, \"$15,000 to $19,999\"),\n", + " (20000, 25000, \"$20,000 to $24,999\"),\n", + " (25000, 30000, \"$25,000 to $29,999\"),\n", + " (30000, 35000, \"$30,000 to $34,999\"),\n", + " (35000, 40000, \"$35,000 to $39,999\"),\n", + " (40000, 45000, \"$40,000 to $44,999\"),\n", + " (45000, 50000, \"$45,000 to $49,999\"),\n", + " (50000, 60000, \"$50,000 to $59,999\"),\n", + " (60000, 75000, \"$60,000 to $74,999\"),\n", + " (75000, 100000, \"$75,000 to $99,999\"),\n", + " (100000, 125000, \"$100,000 to $124,999\"),\n", + " (125000, 150000, \"$125,000 to $149,999\"),\n", + " (150000, 200000, \"$150,000 to $199,999\"),\n", + " (200000, None, \"$200,000 or more\"),\n", + "]\n", + "\n", + "bracket_data = []\n", + "for lower, upper, label in income_brackets:\n", + " if lower is None:\n", + " mask = hh_income < upper\n", + " elif upper is None:\n", + " mask = hh_income >= lower\n", + " else:\n", + " mask = (hh_income >= lower) & (hh_income < upper)\n", + " \n", + " count = weights[mask].sum()\n", + " pct = count / total_households * 100\n", + " \n", + " bracket_data.append({\n", + " \"Income Level\": label,\n", + " \"Households\": int(round(count)),\n", + " \"Percent\": f\"{pct:.0f}%\"\n", + " })\n", + "\n", + "income_df = pd.DataFrame(bracket_data)\n", + "\n", + "print(\"\\n\" + \"=\"*60)\n", + "print(\"Oregon Income Levels or Income Distribution\")\n", + "print(\"=\"*60)\n", + "print(f\"{'Households':<25} {int(round(total_households)):>12,} 100%\")\n", + "print(\"-\"*60)\n", + "for _, row in income_df.iterrows():\n", + " print(f\"{row['Income Level']:<25} {row['Households']:>12,} {row['Percent']:>3}\")\n", + "print(\"=\"*60)" + ] + } + ], + "metadata": { + "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.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/us/states/or/data_exploration_test.ipynb b/us/states/or/data_exploration_test.ipynb new file mode 100644 index 0000000..47cc5be --- /dev/null +++ b/us/states/or/data_exploration_test.ipynb @@ -0,0 +1,452 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# OR Dataset Exploration (TEST Dataset)\n", + "\n", + "This notebook explores the Oregon (OR) TEST dataset to understand household counts, income distribution, and demographic characteristics.\n", + "\n", + "**Dataset:** `hf://policyengine/test/mar/OR.h5`" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from policyengine_us import Microsimulation\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "OR_DATASET = \"hf://policyengine/test/mar/OR.h5\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7c5c3bfaa6414f31be189af7ac26ca73", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "OR.h5: 0%| | 0.00/49.5M [00:00 0]['household_weight'].sum()\n", + "households_with_1_child = children_per_household[children_per_household['is_child'] == 1]['household_weight'].sum()\n", + "households_with_2_children = children_per_household[children_per_household['is_child'] == 2]['household_weight'].sum()\n", + "households_with_3plus_children = children_per_household[children_per_household['is_child'] >= 3]['household_weight'].sum()\n", + "\n", + "print(f\"\\nHouseholds with children (weighted):\")\n", + "print(f\" Total households with children: {total_households_with_children:,.0f}\")\n", + "print(f\" Households with 1 child: {households_with_1_child:,.0f}\")\n", + "print(f\" Households with 2 children: {households_with_2_children:,.0f}\")\n", + "print(f\" Households with 3+ children: {households_with_3plus_children:,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Children by age:\n", + " Total children under 18: 1,043,742\n", + " Children under 6: 312,191\n", + " Children under 3: 138,356\n" + ] + } + ], + "source": [ + "# Check children by age groups\n", + "df = pd.DataFrame({\n", + " \"household_id\": sim.calculate(\"household_id\", map_to=\"person\"),\n", + " \"tax_unit_id\": sim.calculate(\"tax_unit_id\", map_to=\"person\"),\n", + " \"person_id\": sim.calculate(\"person_id\", map_to=\"person\"),\n", + " \"age\": sim.calculate(\"age\", map_to=\"person\"),\n", + " \"person_weight\": sim.calculate(\"person_weight\", map_to=\"person\")\n", + "})\n", + "\n", + "# Filter for children and apply weights\n", + "children_under_18_df = df[df['age'] < 18]\n", + "children_under_6_df = df[df['age'] < 6]\n", + "children_under_3_df = df[df['age'] < 3]\n", + "\n", + "# Calculate weighted totals\n", + "total_children = children_under_18_df['person_weight'].sum()\n", + "children_under_6 = children_under_6_df['person_weight'].sum()\n", + "children_under_3 = children_under_3_df['person_weight'].sum()\n", + "\n", + "print(f\"\\nChildren by age:\")\n", + "print(f\" Total children under 18: {total_children:,.0f}\")\n", + "print(f\" Children under 6: {children_under_6:,.0f}\")\n", + "print(f\" Children under 3: {children_under_3:,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Poverty Rate:\n", + " Overall poverty rate: 23.81%\n", + " Persons in poverty: 1,120,742\n" + ] + } + ], + "source": [ + "# Poverty rate\n", + "person_in_poverty = sim.calculate(\"person_in_poverty\", period=2025)\n", + "poverty_rate = person_in_poverty.mean() * 100\n", + "\n", + "print(f\"\\nPoverty Rate:\")\n", + "print(f\" Overall poverty rate: {poverty_rate:.2f}%\")\n", + "print(f\" Persons in poverty: {person_in_poverty.sum():,.0f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "OR DATASET SUMMARY (TEST) - WEIGHTED (Population Estimates)\n", + "============================================================\n", + " Metric Value\n", + " Household count (weighted) 1,659,322\n", + " Person count (weighted) 4,707,055\n", + " Median household income $68,478\n", + " Per capita income $37,062\n", + "Total households with children 556,340\n", + " Households with 1 child 231,734\n", + " Households with 2 children 206,324\n", + " Households with 3+ children 118,282\n", + " Total children under 18 1,043,742\n", + " Children under 6 312,191\n", + " Children under 3 138,356\n", + " Poverty rate 23.81%\n", + " Persons in poverty 1,120,742\n", + "============================================================\n", + "\n", + "Summary saved to: or_dataset_summary_weighted_test.csv\n" + ] + } + ], + "source": [ + "# Create weighted summary table\n", + "weighted_summary_data = {\n", + " 'Metric': [\n", + " 'Household count (weighted)',\n", + " 'Person count (weighted)',\n", + " 'Median household income',\n", + " 'Per capita income',\n", + " 'Total households with children',\n", + " 'Households with 1 child',\n", + " 'Households with 2 children',\n", + " 'Households with 3+ children',\n", + " 'Total children under 18',\n", + " 'Children under 6',\n", + " 'Children under 3',\n", + " 'Poverty rate',\n", + " 'Persons in poverty'\n", + " ],\n", + " 'Value': [\n", + " f\"{household_count.sum():,.0f}\",\n", + " f\"{person_count.sum():,.0f}\",\n", + " f\"${household_net_income.median():,.0f}\",\n", + " f\"${per_capita_income:,.0f}\",\n", + " f\"{total_households_with_children:,.0f}\",\n", + " f\"{households_with_1_child:,.0f}\",\n", + " f\"{households_with_2_children:,.0f}\",\n", + " f\"{households_with_3plus_children:,.0f}\",\n", + " f\"{total_children:,.0f}\",\n", + " f\"{children_under_6:,.0f}\",\n", + " f\"{children_under_3:,.0f}\",\n", + " f\"{poverty_rate:.2f}%\",\n", + " f\"{person_in_poverty.sum():,.0f}\"\n", + " ]\n", + "}\n", + "\n", + "weighted_df = pd.DataFrame(weighted_summary_data)\n", + "\n", + "print(\"\\n\" + \"=\"*60)\n", + "print(\"OR DATASET SUMMARY (TEST) - WEIGHTED (Population Estimates)\")\n", + "print(\"=\"*60)\n", + "print(weighted_df.to_string(index=False))\n", + "print(\"=\"*60)\n", + "\n", + "# Save table\n", + "weighted_df.to_csv('or_dataset_summary_weighted_test.csv', index=False)\n", + "print(\"\\nSummary saved to: or_dataset_summary_weighted_test.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "======================================================================\n", + "HOUSEHOLDS WITH $0 INCOME\n", + "======================================================================\n", + "Household count: 87,631\n", + "Percentage of all households: 5.28%\n", + "======================================================================\n" + ] + } + ], + "source": [ + "# Households with $0 income\n", + "agi_hh = np.array(sim.calculate(\"adjusted_gross_income\", period=2025, map_to=\"household\"))\n", + "weights = np.array(sim.calculate(\"household_weight\", period=2025))\n", + "\n", + "zero_income_mask = agi_hh == 0\n", + "zero_income_count = weights[zero_income_mask].sum()\n", + "total_households = weights.sum()\n", + "\n", + "print(\"\\n\" + \"=\"*70)\n", + "print(\"HOUSEHOLDS WITH $0 INCOME\")\n", + "print(\"=\"*70)\n", + "print(f\"Household count: {zero_income_count:,.0f}\")\n", + "print(f\"Percentage of all households: {zero_income_count / total_households * 100:.2f}%\")\n", + "print(\"=\"*70)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "============================================================\n", + "Oregon Income Levels or Income Distribution (TEST)\n", + "============================================================\n", + "Households 1,659,322 100%\n", + "------------------------------------------------------------\n", + "Less than $10,000 114,602 7%\n", + "$10,000 to $14,999 32,526 2%\n", + "$15,000 to $19,999 51,358 3%\n", + "$20,000 to $24,999 60,062 4%\n", + "$25,000 to $29,999 58,450 4%\n", + "$30,000 to $34,999 71,698 4%\n", + "$35,000 to $39,999 73,497 4%\n", + "$40,000 to $44,999 68,881 4%\n", + "$45,000 to $49,999 64,684 4%\n", + "$50,000 to $59,999 136,728 8%\n", + "$60,000 to $74,999 165,139 10%\n", + "$75,000 to $99,999 215,260 13%\n", + "$100,000 to $124,999 152,052 9%\n", + "$125,000 to $149,999 105,248 6%\n", + "$150,000 to $199,999 121,381 7%\n", + "$200,000 or more 167,757 10%\n", + "============================================================\n" + ] + } + ], + "source": [ + "# Income distribution by Census-style brackets\n", + "hh_income = np.array(sim.calculate(\"household_net_income\", period=2025))\n", + "weights = np.array(sim.calculate(\"household_weight\", period=2025))\n", + "total_households = weights.sum()\n", + "\n", + "income_brackets = [\n", + " (None, 10000, \"Less than $10,000\"),\n", + " (10000, 15000, \"$10,000 to $14,999\"),\n", + " (15000, 20000, \"$15,000 to $19,999\"),\n", + " (20000, 25000, \"$20,000 to $24,999\"),\n", + " (25000, 30000, \"$25,000 to $29,999\"),\n", + " (30000, 35000, \"$30,000 to $34,999\"),\n", + " (35000, 40000, \"$35,000 to $39,999\"),\n", + " (40000, 45000, \"$40,000 to $44,999\"),\n", + " (45000, 50000, \"$45,000 to $49,999\"),\n", + " (50000, 60000, \"$50,000 to $59,999\"),\n", + " (60000, 75000, \"$60,000 to $74,999\"),\n", + " (75000, 100000, \"$75,000 to $99,999\"),\n", + " (100000, 125000, \"$100,000 to $124,999\"),\n", + " (125000, 150000, \"$125,000 to $149,999\"),\n", + " (150000, 200000, \"$150,000 to $199,999\"),\n", + " (200000, None, \"$200,000 or more\"),\n", + "]\n", + "\n", + "bracket_data = []\n", + "for lower, upper, label in income_brackets:\n", + " if lower is None:\n", + " mask = hh_income < upper\n", + " elif upper is None:\n", + " mask = hh_income >= lower\n", + " else:\n", + " mask = (hh_income >= lower) & (hh_income < upper)\n", + " \n", + " count = weights[mask].sum()\n", + " pct = count / total_households * 100\n", + " \n", + " bracket_data.append({\n", + " \"Income Level\": label,\n", + " \"Households\": int(round(count)),\n", + " \"Percent\": f\"{pct:.0f}%\"\n", + " })\n", + "\n", + "income_df = pd.DataFrame(bracket_data)\n", + "\n", + "print(\"\\n\" + \"=\"*60)\n", + "print(\"Oregon Income Levels or Income Distribution (TEST)\")\n", + "print(\"=\"*60)\n", + "print(f\"{'Households':<25} {int(round(total_households)):>12,} 100%\")\n", + "print(\"-\"*60)\n", + "for _, row in income_df.iterrows():\n", + " print(f\"{row['Income Level']:<25} {row['Households']:>12,} {row['Percent']:>3}\")\n", + "print(\"=\"*60)" + ] + } + ], + "metadata": { + "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.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/us/states/or/or_dataset_summary_weighted.csv b/us/states/or/or_dataset_summary_weighted.csv new file mode 100644 index 0000000..43de842 --- /dev/null +++ b/us/states/or/or_dataset_summary_weighted.csv @@ -0,0 +1,14 @@ +Metric,Value +Household count (weighted),"1,421,300" +Person count (weighted),"4,254,669" +Median household income,"$45,327" +Per capita income,"$20,320" +Total households with children,"430,918" +Households with 1 child,"176,598" +Households with 2 children,"126,902" +Households with 3+ children,"127,418" +Total children under 18,"882,828" +Children under 6,"250,611" +Children under 3,"106,289" +Poverty rate,35.24% +Persons in poverty,"1,499,212" diff --git a/us/states/or/or_dataset_summary_weighted_test.csv b/us/states/or/or_dataset_summary_weighted_test.csv new file mode 100644 index 0000000..a53660d --- /dev/null +++ b/us/states/or/or_dataset_summary_weighted_test.csv @@ -0,0 +1,14 @@ +Metric,Value +Household count (weighted),"1,659,322" +Person count (weighted),"4,707,055" +Median household income,"$68,478" +Per capita income,"$37,062" +Total households with children,"556,340" +Households with 1 child,"231,734" +Households with 2 children,"206,324" +Households with 3+ children,"118,282" +Total children under 18,"1,043,742" +Children under 6,"312,191" +Children under 3,"138,356" +Poverty rate,23.81% +Persons in poverty,"1,120,742"