Skip to content

Commit

Permalink
Update data, pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jiuguangw committed Oct 27, 2023
1 parent aa3c3da commit 417f4a9
Show file tree
Hide file tree
Showing 9 changed files with 6,497 additions and 79 deletions.
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: check-yaml
Expand All @@ -21,7 +21,7 @@ repos:
- id: check-merge-conflict

- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.10.0
rev: v2.11.0
hooks:
- id: pretty-format-ini
args: [--autofix]
Expand All @@ -31,26 +31,26 @@ repos:
- toml-sort==0.23.1

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.0.282'
rev: 'v0.1.0'
hooks:
- id: ruff
args: ['--fix', '--config', 'pyproject.toml']

- repo: https://github.com/psf/black
rev: 23.7.0
rev: 23.10.0
hooks:
- id: black
language_version: python3.10
args: ['--config', 'pyproject.toml']
verbose: true

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.0
rev: v1.6.1
hooks:
- id: mypy
additional_dependencies: [types-python-dateutil]

- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.9.0.5
rev: v0.9.0.6
hooks:
- id: shellcheck
6,432 changes: 6,432 additions & 0 deletions data/dte.csv

Large diffs are not rendered by default.

Binary file modified docs/doc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion dte/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# __init__.py
from .dte import dte_calculator # noqa
from .dte import dte_calculator
82 changes: 49 additions & 33 deletions dte/dte.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 by Jiuguang Wang (www.robo.guru)
# All rights reserved.
# This file is part of DTE Calculator and is released under the MIT License.
# Please see the LICENSE file that should have been included as part of
# this package.

from typing import Tuple

import matplotlib.pyplot as plt
import numpy as np
Expand Down Expand Up @@ -70,29 +67,34 @@ def compute_delivery_charges(kwh_monthly: Series) -> Series:
return total


def compute_ToD_rate(data_raw: DataFrame) -> Tuple[Series, Series, Series]:
def compute_tod_rate(data_raw: DataFrame) -> tuple[Series, Series, Series]:
# Init
data = data_raw

data["Cost_Cap"] = 0
data["Cost_NonCap"] = 0
data["Cost_Cap"] = 0.0
data["Cost_NonCap"] = 0.0

# Weekday filter
index_weekday = data.index.weekday < 5
index_weekend = data.index.weekday >= 5

# Season filter
index_summer = np.logical_and(
data.index.month >= 6, data.index.month <= 10
data.index.month >= 6,
data.index.month <= 10,
)
index_winter = np.logical_or(data.index.month >= 11, data.index.month <= 5)

# Hour filter
index_peak = np.logical_and(
data.index.hour >= 11, data.index.hour <= 18, index_weekday
data.index.hour >= 11,
data.index.hour <= 18,
index_weekday,
)
index_off_peak = np.logical_or(
data.index.hour < 11, data.index.hour > 18, index_weekend
data.index.hour < 11,
data.index.hour > 18,
index_weekend,
)

# Combine filters
Expand Down Expand Up @@ -154,17 +156,18 @@ def compute_ToD_rate(data_raw: DataFrame) -> Tuple[Series, Series, Series]:
return total, consumption_peak, consumption_offpeak


def compute_RES_rate(data_raw: DataFrame) -> Series:
def compute_res_rate(data_raw: DataFrame) -> Series:
# Compute daily total consumption
data = data_raw["Total"].resample("D").sum().to_frame()

data["Cost_CAP_17"] = RES_CUTOFF * RES_CAP_RATE_17KWH
data["Cost_NON_CAP_17"] = RES_CUTOFF * RES_NON_CAP_RATE_17KWH

data["Cost_CAP_ADD"] = 0
data["Cost_NON_CAP_ADD"] = 0
data["Cost_CAP_ADD"] = 0.0
data["Cost_NON_CAP_ADD"] = 0.0

# Filter
data["Total"] = data["Total"].astype(float)
index = data["Total"] > RES_CUTOFF
data.loc[index, "Cost_CAP_ADD"] = (
data["Total"] - RES_CUTOFF
Expand All @@ -186,9 +189,7 @@ def compute_RES_rate(data_raw: DataFrame) -> Series:
)
cost_monthly = data["Total Cost"].resample(SAMPLE_METHOD).sum()
sales_tax = cost_monthly * RATE_SALES_TAX
total = cost_monthly + delivery_charges_monthly + sales_tax

return total
return cost_monthly + delivery_charges_monthly + sales_tax


def format_plots(plot_object: Axes) -> None:
Expand All @@ -202,11 +203,9 @@ def format_plots(plot_object: Axes) -> None:
plot_object.tick_params(labelsize=AXIS_FONT_SIZE)

# Change tick spacing
plot_object.set_xticks(plot_object.get_xticks()[::1])
plot_object.xaxis.set_major_locator(
MonthLocator(range(1, 13), bymonthday=1, interval=2)
)
plot_object.xaxis.set_major_formatter(DateFormatter("%b"))
plot_object.xaxis.set_major_locator(MonthLocator(interval=6))
plot_object.xaxis.set_major_formatter(DateFormatter("%b %Y"))
plot_object.tick_params(axis="x", rotation=90)


def dte_calculator(filename: str) -> None:
Expand All @@ -217,26 +216,37 @@ def dte_calculator(filename: str) -> None:
f, axarr = plt.subplots(2, 2)

# Import data
data = pd.read_csv(filename, parse_dates=[["Day", "Hour of Day"]])
data = data.set_index(data["Day_Hour of Day"])
data.index.rename("Date", inplace=True)
data.rename(columns={"Hourly Total": "Total"}, inplace=True)
data = pd.read_csv(
filename,
parse_dates={"Datetime": ["Day", "Hour of Day"]},
)

# If you want to convert the "Datetime" column to datetime dtype explicitly
data["Datetime"] = pd.to_datetime(data["Datetime"])

data = data.set_index(data["Datetime"])
data = data.rename_axis("Date")
data = data.rename(columns={"Hourly Total": "Total"})
data["Total"] = data["Total"].replace(
"No Data",
0,
) # sometimes DTE has an invalid entry
data["Total"] = data["Total"].astype(float)
# Compute cost for the Residential Electric Service Rate
cost_monthly_res = compute_RES_rate(data)
cost_monthly_res = compute_res_rate(data)

# Compute cost for the Time of Day Service Rate
cost_monthly_ToD, consumption_peak, consumption_offpeak = compute_ToD_rate(
data
cost_monthly_tod, consumption_peak, consumption_offpeak = compute_tod_rate(
data,
)

# Compute consumption KWH by month
kwh_monthly = data["Total"].resample(SAMPLE_METHOD).sum()

# Compute savings
savings_monthly = cost_monthly_res - cost_monthly_ToD
savings_monthly = cost_monthly_res - cost_monthly_tod
res_total = round(cost_monthly_res.sum(), 2)
tod_total = round(cost_monthly_ToD.sum(), 2)
tod_total = round(cost_monthly_tod.sum(), 2)
savings_total = round(savings_monthly.sum(), 2)

# Plot 1 - Consumption
Expand All @@ -256,7 +266,9 @@ def dte_calculator(filename: str) -> None:
# Plot 2 - Peak vs Off Peak
axarr[0, 1].plot(consumption_peak.index, consumption_peak, label="Peak")
axarr[0, 1].plot(
consumption_offpeak.index, consumption_offpeak, label="Off Peak"
consumption_offpeak.index,
consumption_offpeak,
label="Off Peak",
)
axarr[0, 1].set_title("Consumption by Month, Peak vs Off Peak")
axarr[0, 1].set_ylabel("Consumption (kWh)")
Expand All @@ -265,18 +277,22 @@ def dte_calculator(filename: str) -> None:

# Plot 3 - Services
axarr[1, 0].plot(
cost_monthly_res.index, cost_monthly_res, label="Standard RES Service"
cost_monthly_res.index,
cost_monthly_res,
label="Standard RES Service",
)
axarr[1, 0].plot(
cost_monthly_ToD.index, cost_monthly_ToD, label="Time of Day Service"
cost_monthly_tod.index,
cost_monthly_tod,
label="Time of Day Service",
)
axarr[1, 0].set_title("Total Cost by Month")
axarr[1, 0].set_ylabel("Cost in US Dollars")
axarr[1, 0].legend()
format_plots(axarr[1, 0])

# Plot 4 - Savings
axarr[1, 1].plot(cost_monthly_ToD.index, savings_monthly)
axarr[1, 1].plot(cost_monthly_tod.index, savings_monthly)
axarr[1, 1].set_title("Total Savings by Month")
axarr[1, 1].set_ylabel("Cost in US Dollars")

Expand Down
2 changes: 0 additions & 2 deletions dte_calculator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 by Jiuguang Wang (www.robo.guru)
# All rights reserved.
# This file is part of DTE Calculator and is released under the MIT License.
Expand Down
39 changes: 6 additions & 33 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ classifiers = [
]
dependencies = [
"tomli>=2.0.1",
"matplotlib>=3.7",
"pandas>=2.0.3",
"matplotlib>=3.8",
"pandas>=2.1.0",
"seaborn>=0.12.2",
"numpy>=1.25.2",
"chart_studio>=1.1.0",
"toml>=0.10.2"
]
description = "Python based utility to compare electric service plans based on past consumption data."
Expand All @@ -35,7 +36,7 @@ version = "0.1.0"

[project.optional-dependencies]
dev = [
"pre-commit>=3.3.3",
"pre-commit>=3.5.0",
"pytest>=7.4.0",
"pytest-cov>=4.1.0",
"MonkeyType>=23.3.0"
Expand Down Expand Up @@ -70,34 +71,6 @@ strict_equality = true
warn_redundant_casts = true
warn_unreachable = true

[[tool.mypy.overrides]]
disallow_untyped_defs = true
module = "mypy-scripts.*"

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = "matplotlib.*"

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = "setuptools.*"

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = "scipy.*"

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = "pandas.*"

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = "seaborn.*"

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = "chart_studio.*"

[tool.ruff]
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
Expand Down Expand Up @@ -126,11 +99,11 @@ exclude = [
]
# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
ignore = []
ignore = ["D", "PLR2004", "T201", "S101"]
# Same as Black.
line-length = 79
# Enable pycodestyle (`E`), Pyflakes (`F`), and import sorting (`I`)
select = ["E", "F", "I"]
select = ["ALL"]
# Assume Python 3.10.
target-version = "py310"
unfixable = []
Expand Down
Empty file added test/__init__.py
Empty file.
7 changes: 3 additions & 4 deletions test/test_dte.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 by Jiuguang Wang (www.robo.guru)
# All rights reserved.
# This file is part of DTE Calculator and is released under the MIT License.
# Please see the LICENSE file that should have been included as part of
# this package.

import os
from pathlib import Path

import dte

Expand All @@ -16,7 +14,8 @@ def test_dte() -> None:
dte.dte_calculator("data/dte.csv")

# Get the file size of the output PDF
file_size = os.path.getsize("DTE.pdf")
file_path = Path("DTE.pdf")
file_size = file_path.stat().st_size

# Check the size is greater than 40 KB
assert file_size > 20 * 1024, "Test failed"

0 comments on commit 417f4a9

Please sign in to comment.