From b497295b9d51bfedcede7b199eb8bc9d10a0e9e6 Mon Sep 17 00:00:00 2001 From: Vahid Ahmadi Date: Tue, 16 Jun 2026 14:25:56 +0100 Subject: [PATCH 1/3] Add bus_fare_spending input variable Companion to the LCFS bus fare imputation in policyengine-uk-data (#428). Household-level COICOP 7.3.2 (bus & coach fares), mirroring petrol_spending/ diesel_spending. CPI-uprated; not added into the consumption total, which already counts bus fares via transport_consumption. Provides the passenger fare households pay (vs the ETB-based bus_subsidy_spending) for modelling bus fare reforms. Resolves #1779. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../input/consumption/bus_fare_spending.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 policyengine_uk/variables/input/consumption/bus_fare_spending.py diff --git a/policyengine_uk/variables/input/consumption/bus_fare_spending.py b/policyengine_uk/variables/input/consumption/bus_fare_spending.py new file mode 100644 index 000000000..2d80c1b9e --- /dev/null +++ b/policyengine_uk/variables/input/consumption/bus_fare_spending.py @@ -0,0 +1,17 @@ +from policyengine_uk.model_api import * + +# COICOP 7.3.2 (passenger transport by road: bus & coach fares). A +# sub-component of transport_consumption, imputed separately from LCFS by +# policyengine-uk-data so bus fare reforms can be modelled. Not added into the +# `consumption` total, which already counts it via transport_consumption. + + +class bus_fare_spending(Variable): + label = "bus and coach fare spending" + documentation = "Household spending on bus and coach fares (COICOP 7.3.2)." + entity = Household + definition_period = YEAR + value_type = float + unit = GBP + quantity_type = FLOW + uprating = "gov.economic_assumptions.indices.obr.consumer_price_index" From 57acd54620194c0bcd0343da5365237e92ef61ac Mon Sep 17 00:00:00 2001 From: Vahid Ahmadi Date: Tue, 16 Jun 2026 14:26:26 +0100 Subject: [PATCH 2/3] Add changelog entry for bus_fare_spending variable (#1780) Co-Authored-By: Claude Opus 4.8 (1M context) --- changelog.d/1780.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1780.md diff --git a/changelog.d/1780.md b/changelog.d/1780.md new file mode 100644 index 000000000..e56744d74 --- /dev/null +++ b/changelog.d/1780.md @@ -0,0 +1 @@ +- Add `bus_fare_spending` Household input variable (COICOP 7.3.2 bus & coach fares), the companion to the LCFS bus fare imputation in policyengine-uk-data, providing the passenger fare households pay (distinct from the ETB-based `bus_subsidy_spending`) as a building block for modelling bus fare reforms. Resolves #1779. From a420b3eabb3255173d3602f41f51b62774a99194 Mon Sep 17 00:00:00 2001 From: Vahid Ahmadi Date: Wed, 17 Jun 2026 10:36:08 +0100 Subject: [PATCH 3/3] Uprate bus fare spending in extended datasets --- policyengine_uk/data/uprating_indices.yaml | 1 + .../tests/test_road_fuel_volume_uprating.py | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/policyengine_uk/data/uprating_indices.yaml b/policyengine_uk/data/uprating_indices.yaml index 7686f2946..b8a0ad7b9 100644 --- a/policyengine_uk/data/uprating_indices.yaml +++ b/policyengine_uk/data/uprating_indices.yaml @@ -8,6 +8,7 @@ gov.economic_assumptions.yoy_growth.obr.average_earnings: gov.economic_assumptions.yoy_growth.obr.consumer_price_index: - afcs_reported - alcohol_and_tobacco_consumption +- bus_fare_spending - bsp_reported - carers_allowance_reported - child_benefit_reported diff --git a/policyengine_uk/tests/test_road_fuel_volume_uprating.py b/policyengine_uk/tests/test_road_fuel_volume_uprating.py index 9010a0607..13fc0eb7a 100644 --- a/policyengine_uk/tests/test_road_fuel_volume_uprating.py +++ b/policyengine_uk/tests/test_road_fuel_volume_uprating.py @@ -107,3 +107,42 @@ def weighted_litres(household, spending_variable, price_parameter, year): weighted_litres(household_2034, "diesel_spending", diesel_price, 2034) * (1 + road_fuel_volume(2035)) ) + + +def test_bus_fare_spending_uses_cpi_uprating(): + parameters = system.parameters + cpi = parameters.gov.economic_assumptions.yoy_growth.obr.consumer_price_index + + dataset = UKSingleYearDataset( + person=pd.DataFrame( + { + "person_id": [1], + "person_benunit_id": [1], + "person_household_id": [1], + "age": [40], + } + ), + benunit=pd.DataFrame({"benunit_id": [1]}), + household=pd.DataFrame( + { + "household_id": [1], + "region": ["LONDON"], + "tenure_type": ["OWNED_OUTRIGHT"], + "council_tax": [1_500.0], + "rent": [0.0], + "household_weight": [1.0], + "bus_fare_spending": [100.0], + } + ), + fiscal_year=2025, + ) + + extended = extend_single_year_dataset( + dataset, + tax_benefit_system_parameters=parameters, + end_year=2026, + ) + + assert extended[2026].household["bus_fare_spending"].iloc[0] == pytest.approx( + 100 * (1 + cpi(2026)) + )