Ejemplo n.º 1
0
def test_EpBunch1():
    """py.test for EpBunch1"""
    iddfile = StringIO(iddtxt)
    idffile = StringIO(bldfidf)
    block, data, commdct = 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
Ejemplo n.º 2
0
def idfreader1(fname, iddfile, conv=True, commdct=None, block=None):
    """read idf file and reutrn bunches"""
    versiontuple = iddversiontuple(iddfile)
    # import pdbdb; pdb.set_trace()
    block, data, commdct = readidf.readdatacommdct1(fname,
                                                    iddfile=iddfile,
                                                    commdct=commdct,
                                                    block=block)
    if conv:
        convertallfields(data, commdct)
    # fill gaps in idd
    ddtt, dtls = data.dt, data.dtls
    if versiontuple < (8, ):
        skiplist = ["TABLE:MULTIVARIABLELOOKUP"]
    else:
        skiplist = None
    nofirstfields = iddgaps.missingkeys_standard(commdct,
                                                 dtls,
                                                 skiplist=skiplist)
    iddgaps.missingkeys_nonstandard(commdct, dtls, nofirstfields)
    bunchdt = makebunches(data, commdct)
    # TODO : add functions here.
    # -
    addfunctions(dtls, bunchdt)
    # -
    return bunchdt, block, data, commdct
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
def idfreader1(fname, iddfile, conv=True, commdct=None, block=None):
    """read idf file and reutrn bunches"""
    versiontuple = iddversiontuple(iddfile)
  # import pdbdb; pdb.set_trace()
    block, data, commdct = readidf.readdatacommdct1(
        fname,
        iddfile=iddfile,
        commdct=commdct,
        block=block)
    if conv:
        convertallfields(data, commdct)
    # fill gaps in idd
    ddtt, dtls = data.dt, data.dtls
    if versiontuple < (8, ):
        skiplist = ["TABLE:MULTIVARIABLELOOKUP"]
    else:
        skiplist = None
    nofirstfields = iddgaps.missingkeys_standard(
        commdct, dtls,
        skiplist=skiplist)
    iddgaps.missingkeys_nonstandard(commdct, dtls, nofirstfields)
    bunchdt = makebunches(data, commdct)
    # TODO : add functions here.
    # -
    addfunctions(dtls, bunchdt)
    # -
    return bunchdt, block, data, commdct
Ejemplo n.º 5
0
def test_convertallfields():
    """py.test convertallfields"""
    data = (
        ("version, 8.1;", 'VERSION', [u'version', u'8.1']),
        # idfstr, objkey, expected
        ("WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM, simple, 0.45;",
         'WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM',
         [u'WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM', 'simple', 0.45]),
        # idfstr, objkey, expected
        ("HVACTEMPLATE:ZONE:FANCOIL, gumby1, gumby2, 0.45;",
         'HVACTEMPLATE:ZONE:FANCOIL',
         [u'HVACTEMPLATE:ZONE:FANCOIL', 'gumby1', 'gumby2', 0.45]),
        # idfstr, objkey, expected
        ("HVACTEMPLATE:ZONE:FANCOIL, gumby1, gumby2, autosize;",
         'HVACTEMPLATE:ZONE:FANCOIL',
         [u'HVACTEMPLATE:ZONE:FANCOIL', 'gumby1', 'gumby2', 'autosize']),
        # idfstr, objkey, expected
    )
    commdct = None
    block = None
    for idfstr, objkey, expected in data:
        idfhandle = StringIO(idfstr)
        block, data, commdct, idd_index = readidf.readdatacommdct1(
            idfhandle, iddfile=iddfhandle, commdct=commdct, block=block)
        idfreader.convertallfields(data, commdct, block)
        result = data.dt[objkey][0]
        assert result == expected
Ejemplo n.º 6
0
def test_convertallfields():
    """py.test convertallfields"""
    data = (
        ("version, 8.1;", "VERSION", ["version", "8.1"]),
        # idfstr, objkey, expected
        (
            "WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM, simple, 0.45;",
            "WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM",
            ["WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM", "simple", 0.45],
        ),
        # idfstr, objkey, expected
        (
            "HVACTEMPLATE:ZONE:FANCOIL, gumby1, gumby2, 0.45;",
            "HVACTEMPLATE:ZONE:FANCOIL",
            ["HVACTEMPLATE:ZONE:FANCOIL", "gumby1", "gumby2", 0.45],
        ),
        # idfstr, objkey, expected
        (
            "HVACTEMPLATE:ZONE:FANCOIL, gumby1, gumby2, autosize;",
            "HVACTEMPLATE:ZONE:FANCOIL",
            ["HVACTEMPLATE:ZONE:FANCOIL", "gumby1", "gumby2", "autosize"],
        ),
        # idfstr, objkey, expected
    )
    commdct = None
    block = None
    for idfstr, objkey, expected in data:
        idfhandle = StringIO(idfstr)
        block, data, commdct, idd_index = readidf.readdatacommdct1(
            idfhandle, iddfile=iddfhandle, commdct=commdct, block=block)
        idfreader.convertallfields(data, commdct, block)
        result = data.dt[objkey][0]
        assert result == expected
Ejemplo n.º 7
0
def idfreader1(fname, iddfile, theidf, conv=True, commdct=None, block=None):
    """read idf file and return bunches"""
    versiontuple = iddversiontuple(iddfile)
    block, data, commdct, idd_index = readidf.readdatacommdct1(fname,
                                                               iddfile=iddfile,
                                                               commdct=commdct,
                                                               block=block)
    if conv:
        convertallfields(data, commdct)
    # fill gaps in idd
    ddtt, dtls = data.dt, data.dtls
    if versiontuple < (8, ):
        skiplist = ["TABLE:MULTIVARIABLELOOKUP"]
    else:
        skiplist = None
    nofirstfields = iddgaps.missingkeys_standard(commdct,
                                                 dtls,
                                                 skiplist=skiplist)
    iddgaps.missingkeys_nonstandard(commdct, dtls, nofirstfields)
    # bunchdt = makebunches(data, commdct)
    bunchdt = makebunches(data, commdct, theidf)

    return bunchdt, block, data, commdct, idd_index
Ejemplo n.º 8
0
def test_EpBunch():
    """py.test for EpBunch"""

    iddfile = StringIO(iddtxt)
    fname = StringIO(idftxt)
    block, data, commdct = readidf.readdatacommdct1(fname, iddfile=iddfile)

    # setup code walls - can be generic for any object
    ddtt = data.dt
    dtls = data.dtls
    wall_i = dtls.index('BuildingSurface:Detailed'.upper())
    wallkey = 'BuildingSurface:Detailed'.upper()
    wallidd = commdct[wall_i]

    dwalls = ddtt[wallkey]
    dwall = dwalls[0]

    wallfields = [comm.get('field') for comm in commdct[wall_i]]
    wallfields[0] = ['key']
    wallfields = [field[0] for field in wallfields]
    wall_fields = [bunchhelpers.makefieldname(field) for field in wallfields]
    assert wall_fields[:20] == [
        'key', 'Name', 'Surface_Type', 'Construction_Name', 'Zone_Name',
        'Outside_Boundary_Condition', 'Outside_Boundary_Condition_Object',
        'Sun_Exposure', 'Wind_Exposure', 'View_Factor_to_Ground',
        'Number_of_Vertices', 'Vertex_1_Xcoordinate', 'Vertex_1_Ycoordinate',
        'Vertex_1_Zcoordinate', 'Vertex_2_Xcoordinate', 'Vertex_2_Ycoordinate',
        'Vertex_2_Zcoordinate', 'Vertex_3_Xcoordinate', 'Vertex_3_Ycoordinate',
        'Vertex_3_Zcoordinate'
    ]

    bwall = EpBunch(dwall, wall_fields, wallidd)

    # print bwall.Name
    # print data.dt[wallkey][0][1]
    assert bwall.Name == data.dt[wallkey][0][1]
    bwall.Name = 'Gumby'
    # print bwall.Name
    # print data.dt[wallkey][0][1]
    # print
    assert bwall.Name == data.dt[wallkey][0][1]

    # set aliases
    bwall.__aliases = {'Constr': 'Construction_Name'}

    # print "wall.Construction_Name = %s" % (bwall.Construction_Name, )
    # print "wall.Constr = %s" % (bwall.Constr, )
    # print
    assert bwall.Construction_Name == bwall.Constr
    # print "change wall.Constr"
    bwall.Constr = 'AnewConstr'
    # print "wall.Constr = %s" % (bwall.Constr, )
    # print "wall.Constr = %s" % (data.dt[wallkey][0][3], )
    # print
    assert bwall.Constr == data.dt[wallkey][0][3]

    # add functions
    bwall.__functions = {'svalues': bunch_subclass.somevalues}

    # print bwall.svalues
    assert bwall.svalues == ('Gumby', 'AnewConstr', [
        'BuildingSurface:Detailed', 'Gumby', 'Wall', 'AnewConstr', 'West Zone',
        'Outdoors', '', 'SunExposed', 'WindExposed', '0.5000000', '4', '0',
        '0', '3.048000', '0', '0', '0', '6.096000', '0', '0', '6.096000', '0',
        '3.048000'
    ])

    # print bwall.__functions

    # test __getitem__
    assert bwall["Name"] == data.dt[wallkey][0][1]
    # test __setitem__
    newname = "loofah"
    bwall["Name"] = newname
    assert bwall.Name == newname
    assert bwall["Name"] == newname
    assert data.dt[wallkey][0][1] == newname
    # test functions and alias again
    assert bwall.Constr == data.dt[wallkey][0][3]
    assert bwall.svalues == (newname, 'AnewConstr', [
        'BuildingSurface:Detailed', newname, 'Wall', 'AnewConstr', 'West Zone',
        'Outdoors', '', 'SunExposed', 'WindExposed', '0.5000000', '4', '0',
        '0', '3.048000', '0', '0', '0', '6.096000', '0', '0', '6.096000', '0',
        '3.048000'
    ])
    # test bunch_subclass.BadEPFieldError
    with pytest.raises(bunch_subclass.BadEPFieldError):
        bwall.Name_atypo = "newname"
    with pytest.raises(bunch_subclass.BadEPFieldError):
        thename = bwall.Name_atypo
    with pytest.raises(bunch_subclass.BadEPFieldError):
        bwall["Name_atypo"] = "newname"
    with pytest.raises(bunch_subclass.BadEPFieldError):
        thename = bwall["Name_atypo"]

    # test where constr["obj"] has to be extended
    # more items are added to an extendible field
    constr_i = dtls.index('Construction'.upper())
    constrkey = 'Construction'.upper()
    constridd = commdct[constr_i]
    dconstrs = ddtt[constrkey]
    dconstr = dconstrs[0]
    constrfields = [comm.get('field') for comm in commdct[constr_i]]
    constrfields[0] = ['key']
    constrfields = [field[0] for field in constrfields]
    constr_fields = [
        bunchhelpers.makefieldname(field) for field in constrfields
    ]
    bconstr = EpBunch(dconstr, constr_fields, constridd)
    assert bconstr.Name == "Dbl Clr 3mm/13mm Air"
    bconstr.Layer_4 = "butter"
    assert bconstr.obj == [
        'Construction', 'Dbl Clr 3mm/13mm Air', 'CLEAR 3MM', 'AIR 13MM',
        'CLEAR 3MM', 'butter'
    ]
    bconstr.Layer_7 = "cheese"
    assert bconstr.obj == [
        'Construction', 'Dbl Clr 3mm/13mm Air', 'CLEAR 3MM', 'AIR 13MM',
        'CLEAR 3MM', 'butter', '', '', 'cheese'
    ]
    bconstr["Layer_8"] = "jam"
    assert bconstr.obj == [
        'Construction', 'Dbl Clr 3mm/13mm Air', 'CLEAR 3MM', 'AIR 13MM',
        'CLEAR 3MM', 'butter', '', '', 'cheese', 'jam'
    ]

    # retrieve a valid field that has no value
    assert bconstr.Layer_10 == ''
    assert bconstr["Layer_10"] == ''
Ejemplo n.º 9
0
def test_EpBunch():
    """py.test for EpBunch"""

    iddfile = StringIO(iddtxt)
    fname = StringIO(idftxt)
    block, data, commdct, idd_index = readidf.readdatacommdct1(fname, iddfile=iddfile)

    # setup code walls - can be generic for any object
    ddtt = data.dt
    dtls = data.dtls
    wall_i = dtls.index("BuildingSurface:Detailed".upper())
    wallkey = "BuildingSurface:Detailed".upper()
    wallidd = commdct[wall_i]

    dwalls = ddtt[wallkey]
    dwall = dwalls[0]

    wallfields = [comm.get("field") for comm in commdct[wall_i]]
    wallfields[0] = ["key"]
    wallfields = [field[0] for field in wallfields]
    wall_fields = [bunchhelpers.makefieldname(field) for field in wallfields]
    assert wall_fields[:20] == [
        "key",
        "Name",
        "Surface_Type",
        "Construction_Name",
        "Zone_Name",
        "Outside_Boundary_Condition",
        "Outside_Boundary_Condition_Object",
        "Sun_Exposure",
        "Wind_Exposure",
        "View_Factor_to_Ground",
        "Number_of_Vertices",
        "Vertex_1_Xcoordinate",
        "Vertex_1_Ycoordinate",
        "Vertex_1_Zcoordinate",
        "Vertex_2_Xcoordinate",
        "Vertex_2_Ycoordinate",
        "Vertex_2_Zcoordinate",
        "Vertex_3_Xcoordinate",
        "Vertex_3_Ycoordinate",
        "Vertex_3_Zcoordinate",
    ]

    bwall = EpBunch(dwall, wall_fields, wallidd)

    # print bwall.Name
    # print data.dt[wallkey][0][1]
    assert bwall.Name == data.dt[wallkey][0][1]
    bwall.Name = "Gumby"
    # print bwall.Name
    # print data.dt[wallkey][0][1]
    # print
    assert bwall.Name == data.dt[wallkey][0][1]

    # set aliases
    bwall.__aliases = {"Constr": "Construction_Name"}

    # print "wall.Construction_Name = %s" % (bwall.Construction_Name, )
    # print "wall.Constr = %s" % (bwall.Constr, )
    # print
    assert bwall.Construction_Name == bwall.Constr
    # print "change wall.Constr"
    bwall.Constr = "AnewConstr"
    # print "wall.Constr = %s" % (bwall.Constr, )
    # print "wall.Constr = %s" % (data.dt[wallkey][0][3], )
    # print
    assert bwall.Constr == data.dt[wallkey][0][3]

    # add functions
    bwall.__functions = {"svalues": bunch_subclass.somevalues}
    assert "svalues" in bwall.__functions

    # print bwall.svalues
    assert bwall.svalues == (
        "Gumby",
        "AnewConstr",
        [
            "BuildingSurface:Detailed",
            "Gumby",
            "Wall",
            "AnewConstr",
            "West Zone",
            "Outdoors",
            "",
            "SunExposed",
            "WindExposed",
            "0.5000000",
            "4",
            "0",
            "0",
            "3.048000",
            "0",
            "0",
            "0",
            "6.096000",
            "0",
            "0",
            "6.096000",
            "0",
            "3.048000",
        ],
    )

    # print bwall.__functions

    # test __getitem__
    assert bwall["Name"] == data.dt[wallkey][0][1]
    # test __setitem__
    newname = "loofah"
    bwall["Name"] = newname
    assert bwall.Name == newname
    assert bwall["Name"] == newname
    assert data.dt[wallkey][0][1] == newname
    # test functions and alias again
    assert bwall.Constr == data.dt[wallkey][0][3]
    assert bwall.svalues == (
        newname,
        "AnewConstr",
        [
            "BuildingSurface:Detailed",
            newname,
            "Wall",
            "AnewConstr",
            "West Zone",
            "Outdoors",
            "",
            "SunExposed",
            "WindExposed",
            "0.5000000",
            "4",
            "0",
            "0",
            "3.048000",
            "0",
            "0",
            "0",
            "6.096000",
            "0",
            "0",
            "6.096000",
            "0",
            "3.048000",
        ],
    )
    # test bunch_subclass.BadEPFieldError
    with pytest.raises(bunch_subclass.BadEPFieldError):
        bwall.Name_atypo = "newname"
    with pytest.raises(bunch_subclass.BadEPFieldError):
        thename = bwall.Name_atypo
    with pytest.raises(bunch_subclass.BadEPFieldError):
        bwall["Name_atypo"] = "newname"
    with pytest.raises(bunch_subclass.BadEPFieldError):
        thename = bwall["Name_atypo"]

    # test where constr["obj"] has to be extended
    # more items are added to an extendible field
    constr_i = dtls.index("Construction".upper())
    constrkey = "Construction".upper()
    constridd = commdct[constr_i]
    dconstrs = ddtt[constrkey]
    dconstr = dconstrs[0]
    constrfields = [comm.get("field") for comm in commdct[constr_i]]
    constrfields[0] = ["key"]
    constrfields = [field[0] for field in constrfields]
    constr_fields = [bunchhelpers.makefieldname(field) for field in constrfields]
    bconstr = EpBunch(dconstr, constr_fields, constridd)
    assert bconstr.Name == "Dbl Clr 3mm/13mm Air"
    bconstr.Layer_4 = "butter"
    assert bconstr.obj == [
        "Construction",
        "Dbl Clr 3mm/13mm Air",
        "CLEAR 3MM",
        "AIR 13MM",
        "CLEAR 3MM",
        "butter",
    ]
    bconstr.Layer_7 = "cheese"
    assert bconstr.obj == [
        "Construction",
        "Dbl Clr 3mm/13mm Air",
        "CLEAR 3MM",
        "AIR 13MM",
        "CLEAR 3MM",
        "butter",
        "",
        "",
        "cheese",
    ]
    bconstr["Layer_8"] = "jam"
    assert bconstr.obj == [
        "Construction",
        "Dbl Clr 3mm/13mm Air",
        "CLEAR 3MM",
        "AIR 13MM",
        "CLEAR 3MM",
        "butter",
        "",
        "",
        "cheese",
        "jam",
    ]

    # retrieve a valid field that has no value
    assert bconstr.Layer_10 == ""
    assert bconstr["Layer_10"] == ""
Ejemplo n.º 10
0
def test_EpBunch():
    """py.test for EpBunch"""

    iddfile = StringIO(iddtxt)
    fname = StringIO(idftxt)
    block, data, commdct, idd_index = readidf.readdatacommdct1(fname, 
                iddfile=iddfile)

    # setup code walls - can be generic for any object
    ddtt = data.dt
    dtls = data.dtls
    wall_i = dtls.index('BuildingSurface:Detailed'.upper())
    wallkey = 'BuildingSurface:Detailed'.upper()
    wallidd = commdct[wall_i]

    dwalls = ddtt[wallkey]
    dwall = dwalls[0]


    wallfields = [comm.get('field') for comm in commdct[wall_i]]
    wallfields[0] = ['key']
    wallfields = [field[0] for field in wallfields]
    wall_fields = [bunchhelpers.makefieldname(field) for field in wallfields]
    assert wall_fields[:20] == [
        'key', 'Name', 'Surface_Type',
        'Construction_Name', 'Zone_Name', 'Outside_Boundary_Condition',
        'Outside_Boundary_Condition_Object', 'Sun_Exposure', 'Wind_Exposure',
        'View_Factor_to_Ground', 'Number_of_Vertices', 'Vertex_1_Xcoordinate',
        'Vertex_1_Ycoordinate', 'Vertex_1_Zcoordinate', 'Vertex_2_Xcoordinate',
        'Vertex_2_Ycoordinate', 'Vertex_2_Zcoordinate', 'Vertex_3_Xcoordinate',
        'Vertex_3_Ycoordinate', 'Vertex_3_Zcoordinate']


    bwall = EpBunch(dwall, wall_fields, wallidd)

    # print bwall.Name
    # print data.dt[wallkey][0][1]
    assert bwall.Name == data.dt[wallkey][0][1]
    bwall.Name = 'Gumby'
    # print bwall.Name
    # print data.dt[wallkey][0][1]
    # print
    assert bwall.Name == data.dt[wallkey][0][1]

    # set aliases
    bwall.__aliases = {'Constr':'Construction_Name'}

    # print "wall.Construction_Name = %s" % (bwall.Construction_Name, )
    # print "wall.Constr = %s" % (bwall.Constr, )
    # print
    assert bwall.Construction_Name == bwall.Constr
    # print "change wall.Constr"
    bwall.Constr = 'AnewConstr'
    # print "wall.Constr = %s" % (bwall.Constr, )
    # print "wall.Constr = %s" % (data.dt[wallkey][0][3], )
    # print
    assert bwall.Constr == data.dt[wallkey][0][3]

    # add functions
    bwall.__functions = {'svalues':bunch_subclass.somevalues}
    assert 'svalues' in bwall.__functions

    # print bwall.svalues
    assert bwall.svalues == (
        'Gumby', 'AnewConstr',
        [
            'BuildingSurface:Detailed', 'Gumby', 'Wall', 'AnewConstr',
            'West Zone', 'Outdoors', '', 'SunExposed', 'WindExposed',
            '0.5000000', '4', '0', '0', '3.048000', '0', '0', '0', '6.096000',
            '0', '0', '6.096000', '0', '3.048000'])

    # print bwall.__functions

    # test __getitem__
    assert bwall["Name"] == data.dt[wallkey][0][1]
    # test __setitem__
    newname = "loofah"
    bwall["Name"] = newname
    assert bwall.Name == newname
    assert bwall["Name"] == newname
    assert data.dt[wallkey][0][1] == newname
    # test functions and alias again
    assert bwall.Constr == data.dt[wallkey][0][3]
    assert bwall.svalues == (
        newname, 'AnewConstr',
        [
            'BuildingSurface:Detailed', newname, 'Wall', 'AnewConstr',
            'West Zone', 'Outdoors', '', 'SunExposed', 'WindExposed',
            '0.5000000', '4', '0', '0', '3.048000', '0', '0', '0', '6.096000',
            '0', '0', '6.096000', '0', '3.048000'])
    # test bunch_subclass.BadEPFieldError
    with pytest.raises(bunch_subclass.BadEPFieldError):
        bwall.Name_atypo = "newname"
    with pytest.raises(bunch_subclass.BadEPFieldError):
        thename = bwall.Name_atypo
    with pytest.raises(bunch_subclass.BadEPFieldError):
        bwall["Name_atypo"] = "newname"
    with pytest.raises(bunch_subclass.BadEPFieldError):
        thename = bwall["Name_atypo"]

    # test where constr["obj"] has to be extended
    # more items are added to an extendible field
    constr_i = dtls.index('Construction'.upper())
    constrkey = 'Construction'.upper()
    constridd = commdct[constr_i]
    dconstrs = ddtt[constrkey]
    dconstr = dconstrs[0]
    constrfields = [comm.get('field') for comm in commdct[constr_i]]
    constrfields[0] = ['key']
    constrfields = [field[0] for field in constrfields]
    constr_fields = [bunchhelpers.makefieldname(field) for field in constrfields]
    bconstr = EpBunch(dconstr, constr_fields, constridd)
    assert bconstr.Name == "Dbl Clr 3mm/13mm Air"
    bconstr.Layer_4 = "butter"
    assert bconstr.obj == [
        'Construction', 'Dbl Clr 3mm/13mm Air', 'CLEAR 3MM', 'AIR 13MM',
        'CLEAR 3MM', 'butter']
    bconstr.Layer_7 = "cheese"
    assert bconstr.obj == [
        'Construction', 'Dbl Clr 3mm/13mm Air', 'CLEAR 3MM', 'AIR 13MM',
        'CLEAR 3MM', 'butter', '', '', 'cheese']
    bconstr["Layer_8"] = "jam"
    assert bconstr.obj == [
        'Construction', 'Dbl Clr 3mm/13mm Air', 'CLEAR 3MM', 'AIR 13MM',
        'CLEAR 3MM', 'butter', '', '', 'cheese', 'jam']

    # retrieve a valid field that has no value
    assert bconstr.Layer_10 == ''
    assert bconstr["Layer_10"] == ''