-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpscr_parser.py
More file actions
56 lines (43 loc) · 1.75 KB
/
Copy pathpscr_parser.py
File metadata and controls
56 lines (43 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from __future__ import annotations
from decimal import Decimal
import io
import re
from pypdf import PdfReader
_RATE_ROW_RE = re.compile(
r"^\s*(?P<code>[A-Z]\d+(?:\.\d+)?)\s+.+?\s+(?P<pscr>-?\d+\.\d+)\s+\d+\.\d+",
re.IGNORECASE,
)
def parse_pscr_rates_from_pdf(pdf_bytes: bytes) -> dict[str, Decimal]:
"""Extract current PSCR values by tariff code from the MPSC DTE electric rate book."""
reader = PdfReader(io.BytesIO(pdf_bytes))
text = "\n".join(page.extract_text() or "" for page in reader.pages)
lines = [re.sub(r"\s+", " ", line).strip() for line in text.splitlines()]
rates: dict[str, Decimal] = {}
for section in _power_supply_surcharge_sections(lines):
for line in section:
match = _RATE_ROW_RE.match(line)
if match:
rates[match.group("code").upper()] = Decimal(match.group("pscr"))
if rates:
break
if not rates:
raise ValueError("MPSC DTE rate book does not contain PSCR tariff rows")
return rates
def _power_supply_surcharge_sections(lines: list[str]) -> list[list[str]]:
sections: list[list[str]] = []
for idx, line in enumerate(lines):
lower = line.lower()
if "c8.5 surcharges and credits applicable to power supply service" in lower:
end = _next_delivery_surcharge_index(lines, idx + 1)
sections.append(lines[idx:end])
if not sections:
sections.append(lines)
return sections
def _next_delivery_surcharge_index(lines: list[str], start: int) -> int:
end = len(lines)
for idx in range(start, len(lines)):
lower = lines[idx].lower()
if "c9 surcharges and credits applicable to delivery service" in lower:
end = idx
break
return end