Instruction:
Implement a function in Python 3 to
get the display colour of a component.

Response:
def get_colour(self, c, default='#eeeeee', match_only=None):
        """
        Get the display colour of a component. Wraps `getattr()`.

        Development note:
            Cannot define this as a `partial()` because I want
            to maintain the order of arguments in `getattr()`.

        Args:
           c (component): The component to look up.
           default (str): The colour to return in the event of no match.
           match_only (list of str): The component attributes to include in the
               comparison. Default: All of them.

        Returns:
           str. The hex string of the matching Decor in the Legend.
        """
        return self.getattr(c=c,
                            attr='colour',
                            default=default,
                            match_only=match_only)


Instruction:
Implement a Python 3 function for
getting the display width of a component.

Response:
def get_width(self, c, default=0, match_only=None):
        """
        Get the display width of a component. Wraps `getattr()`.

        Development note: Cannot define this as a `partial()` because I want
        to maintain the order of arguments in `getattr()`.

        Args:
            c (component): The component to look up.
            default (float): The width to return in the event of no match.
            match_only (list of str): The component attributes to include in the
                comparison. Default: All of them.

        Returns:
            float. The width of the matching Decor in the Legend.
        """
        return self.getattr(c=c,
                            attr='width',
                            default=default,
                            match_only=match_only)


Instruction:
Make a summary of the following Python 3 code
def get_component(self, colour, tolerance=0, default=None):
        if not (0 <= tolerance <= np.sqrt(195075)):
            raise LegendError('Tolerance must be between 0 and 441.67')

        for decor in self.__list:
            if colour.lower() == decor.colour:
                return decor.component

        # If we're here, we didn't find one yet.
        r1, g1, b1 = utils.hex_to_rgb(colour)

        # Start with a best match of black.
        best_match = '#000000'
        best_match_dist = np.sqrt(r1**2. + g1**2. + b1**2.)

        # Now compare to each colour in the legend.
        for decor in self.__list:
            r2, g2, b2 = decor.rgb
            distance = np.sqrt((r2-r1)**2. + (g2-g1)**2. + (b2-b1)**2.)
            if distance < best_match_dist:
                best_match = decor.component
                best_match_dist = distance
                best_match_colour = decor.colour

        if best_match_dist <= tolerance:
            return best_match
        else:
            with warnings.catch_warnings():
                warnings.simplefilter("always")
                w = "No match found for {0} ".format(colour.lower())
                w += "with tolerance of {0}. Best match is ".format(tolerance)
                w += "{0}, {1}".format(best_match.summary(), best_match_colour)
                w += ", d={0}".format(best_match_dist)
                warnings.warn(w)

            return default

Response: This method returns the component corresponding to a colour. This method is used to get the component corresponding to a display colour. This method is used to get the component corresponding to a colour. This method is used to get the component corresponding to a colour. This method is used to get the component corresponding to a display colour.


Instruction:
Can you tell what is the following Python 3 function doing
def plot(self, fmt=None):
        for d in self.__list:
            d.plot(fmt=fmt)

        return None

Response: Make a simple plot of the current set of items.


Instruction:
Explain what the following Python 3 code does
def _repr_html_(self):
        rows = ''
        s = '
{k}	{v}
'
        for k, v in self.__dict__.items():
            rows += s.format(k=k, v=v)
        html = '
{}
'.format(rows)
        return html

Response: Jupyter Notebook magic repr function.


Instruction:
Make a summary of the following Python 3 code
def from_text(cls, text, lexicon, required=None, first_only=True):
        component = lexicon.get_component(text, first_only=first_only)
        if required and (required not in component):
            return None
        else:
            return cls(component)

Response: Generates a Component object from a text string using a Lexicon.


Instruction:
How would you explain what the following Python 3 function does
def summary(self, fmt=None, initial=True, default=''):
        if default and not self.__dict__:
            return default

        if fmt == '':
            return default

        keys = [k for k, v in self.__dict__.items() if v is not '']

        f = fmt or '{' + '}, {'.join(keys) + '}'

        try:
            summary = CustomFormatter().format(f, **self.__dict__)
        except KeyError as e:
            raise ComponentError("Error building summary, "+str(e))

        if summary and initial and not fmt:
            summary = summary[0].upper() + summary[1:]

        return summary

Response: Returns a summary string of a component.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def Rock(*args, **kwargs):

    with warnings.catch_warnings():
        warnings.simplefilter("always")
        w = "The 'Rock' class was renamed 'Component'. "
        w += "Please update your code."
        warnings.warn(w, DeprecationWarning, stacklevel=2)

    return Component(*args, **kwargs)

Response: Deprecated. Use Component instead.


Instruction:
Implement a function in Python 3 to
process a single row from the file.

Response:
def _process_row(text, columns):
    """
    Processes a single row from the file.
    """
    if not text:
        return

    # Construct the column dictionary that maps each field to
    # its start, its length, and its read and write functions.
    coldict = {k: {'start': s,
                   'len': l,
                   'read': r,
                   'write': w} for k, (s, l, r, w) in columns.items()}

    # Now collect the item
    item = {}
    for field in coldict:
        value = _get_field(text, coldict, field)
        if value is not None:
            item[field] = value

    return item


Instruction:
How would you explain what the following Python 3 function does
def parse_canstrat(text):
    result = {}
    for row in text.split('\n'):
        if not row:
            continue

        if len(row) < 8:  # Not a real record.
            continue

        # Read the metadata for this row/
        row_header = _process_row(row, columns_) or {'card': None}
        card = row_header['card']

        # Now we know the card type for this row, we can process it.
        if card is not None:
            item = _process_row(row, columns[card])

        this_list = result.get(card, [])
        this_list.append(item)
        result[card] = this_list

    # Flatten if possible.
    for c, d in result.items():
        if len(d) == 1:
            result[c] = d[0]

    return result

Response: Read all the rows and return a dict of the results.


Instruction:
Implement a function in Python 3 to
get the template from the given name.

Response:
def get_template(name):
    """
    Still unsure about best way to do this, hence cruft.
    """
    text = re.sub(r'\r\n', r'\n', name)
    text = re.sub(r'\{([FISDE°].*?)\}', r'{{\1}}', text)
    return text


Instruction:
Can you tell what is the following Python 3 function doing
def unique(self):
        all_rx = set([iv.primary for iv in self])
        table = {r: 0 for r in all_rx}
        for iv in self:
            table[iv.primary] += iv.thickness

        return sorted(table.items(), key=operator.itemgetter(1), reverse=True)

Response: Property. Summarize a Striplog with some statistics.


Instruction:
Can you generate the documentation for the following Python 3 function
def top(self):
        # For backwards compatibility.
        with warnings.catch_warnings():
            warnings.simplefilter("always")
            w = "Striplog.top is deprecated; please use Striplog.unique"
            warnings.warn(w, DeprecationWarning, stacklevel=2)
        return self.unique

Response: Return the top entry of the log.


Instruction:
Here you have a function in Python 3, explain what it does
def __intervals_from_tops(self,
                              tops,
                              values,
                              basis,
                              components,
                              field=None,
                              ignore_nan=True):
        """
        Private method. Take a sequence of tops in an arbitrary dimension,
        and provide a list of intervals from which a striplog can be made.

        This is only intended to be used by ``from_image()``.

        Args:
            tops (iterable). A list of floats.
            values (iterable). A list of values to look up.
            basis (iterable). A list of components.
            components (iterable). A list of Components.

        Returns:
            List. A list of Intervals.
        """
        # Scale tops to actual depths.
        length = float(basis.size)
        start, stop = basis[0], basis[-1]
        tops = [start + (p/(length-1)) * (stop-start) for p in tops]
        bases = tops[1:] + [stop]

        list_of_Intervals = []
        for i, t in enumerate(tops):

            v, c, d = values[i], [], {}

            if ignore_nan and np.isnan(v):
                continue

            if (field is not None):
                d = {field: v}

            if components is not None:
                try:
                    c = [deepcopy(components[int(v)])]
                except IndexError:
                    c = []

                if c and (c[0] is None):
                    c = []

            interval = Interval(t, bases[i], data=d, components=c)
            list_of_Intervals.append(interval)

        return list_of_Intervals

Response: Private method that returns a list of Intervals.


Instruction:
Can you generate the documentation for the following Python 3 function
def _clean_longitudinal_data(cls, data, null=None):

        # Rename 'depth' or 'MD'
        if ('top' not in data.keys()):
            data['top'] = data.pop('depth', data.pop('MD', None))

        # Sort everything
        idx = list(data.keys()).index('top')
        values = sorted(zip(*data.values()), key=lambda x: x[idx])
        data = {k: list(v) for k, v in zip(data.keys(), zip(*values))}

        if data['top'] is None:
            raise StriplogError('Could not get tops.')

        # Get rid of null-like values if specified.
        if null is not None:
            for k, v in data.items():
                data[k] = [i if i != null else None for i in v]

        return data

Response: Private function to clean up the longitudinal data.


Instruction:
Given the following Python 3 function, write the documentation
def from_petrel(cls, filename,
                    stop=None,
                    points=False,
                    null=None,
                    function=None,
                    include=None,
                    exclude=None,
                    remap=None,
                    ignore=None):

        """
        Makes a striplog from a Petrel text file.

        Returns:
            striplog.
        """
        result = utils.read_petrel(filename,
                                   function=function,
                                   remap=remap,
                                   )

        data = cls._clean_longitudinal_data(result,
                                            null=null
                                            )

        list_of_Intervals = cls._build_list_of_Intervals(data,
                                                         stop=stop,
                                                         points=points,
                                                         include=include,
                                                         exclude=exclude,
                                                         ignore=ignore
                                                         )
        if list_of_Intervals:
            return cls(list_of_Intervals)
        return None

Response: Makes a striplog from a Petrel text file.


Instruction:
Make a summary of the following Python 3 code
def _build_list_of_Intervals(cls,
                                 data_dict,
                                 stop=None,
                                 points=False,
                                 include=None,
                                 exclude=None,
                                 ignore=None,
                                 lexicon=None):
        """
        Private function. Takes a data dictionary and reconstructs a list
        of Intervals from it.

        Args:
            data_dict (dict)
            stop (float): Where to end the last interval.
            points (bool)
            include (dict)
            exclude (dict)
            ignore (list)
            lexicon (Lexicon)

        Returns:
            list.
        """

        include = include or {}
        exclude = exclude or {}
        ignore = ignore or []

        # Reassemble as list of dicts
        all_data = []
        for data in zip(*data_dict.values()):
            all_data.append({k: v for k, v in zip(data_dict.keys(), data)})

        # Sort
        all_data = sorted(all_data, key=lambda x: x['top'])

        # Filter down:
        wanted_data = []
        for dictionary in all_data:
            keep = True
            delete = []
            for k, v in dictionary.items():
                incl = include.get(k, utils.null_default(True))
                excl = exclude.get(k, utils.null_default(False))
                if k in ignore:
                    delete.append(k)
                if not incl(v):
                    keep = False
                if excl(v):
                    keep = False
            if delete:
                for key in delete:
                    _ = dictionary.pop(key, None)
            if keep:
                wanted_data.append(dictionary)

        # Fill in
        if not points:
            for i, iv in enumerate(wanted_data):
                if iv.get('base', None) is None:
                    try:  # To set from next interval
                        iv['base'] = wanted_data[i+1]['top']
                    except (IndexError, KeyError):
                        # It's the last interval
                        if stop is not None:
                            thick = stop - iv['top']
                        else:
                            thick = 1
                        iv['base'] = iv['top'] + thick

        # Build the list of intervals to pass to __init__()
        list_of_Intervals = []
        for iv in wanted_data:
            top = iv.pop('top')
            base = iv.pop('base', None)
            descr = iv.pop('description', '')
            if iv:
                c, d = {}, {}
                for k, v in iv.items():
                    if (k[:5].lower() == 'comp ') or (k[:9].lower() == 'component'):
                        k = re.sub(r'comp(?:onent)? ', '', k, flags=re.I)
                        c[k] = v  # It's a component
                    else:
                        if v is not None:
                            d[k] = v  # It's data
                comp = [Component(c)] if c else None
                this = Interval(**{'top': top,
                                   'base': base,
                                   'description': descr,
                                   'data': d,
                                   'components': comp})
            else:
                this = Interval(**{'top': top,
                                   'base': base,
                                   'description': descr,
                                   'lexicon': lexicon})
            list_of_Intervals.append(this)

        return list_of_Intervals

Response: Private function to reconstruct a list of Intervals from a dictionary.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def from_csv(cls, filename=None,
                 text=None,
                 dlm=',',
                 lexicon=None,
                 points=False,
                 include=None,
                 exclude=None,
                 remap=None,
                 function=None,
                 null=None,
                 ignore=None,
                 source=None,
                 stop=None,
                 fieldnames=None):
        """
        Load from a CSV file or text.
        """
        if (filename is None) and (text is None):
            raise StriplogError("You must provide a filename or CSV text.")

        if (filename is not None):
            if source is None:
                source = filename
            with open(filename, 'r') as f:
                text = f.read()

        source = source or 'CSV'

        # Deal with multiple spaces in space delimited file.
        if dlm == ' ':
            text = re.sub(r'[ \t]+', ' ', text)

        if fieldnames is not None:
            text = dlm.join(fieldnames) + '\n' + text

        try:
            f = StringIO(text)  # Python 3
        except TypeError:
            f = StringIO(unicode(text))  # Python 2

        reader = csv.DictReader(f, delimiter=dlm)

        # Reorganize the data to make fixing it easier.
        reorg = {k.strip().lower(): [] for k in reader.fieldnames if k is not None}
        t = f.tell()
        for key in reorg:
            f.seek(t)
            for r in reader:
                s = {k.strip().lower(): v.strip() for k, v in r.items()}
                try:
                    reorg[key].append(float(s[key]))
                except ValueError:
                    reorg[key].append(s[key])

        f.close()

        remap = remap or {}
        for k, v in remap.items():
            reorg[v] = reorg.pop(k)

        data = cls._clean_longitudinal_data(reorg, null=null)

        list_of_Intervals = cls._build_list_of_Intervals(data,
                                                         points=points,
                                                         lexicon=lexicon,
                                                         include=include,
                                                         exclude=exclude,
                                                         ignore=ignore,
                                                         stop=stop)

        return cls(list_of_Intervals, source=source)

Response: Load a new entry from a CSV file or text.


Instruction:
Can you generate the documentation for the following Python 3 function
def from_descriptions(cls, text,
                          lexicon=None,
                          source='CSV',
                          dlm=',',
                          points=False,
                          abbreviations=False,
                          complete=False,
                          order='depth',
                          columns=None,
                          ):
        """
        Convert a CSV string into a striplog. Expects 2 or 3 fields:
            top, description
            OR
            top, base, description

        Args:
            text (str): The input text, given by ``well.other``.
            lexicon (Lexicon): A lexicon, required to extract components.
            source (str): A source. Default: 'CSV'.
            dlm (str): The delimiter, given by ``well.dlm``. Default: ','
            points (bool): Whether to treat as points or as intervals.
            abbreviations (bool): Whether to expand abbreviations in the
                description. Default: False.
            complete (bool): Whether to make 'blank' intervals, or just leave
                gaps. Default: False.
            order (str): The order, 'depth' or 'elevation'. Default: 'depth'.
            columns (tuple or list): The names of the columns.

        Returns:
            Striplog: A ``striplog`` object.

        Example:
            # TOP       BOT        LITH
            312.34,   459.61,    Sandstone
            459.71,   589.61,    Limestone
            589.71,   827.50,    Green shale
            827.60,   1010.84,   Fine sandstone
        """

        text = re.sub(r'(\n+|\r\n|\r)', '\n', text.strip())

        as_strings = []
        try:
            f = StringIO(text)  # Python 3
        except TypeError:
            f = StringIO(unicode(text))  # Python 2
        reader = csv.reader(f, delimiter=dlm, skipinitialspace=True)
        for row in reader:
            as_strings.append(row)
        f.close()

        if not columns:
            if order[0].lower() == 'e':
                columns = ('base', 'top', 'description')
            else:
                columns = ('top', 'base', 'description')

        result = {k: [] for k in columns}

        # Set the indices for the fields.
        tix = columns.index('top')
        bix = columns.index('base')
        dix = columns.index('description')

        for i, row in enumerate(as_strings):

            # THIS ONLY WORKS FOR MISSING TOPS!
            if len(row) == 2:
                row = [row[0], None, row[1]]

            # TOP
            this_top = float(row[tix])

            # THIS ONLY WORKS FOR MISSING TOPS!
            # BASE
            # Base is null: use next top if this isn't the end.
            if row[1] is None:
                if i < len(as_strings)-1:
                    this_base = float(as_strings[i+1][0])  # Next top.
                else:
                    this_base = this_top + 1  # Default to 1 m thick at end.
            else:
                this_base = float(row[bix])

            # DESCRIPTION
            this_descr = row[dix].strip()

            # Deal with making intervals or points...
            if not points:
                # Insert intervals where needed.
                if complete and (i > 0) and (this_top != result['base'][-1]):
                    result['top'].append(result['base'][-1])
                    result['base'].append(this_top)
                    result['description'].append('')
            else:
                this_base = None  # Gets set to Top in striplog creation

            # ASSIGN
            result['top'].append(this_top)
            result['base'].append(this_base)
            result['description'].append(this_descr)

        # Build the list.
        list_of_Intervals = []
        for i, t in enumerate(result['top']):
            b = result['base'][i]
            d = result['description'][i]
            interval = Interval(t, b, description=d,
                                lexicon=lexicon,
                                abbreviations=abbreviations)
            list_of_Intervals.append(interval)

        return cls(list_of_Intervals, source=source)

Response: Convert a CSV string into a striplog.


Instruction:
Can you generate the documentation for the following Python 3 function
def from_image(cls, filename, start, stop, legend,
                   source="Image",
                   col_offset=0.1,
                   row_offset=2,
                   tolerance=0):
        """
        Read an image and generate Striplog.

        Args:
            filename (str): An image file, preferably high-res PNG.
            start (float or int): The depth at the top of the image.
            stop (float or int): The depth at the bottom of the image.
            legend (Legend): A legend to look up the components in.
            source (str): A source for the data. Default: 'Image'.
            col_offset (Number): The proportion of the way across the image
                from which to extract the pixel column. Default: 0.1 (ie 10%).
            row_offset (int): The number of pixels to skip at the top of
                each change in colour. Default: 2.
            tolerance (float): The Euclidean distance between hex colours,
                which has a maximum (black to white) of 441.67 in base 10.
                Default: 0.

        Returns:
            Striplog: The ``striplog`` object.
        """
        rgb = utils.loglike_from_image(filename, col_offset)
        loglike = np.array([utils.rgb_to_hex(t) for t in rgb])

        # Get the pixels and colour values at 'tops' (i.e. changes).
        tops, hexes = utils.tops_from_loglike(loglike, offset=row_offset)

        # If there are consecutive tops, we assume it's because there is a
        # single-pixel row that we don't want. So take the second one only.
        # We used to do this reduction in ``utils.tops_from_loglike()`` but
        # it was prventing us from making intervals only one sample thick.
        nonconsecutive = np.append(np.diff(tops), 2)
        tops = tops[nonconsecutive > 1]
        hexes = hexes[nonconsecutive > 1]

        # Get the set of unique colours.
        hexes_reduced = list(set(hexes))

        # Get the components corresponding to the colours.
        components = [legend.get_component(h, tolerance=tolerance)
                      for h in hexes_reduced]

        # Turn them into integers.
        values = [hexes_reduced.index(i) for i in hexes]

        basis = np.linspace(start, stop, loglike.size)

        list_of_Intervals = cls.__intervals_from_tops(tops,
                                                      values,
                                                      basis,
                                                      components)

        return cls(list_of_Intervals, source="Image")

Response: Reads an image and generates a Striplog object.


Instruction:
Explain what the following Python 3 code does
def _from_array(cls, a,
                    lexicon=None,
                    source="",
                    points=False,
                    abbreviations=False):
        """
        DEPRECATING.

        Turn an array-like into a Striplog. It should have the following
        format (where ``base`` is optional):

            [(top, base, description),
             (top, base, description),
             ...
             ]

        Args:
            a (array-like): A list of lists or of tuples, or an array.
            lexicon (Lexicon): A language dictionary to extract structured
                objects from the descriptions.
            source (str): The source of the data. Default: ''.
            points (bool): Whether to treat as point data. Default: False.

        Returns:
            Striplog: The ``striplog`` object.
        """

        with warnings.catch_warnings():
            warnings.simplefilter("always")
            w = "from_array() is deprecated."
            warnings.warn(w, DeprecationWarning, stacklevel=2)

        csv_text = ''
        for interval in a:
            interval = [str(i) for i in interval]
            if (len(interval) < 2) or (len(interval) > 3):
                raise StriplogError('Elements must have 2 or 3 items')
            descr = interval[-1].strip('" ')
            interval[-1] = '"' + descr + '"'
            csv_text += ', '.join(interval) + '\n'

        return cls.from_descriptions(csv_text,
                                     lexicon,
                                     source=source,
                                     points=points,
                                     abbreviations=abbreviations)

Response: Convert an array - like object into a Striplog object.


Instruction:
Write a Python 3 script to
turn a 1D array into a striplog object given a cutoff value.

Response:
def from_log(cls, log,
                 cutoff=None,
                 components=None,
                 legend=None,
                 legend_field=None,
                 field=None,
                 right=False,
                 basis=None,
                 source='Log'):
        """
        Turn a 1D array into a striplog, given a cutoff.

        Args:
            log (array-like): A 1D array or a list of integers.
            cutoff (number or array-like): The log value(s) at which to bin
                the log. Optional.
            components (array-like): A list of components. Use this or
                ``legend``.
            legend (``Legend``): A legend object. Use this or ``components``.
            legend_field ('str'): If you're not trying to match against
                components, then you can match the log values to this field in
                the Decors.
            field (str): The field in the Interval's ``data`` to store the log
                values as.
            right (bool): Which side of the cutoff to send things that are
                equal to, i.e. right on, the cutoff.
            basis (array-like): A depth basis for the log, so striplog knows
                where to put the boundaries.
            source (str): The source of the data. Default 'Log'.

        Returns:
            Striplog: The ``striplog`` object.
        """
        if (components is None) and (legend is None) and (field is None):
            m = 'You must provide a list of components, and legend, or a field.'
            raise StriplogError(m)

        if (legend is not None) and (legend_field is None):
            try:  # To treat it like a legend.
                components = [deepcopy(decor.component) for decor in legend]
            except AttributeError:  # It's just a list of components.
                pass

        if legend_field is not None:
            field_values = [getattr(d, legend_field, 0) for d in legend]
            components = [Component() for i in range(int(max(field_values)+1))]
            for i, decor in enumerate(legend):
                components[i] = deepcopy(decor.component)

        if cutoff is not None:

            # First make sure we have enough components.
            try:
                n = len(cutoff)
            except TypeError:
                n = 1
            if len(components) < n+1:
                m = 'For n cutoffs, you need to provide at least'
                m += 'n+1 components.'
                raise StriplogError(m)

            # Digitize.
            try:  # To use cutoff as a list.
                a = np.digitize(log, cutoff, right)
            except ValueError:  # It's just a number.
                a = np.digitize(log, [cutoff], right)

        else:
            a = np.copy(log)

        tops, values = utils.tops_from_loglike(a)

        if basis is None:
            m = 'You must provide a depth or elevation basis.'
            raise StriplogError(m)

        list_of_Intervals = cls.__intervals_from_tops(tops,
                                                      values,
                                                      basis,
                                                      components,
                                                      field=field
                                                      )

        return cls(list_of_Intervals, source=source)


Instruction:
Explain what the following Python 3 code does
def from_las3(cls, string, lexicon=None,
                  source="LAS",
                  dlm=',',
                  abbreviations=False):
        """
        Turn LAS3 'lithology' section into a Striplog.

        Args:
            string (str): A section from an LAS3 file.
            lexicon (Lexicon): The language for conversion to components.
            source (str): A source for the data.
            dlm (str): The delimiter.
            abbreviations (bool): Whether to expand abbreviations.

        Returns:
            Striplog: The ``striplog`` object.

        Note:
            Handles multiple 'Data' sections. It would be smarter for it
            to handle one at a time, and to deal with parsing the multiple
            sections in the Well object.

            Does not read an actual LAS file. Use the Well object for that.
        """
        f = re.DOTALL | re.IGNORECASE
        regex = r'\~\w+?_Data.+?\n(.+?)(?:\n\n+|\n*\~|\n*$)'
        pattern = re.compile(regex, flags=f)
        text = pattern.search(string).group(1)

        s = re.search(r'\.(.+?)\: ?.+?source', string)
        if s:
            source = s.group(1).strip()

        return cls.from_descriptions(text, lexicon,
                                     source=source,
                                     dlm=dlm,
                                     abbreviations=abbreviations)

Response: Turn a LAS3 file into a Striplog object.


Instruction:
Given the following Python 3 function, write the documentation
def from_canstrat(cls, filename, source='canstrat'):
        with open(filename) as f:
            dat = f.read()

        data = parse_canstrat(dat)

        list_of_Intervals = []
        for d in data[7]:  # 7 is the 'card type' for lithology info.
            if d.pop('skip'):
                continue
            top = d.pop('top')
            base = d.pop('base')
            comps = [Component({'lithology': d['rtc'],
                                'colour': d['colour_name']
                                })]
            iv = Interval(top=top, base=base, components=comps, data=d)
            list_of_Intervals.append(iv)

        return cls(list_of_Intervals, source=source)

Response: Create a striplog from a Canstrat DAT file.


Instruction:
Can you create a Python 3 function that
returns a shallow copy of this Striplog.

Response:
def copy(self):
        """Returns a shallow copy."""
        return Striplog([i.copy() for i in self],
                        order=self.order,
                        source=self.source)


Instruction:
Can you create a Python 3 function that
returns a CSV string of the Intervals.

Response:
def to_csv(self,
               filename=None,
               as_text=True,
               use_descriptions=False,
               dlm=",",
               header=True):
        """
        Returns a CSV string built from the summaries of the Intervals.

        Args:
            use_descriptions (bool): Whether to use descriptions instead
                of summaries, if available.
            dlm (str): The delimiter.
            header (bool): Whether to form a header row.

        Returns:
            str: A string of comma-separated values.
        """
        if (filename is None):
            if (not as_text):
                raise StriplogError("You must provide a filename or set as_text to True.")
        else:
            as_text = False

        if as_text:
            output = StringIO()
        else:
            output = open(filename, 'w')

        fieldnames = ['Top', 'Base', 'Component']
        writer = csv.DictWriter(output,
                                delimiter=dlm,
                                fieldnames=fieldnames,
                                quoting=csv.QUOTE_MINIMAL)

        if header:
            writer.writeheader()

        for i in self.__list:
            if use_descriptions and i.description:
                text = i.description
            elif i.primary:
                text = i.primary.summary()
            else:
                text = ''
            data = {j: k for j, k in zip(fieldnames, [i.top.z, i.base.z, text])}
            writer.writerow(data)

        if as_text:
            return output.getvalue()
            #return output
        else:
            output.close
            return None


Instruction:
Implement a function in Python 3 to
convert the object to a LAS 3. 0 section string.

Response:
def to_las3(self, use_descriptions=False, dlm=",", source="Striplog"):
        """
        Returns an LAS 3.0 section string.

        Args:
            use_descriptions (bool): Whether to use descriptions instead
                of summaries, if available.
            dlm (str): The delimiter.
            source (str): The sourse of the data.

        Returns:
            str: A string forming Lithology section of an LAS3 file.
        """
        data = self.to_csv(use_descriptions=use_descriptions,
                           dlm=dlm,
                           header=False)

        return templates.section.format(name='Lithology',
                                        short="LITH",
                                        source=source,
                                        data=data)


Instruction:
Can you write a function in Python 3 where it
returns a fully sampled log from a striplog file.

Response:
def to_log(self,
               step=1.0,
               start=None,
               stop=None,
               basis=None,
               field=None,
               field_function=None,
               dtype=None,
               table=None,
               legend=None,
               legend_field=None,
               match_only=None,
               undefined=0,
               return_meta=False
               ):
        """
        Return a fully sampled log from a striplog. Useful for crossplotting
        with log data, for example.

        Args:
            step (float): The step size. Default: 1.0.
            start (float): The start depth of the new log. You will want to
                match the logs, so use the start depth from the LAS file.
                Default: The basis if provided, else the start of the striplog.
            stop (float): The stop depth of the new log. Use the stop depth
                of the LAS file. Default: The basis if provided, else the stop
                depth of the striplog.
            field (str): If you want the data to come from one of the
                attributes of the components in the striplog, provide it.
            field_function (function): Provide a function to apply to the field
                you are asking for. It's up to you to make sure the function
                does what you want.
            legend (Legend): If you want the codes to come from a legend,
                provide one. Otherwise the codes come from the log, using
                integers in the order of prevalence. If you use a legend,
                they are assigned in the order of the legend.
            legend_field (str): If you want to get a log representing one of
                the fields in the legend, such as 'width' or 'grainsize'.
            match_only (list): If you only want to match some attributes of
                the Components (e.g. lithology), provide a list of those
                you want to match.
            undefined (number): What to fill in where no value can be
                determined, e.g. ``-999.25`` or ``np.null``. Default 0.
            return_meta (bool): If ``True``, also return the depth basis
                (np.linspace), and the component table.

        Returns:
            ndarray: If ``return_meta`` was ``True``, you get:

                  * The log data as an array of ints.
                  * The depth basis as an array of floats.
                  * A list of the components in the order matching the ints.

                If ``return_meta`` was ``False`` (the default), you only get
                the log data.
        """
        # Make the preparations.
        if basis is not None:
            start, stop = basis[0], basis[-1]
            step = basis[1] - start
        else:
            start = start or self.start.z
            stop = stop or self.stop.z
            pts = np.ceil((stop - start)/step) + 1
            basis = np.linspace(start, stop, int(pts))

        if (field is not None) or (legend_field is not None):
            result = np.zeros_like(basis, dtype=dtype)
        else:
            result = np.zeros_like(basis, dtype=np.int)

        if np.isnan(undefined):
            try:
                result[:] = np.nan
            except:
                pass  # array type is int

        # If needed, make a look-up table for the log values.
        if table is None:
            table = [Component({})]
            if legend:
                table += [j.component for j in legend]
            elif field:
                s = set([iv.data.get(field) for iv in self])
                table = [None] + list(filter(None, s))
            else:
                table += [j[0] for j in self.unique]

        # Adjust the table if necessary. Go over all the components in the
        # table list, and remove elements that are not in the match list.
        # Careful! This results in a new table, with components that may not
        # be in the original list of components.
        if match_only is not None:
            if not isinstance(match_only, (list, tuple, set,)):
                raise StriplogError("match_only should be a list, not a string")
            table_new = []
            for c in table:
                if c == '':
                    continue  # No idea why sometimes there's a ''
                c_new = Component({k: v for k, v in c.__dict__.items()
                                   if k in match_only})
                # Only add unique, and preserve order.
                if c_new not in table_new:
                    table_new.append(c_new)
            table = table_new
        else:
            match_only = []

        start_ix = self.read_at(start, index=True)
        stop_ix = self.read_at(stop, index=True)
        if stop_ix is not None:
            stop_ix += 1

        # Assign the values.
        for i in self[start_ix:stop_ix]:
            c = i.primary
            if match_only:
                c = Component({k: getattr(c, k, None)
                               for k in match_only})

            if legend and legend_field:  # Use the legend field.
                try:
                    key = legend.getattr(c, legend_field, undefined)
                    key = key or undefined
                except ValueError:
                    key = undefined
            elif field:  # Get data directly from that field in iv.data.
                f = field_function or utils.null
                try:
                    v = f(i.data.get(field, undefined)) or undefined
                    key = table.index(v)
                except ValueError:
                    key = undefined
            else:  # Use the lookup table.
                try:
                    key = table.index(c) or undefined
                except ValueError:
                    key = undefined

            top_index = int(np.ceil((max(start, i.top.z)-start)/step))
            base_index = int(np.ceil((min(stop, i.base.z)-start)/step))

            try:
                result[top_index:base_index+1] = key
            except:  # Have a list or array or something.
                result[top_index:base_index+1] = key[0]

        if return_meta:
            return result, basis, table
        else:
            return result


Instruction:
Can you tell what is the following Python 3 function doing
def plot_points(self, ax,
                    legend=None,
                    field=None,
                    field_function=None,
                    undefined=0,
                    **kwargs):
        """
        Plotting, but only for points (as opposed to intervals).
        """

        ys = [iv.top.z for iv in self]

        if field is not None:
            f = field_function or utils.null
            xs = [f(iv.data.get(field, undefined)) for iv in self]
        else:
            xs = [1 for iv in self]

        ax.set_xlim((min(xs), max(xs)))
        for x, y in zip(xs, ys):
            ax.axhline(y, color='lightgray', zorder=0)

        ax.scatter(xs, ys, clip_on=False, **kwargs)

        return ax

Response: Plots the points of the current object.


Instruction:
How would you implement a function in Python 3 that
plots the tops of the related object.

Response:
def plot_tops(self, ax, legend=None, field=None, **kwargs):
        """
        Plotting, but only for tops (as opposed to intervals).
        """
        if field is None:
            raise StriplogError('You must provide a field to plot.')

        ys = [iv.top.z for iv in self]

        try:
            try:
                ts = [getattr(iv.primary, field) for iv in self]
            except:
                ts = [iv.data.get(field) for iv in self]
        except:
            raise StriplogError('Could not retrieve field.')

        for y, t in zip(ys, ts):
            ax.axhline(y, color='lightblue', lw=3, zorder=0)
            ax.text(0.1, y-max(ys)/200, t, ha='left')

        return ax


Instruction:
Write a Python 3 function that can
plot the data for the current calendar.

Response:
def plot_field(self, ax, legend=None, field=None, **kwargs):
        """
        Plotting, but only for tops (as opposed to intervals).
        """
        if field is None:
            raise StriplogError('You must provide a field to plot.')

        try:
            try:
                xs = [getattr(iv.primary, field) for iv in self]
            except:
                xs = [iv.data.get(field) for iv in self]
        except:
            raise StriplogError('Could not retrieve field.')

        for iv, x in zip(self.__list, xs):
            _, ymin = utils.axis_transform(ax, 0, iv.base.z, ylim=(self.start.z, self.stop.z), inverse=True)
            _, ymax = utils.axis_transform(ax, 0, iv.top.z, ylim=(self.start.z, self.stop.z), inverse=True)
            ax.axvline(x, ymin=ymin, ymax=ymax)

        return ax


Instruction:
Write a Python 3 function that can
plot the data in the current figure.

Response:
def plot_axis(self,
                  ax,
                  legend,
                  ladder=False,
                  default_width=1,
                  match_only=None,
                  colour=None,
                  colour_function=None,
                  cmap=None,
                  default=None,
                  width_field=None,
                  **kwargs
                  ):
        """
        Plotting, but only the Rectangles. You have to set up the figure.
        Returns a matplotlib axis object.

        Args:
            ax (axis): The matplotlib axis to plot into.
            legend (Legend): The Legend to use for colours, etc.
            ladder (bool): Whether to use widths or not. Default False.
            default_width (int): A width for the plot if not using widths.
                Default 1.
            match_only (list): A list of strings matching the attributes you
                want to compare when plotting.
            colour (str): Which data field to use for colours.
            cmap (cmap): Matplotlib colourmap. Default ``viridis``.
            default (float): The default (null) value.
            width_field (str): The field to use for the width of the patches.
            **kwargs are passed through to matplotlib's ``patches.Rectangle``.

        Returns:
            axis: The matplotlib.pyplot axis.
        """
        default_c = None
        patches = []
        for iv in self.__list:
            origin = (0, iv.top.z)
            d = legend.get_decor(iv.primary, match_only=match_only)
            thick = iv.base.z - iv.top.z

            if ladder:
                if width_field is not None:
                    w = iv.data.get(width_field, 1)
                    w = default_width * w/self.max_field(width_field)
                    default_c = 'gray'
                elif legend is not None:
                    w = d.width or default_width
                    try:
                        w = default_width * w/legend.max_width
                    except:
                        w = default_width
            else:
                w = default_width

            # Allow override of lw
            this_patch_kwargs = kwargs.copy()
            lw = this_patch_kwargs.pop('lw', 0)
            ec = this_patch_kwargs.pop('ec', 'k')
            fc = this_patch_kwargs.pop('fc', None) or default_c or d.colour

            if colour is None:
                rect = mpl.patches.Rectangle(origin,
                                             w,
                                             thick,
                                             fc=fc,
                                             lw=lw,
                                             hatch=d.hatch,
                                             ec=ec,  # edgecolour for hatching
                                             **this_patch_kwargs)
                ax.add_patch(rect)
            else:
                rect = mpl.patches.Rectangle(origin,
                                             w,
                                             thick,
                                             lw=lw,
                                             ec=ec,  # edgecolour for hatching
                                             **this_patch_kwargs)
                patches.append(rect)

        if colour is not None:
            cmap = cmap or 'viridis'
            p = mpl.collections.PatchCollection(patches, cmap=cmap, lw=lw)
            p.set_array(self.get_data(colour, colour_function, default=default))
            ax.add_collection(p)
            cb = plt.colorbar(p)  #  orientation='horizontal' only really works with ticks=[0, 0.1, 0.2] say
            cb.outline.set_linewidth(0)

        return ax


Instruction:
Write a Python 3 script to
get data from the striplog.

Response:
def get_data(self, field, function=None, default=None):
        """
        Get data from the striplog.
        """
        f = function or utils.null
        data = []
        for iv in self:
            d = iv.data.get(field)
            if d is None:
                if default is not None:
                    d = default
                else:
                    d = np.nan
            data.append(f(d))

        return np.array(data)


Instruction:
How would you implement a function in Python 3 that
plots the object with the specified parameters.

Response:
def plot(self,
             legend=None,
             width=1.5,
             ladder=True,
             aspect=10,
             ticks=(1, 10),
             match_only=None,
             ax=None,
             return_fig=False,
             colour=None,
             cmap='viridis',
             default=None,
             style='intervals',
             field=None,
             **kwargs):
        """
        Hands-free plotting.

        Args:
            legend (Legend): The Legend to use for colours, etc.
            width (int): The width of the plot, in inches. Default 1.
            ladder (bool): Whether to use widths or not. Default False.
            aspect (int): The aspect ratio of the plot. Default 10.
            ticks (int or tuple): The (minor,major) tick interval for depth.
                Only the major interval is labeled. Default (1,10).
            match_only (list): A list of strings matching the attributes you
                want to compare when plotting.
            ax (ax): A maplotlib axis to plot onto. If you pass this, it will
                be returned. Optional.
            return_fig (bool): Whether or not to return the maplotlib ``fig``
                object. Default False.
            colour (str): Which data field to use for colours.
            cmap (cmap): Matplotlib colourmap. Default ``viridis``.
            **kwargs are passed through to matplotlib's ``patches.Rectangle``.

        Returns:
            None. Unless you specify ``return_fig=True`` or pass in an ``ax``.
        """
        if legend is None:
                legend = Legend.random(self.components)

        if style.lower() == 'tops':
            # Make sure width is at least 3 for 'tops' style
            width = max([3, width])

        if ax is None:
            return_ax = False
            fig = plt.figure(figsize=(width, aspect*width))
            ax = fig.add_axes([0.35, 0.05, 0.6, 0.95])
        else:
            return_ax = True

        if (self.order == 'none') or (style.lower() == 'points'):
            # Then this is a set of points.
            ax = self.plot_points(ax=ax, legend=legend, field=field, **kwargs)
        elif style.lower() == 'field':
            if field is None:
                raise StriplogError('You must provide a field to plot.')
            ax = self.plot_field(ax=ax, legend=legend, field=field)
        elif style.lower() == 'tops':
            ax = self.plot_tops(ax=ax, legend=legend, field=field)
            ax.set_xticks([])
        else:
            ax = self.plot_axis(ax=ax,
                                legend=legend,
                                ladder=ladder,
                                default_width=width,
                                match_only=kwargs.get('match_only', match_only),
                                colour=colour,
                                cmap=cmap,
                                default=default,
                                width_field=field,
                                **kwargs
                                )

            ax.set_xlim([0, width])
            ax.set_xticks([])

        # Rely on interval order.
        lower, upper = self[-1].base.z, self[0].top.z
        rng = abs(upper - lower)

        ax.set_ylim([lower, upper])

        # Make sure ticks is a tuple.
        try:
            ticks = tuple(ticks)
        except TypeError:
            ticks = (1, ticks)

        # Avoid MAXTICKS error.
        while rng/ticks[0] > 250:
            mi, ma = 10*ticks[0], ticks[1]
            if ma <= mi:
                ma = 10 * mi
            ticks = (mi, ma)

        # Carry on plotting...
        minorLocator = mpl.ticker.MultipleLocator(ticks[0])
        ax.yaxis.set_minor_locator(minorLocator)

        majorLocator = mpl.ticker.MultipleLocator(ticks[1])
        majorFormatter = mpl.ticker.FormatStrFormatter('%d')
        ax.yaxis.set_major_locator(majorLocator)
        ax.yaxis.set_major_formatter(majorFormatter)

        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.yaxis.set_ticks_position('left')
        ax.get_yaxis().set_tick_params(which='both', direction='out')

        # Optional title.
        title = getattr(self, 'title', None)
        if title is not None:
            ax.set_title(title)

        ax.patch.set_alpha(0)

        if return_ax:
            return ax
        elif return_fig:
            return fig
        else:
            return


Instruction:
Can you write a function in Python 3 where it
returns the index of the interval at a particular depth.

Response:
def read_at(self, d, index=False):
        """
        Get the index of the interval at a particular 'depth' (though this
            might be an elevation or age or anything).

        Args:
            d (Number): The 'depth' to query.
            index (bool): Whether to return the index instead of the interval.

        Returns:
            Interval: The interval, or if ``index==True`` the index of the
                interval, at the specified 'depth', or ``None`` if the depth is
                outside the striplog's range.
        """
        for i, iv in enumerate(self):
            if iv.spans(d):
                return i if index else iv
        return None


Instruction:
Can you implement a function in Python 3 that
returns the depth of the current object.

Response:
def depth(self, d):
        """
        For backwards compatibility.
        """
        with warnings.catch_warnings():
            warnings.simplefilter("always")
            w = "depth() is deprecated; please use read_at()"
            warnings.warn(w)
        return self.read_at(d)


Instruction:
Can you implement a function in Python 3 that
extracts a log into the components of a striplog.

Response:
def extract(self, log, basis, name, function=None):
        """
        'Extract' a log into the components of a striplog.

        Args:
            log (array_like). A log or other 1D data.
            basis (array_like). The depths or elevations of the log samples.
            name (str). The name of the attribute to store in the components.
            function (function). A function that takes an array as the only
                input, and returns whatever you want to store in the 'name'
                attribute of the primary component.
        Returns:
            None. The function works on the striplog in place.
        """
        # Build a dict of {index: [log values]} to keep track.
        intervals = {}
        previous_ix = -1
        for i, z in enumerate(basis):
            ix = self.read_at(z, index=True)
            if ix is None:
                continue
            if ix == previous_ix:
                intervals[ix].append(log[i])
            else:
                intervals[ix] = [log[i]]
            previous_ix = ix

        # Set the requested attribute in the primary comp of each interval.
        for ix, data in intervals.items():
            f = function or utils.null
            d = f(np.array(data))
            self[ix].data[name] = d

        return None


Instruction:
Write a Python 3 function for
searching for a regex expression in the descriptions of the striplog and returns the first occurrence of the search_term.

Response:
def find(self, search_term, index=False):
        """
        Look for a regex expression in the descriptions of the striplog.
        If there's no description, it looks in the summaries.

        If you pass a Component, then it will search the components, not the
        descriptions or summaries.

        Case insensitive.

        Args:
            search_term (string or Component): The thing you want to search
                for. Strings are treated as regular expressions.
            index (bool): Whether to return the index instead of the interval.
        Returns:
            Striplog: A striplog that contains only the 'hit' Intervals.
                However, if ``index`` was ``True``, then that's what you get.
        """
        hits = []
        for i, iv in enumerate(self):
            try:
                search_text = iv.description or iv.primary.summary()
                pattern = re.compile(search_term, flags=re.IGNORECASE)
                if pattern.search(search_text):
                    hits.append(i)
            except TypeError:
                if search_term in iv.components:
                    hits.append(i)
        if hits and index:
            return hits
        elif hits:
            return self[hits]
        else:
            return


Instruction:
Make a summary of the following Python 3 code
def __find_incongruities(self, op, index):
        if len(self) == 1:
            return

        hits = []
        intervals = []

        if self.order == 'depth':
            one, two = 'base', 'top'
        else:
            one, two = 'top', 'base'

        for i, iv in enumerate(self[:-1]):
            next_iv = self[i+1]
            if op(getattr(iv, one), getattr(next_iv, two)):
                hits.append(i)

                top = getattr(iv, one)
                base = getattr(next_iv, two)
                iv_gap = Interval(top, base)
                intervals.append(iv_gap)

        if index and hits:
            return hits
        elif intervals:
            return Striplog(intervals)
        else:
            return

Response: Private method to find gaps and overlaps in a striplog.


Instruction:
Implement a function in Python 3 to
find overlaps in a striplog.

Response:
def find_overlaps(self, index=False):
        """
        Find overlaps in a striplog.

        Args:
            index (bool): If True, returns indices of intervals with
            gaps after them.

        Returns:
            Striplog: A striplog of all the overlaps as intervals.
        """
        return self.__find_incongruities(op=operator.gt, index=index)


Instruction:
Can you generate the documentation for the following Python 3 function
def find_gaps(self, index=False):
        return self.__find_incongruities(op=operator.lt, index=index)

Response: Returns a list of all the gaps in a striplog.


Instruction:
Explain what the following Python 3 code does
def prune(self, limit=None, n=None, percentile=None, keep_ends=False):
        strip = self.copy()

        if not (limit or n or percentile):
            m = "You must provide a limit or n or percentile for pruning."
            raise StriplogError(m)
        if limit:
            prune = [i for i, iv in enumerate(strip) if iv.thickness < limit]
        if n:
            prune = strip.thinnest(n=n, index=True)
        if percentile:
            n = np.floor(len(strip)*percentile/100)
            prune = strip.thinnest(n=n, index=True)

        if keep_ends:
            first, last = 0, len(strip) - 1
            if first in prune:
                prune.remove(first)
            if last in prune:
                prune.remove(last)

        del strip[prune]

        return strip

Response: Remove intervals below a certain limit thickness. In place.


Instruction:
Make a summary of the following Python 3 code
def anneal(self):
        strip = self.copy()

        gaps = strip.find_gaps(index=True)

        if not gaps:
            return

        for gap in gaps:
            before = strip[gap]
            after = strip[gap + 1]

            if strip.order == 'depth':
                t = (after.top.z-before.base.z)/2
                before.base = before.base.z + t
                after.top = after.top.z - t
            else:
                t = (after.base-before.top)/2
                before.top = before.top.z + t
                after.base = after.base.z - t

        return strip

Response: Fill in empty intervals by growing from top and base.


Instruction:
Can you write a function in Python 3 where it
fills the set with the component provided.

Response:
def fill(self, component=None):
        """
        Fill gaps with the component provided.

        Example
            t = s.fill(Component({'lithology': 'cheese'}))
        """
        c = [component] if component is not None else []

        # Make the intervals to go in the gaps.
        gaps = self.find_gaps()
        if not gaps:
            return self
        for iv in gaps:
            iv.components = c

        return deepcopy(self) + gaps


Instruction:
Write a Python 3 function that can
return a new striplog with all the striplogs in self and other.

Response:
def union(self, other):
        """
        Makes a striplog of all unions.

        Args:
            Striplog. The striplog instance to union with.

        Returns:
            Striplog. The result of the union.
        """
        if not isinstance(other, self.__class__):
            m = "You can only union striplogs with each other."
            raise StriplogError(m)

        result = []
        for iv in deepcopy(self):
            for jv in other:
                if iv.any_overlaps(jv):
                    iv = iv.union(jv)
            result.append(iv)
        return Striplog(result)


Instruction:
Can you write a function in Python 3 where it
takes a striplog instance and returns a striplog of all intersections with the other.

Response:
def intersect(self, other):
        """
        Makes a striplog of all intersections.

        Args:
            Striplog. The striplog instance to intersect with.

        Returns:
            Striplog. The result of the intersection.
        """
        if not isinstance(other, self.__class__):
            m = "You can only intersect striplogs with each other."
            raise StriplogError(m)

        result = []
        for iv in self:
            for jv in other:
                try:
                    result.append(iv.intersect(jv))
                except IntervalError:
                    # The intervals don't overlap
                    pass
        return Striplog(result)


Instruction:
Can you tell what is the following Python 3 function doing
def merge_overlaps(self):
        overlaps = np.array(self.find_overlaps(index=True))

        if not overlaps.any():
            return

        for overlap in overlaps:
            before = self[overlap].copy()
            after = self[overlap + 1].copy()

            # Get rid of the before and after pieces.
            del self[overlap]
            del self[overlap]

            # Make the new piece.
            new_segment = before.merge(after)

            # Insert it.
            self.__insert(overlap, new_segment)

            overlaps += 1

        return

Response:
Merges overlaps by merging overlapping Intervals.

        The function takes no arguments and returns ``None``. It operates on
        the striplog 'in place'

        TODO: This function will not work if any interval overlaps more than
            one other intervals at either its base or top.


Instruction:
Write a Python 3 function for
merging the two striplogs in which the same neighbour is unioned.

Response:
def merge_neighbours(self, strict=True):
        """
        Makes a new striplog in which matching neighbours (for which the
        components are the same) are unioned. That is, they are replaced by
        a new Interval with the same top as the uppermost and the same bottom
        as the lowermost.

        Args
            strict (bool): If True, then all of the components must match.
                If False, then only the primary must match.

        Returns:
            Striplog. A new striplog.

        TODO:
            Might need to be tweaked to deal with 'binary striplogs' if those
            aren't implemented with components.
        """
        new_strip = [self[0].copy()]

        for lower in self[1:]:

            # Determine if touching.
            touching = new_strip[-1].touches(lower)

            # Decide if match.
            if strict:
                similar = new_strip[-1].components == lower.components
            else:
                similar = new_strip[-1].primary == lower.primary

            # Union if both criteria met.
            if touching and similar:
                new_strip[-1] = new_strip[-1].union(lower)
            else:
                new_strip.append(lower.copy())

        return Striplog(new_strip)


Instruction:
Create a Python 3 function for
returning the thickest interval in the striplog.

Response:
def thickest(self, n=1, index=False):
        """
        Returns the thickest interval(s) as a striplog.

        Args:
            n (int): The number of thickest intervals to return. Default: 1.
            index (bool): If True, only the indices of the intervals are
                returned. You can use this to index into the striplog.

        Returns:
            Interval. The thickest interval. Or, if ``index`` was ``True``,
            the index of the thickest interval.
        """
        s = sorted(range(len(self)), key=lambda k: self[k].thickness)
        indices = s[-n:]
        if index:
            return indices
        else:
            if n == 1:
                # Then return an interval.
                i = indices[0]
                return self[i]
            else:
                return self[indices]


Instruction:
Implement a function in Python 3 to
plot a histogram of the components of the current node.

Response:
def hist(self,
             lumping=None,
             summary=False,
             sort=True,
             plot=True,
             legend=None,
             ax=None
             ):
        """
        Plots a histogram and returns the data for it.

        Args:
            lumping (str): If given, the bins will be lumped based on this
                attribute of the primary components of the intervals
                encountered.
            summary (bool): If True, the summaries of the components are
                returned as the bins. Otherwise, the default behaviour is to
                return the Components themselves.
            sort (bool): If True (default), the histogram is sorted by value,
                starting with the largest.
            plot (bool): If True (default), produce a bar plot.
            legend (Legend): The legend with which to colour the bars.
            ax (axis): An axis object, which will be returned if provided.
                If you don't provide one, it will be created but not returned.

        Returns:
            Tuple: A tuple of tuples of entities and counts.

        TODO:
            Deal with numeric properties, so I can histogram 'Vp' values, say.
        """
        # This seems like overkill, but collecting all this stuff gives
        # the user some choice about what they get back.
        comps = []
        labels = []
        entries = defaultdict(int)
        for i in self:
            if lumping:
                k = i.primary[lumping]
            else:
                if summary:
                    k = i.primary.summary()
                else:
                    k = i.primary
            comps.append(i.primary)
            labels.append(i.primary.summary())
            entries[k] += i.thickness

        if sort:
            allitems = sorted(entries.items(), key=lambda i: i[1], reverse=True)
            ents, counts = zip(*allitems)
        else:
            ents, counts = tuple(entries.keys()), tuple(entries.values())

        # Make plot.
        if plot:
            if ax is None:
                fig, ax = plt.subplots()
                return_ax = False
            else:
                return_ax = True
            ind = np.arange(len(ents))
            bars = ax.bar(ind, counts, align='center')
            ax.set_xticks(ind)
            ax.set_xticklabels(labels)
            if legend:
                colours = [legend.get_colour(c) for c in comps]
                for b, c in zip(bars, colours):
                    b.set_color(c)
            ax.set_ylabel('Thickness [m]')
        else:
            bars = []

        if plot and return_ax:
            return counts, ents, ax

        return counts, ents, bars


Instruction:
Can you create a Python 3 function that
makes a bar plot of thickness per interval.

Response:
def bar(self, height='thickness', sort=False, reverse=False,
            legend=None, ax=None, figsize=None, **kwargs):
        """
        Make a bar plot of thickness per interval.

        Args:
            height (str): The property of the primary component to plot.
            sort (bool or function): Either pass a boolean indicating whether
                to reverse sort by thickness, or pass a function to be used as
                the sort key.
            reverse (bool): Reverses the sort order.
            legend (Legend): The legend to plot with.
            ax (axis): Optional axis to plot to.
            figsize (tuple): A figure size, (width, height), optional.
            **kwargs: passed to the matplotlib bar plot command, ax.bar().

        Returns:
            axis: If you sent an axis in, you get it back.
        """
        if sort:
            if sort is True:
                def func(x): return x.thickness
                reverse = True
            data = sorted(self, key=func, reverse=reverse)
        else:
            data = self[:]

        if ax is None:
            fig, ax = plt.subplots(figsize=figsize)

        heights = [getattr(i, height) for i in data]

        comps = [i[0] for i in self.unique]

        if legend is None:
            legend = Legend.random(comps)

        colors = [legend.get_colour(i.primary) for i in data]

        bars = ax.bar(range(len(data)), height=heights, color=colors, **kwargs)

        # Legend.
        colourables = [i.primary.summary() for i in data]
        unique_bars = dict(zip(colourables, bars))
        ax.legend(unique_bars.values(), unique_bars.keys())

        ax.set_ylabel(height.title())

        return ax


Instruction:
Can you generate a brief explanation for the following Python 3 code
def invert(self, copy=False):
        if copy:
            return Striplog([i.invert(copy=True) for i in self])
        else:
            for i in self:
                i.invert()
            self.__sort()
            o = self.order
            self.order = {'depth': 'elevation', 'elevation': 'depth'}[o]
            return

Response: Inverts the striplog changing its order and the order of its contents.


Instruction:
Explain what the following Python 3 code does
def crop(self, extent, copy=False):
        try:
            if extent[0] is None:
                extent = (self.start.z, extent[1])
            if extent[1] is None:
                extent = (extent[0], self.stop.z)
        except:
            m = "You must provide a 2-tuple for the new extents. Use None for"
            m += " the existing start or stop."
            raise StriplogError(m)

        first_ix = self.read_at(extent[0], index=True)
        last_ix = self.read_at(extent[1], index=True)

        first = self[first_ix].split_at(extent[0])[1]
        last = self[last_ix].split_at(extent[1])[0]

        new_list = self.__list[first_ix:last_ix+1].copy()
        new_list[0] = first
        new_list[-1] = last

        if copy:
            return Striplog(new_list)
        else:
            self.__list = new_list
            return

Response: Crop the striplog to a new depth range.


Instruction:
Here you have a function in Python 3, explain what it does
def quality(self, tests, alias=None):
        # This is hacky... striplog should probably merge with welly...

        # Ignore aliases
        alias = alias or {}
        alias = alias.get('striplog', alias.get('Striplog', []))

        # Gather the tests.
        # First, anything called 'all', 'All', or 'ALL'.
        # Second, anything with the name of the curve we're in now.
        # Third, anything that the alias list has for this curve.
        # (This requires a reverse look-up so it's a bit messy.)
        this_tests =\
            tests.get('all', [])+tests.get('All', [])+tests.get('ALL', [])\
            + tests.get('striplog', tests.get('Striplog', []))\
            + utils.flatten_list([tests.get(a) for a in alias])
        this_tests = filter(None, this_tests)

        # If we explicitly set zero tests for a particular key, then this
        # overrides the 'all' tests.
        if not tests.get('striplog', tests.get('Striplog', 1)):
            this_tests = []

        return {test.__name__: test(self) for test in this_tests}

Response: Run a series of tests and return the corresponding results.


Instruction:
Here you have a function in Python 3, explain what it does
def hex_to_name(hexx):
    for n, h in defaults.COLOURS.items():
        if (len(n) > 1) and (h == hexx.upper()):
            return n.lower()
    return None

Response: Convert a hex colour to a color name using matplotlib s colour names.


Instruction:
Given the following Python 3 function, write the documentation
def loglike_from_image(filename, offset):
    im = plt.imread(filename)
    if offset < 1:
        col = int(im.shape[1] * offset)
    else:
        col = offset
    return im[:, col, :3]

Response: Get a log - like stream of RGB values from an image.


Instruction:
Create a Python 3 function to
take a log - like stream of numbers or strings and return two arrays that are the tops and values from the stream.

Response:
def tops_from_loglike(a, offset=0, null=None):
    """
    Take a log-like stream of numbers or strings, and return two arrays:
    one of the tops (changes), and one of the values from the stream.

    Args:
        loglike (array-like): The input stream of loglike data.
        offset (int): Offset (down) from top at which to get lithology,
            to be sure of getting 'clean' pixels.

    Returns:
        ndarray: Two arrays, tops and values.
    """
    a = np.copy(a)

    try:
        contains_nans = np.isnan(a).any()
    except:
        contains_nans = False

    if contains_nans:
        # Find a null value that's not in the log, and apply it if possible.
        _null = null or -1
        while _null in a:
            _null -= 1

        try:
            a[np.isnan(a)] = _null
            transformed = True
        except:
            transformed = False

    edges = a[1:] == a[:-1]
    edges = np.append(True, edges)

    tops = np.where(~edges)[0]
    tops = np.append(0, tops)

    values = a[tops + offset]

    if contains_nans and transformed:
        values[values == _null] = np.nan

    return tops, values


Instruction:
Make a summary of the following Python 3 code
def axis_transform(ax, x, y, xlim=None, ylim=None, inverse=False):
    xlim = xlim or ax.get_xlim()
    ylim = ylim or ax.get_ylim()

    xdelta = xlim[1] - xlim[0]
    ydelta = ylim[1] - ylim[0]

    if not inverse:
        xout = xlim[0] + x * xdelta
        yout = ylim[0] + y * ydelta
    else:
        xdelta2 = x - xlim[0]
        ydelta2 = y - ylim[0]
        xout = xdelta2 / xdelta
        yout = ydelta2 / ydelta

    return xout, yout

Response: Transform the data in the axis to the corresponding coordinates.


Instruction:
Write a Python 3 script for
returning an underscore if the attribute is absent.

Response:
def get_field(self, field_name, args, kwargs):
        """
        Return an underscore if the attribute is absent.
        Not all components have the same attributes.
        """
        try:
            s = super(CustomFormatter, self)
            return s.get_field(field_name, args, kwargs)
        except KeyError:    # Key is missing
            return ("_", field_name)
        except IndexError:  # Value is missing
            return ("_", field_name)


Instruction:
Can you tell what is the following Python 3 function doing
def convert_field(self, value, conversion):
        try:  # If the normal behaviour works, do it.
            s = super(CustomFormatter, self)
            return s.convert_field(value, conversion)
        except ValueError:
            funcs = {'s': str,    # Default.
                     'r': repr,   # Default.
                     'a': ascii,  # Default.
                     'u': str.upper,
                     'l': str.lower,
                     'c': str.capitalize,
                     't': str.title,
                     'm': np.mean,
                     'µ': np.mean,
                     'v': np.var,
                     'd': np.std,
                     '+': np.sum,
                     '∑': np.sum,
                     'x': np.product,
                     }
            return funcs.get(conversion)(value)

Response: Convert a value to a specific field.


Instruction:
How would you code a function in Python 3 to
return a list of all the jobs registered with Nomad.

Response:
def get_jobs(self, prefix=None):
        """ Lists all the jobs registered with Nomad.

           https://www.nomadproject.io/docs/http/jobs.html
            arguments:
              - prefix :(str) optional, specifies a string to filter jobs on based on an prefix.
                        This is specified as a querystring parameter.
            returns: list
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        params = {"prefix": prefix}
        return self.request(method="get", params=params).json()


Instruction:
Write a Python 3 script for
parsing a HCL Job file. Returns a dict with the JSON formatted job.

Response:
def parse(self, hcl, canonicalize=False):
        """ Parse a HCL Job file. Returns a dict with the JSON formatted job.
            This API endpoint is only supported from Nomad version 0.8.3.

            https://www.nomadproject.io/api/jobs.html#parse-job

            returns: dict
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        return self.request("parse", json={"JobHCL": hcl, "Canonicalize": canonicalize}, method="post", allow_redirects=True).json()


Instruction:
Can you generate a brief explanation for the following Python 3 code
def update_token(self, id, token):
        return self.request("token", id, json=token, method="post").json()

Response: Update a token in the specified account


Instruction:
Explain what the following Python 3 code does
def create_policy(self, id, policy):
        return self.request("policy", id, json=policy, method="post")

Response: Create a policy with the specified ID.


Instruction:
Can you create a Python 3 function that
updates a policy with the specified ID.

Response:
def update_policy(self, id, policy):
        """ Create policy.

            https://www.nomadproject.io/api/acl-policies.html

            arguments:
                - name
                - policy
            returns: request.Response

            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        return self.request("policy", id, json=policy, method="post")


Instruction:
Make a summary of the following Python 3 code
def get_allocations(self, prefix=None):
        params = {"prefix": prefix}
        return self.request(method="get", params=params).json()

Response: Lists all the allocations.


Instruction:
Given the following Python 3 function, write the documentation
def fail_deployment(self, id):
        fail_json = {"DeploymentID": id}
        return self.request("fail", id, json=fail_json, method="post").json()

Response: This endpoint is used to mark a deployment as failed.


Instruction:
How would you implement a function in Python 3 that
promotes all canaries for a task group to all canaries for a deployment.

Response:
def promote_deployment_all(self, id, all=True):
        """ This endpoint is used to promote task groups that have canaries for a deployment. This should be done when
            the placed canaries are healthy and the rolling upgrade of the remaining allocations should begin.

           https://www.nomadproject.io/docs/http/deployments.html

            arguments:
              - id
              - all, Specifies whether all task groups should be promoted.
            returns: dict
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        promote_all_json = {"All": all,
                            "DeploymentID": id}
        return self.request("promote", id, json=promote_all_json, method="post").json()


Instruction:
Here you have a function in Python 3, explain what it does
def promote_deployment_groups(self, id, groups=list()):
        promote_groups_json = {"Groups": groups,
                               "DeploymentID": id}
        return self.request("promote", id, json=promote_groups_json, method="post").json()

Response: Promotes the set of canaries that have been placed for a deployment.


Instruction:
Create a Python 3 function to
toggle the drain mode of the node. When enabled, no further allocations will be assigned and existing allocations will be migrated. https://www.nomadproject.io/docs/http/node.html arguments: - id (str uuid): node id - enable (bool): enable node drain or not to enable node drain returns: dict raises: - nomad.api.exceptions.BaseNomadException - nomad.api.exceptions.URLNotFoundNomadException

Response:
def drain_node(self, id, enable=False):
        """ Toggle the drain mode of the node.
            When enabled, no further allocations will be
            assigned and existing allocations will be migrated.

           https://www.nomadproject.io/docs/http/node.html

            arguments:
              - id (str uuid): node id
              - enable (bool): enable node drain or not to enable node drain
            returns: dict
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """

        return self.request(id, "drain", params={"enable": enable}, method="post").json()


Instruction:
Can you generate a brief explanation for the following Python 3 code
def drain_node_with_spec(self, id, drain_spec, mark_eligible=None):
        payload = {}

        if drain_spec and mark_eligible is not None:
            payload = {
                "NodeID": id,
                "DrainSpec": drain_spec,
                "MarkEligible": mark_eligible
            }
        elif drain_spec and mark_eligible is None:
            payload = {
                "NodeID": id,
                "DrainSpec": drain_spec
            }
        elif not drain_spec and mark_eligible is not None:
            payload = {
                "NodeID": id,
                "DrainSpec": None,
                "MarkEligible": mark_eligible
            }
        elif not drain_spec and mark_eligible is None:
            payload = {
                "NodeID": id,
                "DrainSpec": None,
            }

        return self.request(id, "drain", json=payload, method="post").json()

Response: This endpoint toggles the drain mode of a node.


Instruction:
Can you generate the documentation for the following Python 3 function
def eligible_node(self, id, eligible=None, ineligible=None):
        payload = {}

        if eligible is not None and ineligible is not None:
            raise nomad.api.exceptions.InvalidParameters
        if eligible is None and ineligible is None:
            raise nomad.api.exceptions.InvalidParameters

        if eligible is not None and eligible:
            payload = {"Eligibility": "eligible", "NodeID": id}
        elif eligible is not None and not eligible:
            payload = {"Eligibility": "ineligible", "NodeID": id}
        elif ineligible is not None:
            payload = {"Eligibility": "ineligible", "NodeID": id}
        elif ineligible is not None and not ineligible:
            payload = {"Eligibility": "eligible", "NodeID": id}

        return self.request(id, "eligibility", json=payload, method="post").json()

Response: Toggle the eligibility of the node.


Instruction:
Write a Python 3 function for
listing files in an allocation directory.

Response:
def list_files(self, id=None, path="/"):
        """ List files in an allocation directory.

           https://www.nomadproject.io/docs/http/client-fs-ls.html

            arguments:
              - id
              - path
            returns: list
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        if id:
            return self.request(id, params={"path": path}, method="get").json()
        else:
            return self.request(params={"path": path}, method="get").json()


Instruction:
Write a Python 3 function that can
read contents of a file in an allocation directory.

Response:
def read_file(self, id=None, path="/"):
        """ Read contents of a file in an allocation directory.

           https://www.nomadproject.io/docs/http/client-fs-cat.html

            arguments:
              - id
              - path
            returns: (str) text
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        if id:
            return self.request(id, params={"path": path}, method="get").text
        else:
            return self.request(params={"path": path}, method="get").text


Instruction:
How would you implement a function in Python 3 that
reads contents of a file in an allocation directory.

Response:
def read_file_offset(self, id, offset, limit, path="/"):
        """ Read contents of a file in an allocation directory.

           https://www.nomadproject.io/docs/http/client-fs-cat.html

            arguments:
              - id: (str) allocation_id required
              - offset: (int) required
              - limit: (int) required
              - path: (str) optional
            returns: (str) text
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.BadRequestNomadException
        """
        params = {
            "path": path,
            "offset": offset,
            "limit": limit
        }
        return self.request(id, params=params, method="get").text


Instruction:
Can you tell what is the following Python 3 function doing
def stream(self, id, offset, origin, path="/"):
        params = {
            "path": path,
            "offset": offset,
            "origin": origin
        }
        return self.request(id, params=params, method="get").text

Response: This endpoint streams the contents of a file in an allocation directory.


Instruction:
Can you generate the documentation for the following Python 3 function
def stream(self, id, task, type, follow=False, offset=0, origin="start", plain=False):
        params = {
            "task": task,
            "type": type,
            "follow": follow,
            "offset": offset,
            "origin": origin,
            "plain": plain
        }
        return self.request(id, params=params, method="get").text

Response: This endpoint streams a task s stderr and stdout logs from a task s allocation.


Instruction:
Implement a function in Python 3 to
initiate a join between the agent and target peers.

Response:
def join_agent(self, addresses):
        """Initiate a join between the agent and target peers.

           https://www.nomadproject.io/docs/http/agent-join.html

            returns: dict
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        params = {"address": addresses}
        return self.request("join", params=params, method="post").json()


Instruction:
Given the following Python 3 function, write the documentation
def update_servers(self, addresses):
        params = {"address": addresses}
        return self.request("servers", params=params, method="post").status_code

Response: Updates the list of known servers to the provided list.


Instruction:
Make a summary of the following Python 3 code
def force_leave(self, node):
        params = {"node": node}
        return self.request("force-leave", params=params, method="post").status_code

Response: Force a failed gossip member into the left state.


Instruction:
Make a summary of the following Python 3 code
def get_nodes(self, prefix=None):
        params = {"prefix": prefix}
        return self.request(method="get", params=params).json()

Response: Returns a list of all the client nodes that are in the cluster.


Instruction:
How would you code a function in Python 3 to
list all the evaluations on the specified resource.

Response:
def get_evaluations(self, prefix=None):
        """ Lists all the evaluations.

           https://www.nomadproject.io/docs/http/evals.html
            arguments:
              - prefix :(str) optional, specifies a string to filter evaluations on based on an prefix.
                        This is specified as a querystring parameter.
            returns: list
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        params = {"prefix": prefix}
        return self.request(method="get", params=params).json()


Instruction:
Given the following Python 3 function, write the documentation
def get_namespaces(self, prefix=None):
        params = {"prefix": prefix}
        return self.request(method="get", params=params).json()

Response: Returns a list of all the namespaces registered with Nomad.


Instruction:
Explain what the following Python 3 code does
def register_job(self, id, job):
        return self.request(id, json=job, method="post").json()

Response: Registers a new job or updates an existing job


Instruction:
Can you create a Python 3 function that
invokes a dry - run of the scheduler for the job.

Response:
def plan_job(self, id, job, diff=False, policy_override=False):
        """ Invoke a dry-run of the scheduler for the job.

           https://www.nomadproject.io/docs/http/job.html

            arguments:
              - id
              - job, dict
              - diff, boolean
              - policy_override, boolean
            returns: dict
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        json_dict = {}
        json_dict.update(job)
        json_dict.setdefault('Diff', diff)
        json_dict.setdefault('PolicyOverride', policy_override)
        return self.request(id, "plan", json=json_dict, method="post").json()


Instruction:
How would you code a function in Python 3 to
dispatch a new instance of a parameterized job.

Response:
def dispatch_job(self, id, payload=None, meta=None):
        """ Dispatches a new instance of a parameterized job.

           https://www.nomadproject.io/docs/http/job.html

            arguments:
              - id
              - payload
              - meta
            returns: dict
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        dispatch_json = {"Meta": meta, "Payload": payload}
        return self.request(id, "dispatch", json=dispatch_json, method="post").json()


Instruction:
Can you generate the documentation for the following Python 3 function
def revert_job(self, id, version, enforce_prior_version=None):
        revert_json = {"JobID": id,
                       "JobVersion": version,
                       "EnforcePriorVersion": enforce_prior_version}
        return self.request(id, "revert", json=revert_json, method="post").json()

Response: This endpoint reverts the job to an older version.


Instruction:
Implement a function in Python 3 to
query the status of a client node registered with Nomad.

Response:
def get_configuration(self, stale=False):
        """ Query the status of a client node registered with Nomad.

            https://www.nomadproject.io/docs/http/operator.html

            returns: dict
            optional arguments:
              - stale, (defaults to False), Specifies if the cluster should respond without an active leader.
                                            This is specified as a querystring parameter.
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """

        params = {"stale": stale}
        return self.request("raft", "configuration", params=params, method="get").json()


Instruction:
Can you generate a brief explanation for the following Python 3 code
def delete_peer(self, peer_address, stale=False):

        params = {"address": peer_address, "stale": stale}
        return self.request("raft", "peer", params=params, method="delete").ok

Response: Remove the Nomad server with given address from the Raft configuration.


Instruction:
Write a Python 3 function that can
update the namespace of a specific resource in a specific resource.

Response:
def update_namespace(self, id, namespace):
        """ Update namespace

           https://www.nomadproject.io/api/namespaces.html

            arguments:
              - id
              - namespace (dict)
            returns: requests.Response
            raises:
              - nomad.api.exceptions.BaseNomadException
              - nomad.api.exceptions.URLNotFoundNomadException
        """
        return self.request(id, json=namespace, method="post")


Instruction:
Explain what the following Python 3 code does
def _get_random(self, obj_type):
        return self.mutator[obj_type][random.randint(0, self.config.level)]

Response: Get a random mutator from a list of mutators


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_mutator(self, obj, obj_type):
        if obj_type == unicode:
            obj_type = str
            obj = str(obj)
        return self._get_random(obj_type)(obj)

Response: Get a random mutator for the given object type


Instruction:
Write a Python 3 script to
return a string containing the original object

Response:
def get_string_polyglot_attack(self, obj):
        """
        Return a polyglot attack containing the original object
        """
        return self.polyglot_attacks[random.choice(self.config.techniques)] % obj


Instruction:
Make a summary of the following Python 3 code
def fuzz(self, obj):
        buf = list(obj)
        FuzzFactor = random.randrange(1, len(buf))
        numwrites=random.randrange(math.ceil((float(len(buf)) / FuzzFactor)))+1
        for j in range(numwrites):
            self.random_action(buf)
        return self.safe_unicode(buf)

Response: Perform the fuzzing on the object.