Files
TJWaterServer/epanet/apply_valve_renames.py
2025-12-31 16:11:28 +08:00

86 lines
2.7 KiB
Python

#!/usr/bin/env python3
from pathlib import Path
import re
inp = Path(r"d:\TJWaterServer\epanet\szhskeleton-patternfixed-ascii.inp")
out = Path(r"d:\TJWaterServer\epanet\szhskeleton-patternfixed-ascii-fixed2.inp")
mapout = Path(r"d:\TJWaterServer\epanet\szhskeleton-patternfixed-ascii-fixed2.mapping.txt")
text = inp.read_text(encoding='utf-8')
lines = text.splitlines()
# find [VALVES] start and end
start = None
for i,l in enumerate(lines):
if l.strip().upper() == '[VALVES]':
start = i
break
if start is None:
print('No [VALVES] section found')
raise SystemExit(1)
end = len(lines)
for j in range(start+1, len(lines)):
if re.match(r"^\s*\[.+\]", lines[j]):
end = j
break
# collect valve lines with their absolute numbers
valve_entries = [] # (absolute_line_index, token, line)
for idx in range(start+1, end):
l = lines[idx]
if not l.strip() or l.strip().startswith(';'):
continue
tok = l.split()[0]
valve_entries.append((idx, tok, l))
from collections import defaultdict
positions = defaultdict(list)
for ln, tok, l in valve_entries:
positions[tok].append(ln)
# find duplicates
dups = {tok:lns for tok,lns in positions.items() if len(lns)>1}
print('Found', sum(1 for _ in valve_entries), 'valve entries; duplicates:', len(dups))
replacements = [] # (line_index, old, new)
counter = 1
for tok, lns in dups.items():
# skip first occurrence, rename others
for occ_index, ln in enumerate(lns):
if occ_index == 0:
continue
# produce new name: prefix V if starts with digit
if re.fullmatch(r"\d+", tok) or re.match(r"^\d", tok):
base = 'V' + tok
else:
base = tok
new = f'{base}_{occ_index}'
# ensure uniqueness globally
while any(rn == new for _,_,rn in replacements) or any(new == t for t in positions.keys()):
counter += 1
new = f'{base}_{occ_index}_{counter}'
replacements.append((ln, tok, new))
# Apply replacements on the given absolute lines
for ln, old, new in replacements:
line = lines[ln]
# replace only first token occurrence
parts = line.split()
if parts:
# find start of token in line (preserve spacing)
m = re.search(re.escape(parts[0]), line)
if m:
startpos = m.start()
endpos = m.end()
newline = line[:startpos] + new + line[endpos:]
lines[ln] = newline
# write new file
out.write_text('\n'.join(lines) + '\n', encoding='utf-8')
# write mapping
with mapout.open('w', encoding='utf-8') as f:
for ln, old, new in replacements:
f.write(f'line {ln+1}: {old} -> {new}\n')
print('Wrote', out, 'with', len(replacements), 'replacements; mapping at', mapout)