fix bug and refine ,end of 2025
This commit is contained in:
85
epanet/apply_valve_renames.py
Normal file
85
epanet/apply_valve_renames.py
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/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)
|
||||
Reference in New Issue
Block a user