From 369e636e132a7582090d457793495b13e038d0f5 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Thu, 9 Mar 2023 13:38:35 +0800 Subject: [PATCH 01/39] Start new parser --- api/inp_in_new.py | 141 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 api/inp_in_new.py diff --git a/api/inp_in_new.py b/api/inp_in_new.py new file mode 100644 index 0000000..304d3ca --- /dev/null +++ b/api/inp_in_new.py @@ -0,0 +1,141 @@ +from .project import * +from .database import ChangeSet, get_current_operation, set_restore_operation +from .sections import section_name + + +def parse_inp(project: str, inp: str) -> None: + section = '' + + for line in open(inp): + line = line.strip() + + if line == '': + if section == 'CONTROLS' or section == 'RULES': + pass + else: + section = '' + continue + + if line.startswith('['): + is_section = False + for s in section_name: + if line.startswith(f'[{s}'): + section = s + is_section = True + break + if is_section: + continue + + if section == 'TITLE': + pass + + elif section == 'JUNCTIONS': # + coords + pass + + elif section == 'RESERVOIRS': # + coords + pass + + elif section == 'TANKS': # + coords + pass + + elif section == 'PIPES': + pass + + elif section == 'PUMPS': + pass + + elif section == 'VALVES': + pass + + elif section == 'TAGS': + pass + + elif section == 'DEMANDS': + pass + + elif section == 'STATUS': + pass + + elif section == 'PATTERNS': + pass + + elif section == 'CURVES': + pass + + elif section == 'CONTROLS': + pass + + elif section == 'RULES': + pass + + elif section == 'ENERGY': + pass + + elif section == 'EMITTERS': + pass + + elif section == 'QUALITY': + pass + + elif section == 'SOURCES': + pass + + elif section == 'REACTIONS': + pass + + elif section == 'MIXING': + pass + + elif section == 'TIMES': + pass + + elif section == 'REPORT': + pass + + elif section == 'OPTIONS': + pass + + elif section == 'COORDINATES': + pass + + elif section == 'VERTICES': + pass + + elif section == 'LABELS': + pass + + elif section == 'BACKDROP': + pass + + elif section == 'END': + pass # :) + + +def read_inp(project: str, inp: str) -> bool: + if is_project_open(project): + close_project(project) + + if have_project(project): + delete_project(project) + + create_project(project) + open_project(project) + + close_project(project) + + return True + + +def import_inp(project: str, cs: ChangeSet) -> bool: + if is_project_open(project): + close_project(project) + + if have_project(project): + delete_project(project) + + create_project(project) + open_project(project) + + close_project(project) + + return True From 96cb99b87a0f4768e7643bd3178127861292765e Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 9 Mar 2023 22:44:13 +0800 Subject: [PATCH 02/39] First pass scan --- api/s11_patterns.py | 22 ++++++++++++++++++++++ api/s12_curves.py | 26 ++++++++++++++++++++++++++ api/s13_controls.py | 5 +++++ api/s14_rules.py | 5 +++++ api/s1_title.py | 9 +++++++++ api/s21_times.py | 12 ++++++++++++ api/s22_report.py | 4 ++++ api/s23_options.py | 12 ++++++++++++ api/s23_options_v3.py | 18 +++++++++++++++++- api/s27_backdrop.py | 9 +++++++++ api/sections.py | 41 +++++++++++++++++++++++++++++++++++------ 11 files changed, 156 insertions(+), 7 deletions(-) diff --git a/api/s11_patterns.py b/api/s11_patterns.py index f354537..5393299 100644 --- a/api/s11_patterns.py +++ b/api/s11_patterns.py @@ -126,6 +126,28 @@ def inp_in_pattern(section: list[str]) -> ChangeSet: return cs +def inp_in_pattern_new(name: str, section: list[str]) -> None: + descs = {} + patterns: list[str] = [] + + count = len(section) + for i in range(0, count): + if section[i].startswith(';'): + # this is description + next = i + 1 + if next < count and section[next].startswith(';') == False: + next_tokens = section[next].split() + descs[next_tokens[0]] = section[i].removeprefix(';') + continue + + tokens = section[i].split() + if tokens[0] not in patterns: + patterns.append(tokens[0]) + write(name, f"insert into _pattern (id) values ('{tokens[0]}');") + for token in tokens[1:]: + write(name, f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});") + + def inp_out_pattern(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from patterns order by _order") diff --git a/api/s12_curves.py b/api/s12_curves.py index 89235cd..1b30709 100644 --- a/api/s12_curves.py +++ b/api/s12_curves.py @@ -159,6 +159,32 @@ def inp_in_curve(section: list[str]) -> ChangeSet: return cs +def inp_in_curve_new(name: str, section: list[str]) -> None: + types = {} + descs = {} + curves: list[str] = [] + + count = len(section) + for i in range(0, count): + if section[i].startswith(';'): + # ;type: desc + type_plus_desc = section[i].removeprefix(';') + type_plus_desc_tokens = type_plus_desc.split(':') + next = i + 1 + if next < count and section[next].startswith(';') == False: + next_tokens = section[next].split() + types[next_tokens[0]] = type_plus_desc_tokens[0].strip().upper() + if len(type_plus_desc_tokens) > 1: + descs[next_tokens[0]] = type_plus_desc_tokens[1].strip() + continue + + tokens = section[i].split() + if tokens[0] not in curves: + curves.append(tokens[0]) + write(name, f"insert into _curve (id, type) values ('{tokens[0]}', '{types[tokens[0]]}');") + write(name, f"insert into curves (id, x, y) values ('{tokens[0]}', {float(tokens[1])}, {float(tokens[2])});") + + def inp_out_curve(name: str) -> list[str]: lines = [] types = read_all(name, f"select * from _curve") diff --git a/api/s13_controls.py b/api/s13_controls.py index 95832a3..c51c8e4 100644 --- a/api/s13_controls.py +++ b/api/s13_controls.py @@ -48,5 +48,10 @@ def inp_in_control(section: list[str]) -> ChangeSet: return ChangeSet() +def inp_in_control_new(name: str, section: list[str]) -> None: + for line in section: + write(name, f"\ninsert into controls (line) values ('{line}');") + + def inp_out_control(name: str) -> list[str]: return get_control(name)['controls'] diff --git a/api/s14_rules.py b/api/s14_rules.py index 714c78c..039ea01 100644 --- a/api/s14_rules.py +++ b/api/s14_rules.py @@ -44,5 +44,10 @@ def inp_in_rule(section: list[str]) -> ChangeSet: return ChangeSet() +def inp_in_rule_new(name: str, section: list[str]) -> None: + for line in section: + write(name, f"\ninsert into rules (line) values ('{line}');") + + def inp_out_rule(name: str) -> list[str]: return get_rule(name)['rules'] \ No newline at end of file diff --git a/api/s1_title.py b/api/s1_title.py index c650cc9..7dde6c3 100644 --- a/api/s1_title.py +++ b/api/s1_title.py @@ -40,6 +40,15 @@ def inp_in_title(section: list[str]) -> ChangeSet: return ChangeSet(g_update_prefix | {'type': 'title', 'value' : obj.value}) +def inp_in_title_new(name: str, section: list[str]) -> None: + if section == []: + return + + title = '\n'.join(section) + sql = f"update title set value = '{title}';" + write(name, sql) + + def inp_out_title(name: str) -> list[str]: obj = str(get_title(name)['value']) return obj.split('\n') diff --git a/api/s21_times.py b/api/s21_times.py index 4e74263..34372ed 100644 --- a/api/s21_times.py +++ b/api/s21_times.py @@ -97,6 +97,18 @@ def inp_in_time(section: list[str]) -> ChangeSet: return ChangeSet() +def inp_in_time_new(name: str, section: list[str]) -> None: + for s in section: + if s.startswith(';'): + continue + + line = s.upper().strip() + for key in get_time_schema('').keys(): + if line.startswith(key): + value = line.removeprefix(key).strip() + write(name, f"update times set value = '{value}' where key = '{key}';") + + def inp_out_time(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from times") diff --git a/api/s22_report.py b/api/s22_report.py index f396142..73aa7e0 100644 --- a/api/s22_report.py +++ b/api/s22_report.py @@ -22,6 +22,10 @@ def inp_in_report(section: list[str]) -> ChangeSet: return ChangeSet() +def inp_in_report_new(name: str, section: list[str]) -> None: + return + + def inp_out_report(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from report") diff --git a/api/s23_options.py b/api/s23_options.py index 01ec503..cb1fc5a 100644 --- a/api/s23_options.py +++ b/api/s23_options.py @@ -40,6 +40,18 @@ def inp_in_option(section: list[str]) -> ChangeSet: return result +def inp_in_option_new(name: str, section: list[str]) -> None: + result = inp_in_option(section) + for op in result.operations: + for key in op.keys(): + if key == 'operation' or key == 'type': + continue + if op['type'] == 'option': + write(name, f"update options set value = '{op[key]}' where key = '{key}';") + else: + write(name, f"update options_v3 set value = '{op[key]}' where key = '{key}';") + + def inp_out_option(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from options") diff --git a/api/s23_options_v3.py b/api/s23_options_v3.py index 65e2691..b31ff4c 100644 --- a/api/s23_options_v3.py +++ b/api/s23_options_v3.py @@ -44,7 +44,11 @@ def inp_in_option_v3(section: list[str]) -> ChangeSet: tokens = s.strip().split() key = tokens[0] if key in get_option_v3_schema('').keys(): - value = tokens[1] if len(tokens) >= 2 else '' + value = '' + if len(tokens) == 2: + value = tokens[1] + elif len(tokens) > 2: + value = ' '.join(tokens[1:]) cs_v3 |= { key : value } else: v2_lines.append(s.strip()) @@ -58,6 +62,18 @@ def inp_in_option_v3(section: list[str]) -> ChangeSet: return result +def inp_in_option_v3_new(name: str, section: list[str]) -> None: + result = inp_in_option_v3(section) + for op in result.operations: + for key in op.keys(): + if key == 'operation' or key == 'type': + continue + if op['type'] == 'option_v3': + write(name, f"update options_v3 set value = '{op[key]}' where key = '{key}';") + else: + write(name, f"update options set value = '{op[key]}' where key = '{key}';") + + def inp_out_option_v3(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from options_v3") diff --git a/api/s27_backdrop.py b/api/s27_backdrop.py index 030eb81..964e2d5 100644 --- a/api/s27_backdrop.py +++ b/api/s27_backdrop.py @@ -38,6 +38,15 @@ def inp_in_backdrop(section: list[str]) -> ChangeSet: return ChangeSet() +def inp_in_backdrop_new(name: str, section: list[str]) -> None: + if section == []: + return + + content = '\n'.join(section) + sql = f"update backdrop set content = '{content}';" + write(name, sql) + + def inp_out_backdrop(name: str) -> list[str]: obj = str(get_backdrop(name)['content']) return obj.split('\n') \ No newline at end of file diff --git a/api/sections.py b/api/sections.py index bd0c097..0a9ee75 100644 --- a/api/sections.py +++ b/api/sections.py @@ -34,9 +34,38 @@ s29_scada_device = 'scada_device' s30_scada_device_data = 'scada_device_data' s31_scada_element = 'scada_element' -section_name = ['TITLE', 'JUNCTIONS', 'RESERVOIRS', 'TANKS', 'PIPES', - 'PUMPS', 'VALVES', 'TAGS', 'DEMANDS', 'STATUS', - 'PATTERNS', 'CURVES', 'CONTROLS', 'RULES', 'ENERGY', - 'EMITTERS', 'QUALITY', 'SOURCES', 'REACTIONS', 'MIXING', - 'TIMES', 'REPORT', 'OPTIONS', 'COORDINATES', 'VERTICES', - 'LABELS', 'BACKDROP', 'END'] +TITLE = 'TITLE' +JUNCTIONS = 'JUNCTIONS' +RESERVOIRS = 'RESERVOIRS' +TANKS = 'TANKS' +PIPES = 'PIPES' +PUMPS = 'PUMPS' +VALVES = 'VALVES' +TAGS = 'TAGS' +DEMANDS = 'DEMANDS' +STATUS = 'STATUS' +PATTERNS = 'PATTERNS' +CURVES = 'CURVES' +CONTROLS = 'CONTROLS' +RULES = 'RULES' +ENERGY = 'ENERGY' +EMITTERS = 'EMITTERS' +QUALITY = 'QUALITY' +SOURCES = 'SOURCES' +REACTIONS = 'REACTIONS' +MIXING = 'MIXING' +TIMES = 'TIMES' +REPORT = 'REPORT' +OPTIONS = 'OPTIONS' +COORDINATES = 'COORDINATES' +VERTICES = 'VERTICES' +LABELS = 'LABELS' +BACKDROP = 'BACKDROP' +END = 'END' + +section_name = [TITLE, JUNCTIONS, RESERVOIRS, TANKS, PIPES, + PUMPS, VALVES, TAGS, DEMANDS, STATUS, + PATTERNS, CURVES, CONTROLS, RULES, ENERGY, + EMITTERS, QUALITY, SOURCES, REACTIONS, MIXING, + TIMES, REPORT, OPTIONS, COORDINATES, VERTICES, + LABELS, BACKDROP, END] From 55febbe163f599aa18f05adaea958b808c138803 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 9 Mar 2023 22:56:43 +0800 Subject: [PATCH 03/39] Remove redundant char --- api/s13_controls.py | 2 +- api/s14_rules.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/s13_controls.py b/api/s13_controls.py index c51c8e4..42810b7 100644 --- a/api/s13_controls.py +++ b/api/s13_controls.py @@ -50,7 +50,7 @@ def inp_in_control(section: list[str]) -> ChangeSet: def inp_in_control_new(name: str, section: list[str]) -> None: for line in section: - write(name, f"\ninsert into controls (line) values ('{line}');") + write(name, f"insert into controls (line) values ('{line}');") def inp_out_control(name: str) -> list[str]: diff --git a/api/s14_rules.py b/api/s14_rules.py index 039ea01..69e2562 100644 --- a/api/s14_rules.py +++ b/api/s14_rules.py @@ -46,7 +46,7 @@ def inp_in_rule(section: list[str]) -> ChangeSet: def inp_in_rule_new(name: str, section: list[str]) -> None: for line in section: - write(name, f"\ninsert into rules (line) values ('{line}');") + write(name, f"insert into rules (line) values ('{line}');") def inp_out_rule(name: str) -> list[str]: From e41abe362f92889158bf00622fc8a9c919518526 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 9 Mar 2023 23:24:41 +0800 Subject: [PATCH 04/39] Second pass scan --- api/s2_junctions.py | 23 +++++++++++++++++++++++ api/s3_reservoirs.py | 21 +++++++++++++++++++++ api/s4_tanks.py | 27 +++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/api/s2_junctions.py b/api/s2_junctions.py index 860da1a..d7b8489 100644 --- a/api/s2_junctions.py +++ b/api/s2_junctions.py @@ -152,6 +152,29 @@ def inp_in_junction(section: list[str]) -> ChangeSet: return cs +def inp_in_junction_new(name: str, line: str) -> None: + # skip comment + if line.startswith(';'): + return + + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + id = str(tokens[0]) + elevation = float(tokens[1]) + demand = float(tokens[2]) if num_without_desc >= 3 else None + pattern = str(tokens[3]) if num_without_desc >= 4 else None + pattern = f"'{pattern}'" if pattern != None else 'null' + desc = str(tokens[-1]) if has_desc else None + + write(name, f"insert into _node (id, type) values ('{id}', 'junction');") + write(name, f"insert into junctions (id, elevation) values ('{id}', {elevation});") + write(name, f"insert into demands (junction, demand, pattern) values ('{id}', {demand}, {pattern});") + + def inp_out_junction(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from junctions') diff --git a/api/s3_reservoirs.py b/api/s3_reservoirs.py index 3a9760a..53e988d 100644 --- a/api/s3_reservoirs.py +++ b/api/s3_reservoirs.py @@ -145,6 +145,27 @@ def inp_in_reservoir(section: list[str]) -> ChangeSet: return cs +def inp_in_reservoir_new(name: str, line: str) -> None: + # skip comment + if line.startswith(';'): + return + + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + id = str(tokens[0]) + head = float(tokens[1]) + pattern = str(tokens[2]) if num_without_desc >= 3 else None + pattern = f"'{pattern}'" if pattern != None else 'null' + desc = str(tokens[-1]) if has_desc else None + + write(name, f"insert into _node (id, type) values ('{id}', 'reservoir');") + write(name, f"\ninsert into reservoirs (id, head, pattern) values ('{id}', {head}, {pattern});") + + def inp_out_reservoir(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from reservoirs') diff --git a/api/s4_tanks.py b/api/s4_tanks.py index ad92d8f..766c336 100644 --- a/api/s4_tanks.py +++ b/api/s4_tanks.py @@ -187,6 +187,33 @@ def inp_in_tank(section: list[str]) -> ChangeSet: return cs +def inp_in_tank_new(name: str, line: str) -> None: + # skip comment + if line.startswith(';'): + return + + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + id = str(tokens[0]) + elevation = float(tokens[1]) + init_level = float(tokens[2]) + min_level = float(tokens[3]) + max_level = float(tokens[4]) + diameter = float(tokens[5]) + min_vol = float(tokens[6]) if num_without_desc >= 7 else 0.0 + vol_curve = str(tokens[7]) if num_without_desc >= 8 and tokens[7] != '*' else None + vol_curve = f"'{vol_curve}'" if vol_curve != None else 'null' + overflow = str(tokens[8].upper()) if num_without_desc >= 9 else None + overflow = f"'{overflow}'" if overflow != None else 'null' + desc = str(tokens[-1]) if has_desc else None + + write(name, f"insert into _node (id, type) values ('{id}', 'tank');") + write(name, f"insert into tanks (id, elevation, init_level, min_level, max_level, diameter, min_vol, vol_curve, overflow) values ('{id}', {elevation}, {init_level}, {min_level}, {max_level}, {diameter}, {min_vol}, {vol_curve}, {overflow});") + def inp_out_tank(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from tanks') From 1fda14c3cf25ab74d25ef5358aec81094ddee0a9 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 10 Mar 2023 00:13:17 +0800 Subject: [PATCH 05/39] Optimize read performance --- api/__init__.py | 1 + api/inp_in_new.py | 318 ++++++++++++++++++++++++++++++---------------- build_db.py | 4 +- tjnetwork.py | 4 +- 4 files changed, 210 insertions(+), 117 deletions(-) diff --git a/api/__init__.py b/api/__init__.py index ad08e19..06230ad 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -3,6 +3,7 @@ from .project import is_project_open, get_project_open_count, open_project, clos from .project import copy_project from .inp_in import read_inp, import_inp +from .inp_in_new import read_inp_new from .inp_out import dump_inp, export_inp from .database import API_ADD, API_UPDATE, API_DELETE diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 304d3ca..fbcdf8c 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -1,132 +1,224 @@ from .project import * -from .database import ChangeSet, get_current_operation, set_restore_operation -from .sections import section_name +from .database import ChangeSet +from .sections import * +from .s1_title import inp_in_title_new +from .s2_junctions import inp_in_junction_new +from .s3_reservoirs import inp_in_reservoir_new +from .s4_tanks import inp_in_tank_new +from .s11_patterns import inp_in_pattern_new +from .s12_curves import inp_in_curve_new +from .s13_controls import inp_in_control_new +from .s14_rules import inp_in_rule_new +from .s21_times import inp_in_time_new +from .s22_report import inp_in_report_new +from .s23_options import inp_in_option_new +from .s27_backdrop import inp_in_backdrop_new -def parse_inp(project: str, inp: str) -> None: - section = '' +_UNKNOWN = 'UNKNOWN' + + +def scan1(project: str, inp: str) -> list[str]: + handlers = { + TITLE: inp_in_title_new, #1 + PATTERNS: inp_in_pattern_new, #11 + CURVES: inp_in_curve_new, #12 + CONTROLS: inp_in_control_new, #13 + RULES: inp_in_rule_new, #14 + TIMES: inp_in_time_new, #21 + REPORT: inp_in_report_new, #22 + OPTIONS: inp_in_option_new, #23 + BACKDROP: inp_in_backdrop_new,#27 + } + + curr_section = _UNKNOWN + prev_section = _UNKNOWN + + inp_sections: list[str] = [] + + sections : dict[str, list[str]]= {} + for c in handlers.keys(): + sections[c] = [] for line in open(inp): line = line.strip() - if line == '': - if section == 'CONTROLS' or section == 'RULES': - pass - else: - section = '' - continue - if line.startswith('['): - is_section = False + the_section = _UNKNOWN + for s in section_name: if line.startswith(f'[{s}'): - section = s - is_section = True + the_section = s + inp_sections.append(s) break - if is_section: + + prev_section = curr_section + if prev_section in handlers.keys(): + handlers[prev_section](project, sections[prev_section]) + sections[prev_section].clear() + + curr_section = the_section + + continue + + elif line == '': + continue + + if curr_section in handlers.keys(): + sections[curr_section].append(line) + + return inp_sections + + +def scan2(project: str, inp: str) -> None: + handlers = { + JUNCTIONS: inp_in_junction_new, #2 + RESERVOIRS: inp_in_reservoir_new, #3 + TANKS: inp_in_tank_new, #4 + } + + curr_section = _UNKNOWN + + sections : dict[str, list[str]]= {} + for c in handlers.keys(): + sections[c] = [] + + for line in open(inp): + line = line.strip() + + if line.startswith('['): + is_candidate = False + + for s in handlers.keys(): + if line.startswith(f'[{s}'): + curr_section = s + is_candidate = True + break + + if is_candidate: + continue + else: + curr_section = _UNKNOWN continue - if section == 'TITLE': - pass + elif line == '': + continue - elif section == 'JUNCTIONS': # + coords - pass - - elif section == 'RESERVOIRS': # + coords - pass - - elif section == 'TANKS': # + coords - pass - - elif section == 'PIPES': - pass - - elif section == 'PUMPS': - pass - - elif section == 'VALVES': - pass - - elif section == 'TAGS': - pass - - elif section == 'DEMANDS': - pass - - elif section == 'STATUS': - pass - - elif section == 'PATTERNS': - pass - - elif section == 'CURVES': - pass - - elif section == 'CONTROLS': - pass - - elif section == 'RULES': - pass - - elif section == 'ENERGY': - pass - - elif section == 'EMITTERS': - pass - - elif section == 'QUALITY': - pass - - elif section == 'SOURCES': - pass - - elif section == 'REACTIONS': - pass - - elif section == 'MIXING': - pass - - elif section == 'TIMES': - pass - - elif section == 'REPORT': - pass - - elif section == 'OPTIONS': - pass - - elif section == 'COORDINATES': - pass - - elif section == 'VERTICES': - pass - - elif section == 'LABELS': - pass - - elif section == 'BACKDROP': - pass - - elif section == 'END': - pass # :) + if curr_section in handlers.keys(): + handlers[curr_section](project, line) -def read_inp(project: str, inp: str) -> bool: - if is_project_open(project): - close_project(project) - - if have_project(project): - delete_project(project) - - create_project(project) - open_project(project) - - close_project(project) - - return True - - -def import_inp(project: str, cs: ChangeSet) -> bool: +def scan3(project: str, inp: str) -> None: + handlers = { + #PIPES: , #5 + #PUMPS: , #6 + #VALVES: , #7 + #DEMANDS: , #9 + #EMITTERS: , #16 + #QUALITY: , #17 + #SOURCES: , #18 + #MIXING: , #20 + #COORDINATES: #24 + #LABELS: #26 + } + + curr_section = _UNKNOWN + + sections : dict[str, list[str]]= {} + for c in handlers.keys(): + sections[c] = [] + + for line in open(inp): + line = line.strip() + + if line.startswith('['): + is_candidate = False + + for s in handlers.keys(): + if line.startswith(f'[{s}'): + curr_section = s + is_candidate = True + break + + if is_candidate: + continue + else: + curr_section = _UNKNOWN + continue + + elif line == '': + continue + + if curr_section in handlers.keys(): + handlers[curr_section](project, line) + + +def scan4(project: str, inp: str) -> None: + handlers = { + #TAGS: inp_in_junction_new, #5 + #STATUS: inp_in_reservoir_new, #6 + #ENERGY: inp_in_tank_new, #7 + #REACTIONS: , #9 + #VERTICES: , #16 + } + + curr_section = _UNKNOWN + + sections : dict[str, list[str]]= {} + for c in handlers.keys(): + sections[c] = [] + + for line in open(inp): + line = line.strip() + + if line.startswith('['): + is_candidate = False + + for s in handlers.keys(): + if line.startswith(f'[{s}'): + curr_section = s + is_candidate = True + break + + if is_candidate: + continue + else: + curr_section = _UNKNOWN + continue + + elif line == '': + continue + + if curr_section in handlers.keys(): + handlers[curr_section](project, line) + + + +def parse_inp(project: str, inp: str) -> None: + scan1(project, inp) + scan2(project, inp) + scan3(project, inp) + scan4(project, inp) + + +def read_inp_new(project: str, inp: str) -> bool: + if is_project_open(project): + close_project(project) + + if have_project(project): + delete_project(project) + + create_project(project) + open_project(project) + + parse_inp(project, inp) + + close_project(project) + + return True + + +def import_inp_new(project: str, cs: ChangeSet) -> bool: if is_project_open(project): close_project(project) diff --git a/build_db.py b/build_db.py index 31f04b1..83862d9 100644 --- a/build_db.py +++ b/build_db.py @@ -6,7 +6,7 @@ files = [ #'fengxian', #'jbh', #'nanjing', - #'net3', + 'net3', #'zj', #'suzhouhe', ] @@ -20,7 +20,7 @@ def db2inp(): dump_inp(file, f'./db_inp/{file}.db.inp') if __name__ == '__main__': - #inp2db() + inp2db() #db2inp() #print(run_inp('net3')) pass diff --git a/tjnetwork.py b/tjnetwork.py index de55849..719d5c0 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -185,8 +185,8 @@ def close_project(name: str) -> None: def copy_project(source: str, new: str) -> None: return api.copy_project(source, new) -def read_inp(name: str, inp: str) -> None: - return api.read_inp(name, inp) +def read_inp(name: str, inp: str) -> bool: + return api.read_inp_new(name, inp) def dump_inp(name: str, inp: str) -> None: return api.dump_inp(name, inp) From b3db5bd027bb7488a00d9c3639566a34fbf1c156 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Fri, 10 Mar 2023 09:23:27 +0800 Subject: [PATCH 06/39] Add level for section --- api/inp_in_new.py | 55 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index fbcdf8c..e1b0b4a 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -17,6 +17,44 @@ from .s27_backdrop import inp_in_backdrop_new _UNKNOWN = 'UNKNOWN' +_level_1 = { + TITLE, + PATTERNS, + CURVES, + CONTROLS, + RULES, + TIMES, + REPORT, + OPTIONS, + BACKDROP, +} + +_level_2 = { + JUNCTIONS, + RESERVOIRS, + TANKS, +} + +_level_3 = { + PIPES, + PUMPS, + VALVES, + DEMANDS, + EMITTERS, + QUALITY, + SOURCES, + MIXING, + COORDINATES, + LABELS, +} + +_level_4 = { + TAGS, + STATUS, + ENERGY, + REACTIONS, + VERTICES, +} def scan1(project: str, inp: str) -> list[str]: handlers = { @@ -110,16 +148,7 @@ def scan2(project: str, inp: str) -> None: def scan3(project: str, inp: str) -> None: handlers = { - #PIPES: , #5 - #PUMPS: , #6 - #VALVES: , #7 - #DEMANDS: , #9 - #EMITTERS: , #16 - #QUALITY: , #17 - #SOURCES: , #18 - #MIXING: , #20 - #COORDINATES: #24 - #LABELS: #26 + } curr_section = _UNKNOWN @@ -155,11 +184,7 @@ def scan3(project: str, inp: str) -> None: def scan4(project: str, inp: str) -> None: handlers = { - #TAGS: inp_in_junction_new, #5 - #STATUS: inp_in_reservoir_new, #6 - #ENERGY: inp_in_tank_new, #7 - #REACTIONS: , #9 - #VERTICES: , #16 + } curr_section = _UNKNOWN From 696bd55ead1f3b74178fed738215139ef5dc89f7 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 10 Mar 2023 19:57:20 +0800 Subject: [PATCH 07/39] Optimize control and rule --- api/s13_controls.py | 5 ++--- api/s14_rules.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/s13_controls.py b/api/s13_controls.py index 42810b7..feef31e 100644 --- a/api/s13_controls.py +++ b/api/s13_controls.py @@ -48,9 +48,8 @@ def inp_in_control(section: list[str]) -> ChangeSet: return ChangeSet() -def inp_in_control_new(name: str, section: list[str]) -> None: - for line in section: - write(name, f"insert into controls (line) values ('{line}');") +def inp_in_control_new(name: str, line: str) -> None: + write(name, f"insert into controls (line) values ('{line}');") def inp_out_control(name: str) -> list[str]: diff --git a/api/s14_rules.py b/api/s14_rules.py index 69e2562..863711d 100644 --- a/api/s14_rules.py +++ b/api/s14_rules.py @@ -44,9 +44,8 @@ def inp_in_rule(section: list[str]) -> ChangeSet: return ChangeSet() -def inp_in_rule_new(name: str, section: list[str]) -> None: - for line in section: - write(name, f"insert into rules (line) values ('{line}');") +def inp_in_rule_new(name: str, line: str) -> None: + write(name, f"insert into rules (line) values ('{line}');") def inp_out_rule(name: str) -> list[str]: From 24a39aeca67eb89ab2b3e24aa91a96f4fcacb591 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 10 Mar 2023 19:57:52 +0800 Subject: [PATCH 08/39] Fix option pattern reading --- api/s23_options.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/s23_options.py b/api/s23_options.py index cb1fc5a..1a02b6b 100644 --- a/api/s23_options.py +++ b/api/s23_options.py @@ -22,9 +22,10 @@ def inp_in_option(section: list[str]) -> ChangeSet: tokens = s.strip().split() if tokens[0].upper() == 'PATTERN': # can not upper id - cs |= { 'PATTERN' : tokens[1] } + value = tokens[1] if len(tokens) > 1 else '' + cs |= { 'PATTERN' : value } elif tokens[0].upper() == 'QUALITY': # can not upper trace node - value = tokens[1] + value = tokens[1] if len(tokens) > 1 else '' if len(tokens) > 2: value += f' {tokens[2]}' cs |= { 'QUALITY' : value } From ed6f6daca0e23731df16b1faf62d8d4ae0d7b431 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 15 Mar 2023 20:03:55 +0800 Subject: [PATCH 09/39] Refine inp in --- api/inp_in_new.py | 250 +++++++++++++++++----------------------------- 1 file changed, 93 insertions(+), 157 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index e1b0b4a..328a67e 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -14,8 +14,39 @@ from .s22_report import inp_in_report_new from .s23_options import inp_in_option_new from .s27_backdrop import inp_in_backdrop_new +_S = 'S' +_L = 'L' -_UNKNOWN = 'UNKNOWN' +_handler = { + TITLE : (_S, inp_in_title_new), + JUNCTIONS : (_L, inp_in_junction_new), + RESERVOIRS : (_L, inp_in_reservoir_new), + TANKS : (_L, inp_in_tank_new), + PIPES : (_L, None), + PUMPS : (_L, None), + VALVES : (_L, None), + TAGS : (_L, None), + DEMANDS : (_L, None), + STATUS : (_L, None), + PATTERNS : (_L, inp_in_pattern_new), + CURVES : (_L, inp_in_curve_new), + CONTROLS : (_L, inp_in_control_new), + RULES : (_L, inp_in_rule_new), + ENERGY : (_L, None), + EMITTERS : (_L, None), + QUALITY : (_L, None), + SOURCES : (_L, None), + REACTIONS : (_L, None), + MIXING : (_L, None), + TIMES : (_S, inp_in_time_new), + REPORT : (_S, inp_in_report_new), + OPTIONS : (_S, inp_in_option_new), + COORDINATES : (_L, None), + VERTICES : (_L, None), + LABELS : (_L, None), + BACKDROP : (_S, inp_in_backdrop_new), + #END : 'END', +} _level_1 = { TITLE, @@ -56,174 +87,75 @@ _level_4 = { VERTICES, } -def scan1(project: str, inp: str) -> list[str]: - handlers = { - TITLE: inp_in_title_new, #1 - PATTERNS: inp_in_pattern_new, #11 - CURVES: inp_in_curve_new, #12 - CONTROLS: inp_in_control_new, #13 - RULES: inp_in_rule_new, #14 - TIMES: inp_in_time_new, #21 - REPORT: inp_in_report_new, #22 - OPTIONS: inp_in_option_new, #23 - BACKDROP: inp_in_backdrop_new,#27 - } - curr_section = _UNKNOWN - prev_section = _UNKNOWN +_UNKNOWN = 'UNKNOWN' - inp_sections: list[str] = [] +class SectionRange: + def __init__(self) -> None: + start = 0 + end = 0 + + +class SectionOffset: + def __init__(self, s: str) -> None: + name = s + ranges: list[SectionRange] = [] + + +def parse_file(project: str, inp: str) -> None: + # find section position + offset_list = [] + + offset: dict[str, list[tuple[int, int]]] = {} + for s in section_name: + offset[s] = [] + + with open(inp) as f: + while True: + line = f.readline() + if not line: + break + + line = line.strip() + if line.startswith('['): + for s in section_name: + if line.startswith(f'[{s}'): + offset[s].append(f.tell()) + break + + # parse the whole section rather than line sections : dict[str, list[str]]= {} - for c in handlers.keys(): - sections[c] = [] + for [s, t] in _handler.items(): + if t[0] == _S: + sections[s] = [] - for line in open(inp): - line = line.strip() + levels = _level_1 | _level_2 | _level_3 | _level_4 - if line.startswith('['): - the_section = _UNKNOWN + with open(inp) as f: + for s in levels: + is_s = _handler[s][0] == _S - for s in section_name: - if line.startswith(f'[{s}'): - the_section = s - inp_sections.append(s) - break + for o in offset[s]: + f.seek(o) - prev_section = curr_section - if prev_section in handlers.keys(): - handlers[prev_section](project, sections[prev_section]) - sections[prev_section].clear() + while True: + line = f.readline() + if not line: + break - curr_section = the_section + line = line.strip() - continue - - elif line == '': - continue - - if curr_section in handlers.keys(): - sections[curr_section].append(line) - - return inp_sections - - -def scan2(project: str, inp: str) -> None: - handlers = { - JUNCTIONS: inp_in_junction_new, #2 - RESERVOIRS: inp_in_reservoir_new, #3 - TANKS: inp_in_tank_new, #4 - } - - curr_section = _UNKNOWN - - sections : dict[str, list[str]]= {} - for c in handlers.keys(): - sections[c] = [] - - for line in open(inp): - line = line.strip() - - if line.startswith('['): - is_candidate = False - - for s in handlers.keys(): - if line.startswith(f'[{s}'): - curr_section = s - is_candidate = True - break - - if is_candidate: - continue - else: - curr_section = _UNKNOWN - continue - - elif line == '': - continue - - if curr_section in handlers.keys(): - handlers[curr_section](project, line) - - -def scan3(project: str, inp: str) -> None: - handlers = { - - } - - curr_section = _UNKNOWN - - sections : dict[str, list[str]]= {} - for c in handlers.keys(): - sections[c] = [] - - for line in open(inp): - line = line.strip() - - if line.startswith('['): - is_candidate = False - - for s in handlers.keys(): - if line.startswith(f'[{s}'): - curr_section = s - is_candidate = True - break - - if is_candidate: - continue - else: - curr_section = _UNKNOWN - continue - - elif line == '': - continue - - if curr_section in handlers.keys(): - handlers[curr_section](project, line) - - -def scan4(project: str, inp: str) -> None: - handlers = { - - } - - curr_section = _UNKNOWN - - sections : dict[str, list[str]]= {} - for c in handlers.keys(): - sections[c] = [] - - for line in open(inp): - line = line.strip() - - if line.startswith('['): - is_candidate = False - - for s in handlers.keys(): - if line.startswith(f'[{s}'): - curr_section = s - is_candidate = True - break - - if is_candidate: - continue - else: - curr_section = _UNKNOWN - continue - - elif line == '': - continue - - if curr_section in handlers.keys(): - handlers[curr_section](project, line) + if is_s: + sections[s].append(line) + else: + pass + f.seek(0) def parse_inp(project: str, inp: str) -> None: - scan1(project, inp) - scan2(project, inp) - scan3(project, inp) - scan4(project, inp) + pass def read_inp_new(project: str, inp: str) -> bool: @@ -236,10 +168,14 @@ def read_inp_new(project: str, inp: str) -> bool: create_project(project) open_project(project) - parse_inp(project, inp) + try: + parse_inp(project, inp) + except: + close_project(project) + delete_project(project) + return False close_project(project) - return True From 2f87d87233a05233bb60b23102915bdafea0099e Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 15 Mar 2023 21:29:33 +0800 Subject: [PATCH 10/39] Specialize pattern and curve --- api/inp_in_new.py | 78 ++++++++++++++++++++++++++++++--------------- api/s11_patterns.py | 24 +++----------- api/s12_curves.py | 27 ++-------------- 3 files changed, 59 insertions(+), 70 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 328a67e..40525de 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -1,5 +1,5 @@ from .project import * -from .database import ChangeSet +from .database import ChangeSet, write from .sections import * from .s1_title import inp_in_title_new from .s2_junctions import inp_in_junction_new @@ -91,25 +91,8 @@ _level_4 = { _UNKNOWN = 'UNKNOWN' -class SectionRange: - def __init__(self) -> None: - start = 0 - end = 0 - - -class SectionOffset: - def __init__(self, s: str) -> None: - name = s - ranges: list[SectionRange] = [] - - -def parse_file(project: str, inp: str) -> None: - # find section position - offset_list = [] - - offset: dict[str, list[tuple[int, int]]] = {} - for s in section_name: - offset[s] = [] +def _get_offset(inp: str) -> dict[str, list[int]]: + offset: dict[str, list[int]] = {} with open(inp) as f: while True: @@ -121,23 +104,39 @@ def parse_file(project: str, inp: str) -> None: if line.startswith('['): for s in section_name: if line.startswith(f'[{s}'): + if s not in offset: + offset[s] = [] offset[s].append(f.tell()) break + return offset + + +def parse_file(project: str, inp: str) -> None: + offset = _get_offset(inp) + print(offset) + + levels = _level_1 | _level_2 | _level_3 | _level_4 + # parse the whole section rather than line sections : dict[str, list[str]]= {} for [s, t] in _handler.items(): if t[0] == _S: sections[s] = [] - levels = _level_1 | _level_2 | _level_3 | _level_4 + pattern_desc_line = None + curve_type_desc_line = None with open(inp) as f: for s in levels: - is_s = _handler[s][0] == _S + if s not in offset: + continue - for o in offset[s]: - f.seek(o) + is_s = _handler[s][0] == _S + handler = _handler[s][1] + + for ptr in offset[s]: + f.seek(ptr) while True: line = f.readline() @@ -145,17 +144,44 @@ def parse_file(project: str, inp: str) -> None: break line = line.strip() + if line == '' or line.startswith('['): + break if is_s: sections[s].append(line) else: - pass + if line.startswith(';'): + line = line.removeprefix(';') + if s == PATTERNS: # ;desc + pattern_desc_line = line + elif s == CURVES: # ;type: desc + curve_type_desc_line = line + continue + + if s == PATTERNS: + if pattern_desc_line != None: + tokens = line.split() + write(project, f"insert into _pattern (id) values ('{tokens[0]}');") + pattern_desc_line = None + elif s == CURVES: + if curve_type_desc_line != None: + type_and_desc = curve_type_desc_line.split(':') + tokens = line.split() + write(project, f"insert into _curve (id, type) values ('{tokens[0]}', '{type_and_desc[0].strip()}');") + curve_type_desc_line = None + + if handler != None: + handler(project, line) + f.seek(0) + if is_s and handler != None: + handler(project, sections[s]) + def parse_inp(project: str, inp: str) -> None: - pass + parse_file(project, inp) def read_inp_new(project: str, inp: str) -> bool: diff --git a/api/s11_patterns.py b/api/s11_patterns.py index 5393299..e3ac647 100644 --- a/api/s11_patterns.py +++ b/api/s11_patterns.py @@ -126,26 +126,10 @@ def inp_in_pattern(section: list[str]) -> ChangeSet: return cs -def inp_in_pattern_new(name: str, section: list[str]) -> None: - descs = {} - patterns: list[str] = [] - - count = len(section) - for i in range(0, count): - if section[i].startswith(';'): - # this is description - next = i + 1 - if next < count and section[next].startswith(';') == False: - next_tokens = section[next].split() - descs[next_tokens[0]] = section[i].removeprefix(';') - continue - - tokens = section[i].split() - if tokens[0] not in patterns: - patterns.append(tokens[0]) - write(name, f"insert into _pattern (id) values ('{tokens[0]}');") - for token in tokens[1:]: - write(name, f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});") +def inp_in_pattern_new(name: str, line: str) -> None: + tokens = line.split() + for token in tokens[1:]: + write(name, f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});") def inp_out_pattern(name: str) -> list[str]: diff --git a/api/s12_curves.py b/api/s12_curves.py index 1b30709..72e91d7 100644 --- a/api/s12_curves.py +++ b/api/s12_curves.py @@ -159,30 +159,9 @@ def inp_in_curve(section: list[str]) -> ChangeSet: return cs -def inp_in_curve_new(name: str, section: list[str]) -> None: - types = {} - descs = {} - curves: list[str] = [] - - count = len(section) - for i in range(0, count): - if section[i].startswith(';'): - # ;type: desc - type_plus_desc = section[i].removeprefix(';') - type_plus_desc_tokens = type_plus_desc.split(':') - next = i + 1 - if next < count and section[next].startswith(';') == False: - next_tokens = section[next].split() - types[next_tokens[0]] = type_plus_desc_tokens[0].strip().upper() - if len(type_plus_desc_tokens) > 1: - descs[next_tokens[0]] = type_plus_desc_tokens[1].strip() - continue - - tokens = section[i].split() - if tokens[0] not in curves: - curves.append(tokens[0]) - write(name, f"insert into _curve (id, type) values ('{tokens[0]}', '{types[tokens[0]]}');") - write(name, f"insert into curves (id, x, y) values ('{tokens[0]}', {float(tokens[1])}, {float(tokens[2])});") +def inp_in_curve_new(name: str, line: str) -> None: + tokens = line.split() + write(name, f"insert into curves (id, x, y) values ('{tokens[0]}', {float(tokens[1])}, {float(tokens[2])});") def inp_out_curve(name: str) -> list[str]: From 4e6864b2fc94152c218505686deda9bacc55b101 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 15 Mar 2023 21:45:12 +0800 Subject: [PATCH 11/39] Remove duplicated checking --- api/s2_junctions.py | 4 ---- api/s3_reservoirs.py | 4 ---- api/s4_tanks.py | 4 ---- 3 files changed, 12 deletions(-) diff --git a/api/s2_junctions.py b/api/s2_junctions.py index d7b8489..1a250d5 100644 --- a/api/s2_junctions.py +++ b/api/s2_junctions.py @@ -153,10 +153,6 @@ def inp_in_junction(section: list[str]) -> ChangeSet: def inp_in_junction_new(name: str, line: str) -> None: - # skip comment - if line.startswith(';'): - return - tokens = line.split() num = len(tokens) diff --git a/api/s3_reservoirs.py b/api/s3_reservoirs.py index 53e988d..6a24b97 100644 --- a/api/s3_reservoirs.py +++ b/api/s3_reservoirs.py @@ -146,10 +146,6 @@ def inp_in_reservoir(section: list[str]) -> ChangeSet: def inp_in_reservoir_new(name: str, line: str) -> None: - # skip comment - if line.startswith(';'): - return - tokens = line.split() num = len(tokens) diff --git a/api/s4_tanks.py b/api/s4_tanks.py index 766c336..813bdd7 100644 --- a/api/s4_tanks.py +++ b/api/s4_tanks.py @@ -188,10 +188,6 @@ def inp_in_tank(section: list[str]) -> ChangeSet: def inp_in_tank_new(name: str, line: str) -> None: - # skip comment - if line.startswith(';'): - return - tokens = line.split() num = len(tokens) From 81c4e0308b402b4199369c8b5e48f4a94ffeb0a5 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 15 Mar 2023 21:47:46 +0800 Subject: [PATCH 12/39] Replace set with list --- api/inp_in_new.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 40525de..d00425f 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -48,7 +48,7 @@ _handler = { #END : 'END', } -_level_1 = { +_level_1 = [ TITLE, PATTERNS, CURVES, @@ -58,15 +58,15 @@ _level_1 = { REPORT, OPTIONS, BACKDROP, -} +] -_level_2 = { +_level_2 = [ JUNCTIONS, RESERVOIRS, TANKS, -} +] -_level_3 = { +_level_3 = [ PIPES, PUMPS, VALVES, @@ -77,15 +77,15 @@ _level_3 = { MIXING, COORDINATES, LABELS, -} +] -_level_4 = { +_level_4 = [ TAGS, STATUS, ENERGY, REACTIONS, VERTICES, -} +] _UNKNOWN = 'UNKNOWN' @@ -114,9 +114,8 @@ def _get_offset(inp: str) -> dict[str, list[int]]: def parse_file(project: str, inp: str) -> None: offset = _get_offset(inp) - print(offset) - levels = _level_1 | _level_2 | _level_3 | _level_4 + levels = _level_1 + _level_2 + _level_3 + _level_4 # parse the whole section rather than line sections : dict[str, list[str]]= {} @@ -194,12 +193,14 @@ def read_inp_new(project: str, inp: str) -> bool: create_project(project) open_project(project) - try: + parse_inp(project, inp) + + '''try: parse_inp(project, inp) except: close_project(project) delete_project(project) - return False + return False''' close_project(project) return True From 617c66d0cd64a02371ac4ecee1e52301abc52bfc Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 15 Mar 2023 22:04:39 +0800 Subject: [PATCH 13/39] Support inp in link new --- api/inp_in_new.py | 9 ++++++--- api/s3_reservoirs.py | 2 +- api/s4_tanks.py | 1 + api/s5_pipes.py | 22 ++++++++++++++++++++++ api/s6_pumps.py | 27 +++++++++++++++++++++++++++ api/s7_valves.py | 20 ++++++++++++++++++++ 6 files changed, 77 insertions(+), 4 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index d00425f..4c4ede6 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -5,6 +5,9 @@ from .s1_title import inp_in_title_new from .s2_junctions import inp_in_junction_new from .s3_reservoirs import inp_in_reservoir_new from .s4_tanks import inp_in_tank_new +from .s5_pipes import inp_in_pipe_new +from .s6_pumps import inp_in_pump_new +from .s7_valves import inp_in_valve_new from .s11_patterns import inp_in_pattern_new from .s12_curves import inp_in_curve_new from .s13_controls import inp_in_control_new @@ -22,9 +25,9 @@ _handler = { JUNCTIONS : (_L, inp_in_junction_new), RESERVOIRS : (_L, inp_in_reservoir_new), TANKS : (_L, inp_in_tank_new), - PIPES : (_L, None), - PUMPS : (_L, None), - VALVES : (_L, None), + PIPES : (_L, inp_in_pipe_new), + PUMPS : (_L, inp_in_pump_new), + VALVES : (_L, inp_in_valve_new), TAGS : (_L, None), DEMANDS : (_L, None), STATUS : (_L, None), diff --git a/api/s3_reservoirs.py b/api/s3_reservoirs.py index 6a24b97..2ffe9bd 100644 --- a/api/s3_reservoirs.py +++ b/api/s3_reservoirs.py @@ -159,7 +159,7 @@ def inp_in_reservoir_new(name: str, line: str) -> None: desc = str(tokens[-1]) if has_desc else None write(name, f"insert into _node (id, type) values ('{id}', 'reservoir');") - write(name, f"\ninsert into reservoirs (id, head, pattern) values ('{id}', {head}, {pattern});") + write(name, f"insert into reservoirs (id, head, pattern) values ('{id}', {head}, {pattern});") def inp_out_reservoir(name: str) -> list[str]: diff --git a/api/s4_tanks.py b/api/s4_tanks.py index 813bdd7..0e5e1cc 100644 --- a/api/s4_tanks.py +++ b/api/s4_tanks.py @@ -210,6 +210,7 @@ def inp_in_tank_new(name: str, line: str) -> None: write(name, f"insert into _node (id, type) values ('{id}', 'tank');") write(name, f"insert into tanks (id, elevation, init_level, min_level, max_level, diameter, min_vol, vol_curve, overflow) values ('{id}', {elevation}, {init_level}, {min_level}, {max_level}, {diameter}, {min_vol}, {vol_curve}, {overflow});") + def inp_out_tank(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from tanks') diff --git a/api/s5_pipes.py b/api/s5_pipes.py index f7c05b8..e31d57f 100644 --- a/api/s5_pipes.py +++ b/api/s5_pipes.py @@ -161,6 +161,28 @@ def inp_in_pipe(section: list[str]) -> ChangeSet: return cs +def inp_in_pipe_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + id = str(tokens[0]) + node1 = str(tokens[1]) + node2 = str(tokens[2]) + length = float(tokens[3]) + diameter = float(tokens[4]) + roughness = float(tokens[5]) + minor_loss = float(tokens[6]) + # status is must-have, here fix input + status = str(tokens[7].upper()) if num_without_desc >= 8 else PIPE_STATUS_OPEN + desc = str(tokens[-1]) if has_desc else None + + write(name, f"insert into _link (id, type) values ('{id}', 'pipe');") + write(name, f"insert into pipes (id, node1, node2, length, diameter, roughness, minor_loss, status) values ('{id}', '{node1}', '{node2}', {length}, {diameter}, {roughness}, {minor_loss}, '{status}');") + + def inp_out_pipe(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from pipes') diff --git a/api/s6_pumps.py b/api/s6_pumps.py index aa2071f..2278060 100644 --- a/api/s6_pumps.py +++ b/api/s6_pumps.py @@ -151,6 +151,33 @@ def inp_in_pump(section: list[str]) -> ChangeSet: return cs +def inp_in_pump_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + id = str(tokens[0]) + node1 = str(tokens[1]) + node2 = str(tokens[2]) + props = {} + for i in range(3, num_without_desc, 2): + props |= { tokens[i].lower(): tokens[i + 1] } + power = float(props['power']) if 'power' in props else None + power = power if power != None else 'null' + head = str(props['head']) if 'head' in props else None + head = f"'{head}'" if head != None else 'null' + speed = float(props['speed']) if 'speed' in props else None + speed = speed if speed != None else 'null' + pattern = str(props['pattern']) if 'pattern' in props else None + pattern = f"'{pattern}'" if pattern != None else 'null' + desc = str(tokens[-1]) if has_desc else None + + write(name, f"insert into _link (id, type) values ('{id}', 'pump');") + write(name, f"insert into pumps (id, node1, node2, power, head, speed, pattern) values ('{id}', '{node1}', '{node2}', {power}, {head}, {speed}, {pattern});") + + def inp_out_pump(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from pumps') diff --git a/api/s7_valves.py b/api/s7_valves.py index fcd5b72..491b961 100644 --- a/api/s7_valves.py +++ b/api/s7_valves.py @@ -157,6 +157,26 @@ def inp_in_valve(section: list[str]) -> ChangeSet: return cs +def inp_in_valve_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + id = str(tokens[0]) + node1 = str(tokens[1]) + node2 = str(tokens[2]) + diameter = float(tokens[3]) + v_type = str(tokens[4].upper()) + setting = str(tokens[5]) + minor_loss = float(tokens[6]) + desc = str(tokens[-1]) if has_desc else None + + write(name, f"insert into _link (id, type) values ('{id}', 'valve');") + write(name, f"insert into valves (id, node1, node2, diameter, type, setting, minor_loss) values ('{id}', '{node1}', '{node2}', {diameter}, '{v_type}', '{setting}', {minor_loss});") + + def inp_out_valve(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from valves') From f79a9cdae89b44ce3b17a3279c3d8c1d77bec053 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 15 Mar 2023 22:34:38 +0800 Subject: [PATCH 14/39] Support inp in tag, demand, status --- api/inp_in_new.py | 23 ++++++++++++++++++----- api/s10_status.py | 15 +++++++++++++++ api/s8_tags.py | 17 +++++++++++++++++ api/s9_demands.py | 17 +++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 4c4ede6..7160a8f 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -1,5 +1,5 @@ from .project import * -from .database import ChangeSet, write +from .database import ChangeSet, write, try_read from .sections import * from .s1_title import inp_in_title_new from .s2_junctions import inp_in_junction_new @@ -8,6 +8,9 @@ from .s4_tanks import inp_in_tank_new from .s5_pipes import inp_in_pipe_new from .s6_pumps import inp_in_pump_new from .s7_valves import inp_in_valve_new +from .s8_tags import inp_in_tag_new +from .s9_demands import inp_in_demand_new +from .s10_status import inp_in_status_new from .s11_patterns import inp_in_pattern_new from .s12_curves import inp_in_curve_new from .s13_controls import inp_in_control_new @@ -28,9 +31,9 @@ _handler = { PIPES : (_L, inp_in_pipe_new), PUMPS : (_L, inp_in_pump_new), VALVES : (_L, inp_in_valve_new), - TAGS : (_L, None), - DEMANDS : (_L, None), - STATUS : (_L, None), + TAGS : (_L, inp_in_tag_new), + DEMANDS : (_L, inp_in_demand_new), + STATUS : (_L, inp_in_status_new), PATTERNS : (_L, inp_in_pattern_new), CURVES : (_L, inp_in_curve_new), CONTROLS : (_L, inp_in_control_new), @@ -128,6 +131,7 @@ def parse_file(project: str, inp: str) -> None: pattern_desc_line = None curve_type_desc_line = None + demand_junction = None with open(inp) as f: for s in levels: @@ -146,8 +150,10 @@ def parse_file(project: str, inp: str) -> None: break line = line.strip() - if line == '' or line.startswith('['): + if line.startswith('['): break + elif line == '': + continue if is_s: sections[s].append(line) @@ -171,6 +177,13 @@ def parse_file(project: str, inp: str) -> None: tokens = line.split() write(project, f"insert into _curve (id, type) values ('{tokens[0]}', '{type_and_desc[0].strip()}');") curve_type_desc_line = None + elif s == DEMANDS: + tokens = line.split() + junction = str(tokens[0]) + if demand_junction != junction: + if try_read(project, f"select * from demands where junction = '{junction}'") != None: + write(project, f"delete from demands where junction = '{junction}';") + demand_junction = junction if handler != None: handler(project, line) diff --git a/api/s10_status.py b/api/s10_status.py index 07d1f50..2aa1cf5 100644 --- a/api/s10_status.py +++ b/api/s10_status.py @@ -113,6 +113,21 @@ def inp_in_status(section: list[str]) -> ChangeSet: return cs +def inp_in_status_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + link = str(tokens[0]) + value = tokens[1].upper() + if value == LINK_STATUS_OPEN or value == LINK_STATUS_CLOSED or value == LINK_STATUS_ACTIVE: + write(name, f"insert into status (link, status, setting) values ('{link}', '{value}', null);") + else: + write(name, f"insert into status (link, status, setting) values ('{link}', null, {float(value)});") + + def inp_out_status(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from status') diff --git a/api/s8_tags.py b/api/s8_tags.py index 9dd8a32..9ce8fd9 100644 --- a/api/s8_tags.py +++ b/api/s8_tags.py @@ -103,6 +103,23 @@ def inp_in_tag(section: list[str]) -> ChangeSet: return cs +def inp_in_tag_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + t_type = str(tokens[0].upper()) + id = str(tokens[1]) + tag = str(tokens[2]) + + if t_type == TAG_TYPE_NODE: + write(name, f"insert into tags_node (id, tag) values ('{id}', '{tag}');") + elif t_type == TAG_TYPE_LINK: + write(name, f"insert into tags_link (id, tag) values ('{id}', '{tag}');") + + def inp_out_tag(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from tags_node') diff --git a/api/s9_demands.py b/api/s9_demands.py index 2fedb1e..d482900 100644 --- a/api/s9_demands.py +++ b/api/s9_demands.py @@ -97,6 +97,23 @@ def inp_in_demand(section: list[str]) -> ChangeSet: return cs +def inp_in_demand_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + junction = str(tokens[0]) + demand = float(tokens[1]) + pattern = str(tokens[2]) if num_without_desc >= 3 else None + pattern = f"'{pattern}'" if pattern != None else 'null' + category = str(tokens[3]) if num_without_desc >= 4 else None + category = f"'{category}'" if category != None else 'null' + + write(name, f"\ninsert into demands (junction, demand, pattern, category) values ('{junction}', {demand}, {pattern}, {category});") + + def inp_out_demand(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from demands order by _order") From b35fccad498ed07f7eb1b652106a5b45b586054a Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 15 Mar 2023 23:47:06 +0800 Subject: [PATCH 15/39] Support inp in energy, emitter --- api/inp_in_new.py | 6 ++++-- api/s15_energy.py | 29 +++++++++++++++++++++++++++++ api/s16_emitters.py | 13 +++++++++++++ api/s9_demands.py | 2 +- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 7160a8f..b1d1f88 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -15,6 +15,8 @@ from .s11_patterns import inp_in_pattern_new from .s12_curves import inp_in_curve_new from .s13_controls import inp_in_control_new from .s14_rules import inp_in_rule_new +from .s15_energy import inp_in_energy_new +from .s16_emitters import inp_in_emitter_new from .s21_times import inp_in_time_new from .s22_report import inp_in_report_new from .s23_options import inp_in_option_new @@ -38,8 +40,8 @@ _handler = { CURVES : (_L, inp_in_curve_new), CONTROLS : (_L, inp_in_control_new), RULES : (_L, inp_in_rule_new), - ENERGY : (_L, None), - EMITTERS : (_L, None), + ENERGY : (_L, inp_in_energy_new), + EMITTERS : (_L, inp_in_emitter_new), QUALITY : (_L, None), SOURCES : (_L, None), REACTIONS : (_L, None), diff --git a/api/s15_energy.py b/api/s15_energy.py index 8b7551c..92a5b20 100644 --- a/api/s15_energy.py +++ b/api/s15_energy.py @@ -169,6 +169,35 @@ def inp_in_energy(section: list[str]) -> ChangeSet: return cs +def inp_in_energy_new(name: str, line: str) -> None: + tokens = line.split() + + if tokens[0].upper() == 'PUMP': + pump = tokens[1] + key = tokens[2].lower() + value = tokens[3] + if key == 'price': + value = float(value) + else: + value = f"'{value}'" + if key == 'efficiency': + key = 'effic' + + write(name, f"insert into energy_pump_{key} (pump, {key}) values ('{pump}', {value});") + + else: + line = line.upper().strip() + for key in get_energy_schema('').keys(): + if line.startswith(key): + value = line.removeprefix(key).strip() + + # exception here + if line.startswith('GLOBAL EFFICIENCY'): + value = line.removeprefix('GLOBAL EFFICIENCY').strip() + + write(name, f"update energy set value = '{value}' where key = '{key}';") + + def inp_out_energy(name: str) -> list[str]: lines = [] diff --git a/api/s16_emitters.py b/api/s16_emitters.py index 844a3fc..db512dc 100644 --- a/api/s16_emitters.py +++ b/api/s16_emitters.py @@ -89,6 +89,19 @@ def inp_in_emitter(section: list[str]) -> ChangeSet: return cs +def inp_in_emitter_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + junction = str(tokens[0]) + coefficient = float(tokens[1]) + + write(name, f"\ninsert into emitters (junction, coefficient) values ('{junction}', {coefficient});") + + def inp_out_emitter(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from emitters') diff --git a/api/s9_demands.py b/api/s9_demands.py index d482900..efdf098 100644 --- a/api/s9_demands.py +++ b/api/s9_demands.py @@ -111,7 +111,7 @@ def inp_in_demand_new(name: str, line: str) -> None: category = str(tokens[3]) if num_without_desc >= 4 else None category = f"'{category}'" if category != None else 'null' - write(name, f"\ninsert into demands (junction, demand, pattern, category) values ('{junction}', {demand}, {pattern}, {category});") + write(name, f"insert into demands (junction, demand, pattern, category) values ('{junction}', {demand}, {pattern}, {category});") def inp_out_demand(name: str) -> list[str]: From bf1aeff1fa6e57bfefaed405ca691e26a8baffba Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 16 Mar 2023 00:02:11 +0800 Subject: [PATCH 16/39] Support inp in quality, source, reaction, mixing --- api/inp_in_new.py | 15 ++++++++------- api/s16_emitters.py | 2 +- api/s17_quality.py | 13 +++++++++++++ api/s18_sources.py | 17 +++++++++++++++++ api/s19_reactions.py | 22 ++++++++++++++++++++++ api/s20_mixing.py | 15 +++++++++++++++ 6 files changed, 76 insertions(+), 8 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index b1d1f88..d98f727 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -17,6 +17,10 @@ from .s13_controls import inp_in_control_new from .s14_rules import inp_in_rule_new from .s15_energy import inp_in_energy_new from .s16_emitters import inp_in_emitter_new +from .s17_quality import inp_in_quality_new +from .s18_sources import inp_in_source_new +from .s19_reactions import inp_in_reaction_new +from .s20_mixing import inp_in_mixing_new from .s21_times import inp_in_time_new from .s22_report import inp_in_report_new from .s23_options import inp_in_option_new @@ -42,10 +46,10 @@ _handler = { RULES : (_L, inp_in_rule_new), ENERGY : (_L, inp_in_energy_new), EMITTERS : (_L, inp_in_emitter_new), - QUALITY : (_L, None), - SOURCES : (_L, None), - REACTIONS : (_L, None), - MIXING : (_L, None), + QUALITY : (_L, inp_in_quality_new), + SOURCES : (_L, inp_in_source_new), + REACTIONS : (_L, inp_in_reaction_new), + MIXING : (_L, inp_in_mixing_new), TIMES : (_S, inp_in_time_new), REPORT : (_S, inp_in_report_new), OPTIONS : (_S, inp_in_option_new), @@ -96,9 +100,6 @@ _level_4 = [ ] -_UNKNOWN = 'UNKNOWN' - - def _get_offset(inp: str) -> dict[str, list[int]]: offset: dict[str, list[int]] = {} diff --git a/api/s16_emitters.py b/api/s16_emitters.py index db512dc..4c73bd7 100644 --- a/api/s16_emitters.py +++ b/api/s16_emitters.py @@ -99,7 +99,7 @@ def inp_in_emitter_new(name: str, line: str) -> None: junction = str(tokens[0]) coefficient = float(tokens[1]) - write(name, f"\ninsert into emitters (junction, coefficient) values ('{junction}', {coefficient});") + write(name, f"insert into emitters (junction, coefficient) values ('{junction}', {coefficient});") def inp_out_emitter(name: str) -> list[str]: diff --git a/api/s17_quality.py b/api/s17_quality.py index faf30fe..d9868ba 100644 --- a/api/s17_quality.py +++ b/api/s17_quality.py @@ -86,6 +86,19 @@ def inp_in_quality(section: list[str]) -> ChangeSet: return cs +def inp_in_quality_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + node = str(tokens[0]) + quality = float(tokens[1]) + + write(name, f"insert into quality (node, quality) values ('{node}', {quality});") + + def inp_out_quality(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from quality') diff --git a/api/s18_sources.py b/api/s18_sources.py index 9c1e210..251a01b 100644 --- a/api/s18_sources.py +++ b/api/s18_sources.py @@ -131,6 +131,23 @@ def inp_in_source(section: list[str]) -> ChangeSet: return cs +def inp_in_source_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + node = str(tokens[0]) + s_type = str(tokens[1].upper()) + strength = float(tokens[2]) + pattern = str(tokens[3]) if num_without_desc >= 4 else None + pattern = f"'{pattern}'" if pattern != None else 'null' + + write(name, f"insert into sources (node, type, strength, pattern) values ('{node}', '{s_type}', {strength}, {pattern});") + + + def inp_out_source(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from sources') diff --git a/api/s19_reactions.py b/api/s19_reactions.py index 5c9117a..57e7773 100644 --- a/api/s19_reactions.py +++ b/api/s19_reactions.py @@ -222,6 +222,28 @@ def inp_in_reaction(section: list[str]) -> ChangeSet: return cs +def inp_in_reaction_new(name: str, line: str) -> None: + tokens = line.split() + token0 = tokens[0].upper() + if token0 == 'BULK' or token0 == 'WALL': + pipe = tokens[1] + key = token0.lower() + value = tokens[2] + write(name, f"insert into reactions_pipe_{key} (pipe, value) values ('{pipe}', {value});") + + elif token0 == 'TANK': + tank = tokens[1] + value = tokens[2] + write(name, f"insert into reactions_tank (tank, value) values ('{tank}', {value});") + + else: + line = line.upper().strip() + for key in get_reaction_schema('').keys(): + if line.startswith(key): + value = line.removeprefix(key).strip() + write(name, f"update reactions set value = '{value}' where key = '{key}';") + + def inp_out_reaction(name: str) -> list[str]: lines = [] diff --git a/api/s20_mixing.py b/api/s20_mixing.py index 1a9704c..6c1f580 100644 --- a/api/s20_mixing.py +++ b/api/s20_mixing.py @@ -125,6 +125,21 @@ def inp_in_mixing(section: list[str]) -> ChangeSet: return cs +def inp_in_mixing_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + tank = str(tokens[0]) + model = str(tokens[1].upper()) + value = float(tokens[3]) if num_without_desc >= 4 else None + value = value if value != None else 'null' + + write(name, f"insert into mixing (tank, model, value) values ('{tank}', '{model}', {value});") + + def inp_out_mixing(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from mixing') From 1d720c5b6c05f82f754ae7ec3c6f98d0961745a1 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 16 Mar 2023 00:15:34 +0800 Subject: [PATCH 17/39] Support inp in coord, vertex, label --- api/inp_in_new.py | 14 ++++++++------ api/s24_coordinates.py | 7 +++++++ api/s25_vertices.py | 8 ++++++++ api/s26_labels.py | 16 ++++++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index d98f727..13ff7bc 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -24,6 +24,9 @@ from .s20_mixing import inp_in_mixing_new from .s21_times import inp_in_time_new from .s22_report import inp_in_report_new from .s23_options import inp_in_option_new +from .s24_coordinates import inp_in_coord_new +from .s25_vertices import inp_in_vertex_new +from .s26_labels import inp_in_label_new from .s27_backdrop import inp_in_backdrop_new _S = 'S' @@ -53,9 +56,9 @@ _handler = { TIMES : (_S, inp_in_time_new), REPORT : (_S, inp_in_report_new), OPTIONS : (_S, inp_in_option_new), - COORDINATES : (_L, None), - VERTICES : (_L, None), - LABELS : (_L, None), + COORDINATES : (_L, inp_in_coord_new), + VERTICES : (_L, inp_in_vertex_new), + LABELS : (_L, inp_in_label_new), BACKDROP : (_S, inp_in_backdrop_new), #END : 'END', } @@ -188,13 +191,12 @@ def parse_file(project: str, inp: str) -> None: write(project, f"delete from demands where junction = '{junction}';") demand_junction = junction - if handler != None: - handler(project, line) + handler(project, line) f.seek(0) - if is_s and handler != None: + if is_s: handler(project, sections[s]) diff --git a/api/s24_coordinates.py b/api/s24_coordinates.py index aa30517..d802a2b 100644 --- a/api/s24_coordinates.py +++ b/api/s24_coordinates.py @@ -27,6 +27,13 @@ def inp_in_coord(section: list[str]) -> dict[str, dict[str, float]]: return coords +def inp_in_coord_new(name: str, line: str) -> None: + tokens = line.split() + node = tokens[0] + coord = f"'({tokens[1]}, {tokens[2]})'" + write(name, f"insert into coordinates (node, coord) values ('{node}', {coord});") + + def inp_out_coord(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from coordinates') diff --git a/api/s25_vertices.py b/api/s25_vertices.py index 932de52..2301817 100644 --- a/api/s25_vertices.py +++ b/api/s25_vertices.py @@ -98,6 +98,14 @@ def inp_in_vertex(section: list[str]) -> ChangeSet: return cs +def inp_in_vertex_new(name: str, line: str) -> None: + tokens = line.split() + link = tokens[0] + x = float(tokens[1]) + y = float(tokens[2]) + write(name, f"insert into vertices (link, x, y) values ('{link}', {x}, {y});") + + def inp_out_vertex(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from vertices order by _order") diff --git a/api/s26_labels.py b/api/s26_labels.py index 172f352..6e5f48c 100644 --- a/api/s26_labels.py +++ b/api/s26_labels.py @@ -124,6 +124,22 @@ def inp_in_label(section: list[str]) -> ChangeSet: return cs +def inp_in_label_new(name: str, line: str) -> None: + tokens = line.split() + + num = len(tokens) + has_desc = tokens[-1].startswith(';') + num_without_desc = (num - 1) if has_desc else num + + x = float(tokens[0]) + y = float(tokens[1]) + label = str(tokens[2]) + node = str(tokens[3]) if num >= 4 else None + node = f"'{node}'" if node != None else 'null' + + write(name, f"insert into labels (x, y, label, node) values ({x}, {y}, '{label}', {node});") + + def inp_out_label(name: str) -> list[str]: lines = [] objs = read_all(name, 'select * from labels') From 1d2ac09c92726edadce078404b300e53283eecaf Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 16 Mar 2023 00:39:33 +0800 Subject: [PATCH 18/39] Print time --- api/inp_in_new.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 13ff7bc..42d9cd1 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -1,3 +1,4 @@ +import datetime from .project import * from .database import ChangeSet, write, try_read from .sections import * @@ -124,7 +125,14 @@ def _get_offset(inp: str) -> dict[str, list[int]]: return offset +def print_time(desc: str) -> None: + time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + print(f"{time}: {desc}") + + def parse_file(project: str, inp: str) -> None: + print_time(f"start reading {inp}...") + offset = _get_offset(inp) levels = _level_1 + _level_2 + _level_3 + _level_4 @@ -144,6 +152,8 @@ def parse_file(project: str, inp: str) -> None: if s not in offset: continue + print_time(f"[{s}]") + is_s = _handler[s][0] == _S handler = _handler[s][1] @@ -199,6 +209,8 @@ def parse_file(project: str, inp: str) -> None: if is_s: handler(project, sections[s]) + print_time(f"end reading {inp}") + def parse_inp(project: str, inp: str) -> None: parse_file(project, inp) From 04a58bb864403752e9e0ba2be3c7b4d4b323d096 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 16 Mar 2023 08:30:04 +0800 Subject: [PATCH 19/39] Use sql batch to optimize --- api/inp_in_new.py | 94 ++++++++++++++++++++++++++++-------------- api/s10_status.py | 6 +-- api/s11_patterns.py | 6 ++- api/s12_curves.py | 4 +- api/s13_controls.py | 4 +- api/s14_rules.py | 4 +- api/s15_energy.py | 8 ++-- api/s16_emitters.py | 4 +- api/s17_quality.py | 4 +- api/s18_sources.py | 4 +- api/s19_reactions.py | 10 +++-- api/s1_title.py | 7 ++-- api/s20_mixing.py | 4 +- api/s21_times.py | 6 ++- api/s22_report.py | 4 +- api/s23_options.py | 8 ++-- api/s23_options_v3.py | 8 ++-- api/s24_coordinates.py | 4 +- api/s25_vertices.py | 4 +- api/s26_labels.py | 4 +- api/s27_backdrop.py | 7 ++-- api/s2_junctions.py | 10 +++-- api/s3_reservoirs.py | 5 +-- api/s4_tanks.py | 5 +-- api/s5_pipes.py | 5 +-- api/s6_pumps.py | 5 +-- api/s7_valves.py | 5 +-- api/s8_tags.py | 7 ++-- api/s9_demands.py | 4 +- 29 files changed, 145 insertions(+), 105 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 42d9cd1..949e904 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -13,7 +13,7 @@ from .s8_tags import inp_in_tag_new from .s9_demands import inp_in_demand_new from .s10_status import inp_in_status_new from .s11_patterns import inp_in_pattern_new -from .s12_curves import inp_in_curve_new +from .s12_curves import CURVE_TYPE_PUMP, inp_in_curve_new from .s13_controls import inp_in_control_new from .s14_rules import inp_in_rule_new from .s15_energy import inp_in_energy_new @@ -103,10 +103,12 @@ _level_4 = [ VERTICES, ] - -def _get_offset(inp: str) -> dict[str, list[int]]: +def _get_offset(inp: str) -> tuple[dict[str, list[int]], bool]: offset: dict[str, list[int]] = {} + current = '' + demand_outside = False + with open(inp) as f: while True: line = f.readline() @@ -120,20 +122,43 @@ def _get_offset(inp: str) -> dict[str, list[int]]: if s not in offset: offset[s] = [] offset[s].append(f.tell()) + current = s break + elif line != '' and line.startswith(';') == False: + if current == DEMANDS: + demand_outside = True - return offset + return (offset, demand_outside) -def print_time(desc: str) -> None: - time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') +def print_time(desc: str) -> datetime.datetime: + now = datetime.datetime.now() + time = now.strftime('%Y-%m-%d %H:%M:%S') print(f"{time}: {desc}") + return now + + +class SQLBatch: + def __init__(self, project: str, count: int = 100) -> None: + self.batch: list[str] = [] + self.project = project + self.count = count + + def add(self, sql: str) -> None: + self.batch.append(sql) + if len(self.batch) == self.count: + self.flush() + + def flush(self) -> None: + write(self.project, ''.join(self.batch)) + self.batch.clear() def parse_file(project: str, inp: str) -> None: - print_time(f"start reading {inp}...") + start = print_time(f'Start reading "{inp}"...') - offset = _get_offset(inp) + print_time("First scan...") + offset, demand_outside = _get_offset(inp) levels = _level_1 + _level_2 + _level_3 + _level_4 @@ -143,15 +168,21 @@ def parse_file(project: str, inp: str) -> None: if t[0] == _S: sections[s] = [] - pattern_desc_line = None + current_pattern = None + current_curve = None curve_type_desc_line = None - demand_junction = None + sql_batch = SQLBatch(project) + + print_time("Second scan...") with open(inp) as f: for s in levels: if s not in offset: continue + if s == DEMANDS and demand_outside == False: + continue + print_time(f"[{s}]") is_s = _handler[s][0] == _S @@ -177,39 +208,40 @@ def parse_file(project: str, inp: str) -> None: if line.startswith(';'): line = line.removeprefix(';') if s == PATTERNS: # ;desc - pattern_desc_line = line + pass elif s == CURVES: # ;type: desc curve_type_desc_line = line continue if s == PATTERNS: - if pattern_desc_line != None: - tokens = line.split() - write(project, f"insert into _pattern (id) values ('{tokens[0]}');") - pattern_desc_line = None - elif s == CURVES: - if curve_type_desc_line != None: - type_and_desc = curve_type_desc_line.split(':') - tokens = line.split() - write(project, f"insert into _curve (id, type) values ('{tokens[0]}', '{type_and_desc[0].strip()}');") - curve_type_desc_line = None - elif s == DEMANDS: tokens = line.split() - junction = str(tokens[0]) - if demand_junction != junction: - if try_read(project, f"select * from demands where junction = '{junction}'") != None: - write(project, f"delete from demands where junction = '{junction}';") - demand_junction = junction - - handler(project, line) + if current_pattern != tokens[0]: + write(project, f"insert into _pattern (id) values ('{tokens[0]}');") + current_pattern = tokens[0] + elif s == CURVES: + tokens = line.split() + if current_curve != tokens[0]: + type = CURVE_TYPE_PUMP + if curve_type_desc_line != None: + type = curve_type_desc_line.split(':')[0].strip() + write(project, f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") + current_curve = tokens[0] + curve_type_desc_line = None + if s == JUNCTIONS: + sql_batch.add(handler(line, demand_outside)) + else: + sql_batch.add(handler(line)) f.seek(0) if is_s: - handler(project, sections[s]) + sql_batch.add(handler(sections[s])) - print_time(f"end reading {inp}") + sql_batch.flush() + + end = print_time(f'End reading "{inp}"') + print(f"Total (in second): {(end-start).seconds}(s)") def parse_inp(project: str, inp: str) -> None: diff --git a/api/s10_status.py b/api/s10_status.py index 2aa1cf5..a5df564 100644 --- a/api/s10_status.py +++ b/api/s10_status.py @@ -113,7 +113,7 @@ def inp_in_status(section: list[str]) -> ChangeSet: return cs -def inp_in_status_new(name: str, line: str) -> None: +def inp_in_status_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -123,9 +123,9 @@ def inp_in_status_new(name: str, line: str) -> None: link = str(tokens[0]) value = tokens[1].upper() if value == LINK_STATUS_OPEN or value == LINK_STATUS_CLOSED or value == LINK_STATUS_ACTIVE: - write(name, f"insert into status (link, status, setting) values ('{link}', '{value}', null);") + return f"insert into status (link, status, setting) values ('{link}', '{value}', null);" else: - write(name, f"insert into status (link, status, setting) values ('{link}', null, {float(value)});") + return f"insert into status (link, status, setting) values ('{link}', null, {float(value)});" def inp_out_status(name: str) -> list[str]: diff --git a/api/s11_patterns.py b/api/s11_patterns.py index e3ac647..35e363c 100644 --- a/api/s11_patterns.py +++ b/api/s11_patterns.py @@ -126,10 +126,12 @@ def inp_in_pattern(section: list[str]) -> ChangeSet: return cs -def inp_in_pattern_new(name: str, line: str) -> None: +def inp_in_pattern_new(line: str) -> str: tokens = line.split() + sql = '' for token in tokens[1:]: - write(name, f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});") + sql += f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});" + return sql def inp_out_pattern(name: str) -> list[str]: diff --git a/api/s12_curves.py b/api/s12_curves.py index 72e91d7..968e4ce 100644 --- a/api/s12_curves.py +++ b/api/s12_curves.py @@ -159,9 +159,9 @@ def inp_in_curve(section: list[str]) -> ChangeSet: return cs -def inp_in_curve_new(name: str, line: str) -> None: +def inp_in_curve_new(line: str) -> str: tokens = line.split() - write(name, f"insert into curves (id, x, y) values ('{tokens[0]}', {float(tokens[1])}, {float(tokens[2])});") + return f"insert into curves (id, x, y) values ('{tokens[0]}', {float(tokens[1])}, {float(tokens[2])});" def inp_out_curve(name: str) -> list[str]: diff --git a/api/s13_controls.py b/api/s13_controls.py index feef31e..ee76e57 100644 --- a/api/s13_controls.py +++ b/api/s13_controls.py @@ -48,8 +48,8 @@ def inp_in_control(section: list[str]) -> ChangeSet: return ChangeSet() -def inp_in_control_new(name: str, line: str) -> None: - write(name, f"insert into controls (line) values ('{line}');") +def inp_in_control_new(line: str) -> str: + return f"insert into controls (line) values ('{line}');" def inp_out_control(name: str) -> list[str]: diff --git a/api/s14_rules.py b/api/s14_rules.py index 863711d..8535efb 100644 --- a/api/s14_rules.py +++ b/api/s14_rules.py @@ -44,8 +44,8 @@ def inp_in_rule(section: list[str]) -> ChangeSet: return ChangeSet() -def inp_in_rule_new(name: str, line: str) -> None: - write(name, f"insert into rules (line) values ('{line}');") +def inp_in_rule_new(line: str) -> str: + return f"insert into rules (line) values ('{line}');" def inp_out_rule(name: str) -> list[str]: diff --git a/api/s15_energy.py b/api/s15_energy.py index 92a5b20..866291e 100644 --- a/api/s15_energy.py +++ b/api/s15_energy.py @@ -169,7 +169,7 @@ def inp_in_energy(section: list[str]) -> ChangeSet: return cs -def inp_in_energy_new(name: str, line: str) -> None: +def inp_in_energy_new(line: str) -> str: tokens = line.split() if tokens[0].upper() == 'PUMP': @@ -183,7 +183,7 @@ def inp_in_energy_new(name: str, line: str) -> None: if key == 'efficiency': key = 'effic' - write(name, f"insert into energy_pump_{key} (pump, {key}) values ('{pump}', {value});") + return f"insert into energy_pump_{key} (pump, {key}) values ('{pump}', {value});" else: line = line.upper().strip() @@ -195,7 +195,9 @@ def inp_in_energy_new(name: str, line: str) -> None: if line.startswith('GLOBAL EFFICIENCY'): value = line.removeprefix('GLOBAL EFFICIENCY').strip() - write(name, f"update energy set value = '{value}' where key = '{key}';") + return f"update energy set value = '{value}' where key = '{key}';" + + return '' def inp_out_energy(name: str) -> list[str]: diff --git a/api/s16_emitters.py b/api/s16_emitters.py index 4c73bd7..e849075 100644 --- a/api/s16_emitters.py +++ b/api/s16_emitters.py @@ -89,7 +89,7 @@ def inp_in_emitter(section: list[str]) -> ChangeSet: return cs -def inp_in_emitter_new(name: str, line: str) -> None: +def inp_in_emitter_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -99,7 +99,7 @@ def inp_in_emitter_new(name: str, line: str) -> None: junction = str(tokens[0]) coefficient = float(tokens[1]) - write(name, f"insert into emitters (junction, coefficient) values ('{junction}', {coefficient});") + return f"insert into emitters (junction, coefficient) values ('{junction}', {coefficient});" def inp_out_emitter(name: str) -> list[str]: diff --git a/api/s17_quality.py b/api/s17_quality.py index d9868ba..63bf851 100644 --- a/api/s17_quality.py +++ b/api/s17_quality.py @@ -86,7 +86,7 @@ def inp_in_quality(section: list[str]) -> ChangeSet: return cs -def inp_in_quality_new(name: str, line: str) -> None: +def inp_in_quality_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -96,7 +96,7 @@ def inp_in_quality_new(name: str, line: str) -> None: node = str(tokens[0]) quality = float(tokens[1]) - write(name, f"insert into quality (node, quality) values ('{node}', {quality});") + return f"insert into quality (node, quality) values ('{node}', {quality});" def inp_out_quality(name: str) -> list[str]: diff --git a/api/s18_sources.py b/api/s18_sources.py index 251a01b..3c1998c 100644 --- a/api/s18_sources.py +++ b/api/s18_sources.py @@ -131,7 +131,7 @@ def inp_in_source(section: list[str]) -> ChangeSet: return cs -def inp_in_source_new(name: str, line: str) -> None: +def inp_in_source_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -144,7 +144,7 @@ def inp_in_source_new(name: str, line: str) -> None: pattern = str(tokens[3]) if num_without_desc >= 4 else None pattern = f"'{pattern}'" if pattern != None else 'null' - write(name, f"insert into sources (node, type, strength, pattern) values ('{node}', '{s_type}', {strength}, {pattern});") + return f"insert into sources (node, type, strength, pattern) values ('{node}', '{s_type}', {strength}, {pattern});" diff --git a/api/s19_reactions.py b/api/s19_reactions.py index 57e7773..563aef2 100644 --- a/api/s19_reactions.py +++ b/api/s19_reactions.py @@ -222,26 +222,28 @@ def inp_in_reaction(section: list[str]) -> ChangeSet: return cs -def inp_in_reaction_new(name: str, line: str) -> None: +def inp_in_reaction_new(line: str) -> str: tokens = line.split() token0 = tokens[0].upper() if token0 == 'BULK' or token0 == 'WALL': pipe = tokens[1] key = token0.lower() value = tokens[2] - write(name, f"insert into reactions_pipe_{key} (pipe, value) values ('{pipe}', {value});") + return f"insert into reactions_pipe_{key} (pipe, value) values ('{pipe}', {value});" elif token0 == 'TANK': tank = tokens[1] value = tokens[2] - write(name, f"insert into reactions_tank (tank, value) values ('{tank}', {value});") + return f"insert into reactions_tank (tank, value) values ('{tank}', {value});" else: line = line.upper().strip() for key in get_reaction_schema('').keys(): if line.startswith(key): value = line.removeprefix(key).strip() - write(name, f"update reactions set value = '{value}' where key = '{key}';") + return f"update reactions set value = '{value}' where key = '{key}';" + + return '' def inp_out_reaction(name: str) -> list[str]: diff --git a/api/s1_title.py b/api/s1_title.py index 7dde6c3..7076769 100644 --- a/api/s1_title.py +++ b/api/s1_title.py @@ -40,13 +40,12 @@ def inp_in_title(section: list[str]) -> ChangeSet: return ChangeSet(g_update_prefix | {'type': 'title', 'value' : obj.value}) -def inp_in_title_new(name: str, section: list[str]) -> None: +def inp_in_title_new(section: list[str]) -> str: if section == []: - return + return '' title = '\n'.join(section) - sql = f"update title set value = '{title}';" - write(name, sql) + return f"update title set value = '{title}';" def inp_out_title(name: str) -> list[str]: diff --git a/api/s20_mixing.py b/api/s20_mixing.py index 6c1f580..6c5435b 100644 --- a/api/s20_mixing.py +++ b/api/s20_mixing.py @@ -125,7 +125,7 @@ def inp_in_mixing(section: list[str]) -> ChangeSet: return cs -def inp_in_mixing_new(name: str, line: str) -> None: +def inp_in_mixing_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -137,7 +137,7 @@ def inp_in_mixing_new(name: str, line: str) -> None: value = float(tokens[3]) if num_without_desc >= 4 else None value = value if value != None else 'null' - write(name, f"insert into mixing (tank, model, value) values ('{tank}', '{model}', {value});") + return f"insert into mixing (tank, model, value) values ('{tank}', '{model}', {value});" def inp_out_mixing(name: str) -> list[str]: diff --git a/api/s21_times.py b/api/s21_times.py index 34372ed..9eec4e9 100644 --- a/api/s21_times.py +++ b/api/s21_times.py @@ -97,7 +97,8 @@ def inp_in_time(section: list[str]) -> ChangeSet: return ChangeSet() -def inp_in_time_new(name: str, section: list[str]) -> None: +def inp_in_time_new(section: list[str]) -> str: + sql = '' for s in section: if s.startswith(';'): continue @@ -106,7 +107,8 @@ def inp_in_time_new(name: str, section: list[str]) -> None: for key in get_time_schema('').keys(): if line.startswith(key): value = line.removeprefix(key).strip() - write(name, f"update times set value = '{value}' where key = '{key}';") + sql += f"update times set value = '{value}' where key = '{key}';" + return sql def inp_out_time(name: str) -> list[str]: diff --git a/api/s22_report.py b/api/s22_report.py index 73aa7e0..2bb2ad3 100644 --- a/api/s22_report.py +++ b/api/s22_report.py @@ -22,8 +22,8 @@ def inp_in_report(section: list[str]) -> ChangeSet: return ChangeSet() -def inp_in_report_new(name: str, section: list[str]) -> None: - return +def inp_in_report_new(section: list[str]) -> str: + return '' def inp_out_report(name: str) -> list[str]: diff --git a/api/s23_options.py b/api/s23_options.py index 1a02b6b..36ca03b 100644 --- a/api/s23_options.py +++ b/api/s23_options.py @@ -41,16 +41,18 @@ def inp_in_option(section: list[str]) -> ChangeSet: return result -def inp_in_option_new(name: str, section: list[str]) -> None: +def inp_in_option_new(section: list[str]) -> str: + sql = '' result = inp_in_option(section) for op in result.operations: for key in op.keys(): if key == 'operation' or key == 'type': continue if op['type'] == 'option': - write(name, f"update options set value = '{op[key]}' where key = '{key}';") + sql += f"update options set value = '{op[key]}' where key = '{key}';" else: - write(name, f"update options_v3 set value = '{op[key]}' where key = '{key}';") + sql += f"update options_v3 set value = '{op[key]}' where key = '{key}';" + return sql def inp_out_option(name: str) -> list[str]: diff --git a/api/s23_options_v3.py b/api/s23_options_v3.py index b31ff4c..888cced 100644 --- a/api/s23_options_v3.py +++ b/api/s23_options_v3.py @@ -62,16 +62,18 @@ def inp_in_option_v3(section: list[str]) -> ChangeSet: return result -def inp_in_option_v3_new(name: str, section: list[str]) -> None: +def inp_in_option_v3_new(section: list[str]) -> str: + sql = '' result = inp_in_option_v3(section) for op in result.operations: for key in op.keys(): if key == 'operation' or key == 'type': continue if op['type'] == 'option_v3': - write(name, f"update options_v3 set value = '{op[key]}' where key = '{key}';") + sql += f"update options_v3 set value = '{op[key]}' where key = '{key}';" else: - write(name, f"update options set value = '{op[key]}' where key = '{key}';") + sql += f"update options set value = '{op[key]}' where key = '{key}';" + return sql def inp_out_option_v3(name: str) -> list[str]: diff --git a/api/s24_coordinates.py b/api/s24_coordinates.py index d802a2b..2b77296 100644 --- a/api/s24_coordinates.py +++ b/api/s24_coordinates.py @@ -27,11 +27,11 @@ def inp_in_coord(section: list[str]) -> dict[str, dict[str, float]]: return coords -def inp_in_coord_new(name: str, line: str) -> None: +def inp_in_coord_new(line: str) -> str: tokens = line.split() node = tokens[0] coord = f"'({tokens[1]}, {tokens[2]})'" - write(name, f"insert into coordinates (node, coord) values ('{node}', {coord});") + return f"insert into coordinates (node, coord) values ('{node}', {coord});" def inp_out_coord(name: str) -> list[str]: diff --git a/api/s25_vertices.py b/api/s25_vertices.py index 2301817..858fb0c 100644 --- a/api/s25_vertices.py +++ b/api/s25_vertices.py @@ -98,12 +98,12 @@ def inp_in_vertex(section: list[str]) -> ChangeSet: return cs -def inp_in_vertex_new(name: str, line: str) -> None: +def inp_in_vertex_new(line: str) -> str: tokens = line.split() link = tokens[0] x = float(tokens[1]) y = float(tokens[2]) - write(name, f"insert into vertices (link, x, y) values ('{link}', {x}, {y});") + return f"insert into vertices (link, x, y) values ('{link}', {x}, {y});" def inp_out_vertex(name: str) -> list[str]: diff --git a/api/s26_labels.py b/api/s26_labels.py index 6e5f48c..e9e3b33 100644 --- a/api/s26_labels.py +++ b/api/s26_labels.py @@ -124,7 +124,7 @@ def inp_in_label(section: list[str]) -> ChangeSet: return cs -def inp_in_label_new(name: str, line: str) -> None: +def inp_in_label_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -137,7 +137,7 @@ def inp_in_label_new(name: str, line: str) -> None: node = str(tokens[3]) if num >= 4 else None node = f"'{node}'" if node != None else 'null' - write(name, f"insert into labels (x, y, label, node) values ({x}, {y}, '{label}', {node});") + return f"insert into labels (x, y, label, node) values ({x}, {y}, '{label}', {node});" def inp_out_label(name: str) -> list[str]: diff --git a/api/s27_backdrop.py b/api/s27_backdrop.py index 964e2d5..b7a7abb 100644 --- a/api/s27_backdrop.py +++ b/api/s27_backdrop.py @@ -38,13 +38,12 @@ def inp_in_backdrop(section: list[str]) -> ChangeSet: return ChangeSet() -def inp_in_backdrop_new(name: str, section: list[str]) -> None: +def inp_in_backdrop_new(section: list[str]) -> str: if section == []: - return + return '' content = '\n'.join(section) - sql = f"update backdrop set content = '{content}';" - write(name, sql) + return f"update backdrop set content = '{content}';" def inp_out_backdrop(name: str) -> list[str]: diff --git a/api/s2_junctions.py b/api/s2_junctions.py index 1a250d5..568ff6a 100644 --- a/api/s2_junctions.py +++ b/api/s2_junctions.py @@ -152,7 +152,7 @@ def inp_in_junction(section: list[str]) -> ChangeSet: return cs -def inp_in_junction_new(name: str, line: str) -> None: +def inp_in_junction_new(line: str, demand_outside: bool) -> str: tokens = line.split() num = len(tokens) @@ -166,9 +166,11 @@ def inp_in_junction_new(name: str, line: str) -> None: pattern = f"'{pattern}'" if pattern != None else 'null' desc = str(tokens[-1]) if has_desc else None - write(name, f"insert into _node (id, type) values ('{id}', 'junction');") - write(name, f"insert into junctions (id, elevation) values ('{id}', {elevation});") - write(name, f"insert into demands (junction, demand, pattern) values ('{id}', {demand}, {pattern});") + sql = f"insert into _node (id, type) values ('{id}', 'junction');insert into junctions (id, elevation) values ('{id}', {elevation});" + if demand != None and demand_outside == False: + sql += f"insert into demands (junction, demand, pattern) values ('{id}', {demand}, {pattern});" + + return sql def inp_out_junction(name: str) -> list[str]: diff --git a/api/s3_reservoirs.py b/api/s3_reservoirs.py index 2ffe9bd..22583d7 100644 --- a/api/s3_reservoirs.py +++ b/api/s3_reservoirs.py @@ -145,7 +145,7 @@ def inp_in_reservoir(section: list[str]) -> ChangeSet: return cs -def inp_in_reservoir_new(name: str, line: str) -> None: +def inp_in_reservoir_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -158,8 +158,7 @@ def inp_in_reservoir_new(name: str, line: str) -> None: pattern = f"'{pattern}'" if pattern != None else 'null' desc = str(tokens[-1]) if has_desc else None - write(name, f"insert into _node (id, type) values ('{id}', 'reservoir');") - write(name, f"insert into reservoirs (id, head, pattern) values ('{id}', {head}, {pattern});") + return f"insert into _node (id, type) values ('{id}', 'reservoir');insert into reservoirs (id, head, pattern) values ('{id}', {head}, {pattern});" def inp_out_reservoir(name: str) -> list[str]: diff --git a/api/s4_tanks.py b/api/s4_tanks.py index 0e5e1cc..198ce21 100644 --- a/api/s4_tanks.py +++ b/api/s4_tanks.py @@ -187,7 +187,7 @@ def inp_in_tank(section: list[str]) -> ChangeSet: return cs -def inp_in_tank_new(name: str, line: str) -> None: +def inp_in_tank_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -207,8 +207,7 @@ def inp_in_tank_new(name: str, line: str) -> None: overflow = f"'{overflow}'" if overflow != None else 'null' desc = str(tokens[-1]) if has_desc else None - write(name, f"insert into _node (id, type) values ('{id}', 'tank');") - write(name, f"insert into tanks (id, elevation, init_level, min_level, max_level, diameter, min_vol, vol_curve, overflow) values ('{id}', {elevation}, {init_level}, {min_level}, {max_level}, {diameter}, {min_vol}, {vol_curve}, {overflow});") + return f"insert into _node (id, type) values ('{id}', 'tank');insert into tanks (id, elevation, init_level, min_level, max_level, diameter, min_vol, vol_curve, overflow) values ('{id}', {elevation}, {init_level}, {min_level}, {max_level}, {diameter}, {min_vol}, {vol_curve}, {overflow});" def inp_out_tank(name: str) -> list[str]: diff --git a/api/s5_pipes.py b/api/s5_pipes.py index e31d57f..b7cf872 100644 --- a/api/s5_pipes.py +++ b/api/s5_pipes.py @@ -161,7 +161,7 @@ def inp_in_pipe(section: list[str]) -> ChangeSet: return cs -def inp_in_pipe_new(name: str, line: str) -> None: +def inp_in_pipe_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -179,8 +179,7 @@ def inp_in_pipe_new(name: str, line: str) -> None: status = str(tokens[7].upper()) if num_without_desc >= 8 else PIPE_STATUS_OPEN desc = str(tokens[-1]) if has_desc else None - write(name, f"insert into _link (id, type) values ('{id}', 'pipe');") - write(name, f"insert into pipes (id, node1, node2, length, diameter, roughness, minor_loss, status) values ('{id}', '{node1}', '{node2}', {length}, {diameter}, {roughness}, {minor_loss}, '{status}');") + return f"insert into _link (id, type) values ('{id}', 'pipe');insert into pipes (id, node1, node2, length, diameter, roughness, minor_loss, status) values ('{id}', '{node1}', '{node2}', {length}, {diameter}, {roughness}, {minor_loss}, '{status}');" def inp_out_pipe(name: str) -> list[str]: diff --git a/api/s6_pumps.py b/api/s6_pumps.py index 2278060..5af4bb7 100644 --- a/api/s6_pumps.py +++ b/api/s6_pumps.py @@ -151,7 +151,7 @@ def inp_in_pump(section: list[str]) -> ChangeSet: return cs -def inp_in_pump_new(name: str, line: str) -> None: +def inp_in_pump_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -174,8 +174,7 @@ def inp_in_pump_new(name: str, line: str) -> None: pattern = f"'{pattern}'" if pattern != None else 'null' desc = str(tokens[-1]) if has_desc else None - write(name, f"insert into _link (id, type) values ('{id}', 'pump');") - write(name, f"insert into pumps (id, node1, node2, power, head, speed, pattern) values ('{id}', '{node1}', '{node2}', {power}, {head}, {speed}, {pattern});") + return f"insert into _link (id, type) values ('{id}', 'pump');insert into pumps (id, node1, node2, power, head, speed, pattern) values ('{id}', '{node1}', '{node2}', {power}, {head}, {speed}, {pattern});" def inp_out_pump(name: str) -> list[str]: diff --git a/api/s7_valves.py b/api/s7_valves.py index 491b961..e1acbd8 100644 --- a/api/s7_valves.py +++ b/api/s7_valves.py @@ -157,7 +157,7 @@ def inp_in_valve(section: list[str]) -> ChangeSet: return cs -def inp_in_valve_new(name: str, line: str) -> None: +def inp_in_valve_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -173,8 +173,7 @@ def inp_in_valve_new(name: str, line: str) -> None: minor_loss = float(tokens[6]) desc = str(tokens[-1]) if has_desc else None - write(name, f"insert into _link (id, type) values ('{id}', 'valve');") - write(name, f"insert into valves (id, node1, node2, diameter, type, setting, minor_loss) values ('{id}', '{node1}', '{node2}', {diameter}, '{v_type}', '{setting}', {minor_loss});") + return f"insert into _link (id, type) values ('{id}', 'valve');insert into valves (id, node1, node2, diameter, type, setting, minor_loss) values ('{id}', '{node1}', '{node2}', {diameter}, '{v_type}', '{setting}', {minor_loss});" def inp_out_valve(name: str) -> list[str]: diff --git a/api/s8_tags.py b/api/s8_tags.py index 9ce8fd9..d65a3a4 100644 --- a/api/s8_tags.py +++ b/api/s8_tags.py @@ -103,7 +103,7 @@ def inp_in_tag(section: list[str]) -> ChangeSet: return cs -def inp_in_tag_new(name: str, line: str) -> None: +def inp_in_tag_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -115,9 +115,10 @@ def inp_in_tag_new(name: str, line: str) -> None: tag = str(tokens[2]) if t_type == TAG_TYPE_NODE: - write(name, f"insert into tags_node (id, tag) values ('{id}', '{tag}');") + return f"insert into tags_node (id, tag) values ('{id}', '{tag}');" elif t_type == TAG_TYPE_LINK: - write(name, f"insert into tags_link (id, tag) values ('{id}', '{tag}');") + return f"insert into tags_link (id, tag) values ('{id}', '{tag}');" + return '' def inp_out_tag(name: str) -> list[str]: diff --git a/api/s9_demands.py b/api/s9_demands.py index efdf098..de72099 100644 --- a/api/s9_demands.py +++ b/api/s9_demands.py @@ -97,7 +97,7 @@ def inp_in_demand(section: list[str]) -> ChangeSet: return cs -def inp_in_demand_new(name: str, line: str) -> None: +def inp_in_demand_new(line: str) -> str: tokens = line.split() num = len(tokens) @@ -111,7 +111,7 @@ def inp_in_demand_new(name: str, line: str) -> None: category = str(tokens[3]) if num_without_desc >= 4 else None category = f"'{category}'" if category != None else 'null' - write(name, f"insert into demands (junction, demand, pattern, category) values ('{junction}', {demand}, {pattern}, {category});") + return f"insert into demands (junction, demand, pattern, category) values ('{junction}', {demand}, {pattern}, {category});" def inp_out_demand(name: str) -> list[str]: From 977e706a054fc3191906f9a59330dec545522983 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 16 Mar 2023 08:30:32 +0800 Subject: [PATCH 20/39] Add any sql to batch --- api/inp_in_new.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 949e904..860dadd 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -216,7 +216,7 @@ def parse_file(project: str, inp: str) -> None: if s == PATTERNS: tokens = line.split() if current_pattern != tokens[0]: - write(project, f"insert into _pattern (id) values ('{tokens[0]}');") + sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');") current_pattern = tokens[0] elif s == CURVES: tokens = line.split() @@ -224,7 +224,7 @@ def parse_file(project: str, inp: str) -> None: type = CURVE_TYPE_PUMP if curve_type_desc_line != None: type = curve_type_desc_line.split(':')[0].strip() - write(project, f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") + sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") current_curve = tokens[0] curve_type_desc_line = None From def44d80b3f1c497ba7099be475e36fe8a9319ac Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 16 Mar 2023 19:00:08 +0800 Subject: [PATCH 21/39] Clean inp in new --- api/inp_in_new.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/api/inp_in_new.py b/api/inp_in_new.py index 860dadd..c3aad8d 100644 --- a/api/inp_in_new.py +++ b/api/inp_in_new.py @@ -1,6 +1,6 @@ import datetime from .project import * -from .database import ChangeSet, write, try_read +from .database import ChangeSet, write from .sections import * from .s1_title import inp_in_title_new from .s2_junctions import inp_in_junction_new @@ -244,10 +244,6 @@ def parse_file(project: str, inp: str) -> None: print(f"Total (in second): {(end-start).seconds}(s)") -def parse_inp(project: str, inp: str) -> None: - parse_file(project, inp) - - def read_inp_new(project: str, inp: str) -> bool: if is_project_open(project): close_project(project) @@ -258,7 +254,7 @@ def read_inp_new(project: str, inp: str) -> bool: create_project(project) open_project(project) - parse_inp(project, inp) + parse_file(project, inp) '''try: parse_inp(project, inp) From 8681a56ed76c362b7d278b3a55aba46ccea5c8d9 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Tue, 21 Mar 2023 21:08:20 +0800 Subject: [PATCH 22/39] Replace inp in file --- api/__init__.py | 1 - api/inp_in.py | 484 +++++++++++++++++++++++----------------------- api/inp_in_new.py | 282 --------------------------- tjnetwork.py | 4 +- 4 files changed, 247 insertions(+), 524 deletions(-) delete mode 100644 api/inp_in_new.py diff --git a/api/__init__.py b/api/__init__.py index 06230ad..ad08e19 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -3,7 +3,6 @@ from .project import is_project_open, get_project_open_count, open_project, clos from .project import copy_project from .inp_in import read_inp, import_inp -from .inp_in_new import read_inp_new from .inp_out import dump_inp, export_inp from .database import API_ADD, API_UPDATE, API_DELETE diff --git a/api/inp_in.py b/api/inp_in.py index a9ebb0d..f33b5ab 100644 --- a/api/inp_in.py +++ b/api/inp_in.py @@ -1,244 +1,252 @@ +import datetime +import os from .project import * -from .database import ChangeSet, get_current_operation, set_restore_operation -from .sections import section_name -from .batch_cmds import execute_batch_commands -from .s1_title import inp_in_title -from .s2_junctions import inp_in_junction -from .s3_reservoirs import inp_in_reservoir -from .s4_tanks import inp_in_tank -from .s5_pipes import inp_in_pipe -from .s6_pumps import inp_in_pump -from .s7_valves import inp_in_valve -from .s8_tags import inp_in_tag -from .s9_demands import inp_in_demand -from .s10_status import inp_in_status -from .s11_patterns import inp_in_pattern -from .s12_curves import inp_in_curve -from .s13_controls import inp_in_control -from .s14_rules import inp_in_rule -from .s15_energy import inp_in_energy -from .s16_emitters import inp_in_emitter -from .s17_quality import inp_in_quality -from .s18_sources import inp_in_source -from .s19_reactions import inp_in_reaction -from .s20_mixing import inp_in_mixing -from .s21_times import inp_in_time -from .s22_report import inp_in_report -from .s23_options import inp_in_option -from .s24_coordinates import inp_in_coord -from .s25_vertices import inp_in_vertex -from .s26_labels import inp_in_label -from .s27_backdrop import inp_in_backdrop -#from .s28_end import * +from .database import ChangeSet, write +from .sections import * +from .s1_title import inp_in_title_new +from .s2_junctions import inp_in_junction_new +from .s3_reservoirs import inp_in_reservoir_new +from .s4_tanks import inp_in_tank_new +from .s5_pipes import inp_in_pipe_new +from .s6_pumps import inp_in_pump_new +from .s7_valves import inp_in_valve_new +from .s8_tags import inp_in_tag_new +from .s9_demands import inp_in_demand_new +from .s10_status import inp_in_status_new +from .s11_patterns import inp_in_pattern_new +from .s12_curves import CURVE_TYPE_PUMP, inp_in_curve_new +from .s13_controls import inp_in_control_new +from .s14_rules import inp_in_rule_new +from .s15_energy import inp_in_energy_new +from .s16_emitters import inp_in_emitter_new +from .s17_quality import inp_in_quality_new +from .s18_sources import inp_in_source_new +from .s19_reactions import inp_in_reaction_new +from .s20_mixing import inp_in_mixing_new +from .s21_times import inp_in_time_new +from .s22_report import inp_in_report_new +from .s23_options import inp_in_option_new +from .s24_coordinates import inp_in_coord_new +from .s25_vertices import inp_in_vertex_new +from .s26_labels import inp_in_label_new +from .s27_backdrop import inp_in_backdrop_new + +_S = 'S' +_L = 'L' + +_handler = { + TITLE : (_S, inp_in_title_new), + JUNCTIONS : (_L, inp_in_junction_new), + RESERVOIRS : (_L, inp_in_reservoir_new), + TANKS : (_L, inp_in_tank_new), + PIPES : (_L, inp_in_pipe_new), + PUMPS : (_L, inp_in_pump_new), + VALVES : (_L, inp_in_valve_new), + TAGS : (_L, inp_in_tag_new), + DEMANDS : (_L, inp_in_demand_new), + STATUS : (_L, inp_in_status_new), + PATTERNS : (_L, inp_in_pattern_new), + CURVES : (_L, inp_in_curve_new), + CONTROLS : (_L, inp_in_control_new), + RULES : (_L, inp_in_rule_new), + ENERGY : (_L, inp_in_energy_new), + EMITTERS : (_L, inp_in_emitter_new), + QUALITY : (_L, inp_in_quality_new), + SOURCES : (_L, inp_in_source_new), + REACTIONS : (_L, inp_in_reaction_new), + MIXING : (_L, inp_in_mixing_new), + TIMES : (_S, inp_in_time_new), + REPORT : (_S, inp_in_report_new), + OPTIONS : (_S, inp_in_option_new), + COORDINATES : (_L, inp_in_coord_new), + VERTICES : (_L, inp_in_vertex_new), + LABELS : (_L, inp_in_label_new), + BACKDROP : (_S, inp_in_backdrop_new), + #END : 'END', +} + +_level_1 = [ + TITLE, + PATTERNS, + CURVES, + CONTROLS, + RULES, + TIMES, + REPORT, + OPTIONS, + BACKDROP, +] + +_level_2 = [ + JUNCTIONS, + RESERVOIRS, + TANKS, +] + +_level_3 = [ + PIPES, + PUMPS, + VALVES, + DEMANDS, + EMITTERS, + QUALITY, + SOURCES, + MIXING, + COORDINATES, + LABELS, +] + +_level_4 = [ + TAGS, + STATUS, + ENERGY, + REACTIONS, + VERTICES, +] -def _parse_inp(inp: str) -> dict[str, list[str]]: - file: dict[str, list[str]] = {} - for s in section_name: - file[s] = [] +class SQLBatch: + def __init__(self, project: str, count: int = 100) -> None: + self.batch: list[str] = [] + self.project = project + self.count = count - section = '' + def add(self, sql: str) -> None: + self.batch.append(sql) + if len(self.batch) == self.count: + self.flush() - for line in open(inp): - line = line.strip() - if line == '': - # skip empty line for control and rule - if section == 'CONTROLS' or section == 'RULES': - pass - else: - section = '' - continue + def flush(self) -> None: + write(self.project, ''.join(self.batch)) + self.batch.clear() - if line.startswith('['): - is_section = False - for s in section_name: - if line.startswith(f'[{s}'): - section = s - is_section = True - break - if is_section: + +def _print_time(desc: str) -> datetime.datetime: + now = datetime.datetime.now() + time = now.strftime('%Y-%m-%d %H:%M:%S') + print(f"{time}: {desc}") + return now + + +def _get_file_offset(inp: str) -> tuple[dict[str, list[int]], bool]: + offset: dict[str, list[int]] = {} + + current = '' + demand_outside = False + + with open(inp) as f: + while True: + line = f.readline() + if not line: + break + + line = line.strip() + if line.startswith('['): + for s in section_name: + if line.startswith(f'[{s}'): + if s not in offset: + offset[s] = [] + offset[s].append(f.tell()) + current = s + break + elif line != '' and line.startswith(';') == False: + if current == DEMANDS: + demand_outside = True + + return (offset, demand_outside) + + +def parse_file(project: str, inp: str) -> None: + start = _print_time(f'Start reading file "{inp}"...') + + _print_time("First scan...") + offset, demand_outside = _get_file_offset(inp) + + levels = _level_1 + _level_2 + _level_3 + _level_4 + + # parse the whole section rather than line + sections : dict[str, list[str]]= {} + for [s, t] in _handler.items(): + if t[0] == _S: + sections[s] = [] + + current_pattern = None + current_curve = None + curve_type_desc_line = None + + sql_batch = SQLBatch(project) + + _print_time("Second scan...") + with open(inp) as f: + for s in levels: + if s not in offset: continue - if section != '': - file[section].append(line) - - return file - - -def _parse_cs(cs: ChangeSet) -> dict[str, list[str]]: - file: dict[str, list[str]] = {} - for s in section_name: - file[s] = [] - - section = '' - - for line in str(cs.operations[0]['inp']).split('\n'): - line = line.strip() - if line == '': - # skip empty line for control and rule - if section == 'CONTROLS' or section == 'RULES': - pass - else: - section = '' - continue - - if line.startswith('['): - is_section = False - for s in section_name: - if line.startswith(f'[{s}'): - section = s - is_section = True - break - if is_section: + if s == DEMANDS and demand_outside == False: continue - if section != '': - file[section].append(line) + _print_time(f"[{s}]") - return file + is_s = _handler[s][0] == _S + handler = _handler[s][1] + for ptr in offset[s]: + f.seek(ptr) -def _read_inp(file: dict[str, list[str]]) -> ChangeSet: - file_cs: dict[str, ChangeSet] = {} - for s in section_name: - file_cs[s] = ChangeSet() + while True: + line = f.readline() + if not line: + break - for name, section in file.items(): - if name == 'TITLE': - file_cs[name].merge(inp_in_title(section)) - - elif name == 'JUNCTIONS': # + coords - file_cs[name].merge(inp_in_junction(section)) - - elif name == 'RESERVOIRS': # + coords - file_cs[name].merge(inp_in_reservoir(section)) - - elif name == 'TANKS': # + coords - file_cs[name].merge(inp_in_tank(section)) - - elif name == 'PIPES': - file_cs[name].merge(inp_in_pipe(section)) - - elif name == 'PUMPS': - file_cs[name].merge(inp_in_pump(section)) - - elif name == 'VALVES': - file_cs[name].merge(inp_in_valve(section)) - - elif name == 'TAGS': - file_cs[name].merge(inp_in_tag(section)) - - elif name == 'DEMANDS': - file_cs[name].merge(inp_in_demand(section)) - - elif name == 'STATUS': - file_cs[name].merge(inp_in_status(section)) - - elif name == 'PATTERNS': - file_cs[name].merge(inp_in_pattern(section)) - - elif name == 'CURVES': - file_cs[name].merge(inp_in_curve(section)) - - elif name == 'CONTROLS': - file_cs[name].merge(inp_in_control(section)) - - elif name == 'RULES': - file_cs[name].merge(inp_in_rule(section)) - - elif name == 'ENERGY': - file_cs[name].merge(inp_in_energy(section)) - - elif name == 'EMITTERS': - file_cs[name].merge(inp_in_emitter(section)) - - elif name == 'QUALITY': - file_cs[name].merge(inp_in_quality(section)) - - elif name == 'SOURCES': - file_cs[name].merge(inp_in_source(section)) - - elif name == 'REACTIONS': - file_cs[name].merge(inp_in_reaction(section)) - - elif name == 'MIXING': - file_cs[name].merge(inp_in_mixing(section)) - - elif name == 'TIMES': - file_cs[name].merge(inp_in_time(section)) - - elif name == 'REPORT': - file_cs[name].merge(inp_in_report(section)) - - elif name == 'OPTIONS': - file_cs[name].merge(inp_in_option(section)) - - elif name == 'COORDINATES': - coords = inp_in_coord(section) - for s in ['JUNCTIONS', 'RESERVOIRS', 'TANKS']: - for node in file_cs[s].operations: - if node['type'] == 'demand': + line = line.strip() + if line.startswith('['): + break + elif line == '': continue - if node['id'] in coords: - coord = coords[node['id']] - node |= { 'x' : coord['x'], 'y' : coord['y'] } + + if is_s: + sections[s].append(line) else: - print(f"WARNING: [{s}] {node['id']} has no coordinate, set it at origin!") - node |= { 'x' : 0.0, 'y' : 0.0 } + if line.startswith(';'): + line = line.removeprefix(';') + if s == PATTERNS: # ;desc + pass + elif s == CURVES: # ;type: desc + curve_type_desc_line = line + continue - elif name == 'VERTICES': - file_cs[name].merge(inp_in_vertex(section)) + if s == PATTERNS: + tokens = line.split() + if current_pattern != tokens[0]: + sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');") + current_pattern = tokens[0] + elif s == CURVES: + tokens = line.split() + if current_curve != tokens[0]: + type = CURVE_TYPE_PUMP + if curve_type_desc_line != None: + type = curve_type_desc_line.split(':')[0].strip() + sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") + current_curve = tokens[0] + curve_type_desc_line = None - elif name == 'LABELS': - file_cs[name].merge(inp_in_label(section)) + if s == JUNCTIONS: + sql_batch.add(handler(line, demand_outside)) + else: + sql_batch.add(handler(line)) - elif name == 'BACKDROP': - file_cs[name].merge(inp_in_backdrop(section)) + f.seek(0) - elif name == 'END': - pass # :) + if is_s: + sql_batch.add(handler(sections[s])) - # release file - file = {} + sql_batch.flush() - cs = ChangeSet() - priorities = [ - 'PATTERNS', - 'CURVES', - 'JUNCTIONS', - 'RESERVOIRS', - 'TANKS', - 'COORDINATES', - 'PIPES', - 'PUMPS', - 'VALVES', - 'DEMANDS', - 'STATUS', - 'OPTIONS', - 'TIMES', - 'EMITTERS', - 'QUALITY', - 'SOURCES', - 'REACTIONS', - 'MIXING', - 'ENERGY', - 'REPORT', - 'VERTICES', - 'CONTROLS', - 'RULES', - 'TITLE', - 'TAGS', - 'LABELS', - 'BACKDROP', - 'END', - ] - for s in priorities: - cs.merge(file_cs[s]) - - return cs + end = _print_time(f'End reading file "{inp}"') + print(f"Total (in second): {(end-start).seconds}(s)") -def read_inp(project: str, inp: str): +def read_inp(project: str, inp: str) -> bool: if is_project_open(project): close_project(project) @@ -248,34 +256,32 @@ def read_inp(project: str, inp: str): create_project(project) open_project(project) - file = _parse_inp(inp) - cs = _read_inp(file) - - execute_batch_commands(project, cs) - op = get_current_operation(project) - set_restore_operation(project, op) + try: + parse_file(project, inp) + except: + close_project(project) + delete_project(project) + return False close_project(project) + return True -def import_inp(project: str, cs: ChangeSet) -> ChangeSet: - if is_project_open(project): - close_project(project) +def import_inp(project: str, cs: ChangeSet) -> bool: + if 'inp' not in cs.operations[0]: + return False - if have_project(project): - delete_project(project) + filename = f'inp/{project}_temp.inp' + if os.path.exists(filename): + os.remove(filename) - create_project(project) - open_project(project) + _print_time(f'Start writing temp file "{filename}"...') + with open(filename, 'w') as f: + f.write(str(cs.operations[0]['inp'])) + _print_time(f'End writing temp file "{filename}"...') - file = _parse_cs(cs) - new_cs = _read_inp(file) + result = read_inp(project, filename) - success_cs = execute_batch_commands(project, new_cs) - op = get_current_operation(project) - set_restore_operation(project, op) + os.remove(filename) - close_project(project) - - # return ? - return success_cs + return result diff --git a/api/inp_in_new.py b/api/inp_in_new.py deleted file mode 100644 index c3aad8d..0000000 --- a/api/inp_in_new.py +++ /dev/null @@ -1,282 +0,0 @@ -import datetime -from .project import * -from .database import ChangeSet, write -from .sections import * -from .s1_title import inp_in_title_new -from .s2_junctions import inp_in_junction_new -from .s3_reservoirs import inp_in_reservoir_new -from .s4_tanks import inp_in_tank_new -from .s5_pipes import inp_in_pipe_new -from .s6_pumps import inp_in_pump_new -from .s7_valves import inp_in_valve_new -from .s8_tags import inp_in_tag_new -from .s9_demands import inp_in_demand_new -from .s10_status import inp_in_status_new -from .s11_patterns import inp_in_pattern_new -from .s12_curves import CURVE_TYPE_PUMP, inp_in_curve_new -from .s13_controls import inp_in_control_new -from .s14_rules import inp_in_rule_new -from .s15_energy import inp_in_energy_new -from .s16_emitters import inp_in_emitter_new -from .s17_quality import inp_in_quality_new -from .s18_sources import inp_in_source_new -from .s19_reactions import inp_in_reaction_new -from .s20_mixing import inp_in_mixing_new -from .s21_times import inp_in_time_new -from .s22_report import inp_in_report_new -from .s23_options import inp_in_option_new -from .s24_coordinates import inp_in_coord_new -from .s25_vertices import inp_in_vertex_new -from .s26_labels import inp_in_label_new -from .s27_backdrop import inp_in_backdrop_new - -_S = 'S' -_L = 'L' - -_handler = { - TITLE : (_S, inp_in_title_new), - JUNCTIONS : (_L, inp_in_junction_new), - RESERVOIRS : (_L, inp_in_reservoir_new), - TANKS : (_L, inp_in_tank_new), - PIPES : (_L, inp_in_pipe_new), - PUMPS : (_L, inp_in_pump_new), - VALVES : (_L, inp_in_valve_new), - TAGS : (_L, inp_in_tag_new), - DEMANDS : (_L, inp_in_demand_new), - STATUS : (_L, inp_in_status_new), - PATTERNS : (_L, inp_in_pattern_new), - CURVES : (_L, inp_in_curve_new), - CONTROLS : (_L, inp_in_control_new), - RULES : (_L, inp_in_rule_new), - ENERGY : (_L, inp_in_energy_new), - EMITTERS : (_L, inp_in_emitter_new), - QUALITY : (_L, inp_in_quality_new), - SOURCES : (_L, inp_in_source_new), - REACTIONS : (_L, inp_in_reaction_new), - MIXING : (_L, inp_in_mixing_new), - TIMES : (_S, inp_in_time_new), - REPORT : (_S, inp_in_report_new), - OPTIONS : (_S, inp_in_option_new), - COORDINATES : (_L, inp_in_coord_new), - VERTICES : (_L, inp_in_vertex_new), - LABELS : (_L, inp_in_label_new), - BACKDROP : (_S, inp_in_backdrop_new), - #END : 'END', -} - -_level_1 = [ - TITLE, - PATTERNS, - CURVES, - CONTROLS, - RULES, - TIMES, - REPORT, - OPTIONS, - BACKDROP, -] - -_level_2 = [ - JUNCTIONS, - RESERVOIRS, - TANKS, -] - -_level_3 = [ - PIPES, - PUMPS, - VALVES, - DEMANDS, - EMITTERS, - QUALITY, - SOURCES, - MIXING, - COORDINATES, - LABELS, -] - -_level_4 = [ - TAGS, - STATUS, - ENERGY, - REACTIONS, - VERTICES, -] - -def _get_offset(inp: str) -> tuple[dict[str, list[int]], bool]: - offset: dict[str, list[int]] = {} - - current = '' - demand_outside = False - - with open(inp) as f: - while True: - line = f.readline() - if not line: - break - - line = line.strip() - if line.startswith('['): - for s in section_name: - if line.startswith(f'[{s}'): - if s not in offset: - offset[s] = [] - offset[s].append(f.tell()) - current = s - break - elif line != '' and line.startswith(';') == False: - if current == DEMANDS: - demand_outside = True - - return (offset, demand_outside) - - -def print_time(desc: str) -> datetime.datetime: - now = datetime.datetime.now() - time = now.strftime('%Y-%m-%d %H:%M:%S') - print(f"{time}: {desc}") - return now - - -class SQLBatch: - def __init__(self, project: str, count: int = 100) -> None: - self.batch: list[str] = [] - self.project = project - self.count = count - - def add(self, sql: str) -> None: - self.batch.append(sql) - if len(self.batch) == self.count: - self.flush() - - def flush(self) -> None: - write(self.project, ''.join(self.batch)) - self.batch.clear() - - -def parse_file(project: str, inp: str) -> None: - start = print_time(f'Start reading "{inp}"...') - - print_time("First scan...") - offset, demand_outside = _get_offset(inp) - - levels = _level_1 + _level_2 + _level_3 + _level_4 - - # parse the whole section rather than line - sections : dict[str, list[str]]= {} - for [s, t] in _handler.items(): - if t[0] == _S: - sections[s] = [] - - current_pattern = None - current_curve = None - curve_type_desc_line = None - - sql_batch = SQLBatch(project) - - print_time("Second scan...") - with open(inp) as f: - for s in levels: - if s not in offset: - continue - - if s == DEMANDS and demand_outside == False: - continue - - print_time(f"[{s}]") - - is_s = _handler[s][0] == _S - handler = _handler[s][1] - - for ptr in offset[s]: - f.seek(ptr) - - while True: - line = f.readline() - if not line: - break - - line = line.strip() - if line.startswith('['): - break - elif line == '': - continue - - if is_s: - sections[s].append(line) - else: - if line.startswith(';'): - line = line.removeprefix(';') - if s == PATTERNS: # ;desc - pass - elif s == CURVES: # ;type: desc - curve_type_desc_line = line - continue - - if s == PATTERNS: - tokens = line.split() - if current_pattern != tokens[0]: - sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');") - current_pattern = tokens[0] - elif s == CURVES: - tokens = line.split() - if current_curve != tokens[0]: - type = CURVE_TYPE_PUMP - if curve_type_desc_line != None: - type = curve_type_desc_line.split(':')[0].strip() - sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") - current_curve = tokens[0] - curve_type_desc_line = None - - if s == JUNCTIONS: - sql_batch.add(handler(line, demand_outside)) - else: - sql_batch.add(handler(line)) - - f.seek(0) - - if is_s: - sql_batch.add(handler(sections[s])) - - sql_batch.flush() - - end = print_time(f'End reading "{inp}"') - print(f"Total (in second): {(end-start).seconds}(s)") - - -def read_inp_new(project: str, inp: str) -> bool: - if is_project_open(project): - close_project(project) - - if have_project(project): - delete_project(project) - - create_project(project) - open_project(project) - - parse_file(project, inp) - - '''try: - parse_inp(project, inp) - except: - close_project(project) - delete_project(project) - return False''' - - close_project(project) - return True - - -def import_inp_new(project: str, cs: ChangeSet) -> bool: - if is_project_open(project): - close_project(project) - - if have_project(project): - delete_project(project) - - create_project(project) - open_project(project) - - close_project(project) - - return True diff --git a/tjnetwork.py b/tjnetwork.py index 719d5c0..ade223f 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -186,12 +186,12 @@ def copy_project(source: str, new: str) -> None: return api.copy_project(source, new) def read_inp(name: str, inp: str) -> bool: - return api.read_inp_new(name, inp) + return api.read_inp(name, inp) def dump_inp(name: str, inp: str) -> None: return api.dump_inp(name, inp) -def import_inp(name: str, cs: ChangeSet) -> ChangeSet: +def import_inp(name: str, cs: ChangeSet) -> bool: return api.import_inp(name, cs) def export_inp(name: str) -> ChangeSet: From 9f9d3227b94b34b24b7152ae71d84466983e7dab Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Tue, 21 Mar 2023 21:18:53 +0800 Subject: [PATCH 23/39] Remove old inp in routine --- api/inp_in.py | 108 ++++++++++++++++++++--------------------- api/s10_status.py | 41 +--------------- api/s11_patterns.py | 28 +---------- api/s12_curves.py | 33 +------------ api/s13_controls.py | 6 +-- api/s14_rules.py | 6 +-- api/s15_energy.py | 32 +----------- api/s16_emitters.py | 23 +-------- api/s17_quality.py | 23 +-------- api/s18_sources.py | 25 +--------- api/s19_reactions.py | 30 +----------- api/s1_title.py | 15 +----- api/s20_mixing.py | 24 +-------- api/s21_times.py | 16 +----- api/s22_report.py | 4 +- api/s23_options.py | 6 +-- api/s24_coordinates.py | 11 +---- api/s25_vertices.py | 18 +------ api/s26_labels.py | 27 +---------- api/s27_backdrop.py | 14 +----- api/s2_junctions.py | 27 +---------- api/s3_reservoirs.py | 25 +--------- api/s4_tanks.py | 31 +----------- api/s5_pipes.py | 31 +----------- api/s6_pumps.py | 32 +----------- api/s7_valves.py | 29 +---------- api/s8_tags.py | 26 +--------- api/s9_demands.py | 34 +------------ 28 files changed, 83 insertions(+), 642 deletions(-) diff --git a/api/inp_in.py b/api/inp_in.py index f33b5ab..9080617 100644 --- a/api/inp_in.py +++ b/api/inp_in.py @@ -3,65 +3,65 @@ import os from .project import * from .database import ChangeSet, write from .sections import * -from .s1_title import inp_in_title_new -from .s2_junctions import inp_in_junction_new -from .s3_reservoirs import inp_in_reservoir_new -from .s4_tanks import inp_in_tank_new -from .s5_pipes import inp_in_pipe_new -from .s6_pumps import inp_in_pump_new -from .s7_valves import inp_in_valve_new -from .s8_tags import inp_in_tag_new -from .s9_demands import inp_in_demand_new -from .s10_status import inp_in_status_new -from .s11_patterns import inp_in_pattern_new -from .s12_curves import CURVE_TYPE_PUMP, inp_in_curve_new -from .s13_controls import inp_in_control_new -from .s14_rules import inp_in_rule_new -from .s15_energy import inp_in_energy_new -from .s16_emitters import inp_in_emitter_new -from .s17_quality import inp_in_quality_new -from .s18_sources import inp_in_source_new -from .s19_reactions import inp_in_reaction_new -from .s20_mixing import inp_in_mixing_new -from .s21_times import inp_in_time_new -from .s22_report import inp_in_report_new -from .s23_options import inp_in_option_new -from .s24_coordinates import inp_in_coord_new -from .s25_vertices import inp_in_vertex_new -from .s26_labels import inp_in_label_new -from .s27_backdrop import inp_in_backdrop_new +from .s1_title import inp_in_title +from .s2_junctions import inp_in_junction +from .s3_reservoirs import inp_in_reservoir +from .s4_tanks import inp_in_tank +from .s5_pipes import inp_in_pipe +from .s6_pumps import inp_in_pump +from .s7_valves import inp_in_valve +from .s8_tags import inp_in_tag +from .s9_demands import inp_in_demand +from .s10_status import inp_in_status +from .s11_patterns import inp_in_pattern +from .s12_curves import CURVE_TYPE_PUMP, inp_in_curve +from .s13_controls import inp_in_control +from .s14_rules import inp_in_rule +from .s15_energy import inp_in_energy +from .s16_emitters import inp_in_emitter +from .s17_quality import inp_in_quality +from .s18_sources import inp_in_source +from .s19_reactions import inp_in_reaction +from .s20_mixing import inp_in_mixing +from .s21_times import inp_in_time +from .s22_report import inp_in_report +from .s23_options import inp_in_option +from .s24_coordinates import inp_in_coord +from .s25_vertices import inp_in_vertex +from .s26_labels import inp_in_label +from .s27_backdrop import inp_in_backdrop _S = 'S' _L = 'L' _handler = { - TITLE : (_S, inp_in_title_new), - JUNCTIONS : (_L, inp_in_junction_new), - RESERVOIRS : (_L, inp_in_reservoir_new), - TANKS : (_L, inp_in_tank_new), - PIPES : (_L, inp_in_pipe_new), - PUMPS : (_L, inp_in_pump_new), - VALVES : (_L, inp_in_valve_new), - TAGS : (_L, inp_in_tag_new), - DEMANDS : (_L, inp_in_demand_new), - STATUS : (_L, inp_in_status_new), - PATTERNS : (_L, inp_in_pattern_new), - CURVES : (_L, inp_in_curve_new), - CONTROLS : (_L, inp_in_control_new), - RULES : (_L, inp_in_rule_new), - ENERGY : (_L, inp_in_energy_new), - EMITTERS : (_L, inp_in_emitter_new), - QUALITY : (_L, inp_in_quality_new), - SOURCES : (_L, inp_in_source_new), - REACTIONS : (_L, inp_in_reaction_new), - MIXING : (_L, inp_in_mixing_new), - TIMES : (_S, inp_in_time_new), - REPORT : (_S, inp_in_report_new), - OPTIONS : (_S, inp_in_option_new), - COORDINATES : (_L, inp_in_coord_new), - VERTICES : (_L, inp_in_vertex_new), - LABELS : (_L, inp_in_label_new), - BACKDROP : (_S, inp_in_backdrop_new), + TITLE : (_S, inp_in_title), + JUNCTIONS : (_L, inp_in_junction), + RESERVOIRS : (_L, inp_in_reservoir), + TANKS : (_L, inp_in_tank), + PIPES : (_L, inp_in_pipe), + PUMPS : (_L, inp_in_pump), + VALVES : (_L, inp_in_valve), + TAGS : (_L, inp_in_tag), + DEMANDS : (_L, inp_in_demand), + STATUS : (_L, inp_in_status), + PATTERNS : (_L, inp_in_pattern), + CURVES : (_L, inp_in_curve), + CONTROLS : (_L, inp_in_control), + RULES : (_L, inp_in_rule), + ENERGY : (_L, inp_in_energy), + EMITTERS : (_L, inp_in_emitter), + QUALITY : (_L, inp_in_quality), + SOURCES : (_L, inp_in_source), + REACTIONS : (_L, inp_in_reaction), + MIXING : (_L, inp_in_mixing), + TIMES : (_S, inp_in_time), + REPORT : (_S, inp_in_report), + OPTIONS : (_S, inp_in_option), + COORDINATES : (_L, inp_in_coord), + VERTICES : (_L, inp_in_vertex), + LABELS : (_L, inp_in_label), + BACKDROP : (_S, inp_in_backdrop), #END : 'END', } diff --git a/api/s10_status.py b/api/s10_status.py index a5df564..9aa61c4 100644 --- a/api/s10_status.py +++ b/api/s10_status.py @@ -72,48 +72,9 @@ def set_status(name: str, cs: ChangeSet) -> ChangeSet: # [EPA2][EPA3][IN][OUT] # link value #-------------------------------------------------------------- -class InpStatus: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.link = str(tokens[0]) - self.value = tokens[1].upper() - self.is_status = True - if self.value == LINK_STATUS_OPEN or self.value == LINK_STATUS_CLOSED or self.value == LINK_STATUS_ACTIVE: - self.status = str(self.value) - else: - self.setting = float(self.value) - self.is_status = False -def inp_in_status(section: list[str]) -> ChangeSet: - objs: dict[str, list[InpStatus]] = {} - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpStatus(s) - if obj.link not in objs: - objs[obj.link] = [] - objs[obj.link].append(obj) - - cs = ChangeSet() - for link, values in objs.items(): - obj_cs : dict[str, Any] = g_update_prefix | {'type': 'status', 'link' : link, 'status': None, 'setting': None} - for obj in values: - if obj.is_status: - obj_cs['status'] = obj.status - else: - obj_cs['setting'] = obj.setting - cs.append(obj_cs) - return cs - - -def inp_in_status_new(line: str) -> str: +def inp_in_status(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s11_patterns.py b/api/s11_patterns.py index 35e363c..229fbc6 100644 --- a/api/s11_patterns.py +++ b/api/s11_patterns.py @@ -98,35 +98,9 @@ def delete_pattern(name: str, cs: ChangeSet) -> ChangeSet: # ;desc # id mult1 mult2 ..... #-------------------------------------------------------------- -def inp_in_pattern(section: list[str]) -> ChangeSet: - descs = {} - patterns: dict[str, list[float]] = {} - - count = len(section) - for i in range(0, count): - if section[i].startswith(';'): - # this is description - next = i + 1 - if next < count and section[next].startswith(';') == False: - next_tokens = section[next].split() - descs[next_tokens[0]] = section[i].removeprefix(';') - continue - - tokens = section[i].split() - if tokens[0] not in patterns: - patterns[tokens[0]] = [] - for token in tokens[1:]: - patterns[tokens[0]].append(float(token)) - - cs = ChangeSet() - for id, factors in patterns.items(): - cs.append(g_add_prefix | {'type': 'pattern', 'id' : id, 'factors' : factors}) - - #print(descs) - return cs -def inp_in_pattern_new(line: str) -> str: +def inp_in_pattern(line: str) -> str: tokens = line.split() sql = '' for token in tokens[1:]: diff --git a/api/s12_curves.py b/api/s12_curves.py index 968e4ce..3adc230 100644 --- a/api/s12_curves.py +++ b/api/s12_curves.py @@ -126,40 +126,9 @@ def delete_curve(name: str, cs: ChangeSet) -> ChangeSet: # ;type: desc # id x y #-------------------------------------------------------------- -def inp_in_curve(section: list[str]) -> ChangeSet: - types = {} - descs = {} - curves: dict[str, list[dict[str, float]]] = {} - - count = len(section) - for i in range(0, count): - if section[i].startswith(';'): - # ;type: desc - type_plus_desc = section[i].removeprefix(';') - type_plus_desc_tokens = type_plus_desc.split(':') - next = i + 1 - if next < count and section[next].startswith(';') == False: - next_tokens = section[next].split() - types[next_tokens[0]] = type_plus_desc_tokens[0].strip().upper() - if len(type_plus_desc_tokens) > 1: - descs[next_tokens[0]] = type_plus_desc_tokens[1].strip() - continue - - tokens = section[i].split() - if tokens[0] not in curves: - curves[tokens[0]] = [] - curves[tokens[0]].append({'x': float(tokens[1]), 'y': float(tokens[2])}) - - cs = ChangeSet() - for id, coords in curves.items(): - c_type = types[id] if id in types else CURVE_TYPE_PUMP - cs.append(g_add_prefix | {'type': 'curve', 'id' : id, 'c_type': c_type, 'coords' : coords}) - - #print(descs) - return cs -def inp_in_curve_new(line: str) -> str: +def inp_in_curve(line: str) -> str: tokens = line.split() return f"insert into curves (id, x, y) values ('{tokens[0]}', {float(tokens[1])}, {float(tokens[2])});" diff --git a/api/s13_controls.py b/api/s13_controls.py index ee76e57..8f50de4 100644 --- a/api/s13_controls.py +++ b/api/s13_controls.py @@ -42,13 +42,9 @@ def set_control(name: str, cs: ChangeSet) -> ChangeSet: # (0) (1) (2) (3) (4) (5) (6) (7) # todo... #-------------------------------------------------------------- -def inp_in_control(section: list[str]) -> ChangeSet: - if len(section) > 0: - return ChangeSet(g_update_prefix | {'type': 'control', 'controls' : section}) - return ChangeSet() -def inp_in_control_new(line: str) -> str: +def inp_in_control(line: str) -> str: return f"insert into controls (line) values ('{line}');" diff --git a/api/s14_rules.py b/api/s14_rules.py index 8535efb..49a47cf 100644 --- a/api/s14_rules.py +++ b/api/s14_rules.py @@ -38,13 +38,9 @@ def set_rule(name: str, cs: ChangeSet) -> ChangeSet: # [EPA2][EPA3] # TODO... #-------------------------------------------------------------- -def inp_in_rule(section: list[str]) -> ChangeSet: - if len(section) > 0: - return ChangeSet(g_update_prefix | {'type': 'rule', 'rules' : section}) - return ChangeSet() -def inp_in_rule_new(line: str) -> str: +def inp_in_rule(line: str) -> str: return f"insert into rules (line) values ('{line}');" diff --git a/api/s15_energy.py b/api/s15_energy.py index 866291e..8bca11b 100644 --- a/api/s15_energy.py +++ b/api/s15_energy.py @@ -137,39 +137,9 @@ def set_pump_energy(name: str, cs: ChangeSet) -> ChangeSet: # PUMP id {PRICE/PATTERN/EFFIC} value # DEMAND CHARGE value #-------------------------------------------------------------- -def inp_in_energy(section: list[str]) -> ChangeSet: - cs = ChangeSet() - - for s in section: - if s.startswith(';'): - continue - - tokens = s.strip().split() - - if tokens[0].upper() == 'PUMP': - pump = tokens[1] - key = tokens[2].lower() - value = tokens[3] - if key == 'price': - value = float(value) - cs.append(g_update_prefix | { 'type' : 'pump_energy', 'pump' : pump, key: value }) - - else: - line = s.upper().strip() - for key in get_energy_schema('').keys(): - if line.startswith(key): - value = line.removeprefix(key).strip() - - # exception here - if line.startswith('GLOBAL EFFICIENCY'): - value = line.removeprefix('GLOBAL EFFICIENCY').strip() - - cs.append(g_update_prefix | { 'type' : 'energy', key : value }) - - return cs -def inp_in_energy_new(line: str) -> str: +def inp_in_energy(line: str) -> str: tokens = line.split() if tokens[0].upper() == 'PUMP': diff --git a/api/s16_emitters.py b/api/s16_emitters.py index e849075..ee88df4 100644 --- a/api/s16_emitters.py +++ b/api/s16_emitters.py @@ -66,30 +66,9 @@ def set_emitter(name: str, cs: ChangeSet) -> ChangeSet: # [EPA3][IN][OUT] # node Ke (exponent pattern) #-------------------------------------------------------------- -class InpEmitter: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.junction = str(tokens[0]) - self.coefficient = float(tokens[1]) -def inp_in_emitter(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpEmitter(s) - cs.append(g_update_prefix | {'type': 'emitter', 'junction': obj.junction, 'coefficient': obj.coefficient}) - return cs - - -def inp_in_emitter_new(line: str) -> str: +def inp_in_emitter(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s17_quality.py b/api/s17_quality.py index 63bf851..a524e0c 100644 --- a/api/s17_quality.py +++ b/api/s17_quality.py @@ -63,30 +63,9 @@ def set_quality(name: str, cs: ChangeSet) -> ChangeSet: # [EPA2][EPA3][IN][OUT] # node initqual #-------------------------------------------------------------- -class InpQuality: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.node = str(tokens[0]) - self.quality = float(tokens[1]) -def inp_in_quality(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpQuality(s) - cs.append(g_update_prefix | {'type': 'quality', 'node': obj.node, 'quality': obj.quality}) - return cs - - -def inp_in_quality_new(line: str) -> str: +def inp_in_quality(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s18_sources.py b/api/s18_sources.py index 3c1998c..dcc4db9 100644 --- a/api/s18_sources.py +++ b/api/s18_sources.py @@ -106,32 +106,9 @@ def delete_source(name: str, cs: ChangeSet) -> ChangeSet: # [EPA2][EPA3][IN][OUT] # node sourcetype quality (pattern) #-------------------------------------------------------------- -class InpSource: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.node = str(tokens[0]) - self.s_type = str(tokens[1].upper()) - self.strength = float(tokens[2]) - self.pattern = str(tokens[3]) if num_without_desc >= 4 else None -def inp_in_source(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpSource(s) - cs.append(g_add_prefix | {'type': 'source', 'node': obj.node, 's_type': obj.s_type, 'strength': obj.strength, 'pattern': obj.pattern}) - return cs - - -def inp_in_source_new(line: str) -> str: +def inp_in_source(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s19_reactions.py b/api/s19_reactions.py index 563aef2..19b9c3f 100644 --- a/api/s19_reactions.py +++ b/api/s19_reactions.py @@ -192,37 +192,9 @@ def set_tank_reaction(name: str, cs: ChangeSet) -> ChangeSet: # LIMITING POTENTIAL value # ROUGHNESS CORRELATION value #-------------------------------------------------------------- -def inp_in_reaction(section: list[str]) -> ChangeSet: - cs = ChangeSet() - - for s in section: - if s.startswith(';'): - continue - - tokens = s.strip().split() - token0 = tokens[0].upper() - if token0 == 'BULK' or token0 == 'WALL': - pipe = tokens[1] - key = token0.lower() - value = tokens[2] - cs.append(g_update_prefix | { 'type' : 'pipe_reaction', 'pipe' : pipe, key: value }) - - elif token0 == 'TANK': - tank = tokens[1] - value = tokens[2] - cs.append(g_update_prefix | { 'type' : 'tank_reaction', 'tank' : tank, 'value': value }) - - else: - line = s.upper().strip() - for key in get_reaction_schema('').keys(): - if line.startswith(key): - value = line.removeprefix(key).strip() - cs.append(g_update_prefix | { 'type' : 'reaction', key : value }) - - return cs -def inp_in_reaction_new(line: str) -> str: +def inp_in_reaction(line: str) -> str: tokens = line.split() token0 = tokens[0].upper() if token0 == 'BULK' or token0 == 'WALL': diff --git a/api/s1_title.py b/api/s1_title.py index 7076769..c897c62 100644 --- a/api/s1_title.py +++ b/api/s1_title.py @@ -27,20 +27,7 @@ def set_title(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, set_title_cmd(name ,cs)) -class InpTitle: - def __init__(self, section) -> None: - self.value = '\n'.join(section) - - -def inp_in_title(section: list[str]) -> ChangeSet: - if section == []: - return ChangeSet() - - obj = InpTitle(section) - return ChangeSet(g_update_prefix | {'type': 'title', 'value' : obj.value}) - - -def inp_in_title_new(section: list[str]) -> str: +def inp_in_title(section: list[str]) -> str: if section == []: return '' diff --git a/api/s20_mixing.py b/api/s20_mixing.py index 6c5435b..1a43465 100644 --- a/api/s20_mixing.py +++ b/api/s20_mixing.py @@ -101,31 +101,9 @@ def delete_mixing(name: str, cs: ChangeSet) -> ChangeSet: # TankID MixModel FractVolume # FractVolume if type == MIX2 #-------------------------------------------------------------- -class InpMixing: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.tank = str(tokens[0]) - self.model = str(tokens[1].upper()) - self.value = float(tokens[3]) if num_without_desc >= 4 else None -def inp_in_mixing(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpMixing(s) - cs.append(g_add_prefix | {'type': 'mixing', 'tank': obj.tank, 'model': obj.model, 'value': obj.value}) - return cs - - -def inp_in_mixing_new(line: str) -> str: +def inp_in_mixing(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s21_times.py b/api/s21_times.py index 9eec4e9..590e91d 100644 --- a/api/s21_times.py +++ b/api/s21_times.py @@ -81,23 +81,9 @@ def set_time(name: str, cs: ChangeSet) -> ChangeSet: # START CLOCKTIME value (AM PM) # [EPA3] supports [EPA2] keyword #-------------------------------------------------------------- -def inp_in_time(section: list[str]) -> ChangeSet: - if len(section) > 0: - cs = g_update_prefix | { 'type' : 'time' } - for s in section: - if s.startswith(';'): - continue - - line = s.upper().strip() - for key in get_time_schema('').keys(): - if line.startswith(key): - value = line.removeprefix(key).strip() - cs |= { key : value } - return ChangeSet(cs) - return ChangeSet() -def inp_in_time_new(section: list[str]) -> str: +def inp_in_time(section: list[str]) -> str: sql = '' for s in section: if s.startswith(';'): diff --git a/api/s22_report.py b/api/s22_report.py index 2bb2ad3..02b675b 100644 --- a/api/s22_report.py +++ b/api/s22_report.py @@ -18,11 +18,9 @@ from .database import * # [EPA3][NOT SUPPORT] # TRIALS {YES/NO} #-------------------------------------------------------------- -def inp_in_report(section: list[str]) -> ChangeSet: - return ChangeSet() -def inp_in_report_new(section: list[str]) -> str: +def inp_in_report(section: list[str]) -> str: return '' diff --git a/api/s23_options.py b/api/s23_options.py index 36ca03b..6748f76 100644 --- a/api/s23_options.py +++ b/api/s23_options.py @@ -11,7 +11,7 @@ def set_option(name: str, cs: ChangeSet) -> ChangeSet: return execute_batch_command(name, new_cs) -def inp_in_option(section: list[str]) -> ChangeSet: +def _inp_in_option(section: list[str]) -> ChangeSet: if len(section) <= 0: return ChangeSet() @@ -41,9 +41,9 @@ def inp_in_option(section: list[str]) -> ChangeSet: return result -def inp_in_option_new(section: list[str]) -> str: +def inp_in_option(section: list[str]) -> str: sql = '' - result = inp_in_option(section) + result = _inp_in_option(section) for op in result.operations: for key in op.keys(): if key == 'operation' or key == 'type': diff --git a/api/s24_coordinates.py b/api/s24_coordinates.py index 2b77296..0df02db 100644 --- a/api/s24_coordinates.py +++ b/api/s24_coordinates.py @@ -16,18 +16,9 @@ def get_node_coord(name: str, id: str) -> dict[str, float]: # id x y #-------------------------------------------------------------- # exception ! need merge to node change set ! -def inp_in_coord(section: list[str]) -> dict[str, dict[str, float]]: - coords = {} - for s in section: - # skip comment - if s.startswith(';'): - continue - tokens = s.split() - coords[tokens[0]] = { 'x': tokens[1], 'y': tokens[2] } - return coords -def inp_in_coord_new(line: str) -> str: +def inp_in_coord(line: str) -> str: tokens = line.split() node = tokens[0] coord = f"'({tokens[1]}, {tokens[2]})'" diff --git a/api/s25_vertices.py b/api/s25_vertices.py index 858fb0c..96c381c 100644 --- a/api/s25_vertices.py +++ b/api/s25_vertices.py @@ -80,25 +80,9 @@ def delete_vertex(name: str, cs: ChangeSet) -> ChangeSet: # id x y # [EPA3][NOT SUPPORT] #-------------------------------------------------------------- -def inp_in_vertex(section: list[str]) -> ChangeSet: - vertices: dict[str, list[dict[str, float]]] = {} - - for s in section: - if s.startswith(';'): - continue - - tokens = s.split() - if tokens[0] not in vertices: - vertices[tokens[0]] = [] - vertices[tokens[0]].append({'x': float(tokens[1]), 'y': float(tokens[2])}) - - cs = ChangeSet() - for link, coords in vertices.items(): - cs.append(g_add_prefix | {'type': 'vertex', 'link' : link, 'coords' : coords}) - return cs -def inp_in_vertex_new(line: str) -> str: +def inp_in_vertex(line: str) -> str: tokens = line.split() link = tokens[0] x = float(tokens[1]) diff --git a/api/s26_labels.py b/api/s26_labels.py index e9e3b33..437bc0e 100644 --- a/api/s26_labels.py +++ b/api/s26_labels.py @@ -99,32 +99,7 @@ def delete_label(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, delete_label_cmd(name, cs)) -class InpLabel: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.x = float(tokens[0]) - self.y = float(tokens[1]) - self.label = str(tokens[2]) - self.node = str(tokens[3]) if num >= 4 else None - - -def inp_in_label(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpLabel(s) - cs.append(g_add_prefix | {'type': 'label', 'x': obj.x, 'y': obj.y, 'label': obj.label, 'node': obj.node}) - return cs - - -def inp_in_label_new(line: str) -> str: +def inp_in_label(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s27_backdrop.py b/api/s27_backdrop.py index b7a7abb..9766948 100644 --- a/api/s27_backdrop.py +++ b/api/s27_backdrop.py @@ -26,19 +26,7 @@ def set_backdrop(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, set_backdrop_cmd(name, cs)) -class InpBackdrop: - def __init__(self, section) -> None: - self.value = '\n'.join(section) - - -def inp_in_backdrop(section: list[str]) -> ChangeSet: - if len(section) > 0: - obj = InpBackdrop(section) - return ChangeSet(g_update_prefix | {'type': 'backdrop', 'content' : obj.value}) - return ChangeSet() - - -def inp_in_backdrop_new(section: list[str]) -> str: +def inp_in_backdrop(section: list[str]) -> str: if section == []: return '' diff --git a/api/s2_junctions.py b/api/s2_junctions.py index 568ff6a..68e6a48 100644 --- a/api/s2_junctions.py +++ b/api/s2_junctions.py @@ -125,34 +125,9 @@ def delete_junction(name: str, cs: ChangeSet) -> ChangeSet: # [OUT] # id elev. * * minpressure fullpressure #-------------------------------------------------------------- -class InpJunction: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.id = str(tokens[0]) - self.elevation = float(tokens[1]) - self.demand = float(tokens[2]) if num_without_desc >= 3 else None - self.pattern = str(tokens[3]) if num_without_desc >= 4 else None - self.desc = str(tokens[-1]) if has_desc else None -def inp_in_junction(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpJunction(s) - cs.append(g_add_prefix | {'type': 'junction', 'id': obj.id, 'elevation': obj.elevation, 'demand': obj.demand, 'pattern': obj.pattern}) - cs.append(g_update_prefix | { 'type': 'demand', 'junction': obj.id, 'demands': [{'demand': obj.demand, 'pattern': obj.pattern, 'category': None}] }) - return cs - - -def inp_in_junction_new(line: str, demand_outside: bool) -> str: +def inp_in_junction(line: str, demand_outside: bool) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s3_reservoirs.py b/api/s3_reservoirs.py index 22583d7..caf8a53 100644 --- a/api/s3_reservoirs.py +++ b/api/s3_reservoirs.py @@ -120,32 +120,9 @@ def delete_reservoir(name: str, cs: ChangeSet) -> ChangeSet: # [EPA2][EPA3][IN][OUT] # id elev (pattern) ;desc #-------------------------------------------------------------- -class InpReservoir: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.id = str(tokens[0]) - self.head = float(tokens[1]) - self.pattern = str(tokens[2]) if num_without_desc >= 3 else None - self.desc = str(tokens[-1]) if has_desc else None -def inp_in_reservoir(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpReservoir(s) - cs.append(g_add_prefix | {'type': 'reservoir', 'id': obj.id, 'head': obj.head, 'pattern': obj.pattern}) - return cs - - -def inp_in_reservoir_new(line: str) -> str: +def inp_in_reservoir(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s4_tanks.py b/api/s4_tanks.py index 198ce21..688e28a 100644 --- a/api/s4_tanks.py +++ b/api/s4_tanks.py @@ -156,38 +156,9 @@ def delete_tank(name: str, cs: ChangeSet) -> ChangeSet: # [EPA3] # id elev initlevel minlevel maxlevel diam minvol (vcurve) #-------------------------------------------------------------- -class InpTank: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.id = str(tokens[0]) - self.elevation = float(tokens[1]) - self.init_level = float(tokens[2]) - self.min_level = float(tokens[3]) - self.max_level = float(tokens[4]) - self.diameter = float(tokens[5]) - self.min_vol = float(tokens[6]) if num_without_desc >= 7 else 0.0 - self.vol_curve = str(tokens[7]) if num_without_desc >= 8 and tokens[7] != '*' else None - self.overflow = str(tokens[8].upper()) if num_without_desc >= 9 else None - self.desc = str(tokens[-1]) if has_desc else None -def inp_in_tank(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpTank(s) - cs.append(g_add_prefix | {'type': 'tank', 'id': obj.id, 'elevation': obj.elevation, 'init_level': obj.init_level, 'min_level': obj.min_level, 'max_level': obj.max_level, 'diameter': obj.diameter, 'min_vol': obj.min_vol, 'vol_curve': obj.vol_curve, 'overflow': obj.overflow}) - return cs - - -def inp_in_tank_new(line: str) -> str: +def inp_in_tank(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s5_pipes.py b/api/s5_pipes.py index b7cf872..e9a40a5 100644 --- a/api/s5_pipes.py +++ b/api/s5_pipes.py @@ -130,38 +130,9 @@ def delete_pipe(name: str, cs: ChangeSet) -> ChangeSet: # [OUT] # id node1 node2 length diam rcoeff lcoeff (status) ;desc #-------------------------------------------------------------- -class InpPipe: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.id = str(tokens[0]) - self.node1 = str(tokens[1]) - self.node2 = str(tokens[2]) - self.length = float(tokens[3]) - self.diameter = float(tokens[4]) - self.roughness = float(tokens[5]) - self.minor_loss = float(tokens[6]) - # status is must-have, here fix input - self.status = str(tokens[7].upper()) if num_without_desc >= 8 else PIPE_STATUS_OPEN - self.desc = str(tokens[-1]) if has_desc else None -def inp_in_pipe(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpPipe(s) - cs.append(g_add_prefix | {'type': 'pipe', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'length': obj.length, 'diameter': obj.diameter, 'roughness': obj.roughness, 'minor_loss': obj.minor_loss, 'status': obj.status}) - return cs - - -def inp_in_pipe_new(line: str) -> str: +def inp_in_pipe(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s6_pumps.py b/api/s6_pumps.py index 5af4bb7..1fb06da 100644 --- a/api/s6_pumps.py +++ b/api/s6_pumps.py @@ -119,39 +119,9 @@ def delete_pump(name: str, cs: ChangeSet) -> ChangeSet: # id node1 node2 KEYWORD value {KEYWORD value ...} ;desc # where KEYWORD = [POWER,HEAD,PATTERN,SPEED] #-------------------------------------------------------------- -class InpPump: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.id = str(tokens[0]) - self.node1 = str(tokens[1]) - self.node2 = str(tokens[2]) - self.props = {} - for i in range(3, num_without_desc, 2): - self.props |= { tokens[i].lower(): tokens[i + 1] } - self.power = float(self.props['power']) if 'power' in self.props else None - self.head = str(self.props['head']) if 'head' in self.props else None - self.speed = float(self.props['speed']) if 'speed' in self.props else None - self.pattern = str(self.props['pattern']) if 'pattern' in self.props else None - self.desc = str(tokens[-1]) if has_desc else None -def inp_in_pump(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpPump(s) - cs.append(g_add_prefix | {'type': 'pump', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'power': obj.power, 'head': obj.head, 'speed': obj.speed, 'pattern': obj.pattern}) - return cs - - -def inp_in_pump_new(line: str) -> str: +def inp_in_pump(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s7_valves.py b/api/s7_valves.py index e1acbd8..5ab210b 100644 --- a/api/s7_valves.py +++ b/api/s7_valves.py @@ -128,36 +128,9 @@ def delete_valve(name: str, cs: ChangeSet) -> ChangeSet: # for GPV, setting is string = head curve id # [NOT SUPPORT] for PCV, add loss curve if present #-------------------------------------------------------------- -class InpValve: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.id = str(tokens[0]) - self.node1 = str(tokens[1]) - self.node2 = str(tokens[2]) - self.diameter = float(tokens[3]) - self.v_type = str(tokens[4].upper()) - self.setting = str(tokens[5]) - self.minor_loss = float(tokens[6]) - self.desc = str(tokens[-1]) if has_desc else None -def inp_in_valve(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpValve(s) - cs.append(g_add_prefix | {'type': 'valve', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'diameter': obj.diameter, 'v_type': obj.v_type, 'setting': obj.setting, 'minor_loss': obj.minor_loss}) - return cs - - -def inp_in_valve_new(line: str) -> str: +def inp_in_valve(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s8_tags.py b/api/s8_tags.py index d65a3a4..8ae4a5d 100644 --- a/api/s8_tags.py +++ b/api/s8_tags.py @@ -79,31 +79,7 @@ def set_tag(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, set_tag_cmd(name, cs)) -class InpTag: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.t_type = str(tokens[0].upper()) - self.id = str(tokens[1]) - self.tag = str(tokens[2]) - - -def inp_in_tag(section: list[str]) -> ChangeSet: - cs = ChangeSet() - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpTag(s) - cs.append(g_update_prefix | {'type': 'tag', 't_type': obj.t_type, 'id': obj.id, 'tag': obj.tag}) - return cs - - -def inp_in_tag_new(line: str) -> str: +def inp_in_tag(line: str) -> str: tokens = line.split() num = len(tokens) diff --git a/api/s9_demands.py b/api/s9_demands.py index de72099..e1465e4 100644 --- a/api/s9_demands.py +++ b/api/s9_demands.py @@ -63,41 +63,9 @@ def set_demand(name: str, cs: ChangeSet) -> ChangeSet: # [EPA2][EPA3][IN][OUT] # node base_demand (pattern) ;category #-------------------------------------------------------------- -class InpDemand: - def __init__(self, line: str) -> None: - tokens = line.split() - - num = len(tokens) - has_desc = tokens[-1].startswith(';') - num_without_desc = (num - 1) if has_desc else num - - self.junction = str(tokens[0]) - self.demand = float(tokens[1]) - self.pattern = str(tokens[2]) if num_without_desc >= 3 else None - self.category = str(tokens[3]) if num_without_desc >= 4 else None -def inp_in_demand(section: list[str]) -> ChangeSet: - objs: dict[str, list[InpDemand]] = {} - for s in section: - # skip comment - if s.startswith(';'): - continue - obj = InpDemand(s) - if obj.junction not in objs: - objs[obj.junction] = [] - objs[obj.junction].append(obj) - - cs = ChangeSet() - for junction, demands in objs.items(): - obj_cs : dict[str, Any] = g_update_prefix | {'type': 'demand', 'junction' : junction, 'demands' : []} - for obj in demands: - obj_cs['demands'].append({'demand': obj.demand, 'pattern' : obj.pattern, 'category': obj.category}) - cs.append(obj_cs) - return cs - - -def inp_in_demand_new(line: str) -> str: +def inp_in_demand(line: str) -> str: tokens = line.split() num = len(tokens) From 6ed7e00e031a70aeb1e9bde56cf4010523cce012 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Tue, 21 Mar 2023 21:19:09 +0800 Subject: [PATCH 24/39] Build all database --- build_db.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build_db.py b/build_db.py index 83862d9..cb764c0 100644 --- a/build_db.py +++ b/build_db.py @@ -1,14 +1,14 @@ from tjnetwork import * files = [ - #'bwsn', - #'exnet', - #'fengxian', - #'jbh', - #'nanjing', + 'bwsn', + 'exnet', + 'fengxian', + 'jbh', + 'nanjing', 'net3', - #'zj', - #'suzhouhe', + 'zj', + 'suzhouhe', ] def inp2db(): From 398ba0910621bdcf2d2d6fbd58ab8e8c54d08c6e Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Tue, 21 Mar 2023 21:29:33 +0800 Subject: [PATCH 25/39] Start to support version read/write --- api/inp_in.py | 4 ++-- api/inp_out.py | 4 ++-- tjnetwork.py | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/api/inp_in.py b/api/inp_in.py index 9080617..e43cc04 100644 --- a/api/inp_in.py +++ b/api/inp_in.py @@ -246,7 +246,7 @@ def parse_file(project: str, inp: str) -> None: print(f"Total (in second): {(end-start).seconds}(s)") -def read_inp(project: str, inp: str) -> bool: +def read_inp(project: str, inp: str, version: str = '3') -> bool: if is_project_open(project): close_project(project) @@ -267,7 +267,7 @@ def read_inp(project: str, inp: str) -> bool: return True -def import_inp(project: str, cs: ChangeSet) -> bool: +def import_inp(project: str, cs: ChangeSet, version: str = '3') -> bool: if 'inp' not in cs.operations[0]: return False diff --git a/api/inp_out.py b/api/inp_out.py index 015556b..d6a5774 100644 --- a/api/inp_out.py +++ b/api/inp_out.py @@ -32,7 +32,7 @@ from .s27_backdrop import inp_out_backdrop #from .s28_end import * -def dump_inp(project: str, inp: str): +def dump_inp(project: str, inp: str, version: str = '3'): if not have_project(project): return @@ -144,7 +144,7 @@ def dump_inp(project: str, inp: str): close_project(project) -def export_inp(project: str) -> ChangeSet: +def export_inp(project: str, version: str = '3') -> ChangeSet: if not have_project(project): return ChangeSet() diff --git a/tjnetwork.py b/tjnetwork.py index ade223f..75ddf32 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -185,17 +185,17 @@ def close_project(name: str) -> None: def copy_project(source: str, new: str) -> None: return api.copy_project(source, new) -def read_inp(name: str, inp: str) -> bool: - return api.read_inp(name, inp) +def read_inp(name: str, inp: str, version: str = '3') -> bool: + return api.read_inp(name, inp, version) -def dump_inp(name: str, inp: str) -> None: - return api.dump_inp(name, inp) +def dump_inp(name: str, inp: str, version: str = '3') -> None: + return api.dump_inp(name, inp, version) -def import_inp(name: str, cs: ChangeSet) -> bool: - return api.import_inp(name, cs) +def import_inp(name: str, cs: ChangeSet, version: str = '3') -> bool: + return api.import_inp(name, cs, version) -def export_inp(name: str) -> ChangeSet: - return api.export_inp(name) +def export_inp(name: str, version: str = '3') -> ChangeSet: + return api.export_inp(name, version) def run_project(name: str) -> str: return epanet.run_project(name) From 0fc34ae1fff87ac417e5c48cf3722659b738329a Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 12:18:07 +0800 Subject: [PATCH 26/39] Comment out pattern and curve v3 version --- api/s11_patterns.py | 18 +++++++++--------- api/s12_curves.py | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/api/s11_patterns.py b/api/s11_patterns.py index 229fbc6..77976f9 100644 --- a/api/s11_patterns.py +++ b/api/s11_patterns.py @@ -98,6 +98,13 @@ def delete_pattern(name: str, cs: ChangeSet) -> ChangeSet: # ;desc # id mult1 mult2 ..... #-------------------------------------------------------------- +#-------------------------------------------------------------- +# [EPA3][IN][OUT] +# id FIXED (interval) +# id factor1 factor2 ... +# id VARIABLE +# id time1 factor1 time2 factor2 ... +#-------------------------------------------------------------- def inp_in_pattern(line: str) -> str: @@ -118,14 +125,7 @@ def inp_out_pattern(name: str) -> list[str]: return lines -#-------------------------------------------------------------- -# [EPA3][IN][OUT] -# id FIXED (interval) -# id factor1 factor2 ... -# id VARIABLE -# id time1 factor1 time2 factor2 ... -#-------------------------------------------------------------- -def inp_in_pattern_v3(section: list[str]) -> ChangeSet: +'''def inp_in_pattern_v3(section: list[str]) -> ChangeSet: patterns: dict[str, list[float]] = {} variable_patterns: list[str] = [] @@ -158,7 +158,7 @@ def inp_in_pattern_v3(section: list[str]) -> ChangeSet: cs.append(g_add_prefix | {'type': 'pattern', 'id' : id, 'factors' : factors}) #print(descs) - return cs + return cs''' def inp_out_pattern_v3(name: str) -> list[str]: diff --git a/api/s12_curves.py b/api/s12_curves.py index 3adc230..fe297dc 100644 --- a/api/s12_curves.py +++ b/api/s12_curves.py @@ -126,6 +126,11 @@ def delete_curve(name: str, cs: ChangeSet) -> ChangeSet: # ;type: desc # id x y #-------------------------------------------------------------- +#-------------------------------------------------------------- +# [EPA3][IN][OUT] +# id type +# id x y +#-------------------------------------------------------------- def inp_in_curve(line: str) -> str: @@ -149,12 +154,7 @@ def inp_out_curve(name: str) -> list[str]: return lines -#-------------------------------------------------------------- -# [EPA3][IN][OUT] -# id type -# id x y -#-------------------------------------------------------------- -def inp_in_curve_v3(section: list[str]) -> ChangeSet: +'''def inp_in_curve_v3(section: list[str]) -> ChangeSet: types = {} curves: dict[str, list[dict[str, float]]] = {} @@ -180,7 +180,7 @@ def inp_in_curve_v3(section: list[str]) -> ChangeSet: cs.append(g_add_prefix | {'type': 'curve', 'id' : id, 'c_type': c_type, 'coords' : coords}) #print(descs) - return cs + return cs''' def inp_out_curve_v3(name: str) -> list[str]: From e18c50406723e37f0bd805c9d7d0bea60ba769eb Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 12:19:43 +0800 Subject: [PATCH 27/39] Support option v3 --- api/s23_options_v3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/s23_options_v3.py b/api/s23_options_v3.py index 888cced..cabf6cf 100644 --- a/api/s23_options_v3.py +++ b/api/s23_options_v3.py @@ -31,7 +31,7 @@ def _parse_v2(v2_lines: list[str]) -> dict[str, str]: return cs_v2 -def inp_in_option_v3(section: list[str]) -> ChangeSet: +def _inp_in_option_v3(section: list[str]) -> ChangeSet: if len(section) <= 0: return ChangeSet() @@ -62,9 +62,9 @@ def inp_in_option_v3(section: list[str]) -> ChangeSet: return result -def inp_in_option_v3_new(section: list[str]) -> str: +def inp_in_option_v3(section: list[str]) -> str: sql = '' - result = inp_in_option_v3(section) + result = _inp_in_option_v3(section) for op in result.operations: for key in op.keys(): if key == 'operation' or key == 'type': From faec3cef739a1c9ef06a4babb43296879b4304d6 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 12:26:54 +0800 Subject: [PATCH 28/39] Support option v3 inp in --- api/inp_in.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/api/inp_in.py b/api/inp_in.py index e43cc04..3432801 100644 --- a/api/inp_in.py +++ b/api/inp_in.py @@ -26,6 +26,7 @@ from .s20_mixing import inp_in_mixing from .s21_times import inp_in_time from .s22_report import inp_in_report from .s23_options import inp_in_option +from .s23_options_v3 import inp_in_option_v3 from .s24_coordinates import inp_in_coord from .s25_vertices import inp_in_vertex from .s26_labels import inp_in_label @@ -156,7 +157,7 @@ def _get_file_offset(inp: str) -> tuple[dict[str, list[int]], bool]: return (offset, demand_outside) -def parse_file(project: str, inp: str) -> None: +def parse_file(project: str, inp: str, version: str = '3') -> None: start = _print_time(f'Start reading file "{inp}"...') _print_time("First scan...") @@ -232,6 +233,11 @@ def parse_file(project: str, inp: str) -> None: if s == JUNCTIONS: sql_batch.add(handler(line, demand_outside)) + elif s == OPTIONS: + if version == '3': + sql_batch.add(inp_in_option_v3(line)) + else: + sql_batch.add(inp_in_option(line)) else: sql_batch.add(handler(line)) @@ -257,7 +263,7 @@ def read_inp(project: str, inp: str, version: str = '3') -> bool: open_project(project) try: - parse_file(project, inp) + parse_file(project, inp, version) except: close_project(project) delete_project(project) @@ -280,7 +286,7 @@ def import_inp(project: str, cs: ChangeSet, version: str = '3') -> bool: f.write(str(cs.operations[0]['inp'])) _print_time(f'End writing temp file "{filename}"...') - result = read_inp(project, filename) + result = read_inp(project, filename, version) os.remove(filename) From 0db93b0637972f8d4ea89d883a6238e88ec5340b Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:00:16 +0800 Subject: [PATCH 29/39] Clean and support v3 inp in --- api/inp_in.py | 49 ++++++++++++++++++++++++++++++-------------- api/s11_patterns.py | 50 ++++++++++----------------------------------- api/s12_curves.py | 2 ++ 3 files changed, 47 insertions(+), 54 deletions(-) diff --git a/api/inp_in.py b/api/inp_in.py index 3432801..fe24282 100644 --- a/api/inp_in.py +++ b/api/inp_in.py @@ -13,8 +13,8 @@ from .s7_valves import inp_in_valve from .s8_tags import inp_in_tag from .s9_demands import inp_in_demand from .s10_status import inp_in_status -from .s11_patterns import inp_in_pattern -from .s12_curves import CURVE_TYPE_PUMP, inp_in_curve +from .s11_patterns import pattern_v3_types, inp_in_pattern +from .s12_curves import curve_types, inp_in_curve from .s13_controls import inp_in_control from .s14_rules import inp_in_rule from .s15_energy import inp_in_energy @@ -35,9 +35,12 @@ from .s27_backdrop import inp_in_backdrop _S = 'S' _L = 'L' +def _inp_in_option(section: list[str], version: str = '3') -> str: + return inp_in_option_v3(section) if version == '3' else inp_in_option(section) + _handler = { TITLE : (_S, inp_in_title), - JUNCTIONS : (_L, inp_in_junction), + JUNCTIONS : (_L, inp_in_junction), # line, demand_outside RESERVOIRS : (_L, inp_in_reservoir), TANKS : (_L, inp_in_tank), PIPES : (_L, inp_in_pipe), @@ -46,7 +49,7 @@ _handler = { TAGS : (_L, inp_in_tag), DEMANDS : (_L, inp_in_demand), STATUS : (_L, inp_in_status), - PATTERNS : (_L, inp_in_pattern), + PATTERNS : (_L, inp_in_pattern), # line, fixed CURVES : (_L, inp_in_curve), CONTROLS : (_L, inp_in_control), RULES : (_L, inp_in_rule), @@ -58,7 +61,7 @@ _handler = { MIXING : (_L, inp_in_mixing), TIMES : (_S, inp_in_time), REPORT : (_S, inp_in_report), - OPTIONS : (_S, inp_in_option), + OPTIONS : (_S, _inp_in_option), # line, version COORDINATES : (_L, inp_in_coord), VERTICES : (_L, inp_in_vertex), LABELS : (_L, inp_in_label), @@ -171,6 +174,7 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: if t[0] == _S: sections[s] = [] + variable_patterns = [] current_pattern = None current_curve = None curve_type_desc_line = None @@ -209,22 +213,38 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: sections[s].append(line) else: if line.startswith(';'): - line = line.removeprefix(';') - if s == PATTERNS: # ;desc - pass - elif s == CURVES: # ;type: desc - curve_type_desc_line = line + if version != '3': #v2 + line = line.removeprefix(';') + if s == PATTERNS: # ;desc + pass + elif s == CURVES: # ;type: desc + curve_type_desc_line = line continue if s == PATTERNS: tokens = line.split() + + if tokens[1].upper() in pattern_v3_types: #v3 + sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');") + current_pattern = tokens[0] + if tokens[1].upper() == 'VARIABLE': + variable_patterns.append(tokens[0]) + continue + if current_pattern != tokens[0]: sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');") current_pattern = tokens[0] + elif s == CURVES: tokens = line.split() + + if tokens[1].upper() in curve_types: #v3 + sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{tokens[1].upper()}');") + current_curve = tokens[0] + continue + if current_curve != tokens[0]: - type = CURVE_TYPE_PUMP + type = curve_types[0] if curve_type_desc_line != None: type = curve_type_desc_line.split(':')[0].strip() sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") @@ -233,11 +253,10 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: if s == JUNCTIONS: sql_batch.add(handler(line, demand_outside)) + elif s == PATTERNS: + sql_batch.add(handler(line, current_pattern not in variable_patterns)) elif s == OPTIONS: - if version == '3': - sql_batch.add(inp_in_option_v3(line)) - else: - sql_batch.add(inp_in_option(line)) + sql_batch.add(handler(line, version)) else: sql_batch.add(handler(line)) diff --git a/api/s11_patterns.py b/api/s11_patterns.py index 77976f9..44bee01 100644 --- a/api/s11_patterns.py +++ b/api/s11_patterns.py @@ -1,5 +1,9 @@ from .database import * +PATTERN_V3_TYPE_FIXED = 'FIXED' +PATTERN_V3_TYPE_VARIABLE = 'VARIABLE' + +pattern_v3_types = [PATTERN_V3_TYPE_FIXED, PATTERN_V3_TYPE_VARIABLE] def get_pattern_schema(name: str) -> dict[str, dict[str, Any]]: return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True }, @@ -107,11 +111,15 @@ def delete_pattern(name: str, cs: ChangeSet) -> ChangeSet: #-------------------------------------------------------------- -def inp_in_pattern(line: str) -> str: +def inp_in_pattern(line: str, fixed: bool = True) -> str: tokens = line.split() sql = '' - for token in tokens[1:]: - sql += f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});" + if fixed: + for token in tokens[1:]: + sql += f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});" + else: + for token in tokens[1::2]: + sql += f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});" return sql @@ -125,42 +133,6 @@ def inp_out_pattern(name: str) -> list[str]: return lines -'''def inp_in_pattern_v3(section: list[str]) -> ChangeSet: - patterns: dict[str, list[float]] = {} - - variable_patterns: list[str] = [] - - count = len(section) - for i in range(0, count): - if section[i].startswith(';'): - continue - - tokens = section[i].split() - - # for EPA3, ignore time of variable pattern... - if tokens[1] == 'VARIABLE': - variable_patterns.append(tokens[0]) - continue - elif tokens[1] == 'FIXED': - continue - - if tokens[0] not in patterns: - patterns[tokens[0]] = [] - if tokens[0] not in variable_patterns: - for token in tokens[1:]: - patterns[tokens[0]].append(float(token)) - else: - for token in tokens[1::2]: - patterns[tokens[0]].append(float(token)) - - cs = ChangeSet() - for id, factors in patterns.items(): - cs.append(g_add_prefix | {'type': 'pattern', 'id' : id, 'factors' : factors}) - - #print(descs) - return cs''' - - def inp_out_pattern_v3(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from patterns order by _order") diff --git a/api/s12_curves.py b/api/s12_curves.py index fe297dc..83c39e8 100644 --- a/api/s12_curves.py +++ b/api/s12_curves.py @@ -5,6 +5,8 @@ CURVE_TYPE_EFFICIENCY = 'EFFICIENCY' CURVE_TYPE_VOLUME = 'VOLUME' CURVE_TYPE_HEADLOSS = 'HEADLOSS' +curve_types = [CURVE_TYPE_PUMP, CURVE_TYPE_EFFICIENCY, CURVE_TYPE_VOLUME, CURVE_TYPE_HEADLOSS] + def get_curve_schema(name: str) -> dict[str, dict[str, Any]]: return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True }, 'c_type' : {'type': 'str' , 'optional': False , 'readonly': False}, From fe0819654b93e4e3dd9d25e9f7770ce42ff24769 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:01:31 +0800 Subject: [PATCH 30/39] Clean curve v3 old inp in --- api/s12_curves.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/api/s12_curves.py b/api/s12_curves.py index 83c39e8..34780b0 100644 --- a/api/s12_curves.py +++ b/api/s12_curves.py @@ -156,35 +156,6 @@ def inp_out_curve(name: str) -> list[str]: return lines -'''def inp_in_curve_v3(section: list[str]) -> ChangeSet: - types = {} - curves: dict[str, list[dict[str, float]]] = {} - - count = len(section) - for i in range(0, count): - if section[i].startswith(';'): - continue - - tokens = section[i].split() - - # for EPA3 - if tokens[1] == 'PUMP' or tokens[1] == 'EFFICIENCY' or tokens[1] == 'VOLUME' or tokens[1] == 'HEADLOSS': - types[tokens[0]] = tokens[1] - continue - - if tokens[0] not in curves: - curves[tokens[0]] = [] - curves[tokens[0]].append({'x': float(tokens[1]), 'y': float(tokens[2])}) - - cs = ChangeSet() - for id, coords in curves.items(): - c_type = types[id] if id in types else CURVE_TYPE_PUMP - cs.append(g_add_prefix | {'type': 'curve', 'id' : id, 'c_type': c_type, 'coords' : coords}) - - #print(descs) - return cs''' - - def inp_out_curve_v3(name: str) -> list[str]: lines = [] types = read_all(name, f"select * from _curve") From a8278e50ddc54a0d4ba7dd221b3a6d751bf390b6 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:14:39 +0800 Subject: [PATCH 31/39] Sync code --- api/s23_options_v3.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/s23_options_v3.py b/api/s23_options_v3.py index cabf6cf..4e62c88 100644 --- a/api/s23_options_v3.py +++ b/api/s23_options_v3.py @@ -16,7 +16,8 @@ def _parse_v2(v2_lines: list[str]) -> dict[str, str]: for s in v2_lines: tokens = s.split() if tokens[0].upper() == 'PATTERN': # can not upper id - cs_v2 |= { 'PATTERN' : tokens[1] } + value = tokens[1] if len(tokens) > 1 else '' + cs_v2 |= { 'PATTERN' : value } elif tokens[0].upper() == 'QUALITY': # can not upper trace node value = tokens[1] if len(tokens) > 2: From 9c2e314416aa3e5a6340369ad90eac6bad7d1ec1 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:26:35 +0800 Subject: [PATCH 32/39] Check input version --- api/inp_in.py | 6 ++++++ api/inp_out.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/api/inp_in.py b/api/inp_in.py index fe24282..df5fe45 100644 --- a/api/inp_in.py +++ b/api/inp_in.py @@ -272,6 +272,9 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: def read_inp(project: str, inp: str, version: str = '3') -> bool: + if version != '3' and version != '2': + version = '2' + if is_project_open(project): close_project(project) @@ -293,6 +296,9 @@ def read_inp(project: str, inp: str, version: str = '3') -> bool: def import_inp(project: str, cs: ChangeSet, version: str = '3') -> bool: + if version != '3' and version != '2': + version = '2' + if 'inp' not in cs.operations[0]: return False diff --git a/api/inp_out.py b/api/inp_out.py index d6a5774..8aef8d8 100644 --- a/api/inp_out.py +++ b/api/inp_out.py @@ -33,6 +33,9 @@ from .s27_backdrop import inp_out_backdrop def dump_inp(project: str, inp: str, version: str = '3'): + if version != '3' and version != '2': + version = '2' + if not have_project(project): return @@ -145,6 +148,9 @@ def dump_inp(project: str, inp: str, version: str = '3'): def export_inp(project: str, version: str = '3') -> ChangeSet: + if version != '3' and version != '2': + version = '2' + if not have_project(project): return ChangeSet() From cf302487d3115a220501c09dde03f6ea36114a1b Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:27:47 +0800 Subject: [PATCH 33/39] Replace section name with pre-defined one --- api/inp_out.py | 118 ++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/api/inp_out.py b/api/inp_out.py index 8aef8d8..baad20b 100644 --- a/api/inp_out.py +++ b/api/inp_out.py @@ -1,7 +1,7 @@ import os from .project import * from .database import ChangeSet -from .sections import section_name +from .sections import * from .s1_title import inp_out_title from .s2_junctions import inp_out_junction from .s3_reservoirs import inp_out_reservoir @@ -51,93 +51,93 @@ def dump_inp(project: str, inp: str, version: str = '3'): file = open(path, mode='w') for name in section_name: - if name == 'TITLE': + if name == TITLE: file.write(f'[{name}]\n') else: file.write(f'\n[{name}]\n') - if name == 'TITLE': + if name == TITLE: file.write('\n'.join(inp_out_title(project))) - elif name == 'JUNCTIONS': # + coords + elif name == JUNCTIONS: # + coords file.write('\n'.join(inp_out_junction(project))) - elif name == 'RESERVOIRS': # + coords + elif name == RESERVOIRS: # + coords file.write('\n'.join(inp_out_reservoir(project))) - elif name == 'TANKS': # + coords + elif name == TANKS: # + coords file.write('\n'.join(inp_out_tank(project))) - elif name == 'PIPES': + elif name == PIPES: file.write('\n'.join(inp_out_pipe(project))) - elif name == 'PUMPS': + elif name == PUMPS: file.write('\n'.join(inp_out_pump(project))) - elif name == 'VALVES': + elif name == VALVES: file.write('\n'.join(inp_out_valve(project))) - elif name == 'TAGS': + elif name == TAGS: file.write('\n'.join(inp_out_tag(project))) - elif name == 'DEMANDS': + elif name == DEMANDS: file.write('\n'.join(inp_out_demand(project))) - elif name == 'STATUS': + elif name == STATUS: file.write('\n'.join(inp_out_status(project))) - elif name == 'PATTERNS': + elif name == PATTERNS: file.write('\n'.join(inp_out_pattern(project))) - elif name == 'CURVES': + elif name == CURVES: file.write('\n'.join(inp_out_curve(project))) - elif name == 'CONTROLS': + elif name == CONTROLS: file.write('\n'.join(inp_out_control(project))) - elif name == 'RULES': + elif name == RULES: file.write('\n'.join(inp_out_rule(project))) - elif name == 'ENERGY': + elif name == ENERGY: file.write('\n'.join(inp_out_energy(project))) - elif name == 'EMITTERS': + elif name == EMITTERS: file.write('\n'.join(inp_out_emitter(project))) - elif name == 'QUALITY': + elif name == QUALITY: file.write('\n'.join(inp_out_quality(project))) - elif name == 'SOURCES': + elif name == SOURCES: file.write('\n'.join(inp_out_source(project))) - elif name == 'REACTIONS': + elif name == REACTIONS: file.write('\n'.join(inp_out_reaction(project))) - elif name == 'MIXING': + elif name == MIXING: file.write('\n'.join(inp_out_mixing(project))) - elif name == 'TIMES': + elif name == TIMES: file.write('\n'.join(inp_out_time(project))) - elif name == 'REPORT': + elif name == REPORT: file.write('\n'.join(inp_out_report(project))) - elif name == 'OPTIONS': + elif name == OPTIONS: file.write('\n'.join(inp_out_option(project))) - elif name == 'COORDINATES': + elif name == COORDINATES: file.write('\n'.join(inp_out_coord(project))) - elif name == 'VERTICES': + elif name == VERTICES: file.write('\n'.join(inp_out_vertex(project))) - elif name == 'LABELS': + elif name == LABELS: file.write('\n'.join(inp_out_label(project))) - elif name == 'BACKDROP': + elif name == BACKDROP: file.write('\n'.join(inp_out_backdrop(project))) - elif name == 'END': + elif name == END: pass # :) file.write('\n') @@ -162,93 +162,93 @@ def export_inp(project: str, version: str = '3') -> ChangeSet: inp = '' for name in section_name: - if name == 'TITLE': + if name == TITLE: inp += f'[{name}]\n' else: inp += f'\n[{name}]\n' - if name == 'TITLE': + if name == TITLE: inp += '\n'.join(inp_out_title(project)) - elif name == 'JUNCTIONS': # + coords + elif name == JUNCTIONS: # + coords inp += '\n'.join(inp_out_junction(project)) - elif name == 'RESERVOIRS': # + coords + elif name == RESERVOIRS: # + coords inp += '\n'.join(inp_out_reservoir(project)) - elif name == 'TANKS': # + coords + elif name == TANKS: # + coords inp += '\n'.join(inp_out_tank(project)) - elif name == 'PIPES': + elif name == PIPES: inp += '\n'.join(inp_out_pipe(project)) - elif name == 'PUMPS': + elif name == PUMPS: inp += '\n'.join(inp_out_pump(project)) - elif name == 'VALVES': + elif name == VALVES: inp += '\n'.join(inp_out_valve(project)) - elif name == 'TAGS': + elif name == TAGS: inp += '\n'.join(inp_out_tag(project)) - elif name == 'DEMANDS': + elif name == DEMANDS: inp += '\n'.join(inp_out_demand(project)) - elif name == 'STATUS': + elif name == STATUS: inp += '\n'.join(inp_out_status(project)) - elif name == 'PATTERNS': + elif name == PATTERNS: inp += '\n'.join(inp_out_pattern(project)) - elif name == 'CURVES': + elif name == CURVES: inp += '\n'.join(inp_out_curve(project)) - elif name == 'CONTROLS': + elif name == CONTROLS: inp += '\n'.join(inp_out_control(project)) - elif name == 'RULES': + elif name == RULES: inp += '\n'.join(inp_out_rule(project)) - elif name == 'ENERGY': + elif name == ENERGY: inp += '\n'.join(inp_out_energy(project)) - elif name == 'EMITTERS': + elif name == EMITTERS: inp += '\n'.join(inp_out_emitter(project)) - elif name == 'QUALITY': + elif name == QUALITY: inp += '\n'.join(inp_out_quality(project)) - elif name == 'SOURCES': + elif name == SOURCES: inp += '\n'.join(inp_out_source(project)) - elif name == 'REACTIONS': + elif name == REACTIONS: inp += '\n'.join(inp_out_reaction(project)) - elif name == 'MIXING': + elif name == MIXING: inp += '\n'.join(inp_out_mixing(project)) - elif name == 'TIMES': + elif name == TIMES: inp += '\n'.join(inp_out_time(project)) - elif name == 'REPORT': + elif name == REPORT: inp += '\n'.join(inp_out_report(project)) - elif name == 'OPTIONS': + elif name == OPTIONS: inp += '\n'.join(inp_out_option(project)) - elif name == 'COORDINATES': + elif name == COORDINATES: inp += '\n'.join(inp_out_coord(project)) - elif name == 'VERTICES': + elif name == VERTICES: inp += '\n'.join(inp_out_vertex(project)) - elif name == 'LABELS': + elif name == LABELS: inp += '\n'.join(inp_out_label(project)) - elif name == 'BACKDROP': + elif name == BACKDROP: inp += '\n'.join(inp_out_backdrop(project)) - elif name == 'END': + elif name == END: pass # :) inp += '\n' From a73cd3debaff065dfa386b91c253fd6c7908f30e Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:32:43 +0800 Subject: [PATCH 34/39] Support inp out v3 --- api/inp_out.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/api/inp_out.py b/api/inp_out.py index baad20b..25568ca 100644 --- a/api/inp_out.py +++ b/api/inp_out.py @@ -12,8 +12,8 @@ from .s7_valves import inp_out_valve from .s8_tags import inp_out_tag from .s9_demands import inp_out_demand from .s10_status import inp_out_status -from .s11_patterns import inp_out_pattern -from .s12_curves import inp_out_curve +from .s11_patterns import inp_out_pattern, inp_out_pattern_v3 +from .s12_curves import inp_out_curve, inp_out_curve_v3 from .s13_controls import inp_out_control from .s14_rules import inp_out_rule from .s15_energy import inp_out_energy @@ -25,6 +25,7 @@ from .s20_mixing import inp_out_mixing from .s21_times import inp_out_time from .s22_report import inp_out_report from .s23_options import inp_out_option +from .s23_options_v3 import inp_out_option_v3 from .s24_coordinates import inp_out_coord from .s25_vertices import inp_out_vertex from .s26_labels import inp_out_label @@ -87,10 +88,16 @@ def dump_inp(project: str, inp: str, version: str = '3'): file.write('\n'.join(inp_out_status(project))) elif name == PATTERNS: - file.write('\n'.join(inp_out_pattern(project))) + if version == '3': + file.write('\n'.join(inp_out_pattern_v3(project))) + else: + file.write('\n'.join(inp_out_pattern(project))) elif name == CURVES: - file.write('\n'.join(inp_out_curve(project))) + if version == '3': + file.write('\n'.join(inp_out_curve_v3(project))) + else: + file.write('\n'.join(inp_out_curve(project))) elif name == CONTROLS: file.write('\n'.join(inp_out_control(project))) @@ -123,7 +130,10 @@ def dump_inp(project: str, inp: str, version: str = '3'): file.write('\n'.join(inp_out_report(project))) elif name == OPTIONS: - file.write('\n'.join(inp_out_option(project))) + if version == '3': + file.write('\n'.join(inp_out_option_v3(project))) + else: + file.write('\n'.join(inp_out_option(project))) elif name == COORDINATES: file.write('\n'.join(inp_out_coord(project))) @@ -198,10 +208,16 @@ def export_inp(project: str, version: str = '3') -> ChangeSet: inp += '\n'.join(inp_out_status(project)) elif name == PATTERNS: - inp += '\n'.join(inp_out_pattern(project)) + if version == '3': + inp += '\n'.join(inp_out_pattern_v3(project)) + else: + inp += '\n'.join(inp_out_pattern(project)) elif name == CURVES: - inp += '\n'.join(inp_out_curve(project)) + if version == '3': + inp += '\n'.join(inp_out_curve_v3(project)) + else: + inp += '\n'.join(inp_out_curve(project)) elif name == CONTROLS: inp += '\n'.join(inp_out_control(project)) @@ -234,7 +250,10 @@ def export_inp(project: str, version: str = '3') -> ChangeSet: inp += '\n'.join(inp_out_report(project)) elif name == OPTIONS: - inp += '\n'.join(inp_out_option(project)) + if version == '3': + inp += '\n'.join(inp_out_option_v3(project)) + else: + inp += '\n'.join(inp_out_option(project)) elif name == COORDINATES: inp += '\n'.join(inp_out_coord(project)) From 9a65990278cfe702e9d96abb5b9d7ff52841441a Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:36:57 +0800 Subject: [PATCH 35/39] Support run epa3 --- api/inp_in.py | 6 ++++-- epanet/epanet2.py | 10 +++++++--- tjnetwork.py | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/api/inp_in.py b/api/inp_in.py index df5fe45..2957c94 100644 --- a/api/inp_in.py +++ b/api/inp_in.py @@ -284,12 +284,14 @@ def read_inp(project: str, inp: str, version: str = '3') -> bool: create_project(project) open_project(project) - try: + parse_file(project, inp, version) + + '''try: parse_file(project, inp, version) except: close_project(project) delete_project(project) - return False + return False''' close_project(project) return True diff --git a/epanet/epanet2.py b/epanet/epanet2.py index 766cde0..ed0f151 100644 --- a/epanet/epanet2.py +++ b/epanet/epanet2.py @@ -227,17 +227,21 @@ def dump_output(path: str) -> str: return json.dumps(data) -def run_project(name: str) -> str: +def run_project(name: str, version: str = '3') -> str: + if version != '3' and version != '2': + version = '2' + if not project.have_project(name): raise Exception(f'Not found project [{name}]') dir = os.path.abspath(os.getcwd()) db_inp = os.path.join(os.path.join(dir, 'db_inp'), name + '.db.inp') - inp_out.dump_inp(name, db_inp) + inp_out.dump_inp(name, db_inp, version) input = name + '.db' - exe = os.path.join(os.path.join(dir, 'epanet'), 'runepanet.exe') + program = 'runepanet.exe' if version == '2' else 'run-epanet3.exe' + exe = os.path.join(os.path.join(dir, 'epanet'), program) inp = os.path.join(os.path.join(dir, 'db_inp'), input + '.inp') rpt = os.path.join(os.path.join(dir, 'temp'), input + '.rpt') opt = os.path.join(os.path.join(dir, 'temp'), input + '.opt') diff --git a/tjnetwork.py b/tjnetwork.py index 75ddf32..52f9f28 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -197,8 +197,8 @@ def import_inp(name: str, cs: ChangeSet, version: str = '3') -> bool: def export_inp(name: str, version: str = '3') -> ChangeSet: return api.export_inp(name, version) -def run_project(name: str) -> str: - return epanet.run_project(name) +def run_project(name: str, version: str = '3') -> str: + return epanet.run_project(name, version) # put in inp folder, name without extension def run_inp(name: str) -> str: From c93298a1b28bcaf9b3697706da66e751f67827bd Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:39:43 +0800 Subject: [PATCH 36/39] Pay attention to epa3 simulation output format --- epanet/epanet2.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/epanet/epanet2.py b/epanet/epanet2.py index ed0f151..bc297c0 100644 --- a/epanet/epanet2.py +++ b/epanet/epanet2.py @@ -254,7 +254,10 @@ def run_project(name: str, version: str = '3') -> str: data['simulation_result'] = 'failed' else: data['simulation_result'] = 'successful' - data |= _dump_output(opt) + if version == '2': + data |= _dump_output(opt) + else: + pass # TODO: epanet3 output format? data['report'] = dump_report(rpt) From b9c8856528a6216790a5a82cb581f03dfbf02468 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:40:47 +0800 Subject: [PATCH 37/39] Rename since we support epa3 --- epanet/__init__.py | 2 +- epanet/{epanet2.py => epanet.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename epanet/{epanet2.py => epanet.py} (100%) diff --git a/epanet/__init__.py b/epanet/__init__.py index b2473ee..7aedf70 100644 --- a/epanet/__init__.py +++ b/epanet/__init__.py @@ -1 +1 @@ -from .epanet2 import run_project, run_inp, dump_output \ No newline at end of file +from .epanet import run_project, run_inp, dump_output \ No newline at end of file diff --git a/epanet/epanet2.py b/epanet/epanet.py similarity index 100% rename from epanet/epanet2.py rename to epanet/epanet.py From 6f9d45d98234894dad5a7cf2dc5f13f2d6fab627 Mon Sep 17 00:00:00 2001 From: Joey Wang Date: Wed, 22 Mar 2023 13:48:59 +0800 Subject: [PATCH 38/39] Run inp should be same with run project --- epanet/epanet.py | 13 ++++++++++--- tjnetwork.py | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/epanet/epanet.py b/epanet/epanet.py index bc297c0..2251ff2 100644 --- a/epanet/epanet.py +++ b/epanet/epanet.py @@ -264,10 +264,14 @@ def run_project(name: str, version: str = '3') -> str: return json.dumps(data) -def run_inp(name: str) -> str: +def run_inp(name: str, version: str = '3') -> str: + if version != '3' and version != '2': + version = '2' + dir = os.path.abspath(os.getcwd()) - exe = os.path.join(os.path.join(dir, 'epanet'), 'runepanet.exe') + program = 'runepanet.exe' if version == '2' else 'run-epanet3.exe' + exe = os.path.join(os.path.join(dir, 'epanet'), program) inp = os.path.join(os.path.join(dir, 'inp'), name + '.inp') rpt = os.path.join(os.path.join(dir, 'temp'), name + '.rpt') opt = os.path.join(os.path.join(dir, 'temp'), name + '.opt') @@ -280,7 +284,10 @@ def run_inp(name: str) -> str: data['simulation_result'] = 'failed' else: data['simulation_result'] = 'successful' - data |= _dump_output(opt) + if version == '2': + data |= _dump_output(opt) + else: + pass # TODO: epanet3 output format? data['report'] = dump_report(rpt) diff --git a/tjnetwork.py b/tjnetwork.py index 52f9f28..9ce64ad 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -201,8 +201,8 @@ def run_project(name: str, version: str = '3') -> str: return epanet.run_project(name, version) # put in inp folder, name without extension -def run_inp(name: str) -> str: - return epanet.run_inp(name) +def run_inp(name: str, version: str = '3') -> str: + return epanet.run_inp(name, version) # path is absolute path def dump_output(path: str) -> str: From 7727591667e18f9dc58eacf6f6bca2ba135da9f2 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Wed, 22 Mar 2023 18:52:46 +0800 Subject: [PATCH 39/39] Reset simulation to v2 --- epanet/epanet.py | 4 ++-- tjnetwork.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/epanet/epanet.py b/epanet/epanet.py index 2251ff2..330639e 100644 --- a/epanet/epanet.py +++ b/epanet/epanet.py @@ -227,7 +227,7 @@ def dump_output(path: str) -> str: return json.dumps(data) -def run_project(name: str, version: str = '3') -> str: +def run_project(name: str, version: str = '2') -> str: if version != '3' and version != '2': version = '2' @@ -264,7 +264,7 @@ def run_project(name: str, version: str = '3') -> str: return json.dumps(data) -def run_inp(name: str, version: str = '3') -> str: +def run_inp(name: str, version: str = '2') -> str: if version != '3' and version != '2': version = '2' diff --git a/tjnetwork.py b/tjnetwork.py index 9ce64ad..b8cd257 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -197,11 +197,11 @@ def import_inp(name: str, cs: ChangeSet, version: str = '3') -> bool: def export_inp(name: str, version: str = '3') -> ChangeSet: return api.export_inp(name, version) -def run_project(name: str, version: str = '3') -> str: +def run_project(name: str, version: str = '2') -> str: return epanet.run_project(name, version) # put in inp folder, name without extension -def run_inp(name: str, version: str = '3') -> str: +def run_inp(name: str, version: str = '2') -> str: return epanet.run_inp(name, version) # path is absolute path