Instruction:
Can you write a function in Python 3 where it
gets the height of a span in the number of newlines it fills.

Response:
def get_span_char_height(span, row_heights):
    """
    Get the height of a span in the number of newlines it fills.

    Parameters
    ----------
    span : list of list of int
        A list of [row, column] pairs that make up the span
    row_heights : list of int
        A list of the number of newlines for each row in the table

    Returns
    -------
    total_height : int
        The height of the span in number of newlines
    """
    start_row = span[0][0]
    row_count = get_span_row_count(span)
    total_height = 0

    for i in range(start_row, start_row + row_count):
        total_height += row_heights[i]
    total_height += row_count - 1

    return total_height


Instruction:
Create a Python 3 function for
converting an html table to a data table and spans.

Response:
def html2data(html_string):
    """
    Convert an html table to a data table and spans.

    Parameters
    ----------
    html_string : str
        The string containing the html table

    Returns
    -------
    table : list of lists of str
    spans : list of lists of lists of int
        A span is a list of [row, column] pairs that define what cells
        are merged in a table.
    use_headers : bool
    """
    spans = extract_spans(html_string)

    column_count = get_html_column_count(html_string)
    row_count = get_html_row_count(spans)

    count = 0
    while count < len(spans):
        if len(spans[count]) == 1:
            spans.pop(count)
        else:
            count += 1

    table = extract_table(html_string, row_count, column_count)

    use_headers = headers_present(html_string)

    return table, spans, use_headers


Instruction:
Create a Python 3 function to
return newick represenation of the tree in its current state.

Response:
def newick(self, tree_format=0):
        "Returns newick represenation of the tree in its current state."
        # checks one of root's children for features and extra feats.
        if self.treenode.children:
            features = {"name", "dist", "support", "height", "idx"}
            testnode = self.treenode.children[0]
            extrafeat = {i for i in testnode.features if i not in features}
            features.update(extrafeat)
            return self.treenode.write(format=tree_format)


Instruction:
Make a summary of the following Python 3 code
def get_edge_values(self, feature='idx'):
        elist = []
        for cidx in self._coords.edges[:, 1]:
            node = self.treenode.search_nodes(idx=cidx)[0]
            elist.append(
                (node.__getattribute__(feature) if hasattr(node, feature) else "")
                )
        return elist

Response: Returns the edge values in the order they are plotted.


Instruction:
Write a Python 3 script for
getting the edge values from a dictionary mapping node idx to values.

Response:
def get_edge_values_from_dict(self, node_value_dict=None, include_stem=True):
        """
        Enter a dictionary mapping node 'idx' or tuple of tipnames to values
        that you want mapped to the stem and descendant edges that node.
        Edge values are returned in proper plot order to be entered to the
        edge_colors or edge_widths arguments to draw(). To see node idx values
        use node_labels=True in draw(). If dictionary keys are integers it is
        assumed they are node idxs.

        Note: it is safer to use tip labels to identify clades than node idxs
        since tree tranformations (e.g., rooting) can change the mapping of
        idx values to nodes on the tree.

        This function is most convenient for applying values to clades. To
        instead map values to specific edges (e.g., a single internal edge)
        it will be easier to use tre.get_edge_values() and then to set the
        values of the internal edges manually.

        Example 1:
          tre = toytree.tree("((a,b),(c,d));")
          tre.get_edge_values_from_dict({5: 'green', 6: 'red'})
          # ['green', 'green', 'green', 'red', 'red', 'red']

        Example 2:
          tre = toytree.tree("((a,b),(c,d));")
          tre.get_edge_values_from_dict({(a, b): 'green', (c, d): 'red'})
          # ['green', 'green', 'green', 'red', 'red', 'red']
        """
        # map node idxs to the order in which edges are plotted
        idxs = {j: i for (i, j) in enumerate(self.get_edge_values())}
        values = [None] * self._coords.edges.shape[0]
        if node_value_dict is None:
            return values

        # convert tipname lists to node idxs
        rmap = {}
        for (key, val) in node_value_dict.items():
            if isinstance(key, (str, tuple)):
                node = fuzzy_match_tipnames(self, key, None, None, True, False)
                rmap[node.idx] = val
            else:
                rmap[key] = val
        node_value_dict = rmap

        # map over tree
        for node in self.treenode.traverse("levelorder"):
            if node.idx in node_value_dict:

                # add value to stem edge
                if include_stem:
                    if not node.is_root():
                        values[idxs[node.idx]] = node_value_dict[node.idx]

                # add value to descendants edges
                for desc in node.get_descendants():
                    values[idxs[desc.idx]] = node_value_dict[node.idx]
        return values


Instruction:
Can you tell what is the following Python 3 function doing
def get_mrca_idx_from_tip_labels(self, names=None, wildcard=None, regex=None):
        if not any([names, wildcard, regex]):
            raise ToytreeError("at least one argument required")
        node = fuzzy_match_tipnames(
            self, names, wildcard, regex, True, False)
        return node.idx

Response: Returns the node idx label for the most recent common ancestor node that includes the selected tips.


Instruction:
How would you implement a function in Python 3 that
gets the node values from the tree object in the tree object order.

Response:
def get_node_values(
        self,
        feature=None,
        show_root=False,
        show_tips=False,
        ):
        """
        Returns node values from tree object in node plot order. To modify
        values you must modify the .treenode object directly by setting new
        'features'. For example

        for node in ttree.treenode.traverse():
            node.add_feature("PP", 100)

        By default node and tip values are hidden (set to "") so that they
        are not shown on the tree plot. To include values for these nodes
        use the 'show_root'=True, or 'show_tips'=True arguments.

        tree.get_node_values("support", True, True)
        """
        # access nodes in the order they will be plotted
        ndict = self.get_node_dict(return_internal=True, return_nodes=True)
        nodes = [ndict[i] for i in range(self.nnodes)[::-1]]

        # get features
        if feature:
            vals = [i.__getattribute__(feature) if hasattr(i, feature)
                    else "" for i in nodes]
        else:
            vals = [" " for i in nodes]

        # apply hiding rules
        if not show_root:
            vals = [i if not j.is_root() else "" for i, j in zip(vals, nodes)]
        if not show_tips:
            vals = [i if not j.is_leaf() else "" for i, j in zip(vals, nodes)]

        # convert float to ints for prettier printing unless all floats
        # raise exception and skip if there are true strings (names)
        try:
            if all([Decimal(str(i)) % 1 == 0 for i in vals if i]):
                vals = [int(i) if isinstance(i, float) else i for i in vals]
        except Exception:
            pass

        return vals


Instruction:
How would you code a function in Python 3 to
return a dictionary mapping idx to name where idx is

Response:
def get_node_dict(self, return_internal=False, return_nodes=False):
        """
        Return node labels as a dictionary mapping {idx: name} where idx is
        the order of nodes in 'preorder' traversal. Used internally by the
        func .get_node_values() to return values in proper order.

        return_internal: if True all nodes are returned, if False only tips.
        return_nodes: if True returns TreeNodes, if False return node names.
        """
        if return_internal:
            if return_nodes:
                return {
                    i.idx: i for i in self.treenode.traverse("preorder")
                }
            else:
                return {
                    i.idx: i.name for i in self.treenode.traverse("preorder")
                }
        else:
            if return_nodes:
                return {
                    i.idx: i for i in self.treenode.traverse("preorder")
                    if i.is_leaf()
                }
            else:
                return {
                    i.idx: i.name for i in self.treenode.traverse("preorder")
                    if i.is_leaf()
                }


Instruction:
Write a Python 3 script to
return the coordinates of the tip positions for a tree.

Response:
def get_tip_coordinates(self, axis=None):
        """
        Returns coordinates of the tip positions for a tree. If no argument
        for axis then a 2-d array is returned. The first column is the x
        coordinates the second column is the y-coordinates. If you enter an
        argument for axis then a 1-d array will be returned of just that axis.
        """
        # get coordinates array
        coords = self.get_node_coordinates()
        if axis == 'x':
            return coords[:self.ntips, 0]
        elif axis == 'y':
            return coords[:self.ntips, 1]
        return coords[:self.ntips]


Instruction:
Here you have a function in Python 3, explain what it does
def get_tip_labels(self, idx=None):
        if not idx:
            return self.treenode.get_leaf_names()[::-1]
        else:
            treenode = self.treenode.search_nodes(idx=idx)[0]
            return treenode.get_leaf_names()[::-1]

Response: Returns the tip labels of the given node in the tree.


Instruction:
Can you create a Python 3 function that
returns True if there is a bifurcating entry in the tree.

Response:
def is_bifurcating(self, include_root=True):
        """
        Returns False if there is a polytomy in the tree, including if the tree
        is unrooted (basal polytomy), unless you use the include_root=False
        argument.
        """
        ctn1 = -1 + (2 * len(self))
        ctn2 = -2 + (2 * len(self))
        if self.is_rooted():
            return bool(ctn1 == sum(1 for i in self.treenode.traverse()))
        if include_root:
            return bool(ctn2 == -1 + sum(1 for i in self.treenode.traverse()))
        return bool(ctn2 == sum(1 for i in self.treenode.traverse()))


Instruction:
Write a Python 3 script for
returning a new tree with internal nodes with dist < = min_dist and support < = 50.

Response:
def collapse_nodes(self, min_dist=1e-6, min_support=0):
        """
        Returns a copy of the tree where internal nodes with dist <= min_dist
        are deleted, resulting in a collapsed tree. e.g.:

        newtre = tre.collapse_nodes(min_dist=0.001)
        newtre = tre.collapse_nodes(min_support=50)
        """
        nself = self.copy()
        for node in nself.treenode.traverse():
            if not node.is_leaf():
                if (node.dist <= min_dist) | (node.support < min_support):
                    node.delete()
        nself._coords.update()
        return nself


Instruction:
Write a Python 3 function that can
return a copy of the tree with the selected tips removed.

Response:
def drop_tips(self, names=None, wildcard=None, regex=None):
        """
        Returns a copy of the tree with the selected tips removed. The entered
        value can be a name or list of names. To prune on an internal node to
        create a subtree see the .prune() function instead.

        Parameters:
        tips: list of tip names.

        # example:
        ptre = tre.drop_tips(['a', 'b'])
        """
        # make a deepcopy of the tree
        nself = self.copy()

        # return if nothing to drop
        if not any([names, wildcard, regex]):
            return nself

        # get matching names list with fuzzy match
        tipnames = fuzzy_match_tipnames(
            ttree=nself,
            names=names,
            wildcard=wildcard,
            regex=regex,
            mrca=False,
            mono=False,
        )

        if len(tipnames) == len(nself):
            raise ToytreeError("You cannot drop all tips from the tree.")

        if not tipnames:
            raise ToytreeError("No tips selected.")

        keeptips = [i for i in nself.get_tip_labels() if i not in tipnames]
        nself.treenode.prune(keeptips, preserve_branch_length=True)
        nself._coords.update()
        return nself


Instruction:
Given the following Python 3 function, write the documentation
def rotate_node(
        self,
        names=None,
        wildcard=None,
        regex=None,
        idx=None,
        # modify_tree=False,
        ):
        """
        Returns a ToyTree with the selected node rotated for plotting.
        tip colors do not align correct currently if nodes are rotated...
        """
        # make a copy
        revd = {j: i for (i, j) in enumerate(self.get_tip_labels())}
        neworder = {}

        # get node to rotate
        treenode = fuzzy_match_tipnames(
            self, names, wildcard, regex, True, True)
        children = treenode.up.children
        names = [[j.name for j in i.get_leaves()] for i in children]
        nidxs = [[revd[i] for i in j] for j in names]

        # get size of the big clade
        move = max((len(i) for i in nidxs))
        if len(nidxs[0]) > len(nidxs[1]):
            move = min((len(i) for i in nidxs))

        # newdict
        cnames = list(itertools.chain(*names))
        tdict = {i: None for i in cnames}
        cycle = itertools.cycle(itertools.chain(*nidxs))
        for m in range(move):
            next(cycle)
        for t in cnames:
            tdict[t] = next(cycle)

        for key in revd:
            if key in tdict:
                neworder[key] = tdict[key]
            else:
                neworder[key] = revd[key]

        revd = {j: i for (i, j) in neworder.items()}
        neworder = [revd[i] for i in range(self.ntips)]

        # returns a new tree (i.e., copy) modified w/ a fixed order
        nself = ToyTree(self.newick, fixed_order=neworder)
        nself._coords.update()
        return nself

Response: Rotate a node in the ToyTree.


Instruction:
Given the following Python 3 function, write the documentation
def resolve_polytomy(
        self,
        dist=1.0,
        support=100,
        recursive=True):
        """
        Returns a copy of the tree with all polytomies randomly resolved.
        Does not transform tree in-place.
        """
        nself = self.copy()
        nself.treenode.resolve_polytomy(
            default_dist=dist,
            default_support=support,
            recursive=recursive)
        nself._coords.update()
        return nself

Response: Returns a new tree with all polytomies randomly resolved.


Instruction:
Explain what the following Python 3 code does
def unroot(self):
        nself = self.copy()
        nself.treenode.unroot()
        nself.treenode.ladderize()
        nself._coords.update()
        return nself

Response: Returns a copy of the tree unrooted. Does not transform tree in - place.


Instruction:
Explain what the following Python 3 code does
def root(self, names=None, wildcard=None, regex=None):
        # make a deepcopy of the tree
        nself = self.copy()

        # get treenode of the common ancestor of selected tips
        try:
            node = fuzzy_match_tipnames(
                nself, names, wildcard, regex, True, True)

        except ToytreeError:
            # try reciprocal taxon list
            tipnames = fuzzy_match_tipnames(
                nself, names, wildcard, regex, False, False)
            tipnames = list(set(self.get_tip_labels()) - set(node))
            node = fuzzy_match_tipnames(
                nself, tipnames, None, None, True, True)

        # split root node if more than di- as this is the unrooted state
        if not nself.is_bifurcating():
            nself.treenode.resolve_polytomy()

        # root the object with ete's translate
        nself.treenode.set_outgroup(node)
        nself._coords.update()

        # get features
        testnode = nself.treenode.get_leaves()[0]
        features = {"name", "dist", "support", "height"}
        extrafeat = {i for i in testnode.features if i not in features}
        features.update(extrafeat)

        # if there is a new node now, clean up its features
        nnode = [i for i in nself.treenode.traverse() if not hasattr(i, "idx")]
        if nnode:
            # nnode is the node that was added
            # rnode is the location where it *should* have been added
            nnode = nnode[0]
            rnode = [i for i in nself.treenode.children if i != node][0]

            # get idxs of existing nodes
            idxs = [int(i.idx) for i in nself.treenode.traverse()
                    if hasattr(i, "idx")]

            # newnode is a tip
            if len(node.is_leaf()) == 1:
                nnode.name = str("rerooted")
                rnode.name = node
                rnode.add_feature("idx", max(idxs) + 1)
                rnode.dist *= 2
                sister = rnode.get_sisters()[0]
                sister.dist *= 2
                rnode.support = 100
                for feature in extrafeat:
                    nnode.add_feature(feature, getattr(rnode, feature))
                    rnode.del_feature(feature)

            # newnode is internal
            else:
                nnode.add_feature("idx", max(idxs) + 1)
                nnode.name = str("rerooted")
                nnode.dist *= 2
                sister = nnode.get_sisters()[0]
                sister.dist *= 2
                nnode.support = 100

        # store tree back into newick and reinit Toytree with new newick
        # if NHX format then preserve the NHX features.
        nself.treenode.ladderize()
        nself._coords.update()
        return nself

Response: Return a new tree with the rooted state.


Instruction:
Can you tell what is the following Python 3 function doing
def draw(
        self,
        tree_style=None,
        height=None,
        width=None,
        axes=None,
        orient=None,
        tip_labels=None,
        tip_labels_colors=None,
        tip_labels_style=None,
        tip_labels_align=None,
        node_labels=None,
        node_labels_style=None,
        node_sizes=None,
        node_colors=None,
        node_style=None,
        node_hover=None,
        node_markers=None,
        edge_colors=None,
        edge_widths=None,
        edge_type=None,
        edge_style=None,
        edge_align_style=None,
        use_edge_lengths=None,
        scalebar=None,
        padding=None,
        xbaseline=0,
        ybaseline=0,
        **kwargs):
        """
        Plot a Toytree tree, returns a tuple of Toyplot (Canvas, Axes) objects.

        Parameters:
        -----------
        tree_style: str
            One of several preset styles for tree plotting. The default is 'n'
            (normal). Other options inlude 'c' (coalescent), 'd' (dark), and
            'm' (multitree). You also create your own TreeStyle objects.
            The tree_style sets a default set of styling on top of which other
            arguments passed to draw() will override when plotting.

        height: int (optional; default=None)
            If None the plot height is autosized. If 'axes' arg is used then
            tree is drawn on an existing Canvas, Axes and this arg is ignored.

        width: int (optional; default=None)
            Similar to height (above).

        axes: Toyplot.Cartesian (default=None)
            A toyplot cartesian axes object. If provided tree is drawn on it.
            If not provided then a new Canvas and Cartesian axes are created
            and returned with the tree plot added to it.

        use_edge_lengths: bool (default=False)
            Use edge lengths from .treenode (.get_edge_lengths) else
            edges are set to length >=1 to make tree ultrametric.

        tip_labels: [True, False, list]
            If True then the tip labels from .treenode are added to the plot.
            If False no tip labels are added. If a list of tip labels
            is provided it must be the same length as .get_tip_labels().

        tip_labels_colors:
            ...

        tip_labels_style:
            ...

        tip_labels_align:
            ...

        node_labels: [True, False, list]
            If True then nodes are shown, if False then nodes are suppressed
            If a list of node labels is provided it must be the same length
            and order as nodes in .get_node_values(). Node labels can be
            generated in the proper order using the the .get_node_labels()
            function from a Toytree tree to draw info from the tree features.
            For example: node_labels=tree.get_node_labels("support").

        node_sizes: [int, list, None]
            If None then nodes are not shown, otherwise, if node_labels
            then node_size can be modified. If a list of node sizes is
            provided it must be the same length and order as nodes in
            .get_node_dict().

        node_colors: [list]
            Use this argument only if you wish to set different colors for
            different nodes, in which case you must enter a list of colors
            as string names or HEX values the length and order of nodes in
            .get_node_dict(). If all nodes will be the same color then use
            instead the node_style dictionary:
            e.g., node_style={"fill": 'red'}

        node_style: [dict]

        ...

        node_hover: [True, False, list, dict]
            Default is True in which case node hover will show the node
            values. If False then no hover is shown. If a list or dict
            is provided (which should be in node order) then the values
            will be shown in order. If a dict then labels can be provided
            as well.
        """
        # allow ts as a shorthand for tree_style
        if kwargs.get("ts"):
            tree_style = kwargs.get("ts")

        # pass a copy of this tree so that any mods to .style are not saved
        nself = deepcopy(self)
        if tree_style:
            nself.style.update(TreeStyle(tree_style[0]))

        # update kwargs to merge it with user-entered arguments:
        userargs = {
            "height": height,
            "width": width,
            "orient": orient,
            "tip_labels": tip_labels,
            "tip_labels_colors": tip_labels_colors,
            "tip_labels_align": tip_labels_align,
            "tip_labels_style": tip_labels_style,
            "node_labels": node_labels,
            "node_labels_style": node_labels_style,
            "node_sizes": node_sizes,
            "node_colors": node_colors,
            "node_hover": node_hover,
            "node_style": node_style,
            "node_markers": node_markers,
            "edge_type": edge_type,
            "edge_colors": edge_colors,
            "edge_widths": edge_widths,
            "edge_style": edge_style,
            "edge_align_style": edge_align_style,
            "use_edge_lengths": use_edge_lengths,
            "scalebar": scalebar,
            "padding": padding,
            "xbaseline": xbaseline,
            "ybaseline": ybaseline,
        }
        kwargs.update(userargs)
        censored = {i: j for (i, j) in kwargs.items() if j is not None}
        nself.style.update(censored)

        # warn user if they entered kwargs that weren't recognized:
        unrecognized = [i for i in kwargs if i not in userargs]
        if unrecognized:
            print("unrecognized arguments skipped: {}".format(unrecognized))
            print("check the docs, argument names may have changed.")

        # Init Drawing class object.
        draw = Drawing(nself)

        # Debug returns the object to test with.
        if kwargs.get("debug"):
            return draw

        # Make plot. If user provided explicit axes then include them.
        canvas, axes = draw.update(axes=axes)
        return canvas, axes

Response: Function to draw a Toytree tree.


Instruction:
Write a Python 3 function that can
return the direction of the merge between two cells.

Response:
def get_merge_direction(cell1, cell2):
    """
    Determine the side of cell1 that can be merged with cell2.

    This is based on the location of the two cells in the table as well
    as the compatability of their height and width.

    For example these cells can merge::

         cell1    cell2      merge "RIGHT"

        +-----+  +------+   +-----+------+
        | foo |  | dog  |   | foo | dog  |
        |     |  +------+   |     +------+
        |     |  | cat  |   |     | cat  |
        |     |  +------+   |     +------+
        |     |  | bird |   |     | bird |
        +-----+  +------+   +-----+------+

    But these cells cannot merge::

        +-----+  +------+
        | foo |  | dog  |
        |     |  +------+
        |     |  | cat  |
        |     |  +------+
        |     |
        +-----+

    Parameters
    ----------
    cell1 : dashtable.data2rst.Cell
    cell2 : dashtable.data2rst.Cell

    Returns
    -------
    str
        The side onto which cell2 can be merged. Will be one of
        ["LEFT", "RIGHT", "BOTTOM", "TOP", "NONE"]
    """
    cell1_left = cell1.column
    cell1_right = cell1.column + cell1.column_count
    cell1_top = cell1.row
    cell1_bottom = cell1.row + cell1.row_count

    cell2_left = cell2.column
    cell2_right = cell2.column + cell2.column_count
    cell2_top = cell2.row
    cell2_bottom = cell2.row + cell2.row_count

    if (cell1_right == cell2_left and cell1_top == cell2_top and
            cell1_bottom == cell2_bottom and
            cell1.right_sections >= cell2.left_sections):
        return "RIGHT"

    elif (cell1_left == cell2_left and cell1_right == cell2_right and
            cell1_top == cell2_bottom and
            cell1.top_sections >= cell2.bottom_sections):
        return "TOP"

    elif (cell1_left == cell2_left and
          cell1_right == cell2_right and
          cell1_bottom == cell2_top and
          cell1.bottom_sections >= cell2.top_sections):
        return "BOTTOM"

    elif (cell1_left == cell2_right and
          cell1_top == cell2_top and
          cell1_bottom == cell2_bottom and
          cell1.left_sections >= cell2.right_sections):
        return "LEFT"

    else:
        return "NONE"


Instruction:
Explain what the following Python 3 code does
def parse_nhx(NHX_string):
    # store features
    ndict = {}

    # parse NHX or MB features
    if "[&&NHX:" in NHX_string:
        NHX_string = NHX_string.replace("[&&NHX:", "")
        NHX_string = NHX_string.replace("]", "")

        for field in NHX_string.split(":"):
            try:
                pname, pvalue = field.split("=")
                ndict[pname] = pvalue
            except ValueError as e:
                raise NewickError('Invalid NHX format %s' % field)
    return ndict

Response: Parse NHX string into a dictionary.


Instruction:
How would you explain what the following Python 3 function does
def get_data_from_intree(self):

        # load string: filename or data stream
        if isinstance(self.intree, (str, bytes)):

            # strip it
            self.intree = self.intree.strip()

            # is a URL: make a list by splitting a string
            if any([i in self.intree for i in ("http://", "https://")]):
                response = requests.get(self.intree)
                response.raise_for_status()
                self.data = response.text.strip().split("\n")

            # is a file: read by lines to a list
            elif os.path.exists(self.intree):
                with open(self.intree, 'rU') as indata:
                    self.data = indata.readlines()

            # is a string: make into a list by splitting
            else:
                self.data = self.intree.split("\n")

        # load iterable: iterable of newick strings
        elif isinstance(self.intree, (list, set, tuple)):
            self.data = list(self.intree)

Response: Load the data from an internal file or string and return as a list of strings.


Instruction:
Here you have a function in Python 3, explain what it does
def parse_nexus(self):
        "get newick data from NEXUS"
        if self.data[0].strip().upper() == "#NEXUS":
            nex = NexusParser(self.data)
            self.data = nex.newicks
            self.tdict = nex.tdict

Response: get newick data from NEXUS


Instruction:
Can you create a Python 3 function that
tests format of intree nex / nwk extra features

Response:
def get_treenodes(self):
        "test format of intree nex/nwk, extra features"

        if not self.multitree:
            # get TreeNodes from Newick
            extractor = Newick2TreeNode(self.data[0].strip(), fmt=self.fmt)

            # extract one tree
            self.treenodes.append(extractor.newick_from_string())

        else:
            for tre in self.data:
                # get TreeNodes from Newick
                extractor = Newick2TreeNode(tre.strip(), fmt=self.fmt)

                # extract one tree
                self.treenodes.append(extractor.newick_from_string())


Instruction:
Write a Python 3 script for
reading a newick string in the New Hampshire format.

Response:
def newick_from_string(self):
        "Reads a newick string in the New Hampshire format."

        # split on parentheses to traverse hierarchical tree structure
        for chunk in self.data.split("(")[1:]:
            # add child to make this node a parent.
            self.current_parent = (
                self.root if self.current_parent is None else
                self.current_parent.add_child()
            )

            # get all parenth endings from this parenth start
            subchunks = [ch.strip() for ch in chunk.split(",")]
            if subchunks[-1] != '' and not subchunks[-1].endswith(';'):
                raise NewickError(
                    'Broken newick structure at: {}'.format(chunk))

            # Every closing parenthesis will close a node and go up one level.
            for idx, leaf in enumerate(subchunks):
                if leaf.strip() == '' and idx == len(subchunks) - 1:
                    continue
                closing_nodes = leaf.split(")")

                # parse features and apply to the node object
                self.apply_node_data(closing_nodes[0], "leaf")

                # next contain closing nodes and data about the internal nodes.
                if len(closing_nodes) > 1:
                    for closing_internal in closing_nodes[1:]:
                        closing_internal = closing_internal.rstrip(";")
                        # read internal node data and go up one level
                        self.apply_node_data(closing_internal, "internal")
                        self.current_parent = self.current_parent.up
        return self.root


Instruction:
Write a Python 3 function that can
iterate through data file to extract trees

Response:
def extract_tree_block(self):
        "iterate through data file to extract trees"

        lines = iter(self.data)
        while 1:
            try:
                line = next(lines).strip()
            except StopIteration:
                break

            # enter trees block
            if line.lower() == "begin trees;":
                while 1:
                    # iter through trees block
                    sub = next(lines).strip().split()

                    # skip if a blank line
                    if not sub:
                        continue

                    # look for translation
                    if sub[0].lower() == "translate":
                        while sub[0] != ";":
                            sub = next(lines).strip().split()
                            self.tdict[sub[0]] = sub[-1].strip(",")

                    # parse tree blocks
                    if sub[0].lower().startswith("tree"):
                        self.newicks.append(sub[-1])

                    # end of trees block
                    if sub[0].lower() == "end;":
                        break


Instruction:
How would you implement a function in Python 3 that
parses command - line arguments and return a list of tuples.

Response:
def parse_command_line():
    """ Parse CLI args."""

    ## create the parser
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
  * Example command-line usage:

  ## push test branch to conda --label=conda-test for travis CI
  ./versioner.py -p toytree -b test -t 0.1.7

  ## push master as a new tag to git and conda
  ./versioner.py -p toytree -b master -t 0.1.7 --deploy

  ## build other deps on conda at --label=conda-test
  ./versioner.py -p toyplot --no-git
  ./versioner.py -p pypng --no-git

    """)

    ## add arguments
    parser.add_argument('-v', '--version', action='version',
        version="0.1")

    parser.add_argument('-p', #"--package",
        dest="package",
        default="toytree",
        type=str,
        help="the tag to put in __init__ and use on conda")

    parser.add_argument('-b', #"--branch",
        dest="branch",
        default="master",
        type=str,
        help="the branch to build conda package from")

    parser.add_argument('-t', #"--tag",
        dest="tag",
        default="test",
        type=str,
        help="the tag to put in __init__ and use on conda")

    parser.add_argument("--deploy",
        dest="deploy",
        action='store_true',
        help="push the tag to git and upload to conda main label")

    parser.add_argument("--no-git",
        dest="nogit",
        action='store_true',
        help="skip git update and only build/upload to conda")

    ## if no args then return help message
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    ## parse args
    args = parser.parse_args()
    return args


Instruction:
Create a Python 3 function to
get git and init versions and commits since the init version

Response:
def get_git_status(self):
        """
        Gets git and init versions and commits since the init version
        """
        ## get git branch
        self._get_git_branch()

        ## get tag in the init file
        self._get_init_release_tag()

        ## get log commits since <tag>
        try:
            self._get_log_commits()
        except Exception as inst:
            raise Exception(
        """
        Error: the version in __init__.py is {}, so 'git log' is
        looking for commits that have happened since that version, but
        it appears there is not existing tag for that version. You may
        need to roll back the version in __init__.py to what is actually
        commited. Check with `git tag`.
        --------
        {}
        """.format(self.init_version, inst))

        ## where are we at?
        print("__init__.__version__ == '{}':".format(self.init_version))
        print("'{}' is {} commits ahead of origin/{}"
              .format(self.tag, len(self.commits), self.init_version))


Instruction:
Write a Python 3 function for
pushing git package to local files

Response:
def push_git_package(self):
        """
        if no conflicts then write new tag to
        """
        ## check for conflicts, then write to local files
        self._pull_branch_from_origin()

        ## log commits to releasenotes
        if self.deploy:
            self._write_commits_to_release_notes()

        ## writes tag or 'devel' to
        try:
            self._write_new_tag_to_init()
            self._write_branch_and_tag_to_meta_yaml()
            self._push_new_tag_to_git()

        except Exception as inst:
            print("\n Error:\n", inst)
            self._revert_tag_in_init()
            sys.exit(2)


Instruction:
Explain what the following Python 3 code does
def _pull_branch_from_origin(self):
        try:
            ## self.repo.git.pull()
            subprocess.check_call(["git", "pull", "origin", self.branch])
        except Exception as inst:
            sys.exit("""
        Your HEAD commit conflicts with origin/{tag}.
        Resolve, merge, and rerun versioner.py
        """)

Response: Pulls branch from origin


Instruction:
Given the following Python 3 function, write the documentation
def _get_init_release_tag(self):
        self.init_version = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
                                      open(self.init_file, "r").read(),
                                      re.M).group(1)

Response: Parses the init. py file to get the previous version


Instruction:
Given the following Python 3 function, write the documentation
def _get_log_commits(self):
        ## check if update is necessary
        cmd = "git log --pretty=oneline {}..".format(self.init_version)
        cmdlist = shlex.split(cmd)
        commits = subprocess.check_output(cmdlist)

        ## Split off just the first element, we don't need commit tag
        self.commits = [x.split(" ", 1) for x in commits.split("\n")]

Response: Get the commits from git log


Instruction:
Can you tell what is the following Python 3 function doing
def _write_commits_to_release_notes(self):
        with open(self.release_file, 'a') as out:
            out.write("==========\n{}\n".format(self.tag))
            for commit in self.commits:
                try:
                    msg = commit[1]
                    if msg != "cosmetic":
                        out.write("-" + msg + "\n")
                except:
                    pass

Response: Writes commits to the releasenotes file by appending to the end


Instruction:
Can you create a Python 3 function that
writes new version to __init__. py by editing in place

Response:
def _write_new_tag_to_init(self):
        """
        Write version to __init__.py by editing in place
        """
        for line in fileinput.input(self.init_file, inplace=1):
            if line.strip().startswith("__version__"):
                line = "__version__ = \"" + self.tag + "\""
            print(line.strip("\n"))


Instruction:
Explain what the following Python 3 code does
def _write_branch_and_tag_to_meta_yaml(self):
        ## set the branch to pull source from
        with open(self.meta_yaml.replace("meta", "template"), 'r') as infile:
            dat = infile.read()
            newdat = dat.format(**{'tag': self.tag, 'branch': self.branch})

        with open(self.meta_yaml, 'w') as outfile:
            outfile.write(newdat)

Response: Write branch and tag to meta. yaml by editing in place


Instruction:
How would you explain what the following Python 3 function does
def _revert_tag_in_init(self):
        for line in fileinput.input(self.init_file, inplace=1):
            if line.strip().startswith("__version__"):
                line = "__version__ = \"" + self.init_version + "\""
            print(line.strip("\n"))

        print("reverted __init__.__version__ back to {}"
              .format(self.init_version))

Response: Revert the version of the __init__. py file in place.


Instruction:
Can you generate the documentation for the following Python 3 function
def _push_new_tag_to_git(self):
        print("Pushing new version to git")

        ## stage the releasefile and initfileb
        subprocess.call(["git", "add", self.release_file])
        subprocess.call(["git", "add", self.init_file])
        subprocess.call([
            "git", "commit", "-m", "Updating {}/__init__.py to version {}"\
            .format(self.package, self.tag)])

        ## push changes to origin <tracked branch>
        subprocess.call(["git", "push", "origin", self.branch])

        ## create a new tag for the version number on deploy
        if self.deploy:
            subprocess.call([
                "git", "tag", "-a", self.tag,
                "-m", "Updating version to {}".format(self.tag),
                ])
            subprocess.call(["git", "push", "origin"])

Response: Push a new release file and init file to git


Instruction:
Can you create a Python 3 function that
runs the Linux build and use converter to build OSX copies

Response:
def build_conda_packages(self):
        """
        Run the Linux build and use converter to build OSX
        """
        ## check if update is necessary
        #if self.nversion == self.pversion:
        #    raise SystemExit("Exited: new version == existing version")

        ## tmp dir
        bldir = "./tmp-bld"
        if not os.path.exists(bldir):
            os.makedirs(bldir)

        ## iterate over builds
        for pybuild in ["2.7", "3"]:

            ## build and upload Linux to anaconda.org
            build = api.build(
                "conda-recipe/{}".format(self.package),
                 python=pybuild)

            ## upload Linux build
            if not self.deploy:
                cmd = ["anaconda", "upload", build[0], "--label", "test", "--force"]
            else:
                cmd = ["anaconda", "upload", build[0]]
            err = subprocess.Popen(cmd).communicate()

            ## build OSX copies
            api.convert(build[0], output_dir=bldir, platforms=["osx-64"])
            osxdir = os.path.join(bldir, "osx-64", os.path.basename(build[0]))
            if not self.deploy:
                cmd = ["anaconda", "upload", osxdir, "--label", "test", "--force"]
            else:
                cmd = ["anaconda", "upload", osxdir]
            err = subprocess.Popen(cmd).communicate()

        ## cleanup tmpdir
        shutil.rmtree(bldir)


Instruction:
How would you code a function in Python 3 to
get the number of rows included in a span in a node - level node - tree tree

Response:
def get_span_row_count(span):
    """
    Gets the number of rows included in a span

    Parameters
    ----------
    span : list of lists of int
        The [row, column] pairs that make up the span

    Returns
    -------
    rows : int
        The number of rows included in the span

    Example
    -------
    Consider this table::

        +--------+-----+
        | foo    | bar |
        +--------+     |
        | spam   |     |
        +--------+     |
        | goblet |     |
        +--------+-----+

    ::

        >>> span = [[0, 1], [1, 1], [2, 1]]
        >>> print(get_span_row_count(span))
        3
    """
    rows = 1
    first_row = span[0][0]

    for i in range(len(span)):
        if span[i][0] > first_row:
            rows += 1
            first_row = span[i][0]

    return rows


Instruction:
Here you have a function in Python 3, explain what it does
def asarray(x, dtype=None):
    '''Convert ``x`` into a ``numpy.ndarray``.'''
    iterable = scalarasiter(x)
    if isinstance(iterable, ndarray):
        return iterable
    else:
        if not hasattr(iterable, '__len__'):
            iterable = list(iterable)
        if dtype == object_type:
            a = ndarray((len(iterable),), dtype=dtype)
            for i,v in enumerate(iterable):
                a[i] = v
            return a
        else:
            return array(iterable, dtype=dtype)

Response: Convert x into a numpy. ndarray.


Instruction:
How would you explain what the following Python 3 function does
def ascolumn(x, dtype = None):
    '''Convert ``x`` into a ``column``-type ``numpy.ndarray``.'''
    x = asarray(x, dtype)
    return x if len(x.shape) >= 2 else x.reshape(len(x),1)

Response: Convert x into a column - type numpy. ndarray.


Instruction:
Can you generate the documentation for the following Python 3 function
def multis_2_mono(table):
    for row in range(len(table)):
        for column in range(len(table[row])):
            table[row][column] = table[row][column].replace('\n', ' ')

    return table

Response: Converts each multiline string in a table to single line.


Instruction:
Explain what the following Python 3 code does
def get_html_row_count(spans):

    if spans == []:
        return 0
    row_counts = {}
    for span in spans:
        span = sorted(span)
        try:
            row_counts[str(span[0][1])] += get_span_row_count(span)
        except KeyError:
            row_counts[str(span[0][1])] = get_span_row_count(span)

    values = list(row_counts.values())
    return max(values)

Response: Get the number of rows in a list of spans


Instruction:
Make a summary of the following Python 3 code
def levenshtein_distance(word1, word2):
    if len(word1) < len(word2):
        return levenshtein_distance(word2, word1)

    if len(word2) == 0:
        return len(word1)

    previous_row = list(range(len(word2) + 1))

    for i, char1 in enumerate(word1):
        current_row = [i + 1]

        for j, char2 in enumerate(word2):
            insertions = previous_row[j + 1] + 1
            deletions = current_row[j] + 1
            substitutions = previous_row[j] + (char1 != char2)

            current_row.append(min(insertions, deletions, substitutions))

        previous_row = current_row
    return previous_row[-1]

Response: Computes the Levenshtein distance between two words.


Instruction:
Can you implement a function in Python 3 that
rolls Z - Score statistics.

Response:
def zscore(ts, **kwargs):
    '''Rolling Z-Score statistics.
    The Z-score is more formally known as ``standardised residuals``.
    To calculate the standardised residuals of a data set,
    the average value and the standard deviation of the data value
    have to be estimated.

    .. math::

        z = \frac{x - \mu(x)}{\sigma(x)}
    '''
    m = ts.rollmean(**kwargs)
    s = ts.rollstddev(**kwargs)
    result = (ts - m)/s
    name = kwargs.get('name', None)
    if name:
        result.name = name
    return result


Instruction:
Explain what the following Python 3 code does
def prange(ts, **kwargs):
    '''Rolling Percentage range.

    Value between 0 and 1 indicating the position in the rolling range.
    '''
    mi = ts.rollmin(**kwargs)
    ma = ts.rollmax(**kwargs)
    return (ts - mi)/(ma - mi)

Response: Returns the rolling percentage of the sequence in a given time series.


Instruction:
Can you create a Python 3 function that
combines the values from two map objects using the indx values using the op operator.

Response:
def binOp(op, indx, amap, bmap, fill_vec):
    '''
    Combines the values from two map objects using the indx values
    using the op operator. In situations where there is a missing value
    it will use the callable function handle_missing
    '''
    def op_or_missing(id):
        va = amap.get(id, None)
        vb = bmap.get(id, None)
        if va is None or vb is None:
            # This should create as many elements as the number of columns!?
            result = fill_vec
        else:
            try:
                result = op(va, vb)
            except Exception:
                result = None
            if result is None:
                result = fill_vec
            return result
    seq_arys = map(op_or_missing, indx)
    data = np.vstack(seq_arys)
    return data


Instruction:
Explain what the following Python 3 code does
def _toVec(shape, val):
    '''
    takes a single value and creates a vecotor / matrix with that value filled
    in it
    '''
    mat = np.empty(shape)
    mat.fill(val)
    return mat

Response: Returns a vecotor matrix filled with a single value


Instruction:
Create a Python 3 function to
center a line within a given allowed character width.

Response:
def center_line(space, line):
    """
    Add leading & trailing space to text to center it within an allowed
    width

    Parameters
    ----------
    space : int
        The maximum character width allowed for the text. If the length
        of text is more than this value, no space will be added.\
    line : str
        The text that will be centered.

    Returns
    -------
    line : str
        The text with the leading space added to it
    """
    line = line.strip()

    left_length = math.floor((space - len(line)) / 2)
    right_length = math.ceil((space - len(line)) / 2)

    left_space = " " * int(left_length)
    right_space = " " * int(right_length)

    line = ''.join([left_space, line, right_space])

    return line


Instruction:
Given the following Python 3 function, write the documentation
def register(self, function):
        function = inspect.isclass(function) and function() or function
        name = function.name
        self[name] = function

Response: Register a function in the registry.


Instruction:
Given the following Python 3 function, write the documentation
def unregister(self, name):
        try:
            name = name.name
        except AttributeError:
            pass
        return self.pop(name,None)

Response: Unregister function by name.


Instruction:
Here you have a function in Python 3, explain what it does
def row_includes_spans(table, row, spans):
    for column in range(len(table[row])):
        for span in spans:
            if [row, column] in span:
                return True
    return False

Response: Determines if a row includes spans within a row.


Instruction:
Given the following Python 3 function, write the documentation
def _setup_states(state_definitions, prev=()):
    states = list(prev)
    for state_def in state_definitions:
        if len(state_def) != 2:
            raise TypeError(
                "The 'state' attribute of a workflow should be "
                "a two-tuple of strings; got %r instead." % (state_def,)
            )
        name, title = state_def
        state = State(name, title)
        if any(st.name == name for st in states):
            # Replacing an existing state
            states = [state if st.name == name else st for st in states]
        else:
            states.append(state)
    return StateList(states)

Response: Create a StateList object from a states workflow attribute.


Instruction:
Write a Python 3 script for
creating a TransitionList object from a transitions workflow attribute.

Response:
def _setup_transitions(tdef, states, prev=()):
    """Create a TransitionList object from a 'transitions' Workflow attribute.

    Args:
        tdef: list of transition definitions
        states (StateList): already parsed state definitions.
        prev (TransitionList): transition definitions from a parent.

    Returns:
        TransitionList: the list of transitions defined in the 'tdef' argument.
    """
    trs = list(prev)
    for transition in tdef:
        if len(transition) == 3:
            (name, source, target) = transition
            if is_string(source) or isinstance(source, State):
                source = [source]
            source = [states[src] for src in source]
            target = states[target]
            tr = Transition(name, source, target)
        else:
            raise TypeError(
                "Elements of the 'transition' attribute of a "
                "workflow should be three-tuples; got %r instead." % (transition,)
            )

        if any(prev_tr.name == tr.name for prev_tr in trs):
            # Replacing an existing state
            trs = [tr if prev_tr.name == tr.name else prev_tr for prev_tr in trs]
        else:
            trs.append(tr)
    return TransitionList(trs)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def transition(trname='', field='', check=None, before=None, after=None):
    if is_callable(trname):
        raise ValueError(
            "The @transition decorator should be called as "
            "@transition(['transition_name'], **kwargs)")
    if check or before or after:
        warnings.warn(
            "The use of check=, before= and after= in @transition decorators is "
            "deprecated in favor of @transition_check, @before_transition and "
            "@after_transition decorators.",
            DeprecationWarning,
            stacklevel=2)
    return TransitionWrapper(trname, field=field, check=check, before=before, after=after)

Response: Decorator to declare a function as a transition implementation.


Instruction:
Given the following Python 3 function, write the documentation
def _make_hook_dict(fun):
    if not hasattr(fun, 'xworkflows_hook'):
        fun.xworkflows_hook = {
            HOOK_BEFORE: [],
            HOOK_AFTER: [],
            HOOK_CHECK: [],
            HOOK_ON_ENTER: [],
            HOOK_ON_LEAVE: [],
        }
    return fun.xworkflows_hook

Response: Ensure the given function has a xworkflows_hook attribute.


Instruction:
Given the following Python 3 function, write the documentation
def _match_state(self, state):
        return (self.names == '*'
                or state in self.names
                or state.name in self.names)

Response: Checks whether a given State matches self. names.


Instruction:
Create a Python 3 function for
checking whether a given Transition matches self. names.

Response:
def _match_transition(self, transition):
        """Checks whether a given Transition matches self.names."""
        return (self.names == '*'
                or transition in self.names
                or transition.name in self.names)


Instruction:
Here you have a function in Python 3, explain what it does
def applies_to(self, transition, from_state=None):
        if '*' in self.names:
            return True
        elif self.kind in (HOOK_BEFORE, HOOK_AFTER, HOOK_CHECK):
            return self._match_transition(transition)
        elif self.kind == HOOK_ON_ENTER:
            return self._match_state(transition.target)
        elif from_state is None:
            # Testing whether the hook may apply to at least one source of the
            # transition
            return any(self._match_state(src) for src in transition.source)
        else:
            return self._match_state(from_state)

Response: Returns True if this hook applies to the given transition.


Instruction:
Make a summary of the following Python 3 code
def _pre_transition_checks(self):
        current_state = getattr(self.instance, self.field_name)
        if current_state not in self.transition.source:
            raise InvalidTransitionError(
                "Transition '%s' isn't available from state '%s'." %
                (self.transition.name, current_state.name))

        for check in self._filter_hooks(HOOK_CHECK):
            if not check(self.instance):
                raise ForbiddenTransition(
                    "Transition '%s' was forbidden by "
                    "custom pre-transition check." % self.transition.name)

Response: Run the pre - transition checks.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _filter_hooks(self, *hook_kinds):
        hooks = sum((self.hooks.get(kind, []) for kind in hook_kinds), [])
        return sorted(hook for hook in hooks
                      if hook.applies_to(self.transition, self.current_state))

Response: Filter a list of hooks keeping only applicable ones.


Instruction:
Can you generate the documentation for the following Python 3 function
def _post_transition(self, result, *args, **kwargs):
        for hook in self._filter_hooks(HOOK_AFTER, HOOK_ON_ENTER):
            hook(self.instance, result, *args, **kwargs)

Response: Performs post - transition actions.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def load_parent_implems(self, parent_implems):
        for trname, attr, implem in parent_implems.get_custom_implementations():
            self.implementations[trname] = implem.copy()
            self.transitions_at[trname] = attr
            self.custom_implems.add(trname)

Response: Import previously defined implementations.


Instruction:
Implement a Python 3 function for
adding an implementation. Args: transition (Transition): the transition for which the implementation is added attribute (str): the name of the attribute where the implementation will be available function (callable): the actual implementation function **kwargs: extra arguments for the related ImplementationProperty.

Response:
def add_implem(self, transition, attribute, function, **kwargs):
        """Add an implementation.

        Args:
            transition (Transition): the transition for which the implementation
                is added
            attribute (str): the name of the attribute where the implementation
                will be available
            function (callable): the actual implementation function
            **kwargs: extra arguments for the related ImplementationProperty.
        """
        implem = ImplementationProperty(
            field_name=self.state_field,
            transition=transition,
            workflow=self.workflow,
            implementation=function,
            **kwargs)
        self.implementations[transition.name] = implem
        self.transitions_at[transition.name] = attribute
        return implem


Instruction:
Create a Python 3 function to
decide whether a given value should be collected.

Response:
def should_collect(self, value):
        """Decide whether a given value should be collected."""
        return (
            # decorated with @transition
            isinstance(value, TransitionWrapper)
            # Relates to a compatible transition
            and value.trname in self.workflow.transitions
            # Either not bound to a state field or bound to the current one
            and (not value.field or value.field == self.state_field))


Instruction:
Create a Python 3 function for
collecting the implementations from a given attributes dict.

Response:
def collect(self, attrs):
        """Collect the implementations from a given attributes dict."""

        for name, value in attrs.items():
            if self.should_collect(value):
                transition = self.workflow.transitions[value.trname]

                if (
                        value.trname in self.implementations
                        and value.trname in self.custom_implems
                        and name != self.transitions_at[value.trname]):
                    # We already have an implementation registered.
                    other_implem_at = self.transitions_at[value.trname]
                    raise ValueError(
                        "Error for attribute %s: it defines implementation "
                        "%s for transition %s, which is already implemented "
                        "at %s." % (name, value, transition, other_implem_at))

                implem = self.add_implem(transition, name, value.func)
                self.custom_implems.add(transition.name)
                if value.check:
                    implem.add_hook(Hook(HOOK_CHECK, value.check))
                if value.before:
                    implem.add_hook(Hook(HOOK_BEFORE, value.before))
                if value.after:
                    implem.add_hook(Hook(HOOK_AFTER, value.after))


Instruction:
Can you create a Python 3 function that
retrieves a list of custom implementation properties.

Response:
def get_custom_implementations(self):
        """Retrieve a list of cutom implementations.

        Yields:
            (str, str, ImplementationProperty) tuples: The name of the attribute
                an implementation lives at, the name of the related transition,
                and the related implementation.
        """
        for trname in self.custom_implems:
            attr = self.transitions_at[trname]
            implem = self.implementations[trname]
            yield (trname, attr, implem)


Instruction:
Can you create a Python 3 function that
looks at an object method and registers it for relevent transitions.

Response:
def register_function_hooks(self, func):
        """Looks at an object method and registers it for relevent transitions."""
        for hook_kind, hooks in func.xworkflows_hook.items():
            for field_name, hook in hooks:
                if field_name and field_name != self.state_field:
                    continue
                for transition in self.workflow.transitions:
                    if hook.applies_to(transition):
                        implem = self.implementations[transition.name]
                        implem.add_hook(hook)


Instruction:
Given the following Python 3 function, write the documentation
def _may_override(self, implem, other):
        if isinstance(other, ImplementationProperty):
            # Overriding another custom implementation for the same transition
            # and field
            return (other.transition == implem.transition and other.field_name == self.state_field)

        elif isinstance(other, TransitionWrapper):
            # Overriding the definition that led to adding the current
            # ImplementationProperty.
            return (
                other.trname == implem.transition.name
                and (not other.field or other.field == self.state_field)
                and other.func == implem.implementation)

        return False

Response: Checks whether an ImplementationProperty may override an attribute.


Instruction:
Create a Python 3 function for
updating the attrs dict with generated ImplementationProperty.

Response:
def fill_attrs(self, attrs):
        """Update the 'attrs' dict with generated ImplementationProperty."""
        for trname, attrname in self.transitions_at.items():

            implem = self.implementations[trname]

            if attrname in attrs:
                conflicting = attrs[attrname]
                if not self._may_override(implem, conflicting):
                    raise ValueError(
                        "Can't override transition implementation %s=%r with %r" %
                        (attrname, conflicting, implem))

            attrs[attrname] = implem
        return attrs


Instruction:
Write a Python 3 function that can
perform all actions on a given attribute dict.

Response:
def transform(self, attrs):
        """Perform all actions on a given attribute dict."""
        self.collect(attrs)
        self.add_missing_implementations()
        self.fill_attrs(attrs)


Instruction:
Can you write a function in Python 3 where it
logs a transition. Args: transition (Transition): the name of the performed transition from_state (State): the source state instance (object): the modified object Kwargs: Any passed when calling the transition

Response:
def log_transition(self, transition, from_state, instance, *args, **kwargs):
        """Log a transition.

        Args:
            transition (Transition): the name of the performed transition
            from_state (State): the source state
            instance (object): the modified object

        Kwargs:
            Any passed when calling the transition
        """
        logger = logging.getLogger('xworkflows.transitions')
        try:
            instance_repr = u(repr(instance), 'ignore')
        except (UnicodeEncodeError, UnicodeDecodeError):
            instance_repr = u("<bad repr>")
        logger.info(
            u("%s performed transition %s.%s (%s -> %s)"), instance_repr,
            self.__class__.__name__, transition.name, from_state.name,
            transition.target.name)


Instruction:
Write a Python 3 function for
attaching a workflow to the attribute list.

Response:
def _add_workflow(mcs, field_name, state_field, attrs):
        """Attach a workflow to the attribute list (create a StateProperty)."""
        attrs[field_name] = StateProperty(state_field.workflow, field_name)


Instruction:
Given the following Python 3 function, write the documentation
def _find_workflows(mcs, attrs):
        workflows = {}
        for attribute, value in attrs.items():
            if isinstance(value, Workflow):
                workflows[attribute] = StateField(value)
        return workflows

Response: Finds all occurrences of a workflow in the attributes definitions.


Instruction:
Can you tell what is the following Python 3 function doing
def _add_transitions(mcs, field_name, workflow, attrs, implems=None):
        new_implems = ImplementationList(field_name, workflow)
        if implems:
            new_implems.load_parent_implems(implems)
        new_implems.transform(attrs)

        return new_implems

Response: Collect and enhance transition definitions to a workflow.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def update(self):
        "Updates cartesian coordinates for drawing tree graph"
        # get new shape and clear for attrs
        self.edges = np.zeros((self.ttree.nnodes - 1, 2), dtype=int)
        self.verts = np.zeros((self.ttree.nnodes, 2), dtype=float)
        self.lines = []
        self.coords = []

        # fill with updates
        self.update_idxs()             # get dimensions of tree
        self.update_fixed_order()      # in case ntips changed
        self.assign_vertices()         # get node locations
        self.assign_coordinates()      # get edge locations
        self.reorient_coordinates()

Response: Updates cartesian coordinates for drawing tree graph


Instruction:
Make a summary of the following Python 3 code
def update_idxs(self):
        "set root idx highest, tip idxs lowest ordered as ladderized"
        # internal nodes: root is highest idx
        idx = self.ttree.nnodes - 1
        for node in self.ttree.treenode.traverse("levelorder"):
            if not node.is_leaf():
                node.add_feature("idx", idx)
                if not node.name:
                    node.name = str(idx)
                idx -= 1

        # external nodes: lowest numbers are for tips (0-N)
        for node in self.ttree.treenode.get_leaves():
            node.add_feature("idx", idx)
            if not node.name:
                node.name = str(idx)
            idx -= 1

Response: set root idx highest tip idxs lowest ordered as ladderized


Instruction:
Can you generate the documentation for the following Python 3 function
def update_fixed_order(self):
        "after pruning fixed order needs update to match new nnodes/ntips."
        # set tips order if fixing for multi-tree plotting (default None)
        fixed_order = self.ttree._fixed_order
        self.ttree_fixed_order = None
        self.ttree_fixed_idx = list(range(self.ttree.ntips))

        # check if fixed_order changed:
        if fixed_order:
            fixed_order = [
                i for i in fixed_order if i in self.ttree.get_tip_labels()]
            self.ttree._set_fixed_order(fixed_order)
        else:
            self.ttree._fixed_idx = list(range(self.ttree.ntips))

Response: after pruning fixed order needs update to match new nnodes / nips.


Instruction:
Can you write a function in Python 3 where it
assigns the vertices of the nodes to the tree.

Response:
def assign_vertices(self):
        """
        Sets .edges, .verts for node positions.
        X and Y positions here refer to base assumption that tree is right
        facing, reorient_coordinates() will handle re-translating this.
        """
        # shortname
        uselen = bool(self.ttree.style.use_edge_lengths)

        # postorder: children then parents (nidxs from 0 up)
        # store edge array for connecting child nodes to parent nodes
        nidx = 0
        for node in self.ttree.treenode.traverse("postorder"):
            if not node.is_root():
                self.edges[nidx, :] = [node.up.idx, node.idx]
                nidx += 1

        # store verts array with x,y positions of nodes (lengths of branches)
        # we want tips to align at the right face (larger axis number)
        _root = self.ttree.treenode.get_tree_root()
        _treeheight = _root.get_distance(_root.get_farthest_leaf()[0])

        # set node x, y
        tidx = len(self.ttree) - 1
        for node in self.ttree.treenode.traverse("postorder"):

            # Just leaves: x positions are evenly spread and ordered on axis
            if node.is_leaf() and (not node.is_root()):

                # set y-positions (heights). Distance from root or zero
                node.y = _treeheight - _root.get_distance(node)
                if not uselen:
                    node.y = 0.0

                # set x-positions (order of samples)
                if self.ttree._fixed_order:
                    node.x = self.ttree._fixed_order.index(node.name)# - tidx
                else:
                    node.x = tidx
                    tidx -= 1

                # store the x,y vertex positions
                self.verts[node.idx] = [node.x, node.y]

            # All internal node positions are not evenly spread or ordered
            else:
                # height is either distance or nnodes from root
                node.y = _treeheight - _root.get_distance(node)
                if not uselen:
                    node.y = max([i.y for i in node.children]) + 1

                # x position is halfway between childrens x-positions
                if node.children:
                    nch = node.children
                    node.x = sum(i.x for i in nch) / float(len(nch))
                else:
                    node.x = tidx

                # store the x,y vertex positions
                self.verts[node.idx] = [node.x, node.y]


Instruction:
Can you create a Python 3 function that
returns a modified. verts array with new coordinates for nodes.

Response:
def reorient_coordinates(self):
        """
        Returns a modified .verts array with new coordinates for nodes.
        This does not need to modify .edges. The order of nodes, and therefore
        of verts rows is still the same because it is still based on the tree
        branching order (ladderized usually).
        """
        # if tree is empty then bail out
        if len(self.ttree) < 2:
            return

        # down is the default orientation
        # down-facing tips align at y=0, first ladderized tip at x=0
        if self.ttree.style.orient in ('down', 0):
            pass

        # right-facing tips align at x=0, last ladderized tip at y=0
        elif self.ttree.style.orient in ('right', 3):

            # verts swap x and ys and make xs 0 to negative
            tmp = np.zeros(self.verts.shape)
            tmp[:, 1] = self.verts[:, 0]
            tmp[:, 0] = self.verts[:, 1] * -1
            self.verts = tmp

            # coords...
            tmp = np.zeros(self.coords.shape)
            tmp[:, 1] = self.coords[:, 0]
            tmp[:, 0] = self.coords[:, 1] * -1
            self.coords = tmp

        elif self.ttree.style.orient in ('left', 1):
            raise NotImplementedError("todo: left facing")

        else:
            raise NotImplementedError("todo: up facing")


Instruction:
Here you have a function in Python 3, explain what it does
def tsiterator(ts, dateconverter=None, desc=None,
               clean=False, start_value=None, **kwargs):
    '''An iterator of timeseries as tuples.'''
    dateconverter = dateconverter or default_converter
    yield ['Date'] + ts.names()
    if clean == 'full':
        for dt, value in full_clean(ts, dateconverter, desc, start_value):
             yield (dt,) + tuple(value)
    else:
        if clean:
            ts = ts.clean()
        for dt, value in ts.items(desc=desc, start_value=start_value):
            dt = dateconverter(dt)
            yield (dt,) + tuple(value)

Response: An iterator of timeseries as tuples.


Instruction:
Explain what the following Python 3 code does
def set_baselines(self):
        if self.style.xbaseline:
            if self.style.orient in ("up", "down"):
                self.coords.coords[:, 0] += self.style.xbaseline
                self.coords.verts[:, 0] += self.style.xbaseline
            else:
                self.coords.coords[:, 1] += self.style.xbaseline
                self.coords.verts[:, 1] += self.style.xbaseline

Response: Modify coords to shift tree position for x y baseline arguments.


Instruction:
Write a Python 3 function for
adding tip - labels to the axes.

Response:
def add_tip_labels_to_axes(self):
        """
        Add text offset from tips of tree with correction for orientation,
        and fixed_order which is usually used in multitree plotting.
        """
        # get tip-coords and replace if using fixed_order
        xpos = self.ttree.get_tip_coordinates('x')
        ypos = self.ttree.get_tip_coordinates('y')

        if self.style.orient in ("up", "down"):
            if self.ttree._fixed_order:
                xpos = list(range(self.ttree.ntips))
                ypos = ypos[self.ttree._fixed_idx]
            if self.style.tip_labels_align:
                ypos = np.zeros(self.ttree.ntips)

        if self.style.orient in ("right", "left"):
            if self.ttree._fixed_order:
                xpos = xpos[self.ttree._fixed_idx]
                ypos = list(range(self.ttree.ntips))
            if self.style.tip_labels_align:
                xpos = np.zeros(self.ttree.ntips)

        # pop fill from color dict if using color
        tstyle = deepcopy(self.style.tip_labels_style)
        if self.style.tip_labels_colors:
            tstyle.pop("fill")

        # add tip names to coordinates calculated above
        self.axes.text(
            xpos,
            ypos,
            self.tip_labels,
            angle=(0 if self.style.orient in ("right", "left") else -90),
            style=tstyle,
            color=self.style.tip_labels_colors,
        )

        # get stroke-width for aligned tip-label lines (optional)
        # copy stroke-width from the edge_style unless user set it
        if not self.style.edge_align_style.get("stroke-width"):
            self.style.edge_align_style["stroke-width"] = (
                self.style.edge_style["stroke-width"])


Instruction:
Explain what the following Python 3 code does
def add_tip_lines_to_axes(self):
        "add lines to connect tips to zero axis for tip_labels_align=True"

        # get tip-coords and align-coords from verts
        xpos, ypos, aedges, averts = self.get_tip_label_coords()
        if self.style.tip_labels_align:
            self.axes.graph(
                aedges,
                vcoordinates=averts,
                estyle=self.style.edge_align_style,
                vlshow=False,
                vsize=0,
            )

Response: add lines to connect tips to zero axis for tip_labels_align = True


Instruction:
Can you implement a function in Python 3 that
fits the tip labels for the current tree level.

Response:
def fit_tip_labels(self):
        """
        Modifies display range to ensure tip labels fit. This is a bit hackish
        still. The problem is that the 'extents' range of the rendered text
        is totally correct. So we add a little buffer here. Should add for
        user to be able to modify this if needed. If not using edge lengths
        then need to use unit length for treeheight.
        """
        # user entered values
        #if self.style.axes.x_domain_max or self.style.axes.y_domain_min:
        #    self.axes.x.domain.max = self.style.axes.x_domain_max
        #    self.axes.y.domain.min = self.style.axes.y_domain_min

        # IF USE WANTS TO CHANGE IT THEN DO IT AFTER USING AXES
        # or auto-fit (tree height)
        #else:
        if self.style.use_edge_lengths:
            addon = self.ttree.treenode.height * .85
        else:
            addon = self.ttree.treenode.get_farthest_leaf(True)[1]

        # modify display for orientations
        if self.style.tip_labels:
            if self.style.orient == "right":
                self.axes.x.domain.max = addon
            elif self.style.orient == "down":
                self.axes.y.domain.min = -1 * addon


Instruction:
Create a Python 3 function to
assign node colors and style to the marker.

Response:
def assign_node_colors_and_style(self):
        """
        Resolve conflict of 'node_color' and 'node_style['fill'] args which are
        redundant. Default is node_style.fill unless user entered node_color.
        To enter multiple colors user must use node_color not style fill.
        Either way, we build a list of colors to pass to Drawing.node_colors
        which is then written to the marker as a fill CSS attribute.
        """
        # SET node_colors and POP node_style.fill
        colors = self.style.node_colors
        style = self.style.node_style
        if colors is None:
            if style["fill"] in (None, "none"):
                style.pop("fill")
            else:
                if isinstance(style["fill"], (list, tuple)):
                    raise ToytreeError(
                        "Use node_color not node_style for multiple node colors")
                # check the color
                color = style["fill"]
                if isinstance(color, (np.ndarray, np.void, list, tuple)):
                    color = toyplot.color.to_css(color)
                self.node_colors = [color] * self.ttree.nnodes

        # otherwise parse node_color
        else:
            style.pop("fill")
            if isinstance(colors, str):
                # check the color
                color = colors
                if isinstance(color, (np.ndarray, np.void, list, tuple)):
                    color = toyplot.color.to_css(color)
                self.node_colors = [color] * self.ttree.nnodes

            elif isinstance(colors, (list, tuple)):
                if len(colors) != len(self.node_colors):
                    raise ToytreeError("node_colors arg is the wrong length")
                for cidx in range(len(self.node_colors)):
                    color = colors[cidx]
                    if isinstance(color, (np.ndarray, np.void, list, tuple)):
                        color = toyplot.color.to_css(color)
                    self.node_colors[cidx] = color

        # use CSS none for stroke=None
        if self.style.node_style["stroke"] is None:
            self.style.node_style.stroke = "none"

        # apply node markers
        markers = self.style.node_markers
        if markers is None:
            self.node_markers = ["o"] * self.ttree.nnodes
        else:
            if isinstance(markers, str):
                self.node_markers = [markers] * self.ttree.nnodes
            elif isinstance(markers, (list, tuple)):
                for cidx in range(len(self.node_markers)):
                    self.node_markers[cidx] = markers[cidx]


Instruction:
How would you explain what the following Python 3 function does
def assign_node_labels_and_sizes(self):
        "assign features of nodes to be plotted based on user kwargs"

        # shorthand
        nvals = self.ttree.get_node_values()

        # False == Hide nodes and labels unless user entered size
        if self.style.node_labels is False:
            self.node_labels = ["" for i in nvals]
            if self.style.node_sizes is not None:
                if isinstance(self.style.node_sizes, (list, tuple, np.ndarray)):
                    assert len(self.node_sizes) == len(self.style.node_sizes)
                    self.node_sizes = self.style.node_sizes

                elif isinstance(self.style.node_sizes, (int, str)):
                    self.node_sizes = (
                        [int(self.style.node_sizes)] * len(nvals)
                    )
                self.node_labels = [" " if i else "" for i in self.node_sizes]

        # True == Show nodes, label=idx, and show hover
        elif self.style.node_labels is True:
            # turn on node hover even if user did not set it explicit
            self.style.node_hover = True

            # get idx labels
            self.node_labels = self.ttree.get_node_values('idx', 1, 1)

            # use default node size as a list if not provided
            if not self.style.node_sizes:
                self.node_sizes = [18] * len(nvals)
            else:
                assert isinstance(self.style.node_sizes, (int, str))
                self.node_sizes = (
                    [int(self.style.node_sizes)] * len(nvals)
                )

        # User entered lists or other for node labels or sizes; check lengths.
        else:
            # make node labels into a list of values
            if isinstance(self.style.node_labels, list):
                assert len(self.style.node_labels) == len(nvals)
                self.node_labels = self.style.node_labels

            # check if user entered a feature else use entered val
            elif isinstance(self.style.node_labels, str):
                self.node_labels = [self.style.node_labels] * len(nvals)
                if self.style.node_labels in self.ttree.features:
                    self.node_labels = self.ttree.get_node_values(
                        self.style.node_labels, 1, 0)

            # default to idx at internals if nothing else
            else:
                self.node_labels = self.ttree.get_node_values("idx", 1, 0)

            # make node sizes as a list; set to zero if node label is ""
            if isinstance(self.style.node_sizes, list):
                assert len(self.style.node_sizes) == len(nvals)
                self.node_sizes = self.style.node_sizes
            elif isinstance(self.style.node_sizes, (str, int, float)):
                self.node_sizes = [int(self.style.node_sizes)] * len(nvals)
            else:
                self.node_sizes = [18] * len(nvals)

            # override node sizes to hide based on node labels
            for nidx, node in enumerate(self.node_labels):
                if self.node_labels[nidx] == "":
                    self.node_sizes[nidx] = 0

        # ensure string type
        self.node_labels = [str(i) for i in self.node_labels]

Response: assign features of nodes to be plotted based on user kwargs


Instruction:
How would you code a function in Python 3 to
assign tip labels based on user provided kwargs

Response:
def assign_tip_labels_and_colors(self):
        "assign tip labels based on user provided kwargs"
        # COLOR
        # tip color overrides tipstyle.fill
        if self.style.tip_labels_colors:
            #if self.style.tip_labels_style.fill:
            #    self.style.tip_labels_style.fill = None
            if self.ttree._fixed_order:
                if isinstance(self.style.tip_labels_colors, (list, np.ndarray)):
                    cols = np.array(self.style.tip_labels_colors)
                    orde = cols[self.ttree._fixed_idx]
                    self.style.tip_labels_colors = list(orde)

        # LABELS
        # False == hide tip labels
        if self.style.tip_labels is False:
            self.style.tip_labels_style["-toyplot-anchor-shift"] = "0px"
            self.tip_labels = ["" for i in self.ttree.get_tip_labels()]

        # LABELS
        # user entered something...
        else:
            # if user did not change label-offset then shift it here
            if not self.style.tip_labels_style["-toyplot-anchor-shift"]:
                self.style.tip_labels_style["-toyplot-anchor-shift"] = "15px"

            # if user entered list in get_tip_labels order reverse it for plot
            if isinstance(self.style.tip_labels, list):
                self.tip_labels = self.style.tip_labels

            # True assigns tip labels from tree
            else:
                if self.ttree._fixed_order:
                    self.tip_labels = self.ttree._fixed_order
                else:
                    self.tip_labels = self.ttree.get_tip_labels()


Instruction:
Implement a function in Python 3 to
assign edge colors and widths to the node_color attribute.

Response:
def assign_edge_colors_and_widths(self):
        """
        Resolve conflict of 'node_color' and 'node_style['fill'] args which are
        redundant. Default is node_style.fill unless user entered node_color.
        To enter multiple colors user must use node_color not style fill.
        Either way, we build a list of colors to pass to Drawing.node_colors
        which is then written to the marker as a fill CSS attribute.
        """
        # node_color overrides fill. Tricky to catch cuz it can be many types.

        # SET edge_widths and POP edge_style.stroke-width
        if self.style.edge_widths is None:
            if not self.style.edge_style["stroke-width"]:
                self.style.edge_style.pop("stroke-width")
                self.style.edge_style.pop("stroke")
                self.edge_widths = [None] * self.nedges
            else:
                if isinstance(self.style.edge_style["stroke-width"], (list, tuple)):
                    raise ToytreeError(
                        "Use edge_widths not edge_style for multiple edge widths")
                # check the color
                width = self.style.edge_style["stroke-width"]
                self.style.edge_style.pop("stroke-width")
                self.edge_widths = [width] * self.nedges
        else:
            self.style.edge_style.pop("stroke-width")
            if isinstance(self.style.edge_widths, (str, int)):
                self.edge_widths = [int(self.style.edge_widths)] * self.nedges

            elif isinstance(self.style.edge_widths, (list, tuple)):
                if len(self.style.edge_widths) != self.nedges:
                    raise ToytreeError("edge_widths arg is the wrong length")
                for cidx in range(self.nedges):
                    self.edge_widths[cidx] = self.style.edge_widths[cidx]

        # SET edge_colors and POP edge_style.stroke
        if self.style.edge_colors is None:
            if self.style.edge_style["stroke"] is None:
                self.style.edge_style.pop("stroke")
                self.edge_colors = [None] * self.nedges
            else:
                if isinstance(self.style.edge_style["stroke"], (list, tuple)):
                    raise ToytreeError(
                        "Use edge_colors not edge_style for multiple edge colors")
                # check the color
                color = self.style.edge_style["stroke"]
                if isinstance(color, (np.ndarray, np.void, list, tuple)):
                    color = toyplot.color.to_css(color)
                self.style.edge_style.pop("stroke")
                self.edge_colors = [color] * self.nedges

        # otherwise parse node_color
        else:
            self.style.edge_style.pop("stroke")
            if isinstance(self.style.edge_colors, (str, int)):
                # check the color
                color = self.style.edge_colors
                if isinstance(color, (np.ndarray, np.void, list, tuple)):
                    color = toyplot.color.to_css(color)
                self.edge_colors = [color] * self.nedges

            elif isinstance(self.style.edge_colors, (list, tuple)):
                if len(self.style.edge_colors) != self.nedges:
                    raise ToytreeError("edge_colors arg is the wrong length")
                for cidx in range(self.nedges):
                    self.edge_colors[cidx] = self.style.edge_colors[cidx]

        # do not allow empty edge_colors or widths
        self.edge_colors = [i if i else "#262626" for i in self.edge_colors]
        self.edge_widths = [i if i else 2 for i in self.edge_widths]


Instruction:
Implement a function in Python 3 to
add nodes to the axes.

Response:
def add_nodes_to_axes(self):
        """
        Creates a new marker for every node from idx indexes and lists of
        node_values, node_colors, node_sizes, node_style, node_labels_style.
        Pulls from node_color and adds to a copy of the style dict for each
        node to create marker.

        Node_colors has priority to overwrite node_style['fill']
        """
        # bail out if not any visible nodes (e.g., none w/ size>0)
        if all([i == "" for i in self.node_labels]):
            return

        # build markers for each node.
        marks = []
        for nidx in self.ttree.get_node_values('idx', 1, 1):

            # select node value from deconstructed lists
            nlabel = self.node_labels[nidx]
            nsize = self.node_sizes[nidx]
            nmarker = self.node_markers[nidx]

            # get styledict copies
            nstyle = deepcopy(self.style.node_style)
            nlstyle = deepcopy(self.style.node_labels_style)

            # and mod style dict copies from deconstructed lists
            nstyle["fill"] = self.node_colors[nidx]

            # create mark if text or node
            if (nlabel or nsize):
                mark = toyplot.marker.create(
                    shape=nmarker,
                    label=str(nlabel),
                    size=nsize,
                    mstyle=nstyle,
                    lstyle=nlstyle,
                )
            else:
                mark = ""

            # store the nodes/marks
            marks.append(mark)

        # node_hover == True to show all features interactive
        if self.style.node_hover is True:
            title = self.get_hover()

        elif isinstance(self.style.node_hover, list):
            # todo: return advice if improperly formatted
            title = self.style.node_hover

        # if hover is false then no hover
        else:
            title = None

        # add nodes
        self.axes.scatterplot(
            self.coords.verts[:, 0],
            self.coords.verts[:, 1],
            marker=marks,
            title=title,
        )


Instruction:
Write a Python 3 script to
get starting position of tip labels text based on locations of the tree face direction and align options.

Response:
def get_tip_label_coords(self):
        """
        Get starting position of tip labels text based on locations of the
        leaf nodes on the tree and style offset and align options. Node
        positions are found using the .verts attribute of coords and is
        already oriented for the tree face direction.
        """
        # number of tips
        ns = self.ttree.ntips

        # x-coordinate of tips assuming down-face
        tip_xpos = self.coords.verts[:ns, 0]
        tip_ypos = self.coords.verts[:ns, 1]
        align_edges = None
        align_verts = None

        # handle orientations
        if self.style.orient in (0, 'down'):
            # align tips at zero
            if self.style.tip_labels_align:
                tip_yend = np.zeros(ns)
                align_edges = np.array([
                    (i + len(tip_ypos), i) for i in range(len(tip_ypos))
                ])
                align_verts = np.array(
                    list(zip(tip_xpos, tip_ypos)) + \
                    list(zip(tip_xpos, tip_yend))
                )
                tip_ypos = tip_yend
        else:
            # tip labels align finds the zero axis for orientation...
            if self.style.tip_labels_align:
                tip_xend = np.zeros(ns)
                align_edges = np.array([
                    (i + len(tip_xpos), i) for i in range(len(tip_xpos))
                ])
                align_verts = np.array(
                    list(zip(tip_xpos, tip_ypos)) + \
                    list(zip(tip_xend, tip_ypos))
                )
                tip_xpos = tip_xend
        return tip_xpos, tip_ypos, align_edges, align_verts


Instruction:
Write a Python 3 script to
calculate reasonable canvas height and width for tree given N tips

Response:
def get_dims_from_tree_size(self):
        "Calculate reasonable canvas height and width for tree given N tips"
        ntips = len(self.ttree)
        if self.style.orient in ("right", "left"):
            # height is long tip-wise dimension
            if not self.style.height:
                self.style.height = max(275, min(1000, 18 * ntips))
            if not self.style.width:
                self.style.width = max(350, min(500, 18 * ntips))
        else:
            # width is long tip-wise dimension
            if not self.style.height:
                self.style.height = max(275, min(500, 18 * ntips))
            if not self.style.width:
                self.style.width = max(350, min(1000, 18 * ntips))


Instruction:
How would you code a function in Python 3 to
get the length longest line in a paragraph

Response:
def get_longest_line_length(text):
    """Get the length longest line in a paragraph"""
    lines = text.split("\n")
    length = 0

    for i in range(len(lines)):
        if len(lines[i]) > length:
            length = len(lines[i])

    return length


Instruction:
How would you explain what the following Python 3 function does
def isnumeric(obj):
    '''
    Return true if obj is a numeric value
    '''
    from decimal import Decimal
    if type(obj) == Decimal:
        return True
    else:
        try:
            float(obj)
        except:
            return False
        return True

Response: Returns true if obj is a numeric value


Instruction:
Write a Python 3 function for
formatting a number according to a given number of significant figures.

Response:
def significant_format(number, decimal_sep='.', thousand_sep=',', n=3):
    """Format a number according to a given number of significant figures.
    """
    str_number = significant(number, n)

    # sign
    if float(number) < 0:
        sign = '-'
    else:
        sign = ''

    if str_number[0] == '-':
        str_number = str_number[1:]
    if '.' in str_number:
        int_part, dec_part = str_number.split('.')
    else:
        int_part, dec_part = str_number, ''
    if dec_part:
        dec_part = decimal_sep + dec_part
    if thousand_sep:
        int_part_gd = ''
        for cnt, digit in enumerate(int_part[::-1]):
            if cnt and not cnt % 3:
                int_part_gd += thousand_sep
            int_part_gd += digit
        int_part = int_part_gd[::-1]
    return sign + int_part + dec_part


Instruction:
Can you implement a function in Python 3 that
converts obj to ( unicode ) text string

Response:
def to_text_string(obj, encoding=None):
    """Convert `obj` to (unicode) text string"""
    if PY2:
        # Python 2
        if encoding is None:
            return unicode(obj)
        else:
            return unicode(obj, encoding)
    else:
        # Python 3
        if encoding is None:
            return str(obj)
        elif isinstance(obj, str):
            # In case this function is not used properly, this could happen
            return obj
        else:
            return str(obj, encoding)


Instruction:
Given the following Python 3 function, write the documentation
def text_to_qcolor(text):
    color = QColor()
    if not is_string(text): # testing for QString (PyQt API#1)
        text = str(text)
    if not is_text_string(text):
        return color
    if text.startswith('#') and len(text)==7:
        correct = '#0123456789abcdef'
        for char in text:
            if char.lower() not in correct:
                return color
    elif text not in list(QColor.colorNames()):
        return color
    color.setNamedColor(text)
    return color

Response: Create a QColor from a string


Instruction:
Implement a Python 3 function for
converting a tuple to a QFont object

Response:
def tuple_to_qfont(tup):
    """
    Create a QFont from tuple:
        (family [string], size [int], italic [bool], bold [bool])
    """
    if not isinstance(tup, tuple) or len(tup) != 4 \
       or not is_text_string(tup[0]) \
       or not isinstance(tup[1], int) \
       or not isinstance(tup[2], bool) \
       or not isinstance(tup[3], bool):
        return None
    font = QFont()
    family, size, italic, bold = tup
    font.setFamily(family)
    font.setPointSize(size)
    font.setItalic(italic)
    font.setBold(bold)
    return font


Instruction:
Write a Python 3 function that can
create a form dialog and return a list of data structures

Response:
def fedit(data, title="", comment="", icon=None, parent=None, apply=None,
          ok=True, cancel=True, result='list', outfile=None, type='form',
          scrollbar=False, background_color=None, widget_color=None):
    """
    Create form dialog and return result
    (if Cancel button is pressed, return None)

    :param tuple data: datalist, datagroup (see below)
    :param str title: form title
    :param str comment: header comment
    :param QIcon icon: dialog box icon
    :param QWidget parent: parent widget
    :param str ok: customized ok button label
    :param str cancel: customized cancel button label
    :param tuple apply: (label, function) customized button label and callback
    :param function apply: function taking two arguments (result, widgets)
    :param str result: result serialization ('list', 'dict', 'OrderedDict',
                                             'JSON' or 'XML')
    :param str outfile: write result to the file outfile.[py|json|xml]
    :param str type: layout type ('form' or 'questions')
    :param bool scrollbar: vertical scrollbar
    :param str background_color: color of the background
    :param str widget_color: color of the widgets

    :return: Serialized result (data type depends on `result` parameter)

    datalist: list/tuple of (field_name, field_value)
    datagroup: list/tuple of (datalist *or* datagroup, title, comment)

    Tips:
      * one field for each member of a datalist
      * one tab for each member of a top-level datagroup
      * one page (of a multipage widget, each page can be selected with a
        combo box) for each member of a datagroup inside a datagroup

    Supported types for field_value:
      - int, float, str, unicode, bool
      - colors: in Qt-compatible text form, i.e. in hex format or name (red,...)
                (automatically detected from a string)
      - list/tuple:
          * the first element will be the selected index (or value)
          * the other elements can be couples (key, value) or only values
    """
    # Create a QApplication instance if no instance currently exists
    # (e.g. if the module is used directly from the interpreter)
    test_travis = os.environ.get('TEST_CI_WIDGETS', None)
    if test_travis is not None:
        app = QApplication.instance()
        if app is None:
            app = QApplication([])
        timer = QTimer(app)
        timer.timeout.connect(app.quit)
        timer.start(1000)
    elif QApplication.startingUp():
        _app = QApplication([])
        translator_qt = QTranslator()
        translator_qt.load('qt_' + QLocale.system().name(),
                       QLibraryInfo.location(QLibraryInfo.TranslationsPath))
        _app.installTranslator(translator_qt)

    serial = ['list', 'dict', 'OrderedDict', 'JSON', 'XML']
    if result not in serial:
        print("Warning: '%s' not in %s, default to list" %
              (result, ', '.join(serial)), file=sys.stderr)
        result = 'list'

    layouts = ['form', 'questions']
    if type not in layouts:
        print("Warning: '%s' not in %s, default to form" %
              (type, ', '.join(layouts)), file=sys.stderr)
        type = 'form'

    dialog = FormDialog(data, title, comment, icon, parent, apply, ok, cancel,
                        result, outfile, type, scrollbar, background_color,
                        widget_color)
    if dialog.exec_():
        return dialog.get()


Instruction:
Write a Python 3 script to
return the FormDialog instance

Response:
def get_dialog(self):
        """Return FormDialog instance"""
        dialog = self.parent()
        while not isinstance(dialog, QDialog):
            dialog = dialog.parent()
        return dialog