Instruction:
Implement a function in Python 3 to
return a pop sequence for 32 bits operands inversion calling __SWAP32.

Response:
def _f16_oper(op1, op2=None, useBC=False, reversed=False):
    """ Returns pop sequence for 32 bits operands
    1st operand in HLDE, 2nd operand remains in the stack

    Now it does support operands inversion calling __SWAP32.

    However, if 1st operand is integer (immediate) or indirect, the stack
    will be rearranged, so it contains a 32 bit pushed parameter value for the
    subroutine to be called.

    If preserveHL is True, then BC will be used instead of HL for lower part
    for the 1st operand.
    """
    output = []

    if op1 is not None:
        op1 = str(op1)

    if op2 is not None:
        op2 = str(op2)

    op = op2 if op2 is not None else op1

    float1 = False  # whether op1 (2nd operand) is float

    indirect = (op[0] == '*')
    if indirect:
        op = op[1:]

    immediate = (op[0] == '#')
    if immediate:
        op = op[1:]

    hl = 'hl' if not useBC and not indirect else 'bc'

    if is_float(op):
        float1 = True
        op = float(op)

        if indirect:
            op = int(op) & 0xFFFF
            if immediate:
                output.append('ld hl, %i' % op)
            else:
                output.append('ld hl, (%i)' % op)

            output.append('call __ILOAD32')
            REQUIRES.add('iload32.asm')

            if preserveHL:  # noqa TODO: it will fail
                output.append('ld b, h')
                output.append('ld c, l')
        else:
            DE, HL = f16(op)
            output.append('ld de, %i' % DE)
            output.append('ld %s, %i' % (hl, HL))
    else:
        if op[0] == '_':
            if immediate:
                output.append('ld %s, %s' % (hl, op))
            else:
                output.append('ld %s, (%s)' % (hl, op))
        else:
            output.append('pop %s' % hl)

        if indirect:
            output.append('call __ILOAD32')
            REQUIRES.add('iload32.asm')

            if preserveHL:  # noqa TODO: it will fail
                output.append('ld b, h')
                output.append('ld c, l')
        else:
            if op[0] == '_':
                output.append('ld de, (%s + 2)' % op)
            else:
                output.append('pop de')

    if op2 is not None:
        op = op1

        indirect = (op[0] == '*')
        if indirect:
            op = op[1:]

        immediate = (op[0] == '#')
        if immediate:
            op = op[1:]

        if is_float(op):
            op = float(op)

            if indirect:
                op = int(op)
                output.append('exx')
                if immediate:
                    output.append('ld hl, %i' % (op & 0xFFFF))
                else:
                    output.append('ld hl, (%i)' % (op & 0xFFFF))

                output.append('call __ILOAD32')
                output.append('push de')
                output.append('push hl')
                output.append('exx')
                REQUIRES.add('iload32.asm')
            else:
                DE, HL = f16(op)
                output.append('ld bc, %i' % DE)
                output.append('push bc')
                output.append('ld bc, %i' % HL)
                output.append('push bc')
        else:
            if indirect:
                output.append('exx')  # uses alternate set to put it on the stack
                if op[0] == '_':
                    if immediate:
                        output.append('ld hl, %s' % op)
                    else:
                        output.append('ld hl, (%s)' % op)
                else:
                    output.append('pop hl')  # Pointers are only 16 bits ***

                output.append('call __ILOAD32')
                output.append('push de')
                output.append('push hl')
                output.append('exx')
                REQUIRES.add('iload32.asm')
            elif op[0] == '_':  # an address
                if float1 or op1[0] == '_':  # If previous op was constant, we can use hl in advance
                    tmp = output
                    output = []
                    output.append('ld hl, (%s + 2)' % op)
                    output.append('push hl')
                    output.append('ld hl, (%s)' % op)
                    output.append('push hl')
                    output.extend(tmp)
                else:
                    output.append('ld bc, (%s + 2)' % op)
                    output.append('push bc')
                    output.append('ld bc, (%s)' % op)
                    output.append('push bc')
            else:
                pass  # 2nd operand remains in the stack

    if op2 is not None and reversed:
        output.append('call __SWAP32')
        REQUIRES.add('swap32.asm')

    return output


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _f16_to_32bit(ins):
    ins.quad = [x for x in ins.quad]
    for i in range(2, len(ins.quad)):
        if is_float(ins.quad[i]):
            de, hl = f16(ins.quad[i])
            ins.quad[i] = str((de << 16) | hl)

    ins.quad = tuple(ins.quad)
    return ins

Response: Convert a 16 bit float to 32bit integer representation.


Instruction:
Explain what the following Python 3 code does
def _mulf16(ins):
    op1, op2 = tuple(ins.quad[2:])

    if _f_ops(op1, op2) is not None:
        op1, op2 = _f_ops(op1, op2)

        if op2 == 1:  # A * 1 => A
            output = _f16_oper(op1)
            output.append('push de')
            output.append('push hl')
            return output

        if op2 == -1:
            return _neg32(ins)

        output = _f16_oper(op1)
        if op2 == 0:
            output.append('ld hl, 0')
            output.append('ld e, h')
            output.append('ld d, l')
            output.append('push de')
            output.append('push hl')
            return output

    output = _f16_oper(op1, str(op2))
    output.append('call __MULF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('mulf16.asm')
    return output

Response: Multiplies 2 32bit fixed point numbers.


Instruction:
Can you create a Python 3 function that
divides 2 32bit fixed point numbers.

Response:
def _divf16(ins):
    """ Divides 2 32bit (16.16) fixed point numbers. The result is pushed onto the stack.

        Optimizations:

         * If 2nd operand is 1, do nothing
         * If 2nd operand is -1, do NEG32
    """
    op1, op2 = tuple(ins.quad[2:])

    if is_float(op2):
        if float(op2) == 1:
            output = _f16_oper(op1)
            output.append('push de')
            output.append('push hl')
            return output

        if float(op2) == -1:
            return _negf(ins)

    rev = not is_float(op1) and op1[0] != 't' and op2[0] == 't'

    output = _f16_oper(op1, op2, reversed=rev)
    output.append('call __DIVF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('divf16.asm')
    return output


Instruction:
Implement a Python 3 function for
raising an exception raised when an invalid number of params in the given quad code has been emmitted.

Response:
def throw_invalid_quad_params(quad, QUADS, nparams):
    """ Exception raised when an invalid number of params in the
        quad code has been emmitted.
    """
    raise InvalidICError(str(quad),
                         "Invalid quad code params for '%s' (expected %i, but got %i)" %
                         (quad, QUADS[quad][0], nparams)
                         )


Instruction:
Write a Python 3 script to
return a floating point number as EXP + 128 Mantissa AttributeNames

Response:
def fp(x):
    """ Returns a floating point number as EXP+128, Mantissa
    """

    def bin32(f):
        """ Returns ASCII representation for a 32 bit integer value
        """
        result = ''
        a = int(f) & 0xFFFFFFFF  # ensures int 32

        for i in range(32):
            result = str(a % 2) + result
            a = a >> 1

        return result

    def bindec32(f):
        """ Returns binary representation of a mantissa x (x is float)
        """
        result = '0'
        a = f

        if f >= 1:
            result = bin32(f)

        result += '.'
        c = int(a)

        for i in range(32):
            a -= c
            a *= 2
            c = int(a)
            result += str(c)

        return result

    e = 0  # exponent
    s = 1 if x < 0 else 0  # sign
    m = abs(x)  # mantissa

    while m >= 1:
        m /= 2.0
        e += 1

    while 0 < m < 0.5:
        m *= 2.0
        e -= 1

    M = bindec32(m)[3:]
    M = str(s) + M
    E = bin32(e + 128)[-8:] if x != 0 else bin32(0)[-8:]

    return M, E


Instruction:
Implement a function in Python 3 to
return C DE HL as values for loading and immediate floating point.

Response:
def immediate_float(x):
    """ Returns C DE HL as values for loading
    and immediate floating point.
    """
    def bin2hex(y):
        return "%02X" % int(y, 2)

    M, E = fp(x)

    C = '0' + bin2hex(E) + 'h'
    ED = '0' + bin2hex(M[8:16]) + bin2hex(M[:8]) + 'h'
    LH = '0' + bin2hex(M[24:]) + bin2hex(M[16:24]) + 'h'

    return C, ED, LH


Instruction:
How would you implement a function in Python 3 that
iterates in order calling the function with the current node.

Response:
def inorder(self, funct, stopOn=None):
        """ Iterates in order, calling the function with the current node.
        If stopOn is set to True or False, it will stop on true or false.
        """
        if stopOn is None:
            for i in self.children:
                i.inorder(funct)
        else:
            for i in self.children:
                if i.inorder(funct) == stopOn:
                    return stopOn

        return funct(self)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def preorder(self, funct, stopOn=None):
        if funct(self.symbol) == stopOn and stopOn is not None:
            return stopOn

        if stopOn is None:
            for i in self.children:
                i.preorder(funct)
        else:
            for i in self.children:
                if i.preorder(funct) == stopOn:
                    return stopOn

Response: Iterates in preorder calling the function with the current node.


Instruction:
Can you create a Python 3 function that
iterates in postorder calling the function with the current node.

Response:
def postorder(self, funct, stopOn=None):
        """ Iterates in postorder, calling the function with the current node.
        If stopOn is set to True or False, it will stop on true or false.
        """
        if stopOn is None:
            for i in range(len(self.children) - 1, -1, -1):
                self.children[i].postorder(funct)
        else:
            for i in range(len(self.children) - 1, -1, -1):
                if self.children[i].postorder(funct) == stopOn:
                    return stopOn
        return funct(self.symbol)


Instruction:
How would you code a function in Python 3 to
store the symbol in an AST instance and left and right to the given ones

Response:
def makenode(clss, symbol, *nexts):
        """ Stores the symbol in an AST instance,
        and left and right to the given ones
        """
        result = clss(symbol)
        for i in nexts:
            if i is None:
                continue
            if not isinstance(i, clss):
                raise NotAnAstError(i)
            result.appendChild(i)

        return result


Instruction:
Given the following Python 3 function, write the documentation
def get_include_path():
    f1 = os.path.basename(sys.argv[0]).lower()  # script filename
    f2 = os.path.basename(sys.executable).lower()  # Executable filename

    # If executable filename and script name are the same, we are
    if f1 == f2 or f2 == f1 + '.exe':  # under a "compiled" python binary
        result = os.path.dirname(os.path.realpath(sys.executable))
    else:
        result = os.path.dirname(os.path.realpath(__file__))

    return result

Response:
Default include path using a tricky sys
    calls.


Instruction:
How would you implement a function in Python 3 that
searches a filename into the list of include paths.

Response:
def search_filename(fname, lineno, local_first):
    """ Search a filename into the list of the include path.
    If local_first is true, it will try first in the current directory of
    the file being analyzed.
    """
    fname = api.utils.sanitize_filename(fname)
    i_path = [CURRENT_DIR] + INCLUDEPATH if local_first else list(INCLUDEPATH)
    i_path.extend(OPTIONS.include_path.value.split(':') if OPTIONS.include_path.value else [])
    if os.path.isabs(fname):
        if os.path.isfile(fname):
            return fname
    else:
        for dir_ in i_path:
            path = api.utils.sanitize_filename(os.path.join(dir_, fname))
            if os.path.exists(path):
                return path

    error(lineno, "file '%s' not found" % fname)
    return ''


Instruction:
Make a summary of the following Python 3 code
def include_file(filename, lineno, local_first):
    global CURRENT_DIR
    filename = search_filename(filename, lineno, local_first)
    if filename not in INCLUDED.keys():
        INCLUDED[filename] = []

    if len(CURRENT_FILE) > 0:  # Added from which file, line
        INCLUDED[filename].append((CURRENT_FILE[-1], lineno))

    CURRENT_FILE.append(filename)
    CURRENT_DIR = os.path.dirname(filename)
    return LEXER.include(filename)

Response: A function that performs a file inclusion in the preprocessor.


Instruction:
Make a summary of the following Python 3 code
def include_once(filename, lineno, local_first):
    filename = search_filename(filename, lineno, local_first)
    if filename not in INCLUDED.keys():  # If not already included
        return include_file(filename, lineno, local_first)  # include it and return

    # Now checks if the file has been included more than once
    if len(INCLUDED[filename]) > 1:
        warning(lineno, "file '%s' already included more than once, in file "
                        "'%s' at line %i" %
                (filename, INCLUDED[filename][0][0], INCLUDED[filename][0][1]))

    # Empty file (already included)
    LEXER.next_token = '_ENDFILE_'
    return ''

Response: A function that will include a file at a specific line.


Instruction:
How would you implement a function in Python 3 that
programs : defs NEWLINE

Response:
def p_program_tokenstring(p):
    """ program : defs NEWLINE
    """
    try:
        tmp = [str(x()) if isinstance(x, MacroCall) else x for x in p[1]]
    except PreprocError as v:
        error(v.lineno, v.message)

    tmp.append(p[2])
    p[0] = tmp


Instruction:
Create a Python 3 function to
include : INCLUDE STRING

Response:
def p_include(p):
    """ include : INCLUDE STRING
    """
    if ENABLED:
        p[0] = include_file(p[2], p.lineno(2), local_first=True)
    else:
        p[0] = []
        p.lexer.next_token = '_ENDFILE_'


Instruction:
Can you implement a function in Python 3 that
includes : INCLUDE FILENAME

Response:
def p_include_fname(p):
    """ include : INCLUDE FILENAME
    """
    if ENABLED:
        p[0] = include_file(p[2], p.lineno(2), local_first=False)
    else:
        p[0] = []
        p.lexer.next_token = '_ENDFILE_'


Instruction:
How would you code a function in Python 3 to
include once is a no - op.

Response:
def p_include_once(p):
    """ include_once : INCLUDE ONCE STRING
    """
    if ENABLED:
        p[0] = include_once(p[3], p.lineno(3), local_first=True)
    else:
        p[0] = []

    if not p[0]:
        p.lexer.next_token = '_ENDFILE_'


Instruction:
Implement a Python 3 function for
defining : DEFINE ID params defs

Response:
def p_define(p):
    """ define : DEFINE ID params defs
    """
    if ENABLED:
        if p[4]:
            if SPACES.match(p[4][0]):
                p[4][0] = p[4][0][1:]
            else:
                warning(p.lineno(1), "missing whitespace after the macro name")

        ID_TABLE.define(p[2], args=p[3], value=p[4], lineno=p.lineno(2),
                        fname=CURRENT_FILE[-1])
    p[0] = []


Instruction:
Given the following Python 3 function, write the documentation
def p_define_params_empty(p):
    # Defines the 'epsilon' parameter
    p[0] = [ID('', value='', args=None, lineno=p.lineno(1),
               fname=CURRENT_FILE[-1])]

Response: Define the empty parameter list in the parameter list.


Instruction:
Can you tell what is the following Python 3 function doing
def p_paramlist_single(p):
    p[0] = [ID(p[1], value='', args=None, lineno=p.lineno(1),
               fname=CURRENT_FILE[-1])]

Response: paramlist is a list of ID tuples where the first element is the parameter name and the second is the value of the parameter.


Instruction:
Can you generate the documentation for the following Python 3 function
def p_ifdef(p):
    global ENABLED

    if ENABLED:
        p[0] = [p[2]] + p[3]
        p[0] += ['#line %i "%s"' % (p.lineno(4) + 1, CURRENT_FILE[-1])]
    else:
        p[0] = ['#line %i "%s"' % (p.lineno(4) + 1, CURRENT_FILE[-1])]

    ENABLED = IFDEFS[-1][0]
    IFDEFS.pop()

Response: P - IF - DEFINE statement


Instruction:
Make a summary of the following Python 3 code
def p_ifdef_else(p):
    global ENABLED

    p[0] = p[1] + p[2]
    p[0] += ['#line %i "%s"' % (p.lineno(3) + 1, CURRENT_FILE[-1])]
    ENABLED = IFDEFS[-1][0]
    IFDEFS.pop()

Response: P 3. 4. 3. ifdef else


Instruction:
Can you tell what is the following Python 3 function doing
def p_if_header(p):
    global ENABLED

    IFDEFS.append((ENABLED, p.lineno(2)))
    ENABLED = ID_TABLE.defined(p[2])

Response: Set ENABLED to True if the first line of the if header is defined.


Instruction:
How would you code a function in Python 3 to
set ENABLED to True if the IFN header is not defined.

Response:
def p_ifn_header(p):
    """ if_header : IFNDEF ID
    """
    global ENABLED

    IFDEFS.append((ENABLED, p.lineno(2)))
    ENABLED = not ID_TABLE.defined(p[2])


Instruction:
Given the following Python 3 function, write the documentation
def p_exprge(p):
    a = int(p[1]) if p[1].isdigit() else 0
    b = int(p[3]) if p[3].isdigit() else 0

    p[0] = '1' if a >= b else '0'

Response: expr : expr GE expr


Instruction:
Can you generate a brief explanation for the following Python 3 code
def filter_(input_, filename='<internal>', state='INITIAL'):
    global CURRENT_DIR

    prev_dir = CURRENT_DIR
    CURRENT_FILE.append(filename)
    CURRENT_DIR = os.path.dirname(CURRENT_FILE[-1])
    LEXER.input(input_, filename)
    LEXER.lex.begin(state)
    parser.parse(lexer=LEXER, debug=OPTIONS.Debug.value > 2)
    CURRENT_FILE.pop()
    CURRENT_DIR = prev_dir

Response: Filter the input string thought the preprocessor.


Instruction:
Explain what the following Python 3 code does
def del_data(name=None):
    if name is None:
        tplot_names = list(data_quants.keys())
        for i in tplot_names:
            del data_quants[i]
        return

    if not isinstance(name, list):
        name = [name]

    entries = []
    ###
    for i in name:
        if ('?' in i) or ('*' in i):
            for j in data_quants.keys():
                var_verif = fnmatch.fnmatch(data_quants[j].name, i)
                if var_verif == 1:
                    entries.append(data_quants[j].name)
                else:
                    continue
            for key in entries:
                if key in data_quants:
                    del data_quants[key]
    ###
        elif i not in data_quants.keys():
            print(str(i) + " is currently not in pytplot.")
            return

        else:
            temp_data_quants = data_quants[i]
            str_name = temp_data_quants.name

            del data_quants[str_name]

    return

Response: This function deletes all tplot variables that are already stored in memory.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def xlim(min, max):
    if not isinstance(min, (int, float, complex)):
        min = tplot_utilities.str_to_int(min)
    if not isinstance(max, (int, float, complex)):
        max = tplot_utilities.str_to_int(max)
    if 'x_range' in tplot_opt_glob:
        lim_info['xlast'] = tplot_opt_glob['x_range']
    else:
        lim_info['xfull'] = Range1d(min, max)
        lim_info['xlast'] = Range1d(min, max)
    tplot_opt_glob['x_range'] = [min, max]
    return

Response: This function will set the x axis range for all time series plots


Instruction:
Can you tell what is the following Python 3 function doing
def ylim(name, min, max):
    if name not in data_quants.keys():
        print("That name is currently not in pytplot.")
        return

    temp_data_quant = data_quants[name]
    temp_data_quant.yaxis_opt['y_range'] = [min, max]

    return

Response: This function will set the y axis limits for a specific tplot variable.


Instruction:
Make a summary of the following Python 3 code
def store_data(name, data=None, delete=False, newname=None):

    """
    This function creates a "Tplot Variable" based on the inputs, and
    stores this data in memory.  Tplot Variables store all of the information
    needed to generate a plot.

    Parameters:
        name : str
            Name of the tplot variable that will be created
        data : dict
            A python dictionary object.

            'x' should be a 1-dimensional array that represents the data's x axis.  Typically this data is time,
            represented in seconds since epoch (January 1st 1970)

            'y' should be the data values. This can be 2 dimensions if multiple lines or a spectrogram are desired.

            'v' is optional, and is only used for spectrogram plots.  This will be a list of bins to be used.  If this
            is provided, then 'y' should have dimensions of x by z.

            'x' and 'y' can be any data format that can be read in by the pandas module.  Python lists, numpy arrays,
            or any pandas data type will all work.
        delete : bool, optional
            Deletes the tplot variable matching the "name" parameter
        newname: str
            Renames TVar to new name

    .. note::
        If you want to combine multiple tplot variables into one, simply supply the list of tplot variables to the
        "data" parameter.  This will cause the data to overlay when plotted.

    Returns:
        None

    Examples:
        >>> # Store a single line
        >>> import pytplot
        >>> x_data = [1,2,3,4,5]
        >>> y_data = [1,2,3,4,5]
        >>> pytplot.store_data("Variable1", data={'x':x_data, 'y':y_data})

        >>> # Store a two lines
        >>> x_data = [1,2,3,4,5]
        >>> y_data = [[1,5],[2,4],[3,3],[4,2],[5,1]]
        >>> pytplot.store_data("Variable2", data={'x':x_data, 'y':y_data})

        >>> # Store a spectrogram
        >>> x_data = [1,2,3]
        >>> y_data = [ [1,2,3] , [4,5,6], [7,8,9] ]
        >>> v_data = [1,2,3]
        >>> pytplot.store_data("Variable3", data={'x':x_data, 'y':y_data, 'v':v_data})

        >>> # Combine two different line plots
        >>> pytplot.store_data("Variable1and2", data=['Variable1', 'Variable2'])

        >>> #Rename TVar
        >>> pytplot.store_data('a', data={'x':[0,4,8,12,16], 'y':[1,2,3,4,5]})
        >>> pytplot.store_data('a',newname='f')

    """

    global tplot_num
    create_time = datetime.datetime.now()

    if delete is True:
        del_data(name)
        return

    if data is None and newname is None:
        print('Please provide data.')
        return

    if newname is not None:
        pytplot.tplot_rename(name, newname)
        return

    if isinstance(data, list):
        base_data = get_base_tplot_vars(data)
        # Use first tplot var as the time range
        trange = [np.nanmin(data_quants[base_data[0]].data.index),
                  np.nanmax(data_quants[base_data[0]].data.index)]
        df = base_data
        spec_bins = None
    else:
        df = format_ydata(data['y'])
        times = data['x']

        # If given a list of datetime objects, convert times to seconds since epoch.
        if any(isinstance(t, datetime.datetime) for t in times):
            for tt, time in enumerate(times):
                times[tt] = (time-datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc)).total_seconds()
        # If given a list of datetime string, convert times to seconds since epoch
        elif any(isinstance(t, str) for t in times):
            for tt, time in enumerate(times):
                times[tt] = pytplot.tplot_utilities.str_to_int(time)

        if len(times) != len(df.index):
            print("The lengths of x and y do not match!")
            return
        elif isinstance(times, pd.Series):
            df = df.set_index(data['x'])
        else:
            df['Index'] = times
            df = df.set_index('Index', drop=True)

        trange = [np.nanmin(times), np.nanmax(times)]

        if 'v' in data or 'v2' in data:
            # Generally the data is 1D, but occasionally
            # the bins will vary in time.
            if 'v' in data:
                spec_bins = data['v']
            else:
                spec_bins = data['v2']

            if type(spec_bins) is not pd.DataFrame:
                spec_bins = pd.DataFrame(spec_bins)
                if len(spec_bins.columns) != 1:
                    if len(spec_bins) == len(df.index):
                        spec_bins = spec_bins.set_index(df.index)
                    else:
                        print("Length of v and x do not match.  Cannot create tplot variable.")
                        return
                else:
                    spec_bins = spec_bins.transpose()
        else:
            spec_bins = None

    xaxis_opt = dict(axis_label='Time')
    yaxis_opt = dict(axis_label=name) if (spec_bins is None) else dict(axis_label='')
    zaxis_opt = dict(axis_label='') if (spec_bins is None) else dict(axis_label=name)
    line_opt = {}
    dtype = ''
    time_bar = []
    # Dictionary to keep track of extra details needed for plotting
    #     that aren't actual attributes in Bokeh
    extras = dict(panel_size=1)
    links = {}
    temp = TVar(name, tplot_num, df, spec_bins, xaxis_opt, yaxis_opt, zaxis_opt, line_opt,
                trange, dtype, create_time, time_bar, extras, links)

    data_quants[name] = temp
    data_quants[name].yaxis_opt['y_range'] = get_y_range(df, spec_bins)

    return

Response: This function creates a Tplot Variable based on the inputs and stores the data in memory.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_data(name):

    global data_quants
    if name not in data_quants.keys():
        print("That name is currently not in pytplot")
        return

    temp_data_quant = data_quants[name]
    data_val = temp_data_quant.data.values
    time_val = temp_data_quant.data.index

    return(time_val, data_val)

Response: This function extracts the data from the Tplot Variables stored in memory. This function extracts the data from the Tplot Variables stored in memory. This function returns the time and data values of the variable whose name is name.


Instruction:
Can you implement a function in Python 3 that
generates a set of drawing specs for this item.

Response:
def generateDrawSpecs(self, p):
        """
        Calls tickValues() and tickStrings() to determine where and how ticks should
        be drawn, then generates from this a set of drawing commands to be
        interpreted by drawPicture().
        """
        profiler = debug.Profiler()

        # bounds = self.boundingRect()
        bounds = self.mapRectFromParent(self.geometry())

        linkedView = self.linkedView()
        if linkedView is None or self.grid is False:
            tickBounds = bounds
        else:
            tickBounds = linkedView.mapRectToItem(self, linkedView.boundingRect())

        if self.orientation == 'left':
            span = (bounds.topRight(), bounds.bottomRight())
            tickStart = tickBounds.right()
            tickStop = bounds.right()
            tickDir = -1
            axis = 0
        elif self.orientation == 'right':
            span = (bounds.topLeft(), bounds.bottomLeft())
            tickStart = tickBounds.left()
            tickStop = bounds.left()
            tickDir = 1
            axis = 0
        elif self.orientation == 'top':
            span = (bounds.bottomLeft(), bounds.bottomRight())
            tickStart = tickBounds.bottom()
            tickStop = bounds.bottom()
            tickDir = -1
            axis = 1
        elif self.orientation == 'bottom':
            span = (bounds.topLeft(), bounds.topRight())
            tickStart = tickBounds.top()
            tickStop = bounds.top()
            tickDir = 1
            axis = 1
        # print tickStart, tickStop, span

        ## determine size of this item in pixels
        points = list(map(self.mapToDevice, span))
        if None in points:
            return
        lengthInPixels = Point(points[1] - points[0]).length()
        if lengthInPixels == 0:
            return

        # Determine major / minor / subminor axis ticks
        if self._tickLevels is None:
            tickLevels = self.tickValues(self.range[0], self.range[1], lengthInPixels)
            tickStrings = None
        else:
            ## parse self.tickLevels into the formats returned by tickLevels() and tickStrings()
            tickLevels = []
            tickStrings = []
            for level in self._tickLevels:
                values = []
                strings = []
                tickLevels.append((None, values))
                tickStrings.append(strings)
                for val, strn in level:
                    values.append(val)
                    strings.append(strn)

        ## determine mapping between tick values and local coordinates
        dif = self.range[1] - self.range[0]
        if dif == 0:
            xScale = 1
            offset = 0
        else:
            if axis == 0:
                xScale = -bounds.height() / dif
                offset = self.range[0] * xScale - bounds.height()
            else:
                xScale = bounds.width() / dif
                offset = self.range[0] * xScale

        xRange = [x * xScale - offset for x in self.range]
        xMin = min(xRange)
        xMax = max(xRange)

        profiler('init')

        tickPositions = []  # remembers positions of previously drawn ticks

        ## compute coordinates to draw ticks
        ## draw three different intervals, long ticks first
        tickSpecs = []
        for i in range(len(tickLevels)):
            tickPositions.append([])
            ticks = tickLevels[i][1]

            ## length of tick
            tickLength = self.style['tickLength'] / ((i * 0.5) + 1.0)

            lineAlpha = 255 / (i + 1)
            if self.grid is not False:
                lineAlpha *= self.grid / 255. * np.clip((0.05 * lengthInPixels / (len(ticks) + 1)), 0., 1.)

            for v in ticks:
                ## determine actual position to draw this tick
                x = (v * xScale) - offset
                if x < xMin or x > xMax:  ## last check to make sure no out-of-bounds ticks are drawn
                    tickPositions[i].append(None)
                    continue
                tickPositions[i].append(x)

                p1 = [x, x]
                p2 = [x, x]
                p1[axis] = tickStart
                p2[axis] = tickStop
                if self.grid is False:
                    p2[axis] += tickLength * tickDir
                tickPen = self.pen()
                color = tickPen.color()
                color.setAlpha(lineAlpha)
                tickPen.setColor(color)
                tickSpecs.append((tickPen, Point(p1), Point(p2)))
        profiler('compute ticks')

        if self.style['stopAxisAtTick'][0] is True:
            stop = max(span[0].y(), min(map(min, tickPositions)))
            if axis == 0:
                span[0].setY(stop)
            else:
                span[0].setX(stop)
        if self.style['stopAxisAtTick'][1] is True:
            stop = min(span[1].y(), max(map(max, tickPositions)))
            if axis == 0:
                span[1].setY(stop)
            else:
                span[1].setX(stop)
        axisSpec = (self.pen(), span[0], span[1])

        textOffset = self.style['tickTextOffset'][axis]  ## spacing between axis and text
        # if self.style['autoExpandTextSpace'] is True:
        # textWidth = self.textWidth
        # textHeight = self.textHeight
        # else:
        # textWidth = self.style['tickTextWidth'] ## space allocated for horizontal text
        # textHeight = self.style['tickTextHeight'] ## space allocated for horizontal text

        textSize2 = 0
        textRects = []
        textSpecs = []  ## list of draw

        # If values are hidden, return early
        if not self.style['showValues']:
            return (axisSpec, tickSpecs, textSpecs)

        for i in range(min(len(tickLevels), self.style['maxTextLevel'] + 1)):
            ## Get the list of strings to display for this level
            if tickStrings is None:
                spacing, values = tickLevels[i]
                strings = self.tickStrings(values, self.autoSIPrefixScale * self.scale, spacing)
            else:
                strings = tickStrings[i]

            if len(strings) == 0:
                continue

            ## ignore strings belonging to ticks that were previously ignored
            for j in range(len(strings)):
                if tickPositions[i][j] is None:
                    strings[j] = None

            ## Measure density of text; decide whether to draw this level
            rects = []
            for s in strings:
                if s is None:
                    rects.append(None)
                else:
                    br = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, asUnicode(s))
                    ## boundingRect is usually just a bit too large
                    ## (but this probably depends on per-font metrics?)
                    br.setHeight(br.height() * 1.4)

                    rects.append(br)
                    textRects.append(rects[-1])

            if len(textRects) > 0:
                ## measure all text, make sure there's enough room
                if axis == 0:
                    textSize = np.sum([r.height() for r in textRects])
                    textSize2 = np.max([r.width() for r in textRects])
                else:
                    textSize = np.sum([r.width() for r in textRects])
                    textSize2 = np.max([r.height() for r in textRects])
            else:
                textSize = 0
                textSize2 = 0

            if i > 0:  ## always draw top level
                ## If the strings are too crowded, stop drawing text now.
                ## We use three different crowding limits based on the number
                ## of texts drawn so far.
                textFillRatio = float(textSize) / lengthInPixels
                finished = False
                for nTexts, limit in self.style['textFillLimits']:
                    if len(textSpecs) >= nTexts and textFillRatio >= limit:
                        finished = True
                        break
                if finished:
                    break

            # spacing, values = tickLevels[best]
            # strings = self.tickStrings(values, self.scale, spacing)
            # Determine exactly where tick text should be drawn
            for j in range(len(strings)):
                vstr = strings[j]
                if vstr is None:  ## this tick was ignored because it is out of bounds
                    continue
                vstr = asUnicode(vstr)
                x = tickPositions[i][j]
                # textRect = p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, vstr)
                textRect = rects[j]
                height = textRect.height()
                width = textRect.width()
                # self.textHeight = height
                offset = max(0, self.style['tickLength']) + textOffset
                if self.orientation == 'left':
                    textFlags = QtCore.Qt.TextDontClip | QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter
                    rect = QtCore.QRectF(tickStop - offset - width, x - (height / 2), width, height)
                elif self.orientation == 'right':
                    textFlags = QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter
                    rect = QtCore.QRectF(tickStop + offset, x - (height / 2), width, height)
                elif self.orientation == 'top':
                    textFlags = QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom
                    rect = QtCore.QRectF(x - width / 2., tickStop - offset - height, width, height)
                elif self.orientation == 'bottom':
                    textFlags = QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter | QtCore.Qt.AlignTop
                    rect = QtCore.QRectF(x - width / 2., tickStop + offset, width, height)

                # p.setPen(self.pen())
                # p.drawText(rect, textFlags, vstr)
                textSpecs.append((rect, textFlags, vstr))
        profiler('compute text')

        ## update max text size if needed.
        self._updateMaxTextSize(textSize2)

        return (axisSpec, tickSpecs, textSpecs)


Instruction:
Can you tell what is the following Python 3 function doing
def static2dplot(var, time):

    # Grab names of data loaded in as tplot variables.
    names = list(pytplot.data_quants.keys())
    # Get data we'll actually work with here.
    valid_variables = tplot_utilities.get_data(names)

    # Don't plot anything unless we have spectrograms with which to work.
    if valid_variables:
        # Get z label
        labels = tplot_utilities.get_labels_axis_types(names)

        # Put together data in easy-to-access format for plots.
        data = {}
        for name in valid_variables:
            bins = tplot_utilities.get_bins(name)
            time_values, z_values = tplot_utilities.get_z_t_values(name)
            data[name] = [bins, z_values, time_values]

        # Set up the 2D static plot
        pytplot.static_window = pg.GraphicsWindow()
        pytplot.static_window.resize(1000, 600)
        pytplot.static_window.setWindowTitle('Static Window')
        plot = pytplot.static_window.addPlot(title='2D Static Plot', row=0, col=0)
        # Make it so that whenever this first starts up, you just have an empty plot
        plot_data = plot.plot([], [])

        if var in valid_variables:
            # Get min/max values of data's time range (in both datetime and seconds since epoch)
            t_min = np.nanmin(time_values)
            t_min_str = tplot_utilities.int_to_str(np.nanmin(time_values))
            t_min_conv_back = tplot_utilities.str_to_int(t_min_str)
            t_max = np.nanmax(time_values)
            t_max_str = tplot_utilities.int_to_str(np.nanmax(time_values))
            t_max_conv_back = tplot_utilities.str_to_int(t_max_str)
            # Convert user input to seconds since epoch
            user_time = tplot_utilities.str_to_int(time)

            # Covering situation where user entered a time not in the dataset!
            # As long as they used a time in the dataset, this will not trigger.
            if user_time not in range(t_min_conv_back, t_max_conv_back+1):
                while True:
                    try:
                        user_time = tplot_utilities.str_to_int(input(
                            'Chosen time not in range of data [{} to {}]. Input new time (%Y-%m-%d %H:%M:%S). '.format(
                                t_min_str, t_max_str)))
                    except:
                        continue
                    else:
                        if user_time not in range(int(t_min), int(t_max)):
                            continue
                        else:
                            break

            # Get time closest to the user's time choice
            time_array = np.array(data[var][2])
            array = np.asarray(time_array)
            idx = (np.abs(array - user_time)).argmin()
            # If user indicated they wanted the interactive plot's axes to be logged, log 'em.
            # But first make sure that values in x and y are loggable!
            x_axis = False
            y_axis = False
            # Checking x axis
            if np.nanmin(data[name][0][:]) < 0:
                print('Negative data is incompatible with log plotting.')
            elif np.nanmin(data[name][0][:]) >= 0 and labels[name][2] == 'log':
                x_axis = True
            # Checking y axis
            if np.nanmin(list(data[name][1][idx])) < 0:
                print('Negative data is incompatible with log plotting')
            elif np.nanmin(list(data[name][1][idx])) >= 0 and labels[name][3] == 'log':
                y_axis = True

            # Set plot labels
            plot.setLabel('bottom', '{}'.format(labels[name][0]))
            plot.setLabel('left', '{}'.format(labels[name][1]))
            plot.setLogMode(x=x_axis, y=y_axis)
            # Update x and y range if user modified it
            tplot_utilities.set_x_range(name, x_axis, plot)
            tplot_utilities.set_y_range(name, y_axis, plot)
            # Plot data based on time we're hovering over
            plot_data.setData(data[name][0][:], list(data[name][1][idx]))

Response: This function will plot the static option of the current page.


Instruction:
Create a Python 3 function to
check if the spec_bins are ascending or descending.

Response:
def _check_spec_bins_ordering(self):
        """
        This is a private function of the TVar object, this is run during
        object creation to check if spec_bins are ascending or descending
        """
        if self.spec_bins is None:
            return
        if len(self.spec_bins) == len(self.data.index):
            self.spec_bins_time_varying = True
            break_top_loop = False
            for index, row in self.spec_bins.iterrows():
                if row.isnull().values.all():
                    continue
                else:
                    for i in row.index:
                        if np.isfinite(row[i]) and np.isfinite(row[i + 1]):
                            ascending = row[i] < row[i + 1]
                            break_top_loop = True
                            break
                        else:
                            continue
                    if break_top_loop:
                        break
        else:
            ascending = self.spec_bins[0].iloc[0] < self.spec_bins[1].iloc[0]
        return ascending


Instruction:
Can you generate the documentation for the following Python 3 function
def interactiveplot(t_average=None):

    # Grab names of data loaded in as tplot variables.
    names = list(pytplot.data_quants.keys())
    # Get data we'll actually work with here.
    valid_variables = tplot_utilities.get_data(names)

    # Don't plot anything unless we have spectrograms with which to work.
    if valid_variables:
        # Get z label
        labels = tplot_utilities.get_labels_axis_types(names)

        # Put together data in easy-to-access format for plots.
        data = {}
        for name in valid_variables:
            bins = tplot_utilities.get_bins(name)
            time_values, z_values = tplot_utilities.get_z_t_values(name)
            data[name] = [bins, z_values, time_values]

        # Set up the 2D interactive plot
        pytplot.interactive_window = pg.GraphicsWindow()
        pytplot.interactive_window.resize(1000, 600)
        pytplot.interactive_window.setWindowTitle('Interactive Window')
        plot = pytplot.interactive_window.addPlot(title='2D Interactive Plot', row=0, col=0)
        # Make it so that whenever this first starts up, you just have an empty plot
        plot_data = plot.plot([], [])

        # The following update function is passed to change_hover_time in the HoverTime class
        # defined in __init__.py. For reference, "t" essentially originates inside of
        # TVarFigure(1D/Spec/Alt/Map), inside the _mousemoved function. It calls
        # "self._mouseMovedFunction(int(mousePoint.x()))" and that is called every time the mouse is
        # moved by Qt. Therefore, it gives the location of the mouse on the x axis. In tplot,
        # mouse_moved_event is set to pytplot.hover_time.change_hover_time, so the mouseMovedFunction
        # is pytplot.hover_time.change_hover_time. Thus, whenever change_hover_time is called, it
        # calls every other function that is registered. Since the below function update() is
        # registered as a listener, it'll update whenever hover_time is updated.
        # to the HoverTime class with "t" as the input.

        # TL;DR, t comes from getting the mouse location in pyqtgraph every time the mouse is moved
        # and the below function will update the plot's position as the mouse is moved.
        def update(t, name):
            if name in valid_variables:
                # Get the time closest to the x position the mouse is over.
                time_array = np.array(data[name][2])
                array = np.asarray(time_array)
                idx = (np.abs(array - t)).argmin()

                # If user indicated they wanted the interactive plot's axes to be logged, log 'em.
                # But first make sure that values in x and y are loggable!
                x_axis = False
                y_axis = False
                # Checking x axis
                if np.nanmin(data[name][0][:]) < 0:
                    print('Negative data is incompatible with log plotting.')
                elif np.nanmin(data[name][0][:]) >= 0 and labels[name][2] == 'log':
                    x_axis = True
                # Checking y axis
                if np.nanmin(list(data[name][1][idx])) < 0:
                    print('Negative data is incompatible with log plotting')
                elif np.nanmin(list(data[name][1][idx])) >= 0 and labels[name][3] == 'log':
                    y_axis = True

                # Set plot labels
                plot.setLabel('bottom', '{}'.format(labels[name][0]))
                plot.setLabel('left', '{}'.format(labels[name][1]))
                plot.setLogMode(x=x_axis, y=y_axis)
                # Update x and y range if user modified it
                tplot_utilities.set_x_range(name, x_axis, plot)
                tplot_utilities.set_y_range(name, y_axis, plot)

                if 't_average' in pytplot.data_quants[name].extras:
                    # If the user indicated that they wanted to average the interactive plot's y values based on a
                    # certain time range around the cursor location, we then want to get average of values around
                    # the cursor location.
                    t_min = data[name][2][0]
                    t_max = data[name][2][-1]

                    delta = pytplot.data_quants[name].extras['t_average']/int(2)

                    left_bound = data[name][2][idx] - delta
                    right_bound = data[name][2][idx] + delta

                    if (left_bound - t_min >= 0) and (t_max - right_bound >= 0):
                        # Find index of left and right bounds, no fancy foot work necessary.
                        idx_left = (np.abs(array - left_bound)).argmin()
                        idx_right = (np.abs(array - right_bound)).argmin()
                    elif left_bound - t_min < 0:
                        # Find the number of seconds difference between the cursor's
                        # left bound and the minimum time in the dataset, add that
                        # difference to the right bound time (since you want to push the bound
                        # forward in time, and set the left bound's index to be 0.
                        idx_left = 0
                        diff = right_bound + (t_min - left_bound)
                        idx_right = (np.abs(array - diff)).argmin()
                    elif t_max - right_bound < 0:
                        # Find the number of seconds difference between the cursor's
                        # right bound and the maximum time in the dataset, subtract that
                        # difference from the left bound time (since you want to push the bound
                        # back in time), and set the right bound's index to be -1.
                        idx_right = -1
                        diff = left_bound - (right_bound - t_max)
                        idx_left = (np.abs(array - diff)).argmin()
                    elif (left_bound - t_min < 0) and (t_max - right_bound < 0):
                        # The user is asking to average the entire time frame of the dataset...
                        # dunno why they want that, but if they do, use the time-averaged static plot,
                        # not this.
                        print(
                            'This plot isn\'t appropriate for what you want, use the time-averaged static plot.')

                    # Average values based on the calculated right and left bounds' indices.
                    time_diff = abs(idx_right - idx_left)
                    # Make sure to account for edge problem
                    if idx_right != -1:
                        y_values_slice = data[name][1][idx_left:idx_right + 1]
                    else:
                        y_values_slice = data[name][1][idx_left:]
                    y_values_avgd = np.sum(y_values_slice, axis=0)/np.float(time_diff)

                    # Update x and y range if user modified it
                    tplot_utilities.set_x_range(name, x_axis, plot)
                    tplot_utilities.set_y_range(name, y_axis, plot)

                    try:
                        # Plot data based on time we're hovering over
                        plot_data.setData(data[name][0][:], y_values_avgd)
                    except ZeroDivisionError:
                        pass
                else:
                    # Update x and y range if user modified it
                    tplot_utilities.set_x_range(name, x_axis, plot)
                    tplot_utilities.set_y_range(name, y_axis, plot)
                    # If the user just wants a plain jane interactive plot...
                    # Plot data based on time we're hovering over'
                    try:
                        plot_data.setData(data[name][0][:], list(data[name][1][idx]))
                    except ZeroDivisionError:
                        pass

            else:
                # Cover the situation where you hover over a non-spectrogram plot.
                plot.setLogMode(False, False)
                plot.setLabel('bottom', '')
                plot.setLabel('left', '')
                plot_data.setData([], [])

        # Make the above function called whenever hover_time is updated.
        pytplot.hover_time.register_listener(update)

Response: Create an interactive plot of the current tplot variables.


Instruction:
Can you tell what is the following Python 3 function doing
def get_timespan(name):

    if name not in data_quants.keys():
        print("That name is currently not in pytplot")
        return
    print("Start Time: " + tplot_utilities.int_to_str(data_quants[name].trange[0]))
    print("End Time:   " + tplot_utilities.int_to_str(data_quants[name].trange[1]))

    return(data_quants[name].trange[0], data_quants[name].trange[1])

Response: This function extracts the time span from the Tplot Variables stored in memory. This function returns the time span of the variable that is currently in memory.


Instruction:
Make a summary of the following Python 3 code
def timebar(t, varname = None, databar = False, delete = False, color = 'black', thick = 1, dash = False):

    # make sure t entered is a list
    if not isinstance(t, list):
        t = [t]

    #if entries in list not numerical, run str_to_int
    if not isinstance(t[0], (int, float, complex)):
        t1 = []
        for time in t:
            t1.append(tplot_utilities.str_to_int(time))
        t = t1

    dim = 'height'
    if databar is True:
        dim = 'width'

    dash_pattern = 'solid'
    if dash is True:
        dash_pattern = 'dashed'

    if delete is True:
        tplot_utilities.timebar_delete(t, varname, dim)
        return

    #if no varname specified, add timebars to every plot
    if varname is None:
        num_bars = len(t)
        for i in range(num_bars):
            tbar = {}
            tbar['location'] = t[i]
            tbar['dimension'] = dim
            tbar['line_color'] = pytplot.tplot_utilities.rgb_color(color)

            tbar['line_width'] = thick
            tbar['line_dash'] = dash_pattern
            for name in data_quants:
                temp_data_quants = data_quants[name]
                temp_data_quants.time_bar.append(tbar)
    #if varname specified
    else:
        if not isinstance(varname, list):
            varname = [varname]
        for j in varname:
            if j not in data_quants.keys():
                print(str(j) + "is currently not in pytplot")
            else:
                num_bars = len(t)
                for i in range(num_bars):
                    tbar = {}
                    tbar['location'] = t[i]
                    tbar['dimension'] = dim
                    tbar['line_color'] = pytplot.tplot_utilities.rgb_color(color)
                    tbar['line_width'] = thick
                    tbar['line_dash'] = dash_pattern
                    temp_data_quants = data_quants[j]
                    temp_data_quants.time_bar.append(tbar)
    return

Response: This function will add a vertical bar to all time series plots.


Instruction:
Given the following Python 3 function, write the documentation
def options(name, option, value):

    if not isinstance(name, list):
        name = [name]

    option = option.lower()

    for i in name:
        if i not in data_quants.keys():
            print(str(i) + " is currently not in pytplot.")
            return

        if option == 'color':
            if isinstance(value, list):
                data_quants[i].extras['line_color'] = value
            else:
                data_quants[i].extras['line_color'] = [value]

        if option == 'link':
            if isinstance(value, list):
                data_quants[i].link_to_tvar(value[0], value[1])

        if option == 'colormap':
            if isinstance(value, list):
                data_quants[i].extras['colormap'] = value
            else:
                data_quants[i].extras['colormap'] = [value]

        if option == 'spec':
            _reset_plots(i)
            data_quants[i].extras['spec'] = value

        if option == 'alt':
            _reset_plots(i)
            data_quants[i].extras['alt'] = value

        if option == 'map':
            _reset_plots(i)
            data_quants[i].extras['map'] = value

        if option == 'legend_names':
            data_quants[i].yaxis_opt['legend_names'] = value

        if option == 'xlog_interactive':
            if value:
                data_quants[i].interactive_xaxis_opt['xi_axis_type'] = 'log'
            else:
                data_quants[i].interactive_xaxis_opt['xi_axis_type'] = 'linear'

        if option == 'ylog':
            negflag = _ylog_check(data_quants, value, i)
            if negflag == 0:
                data_quants[i].yaxis_opt['y_axis_type'] = 'log'
            else:
                data_quants[i].yaxis_opt['y_axis_type'] = 'linear'

        if option == 'ylog_interactive':
            if value:
                data_quants[i].interactive_yaxis_opt['yi_axis_type'] = 'log'
            else:
                data_quants[i].interactive_xaxis_opt['xi_axis_type'] = 'linear'

        if option == 'zlog':
            negflag = _zlog_check(data_quants, value, i)
            if negflag == 0:
                data_quants[i].zaxis_opt['z_axis_type'] = 'log'
            else:
                data_quants[i].zaxis_opt['z_axis_type'] = 'linear'

        if option == 'nodata':
            data_quants[i].line_opt['visible'] = value

        if option == 'line_style':
            to_be = []
            if value == 0 or value == 'solid_line':
                to_be = []
            elif value == 1 or value == 'dot':
                to_be = [2, 4]
            elif value == 2 or value == 'dash':
                to_be = [6]
            elif value == 3 or value == 'dash_dot':
                to_be = [6, 4, 2, 4]
            elif value == 4 or value == 'dash_dot_dot_dot':
                to_be = [6, 4, 2, 4, 2, 4, 2, 4]
            elif value == 5 or value == 'long_dash':
                to_be = [10]

            data_quants[i].line_opt['line_dash'] = to_be

            if(value == 6 or value == 'none'):
                data_quants[i].line_opt['visible'] = False

        if option == 'char_size':
            data_quants[i].extras['char_size'] = value

        if option == 'name':
            data_quants[i].line_opt['name'] = value

        if option == "panel_size":
            if value > 1 or value <= 0:
                print("Invalid value. Should be (0, 1]")
                return
            data_quants[i].extras['panel_size'] = value

        if option == 'basemap':
            data_quants[i].extras['basemap'] = value

        if option == 'alpha':
            if value > 1 or value < 0:
                print("Invalid value. Should be [0, 1]")
                return
            data_quants[i].extras['alpha'] = value

        if option == 'thick':
            data_quants[i].line_opt['line_width'] = value

        if option == ('yrange' or 'y_range'):
            data_quants[i].yaxis_opt['y_range'] = [value[0], value[1]]

        if option == ('zrange' or 'z_range'):
            data_quants[i].zaxis_opt['z_range'] = [value[0], value[1]]

        if option == 'xrange_interactive':
            data_quants[i].interactive_xaxis_opt['xi_range'] = [value[0], value[1]]

        if option == 'yrange_interactive':
            data_quants[i].interactive_yaxis_opt['yi_range'] = [value[0], value[1]]

        if option == 'xtitle':
            data_quants[i].xaxis_opt['axis_label'] = value

        if option == 'ytitle':
            data_quants[i].yaxis_opt['axis_label'] = value

        if option == 'ztitle':
            data_quants[i].zaxis_opt['axis_label'] = value

        if option == 'plotter':
            _reset_plots(i)
            data_quants[i].extras['plotter'] = value

        if option == 'crosshair_x':
            data_quants[i].xaxis_opt['crosshair'] = value

        if option == 'crosshair_y':
            data_quants[i].yaxis_opt['crosshair'] = value

        if option == 'crosshair_z':
            data_quants[i].zaxis_opt['crosshair'] = value

        if option == 'static':
            data_quants[i].extras['static'] = value

        if option == 'static_tavg':
            data_quants[i].extras['static_tavg'] = [value[0], value[1]]

        if option == 't_average':
            data_quants[i].extras['t_average'] = value
    return

Response: This function allows the user to set a large variety of options for individual plots.


Instruction:
Can you tell what is the following Python 3 function doing
def tplot_restore(filename):

    #Error check
    if not (os.path.isfile(filename)):
        print("Not a valid file name")
        return

    #Check if the restored file was an IDL file

    if filename.endswith('.tplot'):
        temp_tplot = readsav(filename)
        for i in range(len(temp_tplot['dq'])):
            data_name = temp_tplot['dq'][i][0].decode("utf-8")
            temp_x_data = temp_tplot['dq'][i][1][0][0]
            #Pandas reads in data the other way I guess
            if len(temp_tplot['dq'][i][1][0][2].shape) == 2:
                temp_y_data = np.transpose(temp_tplot['dq'][i][1][0][2])
            else:
                temp_y_data = temp_tplot['dq'][i][1][0][2]

            #If there are more than 4 fields, that means it is a spectrogram
            if len(temp_tplot['dq'][i][1][0]) > 4:
                temp_v_data = temp_tplot['dq'][i][1][0][4]

                #Change from little endian to big endian, since pandas apparently hates little endian
                #We might want to move this into the store_data procedure eventually
                if (temp_x_data.dtype.byteorder == '>'):
                    temp_x_data = temp_x_data.byteswap().newbyteorder()
                if (temp_y_data.dtype.byteorder == '>'):
                    temp_y_data = temp_y_data.byteswap().newbyteorder()
                if (temp_v_data.dtype.byteorder == '>'):
                    temp_v_data = temp_v_data.byteswap().newbyteorder()

                store_data(data_name, data={'x':temp_x_data, 'y':temp_y_data, 'v':temp_v_data})
            else:
                #Change from little endian to big endian, since pandas apparently hates little endian
                #We might want to move this into the store_data procedure eventually
                if (temp_x_data.dtype.byteorder == '>'):
                    temp_x_data = temp_x_data.byteswap().newbyteorder()
                if (temp_y_data.dtype.byteorder == '>'):
                    temp_y_data = temp_y_data.byteswap().newbyteorder()
                store_data(data_name, data={'x':temp_x_data, 'y':temp_y_data})

            if temp_tplot['dq'][i][3].dtype.names is not None:
                for option_name in temp_tplot['dq'][i][3].dtype.names:
                    options(data_name, option_name, temp_tplot['dq'][i][3][option_name][0])

            data_quants[data_name].trange =  temp_tplot['dq'][i][4].tolist()
            data_quants[data_name].dtype =  temp_tplot['dq'][i][5]
            data_quants[data_name].create_time =  temp_tplot['dq'][i][6]

            for option_name in temp_tplot['tv'][0][0].dtype.names:
                if option_name == 'TRANGE':
                    tplot_options('x_range', temp_tplot['tv'][0][0][option_name][0])
                if option_name == 'WSIZE':
                    tplot_options('wsize', temp_tplot['tv'][0][0][option_name][0])
                if option_name == 'VAR_LABEL':
                    tplot_options('var_label', temp_tplot['tv'][0][0][option_name][0])
            if 'P' in temp_tplot['tv'][0][1].tolist():
                for option_name in temp_tplot['tv'][0][1]['P'][0].dtype.names:
                    if option_name == 'TITLE':
                        tplot_options('title', temp_tplot['tv'][0][1]['P'][0][option_name][0])

        #temp_tplot['tv'][0][1] is all of the "settings" variables
            #temp_tplot['tv'][0][1]['D'][0] is "device" options
            #temp_tplot['tv'][0][1]['P'][0] is "plot" options
            #temp_tplot['tv'][0][1]['X'][0] is x axis options
            #temp_tplot['tv'][0][1]['Y'][0] is y axis options
        ####################################################################
    else:
        temp = pickle.load(open(filename,"rb"))
        num_data_quants = temp[0]
        for i in range(0, num_data_quants):
            data_quants[temp[i+1].name] = temp[i+1]
        tplot_opt_glob = temp[num_data_quants+1]

    return

Response: This function will restore the data contained in the IDL file and return the IDL file that was saved with the tplot_save command.


Instruction:
Can you tell what is the following Python 3 function doing
def tplot(name,
          var_label=None,
          auto_color=True,
          interactive=False,
          combine_axes=True,
          nb=False,
          save_file=None,
          gui=False,
          qt=False,
          bokeh=False,
          save_png=None,
          display=True,
          testing=False):
    """
    This is the function used to display the tplot variables stored in memory.
    The default output is to show the plots stacked on top of one another inside a GUI window.
    The GUI window has the option to export the plots in either PNG or HTML formats.

    .. note::
        This plotting routine uses the python Bokeh library, which creates plots using HTML and Javascript.
        Bokeh is technically still in beta, so future patches to Bokeh may require updates to this function.

    Parameters:
        name : str / list
            List of tplot variables that will be plotted
        var_label : str, optional
            The name of the tplot variable you would like as
            a second x axis.
        auto_color : bool, optional
            Automatically color the plot lines.
        interactive : bool, optional
            If True, a secondary interactive plot will be generated next to spectrogram plots.
            Mousing over the spectrogram will display a slice of data from that time on the
            interactive chart.
        combine_axes : bool, optional
            If True, the axes are combined so that they all display the same x range.  This also enables
            scrolling/zooming/panning on one plot to affect all of the other plots simultaneously.
        nb : bool, optional
            If True, the plot will be displayed inside of a current Jupyter notebook session.
        save_file : str, optional
            A full file name and path.
            If this option is set, the plot will be automatically saved to the file name provided in an HTML format.
            The plots can then be opened and viewed on any browser without any requirements.
        bokeh : bool, optional
            If True, plots data using bokeh
            Else (bokeh=False or omitted), plots data using PyQtGraph
        gui : bool, optional
            If True, then this function will output the 2 HTML components of the generated plots as string variables.
            This is useful if you are embedded the plots in your own GUI.  For more information, see
            http://bokeh.pydata.org/en/latest/docs/user_guide/embed.html
        qt : bool, optional
            If True, then this function will display the plot inside of the Qt window.  From this window, you
            can choose to export the plots as either an HTML file, or as a PNG.
        save_png : str, optional
            A full file name and path.
            If this option is set, the plot will be automatically saved to the file name provided in a PNG format.
        display: bool, optional
            If True, then this function will display the plotted tplot variables. Necessary to make this optional
            so we can avoid it in a headless server environment.
        testing: bool, optional
            If True, doesn't run the '(hasattr(sys, 'ps1'))' line that makes plots interactive - i.e., avoiding issues

    Returns:
        None

    Examples:
        >>> #Plot a single line in bokeh
        >>> import pytplot
        >>> x_data = [2,3,4,5,6]
        >>> y_data = [1,2,3,4,5]
        >>> pytplot.store_data("Variable1", data={'x':x_data, 'y':y_data})
        >>> pytplot.tplot("Variable1",bokeh=True)

        >>> #Display two plots
        >>> x_data = [1,2,3,4,5]
        >>> y_data = [[1,5],[2,4],[3,3],[4,2],[5,1]]
        >>> pytplot.store_data("Variable2", data={'x':x_data, 'y':y_data})
        >>> pytplot.tplot(["Variable1", "Variable2"])

        >>> #Display 2 plots, using Variable1 as another x axis
        >>> x_data = [1,2,3]
        >>> y_data = [ [1,2,3] , [4,5,6], [7,8,9] ]
        >>> v_data = [1,2,3]
        >>> pytplot.store_data("Variable3", data={'x':x_data, 'y':y_data, 'v':v_data})
        >>> pytplot.options("Variable3", 'spec', 1)
        >>> pytplot.tplot(["Variable2", "Variable3"], var_label='Variable1')

        >>> #Plot all 3 tplot variables, sending the output to an HTML file
        >>> pytplot.tplot(["Variable1", "Variable2", "Variable3"], save_file='C:/temp/pytplot_example.html')

        >>> #Plot all 3 tplot variables, sending the HTML output to a pair of strings
        >>> div, component = pytplot.tplot(["Variable1", "Variable2", "Variable3"], gui=True)
    """

    if not pytplot.using_graphics and save_file is None:
        print("Qt was not successfully imported.  Specify save_file to save the file as a .html file.")
        return
    # Check a bunch of things
    if not isinstance(name, list):
        name = [name]
        num_plots = 1
    else:
        num_plots = len(name)

    for i in range(num_plots):
        if isinstance(name[i], int):
            name[i] = list(pytplot.data_quants.keys())[name[i]]
        if name[i] not in pytplot.data_quants.keys():
            print(str(i) + " is currently not in pytplot")
            return

    if isinstance(var_label, int):
        var_label = list(pytplot.data_quants.keys())[var_label]

    if bokeh:
        layout = HTMLPlotter.generate_stack(name, var_label=var_label, auto_color=auto_color, combine_axes=combine_axes,
                                            interactive=interactive)
        # Output types
        if gui:
            script, div = components(layout)
            return script, div
        elif nb:
            output_notebook()
            show(layout)
            return
        elif save_file is not None:
            output_file(save_file, mode='inline')
            save(layout)
            return
        elif qt:
            available_qt_window = tplot_utilities.get_available_qt_window()
            dir_path = tempfile.gettempdir()  # send to user's temp directory
            output_file(os.path.join(dir_path, "temp.html"), mode='inline')
            save(layout)
            new_layout = WebView()
            available_qt_window.resize(pytplot.tplot_opt_glob['window_size'][0] + 100,
                                       pytplot.tplot_opt_glob['window_size'][1] + 100)
            new_layout.resize(pytplot.tplot_opt_glob['window_size'][0], pytplot.tplot_opt_glob['window_size'][1])
            dir_path = tempfile.gettempdir()  # send to user's temp directory
            new_layout.setUrl(QtCore.QUrl.fromLocalFile(os.path.join(dir_path, "temp.html")))
            available_qt_window.newlayout(new_layout)
            available_qt_window.show()
            available_qt_window.activateWindow()
            if testing:
                return
            if not (hasattr(sys, 'ps1')) or not hasattr(QtCore, 'PYQT_VERSION'):
                QtGui.QApplication.instance().exec_()
            return
        else:
            dir_path = tempfile.gettempdir()  # send to user's temp directory
            output_file(os.path.join(dir_path, "temp.html"), mode='inline')
            show(layout)
            return
    else:
        if save_png is not None:
            layout = QtPlotter.generate_stack(name, var_label=var_label, combine_axes=combine_axes,
                                              mouse_moved_event=pytplot.hover_time.change_hover_time)
            layout.resize(pytplot.tplot_opt_glob['window_size'][0], pytplot.tplot_opt_glob['window_size'][1])
            for i, item in enumerate(layout.items()):
                if type(item) == pg.graphicsItems.GraphicsLayout.GraphicsLayout:
                    layout.items()[i].resize(pytplot.tplot_opt_glob['window_size'][0],
                                             pytplot.tplot_opt_glob['window_size'][1])
            exporter = PyTPlot_Exporter.PytplotExporter(layout)
            exporter.parameters()['width'] = pytplot.tplot_opt_glob['window_size'][0]
            exporter.parameters()['height'] = pytplot.tplot_opt_glob['window_size'][1]
            exporter.export(save_png)

        if display:
            # Set up all things needed for when a user asks to save plot from window
            layout_orig = QtPlotter.generate_stack(name, var_label=var_label, combine_axes=combine_axes,
                                                   mouse_moved_event=pytplot.hover_time.change_hover_time)
            layout_orig.resize(pytplot.tplot_opt_glob['window_size'][0], pytplot.tplot_opt_glob['window_size'][1])
            for i, item in enumerate(layout_orig.items()):
                if type(item) == pg.graphicsItems.GraphicsLayout.GraphicsLayout:
                    layout_orig.items()[i].resize(pytplot.tplot_opt_glob['window_size'][0],
                                                  pytplot.tplot_opt_glob['window_size'][1])
            exporter = QtPlotter.PytplotExporter(layout_orig)

            # Set up displayed plot window and grab plots to plot on it
            available_qt_window = tplot_utilities.get_available_qt_window()
            layout = QtPlotter.generate_stack(name, var_label=var_label, combine_axes=combine_axes,
                                              mouse_moved_event=pytplot.hover_time.change_hover_time)

            available_qt_window.newlayout(layout)
            available_qt_window.resize(pytplot.tplot_opt_glob['window_size'][0],
                                       pytplot.tplot_opt_glob['window_size'][1])

            # Implement button that lets you save the PNG
            available_qt_window.init_savepng(exporter)

            # Show the plot window and plot
            available_qt_window.show()
            available_qt_window.activateWindow()

            if interactive:
                # Call 2D interactive window; This will only plot something when spectrograms are involved.
                interactiveplot.interactiveplot()

            static_list = [i for i in name if 'static' in pytplot.data_quants[i].extras]
            for tplot_var in static_list:
                # Call 2D static window; This will only plot something when spectrograms are involved.
                staticplot.static2dplot(tplot_var, pytplot.data_quants[tplot_var].extras['static'])

            static_tavg_list = [i for i in name if 'static_tavg' in pytplot.data_quants[i].extras]
            for tplot_var in static_tavg_list:
                # Call 2D static window for time-averaged values; This will only plot something when spectrograms
                # are involved
                staticplot_tavg.static2dplot_timeaveraged(
                    tplot_var, pytplot.data_quants[tplot_var].extras['static_tavg'])

            # (hasattr(sys, 'ps1')) checks to see if we're in ipython
            # plots the plots!
            if testing:
                return
            if not (hasattr(sys, 'ps1')) or not hasattr(QtCore, 'PYQT_VERSION'):
                QtGui.QApplication.instance().exec_()

        return

Response: This function displays the tplot variables stored in memory.


Instruction:
Here you have a function in Python 3, explain what it does
def static2dplot_timeaveraged(var, time):

    # Grab names of data loaded in as tplot variables.
    names = list(pytplot.data_quants.keys())
    # Get data we'll actually work with here.
    valid_variables = tplot_utilities.get_data(names)

    # Don't plot anything unless we have spectrograms with which to work.
    if valid_variables:
        # Get z label
        labels = tplot_utilities.get_labels_axis_types(names)

        # Put together data in easy-to-access format for plots.
        data = {}
        for name in valid_variables:
            bins = tplot_utilities.get_bins(name)
            time_values, z_values = tplot_utilities.get_z_t_values(name)
            data[name] = [bins, z_values, time_values]

        # Set up the 2D static plot
        pytplot.static_tavg_window = pg.GraphicsWindow()
        pytplot.static_tavg_window.resize(1000, 600)
        pytplot.static_tavg_window.setWindowTitle('Time-Averaged Values Static Window')
        plot = pytplot.static_tavg_window.addPlot(title='2D Static Plot for Time-Averaged Values', row=0, col=0)
        # Make it so that whenever this first starts up, you just have an empty plot
        plot_data = plot.plot([], [])

        if var in valid_variables:
            # Get min/max values of data's time range (in both datetime and seconds since epoch)
            t_min = np.nanmin(time_values)
            t_min_str = tplot_utilities.int_to_str(np.nanmin(time_values))
            t_min_conv_back = tplot_utilities.str_to_int(t_min_str)
            t_max = np.nanmax(time_values)
            t_max_str = tplot_utilities.int_to_str(np.nanmax(time_values))
            t_max_conv_back = tplot_utilities.str_to_int(t_max_str)
            # Convert user input to seconds since epoch
            user_time = [tplot_utilities.str_to_int(i) for i in time]

            # Covering situation where user entered a time not in the dataset!
            # As long as they used a time in the dataset, this will not trigger.
            for t, datetime in enumerate(user_time):
                if datetime not in range(t_min_conv_back, t_max_conv_back+1):
                    while True:
                        try:
                            if t == 0:
                                time_bound = 'left bound'
                            else:
                                time_bound = 'right bound'
                            user_time[t] = tplot_utilities.str_to_int(input(
                                'Chosen {} time [{}] not in range of data [{} to {}]. Input new time (%Y-%m-%d %H:%M:%S).'.format(
                                    time_bound, tplot_utilities.int_to_str(datetime), t_min_str, t_max_str)))
                        except ValueError:
                            continue
                        else:
                            if user_time[t] not in range(int(t_min), int(t_max)):
                                continue
                            else:
                                break

            # Get index of the time closest to the user's time choice
            time_array = np.array(data[var][2])
            array = np.asarray(time_array)
            idx = [(np.abs(array - i)).argmin() for i in user_time]

            # Average values based on the chosen time range's indices
            time_diff = abs(idx[0]-idx[1])
            # Make sure to account for edge problem
            if idx[1] != -1:
                y_values_slice = data[name][1][idx[0]:idx[1]+1]
            else:
                y_values_slice = data[name][1][idx[0]:]
            y_values_avgd = np.nansum(y_values_slice, axis=0)/np.float(time_diff)

            # If user indicated they wanted the interactive plot's axes to be logged, log 'em.
            # But first make sure that values in x and y are loggable!
            x_axis = False
            y_axis = False
            # Checking x axis
            if np.nanmin(data[name][0][:]) < 0:
                print('Negative data is incompatible with log plotting.')
            elif np.nanmin(data[name][0][:]) >= 0 and labels[name][2] == 'log':
                x_axis = True
            # Checking y axis
            if np.nanmin(list(data[name][1][idx[0]])) < 0 or np.nanmin(list(data[name][1][idx[1]])) < 0:
                print('Negative data is incompatible with log plotting')
            elif np.nanmin(list(data[name][1][idx[0]])) >= 0 and np.nanmin(list(data[name][1][idx[1]])) >= 0 and \
                    labels[name][3] == 'log':
                y_axis = True

            # Set plot labels
            plot.setLabel('bottom', '{}'.format(labels[name][0]))
            plot.setLabel('left', '{}'.format(labels[name][1]))
            plot.setLogMode(x=x_axis, y=y_axis)
            # Update x and y range if user modified it
            tplot_utilities.set_x_range(name, x_axis, plot)
            tplot_utilities.set_y_range(name, y_axis, plot)
            # Plot data based on time we're hovering over
            plot_data.setData(data[var][0][:], y_values_avgd)

Response: This function will plot the static 2D static plot for the specified variable and time.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def timestamp(val):

    if val is 'on':
        todaystring = datetime.datetime.now().strftime('%Y-%m-%d %H%M%S')
        extra_layouts['time_stamp'] = todaystring
    else:
        if 'time_stamp' in extra_layouts:
            del extra_layouts['time_stamp']

    return

Response: This function will turn on a time stamp that shows up at the bottom of every generated plot.


Instruction:
How would you explain what the following Python 3 function does
def paint(self, p, *args):
        '''
        I have no idea why, but we need to generate the picture after painting otherwise
        it draws incorrectly.
        '''
        if self.picturenotgened:
            self.generatePicture(self.getBoundingParents()[0].rect())
            self.picturenotgened = False
        pg.ImageItem.paint(self, p, *args)
        self.generatePicture(self.getBoundingParents()[0].rect())

Response: This method is called by the PGImageItem class when painting. It generates the picture if needed.


Instruction:
Write a Python 3 function that can
set the image of the item.

Response:
def setImage(self, image=None, autoLevels=None, **kargs):
        """
        Same this as ImageItem.setImage, but we don't update the drawing
        """

        profile = debug.Profiler()

        gotNewData = False
        if image is None:
            if self.image is None:
                return
        else:
            gotNewData = True
            shapeChanged = (self.image is None or image.shape != self.image.shape)
            image = image.view(np.ndarray)
            if self.image is None or image.dtype != self.image.dtype:
                self._effectiveLut = None
            self.image = image
            if self.image.shape[0] > 2**15-1 or self.image.shape[1] > 2**15-1:
                if 'autoDownsample' not in kargs:
                    kargs['autoDownsample'] = True
            if shapeChanged:
                self.prepareGeometryChange()
                self.informViewBoundsChanged()

        profile()

        if autoLevels is None:
            if 'levels' in kargs:
                autoLevels = False
            else:
                autoLevels = True
        if autoLevels:
            img = self.image
            while img.size > 2**16:
                img = img[::2, ::2]
            mn, mx = img.min(), img.max()
            if mn == mx:
                mn = 0
                mx = 255
            kargs['levels'] = [mn,mx]

        profile()

        self.setOpts(update=False, **kargs)

        profile()

        self.qimage = None
        self.update()

        profile()

        if gotNewData:
            self.sigImageChanged.emit()


Instruction:
How would you explain what the following Python 3 function does
def getPaintItems(self, root=None):
        if root is None:
            root = self.item
        preItems = []
        postItems = []
        if isinstance(root, QtGui.QGraphicsScene):
            childs = [i for i in root.items() if i.parentItem() is None]
            rootItem = []
        else:
            # CHANGE: For GraphicsLayouts, there is no function for childItems(), so I just
            # replaced it with .items()
            try:
                childs = root.childItems()
            except:
                childs = root.items()
            rootItem = [root]
        childs.sort(key=lambda a: a.zValue())
        while len(childs) > 0:
            ch = childs.pop(0)
            tree = self.getPaintItems(ch)

            if int(ch.flags() & ch.ItemStacksBehindParent) > 0 or (
                    ch.zValue() < 0 and int(ch.flags() & ch.ItemNegativeZStacksBehindParent) > 0):
                preItems.extend(tree)
            else:
                postItems.extend(tree)
        return preItems + rootItem + postItems

Response: Return a list of all items that should be painted in the correct order.


Instruction:
Can you create a Python 3 function that
runs normalization on a network.

Response:
def run_norm(net, df=None, norm_type='zscore', axis='row', keep_orig=False):
  '''
  A dataframe (more accurately a dictionary of dataframes, e.g. mat,
  mat_up...) can be passed to run_norm and a normalization will be run (
  e.g. zscore) on either the rows or columns
  '''

  # df here is actually a dictionary of several dataframes, 'mat', 'mat_orig',
  # etc
  if df is None:
    df = net.dat_to_df()

  if norm_type == 'zscore':
    df = zscore_df(df, axis, keep_orig)

  if norm_type == 'qn':
    df = qn_df(df, axis, keep_orig)

  net.df_to_dat(df)


Instruction:
Can you generate the documentation for the following Python 3 function
def qn_df(df, axis='row', keep_orig=False):
  '''
  do quantile normalization of a dataframe dictionary, does not write to net
  '''
  df_qn = {}

  for mat_type in df:
    inst_df = df[mat_type]

    # using transpose to do row qn
    if axis == 'row':
      inst_df = inst_df.transpose()

    missing_values = inst_df.isnull().values.any()

    # make mask of missing values
    if missing_values:

      # get nan mask
      missing_mask = pd.isnull(inst_df)

      # tmp fill in na with zero, will not affect qn
      inst_df = inst_df.fillna(value=0)

    # calc common distribution
    common_dist = calc_common_dist(inst_df)

    # swap in common distribution
    inst_df = swap_in_common_dist(inst_df, common_dist)

    # swap back in missing values
    if missing_values:
      inst_df = inst_df.mask(missing_mask, other=np.nan)

    # using transpose to do row qn
    if axis == 'row':
      inst_df = inst_df.transpose()

    df_qn[mat_type] = inst_df

  return df_qn

Response: do quantile normalization of a dataframe dictionary does not write to net


Instruction:
Can you tell what is the following Python 3 function doing
def calc_common_dist(df):
  '''
  calculate a common distribution (for col qn only) that will be used to qn
  '''

  # axis is col
  tmp_arr = np.array([])

  col_names = df.columns.tolist()

  for inst_col in col_names:

    # sort column
    tmp_vect = df[inst_col].sort_values(ascending=False).values

    # stacking rows vertically (will transpose)
    if tmp_arr.shape[0] == 0:
      tmp_arr = tmp_vect
    else:
      tmp_arr = np.vstack((tmp_arr, tmp_vect))

  tmp_arr = tmp_arr.transpose()

  common_dist = tmp_arr.mean(axis=1)

  return common_dist

Response: calculate a common distribution for col qn only


Instruction:
Explain what the following Python 3 code does
def zscore_df(df, axis='row', keep_orig=False):
  '''
  take the zscore of a dataframe dictionary, does not write to net (self)
  '''
  df_z = {}

  for mat_type in df:
    if keep_orig and mat_type == 'mat':
      mat_orig = deepcopy(df[mat_type])

    inst_df = df[mat_type]

    if axis == 'row':
      inst_df = inst_df.transpose()

    df_z[mat_type] = (inst_df - inst_df.mean())/inst_df.std()

    if axis == 'row':
      df_z[mat_type] = df_z[mat_type].transpose()

  if keep_orig:
    df_z['mat_orig'] = mat_orig

  return df_z

Response: take the zscore of a dataframe dictionary does not write to net


Instruction:
Create a Python 3 function to
calculate pvalue of category closeness → calculate pvalue of category closeness → calculate pvalue of category closeness → calculate pvalue of category closeness → calculate pvalue of category closeness → calculate pvalue of category closeness → calculate pvalue of category closeness → calculate pvalue of category closeness

Response:
def main(net):
  '''
  calculate pvalue of category closeness
  '''
  # calculate the distance between the data points within the same category and
  # compare to null distribution
  for inst_rc in ['row', 'col']:

    inst_nodes = deepcopy(net.dat['nodes'][inst_rc])

    inst_index = deepcopy(net.dat['node_info'][inst_rc]['clust'])

    # reorder based on clustered order
    inst_nodes = [ inst_nodes[i] for i in inst_index]

    # make distance matrix dataframe
    dm = dist_matrix_lattice(inst_nodes)

    node_infos = list(net.dat['node_info'][inst_rc].keys())

    all_cats = []
    for inst_info in node_infos:
      if 'dict_cat_' in inst_info:
        all_cats.append(inst_info)

    for cat_dict in all_cats:

      tmp_dict = net.dat['node_info'][inst_rc][cat_dict]

      pval_name = cat_dict.replace('dict_','pval_')
      net.dat['node_info'][inst_rc][pval_name] = {}

      for cat_name in tmp_dict:

        subset = tmp_dict[cat_name]

        inst_median = calc_median_dist_subset(dm, subset)

        hist = calc_hist_distances(dm, subset, inst_nodes)

        pval = 0

        for i in range(len(hist['prob'])):
          if i == 0:
            pval = hist['prob'][i]
          if i >= 1:
            if inst_median >= hist['bins'][i]:
              pval = pval + hist['prob'][i]

        net.dat['node_info'][inst_rc][pval_name][cat_name] = pval


Instruction:
Make a summary of the following Python 3 code
def df_to_dat(net, df, define_cat_colors=False):
  '''
  This is always run when data is loaded.
  '''
  from . import categories

  # check if df has unique values
  df['mat'] = make_unique_labels.main(net, df['mat'])

  net.dat['mat'] = df['mat'].values
  net.dat['nodes']['row'] = df['mat'].index.tolist()
  net.dat['nodes']['col'] = df['mat'].columns.tolist()

  for inst_rc in ['row', 'col']:

    if type(net.dat['nodes'][inst_rc][0]) is tuple:
      # get the number of categories from the length of the tuple
      # subtract 1 because the name is the first element of the tuple
      num_cat = len(net.dat['nodes'][inst_rc][0]) - 1

      net.dat['node_info'][inst_rc]['full_names'] = net.dat['nodes']\
          [inst_rc]

      for inst_rcat in range(num_cat):
        net.dat['node_info'][inst_rc]['cat-' + str(inst_rcat)] = \
          [i[inst_rcat + 1] for i in net.dat['nodes'][inst_rc]]

      net.dat['nodes'][inst_rc] = [i[0] for i in net.dat['nodes'][inst_rc]]

  if 'mat_up' in df:
    net.dat['mat_up'] = df['mat_up'].values
    net.dat['mat_dn'] = df['mat_dn'].values

  if 'mat_orig' in df:
    net.dat['mat_orig'] = df['mat_orig'].values

  categories.dict_cat(net, define_cat_colors=define_cat_colors)

Response: This function takes a DataFrame and converts it to a dictionary of data structures.


Instruction:
Create a Python 3 function to
convert list to numpy array

Response:
def mat_to_numpy_arr(self):
  ''' convert list to numpy array - numpy arrays can not be saved as json '''
  import numpy as np
  self.dat['mat'] = np.asarray(self.dat['mat'])


Instruction:
Write a Python 3 function for
clustering net. dat and make visualization json and net. viz.

Response:
def cluster_row_and_col(net, dist_type='cosine', linkage_type='average',
                        dendro=True, run_clustering=True, run_rank=True,
                        ignore_cat=False, calc_cat_pval=False, links=False):
  ''' cluster net.dat and make visualization json, net.viz.
  optionally leave out dendrogram colorbar groups with dendro argument '''

  import scipy
  from copy import deepcopy
  from scipy.spatial.distance import pdist
  from . import categories, make_viz, cat_pval

  dm = {}
  for inst_rc in ['row', 'col']:

    tmp_mat = deepcopy(net.dat['mat'])
    dm[inst_rc] = calc_distance_matrix(tmp_mat, inst_rc, dist_type)

    # save directly to dat structure
    node_info = net.dat['node_info'][inst_rc]

    node_info['ini'] = list(range( len(net.dat['nodes'][inst_rc]), -1, -1))

    # cluster
    if run_clustering is True:
      node_info['clust'], node_info['group'] = \
          clust_and_group(net, dm[inst_rc], linkage_type=linkage_type)
    else:
      dendro = False
      node_info['clust'] = node_info['ini']

    # sorting
    if run_rank is True:
      node_info['rank'] = sort_rank_nodes(net, inst_rc, 'sum')
      node_info['rankvar'] = sort_rank_nodes(net, inst_rc, 'var')
    else:
      node_info['rank'] = node_info['ini']
      node_info['rankvar'] = node_info['ini']

    ##################################
    if ignore_cat is False:
      categories.calc_cat_clust_order(net, inst_rc)

  if calc_cat_pval is True:
    cat_pval.main(net)

  # make the visualization json
  make_viz.viz_json(net, dendro, links)

  return dm


Instruction:
Write a Python 3 function for
finding out how many row and col categories are available °C

Response:
def check_categories(lines):
  '''
  find out how many row and col categories are available
  '''
  # count the number of row categories
  rcat_line = lines[0].split('\t')

  # calc the number of row names and categories
  num_rc = 0
  found_end = False

  # skip first tab
  for inst_string in rcat_line[1:]:
    if inst_string == '':
      if found_end is False:
        num_rc = num_rc + 1
    else:
      found_end = True

  max_rcat = 15
  if max_rcat > len(lines):
    max_rcat = len(lines) - 1

  num_cc = 0
  for i in range(max_rcat):
    ccat_line = lines[i + 1].split('\t')

    # make sure that line has length greater than one to prevent false cats from
    # trailing new lines at end of matrix
    if ccat_line[0] == '' and len(ccat_line) > 1:
      num_cc = num_cc + 1

  num_labels = {}
  num_labels['row'] = num_rc + 1
  num_labels['col'] = num_cc + 1

  return num_labels


Instruction:
Here you have a function in Python 3, explain what it does
def dict_cat(net, define_cat_colors=False):
  '''
  make a dictionary of node-category associations
  '''

  # print('---------------------------------')
  # print('---- dict_cat: before setting cat colors')
  # print('---------------------------------\n')
  # print(define_cat_colors)
  # print(net.viz['cat_colors'])

  net.persistent_cat = True

  for inst_rc in ['row', 'col']:
    inst_keys = list(net.dat['node_info'][inst_rc].keys())
    all_cats = [x for x in inst_keys if 'cat-' in x]

    for inst_name_cat in all_cats:

      dict_cat = {}
      tmp_cats = net.dat['node_info'][inst_rc][inst_name_cat]
      tmp_nodes = net.dat['nodes'][inst_rc]

      for i in range(len(tmp_cats)):
        inst_cat = tmp_cats[i]
        inst_node = tmp_nodes[i]

        if inst_cat not in dict_cat:
          dict_cat[inst_cat] = []

        dict_cat[inst_cat].append(inst_node)

      tmp_name = 'dict_' + inst_name_cat.replace('-', '_')
      net.dat['node_info'][inst_rc][tmp_name] = dict_cat

  # merge with old cat_colors by default
  cat_colors = net.viz['cat_colors']

  if define_cat_colors == True:
    cat_number = 0

    for inst_rc in ['row', 'col']:

      inst_keys = list(net.dat['node_info'][inst_rc].keys())
      all_cats = [x for x in inst_keys if 'cat-' in x]

      for cat_index in all_cats:

        if cat_index not in cat_colors[inst_rc]:
          cat_colors[inst_rc][cat_index] = {}

        cat_names = sorted(list(set(net.dat['node_info'][inst_rc][cat_index])))

        # loop through each category name and assign a color
        for tmp_name in cat_names:

          # using the same rules as the front-end to define cat_colors
          inst_color = get_cat_color(cat_number + cat_names.index(tmp_name))

          check_name = tmp_name

          # check if category is string type and non-numeric
          try:
            float(check_name)
            is_string_cat = False
          except:
            is_string_cat = True

          if is_string_cat == True:
            # check for default non-color
            if ': ' in check_name:
              check_name = check_name.split(': ')[1]

            # if check_name == 'False' or check_name == 'false':
            if 'False' in check_name or 'false' in check_name:
              inst_color = '#eee'

            if 'Not ' in check_name:
              inst_color = '#eee'

          # print('cat_colors')
          # print('----------')
          # print(cat_colors[inst_rc][cat_index])

          # do not overwrite old colors
          if tmp_name not in cat_colors[inst_rc][cat_index] and is_string_cat:

            cat_colors[inst_rc][cat_index][tmp_name] = inst_color
            # print('overwrite: ' + tmp_name + ' -> ' + str(inst_color))

          cat_number = cat_number + 1

    net.viz['cat_colors'] = cat_colors

Response:
make a dictionary of node - category associations
 °C


Instruction:
Can you implement a function in Python 3 that
calculates the clustering ordering of the cluster categories in the given node info.

Response:
def calc_cat_clust_order(net, inst_rc):
  '''
  cluster category subset of data
  '''
  from .__init__ import Network
  from copy import deepcopy
  from . import calc_clust, run_filter

  inst_keys = list(net.dat['node_info'][inst_rc].keys())
  all_cats = [x for x in inst_keys if 'cat-' in x]

  if len(all_cats) > 0:

    for inst_name_cat in all_cats:

      tmp_name = 'dict_' + inst_name_cat.replace('-', '_')
      dict_cat = net.dat['node_info'][inst_rc][tmp_name]

      unordered_cats = dict_cat.keys()

      ordered_cats = order_categories(unordered_cats)

      # this is the ordering of the columns based on their category, not
      # including their clustering ordering within category
      all_cat_orders = []
      tmp_names_list = []
      for inst_cat in ordered_cats:

        inst_nodes = dict_cat[inst_cat]

        tmp_names_list.extend(inst_nodes)

      #   cat_net = deepcopy(Network())

      #   cat_net.dat['mat'] = deepcopy(net.dat['mat'])
      #   cat_net.dat['nodes'] = deepcopy(net.dat['nodes'])

      #   cat_df = cat_net.dat_to_df()

      #   sub_df = {}
      #   if inst_rc == 'col':
      #     sub_df['mat'] = cat_df['mat'][inst_nodes]
      #   elif inst_rc == 'row':
      #     # need to transpose df
      #     cat_df['mat'] = cat_df['mat'].transpose()
      #     sub_df['mat'] = cat_df['mat'][inst_nodes]
      #     sub_df['mat'] = sub_df['mat'].transpose()

      #   # filter matrix before clustering
      #   ###################################
      #   threshold = 0.0001
      #   sub_df = run_filter.df_filter_row_sum(sub_df, threshold)
      #   sub_df = run_filter.df_filter_col_sum(sub_df, threshold)

      #   # load back to dat
      #   cat_net.df_to_dat(sub_df)

      #   cat_mat_shape = cat_net.dat['mat'].shape

      #   print('***************')
      #   try:
      #     if cat_mat_shape[0]>1 and cat_mat_shape[1] > 1 and all_are_numbers == False:

      #       calc_clust.cluster_row_and_col(cat_net, 'cos')
      #       inst_cat_order = cat_net.dat['node_info'][inst_rc]['clust']
      #     else:
      #       inst_cat_order = list(range(len(cat_net.dat['nodes'][inst_rc])))

      #   except:
      #     inst_cat_order = list(range(len(cat_net.dat['nodes'][inst_rc])))

      #   prev_order_len = len(all_cat_orders)

      #   # add prev order length to the current order number
      #   inst_cat_order = [i + prev_order_len for i in inst_cat_order]
      #   all_cat_orders.extend(inst_cat_order)

      # # generate ordered list of row/col names, which will be used to
      # # assign the order to specific nodes
      # names_clust_list = [x for (y, x) in sorted(zip(all_cat_orders,
      #                     tmp_names_list))]

      names_clust_list = tmp_names_list

      # calc category-cluster order
      final_order = []

      for i in range(len(net.dat['nodes'][inst_rc])):

        inst_node_name = net.dat['nodes'][inst_rc][i]
        inst_node_num = names_clust_list.index(inst_node_name)

        final_order.append(inst_node_num)

      inst_index_cat = inst_name_cat.replace('-', '_') + '_index'

      net.dat['node_info'][inst_rc][inst_index_cat] = final_order