Instruction:
How would you explain what the following Python 3 function does
def _rough_shake(self, x, normals, values, error):
        '''Take a robust, but not very efficient step towards the constraints.

           Arguments:
            | ``x`` -- The unknowns.
            | ``normals`` -- A numpy array with the gradients of the active
                             constraints. Each row is one gradient.
            | ``values`` -- A numpy array with the values of the constraint
                            functions.
            | ``error`` -- The square root of the constraint cost function.
        '''
        counter = 0
        while error > self.threshold and counter < self.max_iter:
            dxs = []
            for i in range(len(normals)):
                dx = -normals[i]*values[i]/np.dot(normals[i], normals[i])
                dxs.append(dx)
            dxs = np.array(dxs)
            dx = dxs[abs(values).argmax()]
            x = x+dx
            self.lock[:] = False
            normals, values, error = self._compute_equations(x)[:-1]
            counter += 1
        return x, normals, values, error

Response: Take a robust but not very efficient step towards the constraints.


Instruction:
Can you generate the documentation for the following Python 3 function
def _fast_shake(self, x, normals, values, error):
        '''Take an efficient (not always robust) step towards the constraints.

           Arguments:
            | ``x`` -- The unknowns.
            | ``normals`` -- A numpy array with the gradients of the active
                             constraints. Each row is one gradient.
            | ``values`` -- A numpy array with the values of the constraint
                            functions.
            | ``error`` -- The square root of the constraint cost function.
        '''
        # filter out the degrees of freedom that do not feel the constraints.
        mask = (normals!=0).any(axis=0) > 0
        normals = normals[:,mask]
        # Take a step to lower the constraint cost function. If the step is too
        # large, it is reduced iteratively towards a small steepest descent
        # step. This is very similar to the Levenberg-Marquardt algorithm.
        # Singular Value decomposition is used to make this procedure
        # numerically more stable and efficient.
        U, S, Vt = np.linalg.svd(normals, full_matrices=False)
        rcond = None
        counter = 0
        while True:
            if rcond is None:
                rcond = 0.0
            elif rcond == 0.0:
                rcond = self.rcond1
            else:
                rcond *= 10
            # perform the least-norm correction
            Sinv = (S**2+rcond)
            if Sinv.max() == 0.0:
                continue
            Sinv = S/Sinv
            # compute the step
            dx = -np.dot(Vt.transpose(), np.dot(U.transpose(), values)*Sinv)
            new_x = x.copy()
            new_x[mask] += dx
            # try the step
            new_normals, new_values, new_error = self._compute_equations(new_x)[:-1]
            if new_error < 0.9*error:
                # Only if it decreases the constraint cost sufficiently, the
                # step is accepted. This routine is pointless of it converges
                # slowly.
                return new_x, new_normals, new_values, new_error
            elif abs(dx).sum() < self.threshold:
                # If the step becomes too small, then give up.
                break
            elif counter > self.max_iter:
                raise ConstraintError('Exceeded maximum number of shake iterations.')
            counter += 1

Response: This routine is used to fast shake the active set of unknowns.


Instruction:
Write a Python 3 script to
bring unknowns to the constraints.

Response:
def free_shake(self, x):
        '''Brings unknowns to the constraints.

           Arguments:
            | ``x`` -- The unknowns.
        '''
        self.lock[:] = False
        normals, values, error = self._compute_equations(x)[:-1]
        counter = 0
        while True:
            if error <= self.threshold:
                break
            # try a well-behaved move to the constrains
            result = self._fast_shake(x, normals, values, error)
            counter += 1
            if result is not None:
                x, normals, values, error = result
            else:
                # well-behaved move is too slow.
                # do a cumbersome move to satisfy constraints approximately.
                x, normals, values, error = self._rough_shake(x, normals, values, error)
                counter += 1
            # When too many iterations are required, just give up.
            if counter > self.max_iter:
                raise ConstraintError('Exceeded maximum number of shake iterations.')
        return x, counter, len(values)


Instruction:
Can you generate the documentation for the following Python 3 function
def safe_shake(self, x, fun, fmax):
        '''Brings unknowns to the constraints, without increasing fun above fmax.

           Arguments:
            | ``x`` -- The unknowns.
            | ``fun`` -- The function being minimized.
            | ``fmax`` -- The highest allowed value of the function being
                          minimized.

           The function ``fun`` takes a mandatory argument ``x`` and an optional
           argument ``do_gradient``:
            | ``x``  --  the arguments of the function to be tested
            | ``do_gradient``  --  when False, only the function value is
                                   returned. when True, a 2-tuple with the
                                   function value and the gradient are returned
                                   [default=False]
        '''
        self.lock[:] = False
        def extra_equation(xx):
            f, g = fun(xx, do_gradient=True)
            return (f-fmax)/abs(fmax), g/abs(fmax)
        self.equations.append((-1,extra_equation))
        x, shake_counter, constraint_couter = self.free_shake(x)
        del self.equations[-1]
        return x, shake_counter, constraint_couter

Response: Brings unknowns to the constraints without increasing fun above fmax.


Instruction:
Explain what the following Python 3 code does
def project(self, x, vector):
        '''Project a vector (gradient or direction) on the active constraints.

           Arguments:
            | ``x`` -- The unknowns.
            | ``vector`` -- A numpy array with a direction or a gradient.

           The return value is a gradient or direction, where the components
           that point away from the constraints are projected out. In case of
           half-open constraints, the projection is only active of the vector
           points into the infeasible region.
        '''
        scale = np.linalg.norm(vector)
        if scale == 0.0:
            return vector
        self.lock[:] = False
        normals, signs = self._compute_equations(x)[::3]
        if len(normals) == 0:
            return vector

        vector = vector/scale
        mask = signs == 0
        result = vector.copy()
        changed = True
        counter = 0
        while changed:
            changed = False
            y = np.dot(normals, result)
            for i, sign in enumerate(signs):
                if sign != 0:
                    if sign*y[i] < -self.threshold:
                        mask[i] = True
                        changed = True
                    elif mask[i] and np.dot(normals[i], result-vector) < 0:
                        mask[i] = False
                        changed = True

            if mask.any():
                normals_select = normals[mask]
                y = np.dot(normals_select, vector)
                U, S, Vt = np.linalg.svd(normals_select, full_matrices=False)
                if S.min() == 0.0:
                    Sinv = S/(S**2+self.rcond1)
                else:
                    Sinv = 1.0/S
                result = vector - np.dot(Vt.transpose(), np.dot(U.transpose(), y)*Sinv)
            else:
                result = vector.copy()

            if counter > self.max_iter:
                raise ConstraintError('Exceeded maximum number of shake iterations.')
            counter += 1

        return result*scale

Response: Project a vector on the active constraints.


Instruction:
Write a Python 3 script to
return the final solution in the original coordinates

Response:
def get_final(self):
        """Return the final solution in the original coordinates"""
        if self.prec is None:
            return self.x
        else:
            return self.prec.undo(self.x)


Instruction:
Explain what the following Python 3 code does
def _run(self):
        success = self.initialize()
        while success is None:
            success = self.propagate()
        return success

Response: Run the iterative optimizer


Instruction:
Make a summary of the following Python 3 code
def _print_header(self):
        header = " Iter  Dir  "
        if self.constraints is not None:
            header += '  SC CC'
        header += "         Function"
        if self.convergence_condition is not None:
            header += self.convergence_condition.get_header()
        header += "    Time"
        self._screen("-"*(len(header)), newline=True)
        self._screen(header, newline=True)
        self._screen("-"*(len(header)), newline=True)

Response: Print the header for screen logging


Instruction:
Implement a Python 3 function for
printing something on screen when self. verbose == True

Response:
def _screen(self, s, newline=False):
        """Print something on screen when self.verbose == True"""
        if self.verbose:
            if newline:
                print(s)
            else:
                print(s, end=' ')


Instruction:
How would you explain what the following Python 3 function does
def _line_opt(self):
        direction = self.search_direction.direction
        if self.constraints is not None:
            try:
                direction = self.constraints.project(self.x, direction)
            except ConstraintError:
                self._screen("CONSTRAINT PROJECT FAILED", newline=True)
                return False
        direction_norm = np.linalg.norm(direction)
        if direction_norm == 0:
            return False
        self.line.configure(self.x, direction/direction_norm)

        success, wolfe, qopt, fopt = \
            self.line_search(self.line, self.initial_step_size, self.epsilon)
        if success:
            self.step = qopt*self.line.axis
            self.initial_step_size = np.linalg.norm(self.step)
            self.x = self.x + self.step
            self.f = fopt
            if wolfe:
                self._screen("W")
            else:
                self._screen(" ")
                self.search_direction.reset()
            return True
        else:
            if self.debug_line:
                import matplotlib.pyplot as pt
                import datetime
                pt.clf()
                qs = np.arange(0.0, 100.1)*(5*self.initial_step_size/100.0)
                fs = np.array([self.line(q) for q in qs])
                pt.plot(qs, fs)
                pt.xlim(qs[0], qs[-1])
                fdelta = fs.max() - fs.min()
                if fdelta == 0.0:
                    fdelta = fs.mean()
                fmargin = fdelta*0.1
                pt.ylim(fs.min() - fmargin, fs.max() + fmargin)
                pt.title('fdelta = %.2e   fmean = %.2e' % (fdelta, fs.mean()))
                pt.xlabel('Line coordinate, q')
                pt.ylabel('Function value, f')
                pt.savefig('line_failed_%s.png' % (datetime.datetime.now().isoformat()))
            self._reset_state()
            return False

Response: Perform a line search along the current direction


Instruction:
Can you tell what is the following Python 3 function doing
def neighbors(self):
        neighbors = dict(
            (vertex, []) for vertex
            in range(self.num_vertices)
        )
        for a, b in self.edges:
            neighbors[a].append(b)
            neighbors[b].append(a)
        # turn lists into frozensets
        neighbors = dict((key, frozenset(val)) for key, val in neighbors.items())
        return neighbors

Response: A dictionary with neighbors of the current node.


Instruction:
Create a Python 3 function to
list of vertices that are only interconnected within each list

Response:
def independent_vertices(self):
        """Lists of vertices that are only interconnected within each list

           This means that there is no path from a vertex in one list to a
           vertex in another list. In case of a molecular graph, this would
           yield the atoms that belong to individual molecules.
        """
        candidates = set(range(self.num_vertices))

        result = []
        while len(candidates) > 0:
            pivot = candidates.pop()
            group = [
                vertex for vertex, distance
                in self.iter_breadth_first(pivot)
            ]
            candidates.difference_update(group)

            # this sort makes sure that the order of the vertices is respected
            group.sort()
            result.append(group)
        return result


Instruction:
Given the following Python 3 function, write the documentation
def equivalent_vertices(self):
        level1 = {}
        for i, row in enumerate(self.vertex_fingerprints):
            key = row.tobytes()
            l = level1.get(key)
            if l is None:
                l = set([i])
                level1[key] = l
            else:
                l.add(i)
        level2 = {}
        for key, vertices in level1.items():
            for vertex in vertices:
                level2[vertex] = vertices
        return level2

Response: A dictionary with symmetrically equivalent vertices.


Instruction:
Write a Python 3 function that can
graph symmetries that map the graph onto itself.

Response:
def symmetries(self):
        """Graph symmetries (permutations) that map the graph onto itself."""

        symmetry_cycles = set([])
        symmetries = set([])
        for match in GraphSearch(EqualPattern(self))(self):
            match.cycles = match.get_closed_cycles()
            if match.cycles in symmetry_cycles:
                raise RuntimeError("Duplicates in EqualMatch")
            symmetry_cycles.add(match.cycles)
            symmetries.add(match)
        return symmetries


Instruction:
Can you generate the documentation for the following Python 3 function
def iter_breadth_first(self, start=None, do_paths=False, do_duplicates=False):
        if start is None:
            start = self.central_vertex
        else:
            try:
                start = int(start)
            except ValueError:
                raise TypeError("First argument (start) must be an integer.")
            if start < 0 or start >= self.num_vertices:
                raise ValueError("start must be in the range [0, %i[" %
                                 self.num_vertices)
        from collections import deque
        work = np.zeros(self.num_vertices, int)
        work[:] = -1
        work[start] = 0
        if do_paths:
            result = (start, 0, (start, ))
        else:
            result = (start, 0)
        yield result
        todo = deque([result])
        while len(todo) > 0:
            if do_paths:
                parent, parent_length, parent_path = todo.popleft()
            else:
                parent, parent_length = todo.popleft()
            current_length = parent_length + 1
            for current in self.neighbors[parent]:
                visited = work[current]
                if visited == -1 or (do_duplicates and visited == current_length):
                    work[current] = current_length
                    if do_paths:
                        current_path = parent_path + (current, )
                        result = (current, current_length, current_path)
                    else:
                        result = (current, current_length)
                    #print "iter_breadth_first", result
                    yield result
                    todo.append(result)

Response: Iterate over the vertices with the breadth - first algorithm.


Instruction:
Implement a Python 3 function for
iterating over the breadth first edges of the current node.

Response:
def iter_breadth_first_edges(self, start=None):
        """Iterate over the edges with the breadth first convention.

           We need this for the pattern matching algorithms, but a quick look at
           Wikipedia did not result in a known and named algorithm.

           The edges are yielded one by one, together with the distance of the
           edge from the starting vertex and a flag that indicates whether the
           yielded edge connects two vertices that are at the same distance from
           the starting vertex. If that flag is False, the distance from the
           starting vertex to edge[0] is equal to the distance variable and the
           distance from edge[1] to the starting vertex is equal to distance+1.
           One item has the following format: ((i, j), distance, flag)
        """
        if start is None:
            start = self.central_vertex
        else:
            try:
                start = int(start)
            except ValueError:
                raise TypeError("First argument (start) must be an integer.")
            if start < 0 or start >= self.num_vertices:
                raise ValueError("start must be in the range [0, %i[" %
                                 self.num_vertices)
        from collections import deque
        work = np.zeros(self.num_vertices, int)
        work[:] = -1
        work[start] = 0
        todo = deque([start])
        while len(todo) > 0:
            parent = todo.popleft()
            distance = work[parent]
            for current in self.neighbors[parent]:
                if work[current] == -1:
                    yield (parent, current), distance, False
                    work[current] = distance+1
                    todo.append(current)
                elif work[current] == distance and current > parent:
                    # second equation in elif avoids duplicates
                    yield (parent, current), distance, True
                elif work[current] == distance+1:
                    yield (parent, current), distance, False


Instruction:
Given the following Python 3 function, write the documentation
def get_subgraph(self, subvertices, normalize=False):
        if normalize:
            revorder = dict((j, i) for i, j in enumerate(subvertices))
            new_edges = []
            old_edge_indexes = []
            for counter, (i, j) in enumerate(self.edges):
                new_i = revorder.get(i)
                if new_i is None:
                    continue
                new_j = revorder.get(j)
                if new_j is None:
                    continue
                new_edges.append((new_i, new_j))
                old_edge_indexes.append(counter)
            # sort the edges
            order = list(range(len(new_edges)))
            # argsort in pure python
            order.sort( key=(lambda i: tuple(sorted(new_edges[i]))) )
            new_edges = [new_edges[i] for i in order]
            old_edge_indexes = [old_edge_indexes[i] for i in order]

            result = Graph(new_edges, num_vertices=len(subvertices))
            result._old_vertex_indexes = np.array(subvertices, dtype=int)
            #result.new_vertex_indexes = revorder
            result._old_edge_indexes = np.array(old_edge_indexes, dtype=int)
        else:
            subvertices = set(subvertices)
            old_edge_indexes = np.array([
                i for i, edge in enumerate(self.edges)
                if edge.issubset(subvertices)
            ], dtype=int)
            new_edges = tuple(self.edges[i] for i in old_edge_indexes)
            result = Graph(new_edges, self.num_vertices)
            result._old_edge_indexes = old_edge_indexes
            # no need for old and new vertex_indexes because they remain the
            # same.
        return result

Response: Constructs a subgraph of the current graph with the given set of subvertices.


Instruction:
Here you have a function in Python 3, explain what it does
def get_vertex_fingerprints(self, vertex_strings, edge_strings, num_iter=None):
        import hashlib
        def str2array(x):
            """convert a hash string to a numpy array of bytes"""
            if len(x) == 0:
                return np.zeros(0, np.ubyte)
            elif sys.version_info[0] == 2:
                return np.frombuffer(x, np.ubyte)
            else:
                return np.frombuffer(x.encode(), np.ubyte)
        hashrow = lambda x: np.frombuffer(hashlib.sha1(x.data).digest(), np.ubyte)
        # initialization
        result = np.zeros((self.num_vertices, 20), np.ubyte)
        for i in range(self.num_vertices):
            result[i] = hashrow(str2array(vertex_strings[i]))
        for i in range(self.num_edges):
            a, b = self.edges[i]
            tmp = hashrow(str2array(edge_strings[i]))
            result[a] += tmp
            result[b] += tmp
        work = result.copy()
        # iterations
        if num_iter is None:
            num_iter = self.max_distance
        for i in range(num_iter):
            for a, b in self.edges:
                work[a] += result[b]
                work[b] += result[a]
            #for a in xrange(self.num_vertices):
            #    for b in xrange(self.num_vertices):
            #        work[a] += hashrow(result[b]*self.distances[a, b])
            for a in range(self.num_vertices):
                result[a] = hashrow(work[a])
        return result

Response: Return an array with fingerprints for each vertex


Instruction:
Given the following Python 3 function, write the documentation
def get_halfs(self, vertex1, vertex2):
        def grow(origin, other):
            frontier = set(self.neighbors[origin])
            frontier.discard(other)
            result = set([origin])
            while len(frontier) > 0:
                pivot = frontier.pop()
                if pivot == other:
                    raise GraphError("The graph can not be separated in two halfs "
                                     "by disconnecting vertex1 and vertex2.")
                pivot_neighbors = set(self.neighbors[pivot])
                pivot_neighbors -= result
                frontier |= pivot_neighbors
                result.add(pivot)
            return result

        vertex1_part = grow(vertex1, vertex2)
        vertex2_part = grow(vertex2, vertex1)
        return vertex1_part, vertex2_part

Response: Split the graph in two halfs by cutting the edge vertex1 - vertex2 and return the vertices in both halfs.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_part(self, vertex_in, vertices_border):
        vertices_new = set(self.neighbors[vertex_in])
        vertices_part = set([vertex_in])

        while len(vertices_new) > 0:
            pivot = vertices_new.pop()
            if pivot in vertices_border:
                continue
            vertices_part.add(pivot)
            pivot_neighbors = set(self.neighbors[pivot])
            pivot_neighbors -= vertices_part
            vertices_new |= pivot_neighbors

        return vertices_part

Response: List all vertices that are connected to vertex_in but are not covered in or behind vertices_border.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_halfs_double(self, vertex_a1, vertex_b1, vertex_a2, vertex_b2):
        if vertex_a1 not in self.neighbors[vertex_b1]:
            raise GraphError("vertex_a1 must be a neighbor of vertex_b1.")
        if vertex_a2 not in self.neighbors[vertex_b2]:
            raise GraphError("vertex_a2 must be a neighbor of vertex_b2.")

        # find vertex_a_part (and possibly switch vertex_a2, vertex_b2)
        vertex_a_new = set(self.neighbors[vertex_a1])
        vertex_a_new.discard(vertex_b1)
        if vertex_a1 == vertex_b2:
            # we now that we have to swap vertex_a2 and vertex_b2. The algo
            # below will fail otherwise in this 'exotic' case.
            vertex_a2, vertex_b2 = vertex_b2, vertex_a2
            #vertex_a_new.discard(vertex_a2) # in case there is overlap
        if vertex_a1 == vertex_a2:
            vertex_a_new.discard(vertex_b2) # in case there is overlap
        vertex_a_part = set([vertex_a1])

        touched = False # True if (the switched) vertex_a2 has been reached.
        while len(vertex_a_new) > 0:
            pivot = vertex_a_new.pop()
            if pivot == vertex_b1:
                raise GraphError("The graph can not be separated in two halfs. "
                                 "vertex_b1 reached by vertex_a1.")
            vertex_a_part.add(pivot)
            # create a new set that we can modify
            pivot_neighbors = set(self.neighbors[pivot])
            pivot_neighbors -= vertex_a_part
            if pivot == vertex_a2 or pivot == vertex_b2:
                if pivot == vertex_b2:
                    if touched:
                        raise GraphError("The graph can not be separated in "
                                         "two halfs. vertex_b2 reached by "
                                         "vertex_a1.")
                    else:
                        # put them in the correct order
                        vertex_a2, vertex_b2 = vertex_b2, vertex_a2
                pivot_neighbors.discard(vertex_b2)
                touched = True
            vertex_a_new |= pivot_neighbors

        if vertex_a2 not in vertex_a_part:
            raise GraphError("The graph can not be separated in two halfs. "
                             "vertex_a1 can not reach vertex_a2 trough "
                             "vertex_a_part")

        # find vertex_b_part: easy, is just the rest ...
        #vertex_b_part = set(xrange(self.num_vertices)) - vertex_a_part

        # ... but we also want that there is a path in vertex_b_part from
        # vertex_b1 to vertex_b2
        if vertex_b1 == vertex_b2:
            closed = True
        else:
            vertex_b_new = set(self.neighbors[vertex_b1])
            vertex_b_new.discard(vertex_a1)
            vertex_b_part = set([vertex_b1])

            closed = False
            while len(vertex_b_new) > 0:
                pivot = vertex_b_new.pop()
                if pivot == vertex_b2:
                    closed = True
                    break
                pivot_neighbors = set(self.neighbors[pivot])
                pivot_neighbors -= vertex_b_part
                vertex_b_new |= pivot_neighbors
                vertex_b_part.add(pivot)

        if not closed:
            raise GraphError("The graph can not be separated in two halfs. "
                             "vertex_b1 can not reach vertex_b2 trough "
                             "vertex_b_part")

        # finaly compute the real vertex_b_part, the former loop might break
        # early for efficiency.
        vertex_b_part = set(range(self.num_vertices)) - vertex_a_part

        # done!
        return vertex_a_part, vertex_b_part, \
               (vertex_a1, vertex_b1, vertex_a2, vertex_b2)

Response: Compute the two halfs separated by vertex_a1 and vertex_b1 and vertex_b2 and return the two halfs separated by vertex_a1 and vertex_b1 and vertex_b2.


Instruction:
Write a Python 3 function for
finding the mapping between vertex indexes in self and other.

Response:
def full_match(self, other):
        """Find the mapping between vertex indexes in self and other.

           This also works on disconnected graphs. Derived classes should just
           implement get_vertex_string and get_edge_string to make this method
           aware of the different nature of certain vertices. In case molecules,
           this would make the algorithm sensitive to atom numbers etc.
        """
        # we need normalize subgraphs because these graphs are used as patterns.
        graphs0 = [
            self.get_subgraph(group, normalize=True)
            for group in self.independent_vertices
        ]
        graphs1 = [
            other.get_subgraph(group)
            for group in other.independent_vertices
        ]

        if len(graphs0) != len(graphs1):
            return

        matches = []

        for graph0 in graphs0:
            pattern = EqualPattern(graph0)
            found_match = False
            for i, graph1 in enumerate(graphs1):
                local_matches = list(GraphSearch(pattern)(graph1, one_match=True))
                if len(local_matches) == 1:
                    match = local_matches[0]
                    # we need to restore the relation between the normalized
                    # graph0 and its original indexes
                    old_to_new = OneToOne((
                        (j, i) for i, j
                        in enumerate(graph0._old_vertex_indexes)
                    ))
                    matches.append(match * old_to_new)
                    del graphs1[i]
                    found_match = True
                    break
            if not found_match:
                return

        result = OneToOne()
        for match in matches:
            result.add_relations(match.forward.items())
        return result


Instruction:
Implement a Python 3 function for
adding a new relation between source and destination.

Response:
def add_relation(self, source, destination):
        """Add new a relation to the bejection"""
        if self.in_sources(source):
            if self.forward[source] != destination:
                raise ValueError("Source is already in use. Destination does "
                                 "not match.")
            else:
                raise ValueError("Source-Destination relation already exists.")
        elif self.in_destinations(destination):
            raise ValueError("Destination is already in use. Source does not "
                             "match.")
        else:
            self.forward[source] = destination
            self.reverse[destination] = source


Instruction:
Make a summary of the following Python 3 code
def add_relations(self, relations):
        for source, destination in relations:
            self.add_relation(source, destination)

Response: Add multiple relations to a bijection


Instruction:
Make a summary of the following Python 3 code
def inverse(self):
        result = self.__class__()
        result.forward = copy.copy(self.reverse)
        result.reverse = copy.copy(self.forward)
        return result

Response: Returns the inverse bijection.


Instruction:
Here you have a function in Python 3, explain what it does
def get_new_edges(self, subject_graph):
        result = []
        #print "Match.get_new_edges self.previous_ends1", self.previous_ends1
        for vertex in self.previous_ends1:
            for neighbor in subject_graph.neighbors[vertex]:
                if neighbor not in self.reverse:
                    result.append((vertex, neighbor))
        return result

Response: Get new edges from the subject graph for the graph search algorithm


Instruction:
Here you have a function in Python 3, explain what it does
def copy_with_new_relations(self, new_relations):
        result = self.__class__(self.forward.items())
        result.add_relations(new_relations.items())
        result.previous_ends1 = set(new_relations.values())
        return result

Response: Create a new match object extended with new relations


Instruction:
Can you generate the documentation for the following Python 3 function
def _set_pattern_graph(self, pattern_graph):
        self.pattern_graph = pattern_graph
        self.level_edges = {}
        self.level_constraints = {}
        self.duplicate_checks = set([])
        if pattern_graph is None:
            return
        if len(pattern_graph.independent_vertices) != 1:
            raise ValueError("A pattern_graph must not be a disconnected "
                             "graph.")
        # A) the levels for the incremental pattern matching
        ibfe = self.pattern_graph.iter_breadth_first_edges(self.start_vertex)
        for edge, distance, constraint in ibfe:
            if constraint:
                l = self.level_constraints.setdefault(distance-1, [])
            else:
                l = self.level_edges.setdefault(distance, [])
            l.append(edge)
        #print "level_edges", self.level_edges
        #print "level_constraints", self.level_constraints
        # B) The comparisons the should be checked when one wants to avoid
        # symmetrically duplicate pattern matches
        if self.criteria_sets is not None:
            for cycles in pattern_graph.symmetry_cycles:
                if len(cycles) > 0:
                    self.duplicate_checks.add((cycles[0][0], cycles[0][1]))

Response: Initialize the pattern_graph and initialize the internal state of the object.


Instruction:
Can you write a function in Python 3 where it
iterates over all valid initial relations for a match

Response:
def iter_initial_relations(self, subject_graph):
        """Iterate over all valid initial relations for a match"""
        vertex0 = self.start_vertex
        for vertex1 in range(subject_graph.num_vertices):
            if self.compare(vertex0, vertex1, subject_graph):
                yield vertex0, vertex1


Instruction:
Here you have a function in Python 3, explain what it does
def get_new_edges(self, level):
        return (
            self.level_edges.get(level, []),
            self.level_constraints.get(level, [])
        )

Response: Get new edges from the pattern graph for the graph search algorithm


Instruction:
Implement a function in Python 3 to
check if the next match can be a valid one.

Response:
def check_next_match(self, match, new_relations, subject_graph, one_match):
        """Check if the (onset for a) match can be a valid"""
        # only returns true for ecaxtly one set of new_relations from all the
        # ones that are symmetrically equivalent
        if not (self.criteria_sets is None or one_match):
            for check in self.duplicate_checks:
                vertex_a = new_relations.get(check[0])
                vertex_b = new_relations.get(check[1])
                if vertex_a is None and vertex_b is None:
                    continue # if this pair is completely absent in the new
                    # relations, it is either completely in the match or it
                    # is to be matched. So it is either already checked for
                    # symmetry duplicates, or it will be check in future.
                if vertex_a is None:
                    # maybe vertex_a is in the match and vertex_b is the only
                    # one in the new relations. try to get vertex_a from the
                    # match.
                    vertex_a = match.forward.get(check[0])
                    if vertex_a is None:
                        # ok, vertex_a is to be found, don't care about it right
                        # now. it will be checked in future calls.
                        continue
                elif vertex_b is None:
                    # maybe vertex_b is in the match and vertex_a is the only
                    # one in the new relations. try to get vertex_b from the
                    # match.
                    vertex_b = match.forward.get(check[1])
                    if vertex_b is None:
                        # ok, vertex_b is to be found, don't care about it right
                        # now. it will be checked in future calls.
                        continue
                if vertex_a > vertex_b:
                    # Why does this work? The answer is not so easy to explain,
                    # and certainly not easy to find. if vertex_a > vertex_b, it
                    # means that there is a symmetry operation that leads to
                    # an equivalent match where vertex_b < vertex_a. The latter
                    # match is preferred for as much pairs (vertex_a, vertex_b)
                    # as possible without rejecting all possible matches. The
                    # real difficulty is to construct a proper list of
                    # (vertex_a, vertex_b) pairs that will reject all but one
                    # matches. I conjecture that this list contains all the
                    # first two vertices from each normalized symmetry cycle of
                    # the pattern graph. We need a math guy to do the proof. -- Toon
                    return False
            return True
        return True


Instruction:
Create a Python 3 function to
give a match iterate over all related equivalent matches that fulfill one of the criteria sets.

Response:
def iter_final_matches(self, canonical_match, subject_graph, one_match):
        """Given a match, iterate over all related equivalent matches

           When criteria sets are defined, the iterator runs over all symmetric
           equivalent matches that fulfill one of the criteria sets. When not
           criteria sets are defined, the iterator only yields the input match.
        """
        if self.criteria_sets is None or one_match:
            yield canonical_match
        else:
            for criteria_set in self.criteria_sets:
                satisfied_match_tags = set([])
                for symmetry in self.pattern_graph.symmetries:
                    final_match = canonical_match * symmetry
                    #print final_match
                    if criteria_set.test_match(final_match, self.pattern_graph, subject_graph):
                        match_tags = tuple(
                            self.vertex_tags.get(symmetry.reverse[vertex0])
                            for vertex0
                            in range(self.pattern_graph.num_vertices)
                        )
                        if match_tags not in satisfied_match_tags:
                            final_match.__dict__.update(criteria_set.info)
                            yield final_match
                            satisfied_match_tags.add(match_tags)


Instruction:
Create a Python 3 function to
return the closed cycles corresponding to this permutation.

Response:
def get_closed_cycles(self):
        """Return the closed cycles corresponding to this permutation

           The cycle will be normalized to facilitate the elimination of
           duplicates. The following is guaranteed:

           1) If this permutation is represented by disconnected cycles, the
              cycles will be sorted by the lowest index they contain.
           2) Each cycle starts with its lowest index. (unique starting point)
           3) Singletons are discarded. (because they are boring)
        """
        # A) construct all the cycles
        closed_cycles = []
        todo = set(self.forward.keys())
        if todo != set(self.forward.values()):
            raise GraphError("The subject and pattern graph must have the same "
                             "numbering.")
        current_vertex = None
        while len(todo) > 0:
            if current_vertex == None:
                current_vertex = todo.pop()
                current_cycle = []
            else:
                todo.discard(current_vertex)
            current_cycle.append(current_vertex)
            next_vertex = self.get_destination(current_vertex)
            if next_vertex == current_cycle[0]:
                if len(current_cycle) > 1:
                    # bring the lowest element in front
                    pivot = np.argmin(current_cycle)
                    current_cycle = current_cycle[pivot:] + \
                                    current_cycle[:pivot]
                    closed_cycles.append(current_cycle)
                current_vertex = None
            else:
                current_vertex = next_vertex
        # B) normalize the cycle representation
        closed_cycles.sort() # a normal sort is sufficient because only the
                             # first item of each cycle is considered

        # transform the structure into a tuple of tuples
        closed_cycles = tuple(tuple(cycle) for cycle in closed_cycles)
        return closed_cycles


Instruction:
How would you implement a function in Python 3 that
iterates over all valid initial relations for a match

Response:
def iter_initial_relations(self, subject_graph):
        """Iterate over all valid initial relations for a match"""
        if self.pattern_graph.num_edges != subject_graph.num_edges:
            return # don't even try
        for pair in CustomPattern.iter_initial_relations(self, subject_graph):
            yield pair


Instruction:
Can you generate the documentation for the following Python 3 function
def compare(self, vertex0, vertex1, subject_graph):
        return (
            self.pattern_graph.vertex_fingerprints[vertex0] ==
            subject_graph.vertex_fingerprints[vertex1]
        ).all()

Response: Returns true when the two vertices are of the same kind


Instruction:
How would you code a function in Python 3 to
iterate over all valid initial relations for a match

Response:
def iter_initial_relations(self, subject_graph):
        """Iterate over all valid initial relations for a match"""
        vertex0 = 0
        for vertex1 in range(subject_graph.num_vertices):
            yield vertex0, vertex1


Instruction:
How would you code a function in Python 3 to
get the new edges from the pattern graph for the graph search algorithm.

Response:
def get_new_edges(self, level):
        """Get new edges from the pattern graph for the graph search algorithm

           The level argument denotes the distance of the new edges from the
           starting vertex in the pattern graph.
        """
        if level == 0:
            edges0 = [(0, 1), (0, 2)]
        elif level >= (self.max_size-1)//2:
            edges0 = []
        else:
            l2 = level*2
            edges0 = [(l2-1, l2+1), (l2, l2+2)]
        return edges0, []


Instruction:
Here you have a function in Python 3, explain what it does
def check_next_match(self, match, new_relations, subject_graph, one_match):
        # avoid duplicate rings (order of traversal)
        if len(match) == 3:
            if match.forward[1] < match.forward[2]:
                #print "RingPattern.check_next_match: duplicate order", match.forward[1], match.forward[2]
                return False
        # avoid duplicate rings (starting point)
        for vertex1 in new_relations.values():
            if vertex1 < match.forward[0]:
                #print "RingPattern.check_next_match: duplicate start", vertex1, match.forward[0]
                return False
        # can this ever become a strong ring?
        for vertex1 in new_relations.values():
            paths = list(subject_graph.iter_shortest_paths(vertex1, match.forward[0]))
            if len(paths) != 1:
                #print "RingPattern.check_next_match: not strong 1"
                return False
            if len(paths[0]) != (len(match)+1)//2:
                #print "RingPattern.check_next_match: not strong 2"
                return False
        return True

Response: Check if the next match can be a valid one


Instruction:
Given the following Python 3 function, write the documentation
def complete(self, match, subject_graph):
        size = len(match)
        # check whether we have an odd strong ring
        if match.forward[size-1] in subject_graph.neighbors[match.forward[size-2]]:
            # we have an odd closed cycle. check if this is a strong ring
            order = list(range(0, size, 2)) + list(range(1, size-1, 2))[::-1]
            ok = True
            for i in range(len(order)//2):
                # Count the number of paths between two opposite points in the
                # ring. Since the ring has an odd number of vertices, each
                # vertex has two semi-opposite vertices.
                count = len(list(subject_graph.iter_shortest_paths(
                    match.forward[order[i]],
                    match.forward[order[(i+size//2)%size]]
                )))
                if count > 1:
                    ok = False
                    break
                count = len(list(subject_graph.iter_shortest_paths(
                    match.forward[order[i]],
                    match.forward[order[(i+size//2+1)%size]]
                )))
                if count > 1:
                    ok = False
                    break
            if ok:
                match.ring_vertices = tuple(match.forward[i] for i in order)
                #print "RingPattern.complete: found odd ring"
                return True
            #print "RingPattern.complete: no odd ring"
        # check whether we have an even strong ring
        paths = list(subject_graph.iter_shortest_paths(
            match.forward[size-1],
            match.forward[size-2]
        ))
        #print "RingPattern.complete: even paths", paths
        if (size > 3 and len(paths) == 1 and len(paths[0]) == 3) or \
           (size == 3 and len(paths) == 2 and len(paths[0]) == 3):
            path = paths[0]
            if size == 3 and path[1] == match.forward[0]:
                path = paths[1]
            # we have an even closed cycle. check if this is a strong ring
            match.add_relation(size, path[1])
            size += 1
            order = list(range(0, size, 2)) + list(range(size-1, 0, -2))
            ok = True
            for i in range(len(order)//2):
                count = len(list(subject_graph.iter_shortest_paths(
                    match.forward[order[i]],
                    match.forward[order[(i+size//2)%size]]
                )))
                if count != 2:
                    ok = False
                    break
            if ok:
                # also check if this does not violate the requirement for a
                # unique origin:
                if match.forward[size-1] < match.forward[0]:
                    ok = False
            if not ok:
                vertex1 = match.forward[size-1]
                del match.forward[size-1]
                del match.reverse[vertex1]
                size -= 1
                #print "RingPattern.complete: no even ring"
            else:
                match.ring_vertices = tuple(match.forward[i] for i in order)
                #print "RingPattern.complete: found even ring"
            return ok
        #print "RingPattern.complete: not at all"
        return False

Response: Check whether a match is complete.


Instruction:
Can you generate the documentation for the following Python 3 function
def print_debug(self, text, indent=0):
        if self.debug:
            if indent > 0:
                print(" "*self.debug, text)
            self.debug += indent
            if indent <= 0:
                print(" "*self.debug, text)

Response: Only prints debug info on screen when self. debug == True.


Instruction:
Explain what the following Python 3 code does
def _iter_candidate_groups(self, init_match, edges0, edges1):
        # collect all end vertices0 and end vertices1 that belong to the same
        # group.
        sources = {}
        for start_vertex0, end_vertex0 in edges0:
            l = sources.setdefault(start_vertex0, [])
            l.append(end_vertex0)
        dests = {}
        for start_vertex1, end_vertex1 in edges1:
            start_vertex0 = init_match.reverse[start_vertex1]
            l = dests.setdefault(start_vertex0, [])
            l.append(end_vertex1)
        for start_vertex0, end_vertices0 in sources.items():
            end_vertices1 = dests.get(start_vertex0, [])
            yield end_vertices0, end_vertices1

Response: Divide the edges into groups.


Instruction:
Write a Python 3 function for
iterating over all possible new relations in a subject graph.

Response:
def _iter_new_relations(self, init_match, subject_graph, edges0, constraints0, edges1):
        """Given an onset for a match, iterate over all possible new key-value pairs"""
        # Count the number of unique edges0[i][1] values. This is also
        # the number of new relations.
        num_new_relations = len(set(j for i, j in edges0))

        def combine_small(relations, num):
            """iterate over all compatible combinations within one set of relations"""
            if len(relations) == 0:
                return
            for i, pivot in enumerate(relations):
                if num == 1:
                    yield (pivot, )
                else:
                    compatible_relations = list(
                        item for item in relations[:i]
                        if pivot[0]!=item[0] and pivot[1]!=item[1]
                    )
                    for tail in combine_small(compatible_relations, num-1):
                        yield (pivot, ) + tail

        # generate candidate relations
        candidate_relations = []
        icg = self._iter_candidate_groups(init_match, edges0, edges1)
        for end_vertices0, end_vertices1 in icg:
            if len(end_vertices0) > len(end_vertices1):
                return # this can never work, the subject graph is 'too small'
            elif not self.pattern.sub and \
                 len(end_vertices0) != len(end_vertices1):
                return # an exact match is sought, this can never work
            l = []
            for end_vertex0 in end_vertices0:
                for end_vertex1 in end_vertices1:
                    if self.pattern.compare(end_vertex0, end_vertex1, subject_graph):
                        l.append((end_vertex0, end_vertex1))
            # len(end_vertices0) = the total number of relations that must be
            # made in this group
            if len(l) > 0:
                # turn l into a list of sets of internally compatible candidate
                # relations in this group
                l = list(combine_small(l, len(end_vertices0)))
                candidate_relations.append(l)
        if len(candidate_relations) == 0:
            return
        self.print_debug("candidate_relations: %s" % candidate_relations)

        def combine_big(pos=0):
            """Iterate over all possible sets of relations"""
            # pos is an index in candidate_relations
            crs = candidate_relations[pos]
            if pos == len(candidate_relations)-1:
                for relations in crs:
                    yield relations
            else:
                for tail in combine_big(pos+1):
                    for relations in crs:
                        yield relations + tail

        # final loop
        for new_relations in combine_big():
            new_relations = set(new_relations)
            self.print_debug("new_relations: %s" % (new_relations, ))
            # check the total number of new relations
            if len(new_relations) != num_new_relations:
                continue
            # check sanity of relations
            forward = dict(new_relations)
            if len(forward) != num_new_relations:
                continue
            reverse = dict((j, i) for i, j in new_relations)
            if len(reverse) != num_new_relations:
                continue
            # check the constraints
            for a0, b0 in constraints0:
                if forward[a0] not in subject_graph.neighbors[forward[b0]]:
                    forward = None
                    break
            if forward is None:
                continue
            yield forward


Instruction:
Create a Python 3 function to
give an onset for a match, iterate over all completions of that match This iterator works recursively. At each level the match is extended with a new set of relations based on vertices in the pattern graph that are at a distances 'level' from the starting vertex

Response:
def _iter_matches(self, input_match, subject_graph, one_match, level=0):
        """Given an onset for a match, iterate over all completions of that match

           This iterator works recursively. At each level the match is extended
           with a new set of relations based on vertices in the pattern graph
           that are at a distances 'level' from the starting vertex
        """
        self.print_debug("ENTERING _ITER_MATCHES", 1)
        self.print_debug("input_match: %s" % input_match)
        # A) collect the new edges in the pattern graph and the subject graph
        # to extend the match.
        #
        # Note that the edges are ordered. edge[0] is always in the match.
        # edge[1] is never in the match. The constraints contain information
        # about the end points of edges0. It is a list of two-tuples where
        # (a, b) means that a and b must be connected.
        #
        # Second note: suffix 0 indicates the pattern graph and suffix 1
        # is used for the subject graph.
        edges0, constraints0 = self.pattern.get_new_edges(level)
        edges1 = input_match.get_new_edges(subject_graph)
        self.print_debug("edges0: %s" % edges0)
        self.print_debug("constraints0: %s" % constraints0)
        self.print_debug("edges1: %s" % edges1)

        # B) iterate over the sets of new relations: [(vertex0[i], vertex1[j]),
        # ...] that contain all endpoints of edges0, that satisfy the
        # constraints0 and where (vertex0[i], vertex1[j]) only occurs if these
        # are end points of a edge0 and edge1 whose starting points are already
        # in init_match. These conditions are implemented in an iterator as to
        # separate concerns. This iterator also calls the routines that check
        # whether vertex1[j] also satisfies additional conditions inherent
        # vertex0[i].
        inr = self._iter_new_relations(input_match, subject_graph, edges0,
                                       constraints0, edges1)
        for new_relations in inr:
            # for each set of new_relations, construct a next_match and recurse
            next_match = input_match.copy_with_new_relations(new_relations)
            if not self.pattern.check_next_match(next_match, new_relations, subject_graph, one_match):
                continue
            if self.pattern.complete(next_match, subject_graph):
                yield next_match
            else:
                for match in self._iter_matches(next_match, subject_graph, one_match, level+1):
                    yield match
        self.print_debug("LEAVING_ITER_MATCHES", -1)


Instruction:
Can you tell what is the following Python 3 function doing
def dump_pdb(filename, molecule, atomnames=None, resnames=None, chain_ids=None, occupancies=None, betas=None):

    with open(filename, "w") as f:
        res_id = 1
        old_resname = None

        for i in range(molecule.size):
            symbol = periodic[molecule.numbers[i]].symbol
            if atomnames is None:
                atomname = symbol
            else:
                atomname = atomnames[i]
            if resnames is None:
                resname = "OXO"
            else:
                resname = resnames[i]
            if resname != old_resname:
                res_id += 1
            if chain_ids is None:
                chain_id = "A"
            else:
                chain_id = chain_ids[i]
            if occupancies is None:
                occupancy = 1.0
            else:
                occupancy = occupancies[i]
            if betas is None:
                beta = 1.0
            else:
                beta = betas[i]

            print("ATOM   %4i  %3s %3s %1s%4i    %8.3f%8.3f%8.3f%6.2f%6.2f          %2s  " % (
                i+1, atomname.ljust(3), resname.ljust(3), chain_id, res_id,
                molecule.coordinates[i, 0]/angstrom,
                molecule.coordinates[i, 1]/angstrom,
                molecule.coordinates[i, 2]/angstrom,
                occupancy, beta, symbol.ljust(2)
            ), file=f)
            old_resname = resname

Response: Writes a single molecule to a PDB file.


Instruction:
Implement a Python 3 function for
loading a single molecule from a pdb file.

Response:
def load_pdb(filename):
    """Loads a single molecule from a pdb file.

       This function does support only a small fragment from the pdb specification.
       It assumes that there is only one molecular geometry in the pdb file.
    """
    with open(filename) as f:
        numbers = []
        coordinates = []
        occupancies = []
        betas = []
        for line in f:
            if line.startswith("ATOM"):
                symbol = line[76:78].strip()
                numbers.append(periodic[symbol].number)
                coordinates.append([float(line[30:38])*angstrom, float(line[38:46])*angstrom, float(line[46:54])*angstrom])
                occupancies.append(float(line[54:60]))
                betas.append(float(line[60:66]))
    if len(numbers) > 0:
        molecule = Molecule(numbers, coordinates)
        molecule.occupancies = np.array(occupancies)
        molecule.betas = np.array(betas)
        return molecule
    else:
        raise FileFormatError("No molecule found in pdb file %s" % filename)


Instruction:
Write a Python 3 script to
convert a ZMatrix back to cartesian coordinates.

Response:
def zmat_to_cart(zmat):
    """Converts a ZMatrix back to cartesian coordinates."""

    numbers = zmat["number"]
    N = len(numbers)
    coordinates = np.zeros((N, 3), float)

    # special cases for the first coordinates
    coordinates[1, 2] = zmat["distance"][1]
    if zmat["rel1"][2] == 1:
        sign = -1
    else:
        sign = 1
    coordinates[2, 2] = zmat["distance"][2]*sign*np.cos(zmat["angle"][2])
    coordinates[2, 1] = zmat["distance"][2]*sign*np.sin(zmat["angle"][2])
    coordinates[2] += coordinates[2-zmat["rel1"][2]]

    ref0 = 3
    for (number, distance, rel1, angle, rel2, dihed, rel3) in zmat[3:]:
        ref1 = ref0 - rel1
        ref2 = ref0 - rel2
        ref3 = ref0 - rel3
        if ref1 < 0: ref1 = 0
        if ref2 < 0: ref2 = 0
        if ref3 < 0: ref3 = 0
        # define frame axes
        origin = coordinates[ref1]
        new_z = coordinates[ref2] - origin
        norm_z = np.linalg.norm(new_z)
        if norm_z < 1e-15:
            new_z = np.array([0, 0, 1], float)
        else:
            new_z /= np.linalg.norm(new_z)
        new_x = coordinates[ref3] - origin
        new_x -= np.dot(new_x, new_z)*new_z
        norm_x = np.linalg.norm(new_x)
        if norm_x < 1e-15:
            new_x = random_orthonormal(new_z)
        else:
            new_x /= np.linalg.norm(new_x)
        # we must make our axes frame left handed due to the poor IUPAC
        # definition of the sign of a dihedral angle.
        new_y = -np.cross(new_z, new_x)

        # coordinates of new atom:
        x = distance*np.cos(dihed)*np.sin(angle)
        y = distance*np.sin(dihed)*np.sin(angle)
        z = distance*np.cos(angle)
        coordinates[ref0] = origin + x*new_x + y*new_y + z*new_z
        # loop
        ref0 += 1

    return numbers, coordinates


Instruction:
Here you have a function in Python 3, explain what it does
def _get_new_ref(self, existing_refs):
        # ref0 is the atom whose position is defined by the current row in the
        # zmatrix.
        ref0 = existing_refs[0]
        for ref in existing_refs:
            # try to find a neighbor of the ref that can serve as the new ref
            result = None
            for n in sorted(self.graph.neighbors[ref]):
                if self.new_index[n] > self.new_index[ref0]:
                    # index is too high, zmatrix rows can't refer to future
                    # atoms
                    continue
                if n in existing_refs:
                    # ref is already in use
                    continue
                if result is None or self.graph.numbers[n] <= self.graph.numbers[result]:
                    # acceptable ref, prefer heaviest atom
                    result = n
            if result is not None:
                return result
        raise RuntimeError("Could not find new reference.")

Response: Get a new reference atom for a row in the ZMatrix.


Instruction:
Make a summary of the following Python 3 code
def cart_to_zmat(self, coordinates):
        N = len(self.graph.numbers)
        if coordinates.shape != (N, 3):
            raise ValueError("The shape of the coordinates must be (%i, 3)" % N)
        result = np.zeros(N, dtype=self.dtype)
        for i in range(N):
            ref0 = self.old_index[i]
            rel1 = -1
            rel2 = -1
            rel3 = -1
            distance = 0
            angle = 0
            dihed = 0
            if i > 0:
                ref1 = self._get_new_ref([ref0])
                distance = np.linalg.norm(coordinates[ref0]-coordinates[ref1])
                rel1 = i - self.new_index[ref1]
            if i > 1:
                ref2 = self._get_new_ref([ref0, ref1])
                angle, = ic.bend_angle(coordinates[[ref0, ref1, ref2]])
                rel2 = i - self.new_index[ref2]
            if i > 2:
                ref3 = self._get_new_ref([ref0, ref1, ref2])
                dihed, = ic.dihed_angle(coordinates[[ref0, ref1, ref2, ref3]])
                rel3 = i - self.new_index[ref3]
            result[i] = (self.graph.numbers[i], distance, rel1, angle, rel2, dihed, rel3)
        return result

Response: Convert cartesian coordinates to ZMatrix format


Instruction:
How would you explain what the following Python 3 function does
def can_map_ipa_string(self, ipa_string):
        canonical = [(c.canonical_representation, ) for c in ipa_string]
        split = split_using_dictionary(canonical, self, self.max_key_length, single_char_parsing=False)
        for sub in split:
            if not sub in self.ipa_canonical_representation_to_mapped_str:
                return False
        return True

Response: Return True if the mapper can map all the IPA characters in the given IPA string.


Instruction:
Explain what the following Python 3 code does
def map_ipa_string(self, ipa_string, ignore=False, return_as_list=False, return_can_map=False):
        acc = []
        can_map = True
        canonical = [(c.canonical_representation, ) for c in ipa_string]
        split = split_using_dictionary(canonical, self, self.max_key_length, single_char_parsing=False)
        for sub in split:
            try:
                acc.append(self.ipa_canonical_representation_to_mapped_str[sub])
            except KeyError:
                if ignore:
                    can_map = False
                else:
                    raise ValueError("The IPA string contains an IPA character that is not mapped: %s" % sub)
        mapped = acc if return_as_list else u"".join(acc)
        if return_can_map:
            return (can_map, mapped)
        return mapped

Response: Convert the given IPA string to a string containing the corresponding ASCII IPA representation.


Instruction:
Make a summary of the following Python 3 code
def map_unicode_string(self, unicode_string, ignore=False, single_char_parsing=False, return_as_list=False, return_can_map=False):
        if unicode_string is None:
            return None
        ipa_string = IPAString(unicode_string=unicode_string, ignore=ignore, single_char_parsing=single_char_parsing)
        return self.map_ipa_string(
            ipa_string=ipa_string,
            ignore=ignore,
            return_as_list=return_as_list,
            return_can_map=return_can_map
        )

Response: Convert the given Unicode string representing an IPA string and an IPA string to a string containing the corresponding mapped representation.


Instruction:
Write a Python 3 function that can
print Unicode characters that are not IPA valid.

Response:
def print_invalid_chars(invalid_chars, vargs):
    """
    Print Unicode characterss that are not IPA valid,
    if requested by the user.

    :param list invalid_chars: a list (possibly empty) of invalid Unicode characters
    :param dict vargs: the command line parameters
    """
    if len(invalid_chars) > 0:
        if vargs["print_invalid"]:
            print(u"".join(invalid_chars))
        if vargs["unicode"]:
            for u_char in sorted(set(invalid_chars)):
                print(u"'%s'\t%s\t%s" % (u_char, hex(ord(u_char)), unicodedata.name(u_char, "UNKNOWN")))


Instruction:
Can you tell what is the following Python 3 function doing
def command_canonize(string, vargs):
    try:
        ipa_string = IPAString(
            unicode_string=string,
            ignore=vargs["ignore"],
            single_char_parsing=vargs["single_char_parsing"]
        )
        print(vargs["separator"].join([(u"%s" % c) for c in ipa_string]))
    except ValueError as exc:
        print_error(str(exc))

Response: Print the canonical representation of the given string.


Instruction:
Write a Python 3 script to
print a list of all IPA characters in the given string.

Response:
def command_chars(string, vargs):
    """
    Print a list of all IPA characters in the given string.

    It will print the Unicode representation, the full IPA name,
    and the Unicode "U+"-prefixed hexadecimal codepoint representation
    of each IPA character.

    :param str string: the string to act upon
    :param dict vargs: the command line arguments
    """
    try:
        ipa_string = IPAString(
            unicode_string=string,
            ignore=vargs["ignore"],
            single_char_parsing=vargs["single_char_parsing"]
        )
        for c in ipa_string:
            print(u"'%s'\t%s (%s)" % (c.unicode_repr, c.name, unicode_to_hex(c.unicode_repr)))
    except ValueError as exc:
        print_error(str(exc))


Instruction:
Make a summary of the following Python 3 code
def command_check(string, vargs):
    is_valid = is_valid_ipa(string)
    print(is_valid)
    if not is_valid:
        valid_chars, invalid_chars = remove_invalid_ipa_characters(
            unicode_string=string,
            return_invalid=True
        )
        print_invalid_chars(invalid_chars, vargs)

Response: Check if the given string is IPA valid.


Instruction:
Explain what the following Python 3 code does
def command_clean(string, vargs):
    valid_chars, invalid_chars = remove_invalid_ipa_characters(
        unicode_string=string,
        return_invalid=True,
        single_char_parsing=vargs["single_char_parsing"]
    )
    print(u"".join(valid_chars))
    print_invalid_chars(invalid_chars, vargs)

Response: Remove characters that are not IPA valid from the given string and print the remaining string.


Instruction:
Here you have a function in Python 3, explain what it does
def command_u2a(string, vargs):
    try:
        l = ARPABETMapper().map_unicode_string(
            unicode_string=string,
            ignore=vargs["ignore"],
            single_char_parsing=vargs["single_char_parsing"],
            return_as_list=True
        )
        print(vargs["separator"].join(l))
    except ValueError as exc:
        print_error(str(exc))

Response: Print the ARPABEY ASCII string corresponding to the given Unicode IPA string.


Instruction:
Given the following Python 3 function, write the documentation
def command_u2k(string, vargs):
    try:
        l = KirshenbaumMapper().map_unicode_string(
            unicode_string=string,
            ignore=vargs["ignore"],
            single_char_parsing=vargs["single_char_parsing"],
            return_as_list=True
        )
        print(vargs["separator"].join(l))
    except ValueError as exc:
        print_error(str(exc))

Response: Print the Kirshenbaum ASCII string corresponding to the given Unicode IPA string.


Instruction:
Implement a Python 3 function for
setting the list of IPAChar objects composing the IPA string

Response:
def ipa_chars(self, value):
        """
        Set the list of IPAChar objects composing the IPA string

        :param list value: list of IPAChar objects
        """
        if value is None:
            self.__ipa_chars = []
        else:
            if is_list_of_ipachars(value):
                self.__ipa_chars = value
            else:
                raise TypeError("ipa_chars only accepts a list of IPAChar objects")


Instruction:
Can you generate the documentation for the following Python 3 function
def is_equivalent(self, other, ignore=False):
        def is_equivalent_to_list_of_ipachars(other):
            """
            Return ``True`` if the list of IPAChar objects
            in the canonical representation of the string
            is the same as the given list.

            :param list other: list of IPAChar objects
            :rtype: bool
            """
            my_ipa_chars = self.canonical_representation.ipa_chars
            if len(my_ipa_chars) != len(other):
                return False
            for i in range(len(my_ipa_chars)):
                if not my_ipa_chars[i].is_equivalent(other[i]):
                    return False
            return True

        if is_unicode_string(other):
            try:
                return is_equivalent_to_list_of_ipachars(IPAString(unicode_string=other, ignore=ignore).ipa_chars)
            except:
                return False
        if is_list_of_ipachars(other):
            try:
                return is_equivalent_to_list_of_ipachars(other)
            except:
                return False
        if isinstance(other, IPAString):
            return is_equivalent_to_list_of_ipachars(other.canonical_representation.ipa_chars)
        return False

Response: Return True if the given object is equivalent to the given object.


Instruction:
Create a Python 3 function to
return a new IPAString containing the canonical representation of the current string and the minimum number of IPAChar objects.

Response:
def canonical_representation(self):
        """
        Return a new IPAString, containing the canonical representation of the current string,
        that is, the one composed by the (prefix) minimum number of IPAChar objects.

        :rtype: IPAString
        """
        return IPAString(unicode_string=u"".join([c.__unicode__() for c in self.ipa_chars]))


Instruction:
Given the following Python 3 function, write the documentation
def filter_chars(self, chars=u""):
        if chars in [u"cns", u"consonants"]:
            return self.consonants
        elif chars in [u"vwl", u"vowels"]:
            return self.vowels
        elif chars in [u"cns_vwl", u"letters"]:
            return self.letters
        elif chars in [u"cns_vwl_pstr", u"cvp"]:
            return self.cns_vwl_pstr
        elif chars in [u"cns_vwl_pstr_long", u"cvpl"]:
            return self.cns_vwl_pstr_long
        elif chars in [u"cns_vwl_str", u"cvs"]:
            return self.cns_vwl_str
        elif chars in [u"cns_vwl_str_len", u"cvsl"]:
            return self.cns_vwl_str_len
        elif chars in [u"cns_vwl_str_len_wb", u"cvslw"]:
            return self.cns_vwl_str_len_wb
        elif chars in [u"cns_vwl_str_len_wb_sb", u"cvslws"]:
            return self.cns_vwl_str_len_wb_sb
        return self

Response: Returns a new IPAString containing only the characters specified by the chars string.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def consonants(self):
        return IPAString(ipa_chars=[c for c in self.ipa_chars if c.is_consonant])

Response: Returns a new IPAString containing only the consonants in the current string.


Instruction:
How would you explain what the following Python 3 function does
def vowels(self):
        return IPAString(ipa_chars=[c for c in self.ipa_chars if c.is_vowel])

Response: Returns a new string containing only the vowels in the current string.


Instruction:
Explain what the following Python 3 code does
def cns_vwl(self):
        return IPAString(ipa_chars=[c for c in self.ipa_chars if c.is_letter])

Response: Returns a new IPAString containing only the consonants and vowels in the current string.


Instruction:
Given the following Python 3 function, write the documentation
def cns_vwl_pstr(self):
        return IPAString(ipa_chars=[c for c in self.ipa_chars if (c.is_letter) or (c.is_suprasegmental and c.is_primary_stress)])

Response: Returns a new IPAString containing only the consonants and vowels and the primary stress diacritics in the current string.


Instruction:
Implement a Python 3 function for
returning a new string containing only the consonants and vowels and the stress diacritics in the current string.

Response:
def cns_vwl_str(self):
        """
        Return a new IPAString, containing only:

        1. the consonants,
        2. the vowels, and
        3. the stress diacritics

        in the current string.

        :rtype: IPAString
        """
        return IPAString(ipa_chars=[c for c in self.ipa_chars if (c.is_letter) or (c.is_suprasegmental and c.is_stress)])


Instruction:
Can you create a Python 3 function that
returns a new string containing only the consonants and vowels and the length diacritics and the consonants and the length diacritics.

Response:
def cns_vwl_str_len(self):
        """
        Return a new IPAString, containing only:

        1. the consonants,
        2. the vowels, and
        3. the stress diacritics, and
        4. the length diacritics

        in the current string.

        :rtype: IPAString
        """
        return IPAString(ipa_chars=[c for c in self.ipa_chars if (c.is_letter) or (c.is_suprasegmental and (c.is_stress or c.is_length))])


Instruction:
How would you implement a function in Python 3 that
returns a new string containing only the consonants and vowels and the long suprasegmental characters in the current string.

Response:
def cns_vwl_pstr_long(self):
        """
        Return a new IPAString, containing only:

        1. the consonants,
        2. the vowels, and
        3. the primary stress diacritics, and
        4. the long suprasegmental

        in the current string.

        :rtype: IPAString
        """
        return IPAString(ipa_chars=[c for c in self.ipa_chars if (c.is_letter) or (c.is_suprasegmental and (c.is_primary_stress or c.is_long))])


Instruction:
Implement a Python 3 function for
returning a new string containing only the consonants and the length diacritics and the word breaks in the current string.

Response:
def cns_vwl_str_len_wb(self):
        """
        Return a new IPAString, containing only:

        1. the consonants,
        2. the vowels, and
        3. the stress diacritics,
        4. the length diacritics, and
        5. the word breaks

        in the current string.

        :rtype: IPAString
        """
        return IPAString(ipa_chars=[c for c in self.ipa_chars if (c.is_letter) or (c.is_suprasegmental and (c.is_stress or c.is_length or c.is_word_break))])


Instruction:
How would you explain what the following Python 3 function does
def cns_vwl_str_len_wb_sb(self):
        return IPAString(ipa_chars=[c for c in self.ipa_chars if (c.is_letter) or (c.is_suprasegmental and (c.is_stress or c.is_length or c.is_word_break or c.is_syllable_break))])

Response: Return a new string containing only the characters that are not suprasegmental and length diacritics and the word breaks and the syllable breaks in the current string.


Instruction:
Make a summary of the following Python 3 code
def convert_unicode_field(string):
    values = []
    for codepoint in [s for s in string.split(DATA_FILE_CODEPOINT_SEPARATOR) if (s != DATA_FILE_VALUE_NOT_AVAILABLE) and (len(s) > 0)]:
        values.append(u"".join([hex_to_unichr(c) for c in codepoint.split(DATA_FILE_CODEPOINT_JOINER)]))
    return values

Response: Convert a Unicode field into a list of Unicode strings.


Instruction:
Explain what the following Python 3 code does
def convert_ascii_field(string):
    values = []
    for codepoint in [s for s in string.split(DATA_FILE_CODEPOINT_SEPARATOR) if (s != DATA_FILE_VALUE_NOT_AVAILABLE) and (len(s) > 0)]:
        #if DATA_FILE_CODEPOINT_JOINER in codepoint:
        #    values.append(u"".join([hex_to_unichr(c) for c in codepoint.split(DATA_FILE_CODEPOINT_JOINER)]))
        if (codepoint.startswith(DATA_FILE_ASCII_NUMERICAL_CODEPOINT_START)) or (codepoint.startswith(DATA_FILE_ASCII_UNICODE_CODEPOINT_START)):
            values.append(hex_to_unichr(codepoint))
        else:
            values.append(codepoint)
    return values

Response: Convert an ASCII field into a list of Unicode strings.


Instruction:
Implement a function in Python 3 to
convert a tuple of raw values according to the given line format.

Response:
def convert_raw_tuple(value_tuple, format_string):
    """
    Convert a tuple of raw values, according to the given line format.

    :param tuple value_tuple: the tuple of raw values
    :param str format_string: the format of the tuple
    :rtype: list of tuples
    """
    values = []
    for v, c in zip(value_tuple, format_string):
        if v is None:
            # append None
            values.append(v)
        elif c == u"s":
            # string
            values.append(v)
        elif c == u"S":
            # string, split using space as delimiter
            values.append([s for s in v.split(u" ") if len(s) > 0])
        elif c == u"i":
            # int
            values.append(int(v))
        elif c == u"U":
            # Unicode
            values.append(convert_unicode_field(v))
        elif c == u"A":
            # ASCII
            values.append(convert_ascii_field(v))
        #elif c == u"x":
        #    # ignore
        #    pass
    return tuple(values)


Instruction:
Make a summary of the following Python 3 code
def load_data_file(
    file_path,
    file_path_is_relative=False,
    comment_string=DATA_FILE_COMMENT,
    field_separator=DATA_FILE_FIELD_SEPARATOR,
    line_format=None
):
    """
    Load a data file, with one record per line and
    fields separated by ``field_separator``,
    returning a list of tuples.

    It ignores lines starting with ``comment_string`` or empty lines.

    If ``values_per_line`` is not ``None``,
    check that each line (tuple)
    has the prescribed number of values.

    :param str file_path: path of the data file to load
    :param bool file_path_is_relative: if ``True``, ``file_path`` is relative to this source code file
    :param str comment_string: ignore lines starting with this string
    :param str field_separator: fields are separated by this string
    :param str line_format: if not ``None``, parses each line according to the given format
                            (``s`` = string, ``S`` = split string using spaces,
                            ``i`` = int, ``x`` = ignore, ``U`` = Unicode, ``A`` = ASCII)
    :rtype: list of tuples
    """
    raw_tuples = []
    if file_path_is_relative:
        file_path = os.path.join(os.path.dirname(__file__), file_path)
    with io.open(file_path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if (len(line) > 0) and (not line.startswith(comment_string)):
                raw_list = line.split(field_separator)
                if len(raw_list) != len(line_format):
                    raise ValueError("Data file '%s' contains a bad line: '%s'" % (file_path, line))
                raw_tuples.append(tuple(raw_list))
    if (line_format is None) or (len(line_format) < 1):
        return raw_tuples
    return [convert_raw_tuple(t, line_format) for t in raw_tuples]

Response: Load a data file and return a list of tuples.


Instruction:
Write a Python 3 function that can
load the IPA data from the built - in IPA database and create the IPA character objects.

Response:
def load_ipa_data():
    """
    Load the IPA data from the built-in IPA database, creating the following globals:

    1. ``IPA_CHARS``: list of all IPAChar objects
    2. ``UNICODE_TO_IPA``: dict mapping a Unicode string (often, a single char) to an IPAChar
    3. ``UNICODE_TO_IPA_MAX_KEY_LENGTH``: length of a longest key in ``UNICODE_TO_IPA``
    4. ``IPA_TO_UNICODE``: map an IPAChar canonical representation to the corresponding Unicode string (or char)
    """
    ipa_signs = []
    unicode_to_ipa = {}
    ipa_to_unicode = {}
    max_key_length = 0
    for line in load_data_file(
        file_path=u"ipa.dat",
        file_path_is_relative=True,
        line_format=u"sU"
    ):
        # unpack data
        i_desc, i_unicode_keys = line
        name = re.sub(r" [ ]*", " ", i_desc)

        # create a suitable IPACharacter obj
        if u"consonant" in i_desc:
            obj = IPAConsonant(name=name, descriptors=i_desc)
        elif u"vowel" in i_desc:
            obj = IPAVowel(name=name, descriptors=i_desc)
        elif u"diacritic" in i_desc:
            obj = IPADiacritic(name=name, descriptors=i_desc)
        elif u"suprasegmental" in i_desc:
            obj = IPASuprasegmental(name=name, descriptors=i_desc)
        elif u"tone" in i_desc:
            obj = IPATone(name=name, descriptors=i_desc)
        else:
            raise ValueError("The IPA data file contains a bad line, defining an unknown type: '%s'" % (line))
        ipa_signs.append(obj)

        # map Unicode codepoint to object, if the former is available
        if len(i_unicode_keys) > 0:
            # canonical Unicode string
            first_key = i_unicode_keys[0]
            ipa_to_unicode[obj.canonical_representation] = first_key
            obj.unicode_repr = first_key
            max_key_length = max(max_key_length, len(first_key))
            # add all Unicode strings
            for key in i_unicode_keys:
                if key in unicode_to_ipa:
                    raise ValueError("The IPA data file contains a bad line, redefining codepoint '%s': '%s'" % (key, line))
                unicode_to_ipa[key] = obj
    return ipa_signs, unicode_to_ipa, max_key_length, ipa_to_unicode


Instruction:
Write a Python 3 script for
splitting a string into a list of substrings of the given dictionary.

Response:
def split_using_dictionary(string, dictionary, max_key_length, single_char_parsing=False):
    """
    Return a list of (non-empty) substrings of the given string,
    where each substring is either:

    1. the longest string starting at the current index
       that is a key in the dictionary, or
    2. a single character that is not a key in the dictionary.

    If ``single_char_parsing`` is ``False``,
    parse the string one Unicode character at a time,
    that is, do not perform the greedy parsing.

    :param iterable string: the iterable object ("string") to split into atoms
    :param dict dictionary: the dictionary mapping atoms ("characters") to something else
    :param int max_key_length: the length of a longest key, in number of characters
    :param bool single_char_parsing: if ``True``, parse one Unicode character at a time
    """
    def substring(string, i, j):
        if isinstance(string[i], tuple):
            # transform list of tuples with one element in a tuple with all elements
            return tuple([string[k][0] for k in range(i, j)])
        # just return substring
        return string[i:j]

    if string is None:
        return None
    if (single_char_parsing) or (max_key_length < 2):
        return [c for c in string]
    acc = []
    l = len(string)
    i = 0
    while i < l:
        found = False
        for j in range(min(i + max_key_length, l), i, -1):
            sub = substring(string, i, j)
            if sub in dictionary:
                found = True
                acc.append(sub)
                i = j
                break
        if not found:
            acc.append(string[i])
            i += 1
    return acc


Instruction:
Given the following Python 3 function, write the documentation
def ipa_substrings(unicode_string, single_char_parsing=False):
    return split_using_dictionary(
        string=unicode_string,
        dictionary=UNICODE_TO_IPA,
        max_key_length=UNICODE_TO_IPA_MAX_KEY_LENGTH,
        single_char_parsing=single_char_parsing
    )

Response: Returns a list of substrings of the given Unicode string.


Instruction:
Can you generate the documentation for the following Python 3 function
def invalid_ipa_characters(unicode_string, indices=False):
    if unicode_string is None:
        return None
    if indices:
        return [(i, unicode_string[i]) for i in range(len(unicode_string)) if unicode_string[i] not in UNICODE_TO_IPA]
    return set([c for c in unicode_string if c not in UNICODE_TO_IPA])

Response: Returns the list of Unicode characters that are not IPA valid.


Instruction:
Make a summary of the following Python 3 code
def remove_invalid_ipa_characters(unicode_string, return_invalid=False, single_char_parsing=False):
    if unicode_string is None:
        return None
    substrings = ipa_substrings(unicode_string, single_char_parsing=single_char_parsing)
    valid = [s for s in substrings if s in UNICODE_TO_IPA]
    if return_invalid:
        return (valid, [s for s in substrings if s not in UNICODE_TO_IPA])
    return valid

Response: Removes all Unicode characters that are not IPA valid from the given string and returns a list of substrings of the given string that are not IPA valid.


Instruction:
How would you explain what the following Python 3 function does
def variant_to_list(obj):
    if isinstance(obj, list):
        return obj
    elif is_unicode_string(obj):
        return [s for s in obj.split() if len(s) > 0]
    elif isinstance(obj, set) or isinstance(obj, frozenset):
        return list(obj)
    raise TypeError("The given value must be a list or a set of descriptor strings, or a Unicode string.")

Response: Converts a given variant into a list containing the descriptors in the given object.


Instruction:
How would you code a function in Python 3 to
convert a Variant object into a list containing the canonical string for the given object.

Response:
def variant_to_canonical_string(obj):
    """
    Return a list containing the canonical string for the given object.

    The ``obj`` can be a list or a set of descriptor strings, or a Unicode string.

    If ``obj`` is a Unicode string, it will be split using spaces as delimiters.

    :param variant obj: the object to be parsed
    :rtype: str
    :raise TypeError: if the ``obj`` has a type not listed above
    """
    acc = [DG_ALL_DESCRIPTORS.canonical_value(p) for p in variant_to_list(obj)]
    acc = sorted([a for a in acc if a is not None])
    return u" ".join(acc)


Instruction:
Create a Python 3 function for
returning True if the given object is a list of IPAChar objects.

Response:
def is_list_of_ipachars(obj):
    """
    Return ``True`` if the given object is a list of IPAChar objects.

    :param object obj: the object to test
    :rtype: bool
    """
    if isinstance(obj, list):
        for e in obj:
            if not isinstance(e, IPAChar):
                return False
        return True
    return False


Instruction:
Can you generate the documentation for the following Python 3 function
def is_equivalent(self, other):
        if (self.unicode_repr is not None) and (is_unicode_string(other)) and (self.unicode_repr == other):
            return True
        if isinstance(other, IPAChar):
            return self.canonical_representation == other.canonical_representation
        try:
            return self.canonical_representation == IPAChar(name=None, descriptors=other).canonical_representation
        except:
            return False

Response: Return True if the IPA character is equivalent to the other object.


Instruction:
Write a Python 3 script for
returning the canonical value of a character in the given descriptor group.

Response:
def dg_value(self, descriptor_group):
        """
        Return the canonical value of a descriptor of the character,
        provided it is present in the given descriptor group.

        If not present, return ``None``.

        :param IPADescriptorGroup descriptor_group: the descriptor group to be checked against
        :rtype: str
        """
        for p in self.descriptors:
            if p in descriptor_group:
                return descriptor_group.canonical_value(p)
        return None


Instruction:
Can you create a Python 3 function that
returns True if the character has the given descriptor.

Response:
def has_descriptor(self, descriptor):
        """
        Return ``True`` if the character has the given descriptor.

        :param IPADescriptor descriptor: the descriptor to be checked against
        :rtype: bool
        """
        for p in self.descriptors:
            if p in descriptor:
                return True
        return False


Instruction:
Here you have a function in Python 3, explain what it does
def voicing(self, value):
        if (value is not None) and (not value in DG_C_VOICING):
            raise ValueError("Unrecognized value for voicing: '%s'" % value)
        self.__voicing = value

Response: Sets the voicing of the consonant.


Instruction:
How would you explain what the following Python 3 function does
def place(self, value):
        if (value is not None) and (not value in DG_C_PLACE):
            raise ValueError("Unrecognized value for place: '%s'" % value)
        self.__place = value

Response: Sets the place of articulation of the consonant.


Instruction:
Implement a Python 3 function for
setting the manner of articulation of the consonant.

Response:
def manner(self, value):
        """
        Set the manner of articulation of the consonant.

        :param str value: the value to be set
        """
        if (value is not None) and (not value in DG_C_MANNER):
            raise ValueError("Unrecognized value for manner: '%s'" % value)
        self.__manner = value


Instruction:
Can you generate a brief explanation for the following Python 3 code
def height(self, value):
        if (value is not None) and (not value in DG_V_HEIGHT):
            raise ValueError("Unrecognized value for height: '%s'" % value)
        self.__height = value

Response: Sets the height of the vowel.


Instruction:
Explain what the following Python 3 code does
def backness(self, value):
        if (value is not None) and (not value in DG_V_BACKNESS):
            raise ValueError("Unrecognized value for backness: '%s'" % value)
        self.__backness = value

Response: Sets the backness of the vowel.


Instruction:
Explain what the following Python 3 code does
def roundness(self, value):
        if (value is not None) and (not value in DG_V_ROUNDNESS):
            raise ValueError("Unrecognized value for roundness: '%s'" % value)
        self.__roundness = value

Response: Sets the roundness of the vowel.


Instruction:
How would you implement a function in Python 3 that
loads the Kirshenbaum ASCII IPA data from the built - in database.

Response:
def _load_data(self):
        """
        Load the Kirshenbaum ASCII IPA data from the built-in database.
        """
        ipa_canonical_string_to_ascii_str = dict()
        for line in load_data_file(
            file_path=self.DATA_FILE_PATH,
            file_path_is_relative=True,
            line_format=u"sxA"
        ):
            i_desc, i_ascii = line
            if len(i_ascii) == 0:
                raise ValueError("Data file '%s' contains a bad line: '%s'" % (self.DATA_FILE_PATH, line))
            key = (variant_to_canonical_string(i_desc),)
            ipa_canonical_string_to_ascii_str[key] = i_ascii[0]
        return ipa_canonical_string_to_ascii_str


Instruction:
How would you implement a function in Python 3 that
returns the canonical value corresponding to the given query value.

Response:
def canonical_value(self, query):
        """
        Return the canonical value corresponding to the given query value.

        Return ``None`` if the query value is not present in any descriptor of the group.

        :param str query: the descriptor value to be checked against
        """
        for d in self.descriptors:
            if query in d:
                return d.canonical_label
        return None


Instruction:
Given the following Python 3 function, write the documentation
def _load_data(self):
        ipa_canonical_string_to_ascii_str = dict()
        for line in load_data_file(
            file_path=self.DATA_FILE_PATH,
            file_path_is_relative=True,
            line_format=u"UA"
        ):
            i_unicode, i_ascii = line
            if (len(i_unicode) == 0) or (len(i_ascii) == 0):
                raise ValueError("Data file '%s' contains a bad line: '%s'" % (self.DATA_FILE_PATH, line))
            i_unicode = i_unicode[0]
            i_ascii = i_ascii[0]
            key = tuple([UNICODE_TO_IPA[c].canonical_representation for c in i_unicode])
            ipa_canonical_string_to_ascii_str[key] = i_ascii
        return ipa_canonical_string_to_ascii_str

Response: Load the ARPABET ASCII IPA data from the built - in database.


Instruction:
Here you have a function in Python 3, explain what it does
def is_unicode_string(string):
    if string is None:
        return None
    if PY2:
        return isinstance(string, unicode)
    return isinstance(string, str)

Response: Checks if the given string is a Unicode string in Python 2 or str in Python 3.


Instruction:
Write a Python 3 script to
convert a string into a Unicode string.

Response:
def to_unicode_string(string):
    """
    Return a Unicode string out of the given string.

    On Python 2, it calls ``unicode`` with ``utf-8`` encoding.
    On Python 3, it just returns the given string.

    Return ``None`` if ``string`` is ``None``.

    :param str string: the string to convert to Unicode
    :rtype: (Unicode) str
    """
    if string is None:
        return None
    if is_unicode_string(string):
        return string
    # if reached here, string is a byte string
    if PY2:
        return unicode(string, encoding="utf-8")
    return string.decode(encoding="utf-8")


Instruction:
Write a Python 3 script to
convert a string to a native - str.

Response:
def to_str(string):
    """
    Return the given string (either byte string or Unicode string)
    converted to native-str, that is,
    a byte string on Python 2, or a Unicode string on Python 3.

    Return ``None`` if ``string`` is ``None``.

    :param str string: the string to convert to native-str
    :rtype: native-str
    """
    if string is None:
        return None
    if isinstance(string, str):
        return string
    if PY2:
        return string.encode("utf-8")
    return string.decode("utf-8")


Instruction:
Write a Python 3 script to
convert a hexadecimal string to Unicode character.

Response:
def hex_to_unichr(hex_string):
    """
    Return the Unicode character with the given codepoint,
    given as an hexadecimal string.

    Return ``None`` if ``hex_string`` is ``None`` or is empty.

    Example::
        "0061"   => a
        "U+0061" => a

    :param str hex_string: the Unicode codepoint of the desired character
    :rtype: (Unicode) str
    """
    if (hex_string is None) or (len(hex_string) < 1):
        return None
    if hex_string.startswith("U+"):
        hex_string = hex_string[2:]
    return int_to_unichr(int(hex_string, base=16))


Instruction:
Can you generate the documentation for the following Python 3 function
def unicode_to_hex(unicode_string):
    if unicode_string is None:
        return None
    acc = []
    for c in unicode_string:
        s = hex(ord(c)).replace("0x", "").upper()
        acc.append("U+" + ("0" * (4 - len(s))) + s)
    return u" ".join(acc)

Response: Converts a Unicode string to a Unicode hexadecimal codepoint.


Instruction:
Explain what the following Python 3 code does
def parse_html(html):
    body = html.strip().replace('\x00', '').encode('utf8') or b'<html/>'
    parser = lxml.html.HTMLParser(recover=True, encoding='utf8')
    root = lxml.etree.fromstring(body, parser=parser)
    if root is None:
        root = lxml.etree.fromstring(b'<html/>', parser=parser)
    return root

Response: Parse a string with html.


Instruction:
Given the following Python 3 function, write the documentation
def etree_to_text(tree,
                  guess_punct_space=True,
                  guess_layout=True,
                  newline_tags=NEWLINE_TAGS,
                  double_newline_tags=DOUBLE_NEWLINE_TAGS):
    """
    Convert a html tree to text. Tree should be cleaned with
    ``html_text.html_text.cleaner.clean_html`` before passing to this
    function.

    See html_text.extract_text docstring for description of the
    approach and options.
    """
    chunks = []

    _NEWLINE = object()
    _DOUBLE_NEWLINE = object()

    class Context:
        """ workaround for missing `nonlocal` in Python 2 """
        # _NEWLINE, _DOUBLE_NEWLINE or content of the previous chunk (str)
        prev = _DOUBLE_NEWLINE

    def should_add_space(text, prev):
        """ Return True if extra whitespace should be added before text """
        if prev in {_NEWLINE, _DOUBLE_NEWLINE}:
            return False
        if not _has_trailing_whitespace(prev):
            if _has_punct_after(text) or _has_open_bracket_before(prev):
                return False
        return True

    def get_space_between(text, prev):
        if not text or not guess_punct_space:
            return ' '
        return ' ' if should_add_space(text, prev) else ''

    def add_newlines(tag, context):
        if not guess_layout:
            return
        prev = context.prev
        if prev is _DOUBLE_NEWLINE:  # don't output more than 1 blank line
            return
        if tag in double_newline_tags:
            context.prev = _DOUBLE_NEWLINE
            chunks.append('\n' if prev is _NEWLINE else '\n\n')
        elif tag in newline_tags:
            context.prev = _NEWLINE
            if prev is not _NEWLINE:
                chunks.append('\n')

    def add_text(text_content, context):
        text = _normalize_whitespace(text_content) if text_content else ''
        if not text:
            return
        space = get_space_between(text, context.prev)
        chunks.extend([space, text])
        context.prev = text_content

    def traverse_text_fragments(tree, context, handle_tail=True):
        """ Extract text from the ``tree``: fill ``chunks`` variable """
        add_newlines(tree.tag, context)
        add_text(tree.text, context)
        for child in tree:
            traverse_text_fragments(child, context)
        add_newlines(tree.tag, context)
        if handle_tail:
            add_text(tree.tail, context)

    traverse_text_fragments(tree, context=Context(), handle_tail=False)
    return ''.join(chunks).strip()

Response: Convert an etree to text.


Instruction:
Implement a function in Python 3 to
convert a cleaned parsel. Selector to text.

Response:
def selector_to_text(sel, guess_punct_space=True, guess_layout=True):
    """ Convert a cleaned parsel.Selector to text.
    See html_text.extract_text docstring for description of the approach
    and options.
    """
    import parsel
    if isinstance(sel, parsel.SelectorList):
        # if selecting a specific xpath
        text = []
        for s in sel:
            extracted = etree_to_text(
                s.root,
                guess_punct_space=guess_punct_space,
                guess_layout=guess_layout)
            if extracted:
                text.append(extracted)
        return ' '.join(text)
    else:
        return etree_to_text(
            sel.root,
            guess_punct_space=guess_punct_space,
            guess_layout=guess_layout)