Skip to content

Commit ded4c95

Browse files
committed
change over to dataframes, clean up types and pyproject
1 parent 3fe557a commit ded4c95

File tree

4 files changed

+81
-43
lines changed

4 files changed

+81
-43
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ line-length = 120
7070
fix = true
7171

7272
[tool.ruff.lint]
73-
exclude = ["**/*.py", "**/*.pyi"] # TEMPORARY!!!!
73+
exclude = ["**/capex_project.py", "**/model.py", "**/npa_project.py", "**/params.py", "**/utils.py", "**/web_params.py", "skeleton.pyi"] # TEMPORARY!!!!
7474
select = [
7575
# flake8-2020
7676
"YTT",

src/npa_howtopay/capex_project.py

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,52 @@
1-
class CapexProject:
2-
project_year: int
3-
original_cost: float
4-
depreciation_lifetime: int
5-
# depreciation_schedule: str # "straight line" or "accelerated"
1+
from attrs import define
2+
from params import InputParams
63

7-
@property
8-
def get_depreciation(self, year: int) -> float:
9-
if self.project_year < year <= self.project_year + self.depreciation_lifetime:
10-
return self.original_cost / self.depreciation_lifetime
11-
else:
12-
return 0
4+
import polars as pl
135

6+
## All dataframes used by functions in this class will have the following columns:
7+
# project_year: int
8+
# original_cost: float
9+
# depreciation_lifetime: int
10+
## (someday)depreciation_schedule: str # "straight line" or "accelerated"
1411

15-
def non_lpp_gas_capex_projects(year: int, input_params: InputParams) -> list[CapexProject]:
12+
13+
# functions for generating dataframe rows for capex projects
14+
def get_synthetic_initial_capex_projects(
15+
start_year: int, initial_ratebase: float, depreciation_lifetime: int
16+
) -> pl.DataFrame:
17+
total_weight = (depreciation_lifetime * (depreciation_lifetime + 1) / 2) / depreciation_lifetime
18+
est_original_cost_per_year = initial_ratebase / total_weight
19+
return pl.DataFrame({
20+
"project_year": range(start_year, start_year + depreciation_lifetime),
21+
"original_cost": est_original_cost_per_year,
22+
"depreciation_lifetime": depreciation_lifetime,
23+
})
24+
25+
26+
def get_non_lpp_gas_capex_projects(year: int, input_params: InputParams) -> pl.DataFrame:
27+
pass
28+
29+
30+
def get_lpp_gas_capex_projects(year: int, input_params: InputParams, npas_this_year: NpaProject) -> pl.DataFrame:
31+
pass
32+
33+
34+
def get_non_npa_electric_capex_projects(year: int, input_params: InputParams) -> pl.DataFrame:
35+
pass
36+
37+
38+
def get_grid_upgrade_capex_projects(year: int, input_params: InputParams, npas_projects: pl.DataFrame) -> pl.DataFrame:
1639
pass
1740

1841

19-
def lpp_gas_capex_projects(year: int, input_params: InputParams, npas_this_year: NpaProject) -> list[CapexProject]:
42+
def get_npa_capex_projects(year: int, input_params: InputParams, npas_projects: pl.DataFrame) -> pl.DataFrame:
2043
pass
2144

2245

23-
def non_npa_electric_capex_projects(year: int, input_params: InputParams) -> list[CapexProject]:
46+
# functions for computing things given a dataframe of capex projects
47+
def compute_ratebase_from_capex_projects(df: pl.DataFrame, year: int) -> float:
2448
pass
2549

2650

27-
def grid_upgrade_capex_projects(year: int, input_params: InputParams, npas_this_year: NpaProject) -> list[CapexProject]:
51+
def compute_depreciation_expense_from_capex_projects(df: pl.DataFrame, year: int) -> float:
2852
pass

src/npa_howtopay/model.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,48 +16,46 @@ def compute_blue_columns(year: int, gas_params: GasParams, shared_params: Shared
1616

1717

1818
def run_model(scenario_params: ScenarioParams, input_params: InputParams, npa_projects: pl.DataFrame) -> pl.DataFrame:
19-
# initialize all the state
20-
gas_ratebase = 0
21-
electric_ratebase = 0
22-
num_gas_users = input_params.num_users
23-
num_electric_users = input_params.num_users
24-
25-
gas_capex_projects = []
26-
electric_capex_projects = []
19+
gas_capex_projects = pl.DataFrame()
20+
electric_capex_projects = pl.DataFrame()
2721

2822
output_df = pl.DataFrame()
2923

24+
live_params = input_params
25+
3026
for year in range(scenario_params.start_year, scenario_params.end_year):
3127
# INFLATION - probably looks like evolving input_params to current_params
32-
do_cost_inflation(year, input_params)
28+
live_params = do_cost_inflation(year, live_params)
3329

3430
# get the npas for this year
35-
npas_this_year = get_info_about_projects(npa_projects, year) # polars groupby year, weighted_sum
31+
npas_this_year = npa_projects.filter(pl.col("year") == year)
3632

3733
####### ticket
3834
# gas capex
39-
gas_capex_projects.append(
35+
gas_capex_projects = gas_capex_projects.vstack(
4036
non_lpp_gas_capex_projects(year, input_params)
4137
) # maybe has different depreciation schedule
42-
gas_capex_projects.append(lpp_gas_capex_projects(year, input_params, npas_this_year))
38+
gas_capex_projects = gas_capex_projects.vstack(lpp_gas_capex_projects(year, input_params, npas_this_year))
4339

4440
####### ticket
4541
# electric capex
46-
electric_capex_projects.append(non_npa_electric_capex_projects(year, input_params))
47-
electric_capex_projects.append(grid_upgrade_capex_projects(year, input_params, npa_projects))
42+
electric_capex_projects = electric_capex_projects.vstack(non_npa_electric_capex_projects(year, input_params))
43+
electric_capex_projects = electric_capex_projects.vstack(
44+
grid_upgrade_capex_projects(year, input_params, npa_projects)
45+
)
4846

4947
# npa capex
5048
if scenario_params.capex_opex == "capex":
51-
npa_capex = get_npa_capex_project(npas_this_year)
49+
npa_capex = get_npa_capex_projects(npas_this_year, year, input_params)
5250
if scenario_params.gas_electric == "gas":
53-
gas_capex_projects.append(npa_capex)
51+
gas_capex_projects = gas_capex_projects.vstack(npa_capex)
5452
elif scenario_params.gas_electric == "electric":
55-
electric_capex_projects.append(npa_capex)
53+
electric_capex_projects = electric_capex_projects.vstack(npa_capex)
5654

57-
gas_ratebase = update_ratebase(year, gas_ratebase, gas_capex_projects)
58-
electric_ratebase = update_ratebase(year, electric_ratebase, electric_capex_projects)
55+
gas_ratebase = get_ratebase_from_capex_projects(year, gas_capex_projects)
56+
electric_ratebase = get_ratebase_from_capex_projects(year, electric_capex_projects)
5957

60-
num_gas_users -= npas_this_year.num_converts
58+
## TODO: opex stuff?
6159

6260
####### ticket
6361
intermediate_columns = compute_blue_columns() # returns pl.Series

src/npa_howtopay/npa_project.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
from attrs import define
22

3+
import polars as pl
34

4-
@define
5-
class NpaProject:
6-
year: int
7-
num_converts: int
8-
pipe_value_per_user: float
9-
pipe_decomm_cost_per_user: float
10-
# npa_install_costs: float # maybe? is this in 2025 dollars?
5+
6+
## All dataframes used by functions in this class will have the following columns:
7+
# year: int
8+
# num_converts: int
9+
# pipe_value_per_user: float
10+
# pipe_decomm_cost_per_user: float
11+
12+
# note: could represent scattershot electrification as a row with pipe_value_per_user and pipe_decomm_cost_per_user set to 0
13+
14+
15+
def compute_num_converts_from_df(df: pl.DataFrame, year: int) -> int:
16+
return df.filter(pl.col("year") <= year).sum("num_converts")
17+
18+
19+
def compute_avoided_pipe_costs_from_df(df: pl.DataFrame, year: int) -> float:
20+
# wrong, needs to multiply by num_converts
21+
# return df.filter(pl.col("year") == year).sum("pipe_value_per_user")
22+
pass
23+
24+
25+
def compute_pipe_decomm_cost_from_df(df: pl.DataFrame) -> pl.DataFrame:
26+
pass

0 commit comments

Comments
 (0)