Instruction:
How would you implement a function in Python 3 that
gets the install paths for EnergyPlus executable and weather files.

Response:
def install_paths(version=None, iddname=None):
    """Get the install paths for EnergyPlus executable and weather files.

    We prefer to get the install path from the IDD name but fall back to
    getting it from the version number for backwards compatibility and to
    simplify tests.

    Parameters
    ----------
    version : str, optional
        EnergyPlus version in the format "X-X-X", e.g. "8-7-0".
    iddname : str, optional
        File path to the IDD.

    Returns
    -------
    eplus_exe : str
        Full path to the EnergyPlus executable.
    eplus_weather : str
        Full path to the EnergyPlus weather directory.

    """
    try:
        eplus_exe, eplus_home = paths_from_iddname(iddname)
    except (AttributeError, TypeError, ValueError):
        eplus_exe, eplus_home = paths_from_version(version)
    eplus_weather = os.path.join(eplus_home, 'WeatherData')

    return eplus_exe, eplus_weather


Instruction:
Write a Python 3 script for
getting the EnergyPlus install directory and executable path from an IDD.

Response:
def paths_from_iddname(iddname):
    """Get the EnergyPlus install directory and executable path.

    Parameters
    ----------
    iddname : str, optional
        File path to the IDD.

    Returns
    -------
    eplus_exe : str
        Full path to the EnergyPlus executable.
    eplus_home : str
        Full path to the EnergyPlus install directory.

    Raises
    ------
    AttributeError (TypeError on Windows)
        If iddname does not have a directory component (e.g. if None).
    ValueError
        If eplus_exe is not a file.

    """
    eplus_home = os.path.abspath(os.path.dirname(iddname))
    if platform.system() == 'Windows':
        eplus_exe = os.path.join(eplus_home, 'energyplus.exe')
    elif platform.system() == "Linux":
        eplus_exe = os.path.join(eplus_home, 'energyplus')
    else:
        eplus_exe = os.path.join(eplus_home, 'energyplus')
    if not os.path.isfile(eplus_exe):
        raise ValueError
    return eplus_exe, eplus_home


Instruction:
How would you code a function in Python 3 to
get the EnergyPlus install directory and executable path.

Response:
def paths_from_version(version):
    """Get the EnergyPlus install directory and executable path.

    Parameters
    ----------
    version : str, optional
        EnergyPlus version in the format "X-X-X", e.g. "8-7-0".

    Returns
    -------
    eplus_exe : str
        Full path to the EnergyPlus executable.
    eplus_home : str
        Full path to the EnergyPlus install directory.

    """
    if platform.system() == 'Windows':
        eplus_home = "C:/EnergyPlusV{version}".format(version=version)
        eplus_exe = os.path.join(eplus_home, 'energyplus.exe')
    elif platform.system() == "Linux":
        eplus_home = "/usr/local/EnergyPlus-{version}".format(version=version)
        eplus_exe = os.path.join(eplus_home, 'energyplus')
    else:
        eplus_home = "/Applications/EnergyPlus-{version}".format(version=version)
        eplus_exe = os.path.join(eplus_home, 'energyplus')
    return eplus_exe, eplus_home


Instruction:
Can you generate the documentation for the following Python 3 function
def runIDFs(jobs, processors=1):
    if processors <= 0:
        processors = max(1, mp.cpu_count() - processors)

    shutil.rmtree("multi_runs", ignore_errors=True)
    os.mkdir("multi_runs")

    prepared_runs = (prepare_run(run_id, run_data) for run_id, run_data in enumerate(jobs))
    try:
        pool = mp.Pool(processors)
        pool.map(multirunner, prepared_runs)
        pool.close()
    except NameError:
        # multiprocessing not present so pass the jobs one at a time
        for job in prepared_runs:
            multirunner([job])
    shutil.rmtree("multi_runs", ignore_errors=True)

Response: Wrapper for run() to be used when running IDF5 runs in parallel.


Instruction:
How would you explain what the following Python 3 function does
def prepare_run(run_id, run_data):
    idf, kwargs = run_data
    epw = idf.epw
    idf_dir = os.path.join('multi_runs', 'idf_%i' % run_id)
    os.mkdir(idf_dir)
    idf_path = os.path.join(idf_dir, 'in.idf')
    idf.saveas(idf_path)
    return (idf_path, epw), kwargs

Response: Prepare run inputs for one of multiple EnergyPlus runs.


Instruction:
Here you have a function in Python 3, explain what it does
def run(idf=None, weather=None, output_directory='', annual=False,
        design_day=False, idd=None, epmacro=False, expandobjects=False,
        readvars=False, output_prefix=None, output_suffix=None, version=False,
        verbose='v', ep_version=None):
    """
    Wrapper around the EnergyPlus command line interface.

    Parameters
    ----------
    idf : str
        Full or relative path to the IDF file to be run, or an IDF object.

    weather : str
        Full or relative path to the weather file.

    output_directory : str, optional
        Full or relative path to an output directory (default: 'run_outputs)

    annual : bool, optional
        If True then force annual simulation (default: False)

    design_day : bool, optional
        Force design-day-only simulation (default: False)

    idd : str, optional
        Input data dictionary (default: Energy+.idd in EnergyPlus directory)

    epmacro : str, optional
        Run EPMacro prior to simulation (default: False).

    expandobjects : bool, optional
        Run ExpandObjects prior to simulation (default: False)

    readvars : bool, optional
        Run ReadVarsESO after simulation (default: False)

    output_prefix : str, optional
        Prefix for output file names (default: eplus)

    output_suffix : str, optional
        Suffix style for output file names (default: L)
            L: Legacy (e.g., eplustbl.csv)
            C: Capital (e.g., eplusTable.csv)
            D: Dash (e.g., eplus-table.csv)

    version : bool, optional
        Display version information (default: False)

    verbose: str
        Set verbosity of runtime messages (default: v)
            v: verbose
            q: quiet

    ep_version: str
        EnergyPlus version, used to find install directory. Required if run() is
        called with an IDF file path rather than an IDF object.

    Returns
    -------
    str : status

    Raises
    ------
    CalledProcessError

    AttributeError
        If no ep_version parameter is passed when calling with an IDF file path
        rather than an IDF object.

    """
    args = locals().copy()
    # get unneeded params out of args ready to pass the rest to energyplus.exe
    verbose = args.pop('verbose')
    idf = args.pop('idf')
    iddname = args.get('idd')
    if not isinstance(iddname, str):
        args.pop('idd')
    try:
        idf_path = os.path.abspath(idf.idfname)
    except AttributeError:
        idf_path = os.path.abspath(idf)
    ep_version = args.pop('ep_version')
    # get version from IDF object or by parsing the IDF file for it
    if not ep_version:
        try:
            ep_version = '-'.join(str(x) for x in idf.idd_version[:3])
        except AttributeError:
            raise AttributeError(
                "The ep_version must be set when passing an IDF path. \
                Alternatively, use IDF.run()")

    eplus_exe_path, eplus_weather_path = install_paths(ep_version, iddname)
    if version:
        # just get EnergyPlus version number and return
        cmd = [eplus_exe_path, '--version']
        check_call(cmd)
        return

    # convert paths to absolute paths if required
    if os.path.isfile(args['weather']):
        args['weather'] = os.path.abspath(args['weather'])
    else:
        args['weather'] = os.path.join(eplus_weather_path, args['weather'])
    output_dir = os.path.abspath(args['output_directory'])
    args['output_directory'] = output_dir

    # store the directory we start in
    cwd = os.getcwd()
    run_dir = os.path.abspath(tempfile.mkdtemp())
    os.chdir(run_dir)

    # build a list of command line arguments
    cmd = [eplus_exe_path]
    for arg in args:
        if args[arg]:
            if isinstance(args[arg], bool):
                args[arg] = ''
            cmd.extend(['--{}'.format(arg.replace('_', '-'))])
            if args[arg] != "":
                cmd.extend([args[arg]])
    cmd.extend([idf_path])

    try:
        if verbose == 'v':
            print("\r\n" + " ".join(cmd) + "\r\n")
            check_call(cmd)
        elif verbose == 'q':
            check_call(cmd, stdout=open(os.devnull, 'w'))
    except CalledProcessError:
        message = parse_error(output_dir)
        raise EnergyPlusRunError(message)
    finally:
        os.chdir(cwd)
    return 'OK'

Response: Wrapper around the EnergyPlus command line interface.


Instruction:
Here you have a function in Python 3, explain what it does
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")
    if os.path.isfile(err_file):
        with open(err_file, "r") as f:
            ep_err = f.read()
    else:
        ep_err = "<File not found>"
    message = "\r\n{std_err}\r\nContents of EnergyPlus error file at {err_file}\r\n{ep_err}".format(**locals())
    return message

Response: Parse the error file and put it in the exception message.


Instruction:
Write a Python 3 script to
get the rvalue of a single object in IDF

Response:
def rvalue(ddtt):
    """
    R value (W/K) of a construction or material.
    thickness (m) / conductivity (W/m-K)
    """
    object_type = ddtt.obj[0]
    if object_type == 'Construction':
        rvalue = INSIDE_FILM_R + OUTSIDE_FILM_R
        layers = ddtt.obj[2:]
        field_idd = ddtt.getfieldidd('Outside_Layer')
        validobjects = field_idd['validobjects']
        for layer in layers:
            found = False
            for key in validobjects:
                try:
                    rvalue += ddtt.theidf.getobject(key, layer).rvalue
                    found = True
                except AttributeError:
                    pass
            if not found:
                raise AttributeError("%s material not found in IDF" % layer)
    elif object_type == 'Material':
        thickness = ddtt.obj[ddtt.objls.index('Thickness')]
        conductivity = ddtt.obj[ddtt.objls.index('Conductivity')]
        rvalue = thickness / conductivity
    elif object_type == 'Material:AirGap':
        rvalue = ddtt.obj[ddtt.objls.index('Thermal_Resistance')]
    elif object_type == 'Material:InfraredTransparent':
        rvalue = 0
    elif object_type == 'Material:NoMass':
        rvalue = ddtt.obj[ddtt.objls.index('Thermal_Resistance')]
    elif object_type == 'Material:RoofVegetation':
        warnings.warn(
            "Material:RoofVegetation thermal properties are based on dry soil",
            UserWarning)
        thickness = ddtt.obj[ddtt.objls.index('Thickness')]
        conductivity = ddtt.obj[ddtt.objls.index('Conductivity_of_Dry_Soil')]
        rvalue = thickness / conductivity
    else:
        raise AttributeError("%s rvalue property not implemented" % object_type)
    return rvalue


Instruction:
Can you create a Python 3 function that
gets the heat capacity of a single object in IDF

Response:
def heatcapacity(ddtt):
    """
    Heat capacity (kJ/m2-K) of a construction or material.
    thickness (m) * density (kg/m3) * specific heat (J/kg-K) * 0.001
    """
    object_type = ddtt.obj[0]
    if object_type == 'Construction':
        heatcapacity = 0
        layers = ddtt.obj[2:]
        field_idd = ddtt.getfieldidd('Outside_Layer')
        validobjects = field_idd['validobjects']
        for layer in layers:
            found = False
            for key in validobjects:
                try:
                    heatcapacity += ddtt.theidf.getobject(key, layer).heatcapacity
                    found = True
                except AttributeError:
                    pass
            if not found:
                raise AttributeError("%s material not found in IDF" % layer)
    elif object_type == 'Material':
        thickness = ddtt.obj[ddtt.objls.index('Thickness')]
        density = ddtt.obj[ddtt.objls.index('Density')]
        specificheat = ddtt.obj[ddtt.objls.index('Specific_Heat')]
        heatcapacity = thickness * density * specificheat * 0.001
    elif object_type == 'Material:AirGap':
        heatcapacity = 0
    elif object_type == 'Material:InfraredTransparent':
        heatcapacity = 0
    elif object_type == 'Material:NoMass':
        warnings.warn(
            "Material:NoMass materials included in heat capacity calculation",
            UserWarning)
        heatcapacity = 0
    elif object_type == 'Material:RoofVegetation':
        warnings.warn(
            "Material:RoofVegetation thermal properties are based on dry soil",
            UserWarning)
        thickness = ddtt.obj[ddtt.objls.index('Thickness')]
        density = ddtt.obj[ddtt.objls.index('Density_of_Dry_Soil')]
        specificheat = ddtt.obj[ddtt.objls.index('Specific_Heat_of_Dry_Soil')]
        heatcapacity = thickness * density * specificheat * 0.001
    else:
        raise AttributeError("%s has no heatcapacity property" % object_type)
    return heatcapacity


Instruction:
Implement a Python 3 function for
testing if two values are equal to a given number of places.

Response:
def almostequal(first, second, places=7, printit=True):
    """
    Test if two values are equal to a given number of places.
    This is based on python's unittest so may be covered by Python's
    license.

    """
    if first == second:
        return True

    if round(abs(second - first), places) != 0:
        if printit:
            print(round(abs(second - first), places))
            print("notalmost: %s != %s to %i places" % (first, second, places))
        return False
    else:
        return True


Instruction:
Write a Python 3 function that can
make a new object for the given key.

Response:
def newrawobject(data, commdct, key, block=None, defaultvalues=True):
    """Make a new object for the given key.

    Parameters
    ----------
    data : Eplusdata object
        Data dictionary and list of objects for the entire model.
    commdct : list of dicts
        Comments from the IDD file describing each item type in `data`.
    key : str
        Object type of the object to add (in ALL_CAPS).

    Returns
    -------
    list
        A list of field values for the new object.

    """
    dtls = data.dtls
    key = key.upper()

    key_i = dtls.index(key)
    key_comm = commdct[key_i]
    # set default values
    if defaultvalues:
        obj = [comm.get('default', [''])[0] for comm in key_comm]
    else:
        obj = ['' for comm in key_comm]
    if not block:
        inblock = ['does not start with N'] * len(obj)
    else:
        inblock = block[key_i]
    for i, (f_comm, f_val, f_iddname) in enumerate(zip(key_comm, obj, inblock)):
        if i == 0:
            obj[i] = key
        else:
            obj[i] = convertafield(f_comm, f_val, f_iddname)
    obj = poptrailing(obj)  # remove the blank items in a repeating field.
    return obj


Instruction:
Make a summary of the following Python 3 code
def addthisbunch(bunchdt, data, commdct, thisbunch, theidf):
    key = thisbunch.key.upper()
    obj = copy.copy(thisbunch.obj)
    abunch = obj2bunch(data, commdct, obj)
    bunchdt[key].append(abunch)
    return abunch

Response: add a bunch to the bunchdt


Instruction:
Write a Python 3 script for
making a bunch object using the data object

Response:
def obj2bunch(data, commdct, obj):
    """make a new bunch object using the data object"""
    dtls = data.dtls
    key = obj[0].upper()
    key_i = dtls.index(key)
    abunch = makeabunch(commdct, obj, key_i)
    return abunch


Instruction:
Write a Python 3 script to
add an object to the bunchdt

Response:
def addobject(bunchdt, data, commdct, key, theidf, aname=None, **kwargs):
    """add an object to the eplus model"""
    obj = newrawobject(data, commdct, key)
    abunch = obj2bunch(data, commdct, obj)
    if aname:
        namebunch(abunch, aname)
    data.dt[key].append(obj)
    bunchdt[key].append(abunch)
    for key, value in list(kwargs.items()):
        abunch[key] = value
    return abunch


Instruction:
How would you explain what the following Python 3 function does
def getnamedargs(*args, **kwargs):
    adict = {}
    for arg in args:
        if isinstance(arg, dict):
            adict.update(arg)
    adict.update(kwargs)
    return adict

Response:
allows you to pass a dict and named args
Taxonomy so you can pass a dict and named kwargs
Taxonomy so you can pass a dict and named args
Taxonomy so you can pass a dict and get
    dict


Instruction:
How would you explain what the following Python 3 function does
def addobject1(bunchdt, data, commdct, key, **kwargs):
    obj = newrawobject(data, commdct, key)
    abunch = obj2bunch(data, commdct, obj)
    data.dt[key].append(obj)
    bunchdt[key].append(abunch)
    # adict = getnamedargs(*args, **kwargs)
    for kkey, value in iteritems(kwargs):
        abunch[kkey] = value
    return abunch

Response: add an object to the eplus model


Instruction:
Make a summary of the following Python 3 code
def getobject(bunchdt, key, name):
    # TODO : throw exception if more than one object, or return more objects
    idfobjects = bunchdt[key]
    if idfobjects:
        # second item in list is a unique ID
        unique_id = idfobjects[0].objls[1]
    theobjs = [idfobj for idfobj in idfobjects if
               idfobj[unique_id].upper() == name.upper()]
    try:
        return theobjs[0]
    except IndexError:
        return None

Response:
get the object if you have the key and the name
    returns a list of objects


Instruction:
Write a Python 3 function that can
test if the idf object has the fields in kwargs

Response:
def __objecthasfields(bunchdt, data, commdct, idfobject, places=7, **kwargs):
    """test if the idf object has the field values in kwargs"""
    for key, value in list(kwargs.items()):
        if not isfieldvalue(
                bunchdt, data, commdct,
                idfobject, key, value, places=places):
            return False
    return True


Instruction:
How would you explain what the following Python 3 function does
def getobjects(bunchdt, data, commdct, key, places=7, **kwargs):
    idfobjects = bunchdt[key]
    allobjs = []
    for obj in idfobjects:
        if __objecthasfields(
                bunchdt, data, commdct,
                obj, places=places, **kwargs):
            allobjs.append(obj)
    return allobjs

Response: get all the objects of the given key that match the fields in kwargs


Instruction:
Write a Python 3 script to
get the index of the first extensible item

Response:
def getextensibleindex(bunchdt, data, commdct, key, objname):
    """get the index of the first extensible item"""
    theobject = getobject(bunchdt, key, objname)
    if theobject == None:
        return None
    theidd = iddofobject(data, commdct, key)
    extensible_i = [
        i for i in range(len(theidd)) if 'begin-extensible' in theidd[i]]
    try:
        extensible_i = extensible_i[0]
    except IndexError:
        return theobject


Instruction:
Write a Python 3 script to
remove the extensible items in the object

Response:
def removeextensibles(bunchdt, data, commdct, key, objname):
    """remove the extensible items in the object"""
    theobject = getobject(bunchdt, key, objname)
    if theobject == None:
        return theobject
    theidd = iddofobject(data, commdct, key)
    extensible_i = [
        i for i in range(len(theidd)) if 'begin-extensible' in theidd[i]]
    try:
        extensible_i = extensible_i[0]
    except IndexError:
        return theobject
    while True:
        try:
            popped = theobject.obj.pop(extensible_i)
        except IndexError:
            break
    return theobject


Instruction:
Write a Python 3 function for
getting the idd comment for the field

Response:
def getfieldcomm(bunchdt, data, commdct, idfobject, fieldname):
    """get the idd comment for the field"""
    key = idfobject.obj[0].upper()
    keyi = data.dtls.index(key)
    fieldi = idfobject.objls.index(fieldname)
    thiscommdct = commdct[keyi][fieldi]
    return thiscommdct


Instruction:
Implement a Python 3 function for
testing if case has to be retained for that field

Response:
def is_retaincase(bunchdt, data, commdct, idfobject, fieldname):
    """test if case has to be retained for that field"""
    thiscommdct = getfieldcomm(bunchdt, data, commdct, idfobject, fieldname)
    return 'retaincase' in thiscommdct


Instruction:
Given the following Python 3 function, write the documentation
def isfieldvalue(bunchdt, data, commdct, idfobj, fieldname, value, places=7):
    # do a quick type check
    # if type(idfobj[fieldname]) != type(value):
    # return False # takes care of autocalculate and real
    # check float
    thiscommdct = getfieldcomm(bunchdt, data, commdct, idfobj, fieldname)
    if 'type' in thiscommdct:
        if thiscommdct['type'][0] in ('real', 'integer'):
            # test for autocalculate
            try:
                if idfobj[fieldname].upper() == 'AUTOCALCULATE':
                    if value.upper() == 'AUTOCALCULATE':
                        return True
            except AttributeError:
                pass
            return almostequal(float(idfobj[fieldname]), float(value), places, False)
    # check retaincase
    if is_retaincase(bunchdt, data, commdct, idfobj, fieldname):
        return idfobj[fieldname] == value
    else:
        return idfobj[fieldname].upper() == value.upper()

Response: test if idfobj. field == value


Instruction:
Can you generate a brief explanation for the following Python 3 code
def equalfield(bunchdt, data, commdct, idfobj1, idfobj2, fieldname, places=7):
    # TODO test if both objects are of same type
    key1 = idfobj1.obj[0].upper()
    key2 = idfobj2.obj[0].upper()
    if key1 != key2:
        raise NotSameObjectError
    vee2 = idfobj2[fieldname]
    return isfieldvalue(
        bunchdt, data, commdct,
        idfobj1, fieldname, vee2, places=places)

Response: returns true if the two fields are equal


Instruction:
Write a Python 3 function for
getting the reference names for this object

Response:
def getrefnames(idf, objname):
    """get the reference names for this object"""
    iddinfo = idf.idd_info
    dtls = idf.model.dtls
    index = dtls.index(objname)
    fieldidds = iddinfo[index]
    for fieldidd in fieldidds:
        if 'field' in fieldidd:
            if fieldidd['field'][0].endswith('Name'):
                if 'reference' in fieldidd:
                    return fieldidd['reference']
                else:
                    return []


Instruction:
Can you tell what is the following Python 3 function doing
def rename(idf, objkey, objname, newname):
    refnames = getrefnames(idf, objkey)
    for refname in refnames:
        objlists = getallobjlists(idf, refname)
        # [('OBJKEY', refname, fieldindexlist), ...]
        for refname in refnames:
        # TODO : there seems to be a duplication in this loop. Check.
        # refname appears in both loops
            for robjkey, refname, fieldindexlist in objlists:
                idfobjects = idf.idfobjects[robjkey]
                for idfobject in idfobjects:
                    for findex in fieldindexlist:  # for each field
                        if idfobject[idfobject.objls[findex]] == objname:
                            idfobject[idfobject.objls[findex]] = newname
    theobject = idf.getobject(objkey, objname)
    fieldname = [item for item in theobject.objls if item.endswith('Name')][0]
    theobject[fieldname] = newname
    return theobject

Response: rename all the refrences to this objname


Instruction:
Can you generate a brief explanation for the following Python 3 code
def zone_height_min2max(idf, zonename, debug=False):
    zone = idf.getobject('ZONE', zonename)
    surfs = idf.idfobjects['BuildingSurface:Detailed'.upper()]
    zone_surfs = [s for s in surfs if s.Zone_Name == zone.Name]
    surf_xyzs = [eppy.function_helpers.getcoords(s) for s in zone_surfs]
    surf_xyzs = list(itertools.chain(*surf_xyzs))
    surf_zs = [z for x, y, z in surf_xyzs]
    topz = max(surf_zs)
    botz = min(surf_zs)
    height = topz - botz
    return height

Response: zone height min - max


Instruction:
Write a Python 3 script for
getting the height of a zone

Response:
def zoneheight(idf, zonename, debug=False):
    """zone height"""
    zone = idf.getobject('ZONE', zonename)
    surfs = idf.idfobjects['BuildingSurface:Detailed'.upper()]
    zone_surfs = [s for s in surfs if s.Zone_Name == zone.Name]
    floors = [s for s in zone_surfs if s.Surface_Type.upper() == 'FLOOR']
    roofs = [s for s in zone_surfs if s.Surface_Type.upper() == 'ROOF']
    if floors == [] or roofs == []:
        height = zone_height_min2max(idf, zonename)
    else:
        height = zone_floor2roofheight(idf, zonename)
    return height


Instruction:
How would you implement a function in Python 3 that
zones floor to roof height

Response:
def zone_floor2roofheight(idf, zonename, debug=False):
    """zone floor to roof height"""
    zone = idf.getobject('ZONE', zonename)
    surfs = idf.idfobjects['BuildingSurface:Detailed'.upper()]
    zone_surfs = [s for s in surfs if s.Zone_Name == zone.Name]
    floors = [s for s in zone_surfs if s.Surface_Type.upper() == 'FLOOR']
    roofs = [s for s in zone_surfs if s.Surface_Type.upper() == 'ROOF']
    ceilings = [s for s in zone_surfs if s.Surface_Type.upper() == 'CEILING']
    topsurfaces = roofs + ceilings

    topz = []
    for topsurface in topsurfaces:
        for coord in topsurface.coords:
            topz.append(coord[-1])
    topz = max(topz)

    botz = []
    for floor in floors:
        for coord in floor.coords:
            botz.append(coord[-1])
    botz = min(botz)
    height = topz - botz

    return height


Instruction:
Make a summary of the following Python 3 code
def setiddname(cls, iddname, testing=False):
        if cls.iddname == None:
            cls.iddname = iddname
            cls.idd_info = None
            cls.block = None
        elif cls.iddname == iddname:
            pass
        else:
            if testing == False:
                errortxt = "IDD file is set to: %s" % (cls.iddname,)
                raise IDDAlreadySetError(errortxt)

Response: Set the path to the EnergyPlus IDD file which is used by eppy.


Instruction:
Write a Python 3 function that can
set the IDD to be used by eppy.

Response:
def setidd(cls, iddinfo, iddindex, block, idd_version):
        """Set the IDD to be used by eppy.

        Parameters
        ----------
        iddinfo : list
            Comments and metadata about fields in the IDD.
        block : list
            Field names in the IDD.

        """
        cls.idd_info = iddinfo
        cls.block = block
        cls.idd_index = iddindex
        cls.idd_version = idd_version


Instruction:
How would you explain what the following Python 3 function does
def initread(self, idfname):
        with open(idfname, 'r') as _:
            # raise nonexistent file error early if idfname doesn't exist
            pass
        iddfhandle = StringIO(iddcurrent.iddtxt)
        if self.getiddname() == None:
            self.setiddname(iddfhandle)
        self.idfname = idfname
        self.read()

Response: Initialize the IDD with the contents of the IDF file.


Instruction:
Can you tell what is the following Python 3 function doing
def initreadtxt(self, idftxt):
        iddfhandle = StringIO(iddcurrent.iddtxt)
        if self.getiddname() == None:
            self.setiddname(iddfhandle)
        idfhandle = StringIO(idftxt)
        self.idfname = idfhandle
        self.read()

Response: Initialize the IDD and read an IDF from text data.


Instruction:
Can you implement a function in Python 3 that
reads the IDF file and the IDD file.

Response:
def read(self):
        """
        Read the IDF file and the IDD file. If the IDD file had already been
        read, it will not be read again.

        Read populates the following data structures:

        - idfobjects : list
        - model : list
        - idd_info : list
        - idd_index : dict

        """
        if self.getiddname() == None:
            errortxt = ("IDD file needed to read the idf file. "
                        "Set it using IDF.setiddname(iddfile)")
            raise IDDNotSetError(errortxt)
        readout = idfreader1(
            self.idfname, self.iddname, self,
            commdct=self.idd_info, block=self.block)
        (self.idfobjects, block, self.model,
            idd_info, idd_index, idd_version) = readout
        self.__class__.setidd(idd_info, idd_index, block, idd_version)


Instruction:
Can you generate the documentation for the following Python 3 function
def initnew(self, fname):
        iddfhandle = StringIO(iddcurrent.iddtxt)
        if self.getiddname() == None:
            self.setiddname(iddfhandle)
        idfhandle = StringIO('')
        self.idfname = idfhandle
        self.read()
        if fname:
            self.idfname = fname

Response: Initialize the current IDD and create a new empty IDF.


Instruction:
Write a Python 3 function that can
add a new IDF object to the model.

Response:
def newidfobject(self, key, aname='', defaultvalues=True, **kwargs):
        """
        Add a new idfobject to the model. If you don't specify a value for a
        field, the default value will be set.

        For example ::

            newidfobject("CONSTRUCTION")
            newidfobject("CONSTRUCTION",
                Name='Interior Ceiling_class',
                Outside_Layer='LW Concrete',
                Layer_2='soundmat')

        Parameters
        ----------
        key : str
            The type of IDF object. This must be in ALL_CAPS.
        aname : str, deprecated
            This parameter is not used. It is left there for backward
            compatibility.
        defaultvalues: boolean
            default is True. If True default values WILL be set.
            If False, default values WILL NOT be set
        **kwargs
            Keyword arguments in the format `field=value` used to set the value
            of fields in the IDF object when it is created.

        Returns
        -------
        EpBunch object

        """

        obj = newrawobject(self.model, self.idd_info,
                    key, block=self.block, defaultvalues=defaultvalues)
        abunch = obj2bunch(self.model, self.idd_info, obj)
        if aname:
            warnings.warn("The aname parameter should no longer be used.", UserWarning)
            namebunch(abunch, aname)
        self.idfobjects[key].append(abunch)
        for k, v in list(kwargs.items()):
            abunch[k] = v
        return abunch


Instruction:
How would you explain what the following Python 3 function does
def removeidfobject(self, idfobject):
        key = idfobject.key.upper()
        self.idfobjects[key].remove(idfobject)

Response: Removes an IDF object from the IDF.


Instruction:
Explain what the following Python 3 code does
def copyidfobject(self, idfobject):
        return addthisbunch(self.idfobjects,
                     self.model,
                     self.idd_info,
                     idfobject, self)

Response: Add an IDF object to the IDF.


Instruction:
Write a Python 3 function that can
return the index of the first extensible item in the list of items in the IDF table.

Response:
def getextensibleindex(self, key, name):
        """
        Get the index of the first extensible item.

        Only for internal use. # TODO : hide this

        Parameters
        ----------
        key : str
            The type of IDF object. This must be in ALL_CAPS.
        name : str
            The name of the object to fetch.

        Returns
        -------
        int

        """
        return getextensibleindex(
            self.idfobjects, self.model, self.idd_info,
            key, name)


Instruction:
Here you have a function in Python 3, explain what it does
def removeextensibles(self, key, name):
        return removeextensibles(
            self.idfobjects, self.model, self.idd_info,
            key, name)

Response: Remove extensible items in the object of key and name.


Instruction:
Implement a function in Python 3 to
return the string representation of the IDF.

Response:
def idfstr(self):
        """String representation of the IDF.

        Returns
        -------
        str

        """
        if self.outputtype == 'standard':
            astr = ''
        else:
            astr = self.model.__repr__()

        if self.outputtype == 'standard':
            astr = ''
            dtls = self.model.dtls
            for objname in dtls:
                for obj in self.idfobjects[objname]:
                    astr = astr + obj.__repr__()
        elif self.outputtype == 'nocomment':
            return astr
        elif self.outputtype == 'nocomment1':
            slist = astr.split('\n')
            slist = [item.strip() for item in slist]
            astr = '\n'.join(slist)
        elif self.outputtype == 'nocomment2':
            slist = astr.split('\n')
            slist = [item.strip() for item in slist]
            slist = [item for item in slist if item != '']
            astr = '\n'.join(slist)
        elif self.outputtype == 'compressed':
            slist = astr.split('\n')
            slist = [item.strip() for item in slist]
            astr = ' '.join(slist)
        else:
            raise ValueError("%s is not a valid outputtype" % self.outputtype)
        return astr


Instruction:
Can you create a Python 3 function that
saves the IDF as a text file with the optional filename passed or with the current idfname of the IDF.

Response:
def save(self, filename=None, lineendings='default', encoding='latin-1'):
        """
        Save the IDF as a text file with the optional filename passed, or with
        the current idfname of the IDF.

        Parameters
        ----------
        filename : str, optional
            Filepath to save the file. If None then use the IDF.idfname
            parameter. Also accepts a file handle.

        lineendings : str, optional
            Line endings to use in the saved file. Options are 'default',
            'windows' and 'unix' the default is 'default' which uses the line
            endings for the current system.

        encoding : str, optional
            Encoding to use for the saved file. The default is 'latin-1' which
            is compatible with the EnergyPlus IDFEditor.

        """
        if filename is None:
            filename = self.idfname
        s = self.idfstr()
        if lineendings == 'default':
            system = platform.system()
            s = '!- {} Line endings \n'.format(system) + s
            slines = s.splitlines()
            s = os.linesep.join(slines)
        elif lineendings == 'windows':
            s = '!- Windows Line endings \n' + s
            slines = s.splitlines()
            s = '\r\n'.join(slines)
        elif lineendings == 'unix':
            s = '!- Unix Line endings \n' + s
            slines = s.splitlines()
            s = '\n'.join(slines)

        s = s.encode(encoding)
        try:
            with open(filename, 'wb') as idf_out:
                idf_out.write(s)
        except TypeError:  # in the case that filename is a file handle
            try:
                filename.write(s)
            except TypeError:
                filename.write(s.decode(encoding))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def saveas(self, filename, lineendings='default', encoding='latin-1'):
        self.idfname = filename
        self.save(filename, lineendings, encoding)

Response: Save the IDF as a text file with the filename passed.


Instruction:
How would you code a function in Python 3 to
save a copy of the file with the filename passed.

Response:
def savecopy(self, filename, lineendings='default', encoding='latin-1'):
        """Save a copy of the file with the filename passed.

        Parameters
        ----------
        filename : str
            Filepath to save the file.

        lineendings : str, optional
            Line endings to use in the saved file. Options are 'default',
            'windows' and 'unix' the default is 'default' which uses the line
            endings for the current system.

        encoding : str, optional
            Encoding to use for the saved file. The default is 'latin-1' which
            is compatible with the EnergyPlus IDFEditor.

        """
        self.save(filename, lineendings, encoding)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def run(self, **kwargs):
        # write the IDF to the current directory
        self.saveas('in.idf')
        # if `idd` is not passed explicitly, use the IDF.iddname
        idd = kwargs.pop('idd', self.iddname)
        epw = kwargs.pop('weather', self.epw)
        try:
            run(self, weather=epw, idd=idd, **kwargs)
        finally:
            os.remove('in.idf')

Response: This is the main entry point for the EnergyPlus command line interface.


Instruction:
Here you have a function in Python 3, explain what it does
def printdict(adict):
    dlist = list(adict.keys())
    dlist.sort()
    for i in range(0, len(dlist)):
        print(dlist[i], adict[dlist[i]])

Response: printdict - prints the dictionary adict


Instruction:
Implement a Python 3 function for
converting a tabstr to a list of unique ids

Response:
def tabstr2list(data):
    """tabstr2list"""
    alist = data.split(os.linesep)
    blist = alist[1].split('\t')

    clist = []
    for num in range(0, len(alist)):
        ilist = alist[num].split('\t')
        clist = clist+[ilist]
    cclist = clist[:-1]
      #the last element is turning out to be empty
      #this is because the string ends with a os.linesep
    return cclist


Instruction:
Can you tell what is the following Python 3 function doing
def list2doe(alist):
    theequal = ''
    astr = ''
    lenj = len(alist)
    leni = len(alist[0])
    for i in range(0, leni-1):
        for j in range(0, lenj):
            if j == 0:
                astr = astr + alist[j][i + 1] + theequal + alist[j][0] + RET
            else:
                astr = astr + alist[j][0] + theequal + alist[j][i + 1] + RET
        astr = astr + RET
    return astr

Response: converts a list of tables to a single table of tables


Instruction:
Explain what the following Python 3 code does
def tabfile2doefile(tabfile, doefile):
    alist = tabfile2list(tabfile)
    astr = list2doe(alist)
    mylib1.write_str2file(doefile, astr)

Response: convert tabfile to doefile


Instruction:
Explain what the following Python 3 code does
def makedoetree(ddict, bdict):
    dlist = list(ddict.keys())
    blist = list(bdict.keys())
    dlist.sort()
    blist.sort()
    #make space dict
    doesnot = 'DOES NOT'
    lst = []
    for num in range(0, len(blist)):
        if bdict[blist[num]] == doesnot:#belong
            lst = lst + [blist[num]]

    doedict = {}
    for num in range(0, len(lst)):
        #print lst[num]
        doedict[lst[num]] = {}
    lv1list = list(doedict.keys())
    lv1list.sort()

    #make wall dict
    #for each space
    for i in range(0, len(lv1list)):
        walllist = []
        adict = doedict[lv1list[i]]
        #loop thru the entire blist dictonary and list the ones that belong into walllist
        for num in range(0, len(blist)):
            if bdict[blist[num]] == lv1list[i]:
                walllist = walllist + [blist[num]]
        #put walllist into dict
        for j in range(0, len(walllist)):
            adict[walllist[j]] = {}

    #make window dict
    #for each space
    for i in range(0, len(lv1list)):
        adict1 = doedict[lv1list[i]]
        #for each wall
        walllist = list(adict1.keys())
        walllist.sort()
        for j in range(0, len(walllist)):
            windlist = []
            adict2 = adict1[walllist[j]]
           #loop thru the entire blist dictonary and list the ones that belong into windlist
            for num in range(0, len(blist)):
                if bdict[blist[num]] == walllist[j]:
                    windlist = windlist + [blist[num]]
            #put walllist into dict
            for k in range(0, len(windlist)):
                adict2[windlist[k]] = {}
    return doedict

Response: make a new dict that contains all of the keys in ddict and bdict that are not in bdict


Instruction:
Given the following Python 3 function, write the documentation
def tree2doe(str1):
    retstuff = makedoedict(str1)
    ddict = makedoetree(retstuff[0], retstuff[1])
    ddict = retstuff[0]
    retstuff[1] = {}# don't need it anymore

    str1 = ''#just re-using it
    l1list = list(ddict.keys())
    l1list.sort()
    for i in range(0, len(l1list)):
        str1 = str1 + ddict[l1list[i]]
        l2list = list(ddict[l1list[i]].keys())
        l2list.sort()
        for j in range(0, len(l2list)):
            str1 = str1 + ddict[l2list[j]]
            l3list = list(ddict[l1list[i]][l2list[j]].keys())
            l3list.sort()
            for k in range(0, len(l3list)):
                str1 = str1 + ddict[l3list[k]]
    return str1

Response: tree2doe - converts a string into a single DOE


Instruction:
Can you generate the documentation for the following Python 3 function
def mtabstr2doestr(st1):
    seperator = '$ =============='
    alist = st1.split(seperator)

    #this removes all the tabs that excel
    #puts after the seperator and before the next line
    for num in range(0, len(alist)):
        alist[num] = alist[num].lstrip()
    st2 = ''
    for num in range(0, len(alist)):
        alist = tabstr2list(alist[num])
        st2 = st2 + list2doe(alist)

    lss = st2.split('..')
    mylib1.write_str2file('forfinal.txt', st2)#for debugging
    print(len(lss))

    st3 = tree2doe(st2)
    lsss = st3.split('..')
    print(len(lsss))
    return st3

Response: mtabstr2doestr - convert a string to a tree


Instruction:
Write a Python 3 function that can
get the block bounded by start and end doesn t work for multiple blocks

Response:
def getoneblock(astr, start, end):
    """get the block bounded by start and end
    doesn't work for multiple blocks"""
    alist = astr.split(start)
    astr = alist[-1]
    alist = astr.split(end)
    astr = alist[0]
    return astr


Instruction:
Make a summary of the following Python 3 code
def doestr2tabstr(astr, kword):
    alist = astr.split('..')
    del astr
    #strip junk put .. back
    for num in range(0, len(alist)):
        alist[num] = alist[num].strip()
        alist[num] = alist[num] + os.linesep + '..' + os.linesep
    alist.pop()

    lblock = []
    for num in range(0, len(alist)):
        linels = alist[num].split(os.linesep)
        firstline = linels[0]
        assignls = firstline.split('=')
        keyword = assignls[-1].strip()
        if keyword == kword:
            lblock = lblock + [alist[num]]
            #print firstline

    #get all val
    lval = []
    for num in range(0, len(lblock)):
        block = lblock[num]
        linel = block.split(os.linesep)
        lvalin = []
        for k in range(0, len(linel)):
            line = linel[k]
            assignl = line.split('=')
            if k == 0:
                lvalin = lvalin + [assignl[0]]
            else:
                if assignl[-1] == '..':
                    assignl[-1] = '.'
                lvalin = lvalin + [assignl[-1]]
        lvalin.pop()
        lval = lval + [lvalin]

    #get keywords
    kwordl = []
    block = lblock[0]
    linel = block.split(os.linesep)
    for k in range(0, len(linel)):
        line = linel[k]
        assignl = line.split('=')
        if k == 0:
            kword = ' =  ' + assignl[1].strip()
        else:
            if assignl[0] == '..':
                assignl[0] = '.'
            else:
                assignl[0] = assignl[0] + '='
            kword = assignl[0].strip()
        kwordl = kwordl + [kword]
    kwordl.pop()

    astr = ''
    for num in range(0, len(kwordl)):
        linest = ''
        linest = linest + kwordl[num]
        for k in range(0, len(lval)):
            linest = linest + '\t' + lval[k][num]
        astr = astr + linest + os.linesep

    return astr

Response: converts a DOS string to a TAB string


Instruction:
Can you generate the documentation for the following Python 3 function
def myreplace(astr, thefind, thereplace):
    alist = astr.split(thefind)
    new_s = alist.split(thereplace)
    return new_s

Response: in string astr replace all occurences of thefind with thereplace


Instruction:
Can you write a function in Python 3 where it
returns the slice after at sub in string astr

Response:
def fsliceafter(astr, sub):
    """Return the slice after at sub in string astr"""
    findex = astr.find(sub)
    return astr[findex + len(sub):]


Instruction:
How would you explain what the following Python 3 function does
def pickledump(theobject, fname):
    fhandle = open(fname, 'wb')
    pickle.dump(theobject, fhandle)

Response: same as pickle. dump


Instruction:
How would you explain what the following Python 3 function does
def write_str2file(pathname, astr):
    fname = pathname
    fhandle = open(fname, 'wb')
    fhandle.write(astr)
    fhandle.close()

Response: writes a string to file


Instruction:
How would you explain what the following Python 3 function does
def vol_tehrahedron(poly):
    a_pnt = np.array(poly[0])
    b_pnt = np.array(poly[1])
    c_pnt = np.array(poly[2])
    d_pnt = np.array(poly[3])
    return abs(np.dot(
        (a_pnt-d_pnt), np.cross((b_pnt-d_pnt), (c_pnt-d_pnt))) / 6)

Response: volume of a irregular tetrahedron


Instruction:
Can you generate the documentation for the following Python 3 function
def vol_zone(poly1, poly2):
    c_point = central_p(poly1, poly2)
    c_point = (c_point[0], c_point[1], c_point[2])
    vol_therah = 0
    num = len(poly1)
    for i in range(num-2):
        # the upper part
        tehrahedron = [c_point, poly1[0], poly1[i+1], poly1[i+2]]
        vol_therah += vol_tehrahedron(tehrahedron)
        # the bottom part
        tehrahedron = [c_point, poly2[0], poly2[i+1], poly2[i+2]]
        vol_therah += vol_tehrahedron(tehrahedron)
    # the middle part
    for i in range(num-1):
        tehrahedron = [c_point, poly1[i], poly2[i], poly2[i+1]]
        vol_therah += vol_tehrahedron(tehrahedron)
        tehrahedron = [c_point, poly1[i], poly1[i+1], poly2[i]]
        vol_therah += vol_tehrahedron(tehrahedron)
    tehrahedron = [c_point, poly1[num-1], poly2[num-1], poly2[0]]
    vol_therah += vol_tehrahedron(tehrahedron)
    tehrahedron = [c_point, poly1[num-1], poly1[0], poly2[0]]
    vol_therah += vol_tehrahedron(tehrahedron)
    return vol_therah

Response: volume of a zone defined by two polygon bases


Instruction:
Make a summary of the following Python 3 code
def newidf(version=None):
    if not version:
        version = "8.9"
    import eppy.easyopen as easyopen
    idfstring = "  Version,{};".format(str(version))
    fhandle = StringIO(idfstring)
    return easyopen.easyopen(fhandle)

Response: open a new idf file for particular version


Instruction:
Given the following Python 3 function, write the documentation
def openidf(fname, idd=None, epw=None):
    import eppy.easyopen as easyopen
    return easyopen.easyopen(fname, idd=idd, epw=epw)

Response: automatically set idd and open idf file. Uses version from idf to set correct idd


Instruction:
Write a Python 3 function for
returning an interaone wall if the bsd object is an interaone wall

Response:
def wallinterzone(idf, bsdobject, deletebsd=True, setto000=False):
    """return an wall:interzone object if the bsd (buildingsurface:detailed)
    is an interaone wall"""
    # ('WALL:INTERZONE', Wall, Surface OR Zone OR OtherSideCoefficients)
    # test if it is an exterior wall
    if bsdobject.Surface_Type.upper() == 'WALL': # Surface_Type == wall
        if bsdobject.Outside_Boundary_Condition.upper() in ('SURFACE', 'ZONE', 'OtherSideCoefficients'.upper()):
            simpleobject = idf.newidfobject('WALL:INTERZONE')
            simpleobject.Name = bsdobject.Name
            simpleobject.Construction_Name = bsdobject.Construction_Name
            simpleobject.Zone_Name = bsdobject.Zone_Name
            obco = 'Outside_Boundary_Condition_Object'
            simpleobject[obco] = bsdobject[obco]
            simpleobject.Azimuth_Angle = bsdobject.azimuth
            simpleobject.Tilt_Angle = bsdobject.tilt
            surforigin = bsdorigin(bsdobject, setto000=setto000)
            simpleobject.Starting_X_Coordinate = surforigin[0]
            simpleobject.Starting_Y_Coordinate = surforigin[1]
            simpleobject.Starting_Z_Coordinate = surforigin[2]
            simpleobject.Length = bsdobject.width
            simpleobject.Height = bsdobject.height
            if deletebsd:
                idf.removeidfobject(bsdobject)
            return simpleobject
    return None


Instruction:
Given the following Python 3 function, write the documentation
def door(idf, fsdobject, deletebsd=True, setto000=False):
    # ('DOOR', Door, None)
    # test if it is aroof
    if fsdobject.Surface_Type.upper() == 'DOOR': # Surface_Type == w
        simpleobject = idf.newidfobject('DOOR')
        simpleobject.Name = fsdobject.Name
        simpleobject.Construction_Name = fsdobject.Construction_Name
        simpleobject.Building_Surface_Name = fsdobject.Building_Surface_Name
        simpleobject.Multiplier = fsdobject.Multiplier
        surforigin = fsdorigin(fsdobject, setto000=setto000)
        simpleobject.Starting_X_Coordinate = surforigin[0]
        simpleobject.Starting_Z_Coordinate = surforigin[1]
        simpleobject.Length = fsdobject.width
        simpleobject.Height = fsdobject.height
        if deletebsd:
            idf.removeidfobject(fsdobject)
        return simpleobject
    return None

Response:
return an door object if the fsd ( fenestrationsurface : detailed ) is
    a door object if the fsd ( fenestrationsurface : detailed ) is
    a door object if the fsd ( fenestrationsurface : detailed ) is
    a door object if the fsd ( fenestrationsurface : detailed ) is
    a door object if the fsd ( f


Instruction:
Here you have a function in Python 3, explain what it does
def simplesurface(idf, bsd, deletebsd=True, setto000=False):
    funcs = (wallexterior,
        walladiabatic,
        wallunderground,
        wallinterzone,
        roof,
        ceilingadiabatic,
        ceilinginterzone,
        floorgroundcontact,
        flooradiabatic,
        floorinterzone,)
    for func in funcs:
        surface = func(idf, bsd, deletebsd=deletebsd, setto000=setto000)
        if surface:
            return surface
    return None

Response: convert a bsd into a simple surface


Instruction:
Can you write a function in Python 3 where it
converts a bsd ( fenestrationsurface : detailed into a simple

Response:
def simplefenestration(idf, fsd, deletebsd=True, setto000=False):
    """convert a bsd (fenestrationsurface:detailed) into a simple
    fenestrations"""
    funcs = (window,
        door,
        glazeddoor,)
    for func in funcs:
        fenestration = func(idf, fsd, deletebsd=deletebsd, setto000=setto000)
        if fenestration:
            return fenestration
    return None


Instruction:
Make a summary of the following Python 3 code
def tdbr2EOL(td):
    for br in td.find_all("br"):
        br.replace_with("\n")
    txt = six.text_type(td) # make it back into test
                            # would be unicode(id) in python2
    soup = BeautifulSoup(txt, 'lxml') # read it as a BeautifulSoup
    ntxt = soup.find('td') # BeautifulSoup has lot of other html junk.
                           # this line will extract just the <td> block
    return ntxt

Response: convert the br in td into line ending


Instruction:
Can you write a function in Python 3 where it
tests if the table has only strings in the cells

Response:
def is_simpletable(table):
    """test if the table has only strings in the cells"""
    tds = table('td')
    for td in tds:
        if td.contents != []:
            td = tdbr2EOL(td)
            if len(td.contents) == 1:
                thecontents = td.contents[0]
                if not isinstance(thecontents, NavigableString):
                    return False
            else:
                return False
    return True


Instruction:
Write a Python 3 script to
convert a table to a list of lists - a 2D matrix

Response:
def table2matrix(table):
    """convert a table to a list of lists - a 2D matrix"""

    if not is_simpletable(table):
        raise NotSimpleTable("Not able read a cell in the table as a string")
    rows = []
    for tr in table('tr'):
        row = []
        for td in tr('td'):
            td = tdbr2EOL(td) # convert any '<br>' in the td to line ending
            try:
                row.append(td.contents[0])
            except IndexError:
                row.append('')
        rows.append(row)
    return rows


Instruction:
How would you code a function in Python 3 to
convert a table to a list of lists - a 2D matrix

Response:
def table2val_matrix(table):
    """convert a table to a list of lists - a 2D matrix
    Converts numbers to float"""
    if not is_simpletable(table):
        raise NotSimpleTable("Not able read a cell in the table as a string")
    rows = []
    for tr in table('tr'):
        row = []
        for td in tr('td'):
            td = tdbr2EOL(td)
            try:
                val = td.contents[0]
            except IndexError:
                row.append('')
            else:
                try:
                    val = float(val)
                    row.append(val)
                except ValueError:
                    row.append(val)
        rows.append(row)
    return rows


Instruction:
Given the following Python 3 function, write the documentation
def titletable(html_doc, tofloat=True):
    soup = BeautifulSoup(html_doc, "html.parser")
    btables = soup.find_all(['b', 'table']) # find all the <b> and <table>
    titletables = []
    for i, item in enumerate(btables):
        if item.name == 'table':
            for j in range(i + 1):
                if btables[i-j].name == 'b':# step back to find a <b>
                    break
            titletables.append((btables[i - j], item))
    if tofloat:
        t2m = table2val_matrix
    else:
        t2m = table2matrix
    titlerows = [(tl.contents[0], t2m(tb)) for tl, tb in titletables]
    return titlerows

Response: return a list of tuples of title table...


Instruction:
How would you explain what the following Python 3 function does
def _has_name(soup_obj):
    try:
        name = soup_obj.name
        if name == None:
            return False
        return True
    except AttributeError:
        return False

Response: checks if soup_obj is really a soup object or just a string


Instruction:
Can you implement a function in Python 3 that
returns a list of lines between this table and the previous table

Response:
def lines_table(html_doc, tofloat=True):
    """return a list of [(lines, table), .....]

    lines = all the significant lines before the table.
        These are lines between this table and
        the previous table or 'hr' tag
    table = rows -> [[cell1, cell2, ..], [cell1, cell2, ..], ..]

    The lines act as a description for what is in the table
    """
    soup = BeautifulSoup(html_doc, "html.parser")
    linestables = []
    elements = soup.p.next_elements # start after the first para
    for element in elements:
        tabletup = []
        if not _has_name(element):
            continue
        if element.name == 'table': # hit the first table
            beforetable = []
            prev_elements = element.previous_elements # walk back and get the lines
            for prev_element in prev_elements:
                if not _has_name(prev_element):
                    continue
                if prev_element.name not in ('br', None): # no lines here
                    if prev_element.name in ('table', 'hr', 'tr', 'td'):
                        # just hit the previous table. You got all the lines
                        break
                    if prev_element.parent.name == "p":
                        # if the parent is "p", you will get it's text anyways from the parent
                        pass
                    else:
                        if prev_element.get_text(): # skip blank lines
                            beforetable.append(prev_element.get_text())
            beforetable.reverse()
            tabletup.append(beforetable)
            function_selector = {True:table2val_matrix, False:table2matrix}
            function = function_selector[tofloat]
            tabletup.append(function(element))
        if tabletup:
            linestables.append(tabletup)
    return linestables


Instruction:
Implement a Python 3 function for
making a named tuple grid

Response:
def _make_ntgrid(grid):
    """make a named tuple grid

    [["",  "a b", "b c", "c d"],
     ["x y", 1,     2,     3 ],
     ["y z", 4,     5,     6 ],
     ["z z", 7,     8,     9 ],]
    will return
    ntcol(x_y=ntrow(a_b=1, b_c=2, c_d=3),
          y_z=ntrow(a_b=4, b_c=5, c_d=6),
          z_z=ntrow(a_b=7, b_c=8, c_d=9))"""
    hnames = [_nospace(n) for n in grid[0][1:]]
    vnames = [_nospace(row[0]) for row in grid[1:]]
    vnames_s = " ".join(vnames)
    hnames_s = " ".join(hnames)
    ntcol = collections.namedtuple('ntcol', vnames_s)
    ntrow = collections.namedtuple('ntrow', hnames_s)
    rdict = [dict(list(zip(hnames, row[1:]))) for row in grid[1:]]
    ntrows = [ntrow(**rdict[i]) for i, name in enumerate(vnames)]
    ntcols = ntcol(**dict(list(zip(vnames, ntrows))))
    return ntcols


Instruction:
Here you have a function in Python 3, explain what it does
def onlylegalchar(name):
    legalchar = ascii_letters + digits + ' '
    return ''.join([s for s in name[:] if s in legalchar])

Response: return only legal chars


Instruction:
Make a summary of the following Python 3 code
def matchfieldnames(field_a, field_b):
    normalised_a = field_a.replace(' ', '_').lower()
    normalised_b = field_b.replace(' ', '_').lower()

    return normalised_a == normalised_b

Response: Check if two strings are equal ignoring case and spaces / underscore.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def intinlist(lst):
    for item in lst:
        try:
            item = int(item)
            return True
        except ValueError:
            pass
    return False

Response: test if int in list


Instruction:
Can you generate the documentation for the following Python 3 function
def replaceint(fname, replacewith='%s'):
    words = fname.split()
    for i, word in enumerate(words):
        try:
            word = int(word)
            words[i] = replacewith
        except ValueError:
            pass
    return ' '.join(words)

Response: replace int in lst


Instruction:
Make a summary of the following Python 3 code
def cleaniddfield(acomm):
    for key in list(acomm.keys()):
        val = acomm[key]
        acomm[key.lower()] = val
    for key in list(acomm.keys()):
        val = acomm[key]
        if key != key.lower():
            acomm.pop(key)
    return acomm

Response: make all the keys lower case


Instruction:
Can you generate the documentation for the following Python 3 function
def makecsvdiffs(thediffs, dtls, n1, n2):
    def ishere(val):
        if val == None:
            return "not here"
        else:
            return "is here"
    rows = []
    rows.append(['file1 = %s' % (n1, )])
    rows.append(['file2 = %s' % (n2, )])
    rows.append('')
    rows.append(theheader(n1, n2))
    keys = list(thediffs.keys()) # ensures sorting by Name
    keys.sort()
    # sort the keys in the same order as in the idd
    dtlssorter = DtlsSorter(dtls)
    keys = sorted(keys, key=dtlssorter.getkey)
    for key in keys:
        if len(key) == 2:
            rw2 = [''] + [ishere(i) for i in thediffs[key]]
        else:
            rw2 = list(thediffs[key])
        rw1 = list(key)
        rows.append(rw1 + rw2)
    return rows

Response: return the csv to be displayed


Instruction:
Implement a Python 3 function for
returning the diffs between two idfs

Response:
def idfdiffs(idf1, idf2):
    """return the diffs between the two idfs"""
    # for any object type, it is sorted by name
    thediffs = {}
    keys = idf1.model.dtls # undocumented variable

    for akey in keys:
        idfobjs1 = idf1.idfobjects[akey]
        idfobjs2 = idf2.idfobjects[akey]
        names = set([getobjname(i) for i in idfobjs1] +
                    [getobjname(i) for i in idfobjs2])
        names = sorted(names)
        idfobjs1 = sorted(idfobjs1, key=lambda idfobj: idfobj['obj'])
        idfobjs2 = sorted(idfobjs2, key=lambda idfobj: idfobj['obj'])
        for name in names:
            n_idfobjs1 = [item for item in idfobjs1
                          if getobjname(item) == name]
            n_idfobjs2 = [item for item in idfobjs2
                          if getobjname(item) == name]
            for idfobj1, idfobj2 in zip_longest(n_idfobjs1,
                                                           n_idfobjs2):
                if idfobj1 == None:
                    thediffs[(idfobj2.key.upper(),
                                getobjname(idfobj2))] = (None, idf2.idfname) #(idf1.idfname, None) -> old
                    break
                if idfobj2 == None:
                    thediffs[(idfobj1.key.upper(),
                                getobjname(idfobj1))] = (idf1.idfname, None) # (None, idf2.idfname) -> old
                    break
                for i, (f1, f2) in enumerate(zip(idfobj1.obj, idfobj2.obj)):
                    if i == 0:
                        f1, f2 = f1.upper(), f2.upper()
                    if f1 != f2:
                        thediffs[(
                            akey,
                            getobjname(idfobj1),
                            idfobj1.objidd[i]['field'][0])] = (f1, f2)
    return thediffs


Instruction:
Given the following Python 3 function, write the documentation
def heading2table(soup, table, row):
    tr = Tag(soup, name="tr")
    table.append(tr)
    for attr in row:
        th = Tag(soup, name="th")
        tr.append(th)
        th.append(attr)

Response: add heading row to table


Instruction:
Can you generate a brief explanation for the following Python 3 code
def row2table(soup, table, row):
    tr = Tag(soup, name="tr")
    table.append(tr)
    for attr in row:
        td = Tag(soup, name="td")
        tr.append(td)
        td.append(attr)

Response: ad a row to the table


Instruction:
Given the following Python 3 function, write the documentation
def extendlist(lst, i, value=''):
    if i < len(lst):
        pass
    else:
        lst.extend([value, ] * (i - len(lst) + 1))

Response: extend the list so that you have i - th value


Instruction:
Write a Python 3 script to
add functions to the epbunch

Response:
def addfunctions(abunch):
    """add functions to epbunch"""

    key = abunch.obj[0].upper()

    #-----------------
    # TODO : alternate strategy to avoid listing the objkeys in snames
    # check if epbunch has field "Zone_Name" or "Building_Surface_Name"
    # and is in group u'Thermal Zones and Surfaces'
    # then it is likely to be a surface.
    # of course we need to recode for surfaces that do not have coordinates :-(
    # or we can filter those out since they do not have
    # the field "Number_of_Vertices"
    snames = [
        "BuildingSurface:Detailed",
        "Wall:Detailed",
        "RoofCeiling:Detailed",
        "Floor:Detailed",
        "FenestrationSurface:Detailed",
        "Shading:Site:Detailed",
        "Shading:Building:Detailed",
        "Shading:Zone:Detailed", ]
    snames = [sname.upper() for sname in snames]
    if key in snames:
        func_dict = {
            'area': fh.area,
            'height': fh.height,  # not working correctly
            'width': fh.width,  # not working correctly
            'azimuth': fh.azimuth,
            'tilt': fh.tilt,
            'coords': fh.getcoords,  # needed for debugging
        }
        abunch.__functions.update(func_dict)

    #-----------------
    # print(abunch.getfieldidd )
    names = [
        "CONSTRUCTION",
        "MATERIAL",
        "MATERIAL:AIRGAP",
        "MATERIAL:INFRAREDTRANSPARENT",
        "MATERIAL:NOMASS",
        "MATERIAL:ROOFVEGETATION",
        "WINDOWMATERIAL:BLIND",
        "WINDOWMATERIAL:GLAZING",
        "WINDOWMATERIAL:GLAZING:REFRACTIONEXTINCTIONMETHOD",
        "WINDOWMATERIAL:GAP",
        "WINDOWMATERIAL:GAS",
        "WINDOWMATERIAL:GASMIXTURE",
        "WINDOWMATERIAL:GLAZINGGROUP:THERMOCHROMIC",
        "WINDOWMATERIAL:SCREEN",
        "WINDOWMATERIAL:SHADE",
        "WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM",
              ]
    if key in names:
        func_dict = {
            'rvalue': fh.rvalue,
            'ufactor': fh.ufactor,
            'rvalue_ip': fh.rvalue_ip,  # quick fix for Santosh. Needs to thought thru
            'ufactor_ip': fh.ufactor_ip,  # quick fix for Santosh. Needs to thought thru
            'heatcapacity': fh.heatcapacity,
        }
        abunch.__functions.update(func_dict)

    names = [
        'FAN:CONSTANTVOLUME',
        'FAN:VARIABLEVOLUME',
        'FAN:ONOFF',
        'FAN:ZONEEXHAUST',
        'FANPERFORMANCE:NIGHTVENTILATION',
              ]
    if key in names:
        func_dict = {
            'f_fanpower_bhp': fh.fanpower_bhp,
            'f_fanpower_watts': fh.fanpower_watts,
            'f_fan_maxcfm': fh.fan_maxcfm,
        }
        abunch.__functions.update(func_dict)
    # =====
    # code for references
    #-----------------
    # add function zonesurfaces
    if key == 'ZONE':
        func_dict = {'zonesurfaces':fh.zonesurfaces}
        abunch.__functions.update(func_dict)

    #-----------------
    # add function subsurfaces
    # going to cheat here a bit
    # check if epbunch has field "Zone_Name"
    # and is in group u'Thermal Zones and Surfaces'
    # then it is likely to be a surface attached to a zone
    fields = abunch.fieldnames
    try:
        group = abunch.getfieldidd('key')['group']
    except KeyError as e:  # some pytests don't have group
        group = None
    if group == u'Thermal Zones and Surfaces':
        if "Zone_Name" in fields:
            func_dict = {'subsurfaces':fh.subsurfaces}
            abunch.__functions.update(func_dict)

    return abunch


Instruction:
Write a Python 3 script for
getting the ranges for this field

Response:
def getrange(bch, fieldname):
    """get the ranges for this field"""
    keys = ['maximum', 'minimum', 'maximum<', 'minimum>', 'type']
    index = bch.objls.index(fieldname)
    fielddct_orig = bch.objidd[index]
    fielddct = copy.deepcopy(fielddct_orig)
    therange = {}
    for key in keys:
        therange[key] = fielddct.setdefault(key, None)
    if therange['type']:
        therange['type'] = therange['type'][0]
    if therange['type'] == 'real':
        for key in keys[:-1]:
            if therange[key]:
                therange[key] = float(therange[key][0])
    if therange['type'] == 'integer':
        for key in keys[:-1]:
            if therange[key]:
                therange[key] = int(therange[key][0])
    return therange


Instruction:
Create a Python 3 function for
checking if the value of the fieldname is in the range of the idd dict

Response:
def checkrange(bch, fieldname):
    """throw exception if the out of range"""
    fieldvalue = bch[fieldname]
    therange = bch.getrange(fieldname)
    if therange['maximum'] != None:
        if fieldvalue > therange['maximum']:
            astr = "Value %s is not less or equal to the 'maximum' of %s"
            astr = astr % (fieldvalue, therange['maximum'])
            raise RangeError(astr)
    if therange['minimum'] != None:
        if fieldvalue < therange['minimum']:
            astr = "Value %s is not greater or equal to the 'minimum' of %s"
            astr = astr % (fieldvalue, therange['minimum'])
            raise RangeError(astr)
    if therange['maximum<'] != None:
        if fieldvalue >= therange['maximum<']:
            astr = "Value %s is not less than the 'maximum<' of %s"
            astr = astr % (fieldvalue, therange['maximum<'])
            raise RangeError(astr)
    if  therange['minimum>'] != None:
        if fieldvalue <= therange['minimum>']:
            astr = "Value %s is not greater than the 'minimum>' of %s"
            astr = astr % (fieldvalue, therange['minimum>'])
            raise RangeError(astr)
    return fieldvalue
    """get the idd dict for this field
    Will return {} if the fieldname does not exist"""


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getfieldidd(bch, fieldname):
    # print(bch)
    try:
        fieldindex = bch.objls.index(fieldname)
    except ValueError as e:
        return {}  # the fieldname does not exist
                    # so there is no idd
    fieldidd = bch.objidd[fieldindex]
    return fieldidd

Response: get the idd dict for this fieldname Will return {} if the fieldname does not exist


Instruction:
Can you implement a function in Python 3 that
returns an item from the fieldidd given the iddkey

Response:
def getfieldidd_item(bch, fieldname, iddkey):
    """return an item from the fieldidd, given the iddkey
    will return and empty list if it does not have the iddkey
    or if the fieldname does not exist"""
    fieldidd = getfieldidd(bch, fieldname)
    try:
        return fieldidd[iddkey]
    except KeyError as e:
        return []


Instruction:
Make a summary of the following Python 3 code
def isequal(bch, fieldname, value, places=7):
    def equalalphanumeric(bch, fieldname, value):
        if bch.get_retaincase(fieldname):
            return bch[fieldname] == value
        else:
            return bch[fieldname].upper() == value.upper()

    fieldidd = bch.getfieldidd(fieldname)
    try:
        ftype = fieldidd['type'][0]
        if ftype in ['real', 'integer']:
            return almostequal(bch[fieldname], float(value), places=places)
        else:
            return equalalphanumeric(bch, fieldname, value)
    except KeyError as e:
        return equalalphanumeric(bch, fieldname, value)

Response: return True if the field is equal to value


Instruction:
Create a Python 3 function for
getting a list of objects that refer to this object

Response:
def getreferingobjs(referedobj, iddgroups=None, fields=None):
    """Get a list of objects that refer to this object"""
    # pseudocode for code below
    # referringobjs = []
    # referedobj has: -> Name
    #                 -> reference
    # for each obj in idf:
    # [optional filter -> objects in iddgroup]
    #     each field of obj:
    #     [optional filter -> field in fields]
    #         has object-list [refname]:
    #             if refname in reference:
    #                 if Name = field value:
    #                     referringobjs.append()
    referringobjs = []
    idf = referedobj.theidf
    referedidd = referedobj.getfieldidd("Name")
    try:
        references = referedidd['reference']
    except KeyError as e:
        return referringobjs
    idfobjs = idf.idfobjects.values()
    idfobjs = list(itertools.chain.from_iterable(idfobjs))  # flatten list
    if iddgroups:  # optional filter
        idfobjs = [anobj for anobj in idfobjs
            if anobj.getfieldidd('key')['group'] in iddgroups]
    for anobj in idfobjs:
        if not fields:
            thefields = anobj.objls
        else:
            thefields = fields
        for field in thefields:
            try:
                itsidd = anobj.getfieldidd(field)
            except ValueError as e:
                continue
            if 'object-list' in itsidd:
                refname = itsidd['object-list'][0]
                if refname in references:
                    if referedobj.isequal('Name', anobj[field]):
                        referringobjs.append(anobj)
    return referringobjs


Instruction:
Here you have a function in Python 3, explain what it does
def get_referenced_object(referring_object, fieldname):
    idf = referring_object.theidf
    object_list = referring_object.getfieldidd_item(fieldname, u'object-list')
    for obj_type in idf.idfobjects:
        for obj in idf.idfobjects[obj_type]:
            valid_object_lists = obj.getfieldidd_item("Name", u'reference')
            if set(object_list).intersection(set(valid_object_lists)):
                referenced_obj_name = referring_object[fieldname]
                if obj.Name == referenced_obj_name:
                    return obj

Response: Get an object that is referenced by a field in another object.


Instruction:
Implement a function in Python 3 to
return True if the field == value

Response:
def isequal(self, fieldname, value, places=7):
        """return True if the field == value
        Will retain case if get_retaincase == True
        for real value will compare to decimal 'places'
        """
        return isequal(self, fieldname, value, places=places)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getreferingobjs(self, iddgroups=None, fields=None):
        return getreferingobjs(self, iddgroups=iddgroups, fields=fields)

Response: Get a list of objects that refer to this object


Instruction:
Implement a Python 3 function for
voluming of a irregular tetrahedron

Response:
def vol_tehrahedron(poly):
    """volume of a irregular tetrahedron"""
    p_a = np.array(poly[0])
    p_b = np.array(poly[1])
    p_c = np.array(poly[2])
    p_d = np.array(poly[3])
    return abs(np.dot(
        np.subtract(p_a, p_d),
        np.cross(
            np.subtract(p_b, p_d),
            np.subtract(p_c, p_d))) / 6)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def vol(poly1, poly2):
    c_point = central_p(poly1, poly2)
    c_point = (c_point[0], c_point[1], c_point[2])
    vol_therah = 0
    num = len(poly1)
    poly1.append(poly1[0])
    poly2.append(poly2[0])
    for i in range(num - 2):
        # the upper part
        tehrahedron = [c_point, poly1[0], poly1[i+1], poly1[i+2]]
        vol_therah += vol_tehrahedron(tehrahedron)
        # the bottom part
        tehrahedron = [c_point, poly2[0], poly2[i+1], poly2[i+2]]
        vol_therah += vol_tehrahedron(tehrahedron)
    # the middle part
    for i in range(num):
        tehrahedron = [c_point, poly1[i], poly2[i], poly2[i+1]]
        vol_therah += vol_tehrahedron(tehrahedron)
        tehrahedron = [c_point, poly1[i], poly1[i+1], poly2[i]]
        vol_therah += vol_tehrahedron(tehrahedron)
    return vol_therah

Response: volume of a zone defined by two polygon bases


Instruction:
Here you have a function in Python 3, explain what it does
def makename2refdct(commdct):
    refdct = {}
    for comm in commdct: # commdct is a list of dict
        try:
            idfobj = comm[0]['idfobj'].upper()
            field1 = comm[1]
            if 'Name' in field1['field']:
                references = field1['reference']
                refdct[idfobj] = references
        except (KeyError, IndexError) as e:
            continue # not the expected pattern for reference
    return refdct

Response: make the name2refs dict in the idd_index


Instruction:
Implement a Python 3 function for
making the ref2namesdct in the idd_index

Response:
def makeref2namesdct(name2refdct):
    """make the ref2namesdct in the idd_index"""
    ref2namesdct = {}
    for key, values in name2refdct.items():
        for value in values:
            ref2namesdct.setdefault(value, set()).add(key)
    return ref2namesdct


Instruction:
Given the following Python 3 function, write the documentation
def ref2names2commdct(ref2names, commdct):
    for comm in commdct:
        for cdct in comm:
            try:
                refs = cdct['object-list'][0]
                validobjects = ref2names[refs]
                cdct.update({'validobjects':validobjects})
            except KeyError as e:
                continue
    return commdct

Response: embed ref2names into commdct


Instruction:
Can you generate the documentation for the following Python 3 function
def prevnode(edges, component):
    e = edges
    c = component
    n2c = [(a, b) for a, b in e if type(a) == tuple]
    c2n = [(a, b) for a, b in e if type(b) == tuple]
    node2cs = [(a, b) for a, b in e if b == c]
    c2nodes = []
    for node2c in node2cs:
        c2node = [(a, b) for a, b in c2n if b == node2c[0]]
        if len(c2node) == 0:
            # return []
            c2nodes = []
            break
        c2nodes.append(c2node[0])
    cs = [a for a, b in c2nodes]
    # test for connections that have no nodes
    # filter for no nodes
    nonodes = [(a, b) for a, b in e if type(a) != tuple and type(b) != tuple]
    for a, b in nonodes:
        if b == component:
            cs.append(a)
    return cs

Response: get the pervious component in the loop


Instruction:
Can you create a Python 3 function that
inserts an idfobject to list1 and list2.

Response:
def insert(self, i, v):
        """Insert an idfobject (bunch) to list1 and its object to list2."""
        self.list1.insert(i, v)
        self.list2.insert(i, v.obj)
        if isinstance(v, EpBunch):
            v.theidf = self.theidf


Instruction:
Implement a Python 3 function for
collecting data into fixed - length chunks or blocks

Response:
def grouper(num, iterable, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * num
    return zip_longest(fillvalue=fillvalue, *args)


Instruction:
Implement a function in Python 3 to
return the coordinates of the surface

Response:
def getcoords(ddtt):
    """return the coordinates of the surface"""
    n_vertices_index = ddtt.objls.index('Number_of_Vertices')
    first_x = n_vertices_index + 1 # X of first coordinate
    pts = ddtt.obj[first_x:]
    return list(grouper(3, pts))


Instruction:
Given the following Python 3 function, write the documentation
def cleanupversion(ver):
    lst = ver.split(".")
    if len(lst) == 1:
        lst.extend(['0', '0'])
    elif len(lst) == 2:
        lst.extend(['0'])
    elif len(lst) > 2:
        lst = lst[:3]
    lst[2] = '0' # ensure the 3rd number is 0
    cleanver = '.'.join(lst)
    return cleanver

Response: massage the version number so it matches the format of install folder


Instruction:
Make a summary of the following Python 3 code
def getiddfile(versionid):
    vlist = versionid.split('.')
    if len(vlist) == 1:
        vlist = vlist + ['0', '0']
    elif len(vlist) == 2:
        vlist = vlist + ['0']
    ver_str =  '-'.join(vlist)
    eplus_exe, _  = eppy.runner.run_functions.install_paths(ver_str)
    eplusfolder = os.path.dirname(eplus_exe)
    iddfile = '{}/Energy+.idd'.format(eplusfolder, )
    return iddfile

Response: find the IDD file of the E + installation


Instruction:
Make a summary of the following Python 3 code
def removecomment(astr, cphrase):
    # linesep = mylib3.getlinesep(astr)
    alist = astr.splitlines()
    for i in range(len(alist)):
        alist1 = alist[i].split(cphrase)
        alist[i] = alist1[0]

    # return string.join(alist, linesep)
    return '\n'.join(alist)

Response: removecomment is similar to the comment in python.


Instruction:
How would you explain what the following Python 3 function does
def initdict(self, fname):
        if isinstance(fname, Idd):
            self.dt, self.dtls = fname.dt, fname.dtls
            return self.dt, self.dtls

        astr = mylib2.readfile(fname)
        nocom = removecomment(astr, '!')
        idfst = nocom
        alist = idfst.split(';')
        lss = []
        for element in alist:
            lst = element.split(',')
            lss.append(lst)

        for i in range(0, len(lss)):
            for j in range(0, len(lss[i])):
                lss[i][j] = lss[i][j].strip()

        dt = {}
        dtls = []
        for element in lss:
            if element[0] == '':
                continue
            dt[element[0].upper()] = []
            dtls.append(element[0].upper())

        self.dt, self.dtls = dt, dtls
        return dt, dtls

Response: create a blank dictionary


Instruction:
Can you generate a brief explanation for the following Python 3 code
def makedict(self, dictfile, fnamefobject):
        #fname = './exapmlefiles/5ZoneDD.idf'
        #fname = './1ZoneUncontrolled.idf'
        if isinstance(dictfile, Idd):
            localidd = copy.deepcopy(dictfile)
            dt, dtls = localidd.dt, localidd.dtls
        else:
            dt, dtls = self.initdict(dictfile)
        # astr = mylib2.readfile(fname)
        astr = fnamefobject.read()
        try:
            astr = astr.decode('ISO-8859-2')
        except AttributeError:
            pass
        fnamefobject.close()
        nocom = removecomment(astr, '!')
        idfst = nocom
        # alist = string.split(idfst, ';')
        alist = idfst.split(';')
        lss = []
        for element in alist:
            # lst = string.split(element, ',')
            lst = element.split(',')
            lss.append(lst)

        for i in range(0, len(lss)):
            for j in range(0, len(lss[i])):
                lss[i][j] = lss[i][j].strip()

        for element in lss:
            node = element[0].upper()
            if node in dt:
                # stuff data in this key
                dt[node.upper()].append(element)
            else:
                # scream
                if node == '':
                    continue
                print('this node -%s-is not present in base dictionary' %
                      (node))

        self.dt, self.dtls = dt, dtls
        return dt, dtls

Response: stuff file data into the blank dictionary


Instruction:
How would you explain what the following Python 3 function does
def replacenode(self, othereplus, node):
        node = node.upper()
        self.dt[node.upper()] = othereplus.dt[node.upper()]

Response: replace the node here with the node from othereplus


Instruction:
Make a summary of the following Python 3 code
def add2node(self, othereplus, node):
        node = node.upper()
        self.dt[node.upper()] = self.dt[node.upper()] + \
            othereplus.dt[node.upper()]

Response: add the node here with the node from othereplus


Instruction:
Can you implement a function in Python 3 that
adds an item to the node.

Response:
def addinnode(self, otherplus, node, objectname):
        """add an item to the node.
        example: add a new zone to the element 'ZONE' """
        # do a test for unique object here
        newelement = otherplus.dt[node.upper()]


Instruction:
Given the following Python 3 function, write the documentation
def getrefs(self, reflist):
        alist = []
        for element in reflist:
            if element[0].upper() in self.dt:
                for elm in self.dt[element[0].upper()]:
                    alist.append(elm[element[1]])
        return alist

Response: getrefs returns a list of all the fields refered by reflist


Instruction:
Write a Python 3 function for
drawing a graph without the nodes

Response:
def dropnodes(edges):
    """draw a graph without the nodes"""
    newedges = []
    added = False
    for edge in edges:
        if bothnodes(edge):
            newtup = (edge[0][0], edge[1][0])
            newedges.append(newtup)
            added = True
        elif firstisnode(edge):
            for edge1 in edges:
                if edge[0] == edge1[1]:
                    newtup = (edge1[0], edge[1])
                    try:
                        newedges.index(newtup)
                    except ValueError as e:
                        newedges.append(newtup)
                    added = True
        elif secondisnode(edge):
            for edge1 in edges:
                if edge[1] == edge1[0]:
                    newtup = (edge[0], edge1[1])
                    try:
                        newedges.index(newtup)
                    except ValueError as e:
                        newedges.append(newtup)
                    added = True
        # gets the hanging nodes - nodes with no connection
        if not added:
            if firstisnode(edge):
                newedges.append((edge[0][0], edge[1]))
            if secondisnode(edge):
                newedges.append((edge[0], edge[1][0]))
        added = False
    return newedges


Instruction:
Can you create a Python 3 function that
gathers the nodes from the edges

Response:
def edges2nodes(edges):
    """gather the nodes from the edges"""
    nodes = []
    for e1, e2 in edges:
        nodes.append(e1)
        nodes.append(e2)
    nodedict = dict([(n, None) for n in nodes])
    justnodes = list(nodedict.keys())
    # justnodes.sort()
    justnodes = sorted(justnodes, key=lambda x: str(x[0]))
    return justnodes


Instruction:
Given the following Python 3 function, write the documentation
def makediagram(edges):
    graph = pydot.Dot(graph_type='digraph')
    nodes = edges2nodes(edges)
    epnodes = [(node,
        makeanode(node[0])) for node in nodes if nodetype(node)=="epnode"]
    endnodes = [(node,
        makeendnode(node[0])) for node in nodes if nodetype(node)=="EndNode"]
    epbr = [(node, makeabranch(node)) for node in nodes if not istuple(node)]
    nodedict = dict(epnodes + epbr + endnodes)
    for value in list(nodedict.values()):
        graph.add_node(value)
    for e1, e2 in edges:
        graph.add_edge(pydot.Edge(nodedict[e1], nodedict[e2]))
    return graph

Response: make the diagram with the edges


Instruction:
Can you write a function in Python 3 where it
returns the edges jointing the components of a branch

Response:
def makebranchcomponents(data, commdct, anode="epnode"):
    """return the edges jointing the components of a branch"""
    alledges = []

    objkey = 'BRANCH'
    cnamefield = "Component %s Name"
    inletfield = "Component %s Inlet Node Name"
    outletfield = "Component %s Outlet Node Name"

    numobjects = len(data.dt[objkey])
    cnamefields = loops.repeatingfields(data, commdct, objkey, cnamefield)
    inletfields = loops.repeatingfields(data, commdct, objkey, inletfield)
    outletfields = loops.repeatingfields(data, commdct, objkey, outletfield)

    inlts = loops.extractfields(data, commdct,
        objkey, [inletfields] * numobjects)
    cmps = loops.extractfields(data, commdct,
        objkey, [cnamefields] * numobjects)
    otlts = loops.extractfields(data, commdct,
        objkey, [outletfields] * numobjects)

    zipped = list(zip(inlts, cmps, otlts))
    tzipped = [transpose2d(item) for item in zipped]
    for i in range(len(data.dt[objkey])):
        tt = tzipped[i]
        # branchname = data.dt[objkey][i][1]
        edges = []
        for t0 in tt:
            edges = edges + [((t0[0], anode), t0[1]), (t0[1], (t0[2], anode))]
        alledges = alledges + edges
    return alledges


Instruction:
Explain what the following Python 3 code does
def makeairplantloop(data, commdct):
    anode = "epnode"
    endnode = "EndNode"

    # in plantloop get:
    #     demand inlet, outlet, branchlist
    #     supply inlet, outlet, branchlist
    plantloops = loops.plantloopfields(data, commdct)
    # splitters
    #     inlet
    #     outlet1
    #     outlet2
    splitters = loops.splitterfields(data, commdct)
    #
    # mixer
    #     outlet
    #     inlet1
    #     inlet2

    mixers = loops.mixerfields(data, commdct)
    #
    # supply barnchlist
    #     branch1 -> inlet, outlet
    #     branch2 -> inlet, outlet
    #     branch3 -> inlet, outlet
    #
    # CONNET INLET OUTLETS
    edges = []

    # get all branches
    branchkey = "branch".upper()
    branches = data.dt[branchkey]
    branch_i_o = {}
    for br in branches:
        br_name = br[1]
        in_out = loops.branch_inlet_outlet(data, commdct, br_name)
        branch_i_o[br_name] = dict(list(zip(["inlet", "outlet"], in_out)))
    # for br_name, in_out in branch_i_o.items():
    #     edges.append(((in_out["inlet"], anode), br_name))
    #     edges.append((br_name, (in_out["outlet"], anode)))

    # instead of doing the branch
    # do the content of the branch
    edges = makebranchcomponents(data, commdct)

    # connect splitter to nodes
    for splitter in splitters:
        # splitter_inlet = inletbranch.node
        splittername = splitter[0]
        inletbranchname = splitter[1]
        splitter_inlet = branch_i_o[inletbranchname]["outlet"]
        # edges = splitter_inlet -> splittername
        edges.append(((splitter_inlet, anode), splittername))
        # splitter_outlets = ouletbranches.nodes
        outletbranchnames = [br for br in splitter[2:]]
        splitter_outlets = [branch_i_o[br]["inlet"] for br in outletbranchnames]
        # edges = [splittername -> outlet for outlet in splitter_outlets]
        moreedges = [(splittername,
                            (outlet, anode)) for outlet in splitter_outlets]
        edges = edges + moreedges

    for mixer in mixers:
        # mixer_outlet = outletbranch.node
        mixername = mixer[0]
        outletbranchname = mixer[1]
        mixer_outlet = branch_i_o[outletbranchname]["inlet"]
        # edges = mixername -> mixer_outlet
        edges.append((mixername, (mixer_outlet, anode)))
        # mixer_inlets = inletbranches.nodes
        inletbranchnames = [br for br in mixer[2:]]
        mixer_inlets = [branch_i_o[br]["outlet"] for br in inletbranchnames]
        # edges = [mixername -> inlet for inlet in mixer_inlets]
        moreedges = [((inlet, anode), mixername) for inlet in mixer_inlets]
        edges = edges + moreedges

    # connect demand and supply side
    # for plantloop in plantloops:
    #     supplyinlet = plantloop[1]
    #     supplyoutlet = plantloop[2]
    #     demandinlet = plantloop[4]
    #     demandoutlet = plantloop[5]
    #     # edges = [supplyoutlet -> demandinlet, demandoutlet -> supplyinlet]
    #     moreedges = [((supplyoutlet, endnode), (demandinlet, endnode)),
    #         ((demandoutlet, endnode), (supplyinlet, endnode))]
    #     edges = edges + moreedges
    #
    # -----------air loop stuff----------------------
    # from s_airloop2.py
    # Get the demand and supply nodes from 'airloophvac'
    # in airloophvac get:
    #   get branch, supplyinlet, supplyoutlet, demandinlet, demandoutlet
    objkey = "airloophvac".upper()
    fieldlists = [["Branch List Name",
        "Supply Side Inlet Node Name",
        "Demand Side Outlet Node Name",
        "Demand Side Inlet Node Names",
        "Supply Side Outlet Node Names"]] * loops.objectcount(data, objkey)
    airloophvacs = loops.extractfields(data, commdct, objkey, fieldlists)
    # airloophvac = airloophvacs[0]

    # in AirLoopHVAC:ZoneSplitter:
    #   get Name, inlet, all outlets
    objkey = "AirLoopHVAC:ZoneSplitter".upper()
    singlefields = ["Name", "Inlet Node Name"]
    fld = "Outlet %s Node Name"
    repeatfields = loops.repeatingfields(data, commdct, objkey, fld)
    fieldlist = singlefields + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    zonesplitters = loops.extractfields(data, commdct, objkey, fieldlists)

    # in AirLoopHVAC:SupplyPlenum:
    #   get Name, Zone Name, Zone Node Name, inlet, all outlets
    objkey = "AirLoopHVAC:SupplyPlenum".upper()
    singlefields = ["Name", "Zone Name", "Zone Node Name", "Inlet Node Name"]
    fld = "Outlet %s Node Name"
    repeatfields = loops.repeatingfields(data, commdct, objkey, fld)
    fieldlist = singlefields + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    supplyplenums = loops.extractfields(data, commdct, objkey, fieldlists)

    # in AirLoopHVAC:ZoneMixer:
    #   get Name, outlet, all inlets
    objkey = "AirLoopHVAC:ZoneMixer".upper()
    singlefields = ["Name", "Outlet Node Name"]
    fld = "Inlet %s Node Name"
    repeatfields = loops.repeatingfields(data, commdct, objkey, fld)
    fieldlist = singlefields + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    zonemixers = loops.extractfields(data, commdct, objkey, fieldlists)

    # in AirLoopHVAC:ReturnPlenum:
    #   get Name, Zone Name, Zone Node Name, outlet, all inlets
    objkey = "AirLoopHVAC:ReturnPlenum".upper()
    singlefields = ["Name", "Zone Name", "Zone Node Name", "Outlet Node Name"]
    fld = "Inlet %s Node Name"
    repeatfields = loops.repeatingfields(data, commdct, objkey, fld)
    fieldlist = singlefields + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    returnplenums = loops.extractfields(data, commdct, objkey, fieldlists)

    # connect room to each equip in equiplist
    # in ZoneHVAC:EquipmentConnections:
    #   get Name, equiplist, zoneairnode, returnnode
    objkey = "ZoneHVAC:EquipmentConnections".upper()
    singlefields = ["Zone Name", "Zone Conditioning Equipment List Name",
        "Zone Air Node Name", "Zone Return Air Node Name"]
    repeatfields = []
    fieldlist = singlefields + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    equipconnections = loops.extractfields(data, commdct, objkey, fieldlists)
    # in ZoneHVAC:EquipmentList:
    #   get Name, all equiptype, all equipnames
    objkey = "ZoneHVAC:EquipmentList".upper()
    singlefields = ["Name", ]
    fieldlist = singlefields
    flds = ["Zone Equipment %s Object Type", "Zone Equipment %s Name"]
    repeatfields = loops.repeatingfields(data, commdct, objkey, flds)
    fieldlist = fieldlist + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    equiplists = loops.extractfields(data, commdct, objkey, fieldlists)
    equiplistdct = dict([(ep[0], ep[1:])  for ep in equiplists])
    for key, equips in list(equiplistdct.items()):
        enames = [equips[i] for i in range(1, len(equips), 2)]
        equiplistdct[key] = enames
    # adistuunit -> room
    # adistuunit <- VAVreheat
    # airinlet -> VAVreheat
    # in ZoneHVAC:AirDistributionUnit:
    #   get Name, equiplist, zoneairnode, returnnode
    objkey = "ZoneHVAC:AirDistributionUnit".upper()
    singlefields = ["Name", "Air Terminal Object Type", "Air Terminal Name"]
    repeatfields = []
    fieldlist = singlefields + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    adistuunits = loops.extractfields(data, commdct, objkey, fieldlists)
    # code only for AirTerminal:SingleDuct:VAV:Reheat
    # get airinletnodes for vavreheats
    # in AirTerminal:SingleDuct:VAV:Reheat:
    #   get Name, airinletnode
    adistuinlets = loops.makeadistu_inlets(data, commdct)
    alladistu_comps = []
    for key in list(adistuinlets.keys()):
        objkey = key.upper()
        singlefields = ["Name"] + adistuinlets[key]
        repeatfields = []
        fieldlist = singlefields + repeatfields
        fieldlists = [fieldlist] * loops.objectcount(data, objkey)
        adistu_components = loops.extractfields(data, commdct, objkey, fieldlists)
        alladistu_comps.append(adistu_components)

    # in AirTerminal:SingleDuct:Uncontrolled:
    #   get Name, airinletnode
    objkey = "AirTerminal:SingleDuct:Uncontrolled".upper()
    singlefields = ["Name", "Zone Supply Air Node Name"]
    repeatfields = []
    fieldlist = singlefields + repeatfields
    fieldlists = [fieldlist] * loops.objectcount(data, objkey)
    uncontrolleds = loops.extractfields(data, commdct, objkey, fieldlists)

    anode = "epnode"
    endnode = "EndNode"

    # edges = []

    # connect demand and supply side
    # for airloophvac in airloophvacs:
    #     supplyinlet = airloophvac[1]
    #     supplyoutlet = airloophvac[4]
    #     demandinlet = airloophvac[3]
    #     demandoutlet = airloophvac[2]
    #     # edges = [supplyoutlet -> demandinlet, demandoutlet -> supplyinlet]
    #     moreedges = [((supplyoutlet, endnode), (demandinlet, endnode)),
    #         ((demandoutlet, endnode), (supplyinlet, endnode))]
    #     edges = edges + moreedges

    # connect zonesplitter to nodes
    for zonesplitter in zonesplitters:
        name = zonesplitter[0]
        inlet = zonesplitter[1]
        outlets = zonesplitter[2:]
        edges.append(((inlet, anode), name))
        for outlet in outlets:
            edges.append((name, (outlet, anode)))

    # connect supplyplenum to nodes
    for supplyplenum in supplyplenums:
        name = supplyplenum[0]
        inlet = supplyplenum[3]
        outlets = supplyplenum[4:]
        edges.append(((inlet, anode), name))
        for outlet in outlets:
            edges.append((name, (outlet, anode)))

    # connect zonemixer to nodes
    for zonemixer in zonemixers:
        name = zonemixer[0]
        outlet = zonemixer[1]
        inlets = zonemixer[2:]
        edges.append((name, (outlet, anode)))
        for inlet in inlets:
            edges.append(((inlet, anode), name))

    # connect returnplenums to nodes
    for returnplenum in returnplenums:
        name = returnplenum[0]
        outlet = returnplenum[3]
        inlets = returnplenum[4:]
        edges.append((name, (outlet, anode)))
        for inlet in inlets:
            edges.append(((inlet, anode), name))

    # connect room to return node
    for equipconnection in equipconnections:
        zonename = equipconnection[0]
        returnnode = equipconnection[-1]
        edges.append((zonename, (returnnode, anode)))

    # connect equips to room
    for equipconnection in equipconnections:
        zonename = equipconnection[0]
        zequiplistname = equipconnection[1]
        for zequip in equiplistdct[zequiplistname]:
            edges.append((zequip, zonename))

    # adistuunit <- adistu_component
    for adistuunit in adistuunits:
        unitname = adistuunit[0]
        compname = adistuunit[2]
        edges.append((compname, unitname))

    # airinlet -> adistu_component
    for adistu_comps in alladistu_comps:
        for adistu_comp in adistu_comps:
            name = adistu_comp[0]
            for airnode in adistu_comp[1:]:
                edges.append(((airnode, anode), name))

    # supplyairnode -> uncontrolled
    for uncontrolled in uncontrolleds:
        name = uncontrolled[0]
        airnode = uncontrolled[1]
        edges.append(((airnode, anode), name))

    # edges = edges + moreedges
    return edges

Response: make the edges for the airloop and the plantloop


Instruction:
Can you generate the documentation for the following Python 3 function
def getedges(fname, iddfile):
    data, commdct, _idd_index = readidf.readdatacommdct(fname, iddfile=iddfile)
    edges = makeairplantloop(data, commdct)
    return edges

Response: return the edges of the idf file fname