Skip to content

Commit

Permalink
Renamed rules-engine to python (codeforboston#263)
Browse files Browse the repository at this point in the history
* Rename directory

* Rename rules-engine to python
  • Loading branch information
ethanstrominger authored Oct 23, 2024
1 parent e0f8e32 commit 73bf486
Show file tree
Hide file tree
Showing 78 changed files with 188 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/heat-stack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
workflow_dispatch:

env:
rules-engine-working-directory: rules-engine
rules-engine-working-directory: python
heat-stack-working-directory: heat-stack

defaults:
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"python.testing.pytestArgs": [
"rules-engine"
"python"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ To install the front end, see this [README.md](https://github.com/codeforboston/

### Documentation
For the Heat Stack (Javascript) portion read: [README.md](https://github.com/codeforboston/home-energy-analysis-tool/blob/main/heat-stack/README.md)
For the Rules Engine (Python) portion read: [README.md](https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/README.md)
For the Rules Engine (Python) portion read: [README.md](https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/README.md)
2 changes: 1 addition & 1 deletion heat-stack/app/root_original.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
// import type { Weather } from './WeatherExample.d.ts'

// import * as pyodideModule from 'pyodide'
// import engine from '../../rules-engine/src/rules_engine/engine.py'
// import engine from '../../python/src/rules_engine/engine.py'

// const getPyodide = async () => {
// // public folder:
Expand Down
2 changes: 1 addition & 1 deletion heat-stack/app/routes/_heat+/single.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export async function action({ request, params }: ActionFunctionArgs) {
const pyodide: any = await getPyodide()
return pyodide
}
// consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/tests/test_rules_engine/test_engine.py
// consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/tests/test_rules_engine/test_engine.py
const pyodide: any = await runPythonScript()
//////////////////////

Expand Down
30 changes: 15 additions & 15 deletions heat-stack/app/utils/pyodide.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import WeatherUtil from "#app/utils/WeatherUtil";


/* For this to pass, you must run
`pushd ../rules-engine && python3 -m venv venv && source venv/bin/activate && pip install -q build && python3 -m build && popd` */
`pushd ../python && python3 -m venv venv && source venv/bin/activate && pip install -q build && python3 -m build && popd` */

/* Referenced https://github.com/epicweb-dev/full-stack-testing/blob/main/exercises/04.unit-test/02.solution.spies/app/utils/misc.error-message.test.ts of https://www.epicweb.dev/workshops/web-application-testing*/
// test('pyodide loads', async () => {
Expand Down Expand Up @@ -60,12 +60,12 @@ import WeatherUtil from "#app/utils/WeatherUtil";
// // await micropip.install(['annotated-types'])

// await pyodide.loadPackage(
// '../rules-engine/dist/rules_engine-0.0.1-py3-none-any.whl',
// '../python/dist/rules_engine-0.0.1-py3-none-any.whl',
// )

// return pyodide
// }
// // consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/tests/test_rules_engine/test_engine.py
// // consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/tests/test_rules_engine/test_engine.py
// const pyodide: any = await runPythonScript()
// const result = await pyodide.runPythonAsync(`
// from rules_engine import engine
Expand Down Expand Up @@ -127,32 +127,32 @@ test('pyodide solves climate change', async () => {
// await micropip.install(['annotated-types'])

await pyodide.loadPackage(
'../rules-engine/dist/rules_engine-0.0.1-py3-none-any.whl',
'../python/dist/rules_engine-0.0.1-py3-none-any.whl',
)

return pyodide
}
// consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/tests/test_rules_engine/test_engine.py
// consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/tests/test_rules_engine/test_engine.py
const pyodide: any = await runPythonScript()

const GU = new GeocodeUtil();
const WU = new WeatherUtil();

// 1) parser.parse_gas_bill(data: str, company: NaturalGasCompany)
// https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/src/rules_engine/parser.py#L60
// https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/src/rules_engine/parser.py#L60

/* 2) get_outputs_natural_gas(
summary_input: SummaryInput,
temperature_input: TemperatureInput,
natural_gas_billing_input: NaturalGasBillingInput,
) -> RulesEngineResult
https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/src/rules_engine/engine.py#L59
https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/src/rules_engine/engine.py#L59
*/

/**
* TODO:
* - Match up our types with rules engine types at https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/src/rules_engine/pydantic_models.py#L57
* - Match up our types with rules engine types at https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/src/rules_engine/pydantic_models.py#L57
* - Use those to create summary_input (in the same file)
* - Use those to create temperature_input (in the same file)
* - Use those to create natural_gas_billing_input (in the same file)
Expand All @@ -169,7 +169,7 @@ test('pyodide solves climate change', async () => {
console.log("weather data",TIWD);


// https://github.com/codeforboston/home-energy-analysis-tool/tree/main/rules-engine/tests/test_rules_engine/cases/examples/quateman
// https://github.com/codeforboston/home-energy-analysis-tool/tree/main/python/tests/test_rules_engine/cases/examples/quateman
const exampleNationalGridCSV = `Name,FIRST LAST,,,,,
Address,"100 STREET AVE, BOSTON MA 02130",,,,,
Account Number,1111111111,,,,,
Expand Down Expand Up @@ -337,32 +337,32 @@ test('pyodide solves climate change', async () => {
// // await micropip.install(['annotated-types'])

// await pyodide.loadPackage(
// '../rules-engine/dist/rules_engine-0.0.1-py3-none-any.whl',
// '../python/dist/rules_engine-0.0.1-py3-none-any.whl',
// )

// return pyodide
// }
// // consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/tests/test_rules_engine/test_engine.py
// // consider running https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/tests/test_rules_engine/test_engine.py
// const pyodide: any = await runPythonScript()

// const GU = new GeocodeUtil();
// const WU = new WeatherUtil();

// // 1) parser.parse_gas_bill(data: str, company: NaturalGasCompany)
// // https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/src/rules_engine/parser.py#L60
// // https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/src/rules_engine/parser.py#L60

// /* 2) get_outputs_natural_gas(
// summary_input: SummaryInput,
// temperature_input: TemperatureInput,
// natural_gas_billing_input: NaturalGasBillingInput,
// ) -> RulesEngineResult

// https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/src/rules_engine/engine.py#L59
// https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/src/rules_engine/engine.py#L59
// */

// /**
// * TODO:
// * - Match up our types with rules engine types at https://github.com/codeforboston/home-energy-analysis-tool/blob/main/rules-engine/src/rules_engine/pydantic_models.py#L57
// * - Match up our types with rules engine types at https://github.com/codeforboston/home-energy-analysis-tool/blob/main/python/src/rules_engine/pydantic_models.py#L57
// * - Use those to create summary_input (in the same file)
// * - Use those to create temperature_input (in the same file)
// * - Use those to create natural_gas_billing_input (in the same file)
Expand All @@ -377,7 +377,7 @@ test('pyodide solves climate change', async () => {
// const TIWD = await WU.getThatWeathaData(x, y, "2024-03-20", "2024-04-20");
// console.log("weather data",TIWD);

// // https://github.com/codeforboston/home-energy-analysis-tool/tree/main/rules-engine/tests/test_rules_engine/cases/examples/quateman
// // https://github.com/codeforboston/home-energy-analysis-tool/tree/main/python/tests/test_rules_engine/cases/examples/quateman
// const exampleNationalGridCSV = `Name,FIRST LAST,,,,,
// Address,"100 STREET AVE, BOSTON MA 02130",,,,,
// Account Number,1111111111,,,,,
Expand Down
4 changes: 2 additions & 2 deletions heat-stack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"setup": "npm run build && prisma generate && prisma migrate deploy && prisma db seed && playwright install",
"start": "cross-env NODE_ENV=production node .",
"start:mocks": "cross-env NODE_ENV=production MOCKS=true tsx .",
"test": "cd ../rules-engine && python3 -m venv venv && . venv/bin/activate && pip install -q build && python3 -m build && cd ../heat-stack && vitest && rm -rf ../rules-engine/dist ",
"buildpy": "cd ../rules-engine && python3 -m venv venv && . venv/bin/activate && pip install -q build && python3 -m build && cp dist/rules_engine-0.0.1-py3-none-any.whl ../heat-stack/public/pyodide-env",
"test": "cd ../python && python3 -m venv venv && . venv/bin/activate && pip install -q build && python3 -m build && cd ../heat-stack && vitest && rm -rf ../python/dist ",
"buildpy": "cd ../python && python3 -m venv venv && . venv/bin/activate && pip install -q build && python3 -m build && cp dist/rules_engine-0.0.1-py3-none-any.whl ../heat-stack/public/pyodide-env",
"coverage": "vitest run --coverage",
"test:e2e": "npm run test:e2e:dev --silent",
"test:e2e:dev": "playwright test --ui",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
166 changes: 166 additions & 0 deletions python/src/rules_engine/refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
Qs:
- stand_by_losses

home variables used
```
avg_ua
balance_point
non_heating_usage
stdev_pct
balance_point_graph
```

1. Remove temporary_rules_engine.py
2. Rename rules-engine to "python"
3. Rename NormalizedBillingRecordBase class to BillingInput
4. Rename BillingPeriod to ProcessedBill and billing_period to processed_bill
5. Combine get_outputs_normalized and convert_to_intermediate_billing_record and get rid of NormalizedBillingRecord. There is only one place NormalizedBillingRecord is used and combining code
gets rid of the need for the class.
- Change
```
billing_periods: list[NormalizedBillingPeriodRecordBase] = []
for input_val in natural_gas_billing_input.records:
billing_periods.append(
NormalizedBillingPeriodRecordBase(
period_start_date=input_val.period_start_date,
period_end_date=input_val.period_end_date,
usage=input_val.usage_therms,
inclusion_override=bool(input_val.inclusion_override),
)
)
return get_outputs_normalized(
summary_input, None, temperature_input, billing_periods
)
def get_outputs_normalized
loops through billing_periods and does a bunch of stuff
```
to
```
inputBill =
NormalizedBillingPeriodRecordBase(
period_start_date=input_val.period_start_date,
period_end_date=input_val.period_end_date,
usage=input_val.usage_therms,
analysis_type_override=input_val.inclusion_override,
inclusion_override=True,
)
)
avg_temps = derive_avg_temps(temparature_input)
default_analysis_type = derive_default_analysis_type
( fuel_type,
inputBill.start_date,
inputBill.end_date
)
processedBill = ProcessedBill(
input = inputBill,
avg_temps = avg_temps,
default_analysis_type = default_analysis_type
// usage not needed, it is part of inputBill
)
```
6. Home - Call home.calculate from home.init or move the code from home.init into home.calculate. Otherwise, the fact that Home.init does calculations is hidden. Code looks like this:
```
home=Home(args) # does some calculations
home.calculate() # does some calculations
```
This would change to either
```
home=Home(args)
```
or
```
home=Home.calculate(args)
```
7. Home - change to functional programming paradigm where you provide inputs and outputs
- Change
`_calculate_avg_summer_usage()` => `avg_summer_usage = _get_avg_summer_usage(summer_bills)`
- Change
`_calculate_avg_non_heating_usage ()` =>
to
```
avg_non_heating_usage = _get_avg_non_heating_usage (
fuel_type,
avg_summer_usage,
dhw_input.estimated_water_heating_efficiency,
dhw_input.number_of_occupants,
stand_by_losses,
heating_system_efficiency
)
```
==================
- change
`for billing_period in billing_periods ...` =>
to
```
for billing_period in billing_periods
{ bills_summer, bills_winter, bills_shoulder }
=_categorize_bills_by_season (billing_periods)
```
==================
- Change
```
calculate_dhw_usage()
```
to
```
dhw_usage = _calculate_dhw_usage (
estimated_water_heating_efficiency,
dhw_input.number_of_occupants,
stand_by_losses,
heating_system_efficiency
)
```
==================
- Change
`self.initialize_ua(billing_period)` => `_set_ua(billing_period,avg_non_heating_usage)`

- Change?? Parameters are never set
```
def calculate(
self,
initial_balance_point_sensitivity: float = 0.5,
stdev_pct_max: float = 0.10,
max_stdev_pct_diff: float = 0.01,
next_balance_point_sensitivity: float = 0.5,
)
```
=>
```
def calculate (
initial_balance_point_sensitivity: float = 0.5,
stdev_pct_max: float = 0.10,
max_stdev_pct_diff: float = 0.01,
next_balance_point_sensitivity: float = 0.5,
```
==================
- calculate method
`self._calculate_avg_non_heating_usage` - duplicated. Remove one of the calls
==================

- Change
```
self._calculate_balance_point_and_ua(
initial_balance_point_sensitivity,
stdev_pct_max,
max_stdev_pct_diff,
next_balance_point_sensitivity,
)
``` =>
```
{ balance_point, stdev_pct
balance_point_graph } =
_get_graph (initial_balance_point_sensitivity,
stdev_pct_max,
max_stdev_pct_diff,
next_balance_point_sensitivity,
bills_winter)
```
==================
File renamed without changes.

0 comments on commit 73bf486

Please sign in to comment.