policyengine-uk 2.36.1__py3-none-any.whl → 2.37.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -86,6 +86,13 @@ class UKDataset:
86
86
  household=self.household.copy(),
87
87
  )
88
88
 
89
+ def validate(self):
90
+ # Check for NaNs in the tables
91
+ for df in self.tables:
92
+ for col in df.columns:
93
+ if df[col].isna().any():
94
+ raise ValueError(f"Column '{col}' contains NaN values.")
95
+
89
96
  @staticmethod
90
97
  def from_simulation(
91
98
  simulation: "Microsimulation", fiscal_year: int = 2025
@@ -263,3 +263,21 @@ ons:
263
263
  reference:
264
264
  - title: ONS Population Projections
265
265
  href: https://www.ons.gov.uk/
266
+ ofwat:
267
+ water_bills:
268
+ description: Water and sewerage bills year-on-year growth.
269
+ values:
270
+ 2022-01-01: 0.052
271
+ 2023-01-01: 0.092
272
+ 2024-01-01: 0.044
273
+ 2025-01-01: 0.061
274
+ 2026-01-01: 0.061
275
+ 2027-01-01: 0.051
276
+ 2028-01-01: 0.038
277
+ 2029-01-01: 0.043
278
+ metadata:
279
+ unit: /1
280
+ label: water bills growth
281
+ reference:
282
+ - title: Ofwat (and custom projections)
283
+ href: https://www.ofwat.gov.uk/price-review/
@@ -0,0 +1,6 @@
1
+ # Water bills projections
2
+
3
+ In this folder, we have:
4
+
5
+ * `forecast_water_bills.py` - A script that projects water bills based on historical data and proposed increases.
6
+ * `ofwat_increases.csv` A CSV with the data from [here](https://www.ccw.org.uk/our-work/price-review/how-much-will-my-water-and-sewerage-bills-increase-by-2030/breakdown-of-water-companies-bill-increases-2025-30/) with proposed pre-inflation increases for each water company.
@@ -0,0 +1,80 @@
1
+ import pandas as pd
2
+ from pathlib import Path
3
+
4
+
5
+ def project_water_bills():
6
+ df_pre_2025 = pd.DataFrame(
7
+ {
8
+ "Year": [2021, 2022, 2023, 2024, 2025],
9
+ "Oftwat avg bills (real)": [486, 470, 486, 492, 503],
10
+ "CPIH": [113.1, 123.0, 129.9, 134.0, 139.0],
11
+ }
12
+ )
13
+
14
+ df_pre_2025["Oftwat avg bills (nominal)"] = (
15
+ df_pre_2025["Oftwat avg bills (real)"] * df_pre_2025["CPIH"] / 100
16
+ )
17
+ df_pre_2025["Oftwat avg bills (nominal)"] = (
18
+ df_pre_2025["Oftwat avg bills (nominal)"]
19
+ / df_pre_2025["Oftwat avg bills (nominal)"].iloc[0]
20
+ * 100
21
+ ).round(1)
22
+ df_pre_2025["Nominal YoY change"] = (
23
+ df_pre_2025["Oftwat avg bills (nominal)"].pct_change() * 100
24
+ ).round(1)
25
+
26
+ proposed_increases = pd.read_csv(
27
+ Path(__file__).parent / "ofwat_increases.csv"
28
+ )
29
+ avg_bills_2025_onwards = (
30
+ proposed_increases[proposed_increases.columns[1:]].mean()[1:].values
31
+ )
32
+
33
+ df_post_2025 = pd.DataFrame(
34
+ {
35
+ "Year": [2025, 2026, 2027, 2028, 2029],
36
+ "CPIH": [139.0, 142.2, 145.2, 148.2, 151.3],
37
+ "Pre-inflation avg bills (nominal)": avg_bills_2025_onwards,
38
+ }
39
+ )
40
+
41
+ # Add CPIH to each year's change
42
+
43
+ df_post_2025["Avg bills (nominal)"] = df_post_2025[
44
+ "Pre-inflation avg bills (nominal)"
45
+ ].values
46
+ df_post_2025["CPIH change"] = df_post_2025["CPIH"].pct_change() * 100
47
+
48
+ for year in range(2026, 2030):
49
+ row = df_post_2025[df_post_2025["Year"] == year].iloc[0]
50
+ cpi_change = (
51
+ row["CPIH"]
52
+ / df_post_2025[df_post_2025["Year"] == year - 1]["CPIH"].values[0]
53
+ - 1
54
+ ) * 100
55
+ # Increase the nominal bills by the CPIH change
56
+ addition = df_post_2025.loc[
57
+ df_post_2025["Year"] == year - 1, "Avg bills (nominal)"
58
+ ].values[0] * (cpi_change / 100)
59
+ # Add addition to this and future years
60
+ df_post_2025.loc[
61
+ df_post_2025["Year"] >= year, "Avg bills (nominal)"
62
+ ] += addition
63
+
64
+ df_post_2025["Relative change"] = (
65
+ df_post_2025["Avg bills (nominal)"].pct_change() * 100
66
+ ).round(1)
67
+
68
+ df_post_2025
69
+
70
+ combined_water_forecast = pd.DataFrame(
71
+ {
72
+ "Year": list(range(2022, 2030)),
73
+ "Average nominal bills YoY change": df_pre_2025[
74
+ "Nominal YoY change"
75
+ ].tolist()[1:]
76
+ + df_post_2025["Relative change"].tolist()[1:],
77
+ }
78
+ )
79
+
80
+ print(combined_water_forecast.to_markdown(index=False))
@@ -7,3 +7,4 @@ class water_and_sewerage_charges(Variable):
7
7
  label = "water and sewerage charges"
8
8
  documentation = "Total amount spent on water and sewerage charges"
9
9
  definition_period = YEAR
10
+ uprating = "gov.economic_assumptions.indices.ofwat.water_bills"
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.37.0] - 2025-07-14 10:36:08
9
+
10
+ ### Added
11
+
12
+ - Water bills projections.
13
+
8
14
  ## [2.36.1] - 2025-07-13 19:47:46
9
15
 
10
16
  ### Fixed
@@ -1918,6 +1924,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1918
1924
 
1919
1925
 
1920
1926
 
1927
+ [2.37.0]: https://github.com/PolicyEngine/openfisca-uk/compare/2.36.1...2.37.0
1921
1928
  [2.36.1]: https://github.com/PolicyEngine/openfisca-uk/compare/2.36.0...2.36.1
1922
1929
  [2.36.0]: https://github.com/PolicyEngine/openfisca-uk/compare/2.35.1...2.36.0
1923
1930
  [2.35.1]: https://github.com/PolicyEngine/openfisca-uk/compare/2.35.0...2.35.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: policyengine-uk
3
- Version: 2.36.1
3
+ Version: 2.37.0
4
4
  Summary: PolicyEngine tax and benefit system for the UK
5
5
  Project-URL: Homepage, https://github.com/PolicyEngine/policyengine-uk
6
6
  Project-URL: Repository, https://github.com/PolicyEngine/policyengine-uk
@@ -5,7 +5,7 @@ policyengine_uk/modelled_policies.yaml,sha256=TLhvmkuI9ip-Fjq63n66RzDErCkN8K4BzY
5
5
  policyengine_uk/repo.py,sha256=-dqpIMUD7UUj94ql9XwaMrFJUYKvNhFQ_9uj83Z8uh0,55
6
6
  policyengine_uk/system.py,sha256=A17rqR23iIMdvskuucahMvGZnMxwzuTYqGiFGKRu9kE,8613
7
7
  policyengine_uk/data/__init__.py,sha256=9o7hH2qcHChfwDYq8Oqf2jE3b5WDS3TXJm3bf9VC4Ks,58
8
- policyengine_uk/data/dataset_schema.py,sha256=Ad7dt1zBQbL7nvZN2RoaucD5wj_zHkkFvTCpZXU8aN0,3694
8
+ policyengine_uk/data/dataset_schema.py,sha256=kZuDKeBFBmK2B8MKWSAmDhHsTkzOY_WM5FnKcT8G4rA,3942
9
9
  policyengine_uk/data/economic_assumptions.py,sha256=heEro-NYCszFzW-TJ3Vt3DUUrpDkysOpyvZVymJN3-8,5722
10
10
  policyengine_uk/data/uprating_growth_factors.csv,sha256=6H5dq02mRsSgBJ9cYe4lut3fsvVzJXL20FvwT7SnlVc,10378
11
11
  policyengine_uk/parameters/gov/README.md,sha256=bHUep1_2pLHD3Or8SwjStOWXDIbW9OuYxOd4ml8IXcM,13
@@ -311,7 +311,7 @@ policyengine_uk/parameters/gov/dwp/winter_fuel_payment/eligibility/state_pension
311
311
  policyengine_uk/parameters/gov/dwp/winter_fuel_payment/eligibility/taxable_income_test/maximum_taxable_income.yaml,sha256=gLj2M2zoCMPuZ-0UgNSf-FTA5I4CCXhxBsd3qVro7Ck,260
312
312
  policyengine_uk/parameters/gov/dwp/winter_fuel_payment/eligibility/taxable_income_test/use_maximum_taxable_income.yaml,sha256=pHldHvNHeGhG0mcn7LvjYA3b-q_AxrAxm5bu-mkTn1A,261
313
313
  policyengine_uk/parameters/gov/economic_assumptions/create_economic_assumption_indices.py,sha256=Z4dYghSit5gXo4V3wBpnLIc9zgTX4cfEyb_TUlJkTGY,1937
314
- policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml,sha256=LyvtJYhIekZQkEtpy-CkqGOyhnukAqpwEQdbfJLxBZU,6959
314
+ policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml,sha256=D4EiVeOtPiFdNAeLos8nxMLwPk0avInFtr2g5XtSl4s,7428
315
315
  policyengine_uk/parameters/gov/hmrc/README.md,sha256=nkHVZl6lsjI93sR8uC7wAbul3_61wJrsP08iaW8f5lk,7
316
316
  policyengine_uk/parameters/gov/hmrc/minimum_wage.yaml,sha256=1oMbevU0ESHR51mcAG39POd1DA1FgPUep4hL6ojj-P4,2049
317
317
  policyengine_uk/parameters/gov/hmrc/business_rates/README.md,sha256=9ud50i_gMjGj6VymF-nzFDTzkFRMMJx6ybpLwbWzvpI,17
@@ -686,6 +686,8 @@ policyengine_uk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
686
686
  policyengine_uk/utils/create_triple_lock.py,sha256=E8qR51cq5jPL6EOXFoPi1qJhrcUBXg3dfWTvdqWN2Bo,948
687
687
  policyengine_uk/utils/parameters.py,sha256=OQTzTkHMdwbphCo0mV7_n_FJT0rdwIKNFTsk_lsdETE,1301
688
688
  policyengine_uk/utils/solve_private_school_attendance_factor.py,sha256=LUZCgHKAQTY5qHlGJutn7pOFUWT0AP16YcJy-YUjQ3Q,1609
689
+ policyengine_uk/utils/water/README.md,sha256=sdBI-JZ-jcRoSUfwNx5wjv5Ig_nM8OPvvjSsSMs_Wh8,443
690
+ policyengine_uk/utils/water/forecast_water_bills.py,sha256=0wiX-1f5EI2iAEwqMg3J7oByFObsqQmylMgQvmONSmo,2555
689
691
  policyengine_uk/variables/contrib/cec/non_primary_residence_wealth_tax.py,sha256=Hx5HCHc9ioK6InqTgTt6fX9JwI0sroTLgPB5N5YCJz0,668
690
692
  policyengine_uk/variables/contrib/labour/attends_private_school.py,sha256=OfTnVcRhuBNI6bIPdlbLdVvhCYWYu0eHTXNbLeGl3Bs,2422
691
693
  policyengine_uk/variables/contrib/labour/private_school_vat.py,sha256=IF1XfNNYFuYPiZd4HiGF4aAiPcY1_vGA_nAgTW7M2wg,851
@@ -1358,16 +1360,16 @@ policyengine_uk/variables/input/consumption/property/mortgage_interest_repayment
1358
1360
  policyengine_uk/variables/input/consumption/property/non_residential_rent.py,sha256=ksf_xqI_iezcZzRG4TNHDJGcPji8ar1diRmw84RKpR0,316
1359
1361
  policyengine_uk/variables/input/consumption/property/personal_pension_contributions.py,sha256=dZToRCzd-0QhCE2hDnpzqIfjx_uPv2keNK4VblzbpdU,293
1360
1362
  policyengine_uk/variables/input/consumption/property/property_purchased.py,sha256=an296H9Lqw2fFcQLqQeUFv5e0Y7RW0MPjU90CF4o7D0,292
1361
- policyengine_uk/variables/input/consumption/property/water_and_sewerage_charges.py,sha256=MQK3USx_JNPvIuKL_-kcn3AI64rqAjHvBv7tcYD6Y6I,273
1363
+ policyengine_uk/variables/input/consumption/property/water_and_sewerage_charges.py,sha256=nuv-35GU4hiRYfqjjS58YE4UZ2i3Z-TgSKlFSWKrW3M,341
1362
1364
  policyengine_uk/variables/misc/in_original_frs.py,sha256=sqqMJDPkhqaWBjCXU6W06JZLge0qxVD-B-iumHs0DI0,303
1363
1365
  policyengine_uk/variables/misc/spi_imputed.py,sha256=iPVlBF_TisM0rtKvO-3-PQ2UYCe6CVOm5sDPv97XFnU,298
1364
1366
  policyengine_uk/variables/misc/uc_migrated.py,sha256=zFNcUJaO8gwmbL1iY9GKgUt3G6J9yrCraqBV_5dCvlM,306
1365
1367
  policyengine_uk/variables/misc/categories/lower_middle_or_higher.py,sha256=C54tHYz2DmOyvQYCC1bF8RJwRZinhAq_e3aYC-9F5fM,157
1366
1368
  policyengine_uk/variables/misc/categories/lower_or_higher.py,sha256=81NIbLLabRr9NwjpUZDuV8IV8_mqmp5NM-CZvt55TwE,129
1367
- policyengine_uk-2.36.1.data/data/share/openfisca/openfisca-country-template/CHANGELOG.md,sha256=m-ZT7wfCBbHi9WgVmDIhNNhPBA5zjAOUSdn3FzLBvgg,55384
1368
- policyengine_uk-2.36.1.data/data/share/openfisca/openfisca-country-template/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
1369
- policyengine_uk-2.36.1.data/data/share/openfisca/openfisca-country-template/README.md,sha256=PCy7LRLdUDQS8U4PaeHeBVnyBZAqHv1dAVDDvEcom20,1976
1370
- policyengine_uk-2.36.1.dist-info/METADATA,sha256=ODug4dKAhvlw8nUOuFoCngAgorw6BulDbr93nKFMsio,3453
1371
- policyengine_uk-2.36.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1372
- policyengine_uk-2.36.1.dist-info/licenses/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
1373
- policyengine_uk-2.36.1.dist-info/RECORD,,
1369
+ policyengine_uk-2.37.0.data/data/share/openfisca/openfisca-country-template/CHANGELOG.md,sha256=VOafV5TKivt1vJtRfwzFfcUyOXUEg-dp1EvX18Ginzo,55537
1370
+ policyengine_uk-2.37.0.data/data/share/openfisca/openfisca-country-template/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
1371
+ policyengine_uk-2.37.0.data/data/share/openfisca/openfisca-country-template/README.md,sha256=PCy7LRLdUDQS8U4PaeHeBVnyBZAqHv1dAVDDvEcom20,1976
1372
+ policyengine_uk-2.37.0.dist-info/METADATA,sha256=GxvMvy3vZ-l2lIE_NfS7pUI_Uh6qplY3rEeT33veAIk,3453
1373
+ policyengine_uk-2.37.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1374
+ policyengine_uk-2.37.0.dist-info/licenses/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
1375
+ policyengine_uk-2.37.0.dist-info/RECORD,,