From 02157fbd8d35b16e70d4b7626fa556b6687bbbff Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Mon, 5 Aug 2019 14:08:37 -0400 Subject: [PATCH 01/15] Return default value when possible --- eppy/bunch_subclass.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/eppy/bunch_subclass.py b/eppy/bunch_subclass.py index 445576f8..cd3d4c7f 100644 --- a/eppy/bunch_subclass.py +++ b/eppy/bunch_subclass.py @@ -321,7 +321,13 @@ def __getattr__(self, name): try: return self.fieldvalues[i] except IndexError: - return "" + # try to return the default value if defined in IDD. + if 'default' in self.getfieldidd(name).keys(): + _type = _parse_idd_type(self, name) + default_ = next(iter(self.getfieldidd(name)['default']), None) + return _type(default_) + else: + return "" else: astr = "unable to find field %s" % (name,) raise BadEPFieldError(astr) @@ -394,6 +400,18 @@ def __dir__(self): return super(EpBunch, self).__dir__() + fnames + func_names +def _parse_idd_type(epbunch, name): + """parse the fieldvalue type into a python type. eg.: 'real' returns + 'float'""" + _type = next(iter(epbunch.getfieldidd(name)['type']), None) + if _type == 'real': + return float + elif _type == 'alpha': + return str + else: + return str + + def getrange(bch, fieldname): """get the ranges for this field""" keys = ["maximum", "minimum", "maximum<", "minimum>", "type"] From cc29bbec6db929094dd79d7c22e6cfd162626676 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Mon, 5 Aug 2019 22:20:23 -0400 Subject: [PATCH 02/15] Code cleanup --- eppy/bunch_subclass.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eppy/bunch_subclass.py b/eppy/bunch_subclass.py index cd3d4c7f..f034879c 100644 --- a/eppy/bunch_subclass.py +++ b/eppy/bunch_subclass.py @@ -322,9 +322,9 @@ def __getattr__(self, name): return self.fieldvalues[i] except IndexError: # try to return the default value if defined in IDD. - if 'default' in self.getfieldidd(name).keys(): + if "default" in self.getfieldidd(name).keys(): _type = _parse_idd_type(self, name) - default_ = next(iter(self.getfieldidd(name)['default']), None) + default_ = next(iter(self.getfieldidd(name)["default"]), None) return _type(default_) else: return "" @@ -403,10 +403,10 @@ def __dir__(self): def _parse_idd_type(epbunch, name): """parse the fieldvalue type into a python type. eg.: 'real' returns 'float'""" - _type = next(iter(epbunch.getfieldidd(name)['type']), None) - if _type == 'real': + _type = next(iter(epbunch.getfieldidd(name)["type"]), None) + if _type == "real": return float - elif _type == 'alpha': + elif _type == "alpha": return str else: return str From 1ebec2a89a4cb299c901bb469be0a24fb6bbe0ad Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 12:06:44 -0400 Subject: [PATCH 03/15] Adds a test for default values Also, refactors the test_bunch_subclass so that pytest fixtures are used --- eppy/tests/conftest.py | 12 +- eppy/tests/test_bunch_subclass.py | 914 ++++++++++++++++-------------- 2 files changed, 493 insertions(+), 433 deletions(-) diff --git a/eppy/tests/conftest.py b/eppy/tests/conftest.py index f839f046..4e911c1b 100644 --- a/eppy/tests/conftest.py +++ b/eppy/tests/conftest.py @@ -24,18 +24,20 @@ TEST_OLD_IDD = "Energy+V7_2_0.idd" -@pytest.fixture() +@pytest.fixture(scope="module") def test_idf(): idd_file = os.path.join(IDD_FILES, TEST_IDD) idf_file = os.path.join(IDF_FILES, TEST_IDF) - modeleditor.IDF.setiddname(idd_file, testing=True) + modeleditor.IDF.iddname = idd_file idf = modeleditor.IDF(idf_file, TEST_EPW) try: ep_version = idf.idd_version assert ep_version == versiontuple(VERSION) except AttributeError: raise - return idf + yield idf + + del idf @pytest.fixture() @@ -47,4 +49,6 @@ def base_idf(): idftxt = "" idfhandle = StringIO(idftxt) idf = IDF(idfhandle) - return idf + yield idf + + del idf diff --git a/eppy/tests/test_bunch_subclass.py b/eppy/tests/test_bunch_subclass.py index 58ae6975..327da4fe 100644 --- a/eppy/tests/test_bunch_subclass.py +++ b/eppy/tests/test_bunch_subclass.py @@ -19,371 +19,383 @@ import eppy.bunchhelpers as bunchhelpers from eppy.iddcurrent import iddcurrent import eppy.idfreader as idfreader -from eppy.modeleditor import IDF - - -# This test is ugly because I have to send file names and not able to send file handles -EpBunch = bunch_subclass.EpBunch - -iddtxt = iddcurrent.iddtxt - -# idd is read only once in this test -# if it has already been read from some other test, it will continue with -# the old reading -iddfhandle = StringIO(iddcurrent.iddtxt) -if IDF.getiddname() == None: - IDF.setiddname(iddfhandle) - -# This test is ugly because I have to send file names and not able to send file handles -idftxt = """Version, - 6.0; - -BuildingSurface:Detailed, - Zn001:Wall001, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - West Zone, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 0,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 0,0,0, !- X,Y,Z ==> Vertex 2 {m} - 6.096000,0,0, !- X,Y,Z ==> Vertex 3 {m} - 6.096000,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -FenestrationSurface:Detailed, - Zn001:Wall001:Win001, !- Name - Window, !- Surface Type - WIN-CON-LIGHT, !- Construction Name - Zn001:Wall001, !- Building Surface Name - , !- Outside Boundary Condition Object - 0.5000000, !- View Factor to Ground - , !- Shading Control Name - , !- Frame and Divider Name - 1.0, !- Multiplier - 4, !- Number of Vertices - 0.548000,0,2.5000, !- X,Y,Z ==> Vertex 1 {m} - 0.548000,0,0.5000, !- X,Y,Z ==> Vertex 2 {m} - 5.548000,0,0.5000, !- X,Y,Z ==> Vertex 3 {m} - 5.548000,0,2.5000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn001:Wall002, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - West Zone, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 0,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 0,0,0, !- X,Y,Z ==> Vertex 3 {m} - 0,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn001:Wall003, !- Name - Wall, !- Surface Type - PARTITION06, !- Construction Name - West Zone, !- Zone Name - Surface, !- Outside Boundary Condition - Zn003:Wall004, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 0,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 0,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn001:Wall004, !- Name - Wall, !- Surface Type - PARTITION06, !- Construction Name - West Zone, !- Zone Name - Surface, !- Outside Boundary Condition - Zn002:Wall004, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 6.096000,0,0, !- X,Y,Z ==> Vertex 2 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn001:Flr001, !- Name - Floor, !- Surface Type - FLOOR SLAB 8 IN, !- Construction Name - West Zone, !- Zone Name - Surface, !- Outside Boundary Condition - Zn001:Flr001, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 1.000000, !- View Factor to Ground - 4, !- Number of Vertices - 0,0,0, !- X,Y,Z ==> Vertex 1 {m} - 0,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 6.096000,0,0; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn001:Roof001, !- Name - Roof, !- Surface Type - ROOF34, !- Construction Name - West Zone, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0, !- View Factor to Ground - 4, !- Number of Vertices - 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 0,0,3.048000, !- X,Y,Z ==> Vertex 2 {m} - 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 3 {m} - 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn002:Wall001, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - EAST ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 12.19200,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 12.19200,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 9.144000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn002:Wall002, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - EAST ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 6.096000,0,0, !- X,Y,Z ==> Vertex 2 {m} - 12.19200,0,0, !- X,Y,Z ==> Vertex 3 {m} - 12.19200,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn002:Wall003, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - EAST ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 12.19200,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 12.19200,0,0, !- X,Y,Z ==> Vertex 2 {m} - 12.19200,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 12.19200,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn002:Wall004, !- Name - Wall, !- Surface Type - PARTITION06, !- Construction Name - EAST ZONE, !- Zone Name - Surface, !- Outside Boundary Condition - Zn001:Wall004, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 6.096000,0,0, !- X,Y,Z ==> Vertex 3 {m} - 6.096000,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn002:Wall005, !- Name - Wall, !- Surface Type - PARTITION06, !- Construction Name - EAST ZONE, !- Zone Name - Surface, !- Outside Boundary Condition - Zn003:Wall005, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 9.144000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn002:Flr001, !- Name - Floor, !- Surface Type - FLOOR SLAB 8 IN, !- Construction Name - EAST ZONE, !- Zone Name - Surface, !- Outside Boundary Condition - Zn002:Flr001, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 1.000000, !- View Factor to Ground - 4, !- Number of Vertices - 6.096000,0,0, !- X,Y,Z ==> Vertex 1 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 12.19200,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 12.19200,0,0; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn002:Roof001, !- Name - Roof, !- Surface Type - ROOF34, !- Construction Name - EAST ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0, !- View Factor to Ground - 4, !- Number of Vertices - 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 2 {m} - 12.19200,0,3.048000, !- X,Y,Z ==> Vertex 3 {m} - 12.19200,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn003:Wall001, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - NORTH ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 0,12.19200,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 0,12.19200,0, !- X,Y,Z ==> Vertex 2 {m} - 0,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 0,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn003:Wall002, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - NORTH ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 9.144000,12.19200,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 9.144000,12.19200,0, !- X,Y,Z ==> Vertex 2 {m} - 0,12.19200,0, !- X,Y,Z ==> Vertex 3 {m} - 0,12.19200,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn003:Wall003, !- Name - Wall, !- Surface Type - EXTWALL80, !- Construction Name - NORTH ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 9.144000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 9.144000,12.19200,0, !- X,Y,Z ==> Vertex 3 {m} - 9.144000,12.19200,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn003:Wall004, !- Name - Wall, !- Surface Type - PARTITION06, !- Construction Name - NORTH ZONE, !- Zone Name - Surface, !- Outside Boundary Condition - Zn001:Wall003, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 0,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn003:Wall005, !- Name - Wall, !- Surface Type - PARTITION06, !- Construction Name - NORTH ZONE, !- Zone Name - Surface, !- Outside Boundary Condition - Zn002:Wall005, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 0.5000000, !- View Factor to Ground - 4, !- Number of Vertices - 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} - 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} - 9.144000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} - -BuildingSurface:Detailed, - Zn003:Flr001, !- Name - Floor, !- Surface Type - FLOOR SLAB 8 IN, !- Construction Name - NORTH ZONE, !- Zone Name - Surface, !- Outside Boundary Condition - Zn003:Flr001, !- Outside Boundary Condition Object - NoSun, !- Sun Exposure - NoWind, !- Wind Exposure - 1.000000, !- View Factor to Ground - 4, !- Number of Vertices - 0,6.096000,0, !- X,Y,Z ==> Vertex 1 {m} - 0,12.19200,0, !- X,Y,Z ==> Vertex 2 {m} - 9.144000,12.19200,0, !- X,Y,Z ==> Vertex 3 {m} - 9.144000,6.096000,0; !- X,Y,Z ==> Vertex 4 {m} +from eppy.bunch_subclass import EpBunch + + +@pytest.fixture() +def iddtxt(): + # This test is ugly because I have to send file names and not able to send file + # handles + yield iddcurrent.iddtxt + + +@pytest.fixture(scope="class") +def idftxt(): + # This test is ugly because I have to send file names and not able to send file + # handles + idftxt = """Version, + 6.0; + + Building, + Empire State Building, !- Name + , !- North Axis {deg} + Suburbs, !- Terrain + 0.04, !- Loads Convergence Tolerance Value + 0.4, !- Temperature Convergence Tolerance Value { + deltaC} + FullExterior, !- Solar Distribution + 25, !- Maximum Number of Warmup Days + 6; !- Minimum Number of Warmup Days + + BuildingSurface:Detailed, + Zn001:Wall001, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + West Zone, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 0,0,0, !- X,Y,Z ==> Vertex 2 {m} + 6.096000,0,0, !- X,Y,Z ==> Vertex 3 {m} + 6.096000,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + FenestrationSurface:Detailed, + Zn001:Wall001:Win001, !- Name + Window, !- Surface Type + WIN-CON-LIGHT, !- Construction Name + Zn001:Wall001, !- Building Surface Name + , !- Outside Boundary Condition Object + 0.5000000, !- View Factor to Ground + , !- Shading Control Name + , !- Frame and Divider Name + 1.0, !- Multiplier + 4, !- Number of Vertices + 0.548000,0,2.5000, !- X,Y,Z ==> Vertex 1 {m} + 0.548000,0,0.5000, !- X,Y,Z ==> Vertex 2 {m} + 5.548000,0,0.5000, !- X,Y,Z ==> Vertex 3 {m} + 5.548000,0,2.5000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Wall002, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + West Zone, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 0,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 0,0,0, !- X,Y,Z ==> Vertex 3 {m} + 0,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Wall003, !- Name + Wall, !- Surface Type + PARTITION06, !- Construction Name + West Zone, !- Zone Name + Surface, !- Outside Boundary Condition + Zn003:Wall004, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 0,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 0,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Wall004, !- Name + Wall, !- Surface Type + PARTITION06, !- Construction Name + West Zone, !- Zone Name + Surface, !- Outside Boundary Condition + Zn002:Wall004, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 6.096000,0,0, !- X,Y,Z ==> Vertex 2 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Flr001, !- Name + Floor, !- Surface Type + FLOOR SLAB 8 IN, !- Construction Name + West Zone, !- Zone Name + Surface, !- Outside Boundary Condition + Zn001:Flr001, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 1.000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,0,0, !- X,Y,Z ==> Vertex 1 {m} + 0,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 6.096000,0,0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn001:Roof001, !- Name + Roof, !- Surface Type + ROOF34, !- Construction Name + West Zone, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0, !- View Factor to Ground + 4, !- Number of Vertices + 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 0,0,3.048000, !- X,Y,Z ==> Vertex 2 {m} + 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 3 {m} + 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn002:Wall001, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + EAST ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 12.19200,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 12.19200,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 9.144000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn002:Wall002, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + EAST ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 6.096000,0,0, !- X,Y,Z ==> Vertex 2 {m} + 12.19200,0,0, !- X,Y,Z ==> Vertex 3 {m} + 12.19200,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn002:Wall003, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + EAST ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 12.19200,0,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 12.19200,0,0, !- X,Y,Z ==> Vertex 2 {m} + 12.19200,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 12.19200,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn002:Wall004, !- Name + Wall, !- Surface Type + PARTITION06, !- Construction Name + EAST ZONE, !- Zone Name + Surface, !- Outside Boundary Condition + Zn001:Wall004, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 6.096000,0,0, !- X,Y,Z ==> Vertex 3 {m} + 6.096000,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn002:Wall005, !- Name + Wall, !- Surface Type + PARTITION06, !- Construction Name + EAST ZONE, !- Zone Name + Surface, !- Outside Boundary Condition + Zn003:Wall005, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 9.144000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn002:Flr001, !- Name + Floor, !- Surface Type + FLOOR SLAB 8 IN, !- Construction Name + EAST ZONE, !- Zone Name + Surface, !- Outside Boundary Condition + Zn002:Flr001, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 1.000000, !- View Factor to Ground + 4, !- Number of Vertices + 6.096000,0,0, !- X,Y,Z ==> Vertex 1 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 12.19200,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 12.19200,0,0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn002:Roof001, !- Name + Roof, !- Surface Type + ROOF34, !- Construction Name + EAST ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0, !- View Factor to Ground + 4, !- Number of Vertices + 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 6.096000,0,3.048000, !- X,Y,Z ==> Vertex 2 {m} + 12.19200,0,3.048000, !- X,Y,Z ==> Vertex 3 {m} + 12.19200,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn003:Wall001, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + NORTH ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,12.19200,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 0,12.19200,0, !- X,Y,Z ==> Vertex 2 {m} + 0,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 0,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn003:Wall002, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + NORTH ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 9.144000,12.19200,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 9.144000,12.19200,0, !- X,Y,Z ==> Vertex 2 {m} + 0,12.19200,0, !- X,Y,Z ==> Vertex 3 {m} + 0,12.19200,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn003:Wall003, !- Name + Wall, !- Surface Type + EXTWALL80, !- Construction Name + NORTH ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 9.144000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 9.144000,12.19200,0, !- X,Y,Z ==> Vertex 3 {m} + 9.144000,12.19200,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn003:Wall004, !- Name + Wall, !- Surface Type + PARTITION06, !- Construction Name + NORTH ZONE, !- Zone Name + Surface, !- Outside Boundary Condition + Zn001:Wall003, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 0,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 6.096000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn003:Wall005, !- Name + Wall, !- Surface Type + PARTITION06, !- Construction Name + NORTH ZONE, !- Zone Name + Surface, !- Outside Boundary Condition + Zn002:Wall005, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.5000000, !- View Factor to Ground + 4, !- Number of Vertices + 6.096000,6.096000,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 6.096000,6.096000,0, !- X,Y,Z ==> Vertex 2 {m} + 9.144000,6.096000,0, !- X,Y,Z ==> Vertex 3 {m} + 9.144000,6.096000,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn003:Flr001, !- Name + Floor, !- Surface Type + FLOOR SLAB 8 IN, !- Construction Name + NORTH ZONE, !- Zone Name + Surface, !- Outside Boundary Condition + Zn003:Flr001, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 1.000000, !- View Factor to Ground + 4, !- Number of Vertices + 0,6.096000,0, !- X,Y,Z ==> Vertex 1 {m} + 0,12.19200,0, !- X,Y,Z ==> Vertex 2 {m} + 9.144000,12.19200,0, !- X,Y,Z ==> Vertex 3 {m} + 9.144000,6.096000,0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + Zn003:Roof001, !- Name + Roof, !- Surface Type + ROOF34, !- Construction Name + NORTH ZONE, !- Zone Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0, !- View Factor to Ground + 4, !- Number of Vertices + 0,12.19200,3.048000, !- X,Y,Z ==> Vertex 1 {m} + 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 2 {m} + 9.144000,6.096000,3.048000, !- X,Y,Z ==> Vertex 3 {m} + 9.144000,12.19200,3.048000; !- X,Y,Z ==> Vertex 4 {m} + + Construction, + Dbl Clr 3mm/13mm Air, !- Name + CLEAR 3MM, !- Outside Layer + AIR 13MM, !- Layer 2 + CLEAR 3MM; !- Layer 3 + """ -BuildingSurface:Detailed, - Zn003:Roof001, !- Name - Roof, !- Surface Type - ROOF34, !- Construction Name - NORTH ZONE, !- Zone Name - Outdoors, !- Outside Boundary Condition - , !- Outside Boundary Condition Object - SunExposed, !- Sun Exposure - WindExposed, !- Wind Exposure - 0, !- View Factor to Ground - 4, !- Number of Vertices - 0,12.19200,3.048000, !- X,Y,Z ==> Vertex 1 {m} - 0,6.096000,3.048000, !- X,Y,Z ==> Vertex 2 {m} - 9.144000,6.096000,3.048000, !- X,Y,Z ==> Vertex 3 {m} - 9.144000,12.19200,3.048000; !- X,Y,Z ==> Vertex 4 {m} - - Construction, - Dbl Clr 3mm/13mm Air, !- Name - CLEAR 3MM, !- Outside Layer - AIR 13MM, !- Layer 2 - CLEAR 3MM; !- Layer 3 -""" + yield idftxt -def test_EpBunch(): - """py.test for EpBunch""" +def test_EpBunch(iddtxt, idftxt): + """py.test for EpBunch + """ iddfile = StringIO(iddtxt) fname = StringIO(idftxt) @@ -590,6 +602,39 @@ def test_EpBunch(): assert bconstr["Layer_10"] == "" +def test_EpBunch1(iddtxt): + """py.test for EpBunch1 + """ + iddfile = StringIO(iddtxt) + idffile = StringIO(bldfidf) + block, data, commdct, idd_index = readidf.readdatacommdct1(idffile, iddfile=iddfile) + key = "BUILDING" + objs = data.dt[key] + obj = objs[0] + obj_i = data.dtls.index(key) + bunchobj = idfreader.makeabunch(commdct, obj, obj_i) + + # assertions + assert bunchobj.Name == "Empire State Building" + bunchobj.Name = "Kutub Minar" + assert bunchobj.Name == "Kutub Minar" + prnt = bunchobj.__repr__() + result = """ +BUILDING, + Kutub Minar, !- Name + 30.0, !- North Axis + City, !- Terrain + 0.04, !- Loads Convergence Tolerance Value + 0.4, !- Temperature Convergence Tolerance Value + FullExterior, !- Solar Distribution + 25, !- Maximum Number of Warmup Days + 6; !- Minimum Number of Warmup Days +""" + assert prnt == result + # print bunchobj.objidd + # assert 1 == 0 + + def test_extendlist(): """py.test for extendlist""" data = ( @@ -604,12 +649,26 @@ def test_extendlist(): class TestEpBunch(object): - """ - py.test for EpBunch.getrange, EpBunch.checkrange, EpBunch.fieldnames, + """py.test for EpBunch.getrange, EpBunch.checkrange, EpBunch.fieldnames, EpBunch.fieldvalues, EpBunch.getidd. - """ + @pytest.fixture() + def IDF(self): + from eppy.modeleditor import IDF + + # idd is read only once in this test + # if it has already been read from some other test, it will continue with + # the old reading + iddfhandle = StringIO(iddcurrent.iddtxt) + if IDF.getiddname() is None: + IDF.setiddname(iddfhandle) + + yield IDF + + del IDF + + @pytest.fixture() def initdata(self): obj, objls, objidd = ( [ @@ -672,31 +731,29 @@ def initdata(self): }, ], ) - return obj, objls, objidd + yield obj, objls, objidd - def test_fieldnames(self): - """ - Test that the contents of idfobject.fieldnames are the same as those + def test_fieldnames(self, initdata): + """Test that the contents of idfobject.fieldnames are the same as those of objls. - """ - obj, objls, objidd = self.initdata() + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) for fn_item, objls_item in zip(idfobject.fieldnames, idfobject.objls): assert fn_item == objls_item - def test_fieldvalues(self): - """ - Test that the contents of idfobject.fieldvalues are the same as those + def test_fieldvalues(self, initdata): + """Test that the contents of idfobject.fieldvalues are the same as those of obj. - """ - obj, objls, objidd = self.initdata() + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) for fv_item, objls_item in zip(idfobject.fieldvalues, idfobject.obj): assert fv_item == objls_item - def test_getrange(self): + def test_getrange(self, initdata): + """ + """ data = ( ( "Loads_Convergence_Tolerance_Value", @@ -719,13 +776,15 @@ def test_getrange(self): }, ), # fieldname, theranges ) - obj, objls, objidd = self.initdata() + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) for fieldname, theranges in data: result = idfobject.getrange(fieldname) assert result == theranges - def test_checkrange(self): + def test_checkrange(self, initdata): + """ + """ data = ( ("Minimum_Number_of_Warmup_Days", 4, False, None), # fieldname, fieldvalue, isexception, theexception @@ -761,7 +820,7 @@ def test_checkrange(self): ("key", "BUILDING", False, None), # fieldname, fieldvalue, isexception, theexception ) - obj, objls, objidd = self.initdata() + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) for fieldname, fieldvalue, isexception, theexception in data: idfobject[fieldname] = fieldvalue @@ -772,18 +831,20 @@ def test_checkrange(self): with pytest.raises(theexception): result = idfobject.checkrange(fieldname) - def test_getfieldidd(self): - """py.test for getfieldidd""" - obj, objls, objidd = self.initdata() + def test_getfieldidd(self, initdata): + """py.test for getfieldidd + """ + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) result = idfobject.getfieldidd("North_Axis") assert result == {"type": ["real"]} result = idfobject.getfieldidd("No_such_field") assert result == {} - def test_getfieldidd_item(self): - """py.test for test_getfieldidd_item""" - obj, objls, objidd = self.initdata() + def test_getfieldidd_item(self, initdata): + """py.test for test_getfieldidd_item + """ + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) result = idfobject.getfieldidd_item("North_Axis", "type") assert result == ["real"] @@ -792,18 +853,42 @@ def test_getfieldidd_item(self): result = idfobject.getfieldidd_item("no_such_field", "type") assert result == [] - def test_get_retaincase(self): - """py.test for get_retaincase""" - obj, objls, objidd = self.initdata() + def test_get_retaincase(self, initdata): + """py.test for get_retaincase + """ + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) result = idfobject.get_retaincase("Name") assert result == True result = idfobject.get_retaincase("Terrain") assert result == False - def test_isequal(self): - """py.test for isequal""" - obj, objls, objidd = self.initdata() + def test_get_default(self, test_idf): + """py.test for __getattr__ when a value is not defined in the idf file. + We create a new MATERIAL object that does not define the + Solar_Absorptance, Thermal_Absorptance and Visible_Absorptance fields + and assert that their default value is returned + """ + test_idf.newidfobject( + "MATERIAL", + Name="F08 Metal surface", + Roughness="Smooth", + Thickness=0.0008, + Conductivity=45.28, + Density=7824.0, + Specific_Heat=500.0, + ) + + idfobject = test_idf.getobject("MATERIAL", "F08 Metal surface") + + assert idfobject.Solar_Absorptance == 0.7 + assert idfobject.Thermal_Absorptance == 0.9 + assert idfobject.Visible_Absorptance == 0.7 + + def test_isequal(self, initdata): + """py.test for isequal + """ + obj, objls, objidd = initdata idfobject = EpBunch(obj, objls, objidd) # test Terrain -> Alphanumeric, no retaincase result = idfobject.isequal("Terrain", "City") @@ -835,8 +920,9 @@ def test_isequal(self): result = idfobject.isequal("Maximum_Number_of_Warmup_Days", 25.00001) assert result == False - def test_getreferingobjs(self): - """py.test for getreferingobjs""" + def test_getreferingobjs(self, IDF): + """py.test for getreferingobjs + """ thedata = ( ( """ Zone, @@ -972,7 +1058,7 @@ def test_getreferingobjs(self): surfnamelst.sort() assert rnames == windownamelist - def test_get_referenced_object(self): + def test_get_referenced_object(self, IDF): """py.test for get_referenced_object""" idf = IDF() idf.initnew("test.idf") @@ -1007,6 +1093,10 @@ def test_get_referenced_object(self): assert material == expected +# test_EpBunch1() +# import idfreader + + bldfidf = """ Version, 6.0; @@ -1037,37 +1127,3 @@ def test_get_referenced_object(self): 6.096000,0,0, !- X,Y,Z ==> Vertex 3 {m} 6.096000,0,3.048000; !- X,Y,Z ==> Vertex 4 {m} """ -# test_EpBunch1() -# import idfreader - - -def test_EpBunch1(): - """py.test for EpBunch1""" - iddfile = StringIO(iddtxt) - idffile = StringIO(bldfidf) - block, data, commdct, idd_index = readidf.readdatacommdct1(idffile, iddfile=iddfile) - key = "BUILDING" - objs = data.dt[key] - obj = objs[0] - obj_i = data.dtls.index(key) - bunchobj = idfreader.makeabunch(commdct, obj, obj_i) - - # assertions - assert bunchobj.Name == "Empire State Building" - bunchobj.Name = "Kutub Minar" - assert bunchobj.Name == "Kutub Minar" - prnt = bunchobj.__repr__() - result = """ -BUILDING, - Kutub Minar, !- Name - 30.0, !- North Axis - City, !- Terrain - 0.04, !- Loads Convergence Tolerance Value - 0.4, !- Temperature Convergence Tolerance Value - FullExterior, !- Solar Distribution - 25, !- Maximum Number of Warmup Days - 6; !- Minimum Number of Warmup Days -""" - assert prnt == result - # print bunchobj.objidd - # assert 1 == 0 From 610a34593e02ff1ab62538320ffaa24b2403c408 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 12:09:25 -0400 Subject: [PATCH 04/15] Since __getattr__ now returns the default value when a fieldvalue is not provided, asserting that Do_Zone_Sizing_Calculation will return "No" weather or not defaultvalues=True or False. Although the repr() of the EpBunch still behaves properly and won't print the default values. I think this is the correct behavior. --- eppy/tests/test_modeleditor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eppy/tests/test_modeleditor.py b/eppy/tests/test_modeleditor.py index d9cef00c..1c0b79ac 100644 --- a/eppy/tests/test_modeleditor.py +++ b/eppy/tests/test_modeleditor.py @@ -328,7 +328,8 @@ def test_newidfobject(): sim_deftrue = idf.newidfobject("SimulationControl".upper(), defaultvalues=True) assert sim_deftrue.Do_Zone_Sizing_Calculation == "No" sim_deffalse = idf.newidfobject("SimulationControl".upper(), defaultvalues=False) - assert sim_deffalse.Do_Zone_Sizing_Calculation == "" + assert sim_deffalse.Do_Zone_Sizing_Calculation == "No" + assert str(sim_deffalse) == "\n SIMULATIONCONTROL,;\n" def test_newidfobject_warning(): From 7d3ccf4a519e499310f5e9697705408012441809 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 12:21:19 -0400 Subject: [PATCH 05/15] Adds more types to parse_idd_type --- eppy/bunch_subclass.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/eppy/bunch_subclass.py b/eppy/bunch_subclass.py index f034879c..b4bb613c 100644 --- a/eppy/bunch_subclass.py +++ b/eppy/bunch_subclass.py @@ -402,12 +402,24 @@ def __dir__(self): def _parse_idd_type(epbunch, name): """parse the fieldvalue type into a python type. eg.: 'real' returns - 'float'""" - _type = next(iter(epbunch.getfieldidd(name)["type"]), None) + 'float'. + + Possible types are: + - integer -> int + - real -> float + - alpha -> str (arbitrary string), + - choice -> str (alpha with specific list of choices, see \key) + - object-list -> str (link to a list of objects defined elsewhere, see \object-list and \reference) + - external-list -> str (uses a special list from an external source, see \external-list) + - node -> str (name used in connecting HVAC components) + """ + _type = next(iter(epbunch.getfieldidd(name)["type"]), "").lower() if _type == "real": return float elif _type == "alpha": return str + elif _type == "integer": + return int else: return str From 4f9ea7ae1332ba5f141cb4a3393b7f1c534089be Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 13:28:28 -0400 Subject: [PATCH 06/15] Extends the default logic to all returned values that are equal to an empty string If an empty string is returned, will try to return the default value instead if it exists. This behavior is compatible with the the way EnergyPlus handles missing fields --- eppy/bunch_subclass.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/eppy/bunch_subclass.py b/eppy/bunch_subclass.py index b4bb613c..970a393d 100644 --- a/eppy/bunch_subclass.py +++ b/eppy/bunch_subclass.py @@ -319,19 +319,26 @@ def __getattr__(self, name): elif name in self.fieldnames: i = self.fieldnames.index(name) try: - return self.fieldvalues[i] + i_ = self.fieldvalues[i] + if i_ == "": + return self.get_default(name) + else: + return i_ except IndexError: # try to return the default value if defined in IDD. - if "default" in self.getfieldidd(name).keys(): - _type = _parse_idd_type(self, name) - default_ = next(iter(self.getfieldidd(name)["default"]), None) - return _type(default_) - else: - return "" + return self.get_default(name) else: astr = "unable to find field %s" % (name,) raise BadEPFieldError(astr) + def get_default(self, name): + if "default" in self.getfieldidd(name).keys(): + _type = _parse_idd_type(self, name) + default_ = next(iter(self.getfieldidd_item(name, "default")), None) + return _type(default_) + else: + return "" + def __getitem__(self, key): if key in ("obj", "objls", "objidd", "__functions", "__aliases", "theidf"): return super(EpBunch, self).__getitem__(key) @@ -413,7 +420,7 @@ def _parse_idd_type(epbunch, name): - external-list -> str (uses a special list from an external source, see \external-list) - node -> str (name used in connecting HVAC components) """ - _type = next(iter(epbunch.getfieldidd(name)["type"]), "").lower() + _type = next(iter(epbunch.getfieldidd_item(name, "type")), "").lower() if _type == "real": return float elif _type == "alpha": From a4ec70931a948a1e4f7a1bac55691b73e9361d67 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 13:28:39 -0400 Subject: [PATCH 07/15] Adds another test --- eppy/tests/test_bunch_subclass.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/eppy/tests/test_bunch_subclass.py b/eppy/tests/test_bunch_subclass.py index 327da4fe..6affbe6c 100644 --- a/eppy/tests/test_bunch_subclass.py +++ b/eppy/tests/test_bunch_subclass.py @@ -885,6 +885,29 @@ def test_get_default(self, test_idf): assert idfobject.Thermal_Absorptance == 0.9 assert idfobject.Visible_Absorptance == 0.7 + def test_get_default_choice(self, test_idf): + """py.test for __getattr__ when a value is not defined in the idf file. + We create a new MATERIAL object that does not define the + Solar_Absorptance, Thermal_Absorptance and Visible_Absorptance fields + and assert that their default value is returned + """ + surf_1 = test_idf.newidfobject( + "BuildingSurface:Detailed", Name="surface 1", defaultvalues=False + ) + + # even though default values is set to false, Sun_Exposure and + # Number_of_Vertices should assert to True since they have default values in + # the idd + assert surf_1.Sun_Exposure == "SunExposed" + assert surf_1.Number_of_Vertices == "autocalculate" + + surf_2 = test_idf.newidfobject( + "BuildingSurface:Detailed", Name="surface 2", defaultvalues=True + ) + + assert surf_2.Sun_Exposure == "SunExposed" + assert surf_2.Number_of_Vertices == "autocalculate" + def test_isequal(self, initdata): """py.test for isequal """ From b713149d1f02cff026d05d49885f44ec8d5adfb6 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 13:50:56 -0400 Subject: [PATCH 08/15] Fixes an issue where run errors could not be read because of suffix different than "eplus" Now uses glob with a wildcard to catch the first *out.err file --- eppy/runner/run_functions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eppy/runner/run_functions.py b/eppy/runner/run_functions.py index 4dd038a7..bc579839 100644 --- a/eppy/runner/run_functions.py +++ b/eppy/runner/run_functions.py @@ -12,6 +12,7 @@ from __future__ import print_function from __future__ import unicode_literals +import glob import os import platform import pydoc @@ -361,7 +362,8 @@ def parse_error(output_dir): """ sys.stderr.seek(0) std_err = sys.stderr.read().decode("utf-8") - err_file = os.path.join(output_dir, "eplusout.err") + err_file = os.path.join(output_dir, "*out.err") + err_file = next(iter(glob.glob(err_file)), None) if os.path.isfile(err_file): with open(err_file, "r") as f: ep_err = f.read() From fd8789cd8d807bb94b939bbeb20462feb7cd71fe Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 14:11:29 -0400 Subject: [PATCH 09/15] Adds expandobject=True to testrunners to assert tests Running these tests locally with env var EPPY_INTEGRATION=1 would throw errors on EnergyPlus' side; it asks for the expandobject subroutine --- eppy/tests/test_runner.py | 96 ++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 26 deletions(-) diff --git a/eppy/tests/test_runner.py b/eppy/tests/test_runner.py index 0fd2e74b..6b5a1124 100644 --- a/eppy/tests/test_runner.py +++ b/eppy/tests/test_runner.py @@ -223,33 +223,65 @@ def setup(self): "eplustbl.htm", "sqlite.err", ] + self.expected_files_prefix = [ + "sqlite.err", + "testout.audit", + "testout.bnd", + "testout.eio", + "testout.end", + "testout.err", + "testout.eso", + "testout.expidf", + "testout.mdd", + "testout.mtd", + "testout.rdd", + "testout.shd", + "testtbl.htm", + ] self.expected_files_suffix_C = [ "eplus.audit", - "eplus.mdd", - "eplus.err", - "eplusSqlite.err", - "eplus.eio", - "eplusTable.htm", - "eplus.shd", - "eplus.mtd", "eplus.bnd", + "eplus.eio", + "eplus.end", + "eplus.err", "eplus.eso", + "eplus.expidf", + "eplus.mdd", + "eplus.mtd", "eplus.rdd", - "eplus.end", + "eplus.shd", + "eplusSqlite.err", + "eplusTable.htm", ] self.expected_files_suffix_D = [ - "eplus.audit", - "eplus.mdd", "eplus-sqlite.err", "eplus-table.htm", - "eplus.err", - "eplus.eio", + "eplus.audit", "eplus.bnd", - "eplus.shd", - "eplus.mtd", + "eplus.eio", "eplus.end", + "eplus.err", "eplus.eso", + "eplus.expidf", + "eplus.mdd", + "eplus.mtd", "eplus.rdd", + "eplus.shd", + ] + self.expected_files_suffix_L = [ + "eplusout.audit", + "eplusout.bnd", + "eplusout.eio", + "eplusout.end", + "eplusout.err", + "eplusout.eso", + "eplusout.expidf", + "eplusout.mdd", + "eplusout.mtd", + "eplusout.rdd", + "eplusout.shd", + "eplustbl.htm", + "sqlite.err", ] def teardown(self): @@ -302,7 +334,12 @@ def test_run_annual(self, test_idf): """ test_idf.idfobjects["RUNPERIOD"][0].End_Month = 1 - test_idf.run(annual=True, readvars=True, output_directory="run_outputs") + test_idf.run( + annual=True, + readvars=True, + output_directory="run_outputs", + expandobjects=True, + ) assert not has_severe_errors() files = os.listdir("run_outputs") self.expected_files.extend(["eplusout.rvaudit", "eplusout.csv"]) @@ -374,11 +411,12 @@ def test_run_output_prefix(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run(output_prefix="test", output_directory="run_outputs") + test_idf.run( + output_prefix="test", output_directory="run_outputs", expandobjects=True + ) assert not has_severe_errors() files = os.listdir("run_outputs") - prefixed_files = [f.replace("eplus", "test") for f in self.expected_files] - assert set(files) == set(prefixed_files) + assert set(files) == set(self.expected_files_prefix) def test_run_output_suffix_L(self, test_idf): """ @@ -386,10 +424,12 @@ def test_run_output_suffix_L(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run(output_suffix="L", output_directory="run_outputs") + test_idf.run( + output_suffix="L", output_directory="run_outputs", expandobjects=True + ) assert not has_severe_errors() files = os.listdir("run_outputs") - assert set(files) == set(self.expected_files) + assert set(files) == set(self.expected_files_suffix_L) def test_run_output_suffix_C(self, test_idf): """ @@ -397,7 +437,9 @@ def test_run_output_suffix_C(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run(output_suffix="C", output_directory="run_outputs") + test_idf.run( + output_suffix="C", output_directory="run_outputs", expandobjects=True + ) assert not has_severe_errors() files = os.listdir("run_outputs") assert set(files) == set(self.expected_files_suffix_C) @@ -408,7 +450,9 @@ def test_run_output_suffix_D(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run(output_suffix="D", output_directory="run_outputs") + test_idf.run( + output_suffix="D", output_directory="run_outputs", expandobjects=True + ) assert not has_severe_errors() files = os.listdir("run_outputs") assert set(files) == set(self.expected_files_suffix_D) @@ -464,10 +508,10 @@ def test_verbose(self, capfd, test_idf): Fails if no output received from EnergyPlus. """ - test_idf.run(verbose="v", output_directory="run_outputs") + test_idf.run(verbose="v", output_directory="run_outputs", expandobjects=True) assert not has_severe_errors() files = os.listdir("run_outputs") - self.expected_files.extend([]) + self.expected_files.extend(["eplusout.expidf"]) assert set(files) == set(self.expected_files) out, _err = capfd.readouterr() assert len(out) > 0 @@ -479,10 +523,10 @@ def test_quiet(self, capfd, test_idf): Fails if output received from EnergyPlus. """ - test_idf.run(verbose="q", output_directory="run_outputs") + test_idf.run(verbose="q", output_directory="run_outputs", expandobjects=True) assert not has_severe_errors() files = os.listdir("run_outputs") - self.expected_files.extend([]) + self.expected_files.extend(["eplusout.expidf"]) assert set(files) == set(self.expected_files) out, _err = capfd.readouterr() assert len(out) == 0 From a0d2ef50797bd83e9835809d4c2daaca1cdfdb9f Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Tue, 6 Aug 2019 14:11:29 -0400 Subject: [PATCH 10/15] Revert "Adds expandobject=True to testrunners to assert tests" This reverts commit fd8789cd8d807bb94b939bbeb20462feb7cd71fe. --- eppy/tests/test_runner.py | 96 +++++++++++---------------------------- 1 file changed, 26 insertions(+), 70 deletions(-) diff --git a/eppy/tests/test_runner.py b/eppy/tests/test_runner.py index 8d62df77..89b5d6d9 100644 --- a/eppy/tests/test_runner.py +++ b/eppy/tests/test_runner.py @@ -223,65 +223,33 @@ def setup(self): "eplustbl.htm", "sqlite.err", ] - self.expected_files_prefix = [ - "sqlite.err", - "testout.audit", - "testout.bnd", - "testout.eio", - "testout.end", - "testout.err", - "testout.eso", - "testout.expidf", - "testout.mdd", - "testout.mtd", - "testout.rdd", - "testout.shd", - "testtbl.htm", - ] self.expected_files_suffix_C = [ "eplus.audit", - "eplus.bnd", - "eplus.eio", - "eplus.end", - "eplus.err", - "eplus.eso", - "eplus.expidf", "eplus.mdd", - "eplus.mtd", - "eplus.rdd", - "eplus.shd", + "eplus.err", "eplusSqlite.err", + "eplus.eio", "eplusTable.htm", + "eplus.shd", + "eplus.mtd", + "eplus.bnd", + "eplus.eso", + "eplus.rdd", + "eplus.end", ] self.expected_files_suffix_D = [ + "eplus.audit", + "eplus.mdd", "eplus-sqlite.err", "eplus-table.htm", - "eplus.audit", - "eplus.bnd", + "eplus.err", "eplus.eio", + "eplus.bnd", + "eplus.shd", + "eplus.mtd", "eplus.end", - "eplus.err", "eplus.eso", - "eplus.expidf", - "eplus.mdd", - "eplus.mtd", "eplus.rdd", - "eplus.shd", - ] - self.expected_files_suffix_L = [ - "eplusout.audit", - "eplusout.bnd", - "eplusout.eio", - "eplusout.end", - "eplusout.err", - "eplusout.eso", - "eplusout.expidf", - "eplusout.mdd", - "eplusout.mtd", - "eplusout.rdd", - "eplusout.shd", - "eplustbl.htm", - "sqlite.err", ] def teardown(self): @@ -334,12 +302,7 @@ def test_run_annual(self, test_idf): """ test_idf.idfobjects["RUNPERIOD"][0].End_Month = 1 - test_idf.run( - annual=True, - readvars=True, - output_directory="run_outputs", - expandobjects=True, - ) + test_idf.run(annual=True, readvars=True, output_directory="run_outputs") assert not has_severe_errors() files = os.listdir("run_outputs") self.expected_files.extend(["eplusout.rvaudit", "eplusout.csv"]) @@ -431,12 +394,11 @@ def test_run_output_prefix(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run( - output_prefix="test", output_directory="run_outputs", expandobjects=True - ) + test_idf.run(output_prefix="test", output_directory="run_outputs") assert not has_severe_errors() files = os.listdir("run_outputs") - assert set(files) == set(self.expected_files_prefix) + prefixed_files = [f.replace("eplus", "test") for f in self.expected_files] + assert set(files) == set(prefixed_files) def test_run_output_suffix_L(self, test_idf): """ @@ -444,12 +406,10 @@ def test_run_output_suffix_L(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run( - output_suffix="L", output_directory="run_outputs", expandobjects=True - ) + test_idf.run(output_suffix="L", output_directory="run_outputs") assert not has_severe_errors() files = os.listdir("run_outputs") - assert set(files) == set(self.expected_files_suffix_L) + assert set(files) == set(self.expected_files) def test_run_output_suffix_C(self, test_idf): """ @@ -457,9 +417,7 @@ def test_run_output_suffix_C(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run( - output_suffix="C", output_directory="run_outputs", expandobjects=True - ) + test_idf.run(output_suffix="C", output_directory="run_outputs") assert not has_severe_errors() files = os.listdir("run_outputs") assert set(files) == set(self.expected_files_suffix_C) @@ -470,9 +428,7 @@ def test_run_output_suffix_D(self, test_idf): Fails on severe errors or unexpected/missing output files. """ - test_idf.run( - output_suffix="D", output_directory="run_outputs", expandobjects=True - ) + test_idf.run(output_suffix="D", output_directory="run_outputs") assert not has_severe_errors() files = os.listdir("run_outputs") assert set(files) == set(self.expected_files_suffix_D) @@ -528,10 +484,10 @@ def test_verbose(self, capfd, test_idf): Fails if no output received from EnergyPlus. """ - test_idf.run(verbose="v", output_directory="run_outputs", expandobjects=True) + test_idf.run(verbose="v", output_directory="run_outputs") assert not has_severe_errors() files = os.listdir("run_outputs") - self.expected_files.extend(["eplusout.expidf"]) + self.expected_files.extend([]) assert set(files) == set(self.expected_files) out, _err = capfd.readouterr() assert len(out) > 0 @@ -543,10 +499,10 @@ def test_quiet(self, capfd, test_idf): Fails if output received from EnergyPlus. """ - test_idf.run(verbose="q", output_directory="run_outputs", expandobjects=True) + test_idf.run(verbose="q", output_directory="run_outputs") assert not has_severe_errors() files = os.listdir("run_outputs") - self.expected_files.extend(["eplusout.expidf"]) + self.expected_files.extend([]) assert set(files) == set(self.expected_files) out, _err = capfd.readouterr() assert len(out) == 0 From e6375acd9168477208d969aa451282a25184d592 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Wed, 8 Jul 2020 12:32:26 -0400 Subject: [PATCH 11/15] Black --- docs/Main_Tutorial.py | 4 ++-- docs/Outputs_Tutorial.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/Main_Tutorial.py b/docs/Main_Tutorial.py index 48b77de2..5739c4c2 100644 --- a/docs/Main_Tutorial.py +++ b/docs/Main_Tutorial.py @@ -1336,8 +1336,8 @@ # change the construction in the exterior north walls for wall in exterior_nwall: wall.Construction_Name = ( - "NORTHERN-WALL" - ) # make sure such a construction exists in the model + "NORTHERN-WALL" # make sure such a construction exists in the model + ) # diff --git a/docs/Outputs_Tutorial.py b/docs/Outputs_Tutorial.py index 76e4e735..9e575d43 100644 --- a/docs/Outputs_Tutorial.py +++ b/docs/Outputs_Tutorial.py @@ -50,9 +50,7 @@ from eppy import readhtml # the eppy module with functions to read the html -fname = ( - "../eppy/resources/outputfiles/V_7_2/5ZoneCAVtoVAVWarmestTempFlowTable_ABUPS.html" -) # the html file you want to read +fname = "../eppy/resources/outputfiles/V_7_2/5ZoneCAVtoVAVWarmestTempFlowTable_ABUPS.html" # the html file you want to read filehandle = open(fname, "r").read() # get a file handle to the html file From 1422b91b53a476e4847a3539b089212db9fb08a5 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Wed, 2 Sep 2020 19:21:26 -0400 Subject: [PATCH 12/15] addresses issue #303 --- eppy/bunchhelpers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/eppy/bunchhelpers.py b/eppy/bunchhelpers.py index 8d6909af..71828365 100644 --- a/eppy/bunchhelpers.py +++ b/eppy/bunchhelpers.py @@ -14,10 +14,9 @@ from string import ascii_letters, digits -def onlylegalchar(name): +def onlylegalchar(name: str): """return only legal chars""" - legalchar = ascii_letters + digits + " " - return "".join([s for s in name[:] if s in legalchar]) + return name.encode('ascii', 'ignore').decode() def makefieldname(namefromidd): From 8f8eba0497cdb05a830a4c414f2046e7e83f52f5 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Thu, 3 Sep 2020 14:07:39 -0400 Subject: [PATCH 13/15] Moves the creation of the IDD index and the addition of idd groups to the `extractidddata` --- eppy/EPlusInterfaceFunctions/parse_idd.py | 14 +++++++++++--- eppy/EPlusInterfaceFunctions/readidf.py | 8 ++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/eppy/EPlusInterfaceFunctions/parse_idd.py b/eppy/EPlusInterfaceFunctions/parse_idd.py index 62a8072d..96ef65e7 100755 --- a/eppy/EPlusInterfaceFunctions/parse_idd.py +++ b/eppy/EPlusInterfaceFunctions/parse_idd.py @@ -140,8 +140,6 @@ def embedgroupdata(extract_func, fname, debug): return blocklst, commlst, commdct -@make_idd_index -@embedgroupdata def extractidddata(fname, debug=False): """ extracts all the needed information out of the idd file @@ -375,7 +373,17 @@ def extractidddata(fname, debug=False): # commlst = group2commlst(commlst, glist) # commdct = group2commdct(commdct, glist) - return blocklst, commlst, commdct + # Make IDD Index + name2refs = iddindex.makename2refdct(commdct) + ref2namesdct = iddindex.makeref2namesdct(name2refs) + idd_index = dict(name2refs=name2refs, ref2names=ref2namesdct) + + # add group information to commlst and commdct + glist = iddgroups.iddtxt2grouplist(astr) + commlst = iddgroups.group2commlst(commlst, glist) + commdct = iddgroups.group2commdct(commdct, glist) + + return blocklst, commlst, commdct, idd_index # give blocklst a better name :-( diff --git a/eppy/EPlusInterfaceFunctions/readidf.py b/eppy/EPlusInterfaceFunctions/readidf.py index c3b4127c..c6314ba3 100755 --- a/eppy/EPlusInterfaceFunctions/readidf.py +++ b/eppy/EPlusInterfaceFunctions/readidf.py @@ -25,7 +25,7 @@ def readidf(idfname): iddfile = "Energy+.idd" # iddfile = './EPlusInterfaceFunctions/E1.idd' # TODO : can the path name be not hard coded iddtxt = open(iddfile, "r").read() - block, commlst, commdct = parse_idd.extractidddata(iddfile) + block, commlst, commdct, idd_index = parse_idd.extractidddata(iddfile) theidd = eplusdata.Idd(block, 2) data = eplusdata.Eplusdata(theidd, idfname) @@ -38,7 +38,7 @@ def readiddidf(idfname): iddfile = "Energy+.idd" # iddfile = './EPlusInterfaceFunctions/E1.idd' # TODO : can the path name be not hard coded iddtxt = open(iddfile, "r").read() - block, commlst, commdct = parse_idd.extractidddata(iddfile) + block, commlst, commdct, idd_index = parse_idd.extractidddata(iddfile) theidd = eplusdata.Idd(block, 2) data = eplusdata.Eplusdata(theidd, idfname) @@ -51,7 +51,7 @@ def readiddstuff(idfname): iddfile = "Energy+.idd" # iddfile = './EPlusInterfaceFunctions/E1.idd' # TODO : can the path name be not hard coded iddtxt = open(iddfile, "r").read() - block, commlst, commdct = parse_idd.extractidddata(iddfile) + block, commlst, commdct, idd_index = parse_idd.extractidddata(iddfile) theidd = eplusdata.Idd(block, 2) data = eplusdata.Eplusdata(theidd, idfname) @@ -64,7 +64,7 @@ def readdatacommlst(idfname): iddfile = "Energy+.idd" # iddfile = './EPlusInterfaceFunctions/E1.idd' # TODO : can the path name be not hard coded iddtxt = open(iddfile, "r").read() - block, commlst, commdct = parse_idd.extractidddata(iddfile) + block, commlst, commdct, idd_index = parse_idd.extractidddata(iddfile) theidd = eplusdata.Idd(block, 2) data = eplusdata.Eplusdata(theidd, idfname) From cab7bda032a99ca4cd7ded47d4c69c2e57d12285 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Thu, 3 Sep 2020 15:22:00 -0400 Subject: [PATCH 14/15] Using regex improves speed (a little bit slower then encode/decode) but keeps same behavior tests are happy --- eppy/bunchhelpers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eppy/bunchhelpers.py b/eppy/bunchhelpers.py index a985ec97..da353c35 100644 --- a/eppy/bunchhelpers.py +++ b/eppy/bunchhelpers.py @@ -11,12 +11,13 @@ from __future__ import print_function from __future__ import unicode_literals -from string import ascii_letters, digits +import re +pattern = re.compile(r"[^a-zA-Z0-9\s]+") def onlylegalchar(name: str): """return only legal chars""" - return name.encode('ascii', 'ignore').decode() + return pattern.sub("", name) def makefieldname(namefromidd): From 588b3fef1a62f2d6e6574c4708b7f3c2b92e5794 Mon Sep 17 00:00:00 2001 From: Samuel Letellier-Duchesne Date: Thu, 3 Sep 2020 15:35:57 -0400 Subject: [PATCH 15/15] group info must happen before idd_index --- eppy/EPlusInterfaceFunctions/parse_idd.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/eppy/EPlusInterfaceFunctions/parse_idd.py b/eppy/EPlusInterfaceFunctions/parse_idd.py index 96ef65e7..0b75818f 100755 --- a/eppy/EPlusInterfaceFunctions/parse_idd.py +++ b/eppy/EPlusInterfaceFunctions/parse_idd.py @@ -373,16 +373,17 @@ def extractidddata(fname, debug=False): # commlst = group2commlst(commlst, glist) # commdct = group2commdct(commdct, glist) - # Make IDD Index - name2refs = iddindex.makename2refdct(commdct) - ref2namesdct = iddindex.makeref2namesdct(name2refs) - idd_index = dict(name2refs=name2refs, ref2names=ref2namesdct) - # add group information to commlst and commdct glist = iddgroups.iddtxt2grouplist(astr) commlst = iddgroups.group2commlst(commlst, glist) commdct = iddgroups.group2commdct(commdct, glist) + # Make IDD Index + name2refs = iddindex.makename2refdct(commdct) + ref2namesdct = iddindex.makeref2namesdct(name2refs) + idd_index = dict(name2refs=name2refs, ref2names=ref2namesdct) + commdct = iddindex.ref2names2commdct(ref2namesdct, commdct) + return blocklst, commlst, commdct, idd_index # give blocklst a better name :-(