Instruction:
Write a Python 3 function that can
return a tuple of the input string st1 st2 and lss which are the nested list of all the variables in the Energy +. idd file

Response:
def get_nocom_vars(astr):
    """
    input 'astr' which is the Energy+.idd file as a string
    returns (st1, st2, lss)
    st1 = with all the ! comments striped
    st2 = strips all comments - both the '!' and '\\'
    lss = nested list of all the variables in Energy+.idd file
    """
    nocom = nocomment(astr, '!')# remove '!' comments
    st1 = nocom
    nocom1 = nocomment(st1, '\\')# remove '\' comments
    st1 = nocom
    st2 = nocom1
    # alist = string.split(st2, ';')
    alist = st2.split(';')
    lss = []

    # break the .idd file into a nested list
    #=======================================
    for element in alist:
        # item = string.split(element, ',')
        item = element.split(',')
        lss.append(item)
    for i in range(0, len(lss)):
        for j in range(0, len(lss[i])):
            lss[i][j] = lss[i][j].strip()
    if len(lss) > 1:
        lss.pop(-1)
    #=======================================

    #st1 has the '\' comments --- looks like I don't use this
    #lss is the .idd file as a nested list
    return (st1, st2, lss)


Instruction:
Explain what the following Python 3 code does
def removeblanklines(astr):
    lines = astr.splitlines()
    lines = [line for line in lines if line.strip() != ""]
    return "\n".join(lines)

Response: remove the blank lines in astr


Instruction:
Implement a Python 3 function for
copying from extractidddata below. It deals with all the types of files

Response:
def _readfname(fname):
    """copied from extractidddata below.
    It deals with all the types of fnames"""
    try:
        if isinstance(fname, (file, StringIO)):
            astr = fname.read()
        else:
            astr = open(fname, 'rb').read()
    except NameError:
        if isinstance(fname, (FileIO, StringIO)):
            astr = fname.read()
        else:
            astr = mylib2.readfile(fname)
    return astr


Instruction:
How would you implement a function in Python 3 that
inserts group info into extracted idd

Response:
def embedgroupdata(extract_func, fname, debug):
    """insert group info into extracted idd"""

    astr = _readfname(fname)

    # fname is exhausted by the above read
    # reconstitute fname as a StringIO
    fname = StringIO(astr)

    try:
        astr = astr.decode('ISO-8859-2')
    except Exception as e:
        pass # for python 3
    glist = iddgroups.iddtxt2grouplist(astr)

    blocklst, commlst, commdct = extract_func(fname)
    # add group information to commlst and commdct
    # glist = getglist(fname)
    commlst = iddgroups.group2commlst(commlst, glist)
    commdct = iddgroups.group2commdct(commdct, glist)
    return blocklst, commlst, commdct


Instruction:
Can you generate the documentation for the following Python 3 function
def extractidddata(fname, debug=False):
    try:
        if isinstance(fname, (file, StringIO)):
            astr = fname.read()
            try:
                astr = astr.decode('ISO-8859-2')
            except AttributeError:
                pass
        else:
            astr = mylib2.readfile(fname)
            # astr = astr.decode('ISO-8859-2') -> mylib1 does a decode
    except NameError:
        if isinstance(fname, (FileIO, StringIO)):
            astr = fname.read()
            try:
                astr = astr.decode('ISO-8859-2')
            except AttributeError:
                pass
        else:
            astr = mylib2.readfile(fname)
            # astr = astr.decode('ISO-8859-2') -> mylib2.readfile has decoded
    (nocom, nocom1, blocklst) = get_nocom_vars(astr)

    astr = nocom
    st1 = removeblanklines(astr)
    if debug:
        mylib1.write_str2file('nocom2.txt', st1.encode('latin-1'))

    #find the groups and the start object of the group
    #find all the group strings
    groupls = []
    alist = st1.splitlines()
    for element in alist:
        lss = element.split()
        if lss[0].upper() == '\\group'.upper():
            groupls.append(element)

    #find the var just after each item in groupls
    groupstart = []
    for i in range(len(groupls)):
        iindex = alist.index(groupls[i])
        groupstart.append([alist[iindex], alist[iindex+1]])

    #remove the group commentline
    for element in groupls:
        alist.remove(element)

    if debug:
        st1 = '\n'.join(alist)
        mylib1.write_str2file('nocom3.txt', st1.encode('latin-1'))

    #strip each line
    for i in range(len(alist)):
        alist[i] = alist[i].strip()

    if debug:
        st1 = '\n'.join(alist)
        mylib1.write_str2file('nocom4.txt', st1.encode('latin-1'))

    #ensure that each line is a comment or variable
    #find lines that don't start with a comment
    #if this line has a comment in it
    #   then move the comment to a new line below
    lss = []
    for i in range(len(alist)):
        #find lines that don't start with a comment
        if alist[i][0] != '\\':
            #if this line has a comment in it
            pnt = alist[i].find('\\')
            if pnt != -1:
                #then move the comment to a new line below
                lss.append(alist[i][:pnt].strip())
                lss.append(alist[i][pnt:].strip())
            else:
                lss.append(alist[i])
        else:
            lss.append(alist[i])

    alist = lss[:]
    if debug:
        st1 = '\n'.join(alist)
        mylib1.write_str2file('nocom5.txt', st1.encode('latin-1'))

    #need to make sure that each line has only one variable - as in WindowGlassSpectralData,
    lss = []
    for element in alist:
        # if the line is not a comment
        if element[0] != '\\':
            #test for more than one var
            llist = element.split(',')
            if llist[-1] == '':
                tmp = llist.pop()
            for elm in llist:
                if elm[-1] == ';':
                    lss.append(elm.strip())
                else:
                    lss.append((elm+',').strip())
        else:
            lss.append(element)

    ls_debug = alist[:] # needed for the next debug - 'nocom7.txt'
    alist = lss[:]
    if debug:
        st1 = '\n'.join(alist)
        mylib1.write_str2file('nocom6.txt', st1.encode('latin-1'))

    if debug:
        #need to make sure that each line has only one variable - as in WindowGlassSpectralData,
        #this is same as above.
        # but the variables are put in without the ';' and ','
        #so we can do a diff between 'nocom7.txt' and 'nocom8.txt'. Should be identical
        lss_debug = []
        for element in ls_debug:
            # if the line is not a comment
            if element[0] != '\\':
                #test for more than one var
                llist = element.split(',')
                if llist[-1] == '':
                    tmp = llist.pop()
                for elm in llist:
                    if elm[-1] == ';':
                        lss_debug.append(elm[:-1].strip())
                    else:
                        lss_debug.append((elm).strip())
            else:
                lss_debug.append(element)

        ls_debug = lss_debug[:]
        st1 = '\n'.join(ls_debug)
        mylib1.write_str2file('nocom7.txt', st1.encode('latin-1'))

    #replace each var with '=====var======'
    #join into a string,
    #split using '=====var====='
    for i in range(len(lss)):
        #if the line is not a comment
        if lss[i][0] != '\\':
            lss[i] = '=====var====='

    st2 = '\n'.join(lss)
    lss = st2.split('=====var=====\n')
    lss.pop(0) # the above split generates an extra item at start

    if debug:
        fname = 'nocom8.txt'
        fhandle = open(fname, 'wb')
        k = 0
        for i in range(len(blocklst)):
            for j in range(len(blocklst[i])):
                atxt = blocklst[i][j]+'\n'
                fhandle.write(atxt)
                atxt = lss[k]
                fhandle.write(atxt.encode('latin-1'))
                k = k+1

        fhandle.close()

    #map the structure of the comments -(this is 'lss' now) to
    #the structure of blocklst - blocklst is a nested list
    #make lss a similar nested list
    k = 0
    lst = []
    for i in range(len(blocklst)):
        lst.append([])
        for j in range(len(blocklst[i])):
            lst[i].append(lss[k])
            k = k+1

    if debug:
        fname = 'nocom9.txt'
        fhandle = open(fname, 'wb')
        k = 0
        for i in range(len(blocklst)):
            for j in range(len(blocklst[i])):
                atxt = blocklst[i][j]+'\n'
                fhandle.write(atxt)
                fhandle.write(lst[i][j].encode('latin-1'))
                k = k+1

        fhandle.close()

    #break up multiple line comment so that it is a list
    for i in range(len(lst)):
        for j in range(len(lst[i])):
            lst[i][j] = lst[i][j].splitlines()
            # remove the '\'
            for k in range(len(lst[i][j])):
                lst[i][j][k] = lst[i][j][k][1:]
    commlst = lst

    #copied with minor modifications from readidd2_2.py -- which has been erased ha !
    clist = lst
    lss = []
    for i in range(0, len(clist)):
        alist = []
        for j in range(0, len(clist[i])):
            itt = clist[i][j]
            ddtt = {}
            for element in itt:
                if len(element.split()) == 0:
                    break
                ddtt[element.split()[0].lower()] = []

            for element in itt:
                if len(element.split()) == 0:
                    break
                # ddtt[element.split()[0].lower()].append(string.join(element.split()[1:]))
                ddtt[element.split()[0].lower()].append(' '.join(element.split()[1:]))

            alist.append(ddtt)

        lss.append(alist)
    commdct = lss

    # add group information to commlst and commdct
    # glist = iddgroups.idd2grouplist(fname)
    # commlst = group2commlst(commlst, glist)
    # commdct = group2commdct(commdct, glist)

    return blocklst, commlst, commdct

Response: This function extracts all the needed information out of the idd file fname and returns a series of strings.


Instruction:
How would you explain what the following Python 3 function does
def getobjectref(blocklst, commdct):
    objlst_dct = {}
    for eli in commdct:
        for elj in eli:
            if 'object-list' in elj:
                objlist = elj['object-list'][0]
                objlst_dct[objlist] = []

    for objlist in list(objlst_dct.keys()):
        for i in range(len(commdct)):
            for j in range(len(commdct[i])):
                if 'reference' in commdct[i][j]:
                    for ref in commdct[i][j]['reference']:
                        if ref == objlist:
                            objlst_dct[objlist].append((blocklst[i][0], j))
    return objlst_dct

Response: returns a dictionary of object - lists that points to a list of tuples


Instruction:
Implement a function in Python 3 to
read the idf file

Response:
def readdatacommlst(idfname):
    """read the idf file"""
    # iddfile = sys.path[0] + '/EplusCode/Energy+.idd'
    iddfile = 'Energy+.idd'
    # iddfile = './EPlusInterfaceFunctions/E1.idd' # TODO : can the path name be not hard coded
    iddtxt = open(iddfile, 'r').read()
    block, commlst, commdct = parse_idd.extractidddata(iddfile)

    theidd = eplusdata.Idd(block, 2)
    data = eplusdata.Eplusdata(theidd, idfname)
    return data, commlst


Instruction:
How would you code a function in Python 3 to
read the idf file

Response:
def readdatacommdct(idfname, iddfile='Energy+.idd', commdct=None):
    """read the idf file"""
    if not commdct:
        block, commlst, commdct, idd_index = parse_idd.extractidddata(iddfile)
        theidd = eplusdata.Idd(block, 2)
    else:
        theidd = iddfile
    data = eplusdata.Eplusdata(theidd, idfname)
    return data, commdct, idd_index


Instruction:
Can you generate a brief explanation for the following Python 3 code
def extractfields(data, commdct, objkey, fieldlists):
    # TODO : this assumes that the field list identical for
    # each instance of the object. This is not true.
    # So we should have a field list for each instance of the object
    # and map them with a zip
    objindex = data.dtls.index(objkey)
    objcomm = commdct[objindex]
    objfields = []
    # get the field names of that object
    for dct in objcomm[0:]:
        try:
            thefieldcomms = dct['field']
            objfields.append(thefieldcomms[0])
        except KeyError as err:
            objfields.append(None)
    fieldindexes = []
    for fieldlist in fieldlists:
        fieldindex = []
        for item in fieldlist:
            if isinstance(item, int):
                fieldindex.append(item)
            else:
                fieldindex.append(objfields.index(item) + 0)
                # the index starts at 1, not at 0
        fieldindexes.append(fieldindex)
    theobjects = data.dt[objkey]
    fieldcontents = []
    for theobject, fieldindex in zip(theobjects, fieldindexes):
        innerlst = []
        for item in fieldindex:
            try:
                innerlst.append(theobject[item])
            except IndexError as err:
                break
        fieldcontents.append(innerlst)
        # fieldcontents.append([theobject[item] for item in fieldindex])
    return fieldcontents

Response: extracts all the fields of a single object in the object list


Instruction:
How would you explain what the following Python 3 function does
def plantloopfieldlists(data):
    objkey = 'plantloop'.upper()
    numobjects = len(data.dt[objkey])
    return [[
        'Name',
        'Plant Side Inlet Node Name',
        'Plant Side Outlet Node Name',
        'Plant Side Branch List Name',
        'Demand Side Inlet Node Name',
        'Demand Side Outlet Node Name',
        'Demand Side Branch List Name']] * numobjects

Response: return the plantloopfield list


Instruction:
Write a Python 3 function for
getting plantloop fields to diagram it

Response:
def plantloopfields(data, commdct):
    """get plantloop fields to diagram it"""
    fieldlists = plantloopfieldlists(data)
    objkey = 'plantloop'.upper()
    return extractfields(data, commdct, objkey, fieldlists)


Instruction:
Create a Python 3 function for
getting branches from the branchlist

Response:
def branchlist2branches(data, commdct, branchlist):
    """get branches from the branchlist"""
    objkey = 'BranchList'.upper()
    theobjects = data.dt[objkey]
    fieldlists = []
    objnames = [obj[1] for obj in theobjects]
    for theobject in theobjects:
        fieldlists.append(list(range(2, len(theobject))))
    blists = extractfields(data, commdct, objkey, fieldlists)
    thebranches = [branches for name, branches in zip(objnames, blists)
                   if name == branchlist]
    return thebranches[0]


Instruction:
Can you write a function in Python 3 where it
returns the inlet and outlet of a branch

Response:
def branch_inlet_outlet(data, commdct, branchname):
    """return the inlet and outlet of a branch"""
    objkey = 'Branch'.upper()
    theobjects = data.dt[objkey]
    theobject = [obj for obj in theobjects if obj[1] == branchname]
    theobject = theobject[0]
    inletindex = 6
    outletindex = len(theobject) - 2
    return [theobject[inletindex], theobject[outletindex]]


Instruction:
How would you implement a function in Python 3 that
gets splitter fields to diagram it

Response:
def splitterfields(data, commdct):
    """get splitter fields to diagram it"""
    objkey = "Connector:Splitter".upper()
    fieldlists = splittermixerfieldlists(data, commdct, objkey)
    return extractfields(data, commdct, objkey, fieldlists)


Instruction:
Write a Python 3 function that can
get mixer fields to diagram it

Response:
def mixerfields(data, commdct):
    """get mixer fields to diagram it"""
    objkey = "Connector:Mixer".upper()
    fieldlists = splittermixerfieldlists(data, commdct, objkey)
    return extractfields(data, commdct, objkey, fieldlists)


Instruction:
Create a Python 3 function to
return a list of repeating fields

Response:
def repeatingfields(theidd, commdct, objkey, flds):
    """return a list of repeating fields
    fld is in format 'Component %s Name'
    so flds = [fld % (i, ) for i in range(n)]
    does not work for 'fields as indicated' """
    # TODO : make it work for 'fields as indicated'
    if type(flds) != list:
        flds = [flds] # for backward compatability
    objindex = theidd.dtls.index(objkey)
    objcomm = commdct[objindex]
    allfields = []
    for fld in flds:
        thefields = []
        indx = 1
        for i in range(len(objcomm)):
            try:
                thefield = fld % (indx, )
                if objcomm[i]['field'][0] == thefield:
                    thefields.append(thefield)
                    indx = indx + 1
            except KeyError as err:
                pass
        allfields.append(thefields)
    allfields = list(zip(*allfields))
    return [item for sublist in allfields for item in sublist]


Instruction:
Can you generate the documentation for the following Python 3 function
def objectcount(data, key):
    objkey = key.upper()
    return len(data.dt[objkey])

Response: return the count of objects of key


Instruction:
Here you have a function in Python 3, explain what it does
def getfieldindex(data, commdct, objkey, fname):
    objindex = data.dtls.index(objkey)
    objcomm = commdct[objindex]
    for i_index, item in enumerate(objcomm):
        try:
            if item['field'] == [fname]:
                break
        except KeyError as err:
            pass
    return i_index

Response: given objkey and fieldname return its index


Instruction:
Write a Python 3 function that can
make the dict adistu_inlets

Response:
def makeadistu_inlets(data, commdct):
    """make the dict adistu_inlets"""
    adistus = getadistus(data, commdct)
    # assume that the inlet node has the words "Air Inlet Node Name"
    airinletnode = "Air Inlet Node Name"
    adistu_inlets = {}
    for adistu in adistus:
        objkey = adistu.upper()
        objindex = data.dtls.index(objkey)
        objcomm = commdct[objindex]
        airinlets = []
        for i, comm in enumerate(objcomm):
            try:
                if comm['field'][0].find(airinletnode) != -1:
                    airinlets.append(comm['field'][0])
            except KeyError as err:
                pass
        adistu_inlets[adistu] = airinlets
    return adistu_inlets


Instruction:
Implement a Python 3 function for
getting the version number from the E + install folder

Response:
def folder2ver(folder):
    """get the version number from the E+ install folder"""
    ver = folder.split('EnergyPlus')[-1]
    ver = ver[1:]
    splitapp = ver.split('-')
    ver = '.'.join(splitapp)
    return ver


Instruction:
Implement a Python 3 function for
converting the idf text to a simple text

Response:
def idf2txt(txt):
    """convert the idf text to a simple text"""
    astr = nocomment(txt)
    objs = astr.split(';')
    objs = [obj.split(',') for obj in objs]
    objs = [[line.strip() for line in obj] for obj in objs]
    objs = [[_tofloat(line) for line in obj] for obj in objs]
    objs = [tuple(obj) for obj in objs]
    objs.sort()

    lst = []
    for obj in objs:
        for field in obj[:-1]:
            lst.append('%s,' % (field, ))
        lst.append('%s;\n' % (obj[-1], ))

    return '\n'.join(lst)


Instruction:
Given the following Python 3 function, write the documentation
def iddversiontuple(afile):
    def versiontuple(vers):
        """version tuple"""
        return tuple([int(num) for num in vers.split(".")])
    try:
        fhandle = open(afile, 'rb')
    except TypeError:
        fhandle = afile
    line1 = fhandle.readline()
    try:
        line1 = line1.decode('ISO-8859-2')
    except AttributeError:
        pass
    line = line1.strip()
    if line1 == '':
        return (0,)
    vers = line.split()[-1]
    return versiontuple(vers)

Response: given the idd file or filehandle return the version tuple


Instruction:
How would you explain what the following Python 3 function does
def makeabunch(commdct, obj, obj_i):
    objidd = commdct[obj_i]
    objfields = [comm.get('field') for comm in commdct[obj_i]]
    objfields[0] = ['key']
    objfields = [field[0] for field in objfields]
    obj_fields = [bunchhelpers.makefieldname(field) for field in objfields]
    bobj = EpBunch(obj, obj_fields, objidd)
    return bobj

Response: make a bunch from the object


Instruction:
Implement a function in Python 3 to
make bunches with data

Response:
def makebunches(data, commdct):
    """make bunches with data"""
    bunchdt = {}
    ddtt, dtls = data.dt, data.dtls
    for obj_i, key in enumerate(dtls):
        key = key.upper()
        bunchdt[key] = []
        objs = ddtt[key]
        for obj in objs:
            bobj = makeabunch(commdct, obj, obj_i)
            bunchdt[key].append(bobj)
    return bunchdt


Instruction:
Create a Python 3 function to
make bunches with data

Response:
def makebunches_alter(data, commdct, theidf):
    """make bunches with data"""
    bunchdt = {}
    dt, dtls = data.dt, data.dtls
    for obj_i, key in enumerate(dtls):
        key = key.upper()
        objs = dt[key]
        list1 = []
        for obj in objs:
            bobj = makeabunch(commdct, obj, obj_i)
            list1.append(bobj)
        bunchdt[key] = Idf_MSequence(list1, objs, theidf)
    return bunchdt


Instruction:
Implement a Python 3 function for
converting the float and interger fields

Response:
def convertfields_old(key_comm, obj, inblock=None):
    """convert the float and interger fields"""
    convinidd = ConvInIDD()
    typefunc = dict(integer=convinidd.integer, real=convinidd.real)
    types = []
    for comm in key_comm:
        types.append(comm.get('type', [None])[0])
    convs = [typefunc.get(typ, convinidd.no_type) for typ in types]
    try:
        inblock = list(inblock)
    except TypeError as e:
        inblock = ['does not start with N'] * len(obj)
    for i, (val, conv, avar) in enumerate(zip(obj, convs, inblock)):
        if i == 0:
            # inblock[0] is the key
            pass
        else:
            val = conv(val, inblock[i])
        obj[i] = val
    return obj


Instruction:
Explain what the following Python 3 code does
def convertafield(field_comm, field_val, field_iddname):
    convinidd = ConvInIDD()
    field_typ = field_comm.get('type', [None])[0]
    conv = convinidd.conv_dict().get(field_typ, convinidd.no_type)
    return conv(field_val, field_iddname)

Response: convert field based on field info in IDD


Instruction:
Can you tell what is the following Python 3 function doing
def convertfields(key_comm, obj, inblock=None):
    # f_ stands for field_
    convinidd = ConvInIDD()
    if not inblock:
        inblock = ['does not start with N'] * len(obj)
    for i, (f_comm, f_val, f_iddname) in enumerate(zip(key_comm, obj, inblock)):
        if i == 0:
            # inblock[0] is the iddobject key. No conversion here
            pass
        else:
            obj[i] = convertafield(f_comm, f_val, f_iddname)
    return obj

Response: convert based on float integer and A1 and N1


Instruction:
Explain what the following Python 3 code does
def addfunctions(dtls, bunchdt):
    snames = [
        "BuildingSurface:Detailed",
        "Wall:Detailed",
        "RoofCeiling:Detailed",
        "Floor:Detailed",
        "FenestrationSurface:Detailed",
        "Shading:Site:Detailed",
        "Shading:Building:Detailed",
        "Shading:Zone:Detailed", ]
    for sname in snames:
        if sname.upper() in bunchdt:
            surfaces = bunchdt[sname.upper()]
            for surface in surfaces:
                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
                }
                try:
                    surface.__functions.update(func_dict)
                except KeyError as e:
                    surface.__functions = func_dict

Response: add functions to the objects in the objects in the bunchdt


Instruction:
Create a Python 3 function to
add functions to a new bunch object

Response:
def addfunctions2new(abunch, key):
    """add functions to a new bunch/munch object"""
    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
        }
        try:
            abunch.__functions.update(func_dict)
        except KeyError as e:
            abunch.__functions = func_dict
    return abunch


Instruction:
How would you implement a function in Python 3 that
reads idf file and return bunches

Response:
def idfreader(fname, iddfile, conv=True):
    """read idf file and return bunches"""
    data, commdct, idd_index = readidf.readdatacommdct(fname, iddfile=iddfile)
    if conv:
        convertallfields(data, commdct)
    # fill gaps in idd
    ddtt, dtls = data.dt, data.dtls
    # skiplist = ["TABLE:MULTIVARIABLELOOKUP"]
    nofirstfields = iddgaps.missingkeys_standard(
        commdct, dtls,
        skiplist=["TABLE:MULTIVARIABLELOOKUP"])
    iddgaps.missingkeys_nonstandard(None, commdct, dtls, nofirstfields)
    bunchdt = makebunches(data, commdct)
    return bunchdt, data, commdct, idd_index


Instruction:
Can you implement a function in Python 3 that
reads idf file and return bunches

Response:
def idfreader1(fname, iddfile, theidf, conv=True, commdct=None, block=None):
    """read idf file and return bunches"""
    versiontuple = iddversiontuple(iddfile)
    # import pdb; pdb.set_trace()
    block, data, commdct, idd_index = readidf.readdatacommdct1(
        fname,
        iddfile=iddfile,
        commdct=commdct,
        block=block)
    if conv:
        convertallfields(data, commdct, block)
    # fill gaps in idd
    ddtt, dtls = data.dt, data.dtls
    if versiontuple < (8,):
        skiplist = ["TABLE:MULTIVARIABLELOOKUP"]
    else:
        skiplist = None
    nofirstfields = iddgaps.missingkeys_standard(
        commdct, dtls,
        skiplist=skiplist)
    iddgaps.missingkeys_nonstandard(block, commdct, dtls, nofirstfields)
    # bunchdt = makebunches(data, commdct)
    bunchdt = makebunches_alter(data, commdct, theidf)
    return bunchdt, block, data, commdct, idd_index, versiontuple


Instruction:
Can you tell what is the following Python 3 function doing
def getanymentions(idf, anidfobject):
    name = anidfobject.obj[1]
    foundobjs = []
    keys = idfobjectkeys(idf)
    idfkeyobjects = [idf.idfobjects[key.upper()] for key in keys]
    for idfobjects in idfkeyobjects:
        for idfobject in idfobjects:
            if name.upper() in [item.upper()
                                    for item in idfobject.obj
                                        if isinstance(item, basestring)]:
                foundobjs.append(idfobject)
    return foundobjs

Response: Find out if idjobject is mentioned an any object anywhere


Instruction:
Create a Python 3 function for
returning the object that has the given fieldname.

Response:
def getobject_use_prevfield(idf, idfobject, fieldname):
    """field=object_name, prev_field=object_type. Return the object"""
    if not fieldname.endswith("Name"):
        return None
    # test if prevfieldname ends with "Object_Type"
    fdnames = idfobject.fieldnames
    ifieldname = fdnames.index(fieldname)
    prevfdname = fdnames[ifieldname - 1]
    if not prevfdname.endswith("Object_Type"):
        return None
    objkey = idfobject[prevfdname].upper()
    objname = idfobject[fieldname]
    try:
        foundobj = idf.getobject(objkey, objname)
    except KeyError as e:
        return None
    return foundobj


Instruction:
Make a summary of the following Python 3 code
def getidfkeyswithnodes():
    idf = IDF(StringIO(""))
    keys = idfobjectkeys(idf)
    keysfieldnames = ((key, idf.newidfobject(key.upper()).fieldnames)
                for key in keys)
    keysnodefdnames = ((key,  (name for name in fdnames
                                if (name.endswith('Node_Name'))))
                            for key, fdnames in keysfieldnames)
    nodekeys = [key for key, fdnames in keysnodefdnames if list(fdnames)]
    return nodekeys

Response: return a list of keys of idfobjects that have None Name fields


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getobjectswithnode(idf, nodekeys, nodename):
    keys = nodekeys
    # TODO getidfkeyswithnodes needs to be done only once. take out of here
    listofidfobjects = (idf.idfobjects[key.upper()]
                for key in keys if idf.idfobjects[key.upper()])
    idfobjects = [idfobj
                    for idfobjs in listofidfobjects
                        for idfobj in idfobjs]
    objwithnodes = []
    for obj in idfobjects:
        values = obj.fieldvalues
        fdnames = obj.fieldnames
        for value, fdname in zip(values, fdnames):
            if fdname.endswith('Node_Name'):
                if value == nodename:
                    objwithnodes.append(obj)
                    break
    return objwithnodes

Response: return all objects that mention this node name


Instruction:
Implement a Python 3 function for
returning the object if the Name or some other field is known.

Response:
def name2idfobject(idf, groupnamess=None, objkeys=None, **kwargs):
    """return the object, if the Name or some other field is known.
    send filed in **kwargs as Name='a name', Roughness='smooth'
    Returns the first find (field search is unordered)
    objkeys -> if objkeys=['ZONE', 'Material'], search only those
    groupnames -> not yet coded"""
    # TODO : this is a very slow search. revist to speed it up.
    if not objkeys:
        objkeys = idfobjectkeys(idf)
    for objkey in objkeys:
        idfobjs = idf.idfobjects[objkey.upper()]
        for idfobj in idfobjs:
            for key, val in kwargs.items():
                try:
                    if idfobj[key] == val:
                        return idfobj
                except BadEPFieldError as e:
                    continue


Instruction:
Write a Python 3 function that can
return a list of all idfobjects in idf

Response:
def getidfobjectlist(idf):
    """return a list of all idfobjects in idf"""
    idfobjects = idf.idfobjects
    # idfobjlst = [idfobjects[key] for key in idfobjects if idfobjects[key]]
    idfobjlst = [idfobjects[key] for key in idf.model.dtls if idfobjects[key]]
        # `for key in idf.model.dtls` maintains the order
        # `for key in idfobjects` does not have order
    idfobjlst = itertools.chain.from_iterable(idfobjlst)
    idfobjlst = list(idfobjlst)
    return idfobjlst


Instruction:
How would you implement a function in Python 3 that
copies fromidf completely into toidf

Response:
def copyidfintoidf(toidf, fromidf):
    """copy fromidf completely into toidf"""
    idfobjlst = getidfobjectlist(fromidf)
    for idfobj in idfobjlst:
        toidf.copyidfobject(idfobj)


Instruction:
Can you generate the documentation for the following Python 3 function
def idfdiffs(idf1, idf2):
    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 itertools.zip_longest(n_idfobjs1,
                                                          n_idfobjs2):
                if idfobj1 == None:
                    thediffs[(idfobj2.key.upper(),
                                getobjname(idfobj2))] = (None, idf1.idfname) #(idf1.idfname, None)
                    break
                if idfobj2 == None:
                    thediffs[(idfobj1.key.upper(),
                                getobjname(idfobj1))] = (idf2.idfname, None) # (None, idf2.idfname)
                    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

Response: return the diffs between two idfs


Instruction:
How would you code a function in Python 3 to
return autsizeable field names in idfobject

Response:
def autosize_fieldname(idfobject):
    """return autsizeable field names in idfobject"""
    # undocumented stuff in this code
    return [fname for (fname, dct) in zip(idfobject.objls,
                                          idfobject['objidd'])
            if 'autosizable' in dct]


Instruction:
How would you explain what the following Python 3 function does
def iddtxt2groups(txt):
    try:
        txt = txt.decode('ISO-8859-2')
    except AttributeError as e:
        pass # for python 3
    txt = nocomment(txt, '!')
    txt = txt.replace("\\group", "!-group") # retains group in next line
    txt = nocomment(txt, '\\') # remove all other idd info
    lines = txt.splitlines()
    lines = [line.strip() for line in lines] # cleanup
    lines = [line for line in lines if line != ''] # cleanup
    txt = '\n'.join(lines)
    gsplits = txt.split('!') # split into groups, since we have !-group
    gsplits = [gsplit.splitlines() for gsplit in gsplits] # split group

    gsplits[0].insert(0, None)
        # Put None for the first group that does nothave a group name
    gdict = {}
    for gsplit in gsplits:
        gdict.update({gsplit[0]:gsplit[1:]})
        # makes dict {groupname:[k1, k2], groupname2:[k3, k4]}

    gdict = {k:'\n'.join(v) for k, v in gdict.items()}# joins lines back
    gdict = {k:v.split(';') for k, v in gdict.items()} # splits into idfobjects
    gdict = {k:[i.strip() for i in v] for k, v in gdict.items()} # cleanup
    gdict = {k:[i.splitlines() for i in v] for k, v in gdict.items()}
        # splits idfobjects into lines
    gdict = {k:[i for i in v if len(i) > 0] for k, v in gdict.items()}
        # cleanup - removes blank lines
    gdict = {k:[i[0] for i in v] for k, v in gdict.items()} # use first line
    gdict = {k:[i.split(',')[0] for i in v] for k, v in gdict.items()}
        # remove ','
    nvalue = gdict.pop(None) # remove group with no name
    gdict = {k[len('-group '):]:v for k, v in gdict.items()} # get group name
    gdict.update({None:nvalue}) # put back group with no name
    return gdict

Response: extract the groups from the idd file


Instruction:
Create a Python 3 function for
returning a list of group names the list in the same order as the idf objects in idd file

Response:
def iddtxt2grouplist(txt):
    """return a list of group names
    the list in the same order as the idf objects in idd file
    """
    def makenone(astr):
        if astr == 'None':
            return None
        else:
            return astr

    txt = nocomment(txt, '!')
    txt = txt.replace("\\group", "!-group") # retains group in next line
    txt = nocomment(txt, '\\') # remove all other idd info
    lines = txt.splitlines()
    lines = [line.strip() for line in lines] # cleanup
    lines = [line for line in lines if line != ''] # cleanup
    txt = '\n'.join(lines)
    gsplits = txt.split('!') # split into groups, since we have !-group
    gsplits = [gsplit.splitlines() for gsplit in gsplits] # split group

    gsplits[0].insert(0, u'-group None')
        # Put None for the first group that does nothave a group name

    glist = []
    for gsplit in gsplits:
        glist.append((gsplit[0], gsplit[1:]))
        # makes dict {groupname:[k1, k2], groupname2:[k3, k4]}

    glist = [(k, '\n'.join(v)) for k, v in glist]# joins lines back
    glist = [(k, v.split(';')) for k, v in glist] # splits into idfobjects
    glist = [(k, [i.strip() for i in v]) for k, v in glist] # cleanup
    glist = [(k, [i.splitlines() for i in v]) for k, v in glist]
        # splits idfobjects into lines
    glist = [(k, [i for i in v if len(i) > 0]) for k, v in glist]
        # cleanup - removes blank lines
    glist = [(k, [i[0] for i in v]) for k, v in glist] # use first line
    fglist = []
    for gnamelist in glist:
        gname = gnamelist[0]
        thelist = gnamelist[-1]
        for item in thelist:
            fglist.append((gname, item))
    glist = [(gname[len("-group "):], obj) for gname, obj in fglist] # remove "-group "
    glist = [(makenone(gname), obj) for gname, obj in glist] # make str None into None
    glist = [(gname, obj.split(',')[0]) for gname, obj in glist] # remove comma
    return glist


Instruction:
Implement a function in Python 3 to
add group info to commlst

Response:
def group2commlst(commlst, glist):
    """add group info to commlst"""
    for (gname, objname), commitem in zip(glist, commlst):
        newitem1 = "group %s" % (gname, )
        newitem2 = "idfobj %s" % (objname, )
        commitem[0].insert(0, newitem1)
        commitem[0].insert(1, newitem2)
    return commlst


Instruction:
Can you tell what is the following Python 3 function doing
def group2commdct(commdct, glist):
    for (gname, objname), commitem in zip(glist, commdct):
        commitem[0]['group'] = gname
        commitem[0]['idfobj'] = objname
    return commdct

Response: add group info to commct


Instruction:
Create a Python 3 function to
extract embedded group data from commdct. return gdict - > list of objects

Response:
def commdct2grouplist(gcommdct):
    """extract embedded group data from commdct.
    return gdict -> {g1:[obj1, obj2, obj3], g2:[obj4, ..]}"""
    gdict = {}
    for objidd in gcommdct:
        group = objidd[0]['group']
        objname = objidd[0]['idfobj']
        if group in gdict:
            gdict[group].append(objname)
        else:
            gdict[group] = [objname, ]
    return gdict


Instruction:
Can you tell what is the following Python 3 function doing
def flattencopy(lst):
    # modified from
    # http://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists-in-python
    thelist = copy.deepcopy(lst)
    list_is_nested = True
    while list_is_nested:  # outer loop
        keepchecking = False
        atemp = []
        for element in thelist:  # inner loop
            if isinstance(element, list):
                atemp.extend(element)
                keepchecking = True
            else:
                atemp.append(element)
        list_is_nested = keepchecking  # determine if outer loop exits
        thelist = atemp[:]
    return thelist

Response:
flatten and return a copy of the list
    indefficient on large lists


Instruction:
Create a Python 3 function to
make a pipe component generate inlet outlet names

Response:
def makepipecomponent(idf, pname):
    """make a pipe component
    generate inlet outlet names"""
    apipe = idf.newidfobject("Pipe:Adiabatic".upper(), Name=pname)
    apipe.Inlet_Node_Name = "%s_inlet" % (pname,)
    apipe.Outlet_Node_Name = "%s_outlet" % (pname,)
    return apipe


Instruction:
Can you create a Python 3 function that
makes a duct component generate inlet outlet names

Response:
def makeductcomponent(idf, dname):
    """make a duct component
    generate inlet outlet names"""
    aduct = idf.newidfobject("duct".upper(), Name=dname)
    aduct.Inlet_Node_Name = "%s_inlet" % (dname,)
    aduct.Outlet_Node_Name = "%s_outlet" % (dname,)
    return aduct


Instruction:
Implement a Python 3 function for
making a branch with a pipe

Response:
def makepipebranch(idf, bname):
    """make a branch with a pipe
    use standard inlet outlet names"""
    # make the pipe component first
    pname = "%s_pipe" % (bname,)
    apipe = makepipecomponent(idf, pname)
    # now make the branch with the pipe in it
    abranch = idf.newidfobject("BRANCH", Name=bname)
    abranch.Component_1_Object_Type = 'Pipe:Adiabatic'
    abranch.Component_1_Name = pname
    abranch.Component_1_Inlet_Node_Name = apipe.Inlet_Node_Name
    abranch.Component_1_Outlet_Node_Name = apipe.Outlet_Node_Name
    abranch.Component_1_Branch_Control_Type = "Bypass"
    return abranch


Instruction:
Can you create a Python 3 function that
makes a branch with a duct use standard inlet outlet names

Response:
def makeductbranch(idf, bname):
    """make a branch with a duct
    use standard inlet outlet names"""
    # make the duct component first
    pname = "%s_duct" % (bname,)
    aduct = makeductcomponent(idf, pname)
    # now make the branch with the duct in it
    abranch = idf.newidfobject("BRANCH", Name=bname)
    abranch.Component_1_Object_Type = 'duct'
    abranch.Component_1_Name = pname
    abranch.Component_1_Inlet_Node_Name = aduct.Inlet_Node_Name
    abranch.Component_1_Outlet_Node_Name = aduct.Outlet_Node_Name
    abranch.Component_1_Branch_Control_Type = "Bypass"
    return abranch


Instruction:
Create a Python 3 function for
getting the components of the branch

Response:
def getbranchcomponents(idf, branch, utest=False):
    """get the components of the branch"""
    fobjtype = 'Component_%s_Object_Type'
    fobjname = 'Component_%s_Name'
    complist = []
    for i in range(1, 100000):
        try:
            objtype = branch[fobjtype % (i,)]
            if objtype.strip() == '':
                break
            objname = branch[fobjname % (i,)]
            complist.append((objtype, objname))
        except bunch_subclass.BadEPFieldError:
            break
    if utest:
        return complist
    else:
        return [idf.getobject(ot, on) for ot, on in complist]


Instruction:
How would you code a function in Python 3 to
rename all the changed nodes

Response:
def renamenodes(idf, fieldtype):
    """rename all the changed nodes"""
    renameds = []
    for key in idf.model.dtls:
        for idfobject in idf.idfobjects[key]:
            for fieldvalue in idfobject.obj:
                if type(fieldvalue) is list:
                    if fieldvalue not in renameds:
                        cpvalue = copy.copy(fieldvalue)
                        renameds.append(cpvalue)

    # do the renaming
    for key in idf.model.dtls:
        for idfobject in idf.idfobjects[key]:
            for i, fieldvalue in enumerate(idfobject.obj):
                itsidd = idfobject.objidd[i]
                if 'type' in itsidd:
                    if itsidd['type'][0] == fieldtype:
                        tempdct = dict(renameds)
                        if type(fieldvalue) is list:
                            fieldvalue = fieldvalue[-1]
                            idfobject.obj[i] = fieldvalue
                        else:
                            if fieldvalue in tempdct:
                                fieldvalue = tempdct[fieldvalue]
                                idfobject.obj[i] = fieldvalue


Instruction:
How would you explain what the following Python 3 function does
def getfieldnamesendswith(idfobject, endswith):
    objls = idfobject.objls
    tmp = [name for name in objls if name.endswith(endswith)]
    if tmp == []:
        pass
    return [name for name in objls if name.endswith(endswith)]

Response: get the filednames for the idfobject based on endswith


Instruction:
Implement a function in Python 3 to
return the field name of the node fluid is only needed if there are air and water nodes

Response:
def getnodefieldname(idfobject, endswith, fluid=None, startswith=None):
    """return the field name of the node
    fluid is only needed if there are air and water nodes
    fluid is Air or Water or ''.
    if the fluid is Steam, use Water"""
    if startswith is None:
        startswith = ''
    if fluid is None:
        fluid = ''
    nodenames = getfieldnamesendswith(idfobject, endswith)
    nodenames = [name for name in nodenames if name.startswith(startswith)]
    fnodenames = [nd for nd in nodenames if nd.find(fluid) != -1]
    fnodenames = [name for name in fnodenames if name.startswith(startswith)]
    if len(fnodenames) == 0:
        nodename = nodenames[0]
    else:
        nodename = fnodenames[0]
    return nodename


Instruction:
Can you create a Python 3 function that
renames nodes so that the components get connected fluid is only needed if there are air and water nodes fluid is Steam or Air

Response:
def connectcomponents(idf, components, fluid=None):
    """rename nodes so that the components get connected
    fluid is only needed if there are air and water nodes
    fluid is Air or Water or ''.
    if the fluid is Steam, use Water"""
    if fluid is None:
        fluid = ''
    if len(components) == 1:
        thiscomp, thiscompnode = components[0]
        initinletoutlet(idf, thiscomp, thiscompnode, force=False)
        outletnodename = getnodefieldname(thiscomp, "Outlet_Node_Name",
                                          fluid=fluid, startswith=thiscompnode)
        thiscomp[outletnodename] = [thiscomp[outletnodename],
                                    thiscomp[outletnodename]]
        # inletnodename = getnodefieldname(nextcomp, "Inlet_Node_Name", fluid)
        # nextcomp[inletnodename] = [nextcomp[inletnodename], betweennodename]
        return components
    for i in range(len(components) - 1):
        thiscomp, thiscompnode = components[i]
        nextcomp, nextcompnode = components[i + 1]
        initinletoutlet(idf, thiscomp, thiscompnode, force=False)
        initinletoutlet(idf, nextcomp, nextcompnode, force=False)
        betweennodename = "%s_%s_node" % (thiscomp.Name, nextcomp.Name)
        outletnodename = getnodefieldname(thiscomp, "Outlet_Node_Name",
                                          fluid=fluid, startswith=thiscompnode)
        thiscomp[outletnodename] = [thiscomp[outletnodename], betweennodename]
        inletnodename = getnodefieldname(nextcomp, "Inlet_Node_Name", fluid)
        nextcomp[inletnodename] = [nextcomp[inletnodename], betweennodename]
    return components


Instruction:
Can you generate a brief explanation for the following Python 3 code
def initinletoutlet(idf, idfobject, thisnode, force=False):
    def blankfield(fieldvalue):
        """test for blank field"""
        try:
            if fieldvalue.strip() == '':
                return True
            else:
                return False
        except AttributeError:  # field may be a list
            return False
    def trimfields(fields, thisnode):
        if len(fields) > 1:
            if thisnode is not None:
                fields = [field for field in fields
                          if field.startswith(thisnode)]
                return fields
            else:
                print("Where should this loop connect ?")
                print("%s - %s" % (idfobject.key, idfobject.Name))
                print([field.split("Inlet_Node_Name")[0]
                       for field in inletfields])
                raise WhichLoopError
        else:
            return fields

    inletfields = getfieldnamesendswith(idfobject, "Inlet_Node_Name")
    inletfields = trimfields(inletfields, thisnode)  # or warn with exception
    for inletfield in inletfields:
        if blankfield(idfobject[inletfield]) == True or force == True:
            idfobject[inletfield] = "%s_%s" % (idfobject.Name, inletfield)
    outletfields = getfieldnamesendswith(idfobject, "Outlet_Node_Name")
    outletfields = trimfields(outletfields, thisnode)  # or warn with exception
    for outletfield in outletfields:
        if blankfield(idfobject[outletfield]) == True or force == True:
            idfobject[outletfield] = "%s_%s" % (idfobject.Name, outletfield)
    return idfobject

Response: initialze values for all the inlet and outlet nodes for the object.


Instruction:
Explain what the following Python 3 code does
def componentsintobranch(idf, branch, listofcomponents, fluid=None):
    if fluid is None:
        fluid = ''
    componentlist = [item[0] for item in listofcomponents]
    # assumes that the nodes of the component connect to each other
    # empty branch if it has existing components
    thebranchname = branch.Name
    thebranch = idf.removeextensibles('BRANCH', thebranchname)  # empty the branch
    # fill in the new components with the node names into this branch
        # find the first extensible field and fill in the data in obj.
    e_index = idf.getextensibleindex('BRANCH', thebranchname)
    theobj = thebranch.obj
    modeleditor.extendlist(theobj, e_index)  # just being careful here
    for comp, compnode in listofcomponents:
        theobj.append(comp.key)
        theobj.append(comp.Name)
        inletnodename = getnodefieldname(comp, "Inlet_Node_Name", fluid=fluid,
                                         startswith=compnode)
        theobj.append(comp[inletnodename])
        outletnodename = getnodefieldname(comp, "Outlet_Node_Name",
                                          fluid=fluid, startswith=compnode)
        theobj.append(comp[outletnodename])
        theobj.append('')

    return thebranch

Response: insert a list of components into a branch


Instruction:
Can you implement a function in Python 3 that
makes plant loop with pip components

Response:
def makeplantloop(idf, loopname, sloop, dloop, testing=None):
    """make plant loop with pip components"""
    # -------- <testing ---------
    testn = 0
    # -------- testing> ---------
    newplantloop = idf.newidfobject("PLANTLOOP", Name=loopname)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    fields = SomeFields.p_fields

    # for use in bunch
    flnames = [field.replace(' ', '_') for field in fields]

    # simplify naming
    fields1 = [field.replace('Plant Side', 'Supply') for field in fields]
    fields1 = [field.replace('Demand Side', 'Demand') for field in fields1]
    fields1 = [field[:field.find('Name') - 1] for field in fields1]
    fields1 = [field.replace(' Node', '') for field in fields1]
    fields1 = [field.replace(' List', 's') for field in fields1]

    # TODO : pop connectors if no parallel branches
    # make fieldnames in the plant loop
    fieldnames = ['%s %s' % (loopname, field) for field in fields1]
    for fieldname, thefield in zip(fieldnames, flnames):
        newplantloop[thefield] = fieldname
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # make the branch lists for this plant loop
    sbranchlist = idf.newidfobject(
        "BRANCHLIST",
        Name=newplantloop.Plant_Side_Branch_List_Name)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    dbranchlist = idf.newidfobject(
        "BRANCHLIST",
        Name=newplantloop.Demand_Side_Branch_List_Name)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # add branch names to the branchlist
    sbranchnames = flattencopy(sloop)
    # sbranchnames = sloop[1]
    for branchname in sbranchnames:
        sbranchlist.obj.append(branchname)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    dbranchnames = flattencopy(dloop)
    # dbranchnames = dloop[1]
    for branchname in dbranchnames:
        dbranchlist.obj.append(branchname)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # make a pipe branch for all branches in the loop

    # supply side
    sbranchs = []
    for bname in sbranchnames:
        branch = makepipebranch(idf, bname)
        sbranchs.append(branch)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop
    anode = "Component_1_Inlet_Node_Name"
    sameinnode = "Plant_Side_Inlet_Node_Name"
    sbranchs[0][anode] = newplantloop[sameinnode]
    anode = "Component_1_Outlet_Node_Name"
    sameoutnode = "Plant_Side_Outlet_Node_Name"
    sbranchs[-1][anode] = newplantloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop - rename in pipe
    pname = sbranchs[0]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Inlet_Node_Name = newplantloop[sameinnode]
    pname = sbranchs[-1]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Outlet_Node_Name = newplantloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # demand side
    dbranchs = []
    for bname in dbranchnames:
        branch = makepipebranch(idf, bname)
        dbranchs.append(branch)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop - rename in branch
    anode = "Component_1_Inlet_Node_Name"
    sameinnode = "Demand_Side_Inlet_Node_Name"
    dbranchs[0][anode] = newplantloop[sameinnode]
    anode = "Component_1_Outlet_Node_Name"
    sameoutnode = "Demand_Side_Outlet_Node_Name"
    dbranchs[-1][anode] = newplantloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop - rename in pipe
    pname = dbranchs[0]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Inlet_Node_Name = newplantloop[sameinnode]
    pname = dbranchs[-1]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Outlet_Node_Name = newplantloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # TODO : test if there are parallel branches
    # make the connectorlist an fill fields
    sconnlist = idf.newidfobject(
        "CONNECTORLIST",
        Name=newplantloop.Plant_Side_Connector_List_Name)
    sconnlist.Connector_1_Object_Type = "Connector:Splitter"
    sconnlist.Connector_1_Name = "%s_supply_splitter" % (loopname,)
    sconnlist.Connector_2_Object_Type = "Connector:Mixer"
    sconnlist.Connector_2_Name = "%s_supply_mixer" % (loopname,)
    dconnlist = idf.newidfobject(
        "CONNECTORLIST",
        Name=newplantloop.Demand_Side_Connector_List_Name)
    dconnlist.Connector_1_Object_Type = "Connector:Splitter"
    dconnlist.Connector_1_Name = "%s_demand_splitter" % (loopname,)
    dconnlist.Connector_2_Object_Type = "Connector:Mixer"
    dconnlist.Connector_2_Name = "%s_demand_mixer" % (loopname,)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # make splitters and mixers
    s_splitter = idf.newidfobject(
        "CONNECTOR:SPLITTER",
        Name=sconnlist.Connector_1_Name)
    s_splitter.obj.extend([sloop[0]] + sloop[1])
    s_mixer = idf.newidfobject(
        "CONNECTOR:MIXER",
        Name=sconnlist.Connector_2_Name)
    s_mixer.obj.extend([sloop[-1]] + sloop[1])
    # -
    d_splitter = idf.newidfobject(
        "CONNECTOR:SPLITTER",
        Name=dconnlist.Connector_1_Name)
    d_splitter.obj.extend([dloop[0]] + dloop[1])
    d_mixer = idf.newidfobject(
        "CONNECTOR:MIXER",
        Name=dconnlist.Connector_2_Name)
    d_mixer.obj.extend([dloop[-1]] + dloop[1])
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newplantloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    return newplantloop


Instruction:
Implement a function in Python 3 to
make condenser loop with pipe components

Response:
def makecondenserloop(idf, loopname, sloop, dloop, testing=None):
    """make condenser loop with pipe components"""
    # -------- <testing ---------
    testn = 0
    # -------- testing> ---------
    newcondenserloop = idf.newidfobject("CondenserLoop".upper(), Name=loopname)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    fields = SomeFields.c_fields

    # for use in bunch
    flnames = [field.replace(' ', '_') for field in fields]

    # simplify naming
    fields1 = [field.replace(
        'Condenser Side',
        'Cond_Supply') for field in fields]
    fields1 = [field.replace('Demand Side', 'Demand') for field in fields1]
    fields1 = [field[:field.find('Name') - 1] for field in fields1]
    fields1 = [field.replace(' Node', '') for field in fields1]
    fields1 = [field.replace(' List', 's') for field in fields1]

    # old TODO : pop connectors if no parallel branches
    # make fieldnames in the condenser loop
    fieldnames = ['%s %s' % (loopname, field) for field in fields1]
    for fieldname, thefield in zip(fieldnames, flnames):
        newcondenserloop[thefield] = fieldname
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # make the branch lists for this condenser loop
    sbranchlist = idf.newidfobject(
        "BRANCHLIST",
        Name=newcondenserloop.Condenser_Side_Branch_List_Name)
    dbranchlist = idf.newidfobject(
        "BRANCHLIST",
        Name=newcondenserloop.Condenser_Demand_Side_Branch_List_Name)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # add branch names to the branchlist
    sbranchnames = flattencopy(sloop)
    # sbranchnames = sloop[1]
    for branchname in sbranchnames:
        sbranchlist.obj.append(branchname)
    dbranchnames = flattencopy(dloop)
    # dbranchnames = dloop[1]
    for branchname in dbranchnames:
        dbranchlist.obj.append(branchname)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # make a pipe branch for all branches in the loop

    # supply side
    sbranchs = []
    for bname in sbranchnames:
        branch = makepipebranch(idf, bname)
        sbranchs.append(branch)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop
    anode = "Component_1_Inlet_Node_Name"
    sameinnode = "Condenser_Side_Inlet_Node_Name"  # TODO : change ?
    sbranchs[0][anode] = newcondenserloop[sameinnode]
    anode = "Component_1_Outlet_Node_Name"
    sameoutnode = "Condenser_Side_Outlet_Node_Name"  # TODO : change ?
    sbranchs[-1][anode] = newcondenserloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop - rename in pipe
    pname = sbranchs[0]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Inlet_Node_Name = newcondenserloop[sameinnode]
    pname = sbranchs[-1]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Outlet_Node_Name = newcondenserloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # demand side
    dbranchs = []
    for bname in dbranchnames:
        branch = makepipebranch(idf, bname)
        dbranchs.append(branch)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop - rename in branch
    anode = "Component_1_Inlet_Node_Name"
    sameinnode = "Demand_Side_Inlet_Node_Name"  # TODO : change ?
    dbranchs[0][anode] = newcondenserloop[sameinnode]
    anode = "Component_1_Outlet_Node_Name"
    sameoutnode = "Demand_Side_Outlet_Node_Name"  # TODO : change ?
    dbranchs[-1][anode] = newcondenserloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # rename inlet outlet of endpoints of loop - rename in pipe
    pname = dbranchs[0]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Inlet_Node_Name = newcondenserloop[sameinnode]
    pname = dbranchs[-1]['Component_1_Name']  # get the pipe name
    apipe = idf.getobject('Pipe:Adiabatic'.upper(), pname)  # get pipe
    apipe.Outlet_Node_Name = newcondenserloop[sameoutnode]
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # TODO : test if there are parallel branches
    # make the connectorlist an fill fields
    sconnlist = idf.newidfobject(
        "CONNECTORLIST",
        Name=newcondenserloop.Condenser_Side_Connector_List_Name)
    sconnlist.Connector_1_Object_Type = "Connector:Splitter"
    sconnlist.Connector_1_Name = "%s_supply_splitter" % (loopname,)
    sconnlist.Connector_2_Object_Type = "Connector:Mixer"
    sconnlist.Connector_2_Name = "%s_supply_mixer" % (loopname,)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    dconnlist = idf.newidfobject(
        "CONNECTORLIST",
        Name=newcondenserloop.Condenser_Demand_Side_Connector_List_Name)
    dconnlist.Connector_1_Object_Type = "Connector:Splitter"
    dconnlist.Connector_1_Name = "%s_demand_splitter" % (loopname,)
    dconnlist.Connector_2_Object_Type = "Connector:Mixer"
    dconnlist.Connector_2_Name = "%s_demand_mixer" % (loopname,)
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------

    # make splitters and mixers
    s_splitter = idf.newidfobject(
        "CONNECTOR:SPLITTER",
        Name=sconnlist.Connector_1_Name)
    s_splitter.obj.extend([sloop[0]] + sloop[1])
    s_mixer = idf.newidfobject(
        "CONNECTOR:MIXER",
        Name=sconnlist.Connector_2_Name)
    s_mixer.obj.extend([sloop[-1]] + sloop[1])
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    # -
    d_splitter = idf.newidfobject(
        "CONNECTOR:SPLITTER",
        Name=dconnlist.Connector_1_Name)
    d_splitter.obj.extend([dloop[0]] + dloop[1])
    d_mixer = idf.newidfobject(
        "CONNECTOR:MIXER",
        Name=dconnlist.Connector_2_Name)
    d_mixer.obj.extend([dloop[-1]] + dloop[1])
    # -------- <testing ---------
    testn = doingtesting(testing, testn, newcondenserloop)
    if testn == None:
        returnnone()
    # -------- testing> ---------
    return newcondenserloop


Instruction:
How would you implement a function in Python 3 that
forces it to be a list of tuples

Response:
def _clean_listofcomponents(listofcomponents):
    """force it to be a list of tuples"""
    def totuple(item):
        """return a tuple"""
        if isinstance(item, (tuple, list)):
            return item
        else:
            return (item, None)
    return [totuple(item) for item in listofcomponents]


Instruction:
Write a Python 3 script for
cleaning up list of 3 - tuples

Response:
def _clean_listofcomponents_tuples(listofcomponents_tuples):
    """force 3 items in the tuple"""
    def to3tuple(item):
        """return a 3 item tuple"""
        if len(item) == 3:
            return item
        else:
            return (item[0], item[1], None)
    return [to3tuple(item) for item in listofcomponents_tuples]


Instruction:
Can you tell what is the following Python 3 function doing
def getmakeidfobject(idf, key, name):
    idfobject = idf.getobject(key, name)
    if not idfobject:
        return idf.newidfobject(key, Name=name)
    else:
        return idfobject

Response: get idfobject or make it if it does not exist


Instruction:
Can you generate the documentation for the following Python 3 function
def replacebranch1(idf, loop, branchname, listofcomponents_tuples, fluid=None,
                   debugsave=False):
    """do I even use this ? .... yup! I do"""
    if fluid is None:
        fluid = ''
    listofcomponents_tuples = _clean_listofcomponents_tuples(listofcomponents_tuples)
    branch = idf.getobject('BRANCH', branchname)  # args are (key, name)
    listofcomponents = []
    for comp_type, comp_name, compnode in listofcomponents_tuples:
        comp = getmakeidfobject(idf, comp_type.upper(), comp_name)
        listofcomponents.append((comp, compnode))
    newbr = replacebranch(idf, loop, branch, listofcomponents,
                          debugsave=debugsave, fluid=fluid)
    return newbr

Response: replace branch1 with new branch1


Instruction:
Can you generate the documentation for the following Python 3 function
def replacebranch(idf, loop, branch,
                  listofcomponents, fluid=None,
                  debugsave=False,
                  testing=None):
    """It will replace the components in the branch with components in
    listofcomponents"""
    if fluid is None:
        fluid = ''
    # -------- testing ---------
    testn = 0
    # -------- testing ---------

    # join them into a branch
    # -----------------------
    # np1_inlet -> np1 -> np1_np2_node -> np2 -> np2_outlet
        # change the node names in the component
        # empty the old branch
        # fill in the new components with the node names into this branch
    listofcomponents = _clean_listofcomponents(listofcomponents)

    components = [item[0] for item in listofcomponents]
    connectcomponents(idf, listofcomponents, fluid=fluid)
    if debugsave:
        idf.savecopy("hhh3.idf")
    # -------- testing ---------
    testn = doingtesting(testing, testn)
    if testn == None:
        returnnone()
    # -------- testing ---------
    fields = SomeFields.a_fields

    thebranch = branch
    componentsintobranch(idf, thebranch, listofcomponents, fluid=fluid)
    if debugsave:
        idf.savecopy("hhh4.idf")
    # -------- testing ---------
    testn = doingtesting(testing, testn)
    if testn == None:
        returnnone()
    # -------- testing ---------

    # # gather all renamed nodes
    # # do the renaming
    renamenodes(idf, 'node')
    if debugsave:
        idf.savecopy("hhh7.idf")
    # -------- testing ---------
    testn = doingtesting(testing, testn)
    if testn == None:
        returnnone()
    # -------- testing ---------

    # check for the end nodes of the loop
    if loop.key == 'AIRLOOPHVAC':
        fields = SomeFields.a_fields
    if loop.key == 'PLANTLOOP':
        fields = SomeFields.p_fields
    if loop.key == 'CONDENSERLOOP':
        fields = SomeFields.c_fields
    # for use in bunch
    flnames = [field.replace(' ', '_') for field in fields]

    if fluid.upper() == 'WATER':
        supplyconlistname = loop[flnames[3]]
        # Plant_Side_Connector_List_Name or Condenser_Side_Connector_List_Name
    elif fluid.upper() == 'AIR':
        supplyconlistname = loop[flnames[1]]  # Connector_List_Name'
    supplyconlist = idf.getobject('CONNECTORLIST', supplyconlistname)
    for i in range(1, 100000):  # large range to hit end
        try:
            fieldname = 'Connector_%s_Object_Type' % (i,)
            ctype = supplyconlist[fieldname]
        except bunch_subclass.BadEPFieldError:
            break
        if ctype.strip() == '':
            break
        fieldname = 'Connector_%s_Name' % (i,)
        cname = supplyconlist[fieldname]
        connector = idf.getobject(ctype.upper(), cname)
        if connector.key == 'CONNECTOR:SPLITTER':
            firstbranchname = connector.Inlet_Branch_Name
            cbranchname = firstbranchname
            isfirst = True
        if connector.key == 'CONNECTOR:MIXER':
            lastbranchname = connector.Outlet_Branch_Name
            cbranchname = lastbranchname
            isfirst = False
        if cbranchname == thebranch.Name:
            # rename end nodes
            comps = getbranchcomponents(idf, thebranch)
            if isfirst:
                comp = comps[0]
                inletnodename = getnodefieldname(
                    comp,
                    "Inlet_Node_Name", fluid)
                comp[inletnodename] = [
                    comp[inletnodename],
                    loop[flnames[0]]]  # Plant_Side_Inlet_Node_Name
            else:
                comp = comps[-1]
                outletnodename = getnodefieldname(
                    comp,
                    "Outlet_Node_Name", fluid)
                comp[outletnodename] = [
                    comp[outletnodename],
                    loop[flnames[1]]]  # .Plant_Side_Outlet_Node_Name
    # -------- testing ---------
    testn = doingtesting(testing, testn)
    if testn == None:
        returnnone()
    # -------- testing ---------

    if fluid.upper() == 'WATER':
        demandconlistname = loop[flnames[7]]  # .Demand_Side_Connector_List_Name
        demandconlist = idf.getobject('CONNECTORLIST', demandconlistname)
        for i in range(1, 100000):  # large range to hit end
            try:
                fieldname = 'Connector_%s_Object_Type' % (i,)
                ctype = demandconlist[fieldname]
            except bunch_subclass.BadEPFieldError:
                break
            if ctype.strip() == '':
                break
            fieldname = 'Connector_%s_Name' % (i,)
            cname = demandconlist[fieldname]
            connector = idf.getobject(ctype.upper(), cname)
            if connector.key == 'CONNECTOR:SPLITTER':
                firstbranchname = connector.Inlet_Branch_Name
                cbranchname = firstbranchname
                isfirst = True
            if connector.key == 'CONNECTOR:MIXER':
                lastbranchname = connector.Outlet_Branch_Name
                cbranchname = lastbranchname
                isfirst = False
            if cbranchname == thebranch.Name:
                # rename end nodes
                comps = getbranchcomponents(idf, thebranch)
                if isfirst:
                    comp = comps[0]
                    inletnodename = getnodefieldname(
                        comp,
                        "Inlet_Node_Name", fluid)
                    comp[inletnodename] = [
                        comp[inletnodename],
                        loop[flnames[4]]]  # .Demand_Side_Inlet_Node_Name
                if not isfirst:
                    comp = comps[-1]
                    outletnodename = getnodefieldname(
                        comp,
                        "Outlet_Node_Name", fluid)
                    comp[outletnodename] = [
                        comp[outletnodename],
                        loop[flnames[5]]]  # .Demand_Side_Outlet_Node_Name

    # -------- testing ---------
    testn = doingtesting(testing, testn)
    if testn == None:
        returnnone()
    # -------- testing ---------

    if debugsave:
        idf.savecopy("hhh8.idf")

    # # gather all renamed nodes
    # # do the renaming
    renamenodes(idf, 'node')
    # -------- testing ---------
    testn = doingtesting(testing, testn)
    if testn == None:
        returnnone()
    # -------- testing ---------
    if debugsave:
        idf.savecopy("hhh9.idf")
    return thebranch

Response: This function will replace the components in the branch with the components in listofcomponents.


Instruction:
Here you have a function in Python 3, explain what it does
def area(poly):
    if len(poly) < 3: # not a plane - no area
        return 0
    total = [0, 0, 0]
    num = len(poly)
    for i in range(num):
        vi1 = poly[i]
        vi2 = poly[(i+1) % num]
        prod = np.cross(vi1, vi2)
        total[0] += prod[0]
        total[1] += prod[1]
        total[2] += prod[2]
    if total == [0, 0, 0]:  # points are in a straight line - no area
        return 0
    result = np.dot(total, unit_normal(poly[0], poly[1], poly[2]))
    return abs(result/2)

Response: Area of a polygon poly


Instruction:
Given the following Python 3 function, write the documentation
def unit_normal(pt_a, pt_b, pt_c):
    x_val = np.linalg.det([[1, pt_a[1], pt_a[2]], [1, pt_b[1], pt_b[2]], [1, pt_c[1], pt_c[2]]])
    y_val = np.linalg.det([[pt_a[0], 1, pt_a[2]], [pt_b[0], 1, pt_b[2]], [pt_c[0], 1, pt_c[2]]])
    z_val = np.linalg.det([[pt_a[0], pt_a[1], 1], [pt_b[0], pt_b[1], 1], [pt_c[0], pt_c[1], 1]])
    magnitude = (x_val**2 + y_val**2 + z_val**2)**.5
    mag = (x_val/magnitude, y_val/magnitude, z_val/magnitude)
    if magnitude < 0.00000001:
        mag = (0, 0, 0)
    return mag

Response: unit normal vector of plane defined by points pt_a pt_b and pt_c


Instruction:
Can you tell what is the following Python 3 function doing
def width(poly):
    num = len(poly) - 1
    if abs(poly[num][2] - poly[0][2]) < abs(poly[1][2] - poly[0][2]):
        return dist(poly[num], poly[0])
    elif abs(poly[num][2] - poly[0][2]) > abs(poly[1][2] - poly[0][2]):
        return dist(poly[1], poly[0])
    else: return max(dist(poly[num], poly[0]), dist(poly[1], poly[0]))

Response: Width of a polygon poly


Instruction:
How would you explain what the following Python 3 function does
def angle2vecs(vec1, vec2):
    # vector a * vector b = |a|*|b|* cos(angle between vector a and vector b)
    dot = np.dot(vec1, vec2)
    vec1_modulus = np.sqrt(np.multiply(vec1, vec1).sum())
    vec2_modulus = np.sqrt(np.multiply(vec2, vec2).sum())
    if (vec1_modulus * vec2_modulus) == 0:
        cos_angle = 1
    else: cos_angle = dot / (vec1_modulus * vec2_modulus)
    return math.degrees(acos(cos_angle))

Response: angle between two vectors


Instruction:
Create a Python 3 function for
tilting of a polygon poly

Response:
def tilt(poly):
    """Tilt of a polygon poly"""
    num = len(poly) - 1
    vec = unit_normal(poly[0], poly[1], poly[num])
    vec_alt = np.array([vec[0], vec[1], vec[2]])
    vec_z = np.array([0, 0, 1])
    # return (90 - angle2vecs(vec_alt, vec_z)) # update by Santosh
    return angle2vecs(vec_alt, vec_z)


Instruction:
How would you implement a function in Python 3 that
gets all the fields that have the key field

Response:
def getfields(comm):
    """get all the fields that have the key 'field' """
    fields = []
    for field in comm:
        if 'field' in field:
            fields.append(field)
    return fields


Instruction:
Can you generate the documentation for the following Python 3 function
def repeatingfieldsnames(fields):
    fnames = [field['field'][0] for field in fields]
    fnames = [bunchhelpers.onlylegalchar(fname) for fname in fnames]
    fnames = [fname for fname in fnames if bunchhelpers.intinlist(fname.split())]
    fnames = [(bunchhelpers.replaceint(fname), None) for fname in fnames]
    dct = dict(fnames)
    repnames = fnames[:len(list(dct.keys()))]
    return repnames

Response: get the names of the repeating fields


Instruction:
Here you have a function in Python 3, explain what it does
def missingkeys_standard(commdct, dtls, skiplist=None):
    if skiplist == None:
        skiplist = []
    # find objects where all the fields are not named
    gkeys = [dtls[i] for i in range(len(dtls)) if commdct[i].count({}) > 2]
    nofirstfields = []
    # operatie on those fields
    for key_txt in gkeys:
        if key_txt in skiplist:
            continue
        # print key_txt
        # for a function, pass comm as a variable
        key_i = dtls.index(key_txt.upper())
        comm = commdct[key_i]

        # get all fields
        fields = getfields(comm)

        # get repeating field names
        repnames = repeatingfieldsnames(fields)

        try:
            first = repnames[0][0] % (1, )
        except IndexError:
            nofirstfields.append(key_txt)
            continue
        # print first

        # get all comments of the first repeating field names
        firstnames = [repname[0] % (1, ) for repname in repnames]
        fcomments = [field for field in fields
                     if bunchhelpers.onlylegalchar(field['field'][0])
                     in firstnames]
        fcomments = [dict(fcomment) for fcomment in fcomments]
        for cmt in fcomments:
            fld = cmt['field'][0]
            fld = bunchhelpers.onlylegalchar(fld)
            fld = bunchhelpers.replaceint(fld)
            cmt['field'] = [fld]

        for i, cmt in enumerate(comm[1:]):
            thefield = cmt['field'][0]
            thefield = bunchhelpers.onlylegalchar(thefield)
            if thefield == first:
                break
        first_i = i + 1

        newfields = []
        for i in range(1, len(comm[first_i:]) // len(repnames) + 1):
            for fcomment in fcomments:
                nfcomment = dict(fcomment)
                fld = nfcomment['field'][0]
                fld = fld % (i, )
                nfcomment['field'] = [fld]
                newfields.append(nfcomment)

        for i, cmt in enumerate(comm):
            if i < first_i:
                continue
            else:
                afield = newfields.pop(0)
                comm[i] = afield
        commdct[key_i] = comm
    return nofirstfields

Response:
put missing keys in commdct for standard objects
    return a list of keys where it is unable to do so
    commdct is not updated


Instruction:
Given the following Python 3 function, write the documentation
def missingkeys_nonstandard(block, commdct, dtls, objectlist, afield='afiled %s'):
    afield = 'afield %s'
    for key_txt in objectlist:
        key_i = dtls.index(key_txt.upper())
        comm = commdct[key_i]
        if block:
            blk = block[key_i]
        for i, cmt in enumerate(comm):
            if cmt == {}:
                first_i = i
                break
        for i, cmt in enumerate(comm):
            if i >= first_i:
                if block:
                    comm[i]['field'] = ['%s' % (blk[i])]
                else:
                    comm[i]['field'] = [afield % (i - first_i + 1,),]

Response: This function is used to set the field names of the objectlist that are not in the objectlist.


Instruction:
Make a summary of the following Python 3 code
def get_event_loop():
  ev = _state.event_loop
  if not os.getenv(_EVENT_LOOP_KEY) and ev is not None:
    ev.clear()
    _state.event_loop = None
    ev = None
  if ev is None:
    ev = EventLoop()
    _state.event_loop = ev
    os.environ[_EVENT_LOOP_KEY] = '1'
  return ev

Response: Return an EventLoop instance.


Instruction:
Make a summary of the following Python 3 code
def clear(self):
    while self.current or self.idlers or self.queue or self.rpcs:
      current = self.current
      idlers = self.idlers
      queue = self.queue
      rpcs = self.rpcs
      _logging_debug('Clearing stale EventLoop instance...')
      if current:
        _logging_debug('  current = %s', current)
      if idlers:
        _logging_debug('  idlers = %s', idlers)
      if queue:
        _logging_debug('  queue = %s', queue)
      if rpcs:
        _logging_debug('  rpcs = %s', rpcs)
      self.__init__()
      current.clear()
      idlers.clear()
      queue[:] = []
      rpcs.clear()
      _logging_debug('Cleared')

Response: Remove all pending events without running any.


Instruction:
Create a Python 3 function for
inserting event into queue and keep it sorted assuming queue is sorted.

Response:
def insort_event_right(self, event, lo=0, hi=None):
    """Insert event in queue, and keep it sorted assuming queue is sorted.

    If event is already in queue, insert it to the right of the rightmost
    event (to keep FIFO order).

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.

    Args:
      event: a (time in sec since unix epoch, callback, args, kwds) tuple.
    """

    if lo < 0:
      raise ValueError('lo must be non-negative')
    if hi is None:
      hi = len(self.queue)
    while lo < hi:
      mid = (lo + hi) // 2
      if event[0] < self.queue[mid][0]:
        hi = mid
      else:
        lo = mid + 1
    self.queue.insert(lo, event)


Instruction:
How would you code a function in Python 3 to
schedule a function call at a specific time in the future.

Response:
def queue_call(self, delay, callback, *args, **kwds):
    """Schedule a function call at a specific time in the future."""
    if delay is None:
      self.current.append((callback, args, kwds))
      return
    if delay < 1e9:
      when = delay + self.clock.now()
    else:
      # Times over a billion seconds are assumed to be absolute.
      when = delay
    self.insort_event_right((when, callback, args, kwds))


Instruction:
Write a Python 3 script for
scheduling an RPC to be executed on the service.

Response:
def queue_rpc(self, rpc, callback=None, *args, **kwds):
    """Schedule an RPC with an optional callback.

    The caller must have previously sent the call to the service.
    The optional callback is called with the remaining arguments.

    NOTE: If the rpc is a MultiRpc, the callback will be called once
    for each sub-RPC.  TODO: Is this a good idea?
    """
    if rpc is None:
      return
    if rpc.state not in (_RUNNING, _FINISHING):
      raise RuntimeError('rpc must be sent to service before queueing')
    if isinstance(rpc, datastore_rpc.MultiRpc):
      rpcs = rpc.rpcs
      if len(rpcs) > 1:
        # Don't call the callback until all sub-rpcs have completed.
        rpc.__done = False

        def help_multi_rpc_along(r=rpc, c=callback, a=args, k=kwds):
          if r.state == _FINISHING and not r.__done:
            r.__done = True
            c(*a, **k)
            # TODO: And again, what about exceptions?
        callback = help_multi_rpc_along
        args = ()
        kwds = {}
    else:
      rpcs = [rpc]
    for rpc in rpcs:
      self.rpcs[rpc] = (callback, args, kwds)


Instruction:
Write a Python 3 function that can
add an idle callback.

Response:
def add_idle(self, callback, *args, **kwds):
    """Add an idle callback.

    An idle callback can return True, False or None.  These mean:

    - None: remove the callback (don't reschedule)
    - False: the callback did no work; reschedule later
    - True: the callback did some work; reschedule soon

    If the callback raises an exception, the traceback is logged and
    the callback is removed.
    """
    self.idlers.append((callback, args, kwds))


Instruction:
How would you explain what the following Python 3 function does
def run_idle(self):
    if not self.idlers or self.inactive >= len(self.idlers):
      return False
    idler = self.idlers.popleft()
    callback, args, kwds = idler
    _logging_debug('idler: %s', callback.__name__)
    res = callback(*args, **kwds)
    # See add_idle() for the meaning of the callback return value.
    if res is not None:
      if res:
        self.inactive = 0
      else:
        self.inactive += 1
      self.idlers.append(idler)
    else:
      _logging_debug('idler %s removed', callback.__name__)
    return True

Response: Run one of the idle callbacks.


Instruction:
Make a summary of the following Python 3 code
def run0(self):
    if self.current:
      self.inactive = 0
      callback, args, kwds = self.current.popleft()
      _logging_debug('nowevent: %s', callback.__name__)
      callback(*args, **kwds)
      return 0
    if self.run_idle():
      return 0
    delay = None
    if self.queue:
      delay = self.queue[0][0] - self.clock.now()
      if delay <= 0:
        self.inactive = 0
        _, callback, args, kwds = self.queue.pop(0)
        _logging_debug('event: %s', callback.__name__)
        callback(*args, **kwds)
        # TODO: What if it raises an exception?
        return 0
    if self.rpcs:
      self.inactive = 0
      rpc = datastore_rpc.MultiRpc.wait_any(self.rpcs)
      if rpc is not None:
        _logging_debug('rpc: %s.%s', rpc.service, rpc.method)
        # Yes, wait_any() may return None even for a non-empty argument.
        # But no, it won't ever return an RPC not in its argument.
        if rpc not in self.rpcs:
          raise RuntimeError('rpc %r was not given to wait_any as a choice %r' %
                             (rpc, self.rpcs))
        callback, args, kwds = self.rpcs[rpc]
        del self.rpcs[rpc]
        if callback is not None:
          callback(*args, **kwds)
          # TODO: Again, what about exceptions?
      return 0
    return delay

Response: Run one item in a tree.


Instruction:
Can you tell what is the following Python 3 function doing
def run1(self):
    delay = self.run0()
    if delay is None:
      return False
    if delay > 0:
      self.clock.sleep(delay)
    return True

Response: Run one item in the queue.


Instruction:
Given the following Python 3 function, write the documentation
def _get_prop_from_modelclass(modelclass, name):
  if name == '__key__':
    return modelclass._key

  parts = name.split('.')
  part, more = parts[0], parts[1:]
  prop = modelclass._properties.get(part)
  if prop is None:
    if issubclass(modelclass, model.Expando):
      prop = model.GenericProperty(part)
    else:
      raise TypeError('Model %s has no property named %r' %
                      (modelclass._get_kind(), part))

  while more:
    part = more.pop(0)
    if not isinstance(prop, model.StructuredProperty):
      raise TypeError('Model %s has no property named %r' %
                      (modelclass._get_kind(), part))
    maybe = getattr(prop, part, None)
    if isinstance(maybe, model.Property) and maybe._name == part:
      prop = maybe
    else:
      maybe = prop._modelclass._properties.get(part)
      if maybe is not None:
        # Must get it this way to get the copy with the long name.
        # (See StructuredProperty.__getattr__() for details.)
        prop = getattr(prop, maybe._code_name)
      else:
        if issubclass(prop._modelclass, model.Expando) and not more:
          prop = model.GenericProperty()
          prop._name = name  # Bypass the restriction on dots.
        else:
          raise KeyError('Model %s has no property named %r' %
                         (prop._modelclass._get_kind(), part))

  return prop

Response: Helper function for parsing a property name into a property object.


Instruction:
Write a Python 3 function that can
parse a GQL query string.

Response:
def gql(query_string, *args, **kwds):
  """Parse a GQL query string.

  Args:
    query_string: Full GQL query, e.g. 'SELECT * FROM Kind WHERE prop = 1'.
    *args, **kwds: If present, used to call bind().

  Returns:
    An instance of query_class.
  """
  qry = _gql(query_string)
  if args or kwds:
    qry = qry._bind(args, kwds)
  return qry


Instruction:
Write a Python 3 function for
parsing a GQL query string and return an instance of query_class.

Response:
def _gql(query_string, query_class=Query):
  """Parse a GQL query string (internal version).

  Args:
    query_string: Full GQL query, e.g. 'SELECT * FROM Kind WHERE prop = 1'.
    query_class: Optional class to use, default Query.

  Returns:
    An instance of query_class.
  """
  from .google_imports import gql  # Late import, to avoid name conflict.
  gql_qry = gql.GQL(query_string)
  kind = gql_qry.kind()
  if kind is None:
    # The query must be lacking a "FROM <kind>" class.  Let Expando
    # stand in for the model class (it won't actually be used to
    # construct the results).
    modelclass = model.Expando
  else:
    modelclass = model.Model._lookup_model(
        kind,
        tasklets.get_context()._conn.adapter.default_model)
    # Adjust kind to the kind of the model class.
    kind = modelclass._get_kind()
  ancestor = None
  flt = gql_qry.filters()
  filters = list(modelclass._default_filters())
  for name_op in sorted(flt):
    name, op = name_op
    values = flt[name_op]
    op = op.lower()
    if op == 'is' and name == gql.GQL._GQL__ANCESTOR:
      if len(values) != 1:
        raise ValueError('"is" requires exactly one value')
      [(func, args)] = values
      ancestor = _args_to_val(func, args)
      continue
    if op not in _OPS:
      raise NotImplementedError('Operation %r is not supported.' % op)
    for (func, args) in values:
      val = _args_to_val(func, args)
      prop = _get_prop_from_modelclass(modelclass, name)
      if prop._name != name:
        raise RuntimeError('Whoa! _get_prop_from_modelclass(%s, %r) '
                           'returned a property whose name is %r?!' %
                           (modelclass.__name__, name, prop._name))
      if isinstance(val, ParameterizedThing):
        node = ParameterNode(prop, op, val)
      elif op == 'in':
        node = prop._IN(val)
      else:
        node = prop._comparison(op, val)
      filters.append(node)
  if filters:
    filters = ConjunctionNode(*filters)
  else:
    filters = None
  orders = _orderings_to_orders(gql_qry.orderings(), modelclass)
  offset = gql_qry.offset()
  limit = gql_qry.limit()
  if limit < 0:
    limit = None
  keys_only = gql_qry._keys_only
  if not keys_only:
    keys_only = None
  options = QueryOptions(offset=offset, limit=limit, keys_only=keys_only)
  projection = gql_qry.projection()
  if gql_qry.is_distinct():
    group_by = projection
  else:
    group_by = None
  qry = query_class(kind=kind,
                    ancestor=ancestor,
                    filters=filters,
                    orders=orders,
                    default_options=options,
                    projection=projection,
                    group_by=group_by)
  return qry


Instruction:
Can you tell what is the following Python 3 function doing
def _apply(self, key_value_map):
    columns = []
    for key in self.match_keys:
      column = key_value_map.get(key)
      if not column:  # None, or an empty list.
        return False  # If any column is empty there can be no match.
      columns.append(column)
    # Use izip to transpose the columns into rows.
    return self.match_values in itertools.izip(*columns)

Response: Apply the filter to the values extracted from an entity.


Instruction:
Write a Python 3 script to
run this query and put entities into the given queue.

Response:
def run_to_queue(self, queue, conn, options=None, dsquery=None):
    """Run this query, putting entities into the given queue."""
    try:
      multiquery = self._maybe_multi_query()
      if multiquery is not None:
        yield multiquery.run_to_queue(queue, conn, options=options)
        return

      if dsquery is None:
        dsquery = self._get_query(conn)
      rpc = dsquery.run_async(conn, options)
      while rpc is not None:
        batch = yield rpc
        if (batch.skipped_results and
            datastore_query.FetchOptions.offset(options)):
          offset = options.offset - batch.skipped_results
          options = datastore_query.FetchOptions(offset=offset, config=options)
        rpc = batch.next_batch_async(options)
        for i, result in enumerate(batch.results):
          queue.putq((batch, i, result))
      queue.complete()

    except GeneratorExit:
      raise
    except Exception:
      if not queue.done():
        _, e, tb = sys.exc_info()
        queue.set_exception(e, tb)
      raise


Instruction:
Explain what the following Python 3 code does
def is_distinct(self):
    return bool(self.__group_by and
                set(self._to_property_names(self.__group_by)) <=
                set(self._to_property_names(self.__projection)))

Response:
True if results are guaranteed to contain a unique set of property
    values.


Instruction:
How would you code a function in Python 3 to
return a new Query with additional filter ( s ) applied.

Response:
def filter(self, *args):
    """Return a new Query with additional filter(s) applied."""
    if not args:
      return self
    preds = []
    f = self.filters
    if f:
      preds.append(f)
    for arg in args:
      if not isinstance(arg, Node):
        raise TypeError('Cannot filter a non-Node argument; received %r' % arg)
      preds.append(arg)
    if not preds:
      pred = None
    elif len(preds) == 1:
      pred = preds[0]
    else:
      pred = ConjunctionNode(*preds)
    return self.__class__(kind=self.kind, ancestor=self.ancestor,
                          filters=pred, orders=self.orders,
                          app=self.app, namespace=self.namespace,
                          default_options=self.default_options,
                          projection=self.projection, group_by=self.group_by)


Instruction:
Explain what the following Python 3 code does
def order(self, *args):
    # q.order(Employee.name, -Employee.age)
    if not args:
      return self
    orders = []
    o = self.orders
    if o:
      orders.append(o)
    for arg in args:
      if isinstance(arg, model.Property):
        orders.append(datastore_query.PropertyOrder(arg._name, _ASC))
      elif isinstance(arg, datastore_query.Order):
        orders.append(arg)
      else:
        raise TypeError('order() expects a Property or query Order; '
                        'received %r' % arg)
    if not orders:
      orders = None
    elif len(orders) == 1:
      orders = orders[0]
    else:
      orders = datastore_query.CompositeOrder(orders)
    return self.__class__(kind=self.kind, ancestor=self.ancestor,
                          filters=self.filters, orders=orders,
                          app=self.app, namespace=self.namespace,
                          default_options=self.default_options,
                          projection=self.projection, group_by=self.group_by)

Response: Return a new Query with additional sort order ( s ) applied.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def map(self, callback, pass_batch_into_callback=None,
          merge_future=None, **q_options):
    """Map a callback function or tasklet over the query results.

    Args:
      callback: A function or tasklet to be applied to each result; see below.
      merge_future: Optional Future subclass; see below.
      **q_options: All query options keyword arguments are supported.

    Callback signature: The callback is normally called with an entity
    as argument.  However if keys_only=True is given, it is called
    with a Key.  Also, when pass_batch_into_callback is True, it is
    called with three arguments: the current batch, the index within
    the batch, and the entity or Key at that index.  The callback can
    return whatever it wants.  If the callback is None, a trivial
    callback is assumed that just returns the entity or key passed in
    (ignoring produce_cursors).

    Optional merge future: The merge_future is an advanced argument
    that can be used to override how the callback results are combined
    into the overall map() return value.  By default a list of
    callback return values is produced.  By substituting one of a
    small number of specialized alternatives you can arrange
    otherwise.  See tasklets.MultiFuture for the default
    implementation and a description of the protocol the merge_future
    object must implement the default.  Alternatives from the same
    module include QueueFuture, SerialQueueFuture and ReducingFuture.

    Returns:
      When the query has run to completion and all callbacks have
      returned, map() returns a list of the results of all callbacks.
      (But see 'optional merge future' above.)
    """
    return self.map_async(callback,
                          pass_batch_into_callback=pass_batch_into_callback,
                          merge_future=merge_future,
                          **q_options).get_result()

Response: Map a callback function or tasklet over the query results.


Instruction:
Create a Python 3 function for
mapping a callback function or tasklet over the query results.

Response:
def map_async(self, callback, pass_batch_into_callback=None,
                merge_future=None, **q_options):
    """Map a callback function or tasklet over the query results.

    This is the asynchronous version of Query.map().
    """
    qry = self._fix_namespace()
    return tasklets.get_context().map_query(
        qry,
        callback,
        pass_batch_into_callback=pass_batch_into_callback,
        options=self._make_options(q_options),
        merge_future=merge_future)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def fetch_async(self, limit=None, **q_options):
    if limit is None:
      default_options = self._make_options(q_options)
      if default_options is not None and default_options.limit is not None:
        limit = default_options.limit
      else:
        limit = _MAX_LIMIT
    q_options['limit'] = limit
    q_options.setdefault('batch_size', limit)
    if self._needs_multi_query():
      return self.map_async(None, **q_options)
    # Optimization using direct batches.
    options = self._make_options(q_options)
    qry = self._fix_namespace()
    return qry._run_to_list([], options=options)

Response: Fetch a list of query results up to a limit.