def Func(arg_0, arg_1):  # pylint: disable=unused-argument
    """
    Check that if request user has implicit access to `ENTERPRISE_ENROLLMENT_API_ADMIN_ROLE` feature role.

    Returns:
        boolean: whether the request user has access or not
    """
    arg_2 = get_request_or_stub()
    arg_3 = get_decoded_jwt_from_request(arg_2)
    return request_user_has_implicit_access_via_jwt(arg_3, ENTERPRISE_ENROLLMENT_API_ADMIN_ROLE, arg_1)


def Func(arg_0, arg_1):
        """
        Instance is EnterpriseCustomer. Return e-commerce coupon urls.
        """
        if not arg_1.entitlement_id:
            return "N/A"

        return format_html(
            'View coupon "{id}" details',
            base_url=settings.ECOMMERCE_PUBLIC_URL_ROOT, id=arg_1.entitlement_id
        )


def Func(arg_0="Export selected objects as CSV file", arg_1=None, arg_2=True):
    """
    Return an export csv action.

    Arguments:
        description (string): action description
        fields ([string]): list of model fields to include
        header (bool): whether or not to output the column names as the first row
    """
    # adapted from https://gist.github.com/mgerring/3645889
    def arg_15(arg_3, arg_4, arg_5):  # pylint: disable=unused-argument
        """
        Export model fields to CSV.
        """
        arg_6 = arg_3.model._meta

        if not arg_1:
            arg_7 = [arg_13.name for arg_13 in arg_6.fields]
        else:
            arg_7 = arg_1

        arg_8 = HttpResponse(content_type="text/csv")
        arg_8["Content-Disposition"] = "attachment; filename={filename}.csv".format(
            filename=str(arg_6).replace(".", "_")
        )

        arg_9 = unicodecsv.writer(arg_8, encoding="utf-8")
        if arg_2:
            arg_9.writerow(arg_7)
        for arg_10 in arg_5:
            arg_11 = []
            for arg_12 in arg_7:
                arg_13 = getattr(arg_10, arg_12)
                if callable(arg_13):
                    arg_14 = arg_13()
                else:
                    arg_14 = arg_13
                if arg_14 is None:
                    arg_11.append("[Not Set]")
                elif not arg_14 and isinstance(arg_14, string_types):
                    arg_11.append("[Empty]")
                else:
                    arg_11.append(arg_14)
            arg_9.writerow(arg_11)
        return arg_8

    arg_15.short_description = arg_0
    return arg_15


def Func(arg_0=None):
    """
    Return the action method to clear the catalog ID for a EnterpriseCustomer.
    """
    arg_0 = arg_0 or _("Unlink selected objects from existing course catalogs")

    def arg_4(arg_1, arg_2, arg_3):  # pylint: disable=unused-argument
        """
        Clear the catalog ID for a selected EnterpriseCustomer.
        """
        arg_3.update(catalog=None)
    arg_4.short_description = arg_0
    return arg_4


def Func(arg_0):
        """
        Get information about maps of the robots.

        :return:
        """
        for arg_1 in arg_0.robots:
            arg_2 = (
                requests.get(urljoin(arg_0.ENDPOINT, 'users/me/robots/{}/maps'.format(arg_1.serial)),
                             headers=arg_0._headers))
            arg_2.raise_for_status()
            arg_0._maps.update({arg_1.serial: arg_2.json()})


def Func(arg_0):
        """
        Get information about robots connected to account.

        :return:
        """
        arg_1 = requests.get(urljoin(arg_0.ENDPOINT, 'dashboard'),
                            headers=arg_0._headers)
        arg_1.raise_for_status()

        for arg_2 in arg_1.json()['robots']:
            if arg_2['mac_address'] is None:
                continue    # Ignore robots without mac-address

            try:
                arg_0._robots.add(Robot(name=arg_2['name'],
                                       serial=arg_2['serial'],
                                       secret=arg_2['secret_key'],
                                       traits=arg_2['traits'],
                                       endpoint=arg_2['nucleo_url']))
            except requests.exceptions.HTTPError:
                print ("Your '{}' robot is offline.".format(arg_2['name']))
                continue

        arg_0.refresh_persistent_maps()
        for arg_2 in arg_0._robots:
            arg_2.has_persistent_maps = arg_2.serial in arg_0._persistent_maps


def Func(arg_0):
        """
        Get information about persistent maps of the robots.

        :return:
        """
        for arg_1 in arg_0._robots:
            arg_2 = (requests.get(urljoin(
                arg_0.ENDPOINT,
                'users/me/robots/{}/persistent_maps'.format(arg_1.serial)),
                headers=arg_0._headers))
            arg_2.raise_for_status()
            arg_0._persistent_maps.update({arg_1.serial: arg_2.json()})


def Func(arg_0, arg_1):
    """Calculates the distance between two points on earth.
    """
    arg_2, arg_3 = arg_0
    arg_4, arg_5 = arg_1
    arg_6 = arg_5 - arg_3
    arg_7 = arg_4 - arg_2
    arg_8 = 6371  # radius of the earth in kilometers
    arg_9 = np.sin(arg_7 / 2)**2 + np.cos(arg_2) * np.cos(arg_4) * (np.sin(arg_6 / 2))**2
    arg_10 = 2 * np.pi * arg_8 * np.arctan2(np.sqrt(arg_9), np.sqrt(1 - arg_9)) / 180
    return arg_10


def Func(arg_0, arg_1=True):
    """Takes a graph and returns an adjacency list.

    Parameters
    ----------
    g : :any:`networkx.DiGraph`, :any:`networkx.Graph`, etc.
        Any object that networkx can turn into a
        :any:`DiGraph<networkx.DiGraph>`.
    return_dict_of_dict : bool (optional, default: ``True``)
        Specifies whether this function will return a dict of dicts
        or a dict of lists.

    Returns
    -------
    adj : dict
        An adjacency representation of graph as a dictionary of
        dictionaries, where a key is the vertex index for a vertex
        ``v`` and the values are :class:`dicts<.dict>` with keys for
        the vertex index and values as edge properties.

    Examples
    --------
    >>> import queueing_tool as qt
    >>> import networkx as nx
    >>> adj = {0: [1, 2], 1: [0], 2: [0, 3], 3: [2]}
    >>> g = nx.DiGraph(adj)
    >>> qt.Func(g, return_dict_of_dict=True)
    ...  # doctest: +NORMALIZE_WHITESPACE
    {0: {1: {}, 2: {}},
    1: {0: {}},
    2: {0: {}, 3: {}},
    3: {2: {}}}
    >>> qt.Func(g, return_dict_of_dict=False)
    {0: [1, 2], 1: [0], 2: [0, 3], 3: [2]}
    """
    if not isinstance(arg_0, nx.DiGraph):
        arg_0 = QueueNetworkDiGraph(arg_0)

    arg_2 = nx.to_dict_of_dicts(arg_0)
    if arg_1:
        return arg_2
    else:
        return {arg_3: list(arg_4.keys()) for arg_3, arg_4 in arg_2.items()}


def Func(arg_0):
    """Takes a dictionary based representation of an adjacency list
    and returns a dict of dicts based representation.
    """
    arg_1 = arg_0.popitem()
    arg_0[arg_1[0]] = arg_1[1]
    if not isinstance(arg_1[1], dict):
        arg_2 = {}
        for arg_3, arg_4 in arg_0.items():
            arg_2[arg_3] = {v: {} for v in arg_4}

        arg_0 = arg_2
    return arg_0


def Func(arg_0, arg_1=None, arg_2=1, **arg_3):
    """Takes an adjacency list, dict, or matrix and returns a graph.

    The purpose of this function is take an adjacency list (or matrix)
    and return a :class:`.QueueNetworkDiGraph` that can be used with a
    :class:`.QueueNetwork` instance. The Graph returned has the
    ``edge_type`` edge property set for each edge. Note that the graph may
    be altered.

    Parameters
    ----------
    adjacency : dict or :class:`~numpy.ndarray`
        An adjacency list as either a dict, or an adjacency matrix.
    adjust : int ``{1, 2}`` (optional, default: 1)
        Specifies what to do when the graph has terminal vertices
        (nodes with no out-edges). Note that if ``adjust`` is not 2
        then it is assumed to be 1. There are two choices:

        * ``adjust = 1``: A loop is added to each terminal node in the
          graph, and their ``edge_type`` of that loop is set to 0.
        * ``adjust = 2``: All edges leading to terminal nodes have
          their ``edge_type`` set to 0.

    **kwargs :
        Unused.

    Returns
    -------
    out : :any:`networkx.DiGraph`
        A directed graph with the ``edge_type`` edge property.

    Raises
    ------
    TypeError
        Is raised if ``adjacency`` is not a dict or
        :class:`~numpy.ndarray`.

    Examples
    --------
    If terminal nodes are such that all in-edges have edge type ``0``
    then nothing is changed. However, if a node is a terminal node then
    a loop is added with edge type 0.

    >>> import queueing_tool as qt
    >>> adj = {
    ...     0: {1: {}},
    ...     1: {2: {},
    ...         3: {}},
    ...     3: {0: {}}}
    >>> eTy = {0: {1: 1}, 1: {2: 2, 3: 4}, 3: {0: 1}}
    >>> # A loop will be added to vertex 2
    >>> g = qt.Func(adj, edge_type=eTy)
    >>> ans = qt.graph2dict(g)
    >>> sorted(ans.items())     # doctest: +NORMALIZE_WHITESPACE
    [(0, {1: {'edge_type': 1}}),
     (1, {2: {'edge_type': 2}, 3: {'edge_type': 4}}),
     (2, {2: {'edge_type': 0}}),
     (3, {0: {'edge_type': 1}})]

    You can use a dict of lists to represent the adjacency list.

    >>> adj = {0 : [1], 1: [2, 3], 3: [0]}
    >>> g = qt.Func(adj, edge_type=eTy)
    >>> ans = qt.graph2dict(g)
    >>> sorted(ans.items())     # doctest: +NORMALIZE_WHITESPACE
    [(0, {1: {'edge_type': 1}}),
     (1, {2: {'edge_type': 2}, 3: {'edge_type': 4}}),
     (2, {2: {'edge_type': 0}}),
     (3, {0: {'edge_type': 1}})]

    Alternatively, you could have this function adjust the edges that
    lead to terminal vertices by changing their edge type to 0:

    >>> # The graph is unaltered
    >>> g = qt.Func(adj, edge_type=eTy, adjust=2)
    >>> ans = qt.graph2dict(g)
    >>> sorted(ans.items())     # doctest: +NORMALIZE_WHITESPACE
    [(0, {1: {'edge_type': 1}}),
     (1, {2: {'edge_type': 0}, 3: {'edge_type': 4}}),
     (2, {}),
     (3, {0: {'edge_type': 1}})]
    """

    if isinstance(arg_0, np.ndarray):
        arg_0 = _matrix2dict(arg_0)
    elif isinstance(arg_0, dict):
        arg_0 = _dict2dict(arg_0)
    else:
        arg_4 = ("If the adjacency parameter is supplied it must be a "
               "dict, or a numpy.ndarray.")
        raise TypeError(arg_4)

    if arg_1 is None:
        arg_1 = {}
    else:
        if isinstance(arg_1, np.ndarray):
            arg_1 = _matrix2dict(arg_1, etype=True)
        elif isinstance(arg_1, dict):
            arg_1 = _dict2dict(arg_1)

    for arg_5, arg_6 in arg_1.items():
        for arg_7, arg_8 in arg_6.items():
            arg_0[arg_5][arg_7]['edge_type'] = arg_8

    arg_9 = nx.from_dict_of_dicts(arg_0, create_using=nx.DiGraph())
    arg_0 = nx.to_dict_of_dicts(arg_9)
    arg_0 = _adjacency_adjust(arg_0, arg_2, True)

    return nx.from_dict_of_dicts(arg_0, create_using=nx.DiGraph())


def Func(arg_0, arg_1):
        """Returns all edges with the specified edge type.

        Parameters
        ----------
        edge_type : int
            An integer specifying what type of edges to return.

        Returns
        -------
        out : list of 2-tuples
            A list of 2-tuples representing the edges in the graph
            with the specified edge type.

        Examples
        --------
        Lets get type 2 edges from the following graph

        >>> import queueing_tool as qt
        >>> adjacency = {
        ...     0: {1: {'edge_type': 2}},
        ...     1: {2: {'edge_type': 1},
        ...         3: {'edge_type': 4}},
        ...     2: {0: {'edge_type': 2}},
        ...     3: {3: {'edge_type': 0}}
        ... }
        >>> G = qt.QueueNetworkDiGraph(adjacency)
        >>> ans = G.Func(2)
        >>> ans.sort()
        >>> ans
        [(0, 1), (2, 0)]
        """
        arg_2 = []
        for arg_3 in arg_0.edges():
            if arg_0.adj[arg_3[0]][arg_3[1]].get('edge_type') == arg_1:
                arg_2.append(arg_3)
        return arg_2


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None):
        """Returns the arguments used when plotting.

        Takes any keyword arguments for
        :class:`~matplotlib.collections.LineCollection` and
        :meth:`~matplotlib.axes.Axes.scatter` and returns two
        dictionaries with all the defaults set.

        Parameters
        ----------
        line_kwargs : dict (optional, default: ``None``)
            Any keyword arguments accepted by
            :class:`~matplotlib.collections.LineCollection`.
        scatter_kwargs : dict (optional, default: ``None``)
            Any keyword arguments accepted by
            :meth:`~matplotlib.axes.Axes.scatter`.

        Returns
        -------
        tuple
            A 2-tuple of dicts. The first entry is the keyword
            arguments for
            :class:`~matplotlib.collections.LineCollection` and the
            second is the keyword args for
            :meth:`~matplotlib.axes.Axes.scatter`.

        Notes
        -----
        If a specific keyword argument is not passed then the defaults
        are used.
        """
        if arg_3 is not None:
            arg_0.set_pos(arg_3)
        elif arg_0.pos is None:
            arg_0.set_pos()

        arg_4 = [0 for arg_5 in arg_0.edges()]
        for arg_5 in arg_0.edges():
            arg_6 = arg_0.edge_index[arg_5]
            arg_4[arg_6] = (arg_0.pos[arg_5[0]], arg_0.pos[arg_5[1]])

        arg_7 = {
            'segments': arg_4,
            'colors': arg_0.edge_color,
            'linewidths': (1,),
            'antialiaseds': (1,),
            'linestyle': 'solid',
            'transOffset': None,
            'cmap': plt.cm.ocean_r,
            'pickradius': 5,
            'zorder': 0,
            'facecolors': None,
            'norm': None,
            'offsets': None,
            'offset_position': 'screen',
            'hatch': None,
        }
        arg_8 = {
            'x': arg_0.pos[:, 0],
            'y': arg_0.pos[:, 1],
            's': 50,
            'c': arg_0.vertex_fill_color,
            'alpha': None,
            'norm': None,
            'vmin': None,
            'vmax': None,
            'marker': 'o',
            'zorder': 2,
            'cmap': plt.cm.ocean_r,
            'linewidths': 1,
            'edgecolors': arg_0.vertex_color,
            'facecolors': None,
            'antialiaseds': None,
            'offset_position': 'screen',
            'hatch': None,
        }

        arg_1 = {} if arg_1 is None else arg_1
        arg_2 = {} if arg_2 is None else arg_2

        for arg_9, arg_10 in arg_1.items():
            if arg_9 in arg_7:
                arg_7[arg_9] = arg_10

        for arg_9, arg_10 in arg_2.items():
            if arg_9 in arg_8:
                arg_8[arg_9] = arg_10

        return arg_7, arg_8


def Func(arg_0, arg_1, arg_2):
    """A function that returns the arrival time of the next arrival for
    a Poisson random measure.

    Parameters
    ----------
    t : float
        The start time from which to simulate the next arrival time.
    rate : function
        The *intensity function* for the measure, where ``rate(t)`` is
        the expected arrival rate at time ``t``.
    rate_max : float
        The maximum value of the ``rate`` function.

    Returns
    -------
    out : float
        The time of the next arrival.

    Notes
    -----
    This function returns the time of the next arrival, where the
    distribution of the number of arrivals between times :math:`t` and
    :math:`t+s` is Poisson with mean

    .. math::

       \int_{t}^{t+s} dx \, r(x)

    where :math:`r(t)` is the supplied ``rate`` function. This function
    can only simulate processes that have bounded intensity functions.
    See chapter 6 of [3]_ for more on the mathematics behind Poisson
    random measures; the book's publisher, Springer, has that chapter
    available online for free at (`pdf`_\).

    A Poisson random measure is sometimes called a non-homogeneous
    Poisson process. A Poisson process is a special type of Poisson
    random measure.

    .. _pdf: http://www.springer.com/cda/content/document/\
                cda_downloaddocument/9780387878584-c1.pdf

    Examples
    --------
    Suppose you wanted to model the arrival process as a Poisson
    random measure with rate function :math:`r(t) = 2 + \sin( 2\pi t)`.
    Then you could do so as follows:

    >>> import queueing_tool as qt
    >>> import numpy as np
    >>> np.random.seed(10)
    >>> rate  = lambda t: 2 + np.sin(2 * np.pi * t)
    >>> arr_f = lambda t: qt.Func(t, rate, 3)
    >>> arr_f(1)  # doctest: +ELLIPSIS
    1.491...

    References
    ----------
    .. [3] Cinlar, Erhan. *Probability and stochastics*. Graduate Texts in\
           Mathematics. Vol. 261. Springer, New York, 2011.\
           :doi:`10.1007/978-0-387-87859-1`
    """
    arg_3 = 1.0 / arg_2
    arg_0 = arg_0 + exponential(arg_3)
    while arg_2 * uniform() > arg_1(arg_0):
        arg_0 = arg_0 + exponential(arg_3)
    return arg_0


def Func(arg_0, arg_1=0):
        """Returns a color for the queue.

        Parameters
        ----------
        which : int (optional, default: ``0``)
            Specifies the type of color to return.

        Returns
        -------
        color : list
            Returns a RGBA color that is represented as a list with 4
            entries where each entry can be any floating point number
            between 0 and 1.

            * If ``which`` is 1 then it returns the color of the edge
              as if it were a self loop. This is specified in
              ``colors['edge_loop_color']``.
            * If ``which`` is 2 then it returns the color of the vertex
              pen color (defined as color/vertex_color in
              :meth:`.QueueNetworkDiGraph.graph_draw`). This is
              specified in ``colors['vertex_color']``.
            * If ``which`` is anything else, then it returns the a
              shade of the edge that is proportional to the number of
              agents in the system -- which includes those being
              servered and those waiting to be served. More agents
              correspond to darker edge colors. Uses
              ``colors['vertex_fill_color']`` if the queue sits on a
              loop, and ``colors['edge_color']`` otherwise.
        """
        if arg_1 == 1:
            arg_2 = arg_0.colors['edge_loop_color']

        elif arg_1 == 2:
            arg_2 = arg_0.colors['vertex_color']

        else:
            arg_3 = arg_0.coloring_sensitivity * arg_0.num_servers + 1.
            arg_4 = 1. - min(arg_0.num_system / arg_3, 1)

            if arg_0.edge[0] == arg_0.edge[1]:
                arg_2 = [i * arg_4 for i in arg_0.colors['vertex_fill_color']]
                arg_2[3] = 1.0
            else:
                arg_2 = [i * arg_4 for i in arg_0.colors['edge_color']]
                arg_2[3] = 1 / 2.

        return arg_2


def Func(arg_0):
        """Returns an integer representing whether the next event is
        an arrival, a departure, or nothing.

        Returns
        -------
        out : int
            An integer representing whether the next event is an
            arrival or a departure: ``1`` corresponds to an arrival,
            ``2`` corresponds to a departure, and ``0`` corresponds to
            nothing scheduled to occur.
        """
        if arg_0._departures[0]._time < arg_0._arrivals[0]._time:
            return 2
        elif arg_0._arrivals[0]._time < infty:
            return 1
        else:
            return 0


def Func(arg_0):
        """Resets the queue to its initial state.

        The attributes ``t``, ``num_events``, ``num_agents`` are set to
        zero, :meth:`.reset_colors` is called, and the
        :meth:`.QueueServer.Func` method is called for each queue in
        the network.

        Notes
        -----
        ``QueueNetwork`` must be re-initialized before any simulations
        can run.
        """
        arg_0._t = 0
        arg_0.num_events = 0
        arg_0.num_agents = np.zeros(arg_0.nE, int)
        arg_0._fancy_heap = PriorityQueue()
        arg_0._prev_edge = None
        arg_0._initialized = False
        arg_0.reset_colors()
        for arg_7 in arg_0.edge2queue:
            arg_7.Func()


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None):
        """Clears data from all queues.

        If none of the parameters are given then every queue's data is
        cleared.

        Parameters
        ----------
        queues : int or an iterable of int (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` whose data will
            be cleared.
        edge : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues' data to clear. Must be
            either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types will have their data cleared.
        """
        arg_1 = _get_queues(arg_0.g, arg_1, arg_2, arg_3)

        for arg_4 in arg_1:
            arg_0.edge2queue[arg_4].data = {}


def Func(arg_0):
        """Returns a deep Func of itself."""
        arg_1 = QueueNetwork(None)
        arg_1.g = arg_0.g.Func()
        arg_1.max_agents = Func.deepFunc(arg_0.max_agents)
        arg_1.nV = Func.deepFunc(arg_0.nV)
        arg_1.nE = Func.deepFunc(arg_0.nE)
        arg_1.num_agents = Func.deepFunc(arg_0.num_agents)
        arg_1.num_events = Func.deepFunc(arg_0.num_events)
        arg_1._t = Func.deepFunc(arg_0._t)
        arg_1._initialized = Func.deepFunc(arg_0._initialized)
        arg_1._prev_edge = Func.deepFunc(arg_0._prev_edge)
        arg_1._blocking = Func.deepFunc(arg_0._blocking)
        arg_1.colors = Func.deepFunc(arg_0.colors)
        arg_1.out_edges = Func.deepFunc(arg_0.out_edges)
        arg_1.in_edges = Func.deepFunc(arg_0.in_edges)
        arg_1.edge2queue = Func.deepFunc(arg_0.edge2queue)
        arg_1._route_probs = Func.deepFunc(arg_0._route_probs)

        if arg_1._initialized:
            arg_17 = [q._key() for q in arg_1.edge2queue if q._time < np.infty]
            arg_1._fancy_heap = PriorityQueue(arg_17, arg_1.nE)

        return arg_1


def Func(arg_0, arg_1=True, arg_2=None,
             arg_3=None, **arg_4):
        """Draws the network. The coloring of the network corresponds
        to the number of agents at each queue.

        Parameters
        ----------
        update_colors : ``bool`` (optional, default: ``True``).
            Specifies whether all the colors are updated.
        line_kwargs : dict (optional, default: None)
            Any keyword arguments accepted by
            :class:`~matplotlib.collections.LineCollection`
        scatter_kwargs : dict (optional, default: None)
            Any keyword arguments accepted by
            :meth:`~matplotlib.axes.Axes.scatter`.
        bgcolor : list (optional, keyword only)
            A list with 4 floats representing a RGBA color. The
            default is defined in ``self.colors['bgcolor']``.
        figsize : tuple (optional, keyword only, default: ``(7, 7)``)
            The width and height of the canvas in inches.
        **kwargs
            Any parameters to pass to
            :meth:`.QueueNetworkDiGraph.Func_graph`.

        Notes
        -----
        This method relies heavily on
        :meth:`.QueueNetworkDiGraph.Func_graph`. Also, there is a
        parameter that sets the background color of the canvas, which
        is the ``bgcolor`` parameter.

        Examples
        --------
        To Func the current state of the network, call:

        >>> import queueing_tool as qt
        >>> g = qt.generate_pagerank_graph(100, seed=13)
        >>> net = qt.QueueNetwork(g, seed=13)
        >>> net.initialize(100)
        >>> net.simulate(1200)
        >>> net.Func() # doctest: +SKIP

        If you specify a file name and location, the Funcing will be
        saved to disk. For example, to save the Funcing to the current
        working directory do the following:

        >>> net.Func(fname="state.png", scatter_kwargs={'s': 40}) # doctest: +SKIP

        .. figure:: current_state1.png
            :align: center

        The shade of each edge depicts how many agents are located at
        the corresponding queue. The shade of each vertex is determined
        by the total number of inbound agents. Although loops are not
        visible by default, the vertex that corresponds to a loop shows
        how many agents are in that loop.

        There are several additional parameters that can be passed --
        all :meth:`.QueueNetworkDiGraph.Func_graph` parameters are
        valid. For example, to show the edges as dashed lines do the
        following.

        >>> net.Func(line_kwargs={'linestyle': 'dashed'}) # doctest: +SKIP
        """
        if not HAS_MATPLOTLIB:
            raise ImportError("matplotlib is necessary to Func the network.")

        if arg_1:
            arg_0._update_all_colors()

        if 'bgcolor' not in arg_4:
            arg_4['bgcolor'] = arg_0.colors['bgcolor']

        arg_0.g.Func_graph(arg_2=arg_2,
                          arg_3=arg_3, **arg_4)


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None, arg_4=False):
        """Gets data from queues and organizes it by agent.

        If none of the parameters are given then data from every
        :class:`.QueueServer` is retrieved.

        Parameters
        ----------
        queues : int or *array_like* (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` whose data will
            be retrieved.
        edge : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues to retrieve agent data
            from. Must be either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types to retrieve agent data from.
        return_header : bool (optonal, default: False)
            Determines whether the column headers are returned.

        Returns
        -------
        dict
            Returns a ``dict`` where the keys are the
            :class:`Agent's<.Agent>` ``agent_id`` and the values are
            :class:`ndarrays<~numpy.ndarray>` for that
            :class:`Agent's<.Agent>` data. The columns of this array
            are as follows:

            * First: The arrival time of an agent.
            * Second: The service start time of an agent.
            * Third: The departure time of an agent.
            * Fourth: The length of the queue upon the agents arrival.
            * Fifth: The total number of :class:`Agents<.Agent>` in the
              :class:`.QueueServer`.
            * Sixth: the :class:`QueueServer's<.QueueServer>` id
              (its edge index).

        headers : str (optional)
            A comma seperated string of the column headers. Returns
            ``'arrival,service,departure,num_queued,num_total,q_id'``
        """
        arg_1 = _get_queues(arg_0.g, arg_1, arg_2, arg_3)

        arg_5 = {}
        for arg_6 in arg_1:
            for arg_7, arg_8 in arg_0.edge2queue[arg_6].data.items():
                arg_9 = np.zeros((len(arg_8), 6))
                arg_9[:, :5] = np.array(arg_8)
                arg_9[:, 5] = arg_6
                if arg_7 in arg_5:
                    arg_5[arg_7] = np.vstack((arg_5[arg_7], arg_9))
                else:
                    arg_5[arg_7] = arg_9

        arg_10 = [
            ('a', float),
            ('s', float),
            ('d', float),
            ('q', float),
            ('n', float),
            ('id', float)
        ]
        for arg_7, arg_8 in arg_5.items():
            arg_9 = np.array([tuple(d) for d in arg_8.tolist()], dtype=arg_10)
            arg_9 = np.sort(arg_9, order='a')
            arg_5[arg_7] = np.array([tuple(d) for d in arg_9])

        if arg_4:
            return arg_5, 'arrival,service,departure,num_queued,num_total,q_id'

        return arg_5


def Func(arg_0, arg_1=1, arg_2=None, arg_3=None, arg_4=None):
        """Prepares the ``QueueNetwork`` for simulation.

        Each :class:`.QueueServer` in the network starts inactive,
        which means they do not accept arrivals from outside the
        network, and they have no agents in their system. This method
        sets queues to active, which then allows agents to arrive from
        outside the network.

        Parameters
        ----------
        nActive : int (optional, default: ``1``)
            The number of queues to set as active. The queues are
            selected randomly.
        queues : int *array_like* (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` to make active by.
        edges : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues to make active. Must be
            either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types will be set active.

        Raises
        ------
        ValueError
            If ``queues``, ``egdes``, and ``edge_type`` are all ``None``
            and ``nActive`` is an integer less than 1
            :exc:`~ValueError` is raised.
        TypeError
            If ``queues``, ``egdes``, and ``edge_type`` are all ``None``
            and ``nActive`` is not an integer then a :exc:`~TypeError`
            is raised.
        QueueingToolError
            Raised if all the queues specified are
            :class:`NullQueues<.NullQueue>`.

        Notes
        -----
        :class:`NullQueues<.NullQueue>` cannot be activated, and are
        sifted out if they are specified. More specifically, every edge
        with edge type 0 is sifted out.
        """
        if arg_2 is None and arg_3 is None and arg_4 is None:
            if arg_1 >= 1 and isinstance(arg_1, numbers.Integral):
                arg_5 = [q.edge[2] for q in arg_0.edge2queue if q.edge[3] != 0]
                arg_6 = min(arg_1, len(arg_5))
                arg_2 = np.random.choice(arg_5, size=arg_6, replace=False)
            elif not isinstance(arg_1, numbers.Integral):
                arg_7 = "If queues is None, then nActive must be an integer."
                raise TypeError(arg_7)
            else:
                arg_7 = ("If queues is None, then nActive must be a "
                       "positive int.")
                raise ValueError(arg_7)
        else:
            arg_2 = _get_queues(arg_0.g, arg_2, arg_3, arg_4)

        arg_2 = [e for e in arg_2 if arg_0.edge2queue[e].edge[3] != 0]

        if len(arg_2) == 0:
            raise QueueingToolError("There were no queues to Func.")

        if len(arg_2) > arg_0.max_agents:
            arg_2 = arg_2[:arg_0.max_agents]

        for arg_8 in arg_2:
            arg_0.edge2queue[arg_8].set_active()
            arg_0.num_agents[arg_8] = arg_0.edge2queue[arg_8]._num_total

        arg_10 = [q._key() for q in arg_0.edge2queue if q._time < np.infty]
        arg_0._fancy_heap = PriorityQueue(arg_10, arg_0.nE)
        arg_0._Funcd = True


def Func(arg_0):
        """Returns whether the next event is an arrival or a departure
        and the queue the event is accuring at.

        Returns
        -------
        des : str
            Indicates whether the next event is an arrival, a
            departure, or nothing; returns ``'Arrival'``,
            ``'Departure'``, or ``'Nothing'``.
        edge : int or ``None``
            The edge index of the edge that this event will occur at.
            If there are no events then ``None`` is returned.
        """
        if arg_0._fancy_heap.size == 0:
            arg_1 = 'Nothing'
            arg_2 = None
        else:
            arg_3 = [arg_5._key() for arg_5 in arg_0.edge2queue]
            arg_3.sort()
            arg_4 = arg_3[0][1]
            arg_5 = arg_0.edge2queue[arg_4]

            arg_1 = 'Arrival' if arg_5.Func() == 1 else 'Departure'
            arg_2 = arg_5.edge[2]
        return arg_1, arg_2


def Func(arg_0, arg_1):
        """Change the routing transitions probabilities for the
        network.

        Parameters
        ----------
        mat : dict or :class:`~numpy.ndarray`
            A transition routing matrix or transition dictionary. If
            passed a dictionary, the keys are source vertex indices and
            the values are dictionaries with target vertex indicies
            as the keys and the probabilities of routing from the
            source to the target as the values.

        Raises
        ------
        ValueError
            A :exc:`.ValueError` is raised if: the keys in the dict
            don't match with a vertex index in the graph; or if the
            :class:`~numpy.ndarray` is passed with the wrong shape,
            must be (``num_vertices``, ``num_vertices``); or the values
            passed are not probabilities (for each vertex they are
            positive and sum to 1);
        TypeError
            A :exc:`.TypeError` is raised if mat is not a dict or
            :class:`~numpy.ndarray`.

        Examples
        --------
        The default transition matrix is every out edge being equally
        likely:

        >>> import queueing_tool as qt
        >>> adjacency = {
        ...     0: [2],
        ...     1: [2, 3],
        ...     2: [0, 1, 2, 4],
        ...     3: [1],
        ...     4: [2],
        ... }
        >>> g = qt.adjacency2graph(adjacency)
        >>> net = qt.QueueNetwork(g)
        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 1.0},
         1: {2: 0.5, 3: 0.5},
         2: {0: 0.25, 1: 0.25, 2: 0.25, 4: 0.25},
         3: {1: 1.0},
         4: {2: 1.0}}

        If you want to change only one vertex's transition
        probabilities, you can do so with the following:

        >>> net.Func({1 : {2: 0.75, 3: 0.25}})
        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 1.0},
         1: {2: 0.75, 3: 0.25},
         2: {0: 0.25, 1: 0.25, 2: 0.25, 4: 0.25},
         3: {1: 1.0},
         4: {2: 1.0}}

        One can generate a transition matrix using
        :func:`.generate_transition_matrix`. You can change all
        transition probabilities with an :class:`~numpy.ndarray`:

        >>> mat = qt.generate_transition_matrix(g, seed=10)
        >>> net.Func(mat)
        >>> net.transitions(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 1.0},
         1: {2: 0.962..., 3: 0.037...},
         2: {0: 0.301..., 1: 0.353..., 2: 0.235..., 4: 0.108...},
         3: {1: 1.0},
         4: {2: 1.0}}

        See Also
        --------
        :meth:`.transitions` : Return the current routing
            probabilities.
        :func:`.generate_transition_matrix` : Generate a random routing
            matrix.
        """
        if isinstance(arg_1, dict):
            for arg_2, arg_3 in arg_1.items():
                arg_4 = list(arg_3.values())

                if arg_2 not in arg_0.g.node:
                    arg_5 = "One of the keys don't correspond to a vertex."
                    raise ValueError(arg_5)
                elif len(arg_0.out_edges[arg_2]) > 0 and not np.isclose(sum(arg_4), 1):
                    arg_5 = "Sum of transition probabilities at a vertex was not 1."
                    raise ValueError(arg_5)
                elif (np.array(arg_4) < 0).any():
                    arg_5 = "Some transition probabilities were negative."
                    raise ValueError(arg_5)

                for arg_6, arg_7 in enumerate(sorted(arg_0.g.out_edges(arg_2))):
                    arg_0._route_probs[arg_2][arg_6] = arg_3.get(arg_7[1], 0)

        elif isinstance(arg_1, np.ndarray):
            arg_9 = np.array([arg_0.g.out_degree(v) > 0 for v in arg_0.g.nodes()])
            if arg_1.shape != (arg_0.nV, arg_0.nV):
                arg_5 = ("Matrix is the wrong shape, should "
                       "be {0} x {1}.").format(arg_0.nV, arg_0.nV)
                raise ValueError(arg_5)
            elif not np.allclose(np.sum(arg_1[arg_9, :], axis=1), 1):
                arg_5 = "Sum of transition probabilities at a vertex was not 1."
                raise ValueError(arg_5)
            elif (arg_1 < 0).any():
                raise ValueError("Some transition probabilities were negative.")

            for arg_6 in range(arg_0.nV):
                for arg_10, arg_7 in enumerate(sorted(arg_0.g.out_edges(arg_6))):
                    arg_0._route_probs[arg_6][arg_10] = arg_1[arg_6, arg_7[1]]
        else:
            raise TypeError("mat must be a numpy array or a dict.")


def Func(arg_0, arg_1, **arg_2):
        """Draws the network, highlighting queues of a certain type.

        The colored vertices represent self loops of type ``edge_type``.
        Dark edges represent queues of type ``edge_type``.

        Parameters
        ----------
        edge_type : int
            The type of vertices and edges to be shown.
        **kwargs
            Any additional parameters to pass to :meth:`.draw`, and
            :meth:`.QueueNetworkDiGraph.draw_graph`

        Notes
        -----
        The colors are defined by the class attribute ``colors``. The
        relevant colors are ``vertex_active``, ``vertex_inactive``,
        ``vertex_highlight``, ``edge_active``, and ``edge_inactive``.

        Examples
        --------
        The following code highlights all edges with edge type ``2``.
        If the edge is a loop then the vertex is highlighted as well.
        In this case all edges with edge type ``2`` happen to be loops.

        >>> import queueing_tool as qt
        >>> g = qt.generate_pagerank_graph(100, seed=13)
        >>> net = qt.QueueNetwork(g, seed=13)
        >>> fname = 'edge_type_2.png'
        >>> net.Func(2, fname=fname) # doctest: +SKIP

        .. figure:: edge_type_2-1.png
           :align: center
        """
        for arg_3 in arg_0.g.nodes():
            arg_4 = (arg_3, arg_3)
            if arg_0.g.is_edge(arg_4) and arg_0.g.ep(arg_4, 'edge_type') == arg_1:
                arg_5 = arg_0.g.edge_index[arg_4]
                arg_0.g.set_vp(arg_3, 'vertex_fill_color', arg_0.colors['vertex_highlight'])
                arg_0.g.set_vp(arg_3, 'vertex_color', arg_0.edge2queue[arg_5].colors['vertex_color'])
            else:
                arg_0.g.set_vp(arg_3, 'vertex_fill_color', arg_0.colors['vertex_inactive'])
                arg_0.g.set_vp(arg_3, 'vertex_color', [0, 0, 0, 0.9])

        for arg_4 in arg_0.g.edges():
            if arg_0.g.ep(arg_4, 'edge_type') == arg_1:
                arg_0.g.set_ep(arg_4, 'edge_color', arg_0.colors['edge_active'])
            else:
                arg_0.g.set_ep(arg_4, 'edge_color', arg_0.colors['edge_inactive'])

        arg_0.draw(update_colors=False, **arg_2)
        arg_0._update_all_colors()


def Func(arg_0, arg_1=1, arg_2=None):
        """Simulates the network forward.

        Simulates either a specific number of events or for a specified
        amount of simulation time.

        Parameters
        ----------
        n : int (optional, default: 1)
            The number of events to Func. If ``t`` is not given
            then this parameter is used.
        t : float (optional)
            The amount of simulation time to Func forward. If
            given, ``t`` is used instead of ``n``.

        Raises
        ------
        QueueingToolError
            Will raise a :exc:`.QueueingToolError` if the
            ``QueueNetwork`` has not been initialized. Call
            :meth:`.initialize` before calling this method.

        Examples
        --------
        Let ``net`` denote your instance of a ``QueueNetwork``. Before
        you Func, you need to initialize the network, which allows
        arrivals from outside the network. To initialize with 2 (random
        chosen) edges accepting arrivals run:

        >>> import queueing_tool as qt
        >>> g = qt.generate_pagerank_graph(100, seed=50)
        >>> net = qt.QueueNetwork(g, seed=50)
        >>> net.initialize(2)

        To Func the network 50000 events run:

        >>> net.num_events
        0
        >>> net.Func(50000)
        >>> net.num_events
        50000

        To Func the network for at least 75 simulation time units
        run:

        >>> t0 = net.current_time
        >>> net.Func(t=75)
        >>> t1 = net.current_time
        >>> t1 - t0 # doctest: +ELLIPSIS
        75...
        """
        if not arg_0._initialized:
            arg_3 = ("Network has not been initialized. "
                   "Call '.initialize()' first.")
            raise QueueingToolError(arg_3)
        if arg_2 is None:
            for arg_4 in range(arg_1):
                arg_0._Func_next_event(slow=False)
        else:
            arg_5 = arg_0._t
            while arg_0._t < arg_5 + arg_2:
                arg_0._Func_next_event(slow=False)


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None):
        """Tells the queues to collect data on agents' arrival, service
        start, and departure times.

        If none of the parameters are given then every
        :class:`.QueueServer` will start collecting data.

        Parameters
        ----------
        queues : :any:`int`, *array_like* (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` that will start
            collecting data.
        edge : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues will collect data. Must be
            either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types will be set active.
        """
        arg_1 = _get_queues(arg_0.g, arg_1, arg_2, arg_3)

        for arg_4 in arg_1:
            arg_0.edge2queue[arg_4].collect_data = True


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None):
        """Tells the queues to stop collecting data on agents.

        If none of the parameters are given then every
        :class:`.QueueServer` will stop collecting data.

        Parameters
        ----------
        queues : int, *array_like* (optional)
            The edge index (or an iterable of edge indices) identifying
            the :class:`QueueServer(s)<.QueueServer>` that will stop
            collecting data.
        edge : 2-tuple of int or *array_like* (optional)
            Explicitly specify which queues will stop collecting data.
            Must be either:

            * A 2-tuple of the edge's source and target vertex
              indices, or
            * An iterable of 2-tuples of the edge's source and
              target vertex indices.

        edge_type : int or an iterable of int (optional)
            A integer, or a collection of integers identifying which
            edge types will stop collecting data.
        """
        arg_1 = _get_queues(arg_0.g, arg_1, arg_2, arg_3)

        for arg_4 in arg_1:
            arg_0.edge2queue[arg_4].collect_data = False


def Func(arg_0, arg_1=True):
        """Returns the routing probabilities for each vertex in the
        graph.

        Parameters
        ----------
        return_matrix : bool (optional, the default is ``True``)
            Specifies whether an :class:`~numpy.ndarray` is returned.
            If ``False``, a dict is returned instead.

        Returns
        -------
        out : a dict or :class:`~numpy.ndarray`
            The transition probabilities for each vertex in the graph.
            If ``out`` is an :class:`~numpy.ndarray`, then
            ``out[v, u]`` returns the probability of a transition from
            vertex ``v`` to vertex ``u``. If ``out`` is a dict
            then ``out_edge[v][u]`` is the probability of moving from
            vertex ``v`` to the vertex ``u``.

        Examples
        --------
        Lets change the routing probabilities:

        >>> import queueing_tool as qt
        >>> import networkx as nx
        >>> g = nx.sedgewick_maze_graph()
        >>> net = qt.QueueNetwork(g)

        Below is an adjacency list for the graph ``g``.

        >>> ans = qt.graph2dict(g, False)
        >>> {k: sorted(v) for k, v in ans.items()}
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: [2, 5, 7],
         1: [7],
         2: [0, 6],
         3: [4, 5],
         4: [3, 5, 6, 7],
         5: [0, 3, 4],
         6: [2, 4],
         7: [0, 1, 4]}

        The default transition matrix is every out edge being equally
        likely:

        >>> net.Func(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 0.333..., 5: 0.333..., 7: 0.333...},
         1: {7: 1.0},
         2: {0: 0.5, 6: 0.5},
         3: {4: 0.5, 5: 0.5},
         4: {3: 0.25, 5: 0.25, 6: 0.25, 7: 0.25},
         5: {0: 0.333..., 3: 0.333..., 4: 0.333...},
         6: {2: 0.5, 4: 0.5},
         7: {0: 0.333..., 1: 0.333..., 4: 0.333...}}

        Now we will generate a random routing matrix:

        >>> mat = qt.generate_transition_matrix(g, seed=96)
        >>> net.set_Func(mat)
        >>> net.Func(False)  # doctest: +ELLIPSIS
        ...                         # doctest: +NORMALIZE_WHITESPACE
        {0: {2: 0.112..., 5: 0.466..., 7: 0.420...},
         1: {7: 1.0},
         2: {0: 0.561..., 6: 0.438...},
         3: {4: 0.545..., 5: 0.454...},
         4: {3: 0.374..., 5: 0.381..., 6: 0.026..., 7: 0.217...},
         5: {0: 0.265..., 3: 0.460..., 4: 0.274...},
         6: {2: 0.673..., 4: 0.326...},
         7: {0: 0.033..., 1: 0.336..., 4: 0.630...}}

        What this shows is the following: when an :class:`.Agent` is at
        vertex ``2`` they will transition to vertex ``0`` with
        probability ``0.561`` and route to vertex ``6`` probability
        ``0.438``, when at vertex ``6`` they will transition back to
        vertex ``2`` with probability ``0.673`` and route vertex ``4``
        probability ``0.326``, etc.
        """
        if arg_1:
            arg_2 = np.zeros((arg_0.nV, arg_0.nV))
            for arg_3 in arg_0.g.nodes():
                arg_4 = [e[1] for e in sorted(arg_0.g.out_edges(arg_3))]
                arg_2[arg_3, arg_4] = arg_0._route_probs[arg_3]
        else:
            arg_2 = {
                k: {e[1]: p for e, p in zip(sorted(arg_0.g.out_edges(k)), value)}
                for k, value in enumerate(arg_0._route_probs)
            }

        return arg_2


def Func(arg_0, arg_1):
        """Returns the number of elements in the set that ``s`` belongs to.

        Parameters
        ----------
        s : object
            An object

        Returns
        -------
        out : int
            The number of elements in the set that ``s`` belongs to.
        """
        arg_2 = arg_0.find(arg_1)
        return arg_0._Func[arg_2]


def Func(arg_0, arg_1):
        """Locates the leader of the set to which the element ``s`` belongs.

        Parameters
        ----------
        s : object
            An object that the ``UnionFind`` contains.

        Returns
        -------
        object
            The leader of the set that contains ``s``.
        """
        arg_2   = [arg_1]
        arg_3 = arg_0._leader[arg_1]

        while arg_3 != arg_0._leader[arg_3]:
            arg_2.append(arg_3)
            arg_3 = arg_0._leader[arg_3]

        if len(arg_2) > 1:
            for arg_4 in arg_2:
                arg_0._leader[arg_4] = arg_3

        return arg_3


def Func(arg_0, arg_1, arg_2):
        """Merges the set that contains ``a`` with the set that contains ``b``.

        Parameters
        ----------
        a, b : objects
            Two objects whose sets are to be merged.
        """
        arg_3, arg_4 = arg_0.find(arg_1), arg_0.find(arg_2)
        if arg_3 != arg_4:
            arg_5, arg_6  = arg_0._rank[arg_3], arg_0._rank[arg_4]
            if arg_6 > arg_5:
                arg_5, arg_6 = arg_6, arg_5
                arg_3, arg_4 = arg_4, arg_3
            if arg_5 == arg_6:
                arg_0._rank[arg_3] += 1

            arg_0._leader[arg_4] = arg_3
            arg_0._size[arg_3]  += arg_0._size[arg_4]
            arg_0.nClusters  -= 1


def Func(arg_0, arg_1=None):
    """Generates a random transition matrix for the graph ``g``.

    Parameters
    ----------
    g : :any:`networkx.DiGraph`, :class:`numpy.ndarray`, dict, etc.
        Any object that :any:`DiGraph<networkx.DiGraph>` accepts.
    seed : int (optional)
        An integer used to initialize numpy's psuedo-random number
        generator.

    Returns
    -------
    mat : :class:`~numpy.ndarray`
        Returns a transition matrix where ``mat[i, j]`` is the
        probability of transitioning from vertex ``i`` to vertex ``j``.
        If there is no edge connecting vertex ``i`` to vertex ``j``
        then ``mat[i, j] = 0``.
    """
    arg_0 = _test_graph(arg_0)

    if isinstance(arg_1, numbers.Integral):
        arg_8.random.seed(arg_1)

    arg_2 = arg_0.number_of_nodes()
    arg_3 = arg_8.zeros((arg_2, arg_2))

    for arg_4 in arg_0.nodes():
        arg_5 = [e[1] for e in sorted(arg_0.out_edges(arg_4))]
        arg_6 = len(arg_5)
        if arg_6 == 1:
            arg_3[arg_4, arg_5] = 1
        elif arg_6 > 1:
            arg_7 = arg_8.ceil(arg_8.random.rand(arg_6) * 100) / 100.
            if arg_8.isclose(arg_8.sum(arg_7), 0):
                arg_7[arg_8.random.randint(arg_6)] = 1

            arg_3[arg_4, arg_5] = arg_7 / arg_8.sum(arg_7)

    return arg_3


def Func(arg_0=250, **arg_1):
    """Creates a random graph where the vertex types are
    selected using their pagerank.

    Calls :func:`.minimal_random_graph` and then
    :func:`.set_types_rank` where the ``rank`` keyword argument
    is given by :func:`networkx.pagerank`.

    Parameters
    ----------
    num_vertices : int (optional, the default is 250)
        The number of vertices in the graph.
    **kwargs :
        Any parameters to send to :func:`.minimal_random_graph` or
        :func:`.set_types_rank`.

    Returns
    -------
    :class:`.QueueNetworkDiGraph`
        A graph with a ``pos`` vertex property and the ``edge_type``
        edge property.

    Notes
    -----
    This function sets the edge types of a graph to be either 1, 2, or
    3. It sets the vertices to type 2 by selecting the top
    ``pType2 * g.number_of_nodes()`` vertices given by the
    :func:`~networkx.pagerank` of the graph. A loop is added
    to all vertices identified this way (if one does not exist
    already). It then randomly sets vertices close to the type 2
    vertices as type 3, and adds loops to these vertices as well. These
    loops then have edge types that correspond to the vertices type.
    The rest of the edges are set to type 1.
    """
    arg_2 = minimal_random_graph(arg_0, **arg_1)
    arg_3 = np.zeros(arg_0)
    for arg_4, arg_5 in nx.pagerank(arg_2).items():
        arg_3[arg_4] = arg_5
    arg_2 = set_types_rank(arg_2, rank=arg_3, **arg_1)
    return arg_2


def Func(arg_0):
    """ Yield all of the documentation for trait definitions on a class object.
    """
    # FIXME: gracefully handle errors here or in the caller?
    arg_1 = inspect.getsource(arg_0)
    arg_2 = CommentBlocker()
    arg_2.process_file(StringIO(arg_1))
    arg_3 = compiler.parse(arg_1)
    arg_4 = arg_3.node.nodes[0]
    for arg_5 in arg_4.code.nodes:
        # FIXME: handle other kinds of assignments?
        if isinstance(arg_5, compiler.ast.Assign):
            arg_6 = arg_5.nodes[0].name
            arg_7 = unparse(arg_5.expr).strip()
            arg_8 = strip_comment_marker(arg_2.search_for_comment(arg_5.lineno, default=''))
            yield arg_6, arg_7, arg_8


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
        """ Add lines to the block.
        """
        if arg_1.strip():
            # Only Func if not entirely whitespace.
            arg_0.start_lineno = min(arg_0.start_lineno, arg_2[0])
            arg_0.end_lineno = max(arg_0.end_lineno, arg_3[0])


def Func(arg_0, arg_1, arg_2):
        """ We are transitioning from a noncomment to a comment.
        """
        arg_3 = NonComment(arg_1, arg_2)
        arg_0.blocks.append(arg_3)
        arg_0.current_block = arg_3


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
        """ Possibly add a new comment.

        Only adds a new comment if this comment is the only thing on the line.
        Otherwise, it extends the noncomment block.
        """
        arg_5 = arg_4[:arg_2[1]]
        if arg_5.strip():
            # Oops! Trailing comment, not a comment block.
            arg_0.current_block.add(arg_1, arg_2, arg_3, arg_4)
        else:
            # A comment block.
            arg_6 = Comment(arg_2[0], arg_3[0], arg_1)
            arg_0.blocks.append(arg_6)
            arg_0.current_block = arg_6


def Func(arg_0):
        """ Make the index mapping lines of actual code to their associated
        prefix comments.
        """
        for arg_1, arg_2 in zip(arg_0.blocks[:-1], arg_0.blocks[1:]):
            if not arg_2.is_comment:
                arg_0.index[arg_2.start_lineno] = arg_1


def Func(arg_0):
        """
        Read complete DSMR telegram's from the serial interface and parse it
        into CosemObject's and MbusObject's

        :rtype: generator
        """
        with serial.Serial(**arg_0.serial_settings) as serial_handle:
            while True:
                arg_1 = serial_handle.Funcline()
                arg_0.telegram_buffer.append(arg_1.decode('ascii'))

                for arg_2 in arg_0.telegram_buffer.get_all():
                    try:
                        yield arg_0.telegram_parser.parse(arg_2)
                    except InvalidChecksumError as e:
                        logger.warning(str(e))
                    except ParseError as e:
                        logger.error('Failed to parse telegram: %s', e)


def Func(arg_0, arg_1, arg_2=None):
    """Creates a DSMR asyncio protocol."""

    if arg_0 == '2.2':
        arg_3 = telegram_specifications.V2_2
        arg_4 = SERIAL_SETTINGS_V2_2
    elif arg_0 == '4':
        arg_3 = telegram_specifications.V4
        arg_4 = SERIAL_SETTINGS_V4
    elif arg_0 == '5':
        arg_3 = telegram_specifications.V5
        arg_4 = SERIAL_SETTINGS_V5
    else:
        raise NotImplementedError("No telegram parser found for version: %s",
                                  arg_0)

    arg_5 = partial(DSMRProtocol, arg_2, TelegramParser(arg_3),
                       arg_1=arg_1)

    return arg_5, arg_4


def Func(arg_0, arg_1, arg_2, arg_3=None):
    """Creates a DSMR asyncio protocol coroutine using serial port."""
    arg_4, arg_5 = create_dsmr_protocol(
        arg_1, arg_2, arg_3=None)
    arg_5['url'] = arg_0

    arg_6 = create_serial_connection(arg_3, arg_4, **arg_5)
    return arg_6


def Func(arg_0, arg_1):
        """Add incoming data to buffer."""
        arg_1 = arg_1.decode('ascii')
        arg_0.log.debug('received data: %s', arg_1)
        arg_0.telegram_buffer.append(arg_1)

        for arg_2 in arg_0.telegram_buffer.get_all():
            arg_0.handle_telegram(arg_2)


def Func(arg_0, arg_1):
        """Send off parsed telegram to handling callback."""
        arg_0.log.debug('got telegram: %s', arg_1)

        try:
            arg_2 = arg_0.telegram_parser.parse(arg_1)
        except InvalidChecksumError as e:
            arg_0.log.warning(str(e))
        except ParseError:
            arg_0.log.exception("failed to parse telegram")
        else:
            arg_0.telegram_callback(arg_2)


def Func(arg_0, arg_1):
        """
        Parse telegram from string to dict.

        The telegram str type makes python 2.x integration easier.

        :param str telegram_data: full telegram from start ('/') to checksum
            ('!ABCD') including line endings in between the telegram's lines
        :rtype: dict
        :returns: Shortened example:
            {
                ..
                r'\d-\d:96\.1\.1.+?\r\n': <CosemObject>,  # EQUIPMENT_IDENTIFIER
                r'\d-\d:1\.8\.1.+?\r\n': <CosemObject>,   # ELECTRICITY_USED_TARIFF_1
                r'\d-\d:24\.3\.0.+?\r\n.+?\r\n': <MBusObject>,  # GAS_METER_READING
                ..
            }
        :raises ParseError:
        :raises InvalidChecksumError:
        """

        if arg_0.apply_checksum_validation \
                and arg_0.telegram_specification['checksum_support']:
            arg_0.validate_checksum(arg_1)

        arg_2 = {}

        for arg_3, arg_4 in arg_0.telegram_specification['objects'].items():
            arg_5 = re.search(arg_3, arg_1, re.DOTALL)

            # Some signatures are optional and may not be present,
            # so only Func lines that match
            if arg_5:
                arg_2[arg_3] = arg_4.Func(arg_5.group(0))

        return arg_2


def Func(arg_0, arg_1):
        """
        Loads config from string or dict
        """
        if isinstance(arg_1, six.string_types):
            try:
                arg_1 = json.loads(arg_1)
            except ValueError:
                pass
        if not isinstance(arg_1, dict):
            raise TypeError('config block must be an istance '
                            'of dict or a valid NetJSON string')
        return arg_1


def Func(arg_0, arg_1=True):
        """
        Converts the configuration dictionary into the corresponding configuration format

        :param files: whether to include "additional files" in the output or not;
                      defaults to ``True``
        :returns: string with output
        """
        arg_0.validate()
        # convert NetJSON config to intermediate data structure
        if arg_0.intermediate_data is None:
            arg_0.to_intermediate()
        # support multiple Funcers
        arg_2 = getattr(arg_0, 'Funcers', None) or [arg_0.Funcer]
        # convert intermediate data structure to native configuration
        arg_3 = ''
        for arg_4 in arg_2:
            arg_5 = arg_4(arg_0)
            arg_3 += arg_5.Func()
            # remove reference to Funcer instance (not needed anymore)
            del arg_5
        # are we required to include
        # additional files?
        if arg_1:
            # Func additional files
            arg_6 = arg_0._Func_files()
            if arg_6:
                # max 2 new lines
                arg_3 += arg_6.replace('\n\n\n', '\n\n')
        # return the configuration
        return arg_3


def Func(arg_0):
        """
        Returns a ``BytesIO`` instance representing an in-memory tar.gz archive
        containing the native router configuration.

        :returns: in-memory tar.gz archive, instance of ``BytesIO``
        """
        arg_1 = BytesIO()
        arg_2 = tarfile.open(fileobj=arg_1, mode='w')
        arg_0._Func_contents(arg_2)
        arg_0._process_files(arg_2)
        arg_2.close()
        arg_1.seek(0)  # set pointer to beginning of stream
        # `mtime` parameter of gzip file must be 0, otherwise any checksum operation
        # would return a different digest even when content is the same.
        # to achieve this we must use the python `gzip` library because the `tarfile`
        # library does not seem to offer the possibility to modify the gzip `mtime`.
        arg_3 = BytesIO()
        arg_4 = gzip.GzipFile(fileobj=arg_3, mode='wb', mtime=0)
        arg_4.write(arg_1.getvalue())
        arg_4.close()
        arg_3.seek(0)  # set pointer to beginning of stream
        return arg_3


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=arg_5):
        """
        Adds a single file in tarfile instance.

        :param tar: tarfile instance
        :param name: string representing filename or path
        :param contents: string representing file contents
        :param mode: string representing file mode, defaults to 644
        :returns: None
        """
        arg_6 = BytesIO(arg_3.encode('utf8'))
        arg_7 = tarfile.TarInfo(arg_2=arg_2)
        arg_7.size = len(arg_3)
        # mtime must be 0 or any checksum operation
        # will return a different digest even when content is the same
        arg_7.mtime = 0
        arg_7.type = tarfile.REGTYPE
        arg_7.mode = int(arg_4, 8)  # permissions converted to decimal notation
        arg_1.addfile(tarinfo=arg_7, fileobj=arg_6)


def Func(arg_0, arg_1):
        """
        Parses a native configuration and converts
        it to a NetJSON configuration dictionary
        """
        if not hasattr(arg_0, 'Funcr') or not arg_0.Funcr:
            raise NotImplementedError('Parser class not specified')
        arg_2 = arg_0.Funcr(arg_1)
        arg_0.intermediate_data = arg_2.intermediate_data
        del arg_2
        arg_0.to_netjson()


def Func(arg_0, arg_1, arg_2=None):
    """
    Merges ``list2`` on top of ``list1``.

    If both lists contain dictionaries which have keys specified
    in ``identifiers`` which have equal values, those dicts will
    be merged (dicts in ``list2`` will override dicts in ``list1``).
    The remaining elements will be summed in order to create a list
    which contains elements of both lists.

    :param list1: ``list`` from template
    :param list2: ``list`` from config
    :param identifiers: ``list`` or ``None``
    :returns: merged ``list``
    """
    arg_2 = arg_2 or []
    arg_3 = {'list1': OrderedDict(), 'list2': OrderedDict()}
    arg_4 = 1
    for arg_5 in [arg_0, arg_1]:
        arg_6 = arg_3['list{0}'.format(arg_4)]
        for arg_7 in arg_5:
            # merge by internal python id by default
            arg_8 = id(arg_7)
            # if el is a dict, merge by keys specified in ``identifiers``
            if isinstance(arg_7, dict):
                for arg_9 in arg_2:
                    if arg_9 in arg_7:
                        arg_8 = arg_7[arg_9]
                        break
            arg_6[arg_8] = deepcopy(arg_7)
        arg_4 += 1
    arg_10 = merge_config(arg_3['list1'], arg_3['list2'])
    return list(arg_10.values())


def Func(arg_0, arg_1=None):
    """
    Evaluates variables in ``data``

    :param data: data structure containing variables, may be
                 ``str``, ``dict`` or ``list``
    :param context: ``dict`` containing variables
    :returns: modified data structure
    """
    arg_1 = arg_1 or {}
    if isinstance(arg_0, (dict, list)):
        if isinstance(arg_0, dict):
            arg_2 = arg_0.items()
        elif isinstance(arg_0, list):
            arg_2 = enumerate(arg_0)
        for arg_3, arg_4 in arg_2:
            arg_0[arg_3] = Func(arg_4, arg_1)
    elif isinstance(arg_0, six.string_types):
        arg_5 = var_pattern.findall(arg_0)
        for arg_6 in arg_5:
            arg_6 = arg_6.strip()
            # if found multiple variables, create a new regexp pattern for each
            # variable, otherwise different variables would get the same value
            # (see https://github.com/openwisp/netjsonconfig/issues/55)
            if len(arg_5) > 1:
                arg_7 = r'\{\{(\s*%s\s*)\}\}' % arg_6
            # in case of single variables, use the precompiled
            # regexp pattern to save computation
            else:
                arg_7 = var_pattern
            if arg_6 in arg_1:
                arg_0 = re.sub(arg_7, arg_1[arg_6], arg_0)
    return arg_0


def Func(arg_0, arg_1, arg_2=None):
        """
        Looks for a key in a dictionary, if found returns
        a deepcopied value, otherwise returns default value
        """
        arg_3 = arg_0.get(arg_1, arg_2)
        if arg_3:
            return deepcopy(arg_3)
        return arg_3


def Func(arg_0, arg_1, arg_2=None):
        """
        Loops over item and performs type casting
        according to supplied schema fragment
        """
        if arg_2 is None:
            arg_2 = arg_0._schema
        arg_3 = arg_2['properties']
        for arg_4, arg_5 in arg_1.items():
            if arg_4 not in arg_3:
                continue
            try:
                arg_6 = arg_3[arg_4]['type']
            except KeyError:
                arg_6 = None
            if arg_6 == 'integer' and not isinstance(arg_5, int):
                arg_5 = int(arg_5)
            elif arg_6 == 'boolean' and not isinstance(arg_5, bool):
                arg_5 = arg_5 == '1'
            arg_1[arg_4] = arg_5
        return arg_1


def Func(arg_0, arg_1):
        """
        generates install.sh and adds it to included files
        """
        arg_2 = arg_0._render_template('install.sh', arg_1)
        arg_0.config.setdefault('files', [])  # file list might be empty
        # add install.sh to list of included files
        arg_0._add_unique_file({
            "path": "/install.sh",
            "contents": arg_2,
            "mode": "755"
        })


def Func(arg_0):
        """
        generates tc_script.sh and adds it to included files
        """
        # fill context
        arg_1 = dict(tc_options=arg_0.config.get('tc_options', []))
        # import pdb; pdb.set_trace()
        arg_2 = arg_0._render_template('tc_script.sh', arg_1)
        arg_0.config.setdefault('files', [])  # file list might be empty
        # add tc_script.sh to list of included files
        arg_0._add_unique_file({
            "path": "/tc_script.sh",
            "contents": arg_2,
            "mode": "755"
        })


def Func(arg_0):
        """
        Renders configuration by using the jinja2 templating engine
        """
        # get jinja2 template
        arg_1 = '{0}.jinja2'.format(arg_0.get_name())
        arg_2 = arg_0.template_env.get_template(arg_1)
        # Func template and cleanup
        arg_3 = getattr(arg_0.backend, 'intermediate_data', {})
        arg_4 = arg_2.Func(data=arg_3)
        return arg_0.cleanup(arg_4)


def Func(arg_0, arg_1):
        """
        converts NetJSON address to
        UCI intermediate data structure
        """
        arg_2 = arg_0.get_copy(arg_1, 'addresses')
        # do not ignore interfaces if they do not contain any address
        if not arg_2:
            return [{'proto': 'none'}]
        arg_3 = []
        arg_4 = {}
        arg_5 = []
        for arg_6 in arg_2:
            arg_7 = arg_6.get('family')
            # dhcp
            if arg_6['proto'] == 'dhcp':
                arg_6['proto'] = 'dhcp' if arg_7 == 'ipv4' else 'dhcpv6'
                arg_5.append(arg_0.__intermediate_address(arg_6))
                continue
            if 'gateway' in arg_6:
                arg_8 = 'gateway' if arg_7 == 'ipv4' else 'ip6gw'
                arg_1[arg_8] = arg_6['gateway']
            # static
            arg_9 = 'ipaddr' if arg_7 == 'ipv4' else 'ip6addr'
            arg_4.setdefault(arg_9, [])
            arg_4[arg_9].append('{address}/{mask}'.format(**arg_6))
            arg_4.update(arg_0.__intermediate_address(arg_6))
        if arg_4:
            # do not use CIDR notation when using a single ipv4
            # see https://github.com/openwisp/netjsonconfig/issues/54
            if len(arg_4.get('ipaddr', [])) == 1:
                arg_10 = ip_interface(six.text_type(arg_4['ipaddr'][0]))
                arg_4['ipaddr'] = str(arg_10.ip)
                arg_4['netmask'] = str(arg_10.netmask)
            # do not use lists when using a single ipv6 address
            # (avoids to change output of existing configuration)
            if len(arg_4.get('ip6addr', [])) == 1:
                arg_4['ip6addr'] = arg_4['ip6addr'][0]
            arg_3.append(arg_4)
        if arg_5:
            arg_3 += arg_5
        return arg_3


def Func(arg_0, arg_1, arg_2):
        """
        converts NetJSON interface to
        UCI intermediate data structure
        """
        arg_1.update({
            '.type': 'interface',
            '.name': arg_2,
            'ifname': arg_1.pop('name')
        })
        if 'network' in arg_1:
            del arg_1['network']
        if 'mac' in arg_1:
            # mac address of wireless interface must
            # be set in /etc/config/wireless, therfore
            # we can skip this in /etc/config/network
            if arg_1.get('type') != 'wireless':
                arg_1['macaddr'] = arg_1['mac']
            del arg_1['mac']
        if 'autostart' in arg_1:
            arg_1['auto'] = arg_1['autostart']
            del arg_1['autostart']
        if 'disabled' in arg_1:
            arg_1['enabled'] = not arg_1['disabled']
            del arg_1['disabled']
        if 'wireless' in arg_1:
            del arg_1['wireless']
        if 'addresses' in arg_1:
            del arg_1['addresses']
        return arg_1


def Func(arg_0, arg_1):
        """
        deletes NetJSON address keys
        """
        for arg_2 in arg_0._address_keys:
            if arg_2 in arg_1:
                del arg_1[arg_2]
        return arg_1


def Func(arg_0, arg_1, arg_2):
        """
        converts NetJSON bridge to
        UCI intermediate data structure
        """
        # ensure type "bridge" is only given to one logical interface
        if arg_1['type'] == 'bridge' and arg_2 < 2:
            arg_3 = ' '.join(arg_1.pop('bridge_members'))
            # put bridge members in ifname attribute
            if arg_3:
                arg_1['ifname'] = arg_3
            # if no members, this is an empty bridge
            else:
                arg_1['bridge_empty'] = True
                del arg_1['ifname']
        # bridge has already been defined
        # but we need to add more references to it
        elif arg_1['type'] == 'bridge' and arg_2 >= 2:
            # openwrt adds "br-" prefix to bridge interfaces
            # we need to take this into account when referring
            # to these physical names
            if 'br-' not in arg_1['ifname']:
                arg_1['ifname'] = 'br-{ifname}'.format(**arg_1)
            # do not repeat bridge attributes (they have already been processed)
            for arg_4 in ['type', 'bridge_members', 'stp', 'gateway']:
                if arg_4 in arg_1:
                    del arg_1[arg_4]
        elif arg_1['type'] != 'bridge':
            del arg_1['type']
        return arg_1


def Func(arg_0, arg_1, arg_2):
        """
        determines UCI interface "proto" option
        """
        # proto defaults to static
        arg_3 = arg_2.pop('proto', 'static')
        if 'proto' not in arg_1:
            return arg_3
        else:
            # allow override on interface level
            return arg_1.pop('proto')


def Func(arg_0, arg_1, arg_2):
        """
        determines UCI interface "dns" option
        """
        # allow override
        if 'dns' in arg_1:
            return arg_1['dns']
        # ignore if using DHCP or if "proto" is none
        if arg_2['proto'] in ['dhcp', 'dhcpv6', 'none']:
            return None
        arg_3 = arg_0.netjson.get('dns_servers', None)
        if arg_3:
            return ' '.join(arg_3)


def Func(arg_0, arg_1):
        """
        only for mac80211 driver
        """
        arg_2 = arg_1.pop('protocol')
        arg_3 = arg_1.pop('channel_width')
        # allow overriding htmode
        if 'htmode' in arg_1:
            return arg_1['htmode']
        if arg_2 == '802.11n':
            return 'HT{0}'.format(arg_3)
        elif arg_2 == '802.11ac':
            return 'VHT{0}'.format(arg_3)
        # disables n
        return 'NONE'


def Func(arg_0, arg_1):
        """
        determines NetJSON protocol radio attribute
        """
        arg_2 = arg_1.get('htmode')
        arg_3 = arg_1.get('hwmode', None)
        if arg_2.startswith('HT'):
            return '802.11n'
        elif arg_2.startswith('VHT'):
            return '802.11ac'
        return '802.{0}'.format(arg_3)


def Func(arg_0, arg_1, arg_2, arg_3=None, arg_4=None,
                    arg_5=None, arg_6=None, arg_7=None,
                    arg_8=None):
        """
        Returns a configuration dictionary representing an OpenVPN client configuration
        that is compatible with the passed server configuration.

        :param host: remote VPN server
        :param server: dictionary representing a single OpenVPN server configuration
        :param ca_path: optional string representing path to CA, will consequently add
                        a file in the resulting configuration dictionary
        :param ca_contents: optional string representing contents of CA file
        :param cert_path: optional string representing path to certificate, will consequently add
                        a file in the resulting configuration dictionary
        :param cert_contents: optional string representing contents of cert file
        :param key_path: optional string representing path to key, will consequently add
                        a file in the resulting configuration dictionary
        :param key_contents: optional string representing contents of key file
        :returns: dictionary representing a single OpenVPN client configuration
        """
        # client defaults
        arg_9 = {
            "mode": "p2p",
            "nobind": True,
            "resolv_retry": "infinite",
            "tls_client": True
        }
        # remote
        arg_10 = arg_2.get('port') or 1195
        arg_9['remote'] = [{'host': arg_1, 'port': arg_10}]
        # proto
        if arg_2.get('proto') == 'tcp-server':
            arg_9['proto'] = 'tcp-client'
        else:
            arg_9['proto'] = 'udp'
        # determine if pull must be True
        if 'server' in arg_2 or 'server_bridge' in arg_2:
            arg_9['pull'] = True
        # tls_client
        if 'tls_server' not in arg_2 or not arg_2['tls_server']:
            arg_9['tls_client'] = False
        # ns_cert_type
        arg_11 = {None: '',
                        '': '',
                        'client': 'server'}
        arg_9['ns_cert_type'] = arg_11[arg_2.get('ns_cert_type')]
        # remote_cert_tls
        arg_12 = {None: '',
                           '': '',
                           'client': 'server'}
        arg_9['remote_cert_tls'] = arg_12[arg_2.get('remote_cert_tls')]
        arg_13 = ['name', 'dev_type', 'dev', 'comp_lzo', 'auth',
                     'cipher', 'ca', 'cert', 'key', 'pkcs12', 'mtu_disc', 'mtu_test',
                     'fragment', 'mssfix', 'keepalive', 'persist_tun', 'mute',
                     'persist_key', 'script_security', 'user', 'group', 'log',
                     'mute_replay_warnings', 'secret', 'reneg_sec', 'tls_timeout',
                     'tls_cipher', 'float', 'fast_io', 'verb']
        for arg_14 in arg_13:
            if arg_14 in arg_2:
                arg_9[arg_14] = arg_2[arg_14]
        arg_15 = arg_0._Func_files(arg_9, arg_3, arg_4,
                                       arg_5, arg_6,
                                       arg_7, arg_8)
        return {
            'openvpn': [arg_9],
            'files': arg_15
        }


def Func(arg_0, arg_1, arg_2=None, arg_3=None, arg_4=None,
                           arg_5=None, arg_6=None, arg_7=None):
        """
        returns a list of NetJSON extra files for automatically generated clients
        produces side effects in ``client`` dictionary
        """
        arg_8 = []
        if arg_2 and arg_3:
            arg_1['ca'] = arg_2
            arg_8.append(dict(path=arg_2,
                              contents=arg_3,
                              mode=DEFAULT_FILE_MODE))
        if arg_4 and arg_5:
            arg_1['cert'] = arg_4
            arg_8.append(dict(path=arg_4,
                              contents=arg_5,
                              mode=DEFAULT_FILE_MODE))
        if arg_6 and arg_7:
            arg_1['key'] = arg_6
            arg_8.append(dict(path=arg_6,
                              contents=arg_7,
                              mode=DEFAULT_FILE_MODE,))
        return arg_8


def Func():
    """
    parse requirements.txt, ignore links, exclude comments
    """
    arg_0 = []
    for arg_1 in open('requirements.txt').readlines():
        # skip to next iteration if comment or empty line
        if arg_1.startswith('#') or arg_1 == '' or arg_1.startswith('http') or arg_1.startswith('git'):
            continue
        # add line to requirements
        arg_0.append(arg_1.replace('\n', ''))
    # add py2-ipaddress if python2
    if sys.version_info.major < 3:
        arg_0.append('py2-ipaddress')
    return arg_0


def Func(arg_0, **arg_1):
        """Get all Func of this node. Additional arguments may also be
        specified that will be passed to the query function.
        """
        return arg_0.__api.Func(query=EqualsOperator("certname", arg_0.name),
                                **arg_1)


def Func(arg_0, arg_1):
        """Get a single fact from this node."""
        arg_2 = arg_0.facts(arg_1=arg_1)
        return next(Func for Func in arg_2)


def Func(arg_0, arg_1=None, arg_2=None, **arg_3):
        """Get all resources of this node or all resources of the specified
        type. Additional arguments may also be specified that will be passed
        to the query function.
        """
        if arg_1 is None:
            Func = arg_0.__api.resources(
                query=EqualsOperator("certname", arg_0.name),
                **arg_3)
        elif arg_1 is not None and arg_2 is None:
            Func = arg_0.__api.resources(
                arg_1=arg_1,
                query=EqualsOperator("certname", arg_0.name),
                **arg_3)
        else:
            Func = arg_0.__api.resources(
                arg_1=arg_1,
                arg_2=arg_2,
                query=EqualsOperator("certname", arg_0.name),
                **arg_3)
        return Func


def Func(arg_0, **arg_1):
        """Get all Func for this node. Additional arguments may also be
        specified that will be passed to the query function.
        """
        return arg_0.__api.Func(
            query=EqualsOperator("certname", arg_0.name),
            **arg_1)


def Func(arg_0):
        """A Func that will be used to construct the final
        URL we're going to query against.

        :returns: A URL of the form: ``proto://host:port``.
        :rtype: :obj:`string`
        """
        return '{proto}://{host}:{port}{url_path}'.format(
            proto=arg_0.protocol,
            host=arg_0.host,
            port=arg_0.port,
            url_path=arg_0.url_path,
        )


def Func(arg_0, arg_1, arg_2=None):
        """The complete URL we will end up querying. Depending on the
        endpoint we pass in  this will result in different URL's with
        different prefixes.

        :param endpoint: The PuppetDB API endpoint we want to query.
        :type endpoint: :obj:`string`
        :param path: An additional path if we don't wish to query the\
                bare endpoint.
        :type path: :obj:`string`

        :returns: A URL constructed from :func:`baseFunc` with the\
                apropraite API version/prefix and the rest of the path added\
                to it.
        :rtype: :obj:`string`
        """

        log.debug('Func called with endpoint: {0} and path: {1}'.format(
            arg_1, arg_2))

        try:
            arg_1 = ENDPOINTS[arg_1]
        except KeyError:
            # If we reach this we're trying to query an endpoint that doesn't
            # exist. This shouldn't happen unless someone made a booboo.
            raise APIError

        arg_3 = '{baseFunc}/{endpoint}'.format(
            baseFunc=arg_0.baseFunc,
            arg_1=arg_1,
        )

        if arg_2 is not None:
            arg_3 = '{0}/{1}'.format(arg_3, quote(arg_2))

        return arg_3


def Func(arg_0, arg_1=2, arg_2=False, **arg_3):
        """Query for nodes by either name or query. If both aren't
        provided this will return a list of all nodes. This method
        also fetches the nodes status and event counts of the latest
        report from puppetdb.

        :param with_status: (optional) include the node status in the\
                           returned nodes
        :type with_status: :bool:
        :param unreported: (optional) amount of hours when a node gets
                           marked as unreported
        :type unreported: :obj:`None` or integer
        :param \*\*kwargs: The rest of the keyword arguments are passed
                           to the _query function

        :returns: A generator yieling Nodes.
        :rtype: :class:`pypuppetdb.types.Node`
        """
        Func = arg_0._query('nodes', **arg_3)
        arg_5 = datetime.datetime.utcnow()
        # If we happen to only get one node back it
        # won't be inside a list so iterating over it
        # goes boom. Therefor we wrap a list around it.
        if type(Func) == dict:
            Func = [Func, ]

        if arg_2:
            arg_6 = arg_0.event_counts(
                query=EqualsOperator("latest_report?", True),
                summarize_by='certname'
            )

        for arg_7 in Func:
            arg_7['status_report'] = None
            arg_7['events'] = None

            if arg_2:
                arg_8 = [s for s in arg_6
                          if s['subject']['title'] == arg_7['certname']]

                try:
                    arg_7['status_report'] = arg_7['latest_report_status']

                    if arg_8:
                        arg_7['events'] = arg_8[0]
                except KeyError:
                    if arg_8:
                        arg_7['events'] = arg_8 = arg_8[0]
                        if arg_8['successes'] > 0:
                            arg_7['status_report'] = 'changed'
                        if arg_8['noops'] > 0:
                            arg_7['status_report'] = 'noop'
                        if arg_8['failures'] > 0:
                            arg_7['status_report'] = 'failed'
                    else:
                        arg_7['status_report'] = 'unchanged'

                # node report age
                if arg_7['report_timestamp'] is not None:
                    try:
                        arg_9 = json_to_datetime(
                            arg_7['report_timestamp'])
                        arg_9 = arg_9.replace(tzinfo=None)
                        arg_10 = arg_5 - timedelta(hours=arg_1)
                        if arg_9 < arg_10:
                            arg_11 = (arg_5 - arg_9)
                            arg_7['unreported'] = True
                            arg_7['unreported_time'] = '{0}d {1}h {2}m'.format(
                                arg_11.days,
                                int(arg_11.seconds / 3600),
                                int((arg_11.seconds % 3600) / 60)
                            )
                    except AttributeError:
                        arg_7['unreported'] = True

                if not arg_7['report_timestamp']:
                    arg_7['unreported'] = True

            yield Node(arg_0,
                       name=arg_7['certname'],
                       deactivated=arg_7['deactivated'],
                       expired=arg_7['expired'],
                       report_timestamp=arg_7['report_timestamp'],
                       catalog_timestamp=arg_7['catalog_timestamp'],
                       facts_timestamp=arg_7['facts_timestamp'],
                       status_report=arg_7['status_report'],
                       noop=arg_7.get('latest_report_noop'),
                       noop_pending=arg_7.get('latest_report_noop_pending'),
                       events=arg_7['events'],
                       arg_1=arg_7.get('unreported'),
                       unreported_time=arg_7.get('unreported_time'),
                       report_environment=arg_7['report_environment'],
                       catalog_environment=arg_7['catalog_environment'],
                       facts_environment=arg_7['facts_environment'],
                       latest_report_hash=arg_7.get('latest_report_hash'),
                       cached_catalog_status=arg_7.get('cached_catalog_status')
                       )


def Func(arg_0, arg_1):
        """Gets a single node from PuppetDB.

        :param name: The name of the node search.
        :type name: :obj:`string`

        :return: An instance of Node
        :rtype: :class:`pypuppetdb.types.Node`
        """
        arg_2 = arg_0.nodes(path=arg_1)
        return next(Func for Func in arg_2)


def Func(arg_0, arg_1):
        """Get the available Func for a given node.

        :param node: (Required) The name of the PuppetDB node.
        :type: :obj:`string`

        :returns: An instance of Catalog
        :rtype: :class:`pypuppetdb.types.Catalog`
        """
        arg_2 = arg_0.Funcs(path=arg_1)
        return next(arg_3 for arg_3 in arg_2)


def Func(arg_0='localhost', arg_1=8080, arg_2=False, arg_3=None,
            arg_4=None, arg_5=10, arg_6=None, arg_7='/',
            arg_8=None, arg_9=None, arg_10=None):
    """Connect with PuppetDB. This will return an object allowing you
    to query the API through its methods.

    :param host: (Default: 'localhost;) Hostname or IP of PuppetDB.
    :type host: :obj:`string`

    :param port: (Default: '8080') Port on which to talk to PuppetDB.
    :type port: :obj:`int`

    :param ssl_verify: (optional) Verify PuppetDB server certificate.
    :type ssl_verify: :obj:`bool` or :obj:`string` True, False or filesystem \
            path to CA certificate.

    :param ssl_key: (optional) Path to our client secret key.
    :type ssl_key: :obj:`None` or :obj:`string` representing a filesystem\
            path.

    :param ssl_cert: (optional) Path to our client certificate.
    :type ssl_cert: :obj:`None` or :obj:`string` representing a filesystem\
            path.

    :param timeout: (Default: 10) Number of seconds to wait for a response.
    :type timeout: :obj:`int`

    :param protocol: (optional) Explicitly specify the protocol to be used
            (especially handy when using HTTPS with ssl_verify=False and
            without certs)
    :type protocol: :obj:`None` or :obj:`string`

    :param url_path: (Default: '/') The URL path where PuppetDB is served
    :type url_path: :obj:`None` or :obj:`string`

    :param username: (optional) The username to use for HTTP basic
            authentication
    :type username: :obj:`None` or :obj:`string`

    :param password: (optional) The password to use for HTTP basic
            authentication
    :type password: :obj:`None` or :obj:`string`

    :param token: (optional) The x-auth token to use for X-Authentication
    :type token: :obj:`None` or :obj:`string`
    """
    return BaseAPI(arg_0=arg_0, arg_1=arg_1,
                   arg_5=arg_5, arg_2=arg_2, arg_3=arg_3,
                   arg_4=arg_4, arg_6=arg_6, arg_7=arg_7,
                   arg_8=arg_8, arg_9=arg_9, arg_10=arg_10)


def Func():
    """The Master has been started from the command line. Execute ad-hoc tests if desired."""
    # app = MyMaster()
    arg_0 = MyMaster(log_handler=MyLogger(),
                   listener=AppChannelListener(),
                   soe_handler=SOEHandler(),
                   master_application=MasterApplication())
    _log.debug('Initialization complete. In command loop.')
    # Ad-hoc tests can be performed at this point. See master_cmd.py for examples.
    arg_0.shutdown()
    _log.debug('Exiting.')
    exit()


def Func(arg_0, arg_1, arg_2=arg_3.PrintingCommandCallback.Get(),
                                        arg_6=arg_7.TaskConfig().Default()):
        """
            Direct operate a set of commands

        :param command_set: set of command headers
        :param callback: callback that will be invoked upon completion or failure
        :param config: optional configuration that controls normal callbacks and allows the user to be specified for SA
        """
        arg_0.master.DirectOperate(arg_1, arg_2, arg_6)


def Func(arg_0, arg_1, arg_2, arg_3=arg_4.PrintingCommandCallback.Get(),
                                        arg_7=arg_8.TaskConfig().Default()):
        """
            Select and operate a single command

        :param command: command to operate
        :param index: index of the command
        :param callback: callback that will be invoked upon completion or failure
        :param config: optional configuration that controls normal callbacks and allows the user to be specified for SA
        """
        arg_0.master.SelectAndOperate(arg_1, arg_2, arg_3, arg_7)


def Func(arg_0, arg_1, arg_2=arg_3.PrintingCommandCallback.Get(),
                                            arg_6=arg_7.TaskConfig().Default()):
        """
            Select and operate a set of commands

        :param command_set: set of command headers
        :param callback: callback that will be invoked upon completion or failure
        :param config: optional configuration that controls normal callbacks and allows the user to be specified for SA
        """
        arg_0.master.SelectAndOperate(arg_1, arg_2, arg_6)


def Func():
    """The Outstation has been started from the command line. Execute ad-hoc tests if desired."""
    arg_0 = OutstationApplication()
    _log.debug('Initialization complete. In command loop.')
    # Ad-hoc tests can be inserted here if desired. See outstation_cmd.py for examples.
    arg_0.shutdown()
    _log.debug('Exiting.')
    exit()


def Func(arg_0, arg_1, arg_2, arg_3):
        """
            The Master sent an Func command to the Outstation. Handle it.

        :param command: ControlRelayOutputBlock,
                        AnalogOutputInt16, AnalogOutputInt32, AnalogOutputFloat32, or AnalogOutputDouble64.
        :param index: int
        :param op_type: FuncType
        :return: CommandStatus
        """
        OutstationApplication.process_point_value('Func', arg_1, arg_2, arg_3)
        return opendnp3.CommandStatus.SUCCESS


def Func(arg_0=arg_1, arg_2=arg_3, arg_4=False):
    """
    Create Bloomberg connection

    Returns:
        (Bloomberg connection, if connection is new)
    """
    if arg_7 in arg_6():
        if not isinstance(arg_6()[arg_7], pdblp.BCon):
            del arg_6()[arg_7]

    if (arg_7 in arg_6()) and (not arg_4):
        arg_5 = arg_6()[arg_7]
        if getattr(arg_5, '_session').start(): arg_5.start()
        return arg_5, False

    else:
        arg_5 = pdblp.BCon(arg_0=arg_0, arg_2=arg_2)
        arg_6()[arg_7] = arg_5
        arg_5.start()
        return arg_5, True


def Func():
    """
    Stop and destroy Bloomberg connection
    """
    if _CON_SYM_ in globals():
        arg_0 = globals().pop(_CON_SYM_)
        if not getattr(arg_0, '_session').start(): arg_0.stop()


def Func():
    """
    Parse markdown as description
    """
    arg_0 = f'{PACKAGE_ROOT}/README.md'
    if path.exists(arg_0):
        with open(arg_0, 'r', encoding='utf-8') as f:
            arg_1 = f.read()
        return arg_1


def Func(arg_0: arg_1.DataFrame, arg_3: arg_1.DataFrame) -> arg_1.DataFrame:
    """
    Standardized earning outputs and add percentage by each blocks

    Args:
        data: earning data block
        header: earning headers

    Returns:
        pd.DataFrame

    Examples:
        >>> Func(
        ...     data=pd.read_pickle('xbbg/tests/data/sample_earning.pkl'),
        ...     header=pd.read_pickle('xbbg/tests/data/sample_earning_header.pkl')
        ... ).round(2)
                         level  fy2017  fy2017_pct
        Asia-Pacific       1.0  3540.0       66.43
           China           2.0  1747.0       49.35
           Japan           2.0  1242.0       35.08
           Singapore       2.0   551.0       15.56
        United States      1.0  1364.0       25.60
        Europe             1.0   263.0        4.94
        Other Countries    1.0   162.0        3.04
    """
    if arg_0.dropna(subset=['value']).empty: return arg_1.DataFrame()

    arg_4 = arg_1.concat([
        grp.loc[:, ['value']].set_index(arg_3.value)
        for arg_14, grp in arg_0.groupby(arg_0.position)
    ], axis=1)
    arg_4.index.name = None
    arg_4.columns = arg_4.iloc[0]
    arg_4 = arg_4.iloc[1:].transpose().reset_index().apply(
        arg_1.to_numeric, downcast='float', errors='ignore'
    )
    arg_4.rename(
        arg_7=lambda vv: '_'.join(vv.lower().split()).replace('fy_', 'fy'),
        inplace=True,
    )

    arg_8 = arg_4.columns[arg_4.columns.str.startswith('fy')]
    arg_9 = arg_4.level == 1
    for arg_10 in arg_8:
        arg_4.loc[:, arg_10] = arg_4.loc[:, arg_10].round(1)
        arg_12 = f'{yr}_pct'
        arg_4.loc[:, arg_12] = 0.
        arg_4.loc[arg_9, arg_12] = arg_4.loc[arg_9, arg_12].astype(float).round(1)
        arg_4.loc[arg_9, arg_12] = arg_4.loc[arg_9, arg_10] / arg_4.loc[arg_9, arg_10].sum() * 100
        arg_13 = []
        for arg_14, arg_15 in arg_4[::-1].iterrows():
            if arg_15.level > 2: continue
            if arg_15.level == 1:
                if len(arg_13) == 0: continue
                arg_16 = arg_1.concat(arg_13, axis=1).transpose()
                arg_4.loc[arg_16.index, arg_12] = \
                    arg_4.loc[arg_16.index, arg_10] / arg_4.loc[arg_16.index, arg_10].sum() * 100
                arg_13 = []
            if arg_15.level == 2: arg_13.append(arg_15)

    arg_4.set_index('segment_name', inplace=True)
    arg_4.index.name = None
    return arg_4


def Func(arg_0: arg_1.DataFrame, arg_3, arg_4=None) -> arg_1.DataFrame:
    """
    Format `pdblp` outputs to column-based results

    Args:
        data: `pdblp` result
        source: `bdp` or `bds`
        col_maps: rename columns with these mappings

    Returns:
        pd.DataFrame

    Examples:
        >>> Func(
        ...     data=pd.read_pickle('xbbg/tests/data/sample_bdp.pkl'),
        ...     source='bdp'
        ... ).reset_index()
                  ticker                        name
        0  QQQ US Equity  INVESCO QQQ TRUST SERIES 1
        1  SPY US Equity      SPDR S&P 500 ETF TRUST
        >>> Func(
        ...     data=pd.read_pickle('xbbg/tests/data/sample_dvd.pkl'),
        ...     source='bds', col_maps={'Dividend Frequency': 'dvd_freq'}
        ... ).loc[:, ['ex_date', 'dividend_amount', 'dvd_freq']].reset_index()
                ticker     ex_date  dividend_amount dvd_freq
        0  C US Equity  2018-02-02             0.32  Quarter
    """
    if arg_0.empty: return arg_1.DataFrame()
    if arg_3 == 'bdp': arg_5 = ['ticker', 'field', 'value']
    else: arg_5 = ['ticker', 'field', 'name', 'value', 'position']
    if any(arg_6 not in arg_0 for arg_6 in arg_5): return arg_1.DataFrame()
    if arg_0.dropna(subset=['value']).empty: return arg_1.DataFrame()

    if arg_3 == 'bdp':
        arg_7 = arg_1.DataFrame(arg_1.concat([
            arg_1.Series({**{'ticker': t}, **grp.set_index('field').value.to_dict()})
            for t, grp in arg_0.groupby('ticker')
        ], axis=1, sort=False)).transpose().set_index('ticker')
    else:
        arg_7 = arg_1.DataFrame(arg_1.concat([
            grp.loc[:, ['name', 'value']].set_index('name')
            .transpose().reset_index(drop=True).assign(ticker=t)
            for (t, _), grp in arg_0.groupby(['ticker', 'position'])
        ], sort=False)).reset_index(drop=True).set_index('ticker')
        arg_7.columns.name = None

    if arg_4 is None: arg_4 = dict()
    return arg_7.rename(
        arg_8=lambda vv: arg_4.get(
            vv, vv.lower().replace(' ', '_').replace('-', '_')
        )
    ).apply(arg_1.to_numeric, errors='ignore', downcast='float')


def Func(arg_0: arg_1.DataFrame, arg_3, **arg_4) -> arg_1.DataFrame:
    """
    Format intraday data

    Args:
        data: pd.DataFrame from bdib
        ticker: ticker

    Returns:
        pd.DataFrame

    Examples:
        >>> Func(
        ...     data=pd.read_parquet('xbbg/tests/data/sample_bdib.parq'),
        ...     ticker='SPY US Equity',
        ... ).xs('close', axis=1, level=1, drop_level=False)
        ticker                    SPY US Equity
        field                             close
        2018-12-28 09:30:00-05:00        249.67
        2018-12-28 09:31:00-05:00        249.54
        2018-12-28 09:32:00-05:00        249.22
        2018-12-28 09:33:00-05:00        249.01
        2018-12-28 09:34:00-05:00        248.86
        >>> Func(
        ...     data=pd.read_parquet('xbbg/tests/data/sample_bdib.parq'),
        ...     ticker='SPY US Equity', price_only=True
        ... )
        ticker                     SPY US Equity
        2018-12-28 09:30:00-05:00         249.67
        2018-12-28 09:31:00-05:00         249.54
        2018-12-28 09:32:00-05:00         249.22
        2018-12-28 09:33:00-05:00         249.01
        2018-12-28 09:34:00-05:00         248.86
    """
    if arg_0.empty: return arg_1.DataFrame()
    arg_0.columns = arg_1.MultiIndex.from_product([
        [arg_3], arg_0.rename(arg_5=dict(numEvents='num_trds')).columns
    ], names=['ticker', 'field'])
    arg_0.index.name = None
    if arg_4.get('price_only', False):
        arg_8 = dict(axis=1, level=1)
        arg_9 = arg_0.xs('close', **arg_8)
        arg_10 = arg_0.xs('volume', **arg_8).iloc[:, 0]
        return arg_9.loc[arg_10 > 0] if arg_10.min() > 0 else arg_9
    else: return arg_0


def Func(arg_0, arg_1) -> str:
    """
    Logging info for given tickers and fields

    Args:
        tickers: tickers
        flds: fields

    Returns:
        str

    Examples:
        >>> print(Func(
        ...     tickers=['NVDA US Equity'], flds=['Name', 'Security_Name']
        ... ))
        tickers: ['NVDA US Equity']
        fields:  ['Name', 'Security_Name']
    """
    arg_2 = '\n'.join([f'tickers: {tickers[:8]}'] + [
        f'         {tickers[n:(n + 8)]}' for n in range(8, len(arg_0), 8)
    ])
    return f'{full_list}\nfields:  {flds}'