Repository: PolicyEngine/policyengine-us (language: python)

Issue:
Add speedtest to PR actions
It'd be useful to know how much each PR changes the total runtime of the simulation.


Discussion / hints:

Fix patch:
diff --git a/.github/compare_speed.py b/.github/compare_speed.py
new file mode 100644
index 00000000000..06cb2eaf91d
--- /dev/null
+++ b/.github/compare_speed.py
@@ -0,0 +1,38 @@
+import yaml
+
+with open("speedtest_old.yaml", "r") as f:
+    old = yaml.safe_load(f)
+
+with open("speedtest_new.yaml", "r") as f:
+    new = yaml.safe_load(f)
+
+import pandas as pd
+
+df = pd.DataFrame(
+    {
+        "import": [old["import"], new["import"]],
+        "run": [old["run"], new["run"]],
+    }
+)
+df["total"] = df["import"] + df["run"]
+df = df.T
+df.columns = ["old", "new"]
+df["change"] = df["new"] - df["old"]
+df["percent_change"] = df["change"] / df["old"] * 100
+print("Comparison of speedtest results:")
+print(df.to_markdown())
+
+rel_change = df.percent_change.values[-1]
+
+if rel_change < 0:
+    print("Nice! The new version is faster.")
+elif rel_change < 5:
+    print("The new version is slightly slower.")
+elif rel_change < 100:
+    print(
+        "WARNING: The new version is significantly slower. PLEASE make sure to check nothing's super unnecessarily slow."
+    )
+else:
+    raise ValueError(
+        "The new version is WAY slower (over double runtime). Please check what's going on. Throwing this error."
+    )
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index 42749a51658..3f5c2b3a6e2 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -57,6 +57,8 @@ jobs:
         run: make test-other
         env:
           POVERTYTRACKER_RAW_URL: ${{ secrets.POVERTYTRACKER_RAW_URL }}
+      - name: Check model speed
+        run: make compare-speed
       - name: Produce combined coverage repository
         run: make coverage
       - uses: codecov/codecov-action@v4
diff --git a/Makefile b/Makefile
index f510edb3c3d..0cf75688f52 100644
--- a/Makefile
+++ b/Makefile
@@ -39,3 +39,12 @@ clear-storage:
 	rm -f policyengine_us/data/storage/*.h5
 	rm -f policyengine_us/data/storage/*.csv.gz
 	rm -rf policyengine_us/data/storage/*cache
+compare-speed:
+	pip uninstall policyengine-us -y
+	pip install policyengine-us
+	cd policyengine_us/tools && python speedtest.py
+	mv policyengine_us/tools/speedtest.yaml speedtest_old.yaml
+	pip install -e .
+	cd policyengine_us/tools && python speedtest.py
+	mv policyengine_us/tools/speedtest.yaml speedtest_new.yaml
+	python .github/compare_speed.py
diff --git a/changelog_entry.yaml b/changelog_entry.yaml
index e69de29bb2d..06e55e182ba 100644
--- a/changelog_entry.yaml
+++ b/changelog_entry.yaml
@@ -0,0 +1,4 @@
+- bump: patch
+  changes:
+    added:
+    - Speedtests to PRs.


Test patch:
diff --git a/policyengine_us/tools/speedtest.py b/policyengine_us/tools/speedtest.py
index 51c96e56f23..964e4ad998b 100644
--- a/policyengine_us/tools/speedtest.py
+++ b/policyengine_us/tools/speedtest.py
@@ -1,7 +1,22 @@
-from policyengine_us import Simulation, Microsimulation
-from policyengine_core.tracers import FullTracer
+import timeit
+import yaml
 
-simulation = Microsimulation()
-simulation.trace = True
-simulation.calculate("household_net_income", 2023)
-simulation.tracer.generate_performance_graph(".")
+
+def import_pe():
+    from policyengine_us import Microsimulation
+
+
+def run_pe():
+    from policyengine_us import Microsimulation
+
+    Microsimulation().calculate("household_net_income")
+
+
+COUNT_RUNS = 3
+time_to_import = timeit.timeit(import_pe, number=COUNT_RUNS) / COUNT_RUNS
+time_to_run = (
+    timeit.timeit(run_pe, number=COUNT_RUNS) / COUNT_RUNS - time_to_import
+)
+
+with open("speedtest.yaml", "w") as f:
+    f.write(yaml.dump({"import": time_to_import, "run": time_to_run}))
diff --git a/test.ipynb b/test.ipynb
deleted file mode 100644
index 28a0a40d6df..00000000000
--- a/test.ipynb
+++ /dev/null
@@ -1,391 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from policyengine_us.data import CPS_2022\n",
-    "\n",
-    "CPS_2022().generate()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from policyengine_us import Microsimulation\n",
-    "\n",
-    "cps = Microsimulation()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "medicare_part_b_premiums = cps.calc(\"medicare_part_b_premiums\").sum()\n",
-    "health_insurance_premiums_without_medicare_part_b = cps.calc(\n",
-    "    \"health_insurance_premiums_without_medicare_part_b\"\n",
-    ").sum()\n",
-    "over_the_counter_health_expenses = cps.calc(\n",
-    "    \"over_the_counter_health_expenses\"\n",
-    ").sum()\n",
-    "other_medical_expenses = cps.calc(\"other_medical_expenses\").sum()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "723.2645120672555"
-      ]
-     },
-     "execution_count": 18,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "(\n",
-    "    medicare_part_b_premiums\n",
-    "    + health_insurance_premiums_without_medicare_part_b\n",
-    "    + over_the_counter_health_expenses\n",
-    "    + other_medical_expenses\n",
-    ") / 1e9"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "(95.93751102182175, 329.0403248718849, 61.92701522462018, 236.35966094892862)"
-      ]
-     },
-     "execution_count": 19,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# Slight deviation expected as we are using different weights.\n",
-    "medicare_part_b_premiums / 1e9, health_insurance_premiums_without_medicare_part_b / 1e9, over_the_counter_health_expenses / 1e9, other_medical_expenses / 1e9"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 20,
-   "metadata": {},
-   "outputs": [
-    {
-     "ename": "VariableNotFoundError",
-     "evalue": "You tried to calculate or to set a value for variable 'medical_expense', but it was not found in the loaded tax and benefit system (CountryTaxBenefitSystem).\nAre you sure you spelled 'medical_expense' correctly?\nIf this code used to work and suddenly does not, this is most probably linked to an update of the tax and benefit system.\nLook at its changelog to learn about renames and removals and update your code. If it is an official package,\nit is probably available on <https://github.com/openfisca/CountryTaxBenefitSystem/blob/master/CHANGELOG.md>.",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[0;31mVariableNotFoundError\u001b[0m                     Traceback (most recent call last)",
-      "Cell \u001b[0;32mIn[20], line 7\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mpolicyengine_us\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdata\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m (\n\u001b[1;32m      2\u001b[0m     CPS_2022,\n\u001b[1;32m      3\u001b[0m     EnhancedCPS_2022,\n\u001b[1;32m      4\u001b[0m     CalibratedPUFExtendedCPS_2022,\n\u001b[1;32m      5\u001b[0m )\n\u001b[0;32m----> 7\u001b[0m CalibratedPUFExtendedCPS_2022()\u001b[38;5;241m.\u001b[39mgenerate()\n\u001b[1;32m      8\u001b[0m EnhancedCPS_2022()\u001b[38;5;241m.\u001b[39mgenerate()\n",
-      "File \u001b[0;32m~/PolicyEngine/policyengine-us/policyengine_us/data/datasets/cps/enhanced_cps/calibrated_cps.py:20\u001b[0m, in \u001b[0;36mCalibratedDataset.generate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m     18\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m year \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtime_period, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtime_period \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnum_years):\n\u001b[1;32m     19\u001b[0m     year \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(year)\n\u001b[0;32m---> 20\u001b[0m     adjusted_weights \u001b[38;5;241m=\u001b[39m calibrate(\n\u001b[1;32m     21\u001b[0m         cps,\n\u001b[1;32m     22\u001b[0m         time_period\u001b[38;5;241m=\u001b[39myear,\n\u001b[1;32m     23\u001b[0m         training_log_path\u001b[38;5;241m=\u001b[39mSTORAGE_FOLDER \u001b[38;5;241m/\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcalibration_log.csv.gz\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m     24\u001b[0m     )\n\u001b[1;32m     25\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m variable \u001b[38;5;129;01min\u001b[39;00m cps\u001b[38;5;241m.\u001b[39mvariables:\n\u001b[1;32m     26\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m variable \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m new_data:\n",
-      "File \u001b[0;32m~/PolicyEngine/policyengine-us/policyengine_us/data/datasets/cps/enhanced_cps/calibrate.py:37\u001b[0m, in \u001b[0;36mcalibrate\u001b[0;34m(dataset, time_period, training_log_path, learning_rate, epochs)\u001b[0m\n\u001b[1;32m     23\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcalibrate\u001b[39m(\n\u001b[1;32m     24\u001b[0m     dataset: \u001b[38;5;28mstr\u001b[39m,\n\u001b[1;32m     25\u001b[0m     time_period: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m2022\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m     28\u001b[0m     epochs: \u001b[38;5;28mint\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m10_000\u001b[39m,\n\u001b[1;32m     29\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m np\u001b[38;5;241m.\u001b[39mndarray:\n\u001b[1;32m     30\u001b[0m     (\n\u001b[1;32m     31\u001b[0m         household_weights,\n\u001b[1;32m     32\u001b[0m         weight_adjustment,\n\u001b[1;32m     33\u001b[0m         values_df,\n\u001b[1;32m     34\u001b[0m         targets,\n\u001b[1;32m     35\u001b[0m         targets_array,\n\u001b[1;32m     36\u001b[0m         equivalisation_factors_array,\n\u001b[0;32m---> 37\u001b[0m     ) \u001b[38;5;241m=\u001b[39m generate_model_variables(dataset, time_period)\n\u001b[1;32m     38\u001b[0m     household_weights \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mtensor(household_weights, dtype\u001b[38;5;241m=\u001b[39mtorch\u001b[38;5;241m.\u001b[39mfloat32)\n\u001b[1;32m     39\u001b[0m     weight_adjustment \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mtensor(\n\u001b[1;32m     40\u001b[0m         weight_adjustment, dtype\u001b[38;5;241m=\u001b[39mtorch\u001b[38;5;241m.\u001b[39mfloat32, requires_grad\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m     41\u001b[0m     )\n",
-      "File \u001b[0;32m~/PolicyEngine/policyengine-us/policyengine_us/data/datasets/cps/enhanced_cps/loss.py:84\u001b[0m, in \u001b[0;36mgenerate_model_variables\u001b[0;34m(dataset, time_period, no_weight_adjustment)\u001b[0m\n\u001b[1;32m     79\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m variable_name \u001b[38;5;129;01min\u001b[39;00m PROGRAMS:\n\u001b[1;32m     80\u001b[0m     label \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m     81\u001b[0m         simulation\u001b[38;5;241m.\u001b[39mtax_benefit_system\u001b[38;5;241m.\u001b[39mvariables[variable_name]\u001b[38;5;241m.\u001b[39mlabel\n\u001b[1;32m     82\u001b[0m         \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m (CBO)\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m     83\u001b[0m     )\n\u001b[0;32m---> 84\u001b[0m     values_df[label] \u001b[38;5;241m=\u001b[39m simulation\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m     85\u001b[0m         variable_name, map_to\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhousehold\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m     86\u001b[0m     )\u001b[38;5;241m.\u001b[39mvalues\n\u001b[1;32m     87\u001b[0m     targets[label] \u001b[38;5;241m=\u001b[39m parameters\u001b[38;5;241m.\u001b[39mgov\u001b[38;5;241m.\u001b[39mcbo[variable_name]\n\u001b[1;32m     88\u001b[0m     equivalisation[label] \u001b[38;5;241m=\u001b[39m FINANCIAL_EQUIVALISATION\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:631\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    629\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    630\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 631\u001b[0m         values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcalculate_add(variable_name, period)\n\u001b[1;32m    632\u001b[0m     alternate_period_handling \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m    633\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate_add(variable_name, period, map_to)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:788\u001b[0m, in \u001b[0;36mSimulation.calculate_add\u001b[0;34m(self, variable_name, period, decode_enums)\u001b[0m\n\u001b[1;32m    777\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    778\u001b[0m     periods\u001b[38;5;241m.\u001b[39mDAY,\n\u001b[1;32m    779\u001b[0m     periods\u001b[38;5;241m.\u001b[39mMONTH,\n\u001b[1;32m    780\u001b[0m     periods\u001b[38;5;241m.\u001b[39mYEAR,\n\u001b[1;32m    781\u001b[0m ]:\n\u001b[1;32m    782\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m    783\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    784\u001b[0m             variable\u001b[38;5;241m.\u001b[39mname, period\n\u001b[1;32m    785\u001b[0m         )\n\u001b[1;32m    786\u001b[0m     )\n\u001b[0;32m--> 788\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28msum\u001b[39m(\n\u001b[1;32m    789\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcalculate(variable_name, sub_period)\n\u001b[1;32m    790\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    791\u001b[0m )\n\u001b[1;32m    792\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    793\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:789\u001b[0m, in \u001b[0;36m<genexpr>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m    777\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    778\u001b[0m     periods\u001b[38;5;241m.\u001b[39mDAY,\n\u001b[1;32m    779\u001b[0m     periods\u001b[38;5;241m.\u001b[39mMONTH,\n\u001b[1;32m    780\u001b[0m     periods\u001b[38;5;241m.\u001b[39mYEAR,\n\u001b[1;32m    781\u001b[0m ]:\n\u001b[1;32m    782\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m    783\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    784\u001b[0m             variable\u001b[38;5;241m.\u001b[39mname, period\n\u001b[1;32m    785\u001b[0m         )\n\u001b[1;32m    786\u001b[0m     )\n\u001b[1;32m    788\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28msum\u001b[39m(\n\u001b[0;32m--> 789\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcalculate(variable_name, sub_period)\n\u001b[1;32m    790\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    791\u001b[0m )\n\u001b[1;32m    792\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    793\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:947\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    945\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m    946\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 947\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n\u001b[1;32m    949\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n",
-      "File \u001b[0;32m~/PolicyEngine/policyengine-us/policyengine_us/variables/gov/usda/snap/snap.py:23\u001b[0m, in \u001b[0;36msnap.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m     21\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     22\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 23\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m add(\n\u001b[1;32m     24\u001b[0m         spm_unit,\n\u001b[1;32m     25\u001b[0m         period,\n\u001b[1;32m     26\u001b[0m         [\n\u001b[1;32m     27\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_normal_allotment\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m     28\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_emergency_allotment\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m     29\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdc_snap_temporary_local_benefit\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m     30\u001b[0m         ],\n\u001b[1;32m     31\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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 for_each_variable(\n\u001b[1;32m    228\u001b[0m         entity, period, variables, agg_func\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124madd\u001b[39m\u001b[38;5;124m\"\u001b[39m, options\u001b[38;5;241m=\u001b[39moptions\n\u001b[1;32m    229\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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 entity(variable, period, options\u001b[38;5;241m=\u001b[39moptions)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__call__\u001b[39m(variable_name, period, options)\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m    138\u001b[0m         variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m    139\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:947\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    945\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m    946\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 947\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n\u001b[1;32m    949\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n",
-      "File \u001b[0;32m~/PolicyEngine/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 spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mis_snap_eligible\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__call__\u001b[39m(variable_name, period, options)\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m    138\u001b[0m         variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m    139\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:947\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    945\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m    946\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 947\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n\u001b[1;32m    949\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n",
-      "File \u001b[0;32m~/PolicyEngine/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 spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmeets_snap_net_income_test\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__call__\u001b[39m(variable_name, period, options)\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m    138\u001b[0m         variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m    139\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:947\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    945\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m    946\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 947\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n\u001b[1;32m    949\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n",
-      "File \u001b[0;32m~/PolicyEngine/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 spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_net_income_fpg_ratio\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__call__\u001b[39m(variable_name, period, options)\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m    138\u001b[0m         variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m    139\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:945\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    942\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    944\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--> 945\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m    946\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    947\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n",
-      "File \u001b[0;32m~/PolicyEngine/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 spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_net_income\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__call__\u001b[39m(variable_name, period, options)\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m    138\u001b[0m         variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m    139\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:945\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    942\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    944\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--> 945\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m    946\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    947\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n",
-      "File \u001b[0;32m~/PolicyEngine/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 spm_unit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msnap_deductions\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__call__\u001b[39m(variable_name, period, options)\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msimulation\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m    138\u001b[0m         variable_name, period, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcalculate_kwargs\n\u001b[1;32m    139\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:882\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    880\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    881\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--> 882\u001b[0m         values \u001b[38;5;241m=\u001b[39m values \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcalculate(\n\u001b[1;32m    883\u001b[0m             added_variable, period, map_to\u001b[38;5;241m=\u001b[39mvariable\u001b[38;5;241m.\u001b[39mentity\u001b[38;5;241m.\u001b[39mkey\n\u001b[1;32m    884\u001b[0m         )\n\u001b[1;32m    885\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    886\u001b[0m         \u001b[38;5;28;01mtry\u001b[39;00m:\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/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;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mcalculate(variable_name, period, map_to, decode_enums)\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~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:459\u001b[0m, in \u001b[0;36mSimulation.calculate\u001b[0;34m(self, variable_name, period, map_to, decode_enums)\u001b[0m\n\u001b[1;32m    456\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    458\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 459\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_calculate(variable_name, period)\n\u001b[1;32m    460\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    461\u001b[0m         result \u001b[38;5;241m=\u001b[39m result\u001b[38;5;241m.\u001b[39mdecode_to_str()\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:665\u001b[0m, in \u001b[0;36mSimulation._calculate\u001b[0;34m(self, variable_name, period)\u001b[0m\n\u001b[1;32m    663\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    664\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--> 665\u001b[0m     array \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_formula(variable, population, period)\n\u001b[1;32m    667\u001b[0m     \u001b[38;5;66;03m# If no result, use the default value and cache it\u001b[39;00m\n\u001b[1;32m    668\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    669\u001b[0m         \u001b[38;5;66;03m# Check if the variable has a previously defined value\u001b[39;00m\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py:947\u001b[0m, in \u001b[0;36mSimulation._run_formula\u001b[0;34m(self, variable, population, period)\u001b[0m\n\u001b[1;32m    945\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period)\n\u001b[1;32m    946\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 947\u001b[0m     array \u001b[38;5;241m=\u001b[39m formula(population, period, parameters_at)\n\u001b[1;32m    949\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m array\n",
-      "File \u001b[0;32m~/PolicyEngine/policyengine-us/policyengine_us/variables/gov/usda/snap/income/deductions/snap_excess_medical_expense_deduction.py:21\u001b[0m, in \u001b[0;36msnap_excess_medical_expense_deduction.formula\u001b[0;34m(spm_unit, period, parameters)\u001b[0m\n\u001b[1;32m     19\u001b[0m elderly \u001b[38;5;241m=\u001b[39m person(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mis_usda_elderly\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m     20\u001b[0m disabled \u001b[38;5;241m=\u001b[39m person(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mis_usda_disabled\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[0;32m---> 21\u001b[0m moop \u001b[38;5;241m=\u001b[39m person(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmedical_expense\u001b[39m\u001b[38;5;124m\"\u001b[39m, period)\n\u001b[1;32m     22\u001b[0m elderly_disabled_moop \u001b[38;5;241m=\u001b[39m spm_unit\u001b[38;5;241m.\u001b[39msum(moop \u001b[38;5;241m*\u001b[39m (elderly \u001b[38;5;241m|\u001b[39m disabled))\n\u001b[1;32m     23\u001b[0m p \u001b[38;5;241m=\u001b[39m parameters(\n\u001b[1;32m     24\u001b[0m     period\n\u001b[1;32m     25\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[39mdeductions\u001b[38;5;241m.\u001b[39mexcess_medical_expense\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/populations/population.py:103\u001b[0m, in \u001b[0;36mPopulation.__call__\u001b[0;34m(self, variable_name, period, options)\u001b[0m\n\u001b[1;32m     87\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__call__\u001b[39m(\n\u001b[1;32m     88\u001b[0m     \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m     89\u001b[0m     variable_name: \u001b[38;5;28mstr\u001b[39m,\n\u001b[1;32m     90\u001b[0m     period: Period \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m     91\u001b[0m     options: Optional[Container[\u001b[38;5;28mstr\u001b[39m]] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m     92\u001b[0m ):\n\u001b[1;32m     93\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m     94\u001b[0m \u001b[38;5;124;03m    Calculate the variable ``variable_name`` for the entity and the period ``period``, using the variable formula if it exists.\u001b[39;00m\n\u001b[1;32m     95\u001b[0m \n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    101\u001b[0m \u001b[38;5;124;03m    :returns: A numpy array containing the result of the calculation\u001b[39;00m\n\u001b[1;32m    102\u001b[0m \u001b[38;5;124;03m    \"\"\"\u001b[39;00m\n\u001b[0;32m--> 103\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mentity\u001b[38;5;241m.\u001b[39mcheck_variable_defined_for_entity(variable_name)\n\u001b[1;32m    104\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcheck_period_validity(variable_name, period)\n\u001b[1;32m    106\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m options \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/entities/entity.py:34\u001b[0m, in \u001b[0;36mEntity.check_variable_defined_for_entity\u001b[0;34m(self, variable_name)\u001b[0m\n\u001b[1;32m     33\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcheck_variable_defined_for_entity\u001b[39m(\u001b[38;5;28mself\u001b[39m, variable_name: \u001b[38;5;28mstr\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m---> 34\u001b[0m     variable_entity \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_variable(\n\u001b[1;32m     35\u001b[0m         variable_name, check_existence\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m     36\u001b[0m     )\u001b[38;5;241m.\u001b[39mentity\n\u001b[1;32m     37\u001b[0m     \u001b[38;5;66;03m# Should be this:\u001b[39;00m\n\u001b[1;32m     38\u001b[0m     \u001b[38;5;66;03m# if variable_entity is not self:\u001b[39;00m\n\u001b[1;32m     39\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m variable_entity\u001b[38;5;241m.\u001b[39mkey \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkey:\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/entities/entity.py:29\u001b[0m, in \u001b[0;36mEntity.get_variable\u001b[0;34m(self, variable_name, check_existence)\u001b[0m\n\u001b[1;32m     28\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_variable\u001b[39m(\u001b[38;5;28mself\u001b[39m, variable_name: \u001b[38;5;28mstr\u001b[39m, check_existence: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m):\n\u001b[0;32m---> 29\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_tax_benefit_system\u001b[38;5;241m.\u001b[39mget_variable(\n\u001b[1;32m     30\u001b[0m         variable_name, check_existence\n\u001b[1;32m     31\u001b[0m     )\n",
-      "File \u001b[0;32m~/miniconda3/envs/policyengine/lib/python3.11/site-packages/policyengine_core/taxbenefitsystems/tax_benefit_system.py:494\u001b[0m, in \u001b[0;36mTaxBenefitSystem.get_variable\u001b[0;34m(self, variable_name, check_existence)\u001b[0m\n\u001b[1;32m    492\u001b[0m found \u001b[38;5;241m=\u001b[39m variables\u001b[38;5;241m.\u001b[39mget(variable_name)\n\u001b[1;32m    493\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m found \u001b[38;5;129;01mand\u001b[39;00m check_existence:\n\u001b[0;32m--> 494\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m VariableNotFoundError(variable_name, \u001b[38;5;28mself\u001b[39m)\n\u001b[1;32m    495\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m found\n",
-      "\u001b[0;31mVariableNotFoundError\u001b[0m: You tried to calculate or to set a value for variable 'medical_expense', but it was not found in the loaded tax and benefit system (CountryTaxBenefitSystem).\nAre you sure you spelled 'medical_expense' correctly?\nIf this code used to work and suddenly does not, this is most probably linked to an update of the tax and benefit system.\nLook at its changelog to learn about renames and removals and update your code. If it is an official package,\nit is probably available on <https://github.com/openfisca/CountryTaxBenefitSystem/blob/master/CHANGELOG.md>."
-     ]
-    }
-   ],
-   "source": [
-    "from policyengine_us.data import (\n",
-    "    CPS_2022,\n",
-    "    EnhancedCPS_2022,\n",
-    "    CalibratedPUFExtendedCPS_2022,\n",
-    ")\n",
-    "\n",
-    "CalibratedPUFExtendedCPS_2022().generate()\n",
-    "EnhancedCPS_2022().generate()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [
-    {
-     "ename": "",
-     "evalue": "",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[1;31mRunning cells with 'policyengine (Python 3.9.16)' requires the ipykernel package.\n",
-      "\u001b[1;31mRun the following command to install 'ipykernel' into the Python environment. \n",
-      "\u001b[1;31mCommand: 'conda install -n policyengine ipykernel --update-deps --force-reinstall'"
-     ]
-    }
-   ],
-   "source": [
-    "from policyengine_us.data import CalibratedPUFExtendedCPS_2022\n",
-    "\n",
-    "CalibratedPUFExtendedCPS_2022().generate()\n",
-    "# Then rename calibrated_puf_extended_cps_2022.h5 to enhanced_cps_2022.h5 and upload"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from policyengine_us import Microsimulation\n",
-    "from policyengine_core.reforms import Reform\n",
-    "from policyengine_core.periods import instant"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.0"
-      ]
-     },
-     "execution_count": 12,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "def use_reported_state_income_tax(parameters):\n",
-    "    parameters.simulation.reported_state_income_tax.update(\n",
-    "        start=instant(\"2024-01-01\"), stop=instant(\"2024-12-31\"), value=True\n",
-    "    )\n",
-    "    return parameters\n",
-    "\n",
-    "\n",
-    "class baseline_reform(Reform):\n",
-    "    def apply(self):\n",
-    "        self.modify_parameters(use_reported_state_income_tax)\n",
-    "\n",
-    "\n",
-    "sim = Microsimulation(reform=baseline_reform)\n",
-    "sim.calc(\"irs_employment_income\", period=2024).min()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "-5936.919"
-      ]
-     },
-     "execution_count": 21,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sim.calc(\"household_tax_before_refundable_credits\", period=2024).min()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.0"
-      ]
-     },
-     "execution_count": 15,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sim.calc(\"employee_payroll_tax\", period=2024).min()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0.0"
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sim.calc(\"self_employment_tax\", period=2024).min()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "-0.00019454956"
-      ]
-     },
-     "execution_count": 20,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sim.calc(\"income_tax_before_refundable_credits\", period=2024).min()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "income_tax_before_credits 0.0\n",
-      "net_investment_income_tax 0.0\n",
-      "recapture_of_investment_credit 0.0\n",
-      "unreported_payroll_tax 0.0\n",
-      "qualified_retirement_penalty 0.0\n",
-      "income_tax_capped_non_refundable_credits 0.0\n",
-      "spm_unit_state_tax_reported -6045.521\n"
-     ]
-    }
-   ],
-   "source": [
-    "# Print the min of each of these.\n",
-    "COLS = [\n",
-    "    \"income_tax_before_credits\",\n",
-    "    \"net_investment_income_tax\",\n",
-    "    \"recapture_of_investment_credit\",\n",
-    "    \"unreported_payroll_tax\",\n",
-    "    \"qualified_retirement_penalty\",\n",
-    "    \"income_tax_capped_non_refundable_credits\",\n",
-    "    \"spm_unit_state_tax_reported\",\n",
-    "]\n",
-    "for col in COLS:\n",
-    "    print(col, sim.calc(col, period=2024).min())"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "policyengine",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.11.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}