From 3d02ac0ee05829e12b166d81531525c730a63d79 Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 30 Sep 2024 09:02:25 +0800 Subject: [PATCH 1/2] SPM net income to thresholds histgram --- us/household/spm_threshold.ipynb | 1227 ++++++++++++++++++++++++++++++ 1 file changed, 1227 insertions(+) create mode 100644 us/household/spm_threshold.ipynb diff --git a/us/household/spm_threshold.ipynb b/us/household/spm_threshold.ipynb new file mode 100644 index 0000000..73c36a4 --- /dev/null +++ b/us/household/spm_threshold.ipynb @@ -0,0 +1,1227 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "name": "CPS", + "type": "bar", + "x": [ + 0.1, + 0.30000000000000004, + 0.5, + 0.7000000000000001, + 0.9, + 1.1, + 1.3000000000000003, + 1.5, + 1.7000000000000002, + 1.9, + 2.1, + 2.3000000000000003, + 2.5, + 2.7, + 2.9000000000000004, + 3.1, + 3.3000000000000003, + 3.5, + 3.7, + 3.9000000000000004, + 4.1, + 4.300000000000001, + 4.5, + 4.700000000000001, + 4.9 + ], + "xaxis": "x", + "y": [ + 878, + 1296, + 1195, + 1987, + 3008, + 3660, + 3739, + 3450, + 3082, + 2869, + 2581, + 2551, + 2382, + 2263, + 2032, + 1883, + 1674, + 1546, + 1378, + 1306, + 1163, + 1086, + 922, + 817, + 761 + ], + "yaxis": "y" + }, + { + "name": "Enhanced CPS", + "type": "bar", + "x": [ + 0.1, + 0.30000000000000004, + 0.5, + 0.7000000000000001, + 0.9, + 1.1, + 1.3000000000000003, + 1.5, + 1.7000000000000002, + 1.9, + 2.1, + 2.3000000000000003, + 2.5, + 2.7, + 2.9000000000000004, + 3.1, + 3.3000000000000003, + 3.5, + 3.7, + 3.9000000000000004, + 4.1, + 4.300000000000001, + 4.5, + 4.700000000000001, + 4.9 + ], + "xaxis": "x2", + "y": [ + 2109, + 2758, + 2823, + 4100, + 5196, + 5893, + 5724, + 5160, + 4538, + 4190, + 3818, + 3666, + 3401, + 3233, + 2881, + 2638, + 2354, + 2192, + 1943, + 1829, + 1653, + 1510, + 1330, + 1194, + 1113 + ], + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "CPS 2024", + "x": 0.225, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Enhanced CPS 2024", + "x": 0.775, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "bargap": 0.1, + "barmode": "group", + "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)" + }, + "shapes": [ + { + "line": { + "color": "red", + "dash": "dash" + }, + "type": "line", + "x0": 1, + "x1": 1, + "xref": "x", + "y0": 0, + "y1": 1, + "yref": "y domain" + }, + { + "line": { + "color": "red", + "dash": "dash" + }, + "type": "line", + "x0": 1, + "x1": 1, + "xref": "x2", + "y0": 0, + "y1": 1, + "yref": "y2 domain" + } + ], + "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": "Distribution of SPM Unit Net Income / SPM Unit SPM Threshold (2024)" + }, + "width": 800, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.45 + ], + "range": [ + 0, + 5 + ], + "title": { + "text": "Ratio" + } + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.55, + 1 + ], + "range": [ + 0, + 5 + ], + "title": { + "text": "Ratio" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Frequency" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false, + "title": { + "text": "Frequency" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Summary Statistics:\n", + "CPS 2024:\n", + "count 58711.000000\n", + "mean 3.093463\n", + "std 3.311985\n", + "min -44.055717\n", + "25% 1.316754\n", + "50% 2.283899\n", + "75% 3.817694\n", + "max 104.305397\n", + "dtype: float64\n", + "\n", + "Enhanced CPS 2024:\n", + "count 117422.000000\n", + "mean 75.388573\n", + "std 489.630920\n", + "min -2853.169434\n", + "25% 0.974510\n", + "50% 2.163770\n", + "75% 4.607322\n", + "max 11401.973633\n", + "dtype: float64\n" + ] + } + ], + "source": [ + "from policyengine_us import Microsimulation\n", + "import pandas as pd\n", + "import numpy as np\n", + "import plotly.graph_objects as go\n", + "from plotly.subplots import make_subplots\n", + "from policyengine_core.charts import format_fig\n", + "\n", + "def calculate_spm_ratio(simulation, year):\n", + " spm_unit_net_income = simulation.calculate(\"spm_unit_net_income\", period=year)\n", + " spm_unit_spm_threshold = simulation.calculate(\"spm_unit_spm_threshold\", period=year)\n", + " return spm_unit_net_income / spm_unit_spm_threshold\n", + "\n", + "def create_binned_data(data, bins):\n", + " counts, bin_edges = np.histogram(data, bins=bins)\n", + " bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2\n", + " return pd.DataFrame({'bin_center': bin_centers, 'count': counts})\n", + "\n", + "# Create simulations for both datasets\n", + "year = 2024\n", + "baseline_cps = Microsimulation(dataset=\"cps_2024\")\n", + "baseline_ecps = Microsimulation(dataset=\"enhanced_cps_2024\")\n", + "\n", + "# Calculate ratios for both datasets\n", + "ratio_cps = calculate_spm_ratio(baseline_cps, year)\n", + "ratio_ecps = calculate_spm_ratio(baseline_ecps, year)\n", + "\n", + "# Create binned data\n", + "bins = np.linspace(0, 5, 26) # 25 bins from 0 to 5\n", + "df_cps_binned = create_binned_data(ratio_cps, bins)\n", + "df_ecps_binned = create_binned_data(ratio_ecps, bins)\n", + "\n", + "# Create subplots\n", + "fig = make_subplots(rows=1, cols=2, subplot_titles=(\"CPS 2024\", \"Enhanced CPS 2024\"),\n", + " shared_yaxes=True, shared_xaxes=True)\n", + "\n", + "# Add bar charts\n", + "fig.add_trace(\n", + " go.Bar(x=df_cps_binned[\"bin_center\"], y=df_cps_binned[\"count\"], name=\"CPS\"),\n", + " row=1, col=1\n", + ")\n", + "fig.add_trace(\n", + " go.Bar(x=df_ecps_binned[\"bin_center\"], y=df_ecps_binned[\"count\"], name=\"Enhanced CPS\"),\n", + " row=1, col=2\n", + ")\n", + "\n", + "# Update layout\n", + "fig.update_layout(\n", + " title_text=\"Distribution of SPM Unit Net Income / SPM Unit SPM Threshold (2024)\",\n", + " barmode='group',\n", + " bargap=0.1,\n", + " height=600,\n", + " width=1200,\n", + ")\n", + "\n", + "fig.update_xaxes(title_text=\"Ratio\", range=[0, 5])\n", + "fig.update_yaxes(title_text=\"Frequency\")\n", + "\n", + "# Add vertical lines at ratio = 1\n", + "fig.add_vline(x=1, line_dash=\"dash\", line_color=\"red\", row=1, col=1)\n", + "fig.add_vline(x=1, line_dash=\"dash\", line_color=\"red\", row=1, col=2)\n", + "\n", + "# Format the figure\n", + "fig = format_fig(fig)\n", + "\n", + "# Show the plot\n", + "fig.show()\n", + "\n", + "# Print summary statistics\n", + "print(\"Summary Statistics:\")\n", + "print(\"CPS 2024:\")\n", + "print(pd.Series(ratio_cps).describe())\n", + "print(\"\\nEnhanced CPS 2024:\")\n", + "print(pd.Series(ratio_ecps).describe())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "pe", + "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.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 434b1f92d31c16851736f09c1a44ad59d047eeaa Mon Sep 17 00:00:00 2001 From: PavelMakarchuk Date: Mon, 30 Sep 2024 20:01:46 +0800 Subject: [PATCH 2/2] Create histogram --- us/household/spm_threshold.ipynb | 1372 ++++++++++++++++++++++++++---- 1 file changed, 1210 insertions(+), 162 deletions(-) diff --git a/us/household/spm_threshold.ipynb b/us/household/spm_threshold.ipynb index 73c36a4..78e45aa 100644 --- a/us/household/spm_threshold.ipynb +++ b/us/household/spm_threshold.ipynb @@ -2,7 +2,155 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "from policyengine_us import Microsimulation\n", + "import pandas as pd\n", + "import numpy as np\n", + "import plotly.graph_objects as go\n", + "from plotly.subplots import make_subplots\n", + "from policyengine_core.charts import format_fig" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 14\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[38;5;66;03m# Calculate ratios for both datasets\u001b[39;00m\n\u001b[1;32m 13\u001b[0m ratio_cps \u001b[38;5;241m=\u001b[39m calculate_spm_ratio(baseline_cps, year)\n\u001b[0;32m---> 14\u001b[0m ratio_ecps \u001b[38;5;241m=\u001b[39m \u001b[43mcalculate_spm_ratio\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbaseline_ecps\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43myear\u001b[49m\u001b[43m)\u001b[49m\n", + "Cell \u001b[0;32mIn[4], line 2\u001b[0m, in \u001b[0;36mcalculate_spm_ratio\u001b[0;34m(simulation, year)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcalculate_spm_ratio\u001b[39m(simulation, year):\n\u001b[0;32m----> 2\u001b[0m spm_unit_net_income \u001b[38;5;241m=\u001b[39m \u001b[43msimulation\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;43mspm_unit_net_income\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmap_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mperson\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[1;32m 3\u001b[0m spm_unit_spm_threshold \u001b[38;5;241m=\u001b[39m simulation\u001b[38;5;241m.\u001b[39mcalculate(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mspm_unit_spm_threshold\u001b[39m\u001b[38;5;124m\"\u001b[39m, map_to\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mperson\u001b[39m\u001b[38;5;124m\"\u001b[39m, period\u001b[38;5;241m=\u001b[39myear)\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m spm_unit_net_income \u001b[38;5;241m/\u001b[39m spm_unit_spm_threshold\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:905\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[1;32m 904\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[0;32m--> 905\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[1;32m 906\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[1;32m 907\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 908\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 909\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:970\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 968\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\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[1;32m 972\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/household/income/spm_unit/spm_unit_benefits.py:44\u001b[0m, in \u001b[0;36mspm_unit_benefits.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m parameters(period)\u001b[38;5;241m.\u001b[39mgov\u001b[38;5;241m.\u001b[39mhud\u001b[38;5;241m.\u001b[39mabolition:\n\u001b[1;32m 43\u001b[0m BENEFITS\u001b[38;5;241m.\u001b[39mappend(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mspm_unit_capped_housing_subsidy\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 44\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43madd\u001b[49m\u001b[43m(\u001b[49m\u001b[43mspm_unit\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mBENEFITS\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/commons/formulas.py:227\u001b[0m, in \u001b[0;36madd\u001b[0;34m(entity, period, variables, options)\u001b[0m\n\u001b[1;32m 207\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21madd\u001b[39m(\n\u001b[1;32m 208\u001b[0m entity: Population,\n\u001b[1;32m 209\u001b[0m period: Period,\n\u001b[1;32m 210\u001b[0m variables: List[\u001b[38;5;28mstr\u001b[39m],\n\u001b[1;32m 211\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[1;32m 212\u001b[0m ):\n\u001b[1;32m 213\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Sums a list of variables.\u001b[39;00m\n\u001b[1;32m 214\u001b[0m \n\u001b[1;32m 215\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 225\u001b[0m \u001b[38;5;124;03m ArrayLike: The result of the operation.\u001b[39;00m\n\u001b[1;32m 226\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 227\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfor_each_variable\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 228\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[1;32m 229\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/commons/formulas.py:183\u001b[0m, in \u001b[0;36mfor_each_variable\u001b[0;34m(entity, period, variables, agg_func, group_agg_func, options)\u001b[0m\n\u001b[1;32m 181\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[1;32m 182\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[0;32m--> 183\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[1;32m 184\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mis_person:\n\u001b[1;32m 185\u001b[0m values \u001b[38;5;241m=\u001b[39m group_agg_func(\n\u001b[1;32m 186\u001b[0m entity\u001b[38;5;241m.\u001b[39mmembers(variable, period, options\u001b[38;5;241m=\u001b[39moptions)\n\u001b[1;32m 187\u001b[0m )\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:654\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 652\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, contained_months[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m])\n\u001b[1;32m 653\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 654\u001b[0m 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_add\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[1;32m 655\u001b[0m alternate_period_handling \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 656\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m variable\u001b[38;5;241m.\u001b[39mdefinition_period \u001b[38;5;241m==\u001b[39m YEAR \u001b[38;5;129;01mand\u001b[39;00m period\u001b[38;5;241m.\u001b[39munit \u001b[38;5;241m==\u001b[39m MONTH:\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:67\u001b[0m, in \u001b[0;36mMicrosimulation.calculate_add\u001b[0;34m(self, variable_name, period, map_to, use_weights)\u001b[0m\n\u001b[1;32m 60\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcalculate_add\u001b[39m(\n\u001b[1;32m 61\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 62\u001b[0m variable_name: \u001b[38;5;28mstr\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 65\u001b[0m use_weights: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[1;32m 66\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m MicroSeries:\n\u001b[0;32m---> 67\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_add\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\n\u001b[1;32m 68\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 69\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:811\u001b[0m, in \u001b[0;36mSimulation.calculate_add\u001b[0;34m(self, variable_name, period, decode_enums)\u001b[0m\n\u001b[1;32m 800\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m variable\u001b[38;5;241m.\u001b[39mdefinition_period \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m [\n\u001b[1;32m 801\u001b[0m periods\u001b[38;5;241m.\u001b[39mDAY,\n\u001b[1;32m 802\u001b[0m periods\u001b[38;5;241m.\u001b[39mMONTH,\n\u001b[1;32m 803\u001b[0m periods\u001b[38;5;241m.\u001b[39mYEAR,\n\u001b[1;32m 804\u001b[0m ]:\n\u001b[1;32m 805\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 806\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUnable to sum constant variable \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m over period \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m: only variables defined daily, monthly, or yearly can be summed over time.\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m 807\u001b[0m variable\u001b[38;5;241m.\u001b[39mname, period\n\u001b[1;32m 808\u001b[0m )\n\u001b[1;32m 809\u001b[0m )\n\u001b[0;32m--> 811\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43msum\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 812\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;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[43msub_period\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 813\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43msub_period\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_subperiods\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvariable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdefinition_period\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 814\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 815\u001b[0m holder \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_holder(variable\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m 816\u001b[0m holder\u001b[38;5;241m.\u001b[39mput_in_cache(result, period, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbranch_name)\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:812\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 800\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m variable\u001b[38;5;241m.\u001b[39mdefinition_period \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m [\n\u001b[1;32m 801\u001b[0m periods\u001b[38;5;241m.\u001b[39mDAY,\n\u001b[1;32m 802\u001b[0m periods\u001b[38;5;241m.\u001b[39mMONTH,\n\u001b[1;32m 803\u001b[0m periods\u001b[38;5;241m.\u001b[39mYEAR,\n\u001b[1;32m 804\u001b[0m ]:\n\u001b[1;32m 805\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 806\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUnable to sum constant variable \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m over period \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m: only variables defined daily, monthly, or yearly can be summed over time.\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m 807\u001b[0m variable\u001b[38;5;241m.\u001b[39mname, period\n\u001b[1;32m 808\u001b[0m )\n\u001b[1;32m 809\u001b[0m )\n\u001b[1;32m 811\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28msum\u001b[39m(\n\u001b[0;32m--> 812\u001b[0m \u001b[38;5;28;43mself\u001b[39;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[43msub_period\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 813\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m sub_period \u001b[38;5;129;01min\u001b[39;00m period\u001b[38;5;241m.\u001b[39mget_subperiods(variable\u001b[38;5;241m.\u001b[39mdefinition_period)\n\u001b[1;32m 814\u001b[0m )\n\u001b[1;32m 815\u001b[0m holder \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_holder(variable\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m 816\u001b[0m holder\u001b[38;5;241m.\u001b[39mput_in_cache(result, period, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbranch_name)\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:970\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 968\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\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[1;32m 972\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/snap.py:25\u001b[0m, in \u001b[0;36msnap.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_reported\u001b[39m\u001b[38;5;124m\"\u001b[39m, period) \u001b[38;5;241m/\u001b[39m MONTHS_IN_YEAR\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 25\u001b[0m value \u001b[38;5;241m=\u001b[39m \u001b[43madd\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 26\u001b[0m \u001b[43m \u001b[49m\u001b[43mspm_unit\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 27\u001b[0m \u001b[43m \u001b[49m\u001b[43mperiod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 28\u001b[0m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\n\u001b[1;32m 29\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msnap_normal_allotment\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 30\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msnap_emergency_allotment\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 31\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdc_snap_temporary_local_benefit\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 32\u001b[0m \u001b[43m \u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 33\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 34\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m is_in_microsim:\n\u001b[1;32m 35\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m value \u001b[38;5;241m*\u001b[39m takes_up\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/commons/formulas.py:227\u001b[0m, in \u001b[0;36madd\u001b[0;34m(entity, period, variables, options)\u001b[0m\n\u001b[1;32m 207\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21madd\u001b[39m(\n\u001b[1;32m 208\u001b[0m entity: Population,\n\u001b[1;32m 209\u001b[0m period: Period,\n\u001b[1;32m 210\u001b[0m variables: List[\u001b[38;5;28mstr\u001b[39m],\n\u001b[1;32m 211\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[1;32m 212\u001b[0m ):\n\u001b[1;32m 213\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Sums a list of variables.\u001b[39;00m\n\u001b[1;32m 214\u001b[0m \n\u001b[1;32m 215\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 225\u001b[0m \u001b[38;5;124;03m ArrayLike: The result of the operation.\u001b[39;00m\n\u001b[1;32m 226\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 227\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfor_each_variable\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 228\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[1;32m 229\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/commons/formulas.py:183\u001b[0m, in \u001b[0;36mfor_each_variable\u001b[0;34m(entity, period, variables, agg_func, group_agg_func, options)\u001b[0m\n\u001b[1;32m 181\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[1;32m 182\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[0;32m--> 183\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[1;32m 184\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mis_person:\n\u001b[1;32m 185\u001b[0m values \u001b[38;5;241m=\u001b[39m group_agg_func(\n\u001b[1;32m 186\u001b[0m entity\u001b[38;5;241m.\u001b[39mmembers(variable, period, options\u001b[38;5;241m=\u001b[39moptions)\n\u001b[1;32m 187\u001b[0m )\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:970\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 968\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\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[1;32m 972\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/snap_normal_allotment.py:16\u001b[0m, in \u001b[0;36msnap_normal_allotment.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mformula\u001b[39m(spm_unit, period, parameters):\n\u001b[1;32m 14\u001b[0m \u001b[38;5;66;03m# Federal SNAP rules are defined in U.S.C Title 7, Chapter 51, which\u001b[39;00m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;66;03m# also defines state powers to modify the rules.\u001b[39;00m\n\u001b[0;32m---> 16\u001b[0m eligible \u001b[38;5;241m=\u001b[39m \u001b[43mspm_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mis_snap_eligible\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[1;32m 17\u001b[0m expected_contribution \u001b[38;5;241m=\u001b[39m spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_expected_contribution\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m 18\u001b[0m max_allotment \u001b[38;5;241m=\u001b[39m spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_max_allotment\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:970\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 968\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\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[1;32m 972\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/eligibility/is_snap_eligible.py:16\u001b[0m, in \u001b[0;36mis_snap_eligible.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mformula\u001b[39m(spm_unit, period, parameters):\n\u001b[0;32m---> 16\u001b[0m net \u001b[38;5;241m=\u001b[39m \u001b[43mspm_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmeets_snap_net_income_test\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[1;32m 17\u001b[0m gross \u001b[38;5;241m=\u001b[39m spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmeets_snap_gross_income_test\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m 18\u001b[0m asset \u001b[38;5;241m=\u001b[39m spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmeets_snap_asset_test\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:970\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 968\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\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[1;32m 972\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/eligibility/meets_snap_net_income_test.py:19\u001b[0m, in \u001b[0;36mmeets_snap_net_income_test.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mformula\u001b[39m(spm_unit, period, parameters):\n\u001b[1;32m 16\u001b[0m net_income_limit_fpg \u001b[38;5;241m=\u001b[39m parameters(\n\u001b[1;32m 17\u001b[0m period\n\u001b[1;32m 18\u001b[0m )\u001b[38;5;241m.\u001b[39mgov\u001b[38;5;241m.\u001b[39musda\u001b[38;5;241m.\u001b[39msnap\u001b[38;5;241m.\u001b[39mincome\u001b[38;5;241m.\u001b[39mlimit\u001b[38;5;241m.\u001b[39mnet\n\u001b[0;32m---> 19\u001b[0m net_income_fpg \u001b[38;5;241m=\u001b[39m \u001b[43mspm_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msnap_net_income_fpg_ratio\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[1;32m 20\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m net_income_fpg \u001b[38;5;241m<\u001b[39m\u001b[38;5;241m=\u001b[39m net_income_limit_fpg\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:968\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 965\u001b[0m parameters_at \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mparameters\n\u001b[1;32m 967\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m formula\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__code__\u001b[39m\u001b[38;5;241m.\u001b[39mco_argcount \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[0;32m--> 968\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\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 970\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/income/snap_net_income_fpg_ratio.py:15\u001b[0m, in \u001b[0;36msnap_net_income_fpg_ratio.formula\u001b[0;34m(spm_unit, period)\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mformula\u001b[39m(spm_unit, period):\n\u001b[0;32m---> 15\u001b[0m income \u001b[38;5;241m=\u001b[39m \u001b[43mspm_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msnap_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[43m)\u001b[49m\n\u001b[1;32m 16\u001b[0m fpg \u001b[38;5;241m=\u001b[39m spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_fpg\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m 17\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m income \u001b[38;5;241m/\u001b[39m fpg\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:968\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 965\u001b[0m parameters_at \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mparameters\n\u001b[1;32m 967\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m formula\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__code__\u001b[39m\u001b[38;5;241m.\u001b[39mco_argcount \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[0;32m--> 968\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\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 970\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/income/snap_net_income.py:15\u001b[0m, in \u001b[0;36msnap_net_income.formula\u001b[0;34m(spm_unit, period)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mformula\u001b[39m(spm_unit, period):\n\u001b[1;32m 14\u001b[0m gross_income \u001b[38;5;241m=\u001b[39m spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_gross_income\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[0;32m---> 15\u001b[0m deductions \u001b[38;5;241m=\u001b[39m \u001b[43mspm_unit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msnap_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[1;32m 16\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m max_(\u001b[38;5;241m0\u001b[39m, gross_income \u001b[38;5;241m-\u001b[39m deductions)\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:905\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[1;32m 904\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[0;32m--> 905\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[1;32m 906\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[1;32m 907\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 908\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 909\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:970\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 968\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\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[1;32m 972\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/income/deductions/shelter/snap_excess_shelter_expense_deduction.py:25\u001b[0m, in \u001b[0;36msnap_excess_shelter_expense_deduction.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m 21\u001b[0m net_income_pre_shelter \u001b[38;5;241m=\u001b[39m spm_unit(\n\u001b[1;32m 22\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_net_income_pre_shelter\u001b[39m\u001b[38;5;124m\"\u001b[39m, period\n\u001b[1;32m 23\u001b[0m )\n\u001b[1;32m 24\u001b[0m subtracted_income \u001b[38;5;241m=\u001b[39m p\u001b[38;5;241m.\u001b[39mincome_share_disregard \u001b[38;5;241m*\u001b[39m net_income_pre_shelter\n\u001b[0;32m---> 25\u001b[0m housing_cost \u001b[38;5;241m=\u001b[39m \u001b[43madd\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 26\u001b[0m \u001b[43m \u001b[49m\u001b[43mspm_unit\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;43msnap_utility_allowance\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhousing_cost\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[1;32m 27\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 28\u001b[0m uncapped_ded \u001b[38;5;241m=\u001b[39m max_(housing_cost \u001b[38;5;241m-\u001b[39m subtracted_income, \u001b[38;5;241m0\u001b[39m)\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Calculate capped deduction based on state group parameter.\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/commons/formulas.py:227\u001b[0m, in \u001b[0;36madd\u001b[0;34m(entity, period, variables, options)\u001b[0m\n\u001b[1;32m 207\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21madd\u001b[39m(\n\u001b[1;32m 208\u001b[0m entity: Population,\n\u001b[1;32m 209\u001b[0m period: Period,\n\u001b[1;32m 210\u001b[0m variables: List[\u001b[38;5;28mstr\u001b[39m],\n\u001b[1;32m 211\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[1;32m 212\u001b[0m ):\n\u001b[1;32m 213\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Sums a list of variables.\u001b[39;00m\n\u001b[1;32m 214\u001b[0m \n\u001b[1;32m 215\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 225\u001b[0m \u001b[38;5;124;03m ArrayLike: The result of the operation.\u001b[39;00m\n\u001b[1;32m 226\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 227\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfor_each_variable\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 228\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[1;32m 229\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/commons/formulas.py:183\u001b[0m, in \u001b[0;36mfor_each_variable\u001b[0;34m(entity, period, variables, agg_func, group_agg_func, options)\u001b[0m\n\u001b[1;32m 181\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[1;32m 182\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[0;32m--> 183\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[1;32m 184\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mis_person:\n\u001b[1;32m 185\u001b[0m values \u001b[38;5;241m=\u001b[39m group_agg_func(\n\u001b[1;32m 186\u001b[0m entity\u001b[38;5;241m.\u001b[39mmembers(variable, period, options\u001b[38;5;241m=\u001b[39moptions)\n\u001b[1;32m 187\u001b[0m )\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/populations/group_population.py:38\u001b[0m, in \u001b[0;36mGroupPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;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[1;32m 37\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;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[0;32m~/policyengine-core/policyengine_core/populations/population.py:137\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m 133\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[1;32m 134\u001b[0m variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 137\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[1;32m 138\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[1;32m 139\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:905\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m added_variable \u001b[38;5;129;01min\u001b[39;00m adds_list:\n\u001b[1;32m 904\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[0;32m--> 905\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[1;32m 906\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[1;32m 907\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 908\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 909\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/microsimulation.py:54\u001b[0m, in \u001b[0;36mMicrosimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, use_weights, decode_enums)\u001b[0m\n\u001b[1;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[1;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[0;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[1;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m use_weights:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:463\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m 460\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[1;32m 462\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 463\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[1;32m 464\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[1;32m 465\u001b[0m result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:688\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 687\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[0;32m--> 688\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[1;32m 690\u001b[0m \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m 691\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[1;32m 692\u001b[0m \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/simulations/simulation.py:970\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m 968\u001b[0m array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\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[1;32m 972\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/income/deductions/shelter/snap_individual_utility_allowance.py:19\u001b[0m, in \u001b[0;36msnap_individual_utility_allowance.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m 16\u001b[0m region \u001b[38;5;241m=\u001b[39m spm_unit\u001b[38;5;241m.\u001b[39mhousehold(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_utility_region_str\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m 17\u001b[0m expense_types \u001b[38;5;241m=\u001b[39m utility\u001b[38;5;241m.\u001b[39msingle\u001b[38;5;241m.\u001b[39mutility_types\n\u001b[1;32m 18\u001b[0m sum_of_individual_allowances \u001b[38;5;241m=\u001b[39m \u001b[38;5;28msum\u001b[39m(\n\u001b[0;32m---> 19\u001b[0m [\n\u001b[1;32m 20\u001b[0m utility\u001b[38;5;241m.\u001b[39msingle[expense\u001b[38;5;241m.\u001b[39mreplace(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_expense\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m)][region]\n\u001b[1;32m 21\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m expense \u001b[38;5;129;01min\u001b[39;00m expense_types\n\u001b[1;32m 22\u001b[0m ]\n\u001b[1;32m 23\u001b[0m )\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m where(\n\u001b[1;32m 25\u001b[0m allowance_type \u001b[38;5;241m==\u001b[39m allowance_types\u001b[38;5;241m.\u001b[39mIUA,\n\u001b[1;32m 26\u001b[0m sum_of_individual_allowances,\n\u001b[1;32m 27\u001b[0m \u001b[38;5;241m0\u001b[39m,\n\u001b[1;32m 28\u001b[0m )\n", + "File \u001b[0;32m~/policyengine-us/policyengine_us/variables/gov/usda/snap/income/deductions/shelter/snap_individual_utility_allowance.py:20\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 16\u001b[0m region \u001b[38;5;241m=\u001b[39m spm_unit\u001b[38;5;241m.\u001b[39mhousehold(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_utility_region_str\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m 17\u001b[0m expense_types \u001b[38;5;241m=\u001b[39m utility\u001b[38;5;241m.\u001b[39msingle\u001b[38;5;241m.\u001b[39mutility_types\n\u001b[1;32m 18\u001b[0m sum_of_individual_allowances \u001b[38;5;241m=\u001b[39m \u001b[38;5;28msum\u001b[39m(\n\u001b[1;32m 19\u001b[0m [\n\u001b[0;32m---> 20\u001b[0m \u001b[43mutility\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msingle\u001b[49m\u001b[43m[\u001b[49m\u001b[43mexpense\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreplace\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m_expense\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m[\u001b[49m\u001b[43mregion\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 21\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m expense \u001b[38;5;129;01min\u001b[39;00m expense_types\n\u001b[1;32m 22\u001b[0m ]\n\u001b[1;32m 23\u001b[0m )\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m where(\n\u001b[1;32m 25\u001b[0m allowance_type \u001b[38;5;241m==\u001b[39m allowance_types\u001b[38;5;241m.\u001b[39mIUA,\n\u001b[1;32m 26\u001b[0m sum_of_individual_allowances,\n\u001b[1;32m 27\u001b[0m \u001b[38;5;241m0\u001b[39m,\n\u001b[1;32m 28\u001b[0m )\n", + "File \u001b[0;32m~/policyengine-core/policyengine_core/parameters/parameter_node_at_instant.py:58\u001b[0m, in \u001b[0;36mParameterNodeAtInstant.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__getitem__\u001b[39m(\n\u001b[1;32m 54\u001b[0m \u001b[38;5;28mself\u001b[39m, key: \u001b[38;5;28mstr\u001b[39m\n\u001b[1;32m 55\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mParameterNodeAtInstant\u001b[39m\u001b[38;5;124m\"\u001b[39m, VectorialParameterNodeAtInstant]:\n\u001b[1;32m 56\u001b[0m \u001b[38;5;66;03m# If fancy indexing is used, cast to a vectorial node\u001b[39;00m\n\u001b[1;32m 57\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[0;32m---> 58\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[1;32m 59\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\n\u001b[1;32m 60\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 61\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[0;32m~/policyengine-core/policyengine_core/parameters/vectorial_parameter_node_at_instant.py:215\u001b[0m, in \u001b[0;36mVectorialParameterNodeAtInstant.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 210\u001b[0m key \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39mselect(\n\u001b[1;32m 211\u001b[0m [key \u001b[38;5;241m==\u001b[39m item\u001b[38;5;241m.\u001b[39mindex \u001b[38;5;28;01mfor\u001b[39;00m item \u001b[38;5;129;01min\u001b[39;00m enum],\n\u001b[1;32m 212\u001b[0m [item\u001b[38;5;241m.\u001b[39mname \u001b[38;5;28;01mfor\u001b[39;00m item \u001b[38;5;129;01min\u001b[39;00m enum],\n\u001b[1;32m 213\u001b[0m )\n\u001b[1;32m 214\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 215\u001b[0m key \u001b[38;5;241m=\u001b[39m \u001b[43mkey\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mastype\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstr\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 216\u001b[0m names \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlist\u001b[39m(\n\u001b[1;32m 217\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdtype\u001b[38;5;241m.\u001b[39mnames\n\u001b[1;32m 218\u001b[0m ) \u001b[38;5;66;03m# Get all the names of the subnodes, e.g. ['zone_1', 'zone_2']\u001b[39;00m\n\u001b[1;32m 219\u001b[0m default \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39mfull_like(\n\u001b[1;32m 220\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvector[key[\u001b[38;5;241m0\u001b[39m]], numpy\u001b[38;5;241m.\u001b[39mnan\n\u001b[1;32m 221\u001b[0m ) \u001b[38;5;66;03m# In case of unexpected key, we will set the corresponding value to NaN.\u001b[39;00m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "\n", + "\n", + "def calculate_spm_ratio(simulation, year):\n", + " spm_unit_net_income = simulation.calculate(\"spm_unit_net_income\", map_to=\"person\", period=year)\n", + " spm_unit_spm_threshold = simulation.calculate(\"spm_unit_spm_threshold\", map_to=\"person\", period=year)\n", + " return spm_unit_net_income / spm_unit_spm_threshold\n", + "\n", + "\n", + "# Create simulations for both datasets\n", + "year = 2024\n", + "baseline_cps = Microsimulation(dataset=\"cps_2024\")\n", + "baseline_ecps = Microsimulation(dataset=\"enhanced_cps_2024\")\n", + "\n", + "# Calculate ratios for both datasets\n", + "ratio_cps = calculate_spm_ratio(baseline_cps, year)\n", + "ratio_ecps = calculate_spm_ratio(baseline_ecps, year)\n", + "\n", + "# Calculate dollar difference\n", + "spm_unit_net_income_cps = baseline_cps.calculate(\"spm_unit_net_income\", map_to=\"person\", period=year)\n", + "spm_unit_spm_threshold_cps = baseline_cps.calculate(\"spm_unit_spm_threshold\", map_to=\"person\", period=year)\n", + "diff_cps = spm_unit_net_income_cps - spm_unit_spm_threshold_cps\n", + "\n", + "spm_unit_net_income_ecps = baseline_ecps.calculate(\"spm_unit_net_income\", map_to=\"person\", period=year)\n", + "spm_unit_spm_threshold_ecps = baseline_ecps.calculate(\"spm_unit_spm_threshold\", map_to=\"person\", period=year)\n", + "diff_ecps = spm_unit_net_income_ecps - spm_unit_spm_threshold_ecps" + ] + }, + { + "cell_type": "code", + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -13,124 +161,512 @@ }, "data": [ { - "name": "CPS", + "name": "CPS - Ratio", "type": "bar", "x": [ - 0.1, - 0.30000000000000004, - 0.5, - 0.7000000000000001, - 0.9, - 1.1, - 1.3000000000000003, - 1.5, - 1.7000000000000002, - 1.9, - 2.1, - 2.3000000000000003, - 2.5, - 2.7, - 2.9000000000000004, - 3.1, - 3.3000000000000003, - 3.5, - 3.7, - 3.9000000000000004, - 4.1, - 4.300000000000001, - 4.5, - 4.700000000000001, - 4.9 + null, + 0.05, + 0.15000000000000002, + 0.25, + 0.35000000000000003, + 0.45, + 0.55, + 0.6500000000000001, + 0.75, + 0.8500000000000001, + 0.95, + 1.05, + 1.1500000000000001, + 1.25, + 1.35, + 1.4500000000000002, + null ], "xaxis": "x", "y": [ - 878, - 1296, - 1195, - 1987, - 3008, - 3660, - 3739, - 3450, - 3082, - 2869, - 2581, - 2551, - 2382, - 2263, - 2032, - 1883, - 1674, - 1546, - 1378, - 1306, - 1163, - 1086, - 922, - 817, - 761 + 666, + 536, + 750, + 1165, + 947, + 1041, + 1363, + 1766, + 2368, + 2866, + 3653, + 4117, + 4206, + 4640, + 5014, + 4722, + 104445 ], "yaxis": "y" }, { - "name": "Enhanced CPS", + "name": "Enhanced CPS - Ratio", "type": "bar", "x": [ - 0.1, - 0.30000000000000004, - 0.5, - 0.7000000000000001, - 0.9, - 1.1, - 1.3000000000000003, - 1.5, - 1.7000000000000002, - 1.9, - 2.1, - 2.3000000000000003, - 2.5, - 2.7, - 2.9000000000000004, - 3.1, - 3.3000000000000003, - 3.5, - 3.7, - 3.9000000000000004, - 4.1, - 4.300000000000001, - 4.5, - 4.700000000000001, - 4.9 + null, + 0.05, + 0.15000000000000002, + 0.25, + 0.35000000000000003, + 0.45, + 0.55, + 0.6500000000000001, + 0.75, + 0.8500000000000001, + 0.95, + 1.05, + 1.1500000000000001, + 1.25, + 1.35, + 1.4500000000000002, + null ], "xaxis": "x2", "y": [ - 2109, - 2758, - 2823, - 4100, - 5196, - 5893, - 5724, - 5160, - 4538, - 4190, - 3818, - 3666, - 3401, - 3233, - 2881, - 2638, - 2354, - 2192, - 1943, - 1829, - 1653, - 1510, - 1330, - 1194, - 1113 + 31339, + 1531, + 1917, + 2376, + 2236, + 2510, + 3121, + 3685, + 4550, + 5129, + 6010, + 6639, + 6827, + 7352, + 7434, + 6784, + 189090 ], "yaxis": "y2" + }, + { + "name": "CPS - Difference", + "type": "bar", + "x": [ + -49500, + -48500, + -47500, + -46500, + -45500, + -44500, + -43500, + -42500, + -41500, + -40500, + -39500, + -38500, + -37500, + -36500, + -35500, + -34500, + -33500, + -32500, + -31500, + -30500, + -29500, + -28500, + -27500, + -26500, + -25500, + -24500, + -23500, + -22500, + -21500, + -20500, + -19500, + -18500, + -17500, + -16500, + -15500, + -14500, + -13500, + -12500, + -11500, + -10500, + -9500, + -8500, + -7500, + -6500, + -5500, + -4500, + -3500, + -2500, + -1500, + -500, + 500, + 1500, + 2500, + 3500, + 4500, + 5500, + 6500, + 7500, + 8500, + 9500, + 10500, + 11500, + 12500, + 13500, + 14500, + 15500, + 16500, + 17500, + 18500, + 19500, + 20500, + 21500, + 22500, + 23500, + 24500, + 25500, + 26500, + 27500, + 28500, + 29500, + 30500, + 31500, + 32500, + 33500, + 34500, + 35500, + 36500, + 37500, + 38500, + 39500, + 40500, + 41500, + 42500, + 43500, + 44500, + 45500, + 46500, + 47500, + 48500, + 49500 + ], + "xaxis": "x3", + "y": [ + 28, + 12, + 14, + 18, + 14, + 32, + 26, + 5, + 23, + 30, + 39, + 38, + 34, + 38, + 69, + 44, + 57, + 68, + 65, + 67, + 102, + 92, + 126, + 155, + 128, + 126, + 173, + 240, + 221, + 334, + 322, + 347, + 387, + 443, + 441, + 539, + 591, + 571, + 670, + 673, + 664, + 630, + 715, + 828, + 828, + 970, + 1058, + 1133, + 1335, + 1453, + 1544, + 1397, + 1397, + 1510, + 1438, + 1441, + 1377, + 1393, + 1356, + 1419, + 1504, + 1515, + 1566, + 1604, + 1404, + 1457, + 1362, + 1553, + 1485, + 1291, + 1360, + 1289, + 1239, + 1255, + 1287, + 1204, + 1225, + 1300, + 1103, + 1153, + 1227, + 1184, + 1168, + 1091, + 1095, + 1133, + 1098, + 1078, + 1110, + 1127, + 1059, + 1034, + 1002, + 996, + 937, + 925, + 1089, + 942, + 871, + 860 + ], + "yaxis": "y3" + }, + { + "name": "Enhanced CPS - Difference", + "type": "bar", + "x": [ + -49500, + -48500, + -47500, + -46500, + -45500, + -44500, + -43500, + -42500, + -41500, + -40500, + -39500, + -38500, + -37500, + -36500, + -35500, + -34500, + -33500, + -32500, + -31500, + -30500, + -29500, + -28500, + -27500, + -26500, + -25500, + -24500, + -23500, + -22500, + -21500, + -20500, + -19500, + -18500, + -17500, + -16500, + -15500, + -14500, + -13500, + -12500, + -11500, + -10500, + -9500, + -8500, + -7500, + -6500, + -5500, + -4500, + -3500, + -2500, + -1500, + -500, + 500, + 1500, + 2500, + 3500, + 4500, + 5500, + 6500, + 7500, + 8500, + 9500, + 10500, + 11500, + 12500, + 13500, + 14500, + 15500, + 16500, + 17500, + 18500, + 19500, + 20500, + 21500, + 22500, + 23500, + 24500, + 25500, + 26500, + 27500, + 28500, + 29500, + 30500, + 31500, + 32500, + 33500, + 34500, + 35500, + 36500, + 37500, + 38500, + 39500, + 40500, + 41500, + 42500, + 43500, + 44500, + 45500, + 46500, + 47500, + 48500, + 49500 + ], + "xaxis": "x4", + "y": [ + 106, + 148, + 158, + 130, + 139, + 135, + 173, + 118, + 180, + 165, + 193, + 172, + 211, + 213, + 265, + 199, + 257, + 245, + 285, + 275, + 355, + 271, + 329, + 445, + 419, + 408, + 512, + 644, + 584, + 745, + 788, + 828, + 914, + 990, + 1103, + 1110, + 1258, + 1273, + 1370, + 1423, + 1312, + 1364, + 1612, + 1615, + 1627, + 1800, + 1911, + 2050, + 2147, + 2326, + 2357, + 2258, + 2289, + 2436, + 2286, + 2293, + 2236, + 2232, + 2262, + 2257, + 2303, + 2294, + 2339, + 2424, + 2117, + 2201, + 2176, + 2209, + 2171, + 1997, + 2014, + 1844, + 1917, + 1825, + 1851, + 1750, + 1802, + 1883, + 1605, + 1681, + 1726, + 1677, + 1627, + 1558, + 1601, + 1539, + 1573, + 1476, + 1543, + 1617, + 1457, + 1470, + 1422, + 1371, + 1327, + 1294, + 1391, + 1348, + 1255, + 1167 + ], + "yaxis": "y4" } ], "layout": { @@ -140,7 +676,7 @@ "size": 16 }, "showarrow": false, - "text": "CPS 2024", + "text": "CPS 2024 - Ratio", "x": 0.225, "xanchor": "center", "xref": "paper", @@ -153,13 +689,39 @@ "size": 16 }, "showarrow": false, - "text": "Enhanced CPS 2024", + "text": "Enhanced CPS 2024 - Ratio", "x": 0.775, "xanchor": "center", "xref": "paper", "y": 1, "yanchor": "bottom", "yref": "paper" + }, + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "CPS 2024 - Dollar Difference", + "x": 0.225, + "xanchor": "center", + "xref": "paper", + "y": 0.375, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Enhanced CPS 2024 - Dollar Difference", + "x": 0.775, + "xanchor": "center", + "xref": "paper", + "y": 0.375, + "yanchor": "bottom", + "yref": "paper" } ], "bargap": 0.1, @@ -212,6 +774,32 @@ "y0": 0, "y1": 1, "yref": "y2 domain" + }, + { + "line": { + "color": "red", + "dash": "dash" + }, + "type": "line", + "x0": 0, + "x1": 0, + "xref": "x3", + "y0": 0, + "y1": 1, + "yref": "y3 domain" + }, + { + "line": { + "color": "red", + "dash": "dash" + }, + "type": "line", + "x0": 0, + "x1": 0, + "xref": "x4", + "y0": 0, + "y1": 1, + "yref": "y4 domain" } ], "template": { @@ -1031,7 +1619,7 @@ } }, "title": { - "text": "Distribution of SPM Unit Net Income / SPM Unit SPM Threshold (2024)" + "text": "Distribution of SPM Unit Net Income / SPM Unit SPM Threshold and Dollar Difference (2024)" }, "width": 800, "xaxis": { @@ -1042,7 +1630,7 @@ ], "range": [ 0, - 5 + 1.5 ], "title": { "text": "Ratio" @@ -1056,16 +1644,44 @@ ], "range": [ 0, - 5 + 1.5 ], "title": { "text": "Ratio" } }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.45 + ], + "range": [ + -20000, + 20000 + ], + "title": { + "text": "Dollar Difference" + } + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.55, + 1 + ], + "range": [ + -20000, + 20000 + ], + "title": { + "text": "Dollar Difference" + } + }, "yaxis": { "anchor": "x", "domain": [ - 0, + 0.625, 1 ], "title": { @@ -1075,14 +1691,30 @@ "yaxis2": { "anchor": "x2", "domain": [ - 0, + 0.625, 1 ], "matches": "y", - "showticklabels": false, + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 0.375 + ], "title": { "text": "Frequency" } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0, + 0.375 + ], + "matches": "y3", + "showticklabels": false } } } @@ -1096,90 +1728,103 @@ "text": [ "Summary Statistics:\n", "CPS 2024:\n", - "count 58711.000000\n", - "mean 3.093463\n", - "std 3.311985\n", - "min -44.055717\n", - "25% 1.316754\n", - "50% 2.283899\n", - "75% 3.817694\n", - "max 104.305397\n", + "count 144265.000000\n", + "mean 3.112052\n", + "std 3.075388\n", + "min -44.055717\n", + "25% 1.420955\n", + "50% 2.346481\n", + "75% 3.801475\n", + "max 104.305397\n", "dtype: float64\n", "\n", "Enhanced CPS 2024:\n", - "count 117422.000000\n", - "mean 75.388573\n", - "std 489.630920\n", - "min -2853.169434\n", - "25% 0.974510\n", - "50% 2.163770\n", - "75% 4.607322\n", - "max 11401.973633\n", + "count 288530.000000\n", + "mean 74.728607\n", + "std 438.380035\n", + "min -3641.827637\n", + "25% 1.116068\n", + "50% 2.306132\n", + "75% 4.879819\n", + "max 11173.454102\n", "dtype: float64\n" ] } ], "source": [ - "from policyengine_us import Microsimulation\n", - "import pandas as pd\n", - "import numpy as np\n", - "import plotly.graph_objects as go\n", - "from plotly.subplots import make_subplots\n", - "from policyengine_core.charts import format_fig\n", - "\n", - "def calculate_spm_ratio(simulation, year):\n", - " spm_unit_net_income = simulation.calculate(\"spm_unit_net_income\", period=year)\n", - " spm_unit_spm_threshold = simulation.calculate(\"spm_unit_spm_threshold\", period=year)\n", - " return spm_unit_net_income / spm_unit_spm_threshold\n", - "\n", "def create_binned_data(data, bins):\n", - " counts, bin_edges = np.histogram(data, bins=bins)\n", - " bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2\n", + " counts = np.zeros(len(bins) - 1, dtype=int)\n", + " for i in range(len(bins) - 1):\n", + " counts[i] = ((data >= bins[i]) & (data < bins[i+1])).sum()\n", + " bin_centers = (bins[:-1] + bins[1:]) / 2\n", " return pd.DataFrame({'bin_center': bin_centers, 'count': counts})\n", "\n", - "# Create simulations for both datasets\n", - "year = 2024\n", - "baseline_cps = Microsimulation(dataset=\"cps_2024\")\n", - "baseline_ecps = Microsimulation(dataset=\"enhanced_cps_2024\")\n", + "# Calculate dollar difference\n", + "spm_unit_net_income_cps = baseline_cps.calculate(\"spm_unit_net_income\", map_to=\"person\", period=year)\n", + "spm_unit_spm_threshold_cps = baseline_cps.calculate(\"spm_unit_spm_threshold\", map_to=\"person\", period=year)\n", + "diff_cps = spm_unit_net_income_cps - spm_unit_spm_threshold_cps\n", "\n", - "# Calculate ratios for both datasets\n", - "ratio_cps = calculate_spm_ratio(baseline_cps, year)\n", - "ratio_ecps = calculate_spm_ratio(baseline_ecps, year)\n", + "spm_unit_net_income_ecps = baseline_ecps.calculate(\"spm_unit_net_income\", map_to=\"person\", period=year)\n", + "spm_unit_spm_threshold_ecps = baseline_ecps.calculate(\"spm_unit_spm_threshold\", map_to=\"person\", period=year)\n", + "diff_ecps = spm_unit_net_income_ecps - spm_unit_spm_threshold_ecps\n", + "\n", + "# Create binned data for ratios\n", + "ratio_bins = np.concatenate([[-np.inf], np.linspace(0, 1.5, 16), [np.inf]])\n", + "df_cps_ratio = create_binned_data(ratio_cps, ratio_bins)\n", + "df_ecps_ratio = create_binned_data(ratio_ecps, ratio_bins)\n", "\n", - "# Create binned data\n", - "bins = np.linspace(0, 5, 26) # 25 bins from 0 to 5\n", - "df_cps_binned = create_binned_data(ratio_cps, bins)\n", - "df_ecps_binned = create_binned_data(ratio_ecps, bins)\n", + "# Create binned data for dollar differences\n", + "diff_bins = np.arange(-50000, 50001, 1000)\n", + "df_cps_diff = create_binned_data(diff_cps, diff_bins)\n", + "df_ecps_diff = create_binned_data(diff_ecps, diff_bins)\n", "\n", "# Create subplots\n", - "fig = make_subplots(rows=1, cols=2, subplot_titles=(\"CPS 2024\", \"Enhanced CPS 2024\"),\n", - " shared_yaxes=True, shared_xaxes=True)\n", + "fig = make_subplots(rows=2, cols=2, \n", + " subplot_titles=(\"CPS 2024 - Ratio\", \"Enhanced CPS 2024 - Ratio\",\n", + " \"CPS 2024 - Dollar Difference\", \"Enhanced CPS 2024 - Dollar Difference\"),\n", + " shared_yaxes=True)\n", "\n", - "# Add bar charts\n", + "# Add bar charts for ratios\n", "fig.add_trace(\n", - " go.Bar(x=df_cps_binned[\"bin_center\"], y=df_cps_binned[\"count\"], name=\"CPS\"),\n", + " go.Bar(x=df_cps_ratio['bin_center'], y=df_cps_ratio['count'], name=\"CPS - Ratio\"),\n", " row=1, col=1\n", ")\n", "fig.add_trace(\n", - " go.Bar(x=df_ecps_binned[\"bin_center\"], y=df_ecps_binned[\"count\"], name=\"Enhanced CPS\"),\n", + " go.Bar(x=df_ecps_ratio['bin_center'], y=df_ecps_ratio['count'], name=\"Enhanced CPS - Ratio\"),\n", " row=1, col=2\n", ")\n", "\n", + "# Add bar charts for dollar differences\n", + "fig.add_trace(\n", + " go.Bar(x=df_cps_diff['bin_center'], y=df_cps_diff['count'], name=\"CPS - Difference\"),\n", + " row=2, col=1\n", + ")\n", + "fig.add_trace(\n", + " go.Bar(x=df_ecps_diff['bin_center'], y=df_ecps_diff['count'], name=\"Enhanced CPS - Difference\"),\n", + " row=2, col=2\n", + ")\n", + "\n", "# Update layout\n", "fig.update_layout(\n", - " title_text=\"Distribution of SPM Unit Net Income / SPM Unit SPM Threshold (2024)\",\n", + " title_text=\"Distribution of SPM Unit Net Income / SPM Unit SPM Threshold and Dollar Difference (2024)\",\n", " barmode='group',\n", " bargap=0.1,\n", - " height=600,\n", + " height=1200,\n", " width=1200,\n", ")\n", "\n", - "fig.update_xaxes(title_text=\"Ratio\", range=[0, 5])\n", - "fig.update_yaxes(title_text=\"Frequency\")\n", + "fig.update_xaxes(title_text=\"Ratio\", range=[0, 1.5], row=1, col=1)\n", + "fig.update_xaxes(title_text=\"Ratio\", range=[0, 1.5], row=1, col=2)\n", + "fig.update_xaxes(title_text=\"Dollar Difference\", range=[-20000, 20000], row=2, col=1)\n", + "fig.update_xaxes(title_text=\"Dollar Difference\", range=[-20000, 20000], row=2, col=2)\n", + "fig.update_yaxes(title_text=\"Frequency\", row=1, col=1)\n", + "fig.update_yaxes(title_text=\"Frequency\", row=2, col=1)\n", "\n", - "# Add vertical lines at ratio = 1\n", + "# Add vertical lines at ratio = 1 and difference = 0\n", "fig.add_vline(x=1, line_dash=\"dash\", line_color=\"red\", row=1, col=1)\n", "fig.add_vline(x=1, line_dash=\"dash\", line_color=\"red\", row=1, col=2)\n", + "fig.add_vline(x=0, line_dash=\"dash\", line_color=\"red\", row=2, col=1)\n", + "fig.add_vline(x=0, line_dash=\"dash\", line_color=\"red\", row=2, col=2)\n", "\n", "# Format the figure\n", "fig = format_fig(fig)\n", @@ -1195,6 +1840,409 @@ "print(pd.Series(ratio_ecps).describe())" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# We care aboout of up to 150% - also include negative item , also do dollar perspective - $1,000 bin of how for from poverty line (keep 10% bins as well)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "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", + " \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", + "
bin_centercount
00.1793342
10.31803468
20.55449166
30.79763932
40.923043143
51.134265985
61.327311177
71.540745925
81.725037491
91.924195811
102.129200200
112.326410743
122.525655470
132.739314615
142.923762198
153.131972235
163.324221269
173.513114715
183.723810156
193.935762263
204.112501176
214.318227428
224.515230711
234.721192736
244.94135988
\n", + "
" + ], + "text/plain": [ + " bin_center count\n", + "0 0.1 793342\n", + "1 0.3 1803468\n", + "2 0.5 5449166\n", + "3 0.7 9763932\n", + "4 0.9 23043143\n", + "5 1.1 34265985\n", + "6 1.3 27311177\n", + "7 1.5 40745925\n", + "8 1.7 25037491\n", + "9 1.9 24195811\n", + "10 2.1 29200200\n", + "11 2.3 26410743\n", + "12 2.5 25655470\n", + "13 2.7 39314615\n", + "14 2.9 23762198\n", + "15 3.1 31972235\n", + "16 3.3 24221269\n", + "17 3.5 13114715\n", + "18 3.7 23810156\n", + "19 3.9 35762263\n", + "20 4.1 12501176\n", + "21 4.3 18227428\n", + "22 4.5 15230711\n", + "23 4.7 21192736\n", + "24 4.9 4135988" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_ecps_binned" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "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", + " \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", + "
bin_centercount
00.1368725
10.31542170
20.52713584
30.76793768
40.913535442
51.121175379
61.328231565
71.530122345
81.729415661
91.931482229
102.131728681
112.333893848
122.534590418
132.735356225
142.933997876
153.133605395
163.330738193
173.530943792
183.730395200
193.928515424
204.126817481
214.327186862
224.523775144
234.721622333
244.921527679
\n", + "
" + ], + "text/plain": [ + " bin_center count\n", + "0 0.1 368725\n", + "1 0.3 1542170\n", + "2 0.5 2713584\n", + "3 0.7 6793768\n", + "4 0.9 13535442\n", + "5 1.1 21175379\n", + "6 1.3 28231565\n", + "7 1.5 30122345\n", + "8 1.7 29415661\n", + "9 1.9 31482229\n", + "10 2.1 31728681\n", + "11 2.3 33893848\n", + "12 2.5 34590418\n", + "13 2.7 35356225\n", + "14 2.9 33997876\n", + "15 3.1 33605395\n", + "16 3.3 30738193\n", + "17 3.5 30943792\n", + "18 3.7 30395200\n", + "19 3.9 28515424\n", + "20 4.1 26817481\n", + "21 4.3 27186862\n", + "22 4.5 23775144\n", + "23 4.7 21622333\n", + "24 4.9 21527679" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_cps_binned" + ] + }, { "cell_type": "code", "execution_count": null,