Housing assistance#
Housing assistance is a payment that varies with income, household size, rental expenses, local economic conditions, and other factors.
How earnings affect a one-person household’s housing assistance#
Consider a single person household in San Francisco, California with $2,000 monthly earned income and $1,000 monthly rent. They would be eligible for $400 per month in housing assistance.
from policyengine_us import IndividualSim
import pandas as pd
import plotly.express as px
sim_emp = IndividualSim(year=2022)
sim_emp.add_person(name="person", employment_income=2000 * 12)
sim_emp.add_spm_unit(
name="spm_unit",
members=["person"],
hud_gross_rent=1_000 * 12,
# 2022 AMI.
# https://sfmohcd.org/sites/default/files/Documents/MOH/BMR%20Ownership/2022%20AMI-IncomeLimits.pdf
ami=138550,
# 2019 1BR payment standard.
# https://sfmohcd.org/sites/default/files/Documents/MOH/Asset%20Management/2019%20AMI_RentLimits-HMFA.pdf
pha_payment_standard=2748 * 12,
)
print(
"Housing assistance: ",
round(sim_emp.calc("housing_assistance")[0] / 12),
)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/simulation_builder.py in init_variable_values(self, entity, instance_object, instance_id)
548 try:
--> 549 entity.check_variable_defined_for_entity(variable_name)
550 except (
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/entities/entity.py in check_variable_defined_for_entity(self, variable_name)
51 )
---> 52 raise ValueError(message)
ValueError: You tried to compute the variable 'ami' for the entity 'spm_units';
however the variable 'ami' is defined for 'households'.
Learn more about entities in our documentation:
<https://openfisca.org/doc/coding-the-legislation/50_entities.html>.
During handling of the above exception, another exception occurred:
SituationParsingError Traceback (most recent call last)
/tmp/ipykernel_2520/768002617.py in <cell line: 0>()
19 print(
20 "Housing assistance: ",
---> 21 round(sim_emp.calc("housing_assistance")[0] / 12),
22 )
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/individual_sim.py in calc(self, var, period, target, index, map_to, reform)
238 """
239 if not hasattr(self, "simulation"):
--> 240 self.build()
241
242 if self.parametric_vary and reform is None:
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/individual_sim.py in build(self)
86 ] = members
87 # Add missing entities with specified default roles
---> 88 self.simulation = Simulation(
89 tax_benefit_system=self.system,
90 situation=self.situation_data,
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/simulation.py in __init__(self, tax_benefit_system, populations, situation, dataset, reform, trace)
146 builder = SimulationBuilder()
147 builder.default_period = self.default_input_period
--> 148 builder.build_from_dict(self.tax_benefit_system, situation, self)
149 self.has_axes = builder.has_axes
150
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/simulation_builder.py in build_from_dict(self, tax_benefit_system, input_dict, simulation)
84 for key in input_dict.keys()
85 ):
---> 86 simulation = self.build_from_entities(
87 tax_benefit_system, input_dict, simulation
88 )
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/simulation_builder.py in build_from_entities(self, tax_benefit_system, input_dict, simulation)
174 instances_json = input_dict.get(entity_class.plural)
175 if instances_json is not None:
--> 176 self.add_group_entity(
177 self.persons_plural,
178 persons_ids,
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/simulation_builder.py in add_group_entity(self, persons_plural, persons_ids, entity, instances_json)
483 self.roles[entity.plural][person_index] = person_role
484
--> 485 self.init_variable_values(entity, variables_json, instance_id)
486
487 if persons_to_allocate:
/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/policyengine_core/simulations/simulation_builder.py in init_variable_values(self, entity, instance_object, instance_id)
551 ValueError
552 ) as e: # The variable is defined for another entity
--> 553 raise SituationParsingError(path_in_json, e.args[0])
554 except VariableNotFoundError as e: # The variable doesn't exist
555 raise SituationParsingError(path_in_json, str(e), code=404)
SituationParsingError: {'spm_units': {'spm_unit': {'ami': "You tried to compute the variable 'ami' for the entity 'spm_units'; however the variable 'ami' is defined for 'households'. Learn more about entities in our documentation: <https://openfisca.org/doc/coding-the-legislation/50_entities.html>."}}}
What if their earnings change? They receive their full rent of $1,000 if they have zero earnings, and the benefit phases out at 30 cents per dollar of earnings, until it fully phases out at $3,333 monthly earnings.
sim_emp.vary("employment_income", max=4_000 * 12, step=120)
import plotly.express as px
LABELS = dict(
employment_income="Monthly employment income",
dividend_income="Monthly dividend income",
income="Monthly income",
income_source="Income source",
housing_cost="Monthly housing cost",
housing_assistance="Monthly housing assistance",
hap_mtr="Marginal tax rate from HAP",
housing_assistance_mtr="Marginal tax rate from housing assistance",
hap="Housing assistance payment (if eligible)",
)
emp_df_full = pd.DataFrame(
dict(
employment_income=sim_emp.calc("employment_income")[0] / 12,
hap=sim_emp.calc("hud_hap")[0] / 12,
housing_assistance=sim_emp.calc("housing_assistance")[0] / 12,
hap_mtr=-sim_emp.deriv("hud_hap", "employment_income"),
housing_assistance_mtr=-sim_emp.deriv(
"housing_assistance", "employment_income"
),
)
)
fig = px.line(
emp_df_full,
"employment_income",
"housing_assistance",
labels=LABELS,
title="Housing assistance for a one-person household in California with $1,000 monthly housing costs",
)
fig.update_layout(xaxis_tickformat="$,", yaxis_tickformat="$,")
fig.show()
We can also view their marginal tax rate from the program, revealing housing assistance’s 30% phase-out rate.
fig = px.line(
emp_df_full,
"employment_income",
"housing_assistance_mtr",
labels=LABELS,
title="Housing assistance MTR for a one-person household in California with $1,000 monthly housing costs",
)
fig.update_layout(
xaxis_tickformat="$,", yaxis_tickformat=".0%", yaxis_range=[0, 1]
)
fig.show()