g = self.g<EOL>for v in g.nodes():<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT>])<EOL>is_active = False<EOL>my_iter = g.in_edges(v) if g.is_directed() else g.out_edges(v)<EOL>for e in my_iter:<EOL><INDENT>ei = g.edge_index[e]<EOL>if self.edge2queue[ei]._active:<EOL><INDENT>is_active = True<EOL>break<EOL><DEDENT><DEDENT>if is_active:<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>for e in g.edges():<EOL><INDENT>ei = g.edge_index[e]<EOL>if self.edge2queue[ei]._active:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>self.draw(update_colors=False, **kwargs)<EOL>self._update_all_colors()<EOL>

Draws the network, highlighting active queues.

        The colored vertices represent vertices that have at least one
        queue on an in-edge that is active. Dark edges represent
        queues that are active, light edges represent queues that are
        inactive.

        Parameters
        ----------
        **kwargs
            Any additional parameters to pass to :meth:`.draw`, and
            :meth:`.QueueNetworkDiGraph.draw_graph`.

        Notes
        -----
        Active queues are :class:`QueueServers<.QueueServer>` that
        accept arrivals from outside the network. The colors are
        defined by the class attribute ``colors``. The relevant keys
        are ``vertex_active``, ``vertex_inactive``, ``edge_active``,
        and ``edge_inactive``.


def show_type(self, edge_type, **kwargs):

for v in self.g.nodes():<EOL><INDENT>e = (v, v)<EOL>if self.g.is_edge(e) and self.g.ep(e, '<STR_LIT>') == edge_type:<EOL><INDENT>ei = self.g.edge_index[e]<EOL>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL>self.g.set_vp(v, '<STR_LIT>', self.edge2queue[ei].colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_vp(v, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL>self.g.set_vp(v, '<STR_LIT>', [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT>])<EOL><DEDENT><DEDENT>for e in self.g.edges():<EOL><INDENT>if self.g.ep(e, '<STR_LIT>') == edge_type:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>self.g.set_ep(e, '<STR_LIT>', self.colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>self.draw(update_colors=False, **kwargs)<EOL>self._update_all_colors()<EOL>

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.show_type(2, fname=fname) # doctest: +SKIP

        .. figure:: edge_type_2-1.png
           :align: center


def simulate(self, n=<NUM_LIT:1>, t=None):

if not self._initialized:<EOL><INDENT>msg = ("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>raise QueueingToolError(msg)<EOL><DEDENT>if t is None:<EOL><INDENT>for dummy in range(n):<EOL><INDENT>self._simulate_next_event(slow=False)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>now = self._t<EOL>while self._t < now + t:<EOL><INDENT>self._simulate_next_event(slow=False)<EOL><DEDENT><DEDENT>

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 simulate. If ``t`` is not given
            then this parameter is used.
        t : float (optional)
            The amount of simulation time to simulate 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 simulate, 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 simulate the network 50000 events run:

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

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

        >>> t0 = net.current_time
        >>> net.simulate(t=75)
        >>> t1 = net.current_time
        >>> t1 - t0 # doctest: +ELLIPSIS
        75...


def start_collecting_data(self, queues=None, edge=None, edge_type=None):

queues = _get_queues(self.g, queues, edge, edge_type)<EOL>for k in queues:<EOL><INDENT>self.edge2queue[k].collect_data = True<EOL><DEDENT>

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.


def stop_collecting_data(self, queues=None, edge=None, edge_type=None):

queues = _get_queues(self.g, queues, edge, edge_type)<EOL>for k in queues:<EOL><INDENT>self.edge2queue[k].collect_data = False<EOL><DEDENT>

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.


if return_matrix:<EOL><INDENT>mat = np.zeros((self.nV, self.nV))<EOL>for v in self.g.nodes():<EOL><INDENT>ind = [e[<NUM_LIT:1>] for e in sorted(self.g.out_edges(v))]<EOL>mat[v, ind] = self._route_probs[v]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>mat = {<EOL>k: {e[<NUM_LIT:1>]: p for e, p in zip(sorted(self.g.out_edges(k)), value)}<EOL>for k, value in enumerate(self._route_probs)<EOL>}<EOL><DEDENT>return mat<EOL>

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.transitions(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_transitions(mat)
        >>> net.transitions(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.


leader = self.find(s)<EOL>return self._size[leader]<EOL>

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.


pSet   = [s]<EOL>parent = self._leader[s]<EOL>while parent != self._leader[parent]:<EOL><INDENT>pSet.append(parent)<EOL>parent = self._leader[parent]<EOL><DEDENT>if len(pSet) > <NUM_LIT:1>:<EOL><INDENT>for a in pSet:<EOL><INDENT>self._leader[a] = parent<EOL><DEDENT><DEDENT>return parent<EOL>

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``.


s1, s2 = self.find(a), self.find(b)<EOL>if s1 != s2:<EOL><INDENT>r1, r2  = self._rank[s1], self._rank[s2]<EOL>if r2 > r1:<EOL><INDENT>r1, r2 = r2, r1<EOL>s1, s2 = s2, s1<EOL><DEDENT>if r1 == r2:<EOL><INDENT>self._rank[s1] += <NUM_LIT:1><EOL><DEDENT>self._leader[s2] = s1<EOL>self._size[s1]  += self._size[s2]<EOL>self.nClusters  -= <NUM_LIT:1><EOL><DEDENT>

Merges the set that contains ``a`` with the set that contains ``b``.

        Parameters
        ----------
        a, b : objects
            Two objects whose sets are to be merged.


self.blocked += <NUM_LIT:1><EOL>

Adds one to the number of times the agent has been blocked
        from entering a queue.


def desired_destination(self, network, edge):

n = len(network.out_edges[edge[<NUM_LIT:1>]])<EOL>if n <= <NUM_LIT:1>:<EOL><INDENT>return network.out_edges[edge[<NUM_LIT:1>]][<NUM_LIT:0>]<EOL><DEDENT>u = uniform()<EOL>pr = network._route_probs[edge[<NUM_LIT:1>]]<EOL>k = _choice(pr, u, n)<EOL>return network.out_edges[edge[<NUM_LIT:1>]][k]<EOL>

Returns the agents next destination given their current
        location on the network.

        An ``Agent`` chooses one of the out edges at random. The
        probability that the ``Agent`` will travel along a specific
        edge is specified in the :class:`QueueNetwork's<.QueueNetwork>`
        transition matrix.

        Parameters
        ----------
        network : :class:`.QueueNetwork`
            The :class:`.QueueNetwork` where the Agent resides.
        edge : tuple
            A 4-tuple indicating which edge this agent is located at.
            The first two slots indicate the current edge's source and
            target vertices, while the third slot indicates this edges
            ``edge_index``. The last slot indicates the edge type of
            that edge

        Returns
        -------
        out : int
            Returns an the edge index corresponding to the agents next
            edge to visit in the network.

        See Also
        --------
        :meth:`.transitions` : :class:`QueueNetwork's<.QueueNetwork>`
            method that returns the transition probabilities for each
            edge in the graph.


def queue_action(self, queue, *args, **kwargs):

pass<EOL>

A method that acts on the queue the Agent is at. This method
        is called when the Agent arrives at the queue (where
        ``args[0] == 0``), when service starts for the Agent (where
        ``args[0] == 1``), and when the Agent departs from the queue
        (where ``args[0] == 2``). By default, this method does nothing
        to the queue, but is here if the Agent class is extended and
        this method is overwritten.


adjacent_edges = network.out_edges[edge[<NUM_LIT:1>]]<EOL>d = _argmin([network.edge2queue[d].number_queued() for d in adjacent_edges])<EOL>return adjacent_edges[d]<EOL>

Returns the agents next destination given their current
        location on the network.

        ``GreedyAgents`` choose their next destination with-in the
        network by picking the adjacent queue with the fewest number of
        :class:`Agents<.Agent>` in the queue.

        Parameters
        ----------
        network : :class:`.QueueNetwork`
            The :class:`.QueueNetwork` where the Agent resides.
        edge : tuple
            A 4-tuple indicating which edge this agent is located at.
            The first two slots indicate the current edge's source and
            target vertices, while the third slot indicates this edges
            ``edge_index``. The last slot indicates the edges edge
            type.

        Returns
        -------
        out : int
            Returns an the edge index corresponding to the agents next
            edge to visit in the network.


if isinstance(queue, ResourceQueue):<EOL><INDENT>if self._has_resource:<EOL><INDENT>self._has_resource = False<EOL>self._had_resource = True<EOL><DEDENT>else:<EOL><INDENT>if queue.num_servers > <NUM_LIT:0>:<EOL><INDENT>queue.set_num_servers(queue.num_servers - <NUM_LIT:1>)<EOL>self._has_resource = True<EOL>self._had_resource = False<EOL><DEDENT><DEDENT><DEDENT>

Function that specifies the interaction with a
        :class:`.ResourceQueue` upon departure.

        When departuring from a :class:`.ResourceQueue` (or a
        :class:`.QueueServer`), this method is called. If the agent
        does not already have a resource then it decrements the number
        of servers at :class:`.ResourceQueue` by one. Note that this
        only applies to :class:`ResourceQueue's<.ResourceQueue>`.

        Parameters
        ----------
        queue : :class:`.QueueServer`
            The instance of the queue that the ``ResourceAgent`` will
            interact with.


if isinstance(self._arrivals[<NUM_LIT:0>], ResourceAgent):<EOL><INDENT>if self._departures[<NUM_LIT:0>]._time < self._arrivals[<NUM_LIT:0>]._time:<EOL><INDENT>return super(ResourceQueue, self).next_event()<EOL><DEDENT>elif self._arrivals[<NUM_LIT:0>]._time < infty:<EOL><INDENT>if self._arrivals[<NUM_LIT:0>]._has_resource:<EOL><INDENT>arrival = heappop(self._arrivals)<EOL>self._current_t = arrival._time<EOL>self._num_total -= <NUM_LIT:1><EOL>self.set_num_servers(self.num_servers + <NUM_LIT:1>)<EOL>if self.collect_data:<EOL><INDENT>t = arrival._time<EOL>if arrival.agent_id not in self.data:<EOL><INDENT>self.data[arrival.agent_id] = [[t, t, t, len(self.queue), self.num_system]]<EOL><DEDENT>else:<EOL><INDENT>self.data[arrival.agent_id].append([t, t, t, len(self.queue), self.num_system])<EOL><DEDENT><DEDENT>if self._arrivals[<NUM_LIT:0>]._time < self._departures[<NUM_LIT:0>]._time:<EOL><INDENT>self._time = self._arrivals[<NUM_LIT:0>]._time<EOL><DEDENT>else:<EOL><INDENT>self._time = self._departures[<NUM_LIT:0>]._time<EOL><DEDENT><DEDENT>elif self.num_system < self.num_servers:<EOL><INDENT>super(ResourceQueue, self).next_event()<EOL><DEDENT>else:<EOL><INDENT>self.num_blocked += <NUM_LIT:1><EOL>self._num_arrivals += <NUM_LIT:1><EOL>self._num_total -= <NUM_LIT:1><EOL>arrival = heappop(self._arrivals)<EOL>self._current_t = arrival._time<EOL>if self.collect_data:<EOL><INDENT>if arrival.agent_id not in self.data:<EOL><INDENT>self.data[arrival.agent_id] = [[arrival._time, <NUM_LIT:0>, <NUM_LIT:0>, len(self.queue), self.num_system]]<EOL><DEDENT>else:<EOL><INDENT>self.data[arrival.agent_id].append([arrival._time, <NUM_LIT:0>, <NUM_LIT:0>, len(self.queue), self.num_system])<EOL><DEDENT><DEDENT>if self._arrivals[<NUM_LIT:0>]._time < self._departures[<NUM_LIT:0>]._time:<EOL><INDENT>self._time = self._arrivals[<NUM_LIT:0>]._time<EOL><DEDENT>else:<EOL><INDENT>self._time = self._departures[<NUM_LIT:0>]._time<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>return super(ResourceQueue, self).next_event()<EOL><DEDENT>

Simulates the queue forward one event.

        This method behaves identically to a :class:`.LossQueue` if the
        arriving/departing agent is anything other than a
        :class:`.ResourceAgent`. The differences are;

        Arriving:

        * If the :class:`.ResourceAgent` has a resource then it deletes
          the agent upon arrival and adds one to ``num_servers``.
        * If the :class:`.ResourceAgent` is arriving without a resource
          then nothing special happens.

        Departing:

        * If the :class:`.ResourceAgent` does not have a resource, then
          ``num_servers`` decreases by one and the agent then *has a
          resource*.

        Use :meth:`~QueueServer.simulate` for simulating instead.


def poisson_random_measure(t, rate, rate_max):

scale = <NUM_LIT:1.0> / rate_max<EOL>t = t + exponential(scale)<EOL>while rate_max * uniform() > rate(t):<EOL><INDENT>t = t + exponential(scale)<EOL><DEDENT>return t<EOL>

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.poisson_random_measure(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`


return False<EOL>

Returns whether the queue is at capacity or not.

        Returns
        -------
        bool
            Always returns ``False``, since the ``QueueServer`` class
            has infinite capacity.


self.data = {}<EOL>self._num_arrivals = <NUM_LIT:0><EOL>self._oArrivals = <NUM_LIT:0><EOL>self.num_departures = <NUM_LIT:0><EOL>self.num_system = <NUM_LIT:0><EOL>self._num_total = <NUM_LIT:0><EOL>self._current_t = <NUM_LIT:0><EOL>self._time = infty<EOL>self._next_ct = <NUM_LIT:0><EOL>self._active = False<EOL>self.queue = collections.deque()<EOL>inftyAgent = InftyAgent()<EOL>self._arrivals = [inftyAgent]<EOL>self._departures = [inftyAgent]<EOL>

Clears out the queue. Removes all arrivals, departures, and
        queued agents from the :class:`.QueueServer`, resets
        ``num_arrivals``, ``num_departures``, ``num_system``, and the clock to
        zero. It also clears any stored ``data`` and the server is then
        set to inactive.


return copy.deepcopy(self)<EOL>


if which == <NUM_LIT:1>:<EOL><INDENT>color = self.colors['<STR_LIT>']<EOL><DEDENT>elif which == <NUM_LIT:2>:<EOL><INDENT>color = self.colors['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>div = self.coloring_sensitivity * self.num_servers + <NUM_LIT:1.><EOL>tmp = <NUM_LIT:1.> - min(self.num_system / div, <NUM_LIT:1>)<EOL>if self.edge[<NUM_LIT:0>] == self.edge[<NUM_LIT:1>]:<EOL><INDENT>color = [i * tmp for i in self.colors['<STR_LIT>']]<EOL>color[<NUM_LIT:3>] = <NUM_LIT:1.0><EOL><DEDENT>else:<EOL><INDENT>color = [i * tmp for i in self.colors['<STR_LIT>']]<EOL>color[<NUM_LIT:3>] = <NUM_LIT:1> / <NUM_LIT><EOL><DEDENT><DEDENT>return color<EOL>

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 len(self._departures) > <NUM_LIT:1>:<EOL><INDENT>agent = heappop(self._departures)<EOL>if t is None:<EOL><INDENT>agent._time = self.service_f(agent._time)<EOL><DEDENT>else:<EOL><INDENT>agent._time = t<EOL><DEDENT>heappush(self._departures, agent)<EOL>self._update_time()<EOL><DEDENT>

Adds an extra service time to the next departing
        :class:`Agent's<.Agent>` service time.

        Parameters
        ----------
        t : float (optional)
            Specifies the departing time for the agent scheduled
            to depart next. If ``t`` is not given, then an additional
            service time is added to the next departing agent.


qdata = []<EOL>for d in self.data.values():<EOL><INDENT>qdata.extend(d)<EOL><DEDENT>dat = np.zeros((len(qdata), <NUM_LIT:6>))<EOL>if len(qdata) > <NUM_LIT:0>:<EOL><INDENT>dat[:, :<NUM_LIT:5>] = np.array(qdata)<EOL>dat[:, <NUM_LIT:5>] = self.edge[<NUM_LIT:2>]<EOL>dType = [<EOL>('<STR_LIT:a>', float),<EOL>('<STR_LIT:s>', float),<EOL>('<STR_LIT:d>', float),<EOL>('<STR_LIT:q>', float),<EOL>('<STR_LIT:n>', float),<EOL>('<STR_LIT:id>', float)<EOL>]<EOL>dat = np.array([tuple(d) for d in dat], dtype=dType)<EOL>dat = np.sort(dat, order='<STR_LIT:a>')<EOL>dat = np.array([tuple(d) for d in dat])<EOL><DEDENT>if return_header:<EOL><INDENT>return dat, '<STR_LIT>'<EOL><DEDENT>return dat<EOL>

Fetches data from the queue.

        Parameters
        ----------
        return_header : bool (optonal, default: ``False``)
            Determines whether the column headers are returned.

        Returns
        -------
        data : :class:`~numpy.ndarray`
            A six column :class:`~numpy.ndarray` of all the data. The
            columns are:

            * 1st: The arrival time of an agent.
            * 2nd: The service start time of an agent.
            * 3rd: The departure time of an agent.
            * 4th: The length of the queue upon the agents arrival.
            * 5th: The total number of :class:`Agents<.Agent>` in the
              :class:`.QueueServer`.
            * 6th: The :class:`QueueServer's<.QueueServer>` edge index.

        headers : str (optional)
            A comma seperated string of the column headers. Returns
            ``'arrival,service,departure,num_queued,num_total,q_id'``


return len(self.queue)<EOL>

Returns the number of agents waiting in line to be served.

        Returns
        -------
        out : int
            The number of agents waiting in line to be served.


if self._departures[<NUM_LIT:0>]._time < self._arrivals[<NUM_LIT:0>]._time:<EOL><INDENT>new_depart = heappop(self._departures)<EOL>self._current_t = new_depart._time<EOL>self._num_total -= <NUM_LIT:1><EOL>self.num_system -= <NUM_LIT:1><EOL>self.num_departures += <NUM_LIT:1><EOL>if self.collect_data and new_depart.agent_id in self.data:<EOL><INDENT>self.data[new_depart.agent_id][-<NUM_LIT:1>][<NUM_LIT:2>] = self._current_t<EOL><DEDENT>if len(self.queue) > <NUM_LIT:0>:<EOL><INDENT>agent = self.queue.popleft()<EOL>if self.collect_data and agent.agent_id in self.data:<EOL><INDENT>self.data[agent.agent_id][-<NUM_LIT:1>][<NUM_LIT:1>] = self._current_t<EOL><DEDENT>agent._time = self.service_f(self._current_t)<EOL>agent.queue_action(self, <NUM_LIT:1>)<EOL>heappush(self._departures, agent)<EOL><DEDENT>new_depart.queue_action(self, <NUM_LIT:2>)<EOL>self._update_time()<EOL>return new_depart<EOL><DEDENT>elif self._arrivals[<NUM_LIT:0>]._time < infty:<EOL><INDENT>arrival = heappop(self._arrivals)<EOL>self._current_t = arrival._time<EOL>if self._active:<EOL><INDENT>self._add_arrival()<EOL><DEDENT>self.num_system += <NUM_LIT:1><EOL>self._num_arrivals += <NUM_LIT:1><EOL>if self.collect_data:<EOL><INDENT>b = <NUM_LIT:0> if self.num_system <= self.num_servers else <NUM_LIT:1><EOL>if arrival.agent_id not in self.data:<EOL><INDENT>self.data[arrival.agent_id] =[[arrival._time, <NUM_LIT:0>, <NUM_LIT:0>, len(self.queue) + b, self.num_system]]<EOL><DEDENT>else:<EOL><INDENT>self.data[arrival.agent_id].append([arrival._time, <NUM_LIT:0>, <NUM_LIT:0>, len(self.queue) + b, self.num_system])<EOL><DEDENT><DEDENT>arrival.queue_action(self, <NUM_LIT:0>)<EOL>if self.num_system <= self.num_servers:<EOL><INDENT>if self.collect_data:<EOL><INDENT>self.data[arrival.agent_id][-<NUM_LIT:1>][<NUM_LIT:1>] = arrival._time<EOL><DEDENT>arrival._time = self.service_f(arrival._time)<EOL>arrival.queue_action(self, <NUM_LIT:1>)<EOL>heappush(self._departures, arrival)<EOL><DEDENT>else:<EOL><INDENT>self.queue.append(arrival)<EOL><DEDENT>self._update_time()<EOL><DEDENT>

Simulates the queue forward one event.

        Use :meth:`.simulate` instead.

        Returns
        -------
        out : :class:`.Agent` (sometimes)
            If the next event is a departure then the departing agent
            is returned, otherwise nothing is returned.

        See Also
        --------
        :meth:`.simulate` : Simulates the queue forward.


if self._departures[<NUM_LIT:0>]._time < self._arrivals[<NUM_LIT:0>]._time:<EOL><INDENT>return <NUM_LIT:2><EOL><DEDENT>elif self._arrivals[<NUM_LIT:0>]._time < infty:<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>

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 not self._active:<EOL><INDENT>self._active = True<EOL>self._add_arrival()<EOL><DEDENT>

Changes the ``active`` attribute to True. Agents may now
        arrive from outside the network.


self._active = False<EOL>

Changes the ``active`` attribute to False.


if not isinstance(n, numbers.Integral) and n is not infty:<EOL><INDENT>the_str = "<STR_LIT>"<EOL>raise TypeError(the_str.format(str(self)))<EOL><DEDENT>elif n <= <NUM_LIT:0>:<EOL><INDENT>the_str = "<STR_LIT>"<EOL>raise ValueError(the_str.format(str(self)))<EOL><DEDENT>else:<EOL><INDENT>self.num_servers = n<EOL><DEDENT>

Change the number of servers in the queue to ``n``.

        Parameters
        ----------
        n : int or :const:`numpy.infty`
            A positive integer (or ``numpy.infty``) to set the number
            of queues in the system to.

        Raises
        ------
        TypeError
            If ``n`` is not an integer or positive infinity then this
            error is raised.
        ValueError
            If ``n`` is not positive.


def simulate(self, n=<NUM_LIT:1>, t=None, nA=None, nD=None):

if t is None and nD is None and nA is None:<EOL><INDENT>for dummy in range(n):<EOL><INDENT>self.next_event()<EOL><DEDENT><DEDENT>elif t is not None:<EOL><INDENT>then = self._current_t + t<EOL>while self._current_t < then and self._time < infty:<EOL><INDENT>self.next_event()<EOL><DEDENT><DEDENT>elif nD is not None:<EOL><INDENT>num_departures = self.num_departures + nD<EOL>while self.num_departures < num_departures and self._time < infty:<EOL><INDENT>self.next_event()<EOL><DEDENT><DEDENT>elif nA is not None:<EOL><INDENT>num_arrivals = self._oArrivals + nA<EOL>while self._oArrivals < num_arrivals and self._time < infty:<EOL><INDENT>self.next_event()<EOL><DEDENT><DEDENT>

This method simulates the queue forward for a specified
        amount of simulation time, or for a specific number of
        events.

        Parameters
        ----------
        n : int (optional, default: ``1``)
            The number of events to simulate. If ``t``, ``nA``, and
            ``nD`` are not given then this parameter is used.
        t : float (optional)
            The minimum amount of simulation time to simulate forward.
        nA : int (optional)
            Simulate until ``nA`` additional arrivals are observed.
        nD : int (optional)
            Simulate until ``nD`` additional departures are observed.

        Examples
        --------
        Before any simulations can take place the ``QueueServer`` must
        be activated:

        >>> import queueing_tool as qt
        >>> import numpy as np
        >>> rate = lambda t: 2 + 16 * np.sin(np.pi * t / 8)**2
        >>> arr = lambda t: qt.poisson_random_measure(t, rate, 18)
        >>> ser = lambda t: t + np.random.gamma(4, 0.1)
        >>> q = qt.QueueServer(5, arrival_f=arr, service_f=ser, seed=54)
        >>> q.set_active()

        To simulate 50000 events do the following:

        >>> q.simulate(50000)
        >>> num_events = q.num_arrivals[0] + q.num_departures
        >>> num_events
        50000

        To simulate forward 75 time units, do the following:

        >>> t0 = q.time
        >>> q.simulate(t=75)
        >>> round(float(q.time - t0), 1)
        75.1
        >>> q.num_arrivals[1] + q.num_departures - num_events
        1597

        To simulate forward until 1000 new departures are observed run:

        >>> nA0, nD0 = q.num_arrivals[1], q.num_departures
        >>> q.simulate(nD=1000)
        >>> q.num_departures - nD0, q.num_arrivals[1] - nA0
        (1000, 983)

        To simulate until 1000 new arrivals are observed run:

        >>> nA0, nD0 = q.num_arrivals[1], q.num_departures
        >>> q.simulate(nA=1000)
        >>> q.num_departures - nD0, q.num_arrivals[1] - nA0,
        (987, 1000)


return self.num_system >= self.num_servers + self.buffer<EOL>

Returns whether the queue is at capacity or not.

        Returns
        -------
        out : bool
            Returns whether the number of agents in the system -- the
            number of agents being serviced plus those waiting to be
            serviced -- is equal to ``num_servers + buffer``.


n = len(matrix)<EOL>adj = {k: {} for k in range(n)}<EOL>for k in range(n):<EOL><INDENT>for j in range(n):<EOL><INDENT>if matrix[k, j] != <NUM_LIT:0>:<EOL><INDENT>adj[k][j] = {} if not etype else matrix[k, j]<EOL><DEDENT><DEDENT><DEDENT>return adj<EOL>

Takes an adjacency matrix and returns an adjacency list.


item = adj_dict.popitem()<EOL>adj_dict[item[<NUM_LIT:0>]] = item[<NUM_LIT:1>]<EOL>if not isinstance(item[<NUM_LIT:1>], dict):<EOL><INDENT>new_dict = {}<EOL>for key, value in adj_dict.items():<EOL><INDENT>new_dict[key] = {v: {} for v in value}<EOL><DEDENT>adj_dict = new_dict<EOL><DEDENT>return adj_dict<EOL>

Takes a dictionary based representation of an adjacency list
    and returns a dict of dicts based representation.


def _adjacency_adjust(adjacency, adjust, is_directed):

for v, adj in adjacency.items():<EOL><INDENT>for properties in adj.values():<EOL><INDENT>if properties.get('<STR_LIT>') is None:<EOL><INDENT>properties['<STR_LIT>'] = <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>if is_directed:<EOL><INDENT>if adjust == <NUM_LIT:2>:<EOL><INDENT>null_nodes = set()<EOL>for k, adj in adjacency.items():<EOL><INDENT>if len(adj) == <NUM_LIT:0>:<EOL><INDENT>null_nodes.add(k)<EOL><DEDENT><DEDENT>for k, adj in adjacency.items():<EOL><INDENT>for v in adj.keys():<EOL><INDENT>if v in null_nodes:<EOL><INDENT>adj[v]['<STR_LIT>'] = <NUM_LIT:0><EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>for k, adj in adjacency.items():<EOL><INDENT>if len(adj) == <NUM_LIT:0>:<EOL><INDENT>adj[k] = {'<STR_LIT>': <NUM_LIT:0>}<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return adjacency<EOL>

Takes an adjacency list and returns a (possibly) modified
    adjacency list.


def adjacency2graph(adjacency, edge_type=None, adjust=<NUM_LIT:1>, **kwargs):

if isinstance(adjacency, np.ndarray):<EOL><INDENT>adjacency = _matrix2dict(adjacency)<EOL><DEDENT>elif isinstance(adjacency, dict):<EOL><INDENT>adjacency = _dict2dict(adjacency)<EOL><DEDENT>else:<EOL><INDENT>msg = ("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>raise TypeError(msg)<EOL><DEDENT>if edge_type is None:<EOL><INDENT>edge_type = {}<EOL><DEDENT>else:<EOL><INDENT>if isinstance(edge_type, np.ndarray):<EOL><INDENT>edge_type = _matrix2dict(edge_type, etype=True)<EOL><DEDENT>elif isinstance(edge_type, dict):<EOL><INDENT>edge_type = _dict2dict(edge_type)<EOL><DEDENT><DEDENT>for u, ty in edge_type.items():<EOL><INDENT>for v, et in ty.items():<EOL><INDENT>adjacency[u][v]['<STR_LIT>'] = et<EOL><DEDENT><DEDENT>g = nx.from_dict_of_dicts(adjacency, create_using=nx.DiGraph())<EOL>adjacency = nx.to_dict_of_dicts(g)<EOL>adjacency = _adjacency_adjust(adjacency, adjust, True)<EOL>return nx.from_dict_of_dicts(adjacency, create_using=nx.DiGraph())<EOL>

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.adjacency2graph(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.adjacency2graph(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.adjacency2graph(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}})]


edges = []<EOL>for e in self.edges():<EOL><INDENT>if self.adj[e[<NUM_LIT:0>]][e[<NUM_LIT:1>]].get('<STR_LIT>') == edge_type:<EOL><INDENT>edges.append(e)<EOL><DEDENT><DEDENT>return edges<EOL>

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.get_edge_type(2)
        >>> ans.sort()
        >>> ans
        [(0, 1), (2, 0)]


def draw_graph(self, line_kwargs=None, scatter_kwargs=None, **kwargs):

if not HAS_MATPLOTLIB:<EOL><INDENT>raise ImportError("<STR_LIT>")<EOL><DEDENT>fig = plt.figure(figsize=kwargs.get('<STR_LIT>', (<NUM_LIT:7>, <NUM_LIT:7>)))<EOL>ax = fig.gca()<EOL>mpl_kwargs = {<EOL>'<STR_LIT>': line_kwargs,<EOL>'<STR_LIT>': scatter_kwargs,<EOL>'<STR_LIT>': kwargs.get('<STR_LIT>')<EOL>}<EOL>line_kwargs, scatter_kwargs = self.lines_scatter_args(**mpl_kwargs)<EOL>edge_collection = LineCollection(**line_kwargs)<EOL>ax.add_collection(edge_collection)<EOL>ax.scatter(**scatter_kwargs)<EOL>if hasattr(ax, '<STR_LIT>'):<EOL><INDENT>ax.set_facecolor(kwargs.get('<STR_LIT>', [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>]))<EOL><DEDENT>else:<EOL><INDENT>ax.set_axis_bgcolor(kwargs.get('<STR_LIT>', [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>]))<EOL><DEDENT>ax.get_xaxis().set_visible(False)<EOL>ax.get_yaxis().set_visible(False)<EOL>if '<STR_LIT>' in kwargs:<EOL><INDENT>new_kwargs = {k: v for k, v in kwargs.items() if k in SAVEFIG_KWARGS}<EOL>fig.savefig(kwargs['<STR_LIT>'], **new_kwargs)<EOL><DEDENT>else:<EOL><INDENT>plt.ion()<EOL>plt.show()<EOL><DEDENT>

Draws the graph.

        Uses matplotlib, specifically
        :class:`~matplotlib.collections.LineCollection` and
        :meth:`~matplotlib.axes.Axes.scatter`. Gets the default
        keyword arguments for both methods by calling
        :meth:`~.QueueNetworkDiGraph.lines_scatter_args` first.

        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`.
        bgcolor : list (optional, keyword only)
            A list with 4 floats representing a RGBA color. Defaults
            to ``[1, 1, 1, 1]``.
        figsize : tuple (optional, keyword only, default: ``(7, 7)``)
            The width and height of the figure in inches.
        kwargs :
            Any keyword arguments used by
            :meth:`~matplotlib.figure.Figure.savefig`.

        Raises
        ------
        ImportError :
            If Matplotlib is not installed then an :exc:`ImportError`
            is raised.

        Notes
        -----
        If the ``fname`` keyword is passed, then the figure is saved
        locally.


def lines_scatter_args(self, line_kwargs=None, scatter_kwargs=None, pos=None):

if pos is not None:<EOL><INDENT>self.set_pos(pos)<EOL><DEDENT>elif self.pos is None:<EOL><INDENT>self.set_pos()<EOL><DEDENT>edge_pos = [<NUM_LIT:0> for e in self.edges()]<EOL>for e in self.edges():<EOL><INDENT>ei = self.edge_index[e]<EOL>edge_pos[ei] = (self.pos[e[<NUM_LIT:0>]], self.pos[e[<NUM_LIT:1>]])<EOL><DEDENT>line_collecton_kwargs = {<EOL>'<STR_LIT>': edge_pos,<EOL>'<STR_LIT>': self.edge_color,<EOL>'<STR_LIT>': (<NUM_LIT:1>,),<EOL>'<STR_LIT>': (<NUM_LIT:1>,),<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': plt.cm.ocean_r,<EOL>'<STR_LIT>': <NUM_LIT:5>,<EOL>'<STR_LIT>': <NUM_LIT:0>,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>}<EOL>scatter_kwargs_ = {<EOL>'<STR_LIT:x>': self.pos[:, <NUM_LIT:0>],<EOL>'<STR_LIT:y>': self.pos[:, <NUM_LIT:1>],<EOL>'<STR_LIT:s>': <NUM_LIT:50>,<EOL>'<STR_LIT:c>': self.vertex_fill_color,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT:o>',<EOL>'<STR_LIT>': <NUM_LIT:2>,<EOL>'<STR_LIT>': plt.cm.ocean_r,<EOL>'<STR_LIT>': <NUM_LIT:1>,<EOL>'<STR_LIT>': self.vertex_color,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>}<EOL>line_kwargs = {} if line_kwargs is None else line_kwargs<EOL>scatter_kwargs = {} if scatter_kwargs is None else scatter_kwargs<EOL>for key, value in line_kwargs.items():<EOL><INDENT>if key in line_collecton_kwargs:<EOL><INDENT>line_collecton_kwargs[key] = value<EOL><DEDENT><DEDENT>for key, value in scatter_kwargs.items():<EOL><INDENT>if key in scatter_kwargs_:<EOL><INDENT>scatter_kwargs_[key] = value<EOL><DEDENT><DEDENT>return line_collecton_kwargs, scatter_kwargs_<EOL>

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.


g = _test_graph(g)<EOL>g.new_edge_property('<STR_LIT>')<EOL>for e in g.edges():<EOL><INDENT>latlon1 = g.vp(e[<NUM_LIT:1>], '<STR_LIT>')<EOL>latlon2 = g.vp(e[<NUM_LIT:0>], '<STR_LIT>')<EOL>g.set_ep(e, '<STR_LIT>', np.round(_calculate_distance(latlon1, latlon2), <NUM_LIT:3>))<EOL><DEDENT>return g<EOL>

Add add the edge lengths as a :any:`DiGraph<networkx.DiGraph>`
    for the graph.

    Uses the ``pos`` vertex property to get the location of each
    vertex. These are then used to calculate the length of an edge
    between two vertices.

    Parameters
    ----------
    g : :any:`networkx.DiGraph`, :class:`numpy.ndarray`, dict, \
        ``None``, etc.
        Any object that networkx can turn into a
        :any:`DiGraph<networkx.DiGraph>`

    Returns
    -------
    :class:`.QueueNetworkDiGraph`
        Returns the a graph with the ``edge_length`` edge property.

    Raises
    ------
    TypeError
        Raised when the parameter ``g`` is not of a type that can be
        made into a :any:`networkx.DiGraph`.


def _prepare_graph(g, g_colors, q_cls, q_arg, adjust_graph):

g = _test_graph(g)<EOL>if adjust_graph:<EOL><INDENT>pos = nx.get_node_attributes(g, '<STR_LIT>')<EOL>ans = nx.to_dict_of_dicts(g)<EOL>g = adjacency2graph(ans, adjust=<NUM_LIT:2>, is_directed=g.is_directed())<EOL>g = QueueNetworkDiGraph(g)<EOL>if len(pos) > <NUM_LIT:0>:<EOL><INDENT>g.set_pos(pos)<EOL><DEDENT><DEDENT>g.new_vertex_property('<STR_LIT>')<EOL>g.new_vertex_property('<STR_LIT>')<EOL>g.new_vertex_property('<STR_LIT>')<EOL>g.new_vertex_property('<STR_LIT>')<EOL>g.new_edge_property('<STR_LIT>')<EOL>g.new_edge_property('<STR_LIT>')<EOL>g.new_edge_property('<STR_LIT>')<EOL>g.new_edge_property('<STR_LIT>')<EOL>queues = _set_queues(g, q_cls, q_arg, '<STR_LIT>' in g.vertex_properties())<EOL>if '<STR_LIT>' not in g.vertex_properties():<EOL><INDENT>g.set_pos()<EOL><DEDENT>for k, e in enumerate(g.edges()):<EOL><INDENT>g.set_ep(e, '<STR_LIT>', <NUM_LIT>)<EOL>g.set_ep(e, '<STR_LIT>', <NUM_LIT:8>)<EOL>if e[<NUM_LIT:0>] == e[<NUM_LIT:1>]:<EOL><INDENT>g.set_ep(e, '<STR_LIT>', queues[k].colors['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>g.set_ep(e, '<STR_LIT>', queues[k].colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>for v in g.nodes():<EOL><INDENT>g.set_vp(v, '<STR_LIT>', <NUM_LIT:1>)<EOL>g.set_vp(v, '<STR_LIT>', <NUM_LIT:8>)<EOL>e = (v, v)<EOL>if g.is_edge(e):<EOL><INDENT>g.set_vp(v, '<STR_LIT>', queues[g.edge_index[e]]._current_color(<NUM_LIT:2>))<EOL>g.set_vp(v, '<STR_LIT>', queues[g.edge_index[e]]._current_color())<EOL><DEDENT>else:<EOL><INDENT>g.set_vp(v, '<STR_LIT>', g_colors['<STR_LIT>'])<EOL>g.set_vp(v, '<STR_LIT>', g_colors['<STR_LIT>'])<EOL><DEDENT><DEDENT>return g, queues<EOL>

Prepares a graph for use in :class:`.QueueNetwork`.

    This function is called by ``__init__`` in the
    :class:`.QueueNetwork` class. It creates the :class:`.QueueServer`
    instances that sit on the edges, and sets various edge and node
    properties that are used when drawing the graph.

    Parameters
    ----------
    g : :any:`networkx.DiGraph`, :class:`numpy.ndarray`, dict, \
        ``None``,  etc.
        Any object that networkx can turn into a
        :any:`DiGraph<networkx.DiGraph>`
    g_colors : dict
        A dictionary of colors. The specific keys used are
        ``vertex_color`` and ``vertex_fill_color`` for vertices that
        do not have any loops. Set :class:`.QueueNetwork` for the
        default values passed.
    q_cls : dict
        A dictionary where the keys are integers that represent an edge
        type, and the values are :class:`.QueueServer` classes.
    q_args : dict
        A dictionary where the keys are integers that represent an edge
        type, and the values are the arguments that are used when
        creating an instance of that :class:`.QueueServer` class.
    adjust_graph : bool
        Specifies whether the graph will be adjusted using
        :func:`.adjacency2graph`.

    Returns
    -------
    g : :class:`.QueueNetworkDiGraph`
    queues : list
        A list of :class:`QueueServers<.QueueServer>` where
        ``queues[k]`` is the ``QueueServer`` that sets on the edge with
        edge index ``k``.

    Notes
    -----
    The graph ``g`` should have the ``edge_type`` edge property map.
    If it does not then an ``edge_type`` edge property is
    created and set to 1.

    The following properties are set by each queue: ``vertex_color``,
    ``vertex_fill_color``, ``vertex_fill_color``, ``edge_color``.
    See :class:`.QueueServer` for more on setting these values.

    The following properties are assigned as a properties to the graph;
    their default values for each edge or vertex is shown:

        * ``vertex_pen_width``: ``1``,
        * ``vertex_size``: ``8``,
        * ``edge_control_points``: ``[]``
        * ``edge_marker_size``: ``8``
        * ``edge_pen_width``: ``1.25``

    Raises
    ------
    TypeError
        Raised when the parameter ``g`` is not of a type that can be
        made into a :any:`networkx.DiGraph`.


lat1, lon1 = latlon1<EOL>lat2, lon2 = latlon2<EOL>dlon = lon2 - lon1<EOL>dlat = lat2 - lat1<EOL>R = <NUM_LIT>  <EOL>a = np.sin(dlat / <NUM_LIT:2>)**<NUM_LIT:2> + np.cos(lat1) * np.cos(lat2) * (np.sin(dlon / <NUM_LIT:2>))**<NUM_LIT:2><EOL>c = <NUM_LIT:2> * np.pi * R * np.arctan2(np.sqrt(a), np.sqrt(<NUM_LIT:1> - a)) / <NUM_LIT><EOL>return c<EOL>

Calculates the distance between two points on earth.


if not isinstance(g, nx.DiGraph):<EOL><INDENT>g = QueueNetworkDiGraph(g)<EOL><DEDENT>dict_of_dicts = nx.to_dict_of_dicts(g)<EOL>if return_dict_of_dict:<EOL><INDENT>return dict_of_dicts<EOL><DEDENT>else:<EOL><INDENT>return {k: list(val.keys()) for k, val in dict_of_dicts.items()}<EOL><DEDENT>

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.graph2dict(g, return_dict_of_dict=True)
    ...  # doctest: +NORMALIZE_WHITESPACE
    {0: {1: {}, 2: {}},
    1: {0: {}},
    2: {0: {}, 3: {}},
    3: {2: {}}}
    >>> qt.graph2dict(g, return_dict_of_dict=False)
    {0: [1, 2], 1: [0], 2: [0, 3], 3: [2]}


g = _test_graph(g)<EOL>if isinstance(seed, numbers.Integral):<EOL><INDENT>np.random.seed(seed)<EOL><DEDENT>nV = g.number_of_nodes()<EOL>mat = np.zeros((nV, nV))<EOL>for v in g.nodes():<EOL><INDENT>ind = [e[<NUM_LIT:1>] for e in sorted(g.out_edges(v))]<EOL>deg = len(ind)<EOL>if deg == <NUM_LIT:1>:<EOL><INDENT>mat[v, ind] = <NUM_LIT:1><EOL><DEDENT>elif deg > <NUM_LIT:1>:<EOL><INDENT>probs = np.ceil(np.random.rand(deg) * <NUM_LIT:100>) / <NUM_LIT><EOL>if np.isclose(np.sum(probs), <NUM_LIT:0>):<EOL><INDENT>probs[np.random.randint(deg)] = <NUM_LIT:1><EOL><DEDENT>mat[v, ind] = probs / np.sum(probs)<EOL><DEDENT><DEDENT>return mat<EOL>

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``.


def generate_random_graph(num_vertices=<NUM_LIT>, prob_loop=<NUM_LIT:0.5>, **kwargs):

g = minimal_random_graph(num_vertices, **kwargs)<EOL>for v in g.nodes():<EOL><INDENT>e = (v, v)<EOL>if not g.is_edge(e):<EOL><INDENT>if np.random.uniform() < prob_loop:<EOL><INDENT>g.add_edge(*e)<EOL><DEDENT><DEDENT><DEDENT>g = set_types_random(g, **kwargs)<EOL>return g<EOL>

Creates a random graph where the edges have different types.

    This method calls :func:`.minimal_random_graph`, and then adds
    a loop to each vertex with ``prob_loop`` probability. It then
    calls :func:`.set_types_random` on the resulting graph.

    Parameters
    ----------
    num_vertices : int (optional, default: 250)
        The number of vertices in the graph.
    prob_loop : float (optional, default: 0.5)
        The probability that a loop gets added to a vertex.
    **kwargs :
        Any parameters to send to :func:`.minimal_random_graph` or
        :func:`.set_types_random`.

    Returns
    -------
    :class:`.QueueNetworkDiGraph`
        A graph with the position of the vertex set as a property.
        The position property is called ``pos``. Also, the ``edge_type``
        edge property is set for each edge.

    Examples
    --------
    The following generates a directed graph with 50 vertices where half
    the edges are type 1 and 1/4th are type 2 and 1/4th are type 3:

    >>> import queueing_tool as qt
    >>> pTypes = {1: 0.5, 2: 0.25, 3: 0.25}
    >>> g = qt.generate_random_graph(100, proportions=pTypes, seed=17)
    >>> non_loops = [e for e in g.edges() if e[0] != e[1]]
    >>> p1 = np.sum([g.ep(e, 'edge_type') == 1 for e in non_loops])
    >>> float(p1) / len(non_loops) # doctest: +ELLIPSIS
    0.486...
    >>> p2 = np.sum([g.ep(e, 'edge_type') == 2 for e in non_loops])
    >>> float(p2) / len(non_loops) # doctest: +ELLIPSIS
    0.249...
    >>> p3 = np.sum([g.ep(e, 'edge_type') == 3 for e in non_loops])
    >>> float(p3) / len(non_loops) # doctest: +ELLIPSIS
    0.264...

    To make an undirected graph with 25 vertices where there are 4
    different edge types with random proportions:

    >>> p = np.random.rand(4)
    >>> p = p / sum(p)
    >>> p = {k + 1: p[k] for k in range(4)}
    >>> g = qt.generate_random_graph(num_vertices=25, is_directed=False, proportions=p)

    Note that none of the edge types in the above example are 0. It is
    recommended use edge type indices starting at 1, since 0 is
    typically used for terminal edges.


g = minimal_random_graph(num_vertices, **kwargs)<EOL>r = np.zeros(num_vertices)<EOL>for k, pr in nx.pagerank(g).items():<EOL><INDENT>r[k] = pr<EOL><DEDENT>g = set_types_rank(g, rank=r, **kwargs)<EOL>return g<EOL>

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.


def minimal_random_graph(num_vertices, seed=None, **kwargs):

if isinstance(seed, numbers.Integral):<EOL><INDENT>np.random.seed(seed)<EOL><DEDENT>points = np.random.random((num_vertices, <NUM_LIT:2>)) * <NUM_LIT:10><EOL>edges = []<EOL>for k in range(num_vertices - <NUM_LIT:1>):<EOL><INDENT>for j in range(k + <NUM_LIT:1>, num_vertices):<EOL><INDENT>v = points[k] - points[j]<EOL>edges.append((k, j, v[<NUM_LIT:0>]**<NUM_LIT:2> + v[<NUM_LIT:1>]**<NUM_LIT:2>))<EOL><DEDENT><DEDENT>mytype = [('<STR_LIT>', int), ('<STR_LIT>', int), ('<STR_LIT>', np.float)]<EOL>edges = np.array(edges, dtype=mytype)<EOL>edges = np.sort(edges, order='<STR_LIT>')<EOL>unionF = UnionFind([k for k in range(num_vertices)])<EOL>g = nx.Graph()<EOL>for n1, n2, dummy in edges:<EOL><INDENT>unionF.union(n1, n2)<EOL>g.add_edge(n1, n2)<EOL>if unionF.nClusters == <NUM_LIT:1>:<EOL><INDENT>break<EOL><DEDENT><DEDENT>pos = {j: p for j, p in enumerate(points)}<EOL>g = QueueNetworkDiGraph(g.to_directed())<EOL>g.set_pos(pos)<EOL>return g<EOL>

Creates a connected graph with random vertex locations.

    Parameters
    ----------
    num_vertices : int
        The number of vertices in the graph.
    seed : int (optional)
        An integer used to initialize numpy's psuedorandom number
        generators.
    **kwargs :
        Unused.

    Returns
    -------
    :class:`.QueueNetworkDiGraph`
        A graph with a ``pos`` vertex property for each vertex's
        position.

    Notes
    -----
    This function first places ``num_vertices`` points in the unit square
    randomly (using the uniform distribution). Then, for every vertex
    ``v``, all other vertices with Euclidean distance less or equal to
    ``r`` are connect by an edge --- where ``r`` is the smallest number
    such that the graph ends up connected.


def set_types_random(g, proportions=None, loop_proportions=None, seed=None,<EOL>**kwargs):

g = _test_graph(g)<EOL>if isinstance(seed, numbers.Integral):<EOL><INDENT>np.random.seed(seed)<EOL><DEDENT>if proportions is None:<EOL><INDENT>proportions = {k: <NUM_LIT:1.> / <NUM_LIT:3> for k in range(<NUM_LIT:1>, <NUM_LIT:4>)}<EOL><DEDENT>if loop_proportions is None:<EOL><INDENT>loop_proportions = {k: <NUM_LIT:1.> / <NUM_LIT:4> for k in range(<NUM_LIT:4>)}<EOL><DEDENT>edges = [e for e in g.edges() if e[<NUM_LIT:0>] != e[<NUM_LIT:1>]]<EOL>loops = [e for e in g.edges() if e[<NUM_LIT:0>] == e[<NUM_LIT:1>]]<EOL>props = list(proportions.values())<EOL>lprops = list(loop_proportions.values())<EOL>if not np.isclose(sum(props), <NUM_LIT:1.0>):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if not np.isclose(sum(lprops), <NUM_LIT:1.0>):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>eTypes = {}<EOL>types = list(proportions.keys())<EOL>values = np.random.choice(types, size=len(edges), replace=True, p=props)<EOL>for k, e in enumerate(edges):<EOL><INDENT>eTypes[e] = values[k]<EOL><DEDENT>types = list(loop_proportions.keys())<EOL>values = np.random.choice(types, size=len(loops), replace=True, p=lprops)<EOL>for k, e in enumerate(loops):<EOL><INDENT>eTypes[e] = values[k]<EOL><DEDENT>g.new_edge_property('<STR_LIT>')<EOL>for e in g.edges():<EOL><INDENT>g.set_ep(e, '<STR_LIT>', eTypes[e])<EOL><DEDENT>return g<EOL>

Randomly sets ``edge_type`` (edge type) properties of the graph.

    This function randomly assigns each edge a type. The probability of
    an edge being a specific type is proscribed in the
    ``proportions``, ``loop_proportions`` variables.

    Parameters
    ----------
    g : :any:`networkx.DiGraph`, :class:`numpy.ndarray`, dict, etc.
        Any object that :any:`DiGraph<networkx.DiGraph>` accepts.
    proportions : dict (optional, default: ``{k: 0.25 for k in range(1, 4)}``)
        A dictionary of edge types and proportions, where the keys are
        the types and the values are the proportion of non-loop edges
        that are expected to be of that type. The values can must sum
        to one.
    loop_proportions : dict (optional, default: ``{k: 0.25 for k in range(4)}``)
        A dictionary of edge types and proportions, where the keys are
        the types and the values are the proportion of loop edges
        that are expected to be of that type. The values can must sum
        to one.
    seed : int (optional)
        An integer used to initialize numpy's psuedorandom number
        generator.
    **kwargs :
        Unused.

    Returns
    -------
    :class:`.QueueNetworkDiGraph`
        Returns the a graph with an ``edge_type`` edge property.

    Raises
    ------
    TypeError
        Raised when the parameter ``g`` is not of a type that can be
        made into a :any:`networkx.DiGraph`.

    ValueError
        Raises a :exc:`~ValueError` if the ``pType`` values do not sum
        to one.

    Notes
    -----
    If ``pTypes`` is not explicitly specified in the arguments, then it
    defaults to four types in the graph (types 0, 1, 2, and 3). It sets
    non-loop edges to be either 1, 2, or 3 33\% chance, and loops are
    types 0, 1, 2, 3 with 25\% chance.


def set_types_rank(g, rank, pType2=<NUM_LIT:0.1>, pType3=<NUM_LIT:0.1>, seed=None, **kwargs):

g = _test_graph(g)<EOL>if isinstance(seed, numbers.Integral):<EOL><INDENT>np.random.seed(seed)<EOL><DEDENT>tmp = np.sort(np.array(rank))<EOL>nDests = int(np.ceil(g.number_of_nodes() * pType2))<EOL>dests = np.where(rank >= tmp[-nDests])[<NUM_LIT:0>]<EOL>if '<STR_LIT>' not in g.vertex_properties():<EOL><INDENT>g.set_pos()<EOL><DEDENT>dest_pos = np.array([g.vp(v, '<STR_LIT>') for v in dests])<EOL>nFCQ = int(pType3 * g.number_of_nodes())<EOL>min_g_dist = np.ones(nFCQ) * np.infty<EOL>ind_g_dist = np.ones(nFCQ, int)<EOL>r, theta = np.random.random(nFCQ) / <NUM_LIT>, np.random.random(nFCQ) * <NUM_LIT><EOL>xy_pos = np.array([r * np.cos(theta), r * np.sin(theta)]).transpose()<EOL>g_pos = xy_pos + dest_pos[np.array(np.mod(np.arange(nFCQ), nDests), int)]<EOL>for v in g.nodes():<EOL><INDENT>if v not in dests:<EOL><INDENT>tmp = np.array([_calculate_distance(g.vp(v, '<STR_LIT>'), g_pos[k, :]) for k in range(nFCQ)])<EOL>min_g_dist = np.min((tmp, min_g_dist), <NUM_LIT:0>)<EOL>ind_g_dist[min_g_dist == tmp] = v<EOL><DEDENT><DEDENT>ind_g_dist = np.unique(ind_g_dist)<EOL>fcqs = set(ind_g_dist[:min(nFCQ, len(ind_g_dist))])<EOL>dests = set(dests)<EOL>g.new_vertex_property('<STR_LIT>')<EOL>for v in g.nodes():<EOL><INDENT>if v in dests:<EOL><INDENT>g.set_vp(v, '<STR_LIT>', <NUM_LIT:3>)<EOL>if not g.is_edge((v, v)):<EOL><INDENT>g.add_edge(v, v)<EOL><DEDENT><DEDENT>elif v in fcqs:<EOL><INDENT>g.set_vp(v, '<STR_LIT>', <NUM_LIT:2>)<EOL>if not g.is_edge((v, v)):<EOL><INDENT>g.add_edge(v, v)<EOL><DEDENT><DEDENT><DEDENT>g.new_edge_property('<STR_LIT>')<EOL>for e in g.edges():<EOL><INDENT>g.set_ep(e, '<STR_LIT>', <NUM_LIT:1>)<EOL><DEDENT>for v in g.nodes():<EOL><INDENT>if g.vp(v, '<STR_LIT>') in [<NUM_LIT:2>, <NUM_LIT:3>]:<EOL><INDENT>e = (v, v)<EOL>if g.vp(v, '<STR_LIT>') == <NUM_LIT:2>:<EOL><INDENT>g.set_ep(e, '<STR_LIT>', <NUM_LIT:2>)<EOL><DEDENT>else:<EOL><INDENT>g.set_ep(e, '<STR_LIT>', <NUM_LIT:3>)<EOL><DEDENT><DEDENT><DEDENT>return g<EOL>

Creates a stylized graph. Sets edge and types using `pagerank`_.

    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 the correspond to the vertices type. The
    rest of the edges are set to type 1.

    .. _pagerank: http://en.wikipedia.org/wiki/PageRank

    Parameters
    ----------
    g : :any:`networkx.DiGraph`, :class:`~numpy.ndarray`, dict, etc.
        Any object that :any:`DiGraph<networkx.DiGraph>` accepts.
    rank : :class:`numpy.ndarray`
        An ordering of the vertices.
    pType2 : float (optional, default: 0.1)
        Specifies the proportion of vertices that will be of type 2.
    pType3 : float (optional, default: 0.1)
        Specifies the proportion of vertices that will be of type 3 and
        that are near pType2 vertices.
    seed : int (optional)
        An integer used to initialize numpy's psuedo-random number
        generator.
    **kwargs :
        Unused.

    Returns
    -------
    :class:`.QueueNetworkDiGraph`
        Returns the a graph with an ``edge_type`` edge property.

    Raises
    ------
    TypeError
        Raised when the parameter ``g`` is not of a type that can be
        made into a :any:`DiGraph<networkx.DiGraph>`.


parts = []<EOL>is_doctest = contains_doctest(text)<EOL>part = []<EOL>for line in text.split("<STR_LIT:\n>"):<EOL><INDENT>if (not is_doctest and line.strip() == '<STR_LIT>') or(is_doctest and line.strip() == '<STR_LIT>'):<EOL><INDENT>part.append(line)<EOL>parts.append("<STR_LIT:\n>".join(part))<EOL>part = []<EOL><DEDENT>else:<EOL><INDENT>part.append(line)<EOL><DEDENT><DEDENT>if "<STR_LIT:\n>".join(part).strip():<EOL><INDENT>parts.append("<STR_LIT:\n>".join(part))<EOL><DEDENT>return parts<EOL>


return (not os.path.exists(derived)<EOL>or os.stat(derived).st_mtime < os.stat(original).st_mtime)<EOL>

Returns True if derivative is out-of-date wrt original,
both of which are full file paths.


def makefig(code, code_path, output_dir, output_base, config):

<EOL>default_dpi = {'<STR_LIT>': <NUM_LIT>, '<STR_LIT>': <NUM_LIT:200>, '<STR_LIT>': <NUM_LIT:50>}<EOL>formats = []<EOL>for fmt in config.plot_formats:<EOL><INDENT>if isinstance(fmt, str):<EOL><INDENT>formats.append((fmt, default_dpi.get(fmt, <NUM_LIT>)))<EOL><DEDENT>elif type(fmt) in (tuple, list) and len(fmt)==<NUM_LIT:2>:<EOL><INDENT>formats.append((str(fmt[<NUM_LIT:0>]), int(fmt[<NUM_LIT:1>])))<EOL><DEDENT>else:<EOL><INDENT>raise PlotError('<STR_LIT>' % fmt)<EOL><DEDENT><DEDENT>code_pieces = split_code_at_show(code)<EOL>all_exists = True<EOL>img = ImageFile(output_base, output_dir)<EOL>for format, dpi in formats:<EOL><INDENT>if out_of_date(code_path, img.filename(format)):<EOL><INDENT>all_exists = False<EOL>break<EOL><DEDENT>img.formats.append(format)<EOL><DEDENT>if all_exists:<EOL><INDENT>return [(code, [img])]<EOL><DEDENT>results = []<EOL>all_exists = True<EOL>for i, code_piece in enumerate(code_pieces):<EOL><INDENT>images = []<EOL>for j in range(<NUM_LIT:1000>):<EOL><INDENT>img = ImageFile('<STR_LIT>' % (output_base, i, j), output_dir)<EOL>for format, dpi in formats:<EOL><INDENT>if out_of_date(code_path, img.filename(format)):<EOL><INDENT>all_exists = False<EOL>break<EOL><DEDENT>img.formats.append(format)<EOL><DEDENT>if not all_exists:<EOL><INDENT>all_exists = (j > <NUM_LIT:0>)<EOL>break<EOL><DEDENT>images.append(img)<EOL><DEDENT>if not all_exists:<EOL><INDENT>break<EOL><DEDENT>results.append((code_piece, images))<EOL><DEDENT>if all_exists:<EOL><INDENT>return results<EOL><DEDENT>results = []<EOL>ns = {}<EOL>for i, code_piece in enumerate(code_pieces):<EOL><INDENT>plt.close('<STR_LIT:all>')<EOL>run_code(code_piece, code_path, ns)<EOL>images = []<EOL>fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()<EOL>for j, figman in enumerate(fig_managers):<EOL><INDENT>if len(fig_managers) == <NUM_LIT:1> and len(code_pieces) == <NUM_LIT:1>:<EOL><INDENT>img = ImageFile(output_base, output_dir)<EOL><DEDENT>else:<EOL><INDENT>img = ImageFile("<STR_LIT>" % (output_base, i, j),<EOL>output_dir)<EOL><DEDENT>images.append(img)<EOL>for format, dpi in formats:<EOL><INDENT>try:<EOL><INDENT>figman.canvas.figure.savefig(img.filename(format), dpi=dpi)<EOL><DEDENT>except exceptions.BaseException as err:<EOL><INDENT>raise PlotError(traceback.format_exc())<EOL><DEDENT>img.formats.append(format)<EOL><DEDENT><DEDENT>results.append((code_piece, images))<EOL><DEDENT>return results<EOL>

Run a pyplot script *code* and save the images under *output_dir*
with file names derived from *output_base*


def __init__(self, tree, file = sys.stdout, single_line_functions=False):

self.f = file<EOL>self._single_func = single_line_functions<EOL>self._do_indent = True<EOL>self._indent = <NUM_LIT:0><EOL>self._dispatch(tree)<EOL>self._write("<STR_LIT:\n>")<EOL>self.f.flush()<EOL>

Unparser(tree, file=sys.stdout) -> None.

            Print the source for tree to file.


if self._do_indent:<EOL><INDENT>self._write("<STR_LIT:\n>"+"<STR_LIT:U+0020>"*self._indent + text)<EOL><DEDENT>else:<EOL><INDENT>self._write(text)<EOL><DEDENT>

Indent a piece of text, according to the current indentation level


self.f.write(text)<EOL>

Append a piece of text to the current line.


self._write("<STR_LIT>")<EOL>self._indent += <NUM_LIT:1><EOL>

Print ':', and increase the indentation.


self._indent -= <NUM_LIT:1><EOL>


if isinstance(tree, list):<EOL><INDENT>for t in tree:<EOL><INDENT>self._dispatch(t)<EOL><DEDENT>return<EOL><DEDENT>meth = getattr(self, "<STR_LIT:_>"+tree.__class__.__name__)<EOL>if tree.__class__.__name__ == '<STR_LIT>' and not self._do_indent:<EOL><INDENT>return<EOL><DEDENT>meth(tree)<EOL>

_dispatcher function, _dispatching tree type T to method _T.


self._dispatch(t.expr)<EOL>self._write('<STR_LIT:.>'+t.attrname)<EOL>

Handle assigning an attribute of an object


self._fill()<EOL>for target in t.nodes:<EOL><INDENT>self._dispatch(target)<EOL>self._write("<STR_LIT>")<EOL><DEDENT>self._dispatch(t.expr)<EOL>if not self._do_indent:<EOL><INDENT>self._write('<STR_LIT>')<EOL><DEDENT>

Expression Assignment such as "a = 1".

            This only handles assignment in expressions.  Keyword assignment
            is handled separately.


Name on left hand side of expression.

            Treat just like a name on the right side of an expression.


<EOL>for element in t.nodes[:-<NUM_LIT:1>]:<EOL><INDENT>self._dispatch(element)<EOL>self._write("<STR_LIT:U+002CU+0020>")<EOL><DEDENT>last_element = t.nodes[-<NUM_LIT:1>]<EOL>self._dispatch(last_element)<EOL>

Tuple on left hand side of an expression.


for i, node in enumerate(t.nodes):<EOL><INDENT>self._write("<STR_LIT:(>")<EOL>self._dispatch(node)<EOL>self._write("<STR_LIT:)>")<EOL>if i != len(t.nodes)-<NUM_LIT:1>:<EOL><INDENT>self._write("<STR_LIT>")<EOL><DEDENT><DEDENT>


self._dispatch(t.node)<EOL>self._write("<STR_LIT:(>")<EOL>comma = False<EOL>for e in t.args:<EOL><INDENT>if comma: self._write("<STR_LIT:U+002CU+0020>")<EOL>else: comma = True<EOL>self._dispatch(e)<EOL><DEDENT>if t.star_args:<EOL><INDENT>if comma: self._write("<STR_LIT:U+002CU+0020>")<EOL>else: comma = True<EOL>self._write("<STR_LIT:*>")<EOL>self._dispatch(t.star_args)<EOL><DEDENT>if t.dstar_args:<EOL><INDENT>if comma: self._write("<STR_LIT:U+002CU+0020>")<EOL>else: comma = True<EOL>self._write("<STR_LIT>")<EOL>self._dispatch(t.dstar_args)<EOL><DEDENT>self._write("<STR_LIT:)>")<EOL>


A constant value such as an integer value, 3, or a string, "hello".


for node in t.nodes:<EOL><INDENT>self._dispatch(node)<EOL><DEDENT>

Handle function decorators (eg. @has_units)


self._fill()<EOL>self._dispatch(t.expr)<EOL>

Node for when return value is ignored such as in "foo(a)".


<EOL>self._fill("<STR_LIT>")<EOL>self._write(t.modname)<EOL>self._write("<STR_LIT>")<EOL>for i, (name,asname) in enumerate(t.names):<EOL><INDENT>if i != <NUM_LIT:0>:<EOL><INDENT>self._write("<STR_LIT:U+002CU+0020>")<EOL><DEDENT>self._write(name)<EOL>if asname is not None:<EOL><INDENT>self._write("<STR_LIT>"+asname)<EOL><DEDENT><DEDENT>

Handle "from xyz import foo, bar as baz".


if t.decorators is not None:<EOL><INDENT>self._fill("<STR_LIT:@>")<EOL>self._dispatch(t.decorators)<EOL><DEDENT>self._fill("<STR_LIT>"+t.name + "<STR_LIT:(>")<EOL>defaults = [None] * (len(t.argnames) - len(t.defaults)) + list(t.defaults)<EOL>for i, arg in enumerate(zip(t.argnames, defaults)):<EOL><INDENT>self._write(arg[<NUM_LIT:0>])<EOL>if arg[<NUM_LIT:1>] is not None:<EOL><INDENT>self._write('<STR_LIT:=>')<EOL>self._dispatch(arg[<NUM_LIT:1>])<EOL><DEDENT>if i < len(t.argnames)-<NUM_LIT:1>:<EOL><INDENT>self._write('<STR_LIT:U+002CU+0020>')<EOL><DEDENT><DEDENT>self._write("<STR_LIT:)>")<EOL>if self._single_func:<EOL><INDENT>self._do_indent = False<EOL><DEDENT>self._enter()<EOL>self._dispatch(t.code)<EOL>self._leave()<EOL>self._do_indent = True<EOL>


if isinstance(t.expr, (Div, Mul, Sub, Add)):<EOL><INDENT>self._write('<STR_LIT:(>')<EOL>self._dispatch(t.expr)<EOL>self._write('<STR_LIT:)>')<EOL><DEDENT>else:<EOL><INDENT>self._dispatch(t.expr)<EOL><DEDENT>self._write('<STR_LIT:.>'+t.attrname)<EOL>

Handle getting an attribute of an object


self._fill("<STR_LIT>")<EOL>for i, (name,asname) in enumerate(t.names):<EOL><INDENT>if i != <NUM_LIT:0>:<EOL><INDENT>self._write("<STR_LIT:U+002CU+0020>")<EOL><DEDENT>self._write(name)<EOL>if asname is not None:<EOL><INDENT>self._write("<STR_LIT>"+asname)<EOL><DEDENT><DEDENT>


self._write(t.name)<EOL>self._write("<STR_LIT:=>")<EOL>self._dispatch(t.expr)<EOL>

Keyword value assignment within function calls and definitions.


out = []<EOL>if self[name]:<EOL><INDENT>out += ['<STR_LIT>' % name, '<STR_LIT>']<EOL>prefix = getattr(self, '<STR_LIT>', '<STR_LIT>')<EOL>if prefix:<EOL><INDENT>prefix = '<STR_LIT>' % prefix<EOL><DEDENT>autosum = []<EOL>others = []<EOL>for param, param_type, desc in self[name]:<EOL><INDENT>param = param.strip()<EOL>param_obj = getattr(self._obj, param, None)<EOL>if not (callable(param_obj)<EOL>or isinstance(param_obj, property)<EOL>or inspect.isgetsetdescriptor(param_obj)):<EOL><INDENT>param_obj = None<EOL><DEDENT>if param_obj and (pydoc.getdoc(param_obj) or not desc):<EOL><INDENT>autosum += ["<STR_LIT>" % (prefix, param)]<EOL><DEDENT>else:<EOL><INDENT>others.append((param, param_type, desc))<EOL><DEDENT><DEDENT>if autosum:<EOL><INDENT>out += ['<STR_LIT>']<EOL>if self.class_members_toctree:<EOL><INDENT>out += ['<STR_LIT>']<EOL><DEDENT>out += ['<STR_LIT>'] + autosum<EOL><DEDENT>if others:<EOL><INDENT>maxlen_0 = max(<NUM_LIT:3>, max([len(x[<NUM_LIT:0>]) for x in others]))<EOL>hdr = sixu("<STR_LIT:=>")*maxlen_0 + sixu("<STR_LIT:U+0020>") + sixu("<STR_LIT:=>")*<NUM_LIT:10><EOL>fmt = sixu('<STR_LIT>') % (maxlen_0,)<EOL>out += ['<STR_LIT>', hdr]<EOL>for param, param_type, desc in others:<EOL><INDENT>desc = sixu("<STR_LIT:U+0020>").join(x.strip() for x in desc).strip()<EOL>if param_type:<EOL><INDENT>desc = "<STR_LIT>" % (param_type, desc)<EOL><DEDENT>out += [fmt % (param.strip(), desc)]<EOL><DEDENT>out += [hdr]<EOL><DEDENT>out += ['<STR_LIT>']<EOL><DEDENT>return out<EOL>

Generate a member listing, autosummary:: table where possible,
and a table where not.


return textwrap.dedent("<STR_LIT:\n>".join(lines)).split("<STR_LIT:\n>")<EOL>


if isinstance(data,list):<EOL><INDENT>self._str = data<EOL><DEDENT>else:<EOL><INDENT>self._str = data.split('<STR_LIT:\n>') <EOL><DEDENT>self.reset()<EOL>

Parameters
----------
data : str
   String with lines separated by '\n'.


items = []<EOL>def parse_item_name(text):<EOL><INDENT>"""<STR_LIT>"""<EOL>m = self._name_rgx.match(text)<EOL>if m:<EOL><INDENT>g = m.groups()<EOL>if g[<NUM_LIT:1>] is None:<EOL><INDENT>return g[<NUM_LIT:3>], None<EOL><DEDENT>else:<EOL><INDENT>return g[<NUM_LIT:2>], g[<NUM_LIT:1>]<EOL><DEDENT><DEDENT>raise ValueError("<STR_LIT>" % text)<EOL><DEDENT>def push_item(name, rest):<EOL><INDENT>if not name:<EOL><INDENT>return<EOL><DEDENT>name, role = parse_item_name(name)<EOL>items.append((name, list(rest), role))<EOL>del rest[:]<EOL><DEDENT>current_func = None<EOL>rest = []<EOL>for line in content:<EOL><INDENT>if not line.strip(): continue<EOL>m = self._name_rgx.match(line)<EOL>if m and line[m.end():].strip().startswith('<STR_LIT::>'):<EOL><INDENT>push_item(current_func, rest)<EOL>current_func, line = line[:m.end()], line[m.end():]<EOL>rest = [line.split('<STR_LIT::>', <NUM_LIT:1>)[<NUM_LIT:1>].strip()]<EOL>if not rest[<NUM_LIT:0>]:<EOL><INDENT>rest = []<EOL><DEDENT><DEDENT>elif not line.startswith('<STR_LIT:U+0020>'):<EOL><INDENT>push_item(current_func, rest)<EOL>current_func = None<EOL>if '<STR_LIT:U+002C>' in line:<EOL><INDENT>for func in line.split('<STR_LIT:U+002C>'):<EOL><INDENT>if func.strip():<EOL><INDENT>push_item(func, [])<EOL><DEDENT><DEDENT><DEDENT>elif line.strip():<EOL><INDENT>current_func = line<EOL><DEDENT><DEDENT>elif current_func is not None:<EOL><INDENT>rest.append(line.strip())<EOL><DEDENT><DEDENT>push_item(current_func, rest)<EOL>return items<EOL>

func_name : Descriptive text
    continued text
another_func_name : Descriptive text
func_name1, func_name2, :meth:`func_name`, func_name3


def _parse_index(self, section, content):

def strip_each_in(lst):<EOL><INDENT>return [s.strip() for s in lst]<EOL><DEDENT>out = {}<EOL>section = section.split('<STR_LIT>')<EOL>if len(section) > <NUM_LIT:1>:<EOL><INDENT>out['<STR_LIT:default>'] = strip_each_in(section[<NUM_LIT:1>].split('<STR_LIT:U+002C>'))[<NUM_LIT:0>]<EOL><DEDENT>for line in content:<EOL><INDENT>line = line.split('<STR_LIT::>')<EOL>if len(line) > <NUM_LIT:2>:<EOL><INDENT>out[line[<NUM_LIT:1>]] = strip_each_in(line[<NUM_LIT:2>].split('<STR_LIT:U+002C>'))<EOL><DEDENT><DEDENT>return out<EOL>

.. index: default
   :refguide: something, else, and more


if self._is_at_section():<EOL><INDENT>return<EOL><DEDENT>while True:<EOL><INDENT>summary = self._doc.read_to_next_empty_line()<EOL>summary_str = "<STR_LIT:U+0020>".join([s.strip() for s in summary]).strip()<EOL>if re.compile('<STR_LIT>').match(summary_str):<EOL><INDENT>self['<STR_LIT>'] = summary_str<EOL>if not self._is_at_section():<EOL><INDENT>continue<EOL><DEDENT><DEDENT>break<EOL><DEDENT>if summary is not None:<EOL><INDENT>self['<STR_LIT>'] = summary<EOL><DEDENT>if not self._is_at_section():<EOL><INDENT>self['<STR_LIT>'] = self._read_to_next_section()<EOL><DEDENT>


import lxml.etree as etree<EOL>object_cache = {}<EOL>tree = etree.parse(xml_file)<EOL>root = tree.getroot()<EOL>all_nodes = dict([(n.attrib['<STR_LIT:id>'], n) for n in root])<EOL>def _get_bases(node, recurse=False):<EOL><INDENT>bases = [x.attrib['<STR_LIT>'] for x in node.findall('<STR_LIT>')]<EOL>if recurse:<EOL><INDENT>j = <NUM_LIT:0><EOL>while True:<EOL><INDENT>try:<EOL><INDENT>b = bases[j]<EOL><DEDENT>except IndexError: break<EOL>if b in all_nodes:<EOL><INDENT>bases.extend(_get_bases(all_nodes[b]))<EOL><DEDENT>j += <NUM_LIT:1><EOL><DEDENT><DEDENT>return bases<EOL><DEDENT>type_index = ['<STR_LIT>', '<STR_LIT:class>', '<STR_LIT>', '<STR_LIT:object>']<EOL>def base_cmp(a, b):<EOL><INDENT>x = cmp(type_index.index(a.tag), type_index.index(b.tag))<EOL>if x != <NUM_LIT:0>: return x<EOL>if a.tag == '<STR_LIT:class>' and b.tag == '<STR_LIT:class>':<EOL><INDENT>a_bases = _get_bases(a, recurse=True)<EOL>b_bases = _get_bases(b, recurse=True)<EOL>x = cmp(len(a_bases), len(b_bases))<EOL>if x != <NUM_LIT:0>: return x<EOL>if a.attrib['<STR_LIT:id>'] in b_bases: return -<NUM_LIT:1><EOL>if b.attrib['<STR_LIT:id>'] in a_bases: return <NUM_LIT:1><EOL><DEDENT>return cmp(a.attrib['<STR_LIT:id>'].count('<STR_LIT:.>'), b.attrib['<STR_LIT:id>'].count('<STR_LIT:.>'))<EOL><DEDENT>nodes = root.getchildren()<EOL>nodes.sort(base_cmp)<EOL>for node in nodes:<EOL><INDENT>name = node.attrib['<STR_LIT:id>']<EOL>doc = (node.text or '<STR_LIT>').decode('<STR_LIT>') + "<STR_LIT:\n>"<EOL>if doc == "<STR_LIT:\n>": doc = "<STR_LIT>"<EOL>parent = name<EOL>while True:<EOL><INDENT>parent = '<STR_LIT:.>'.join(parent.split('<STR_LIT:.>')[:-<NUM_LIT:1>])<EOL>if not parent: break<EOL>if parent in object_cache: break<EOL>obj = imp.new_module(parent)<EOL>object_cache[parent] = obj<EOL>sys.modules[parent] = obj<EOL><DEDENT>if node.tag == '<STR_LIT>':<EOL><INDENT>obj = imp.new_module(name)<EOL>obj.__doc__ = doc<EOL>sys.modules[name] = obj<EOL><DEDENT>elif node.tag == '<STR_LIT:class>':<EOL><INDENT>bases = [object_cache[b] for b in _get_bases(node)<EOL>if b in object_cache]<EOL>bases.append(object)<EOL>init = lambda self: None<EOL>init.__doc__ = doc<EOL>obj = type(name, tuple(bases), {'<STR_LIT>': doc, '<STR_LIT>': init})<EOL>obj.__name__ = name.split('<STR_LIT:.>')[-<NUM_LIT:1>]<EOL><DEDENT>elif node.tag == '<STR_LIT>':<EOL><INDENT>funcname = node.attrib['<STR_LIT:id>'].split('<STR_LIT:.>')[-<NUM_LIT:1>]<EOL>argspec = node.attrib.get('<STR_LIT>')<EOL>if argspec:<EOL><INDENT>argspec = re.sub('<STR_LIT>', '<STR_LIT>', argspec)<EOL>doc = "<STR_LIT>" % (funcname, argspec, doc)<EOL><DEDENT>obj = lambda: <NUM_LIT:0><EOL>obj.__argspec_is_invalid_ = True<EOL>if sys.version_info[<NUM_LIT:0>] >= <NUM_LIT:3>:<EOL><INDENT>obj.__name__ = funcname<EOL><DEDENT>else:<EOL><INDENT>obj.func_name = funcname<EOL><DEDENT>obj.__name__ = name<EOL>obj.__doc__ = doc<EOL>if inspect.isclass(object_cache[parent]):<EOL><INDENT>obj.__objclass__ = object_cache[parent]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>class Dummy(object): pass<EOL>obj = Dummy()<EOL>obj.__name__ = name<EOL>obj.__doc__ = doc<EOL>if inspect.isclass(object_cache[parent]):<EOL><INDENT>obj.__get__ = lambda: None<EOL><DEDENT><DEDENT>object_cache[name] = obj<EOL>if parent:<EOL><INDENT>if inspect.ismodule(object_cache[parent]):<EOL><INDENT>obj.__module__ = parent<EOL>setattr(object_cache[parent], name.split('<STR_LIT:.>')[-<NUM_LIT:1>], obj)<EOL><DEDENT><DEDENT><DEDENT>for node in root:<EOL><INDENT>obj = object_cache.get(node.attrib['<STR_LIT:id>'])<EOL>if obj is None: continue<EOL>for ref in node.findall('<STR_LIT>'):<EOL><INDENT>if node.tag == '<STR_LIT:class>':<EOL><INDENT>if ref.attrib['<STR_LIT>'].startswith(node.attrib['<STR_LIT:id>'] + '<STR_LIT:.>'):<EOL><INDENT>setattr(obj, ref.attrib['<STR_LIT:name>'],<EOL>object_cache.get(ref.attrib['<STR_LIT>']))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>setattr(obj, ref.attrib['<STR_LIT:name>'],<EOL>object_cache.get(ref.attrib['<STR_LIT>']))<EOL><DEDENT><DEDENT><DEDENT>

Insert a fake Python module to sys.modules, based on a XML file.

The XML file is expected to conform to Pydocweb DTD. The fake
module will contain dummy objects, which guarantee the following:

- Docstrings are correct.
- Class inheritance relationships are correct (if present in XML).
- Function argspec is *NOT* correct (even if present in XML).
  Instead, the function signature is prepended to the function docstring.
- Class attributes are *NOT* correct; instead, they are dummy objects.

Parameters
----------
xml_file : str
    Name of an XML file to read


t = obj<EOL>if t.__name__ == classname:<EOL><INDENT>return True<EOL><DEDENT>for klass in t.__mro__:<EOL><INDENT>if klass.__name__ == classname:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Return True if the object has a class or superclass with the given class
    name.

    Ignores old-style classes.


lines = []<EOL>for line in text.splitlines():<EOL><INDENT>lines.append(line.lstrip('<STR_LIT:#>'))<EOL><DEDENT>text = textwrap.dedent('<STR_LIT:\n>'.join(lines))<EOL>return text<EOL>

Strip # markers at the front of a block of comment text.


<EOL>source = inspect.getsource(klass)<EOL>cb = CommentBlocker()<EOL>cb.process_file(StringIO(source))<EOL>mod_ast = compiler.parse(source)<EOL>class_ast = mod_ast.node.nodes[<NUM_LIT:0>]<EOL>for node in class_ast.code.nodes:<EOL><INDENT>if isinstance(node, compiler.ast.Assign):<EOL><INDENT>name = node.nodes[<NUM_LIT:0>].name<EOL>rhs = unparse(node.expr).strip()<EOL>doc = strip_comment_marker(cb.search_for_comment(node.lineno, default='<STR_LIT>'))<EOL>yield name, rhs, doc<EOL><DEDENT><DEDENT>

Yield all of the documentation for trait definitions on a class object.


def add(self, string, start, end, line):

self.start_lineno = min(self.start_lineno, start[<NUM_LIT:0>])<EOL>self.end_lineno = max(self.end_lineno, end[<NUM_LIT:0>])<EOL>self.text += string<EOL>


if string.strip():<EOL><INDENT>self.start_lineno = min(self.start_lineno, start[<NUM_LIT:0>])<EOL>self.end_lineno = max(self.end_lineno, end[<NUM_LIT:0>])<EOL><DEDENT>


if sys.version_info[<NUM_LIT:0>] >= <NUM_LIT:3>:<EOL><INDENT>nxt = file.__next__<EOL><DEDENT>else:<EOL><INDENT>nxt = file.next<EOL><DEDENT>for token in tokenize.generate_tokens(nxt):<EOL><INDENT>self.process_token(*token)<EOL><DEDENT>self.make_index()<EOL>


def process_token(self, kind, string, start, end, line):

if self.current_block.is_comment:<EOL><INDENT>if kind == tokenize.COMMENT:<EOL><INDENT>self.current_block.add(string, start, end, line)<EOL><DEDENT>else:<EOL><INDENT>self.new_noncomment(start[<NUM_LIT:0>], end[<NUM_LIT:0>])<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if kind == tokenize.COMMENT:<EOL><INDENT>self.new_comment(string, start, end, line)<EOL><DEDENT>else:<EOL><INDENT>self.current_block.add(string, start, end, line)<EOL><DEDENT><DEDENT>


def new_noncomment(self, start_lineno, end_lineno):

block = NonComment(start_lineno, end_lineno)<EOL>self.blocks.append(block)<EOL>self.current_block = block<EOL>

We are transitioning from a noncomment to a comment.


def new_comment(self, string, start, end, line):

prefix = line[:start[<NUM_LIT:1>]]<EOL>if prefix.strip():<EOL><INDENT>self.current_block.add(string, start, end, line)<EOL><DEDENT>else:<EOL><INDENT>block = Comment(start[<NUM_LIT:0>], end[<NUM_LIT:0>], string)<EOL>self.blocks.append(block)<EOL>self.current_block = block<EOL><DEDENT>

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.


for prev, block in zip(self.blocks[:-<NUM_LIT:1>], self.blocks[<NUM_LIT:1>:]):<EOL><INDENT>if not block.is_comment:<EOL><INDENT>self.index[block.start_lineno] = prev<EOL><DEDENT><DEDENT>

Make the index mapping lines of actual code to their associated
        prefix comments.


def search_for_comment(self, lineno, default=None):

if not self.index:<EOL><INDENT>self.make_index()<EOL><DEDENT>block = self.index.get(lineno, None)<EOL>text = getattr(block, '<STR_LIT:text>', default)<EOL>return text<EOL>

Find the comment block just before the given line number.

        Returns None (or the specified default) if there is no such block.


def __init__(self, fp, observer_code, *, delimiter='<STR_LIT:U+002C>', date_format='<STR_LIT>',<EOL>obstype='<STR_LIT>'):

self.observer_code = observer_code<EOL>self.date_format = date_format<EOL>self.obstype = obstype<EOL>fp.write('<STR_LIT>')<EOL>fp.write('<STR_LIT>' % observer_code)<EOL>fp.write("<STR_LIT>" % pyaavso.get_version())<EOL>fp.write("<STR_LIT>" % delimiter)<EOL>fp.write("<STR_LIT>" % date_format.upper())<EOL>fp.write("<STR_LIT>" % obstype)<EOL>self.writer = csv.writer(fp, delimiter=delimiter)<EOL>

Creates the writer which will write observations into the file-like
object given in first parameter. The only other required parameter
is the official AAVSO-assigned observer code.

:param fp: file-like object to write observations into
:param observer_code: AAVSO observer code
:param delimiter: field delimiter (set as DELIM header)
:param date_format: observation date format (one of *JD* or *Excel*)
:param obstype: observation type (*Visual* or *PTG*)


if isinstance(observation_data, (list, tuple)):<EOL><INDENT>row = observation_data<EOL><DEDENT>else:<EOL><INDENT>row = self.dict_to_row(observation_data)<EOL><DEDENT>self.writer.writerow(row)<EOL>

Writes a single observation to the output file.

If the ``observation_data`` parameter is a dictionary, it is
converted to a list to keep a consisted field order (as described
in format specification). Otherwise it is assumed that the data
is a raw record ready to be written to file.

:param observation_data: a single observation as a dictionary or list


row = []<EOL>row.append(observation_data['<STR_LIT:name>'])<EOL>row.append(observation_data['<STR_LIT:date>'])<EOL>row.append(observation_data['<STR_LIT>'])<EOL>comment_code = observation_data.get('<STR_LIT>', '<STR_LIT>')<EOL>if not comment_code:<EOL><INDENT>comment_code = '<STR_LIT>'<EOL><DEDENT>row.append(comment_code)<EOL>comp1 = observation_data.get('<STR_LIT>', '<STR_LIT>')<EOL>if not comp1:<EOL><INDENT>comp1 = '<STR_LIT>'<EOL><DEDENT>row.append(comp1)<EOL>comp2 = observation_data.get('<STR_LIT>', '<STR_LIT>')<EOL>if not comp2:<EOL><INDENT>comp2 = '<STR_LIT>'<EOL><DEDENT>row.append(comp2)<EOL>chart = observation_data.get('<STR_LIT>', '<STR_LIT>')<EOL>if not chart:<EOL><INDENT>chart = '<STR_LIT>'<EOL><DEDENT>row.append(chart)<EOL>notes = observation_data.get('<STR_LIT>', '<STR_LIT>')<EOL>if not notes:<EOL><INDENT>notes = '<STR_LIT>'<EOL><DEDENT>row.append(notes)<EOL>return row<EOL>

Takes a dictionary of observation data and converts it to a list
of fields according to AAVSO visual format specification.

:param cls: current class
:param observation_data: a single observation as a dictionary


headers = {}<EOL>for line in fp:<EOL><INDENT>if isinstance(line, bytes):<EOL><INDENT>line = line.decode('<STR_LIT:utf-8>')<EOL><DEDENT>line = line.strip()<EOL>if line and line[<NUM_LIT:0>] == '<STR_LIT:#>' and '<STR_LIT:=>' in line:<EOL><INDENT>header_str = line[<NUM_LIT:1>:]<EOL>key, value = header_str.split('<STR_LIT:=>', <NUM_LIT:1>)<EOL>headers[key] = value<EOL><DEDENT>elif line and line[<NUM_LIT:0>] != '<STR_LIT:#>':<EOL><INDENT>break<EOL><DEDENT><DEDENT>if '<STR_LIT>' not in headers:<EOL><INDENT>raise FormatException('<STR_LIT>')<EOL><DEDENT>try:<EOL><INDENT>self.observer_code = headers['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>raise FormatException('<STR_LIT>')<EOL><DEDENT>try:<EOL><INDENT>self.date_format = headers['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>raise FormatException('<STR_LIT>')<EOL><DEDENT>self.software = headers.get('<STR_LIT>', '<STR_LIT>')<EOL>self.delimiter = str(headers.get('<STR_LIT>', '<STR_LIT:U+002C>'))<EOL>self.obstype = headers.get('<STR_LIT>', '<STR_LIT>')<EOL>data = itertools.chain([line], fp)<EOL>self.reader = csv.reader(data, delimiter=self.delimiter)<EOL>

Creates the reader instance and reads file headers.

Raises :py:exc:`~pyaavso.format.visual.FormatException` when any of
the required headers could not be found in input. The following header
parameters are required:

 * *TYPE* - always 'Visual', yet must be specified in file
 * *OBSCODE* - official AAVSO-assigned observer code
 * *DATE* - date format, must be one of 'JD' or 'Excel'

Other headers described in AAVSO specification have reasonable default
values, eg. the default delimiter is a comma, when not specified
in headers. Without the *OBSTYPE* header, observations are assumed
to be visual.

:param fp: a file-like object from which data will be read


comment_code = row[<NUM_LIT:3>]<EOL>if comment_code.lower() == '<STR_LIT>':<EOL><INDENT>comment_code = '<STR_LIT>'<EOL><DEDENT>comp1 = row[<NUM_LIT:4>]<EOL>if comp1.lower() == '<STR_LIT>':<EOL><INDENT>comp1 = '<STR_LIT>'<EOL><DEDENT>comp2 = row[<NUM_LIT:5>]<EOL>if comp2.lower() == '<STR_LIT>':<EOL><INDENT>comp2 = '<STR_LIT>'<EOL><DEDENT>chart = row[<NUM_LIT:6>]<EOL>if chart.lower() == '<STR_LIT>':<EOL><INDENT>chart = '<STR_LIT>'<EOL><DEDENT>notes = row[<NUM_LIT:7>]<EOL>if notes.lower() == '<STR_LIT>':<EOL><INDENT>notes = '<STR_LIT>'<EOL><DEDENT>return {<EOL>'<STR_LIT:name>': row[<NUM_LIT:0>],<EOL>'<STR_LIT:date>': row[<NUM_LIT:1>],<EOL>'<STR_LIT>': row[<NUM_LIT:2>],<EOL>'<STR_LIT>': comment_code,<EOL>'<STR_LIT>': comp1,<EOL>'<STR_LIT>': comp2,<EOL>'<STR_LIT>': chart,<EOL>'<STR_LIT>': notes,<EOL>}<EOL>

Converts a raw input record to a dictionary of observation data.

:param cls: current class
:param row: a single observation as a list or tuple


return value.replace('<STR_LIT>', '<STR_LIT>').strip()<EOL>

Removes dashes and strips whitespace from the given value.


self.empty = "<STR_LIT>" in html_source<EOL>if not self.empty:<EOL><INDENT>root = html.fromstring(html_source)<EOL>self.tbody = TBODY_XPATH(root)[<NUM_LIT:0>]<EOL><DEDENT>

Creates the parser and feeds it source code of the page.


if self.empty:<EOL><INDENT>return []<EOL><DEDENT>rows = list(self.tbody)<EOL>observations = []<EOL>for row_observation, row_details in zip(rows[::<NUM_LIT:2>], rows[<NUM_LIT:1>::<NUM_LIT:2>]):<EOL><INDENT>data = {}<EOL>cells = OBSERVATION_XPATH(row_observation)<EOL>data['<STR_LIT:name>'] = _clean_cell(cells[<NUM_LIT:0>])<EOL>data['<STR_LIT:date>'] = _clean_cell(cells[<NUM_LIT:1>])<EOL>data['<STR_LIT>'] = _clean_cell(cells[<NUM_LIT:3>])<EOL>data['<STR_LIT>'] = _clean_cell(cells[<NUM_LIT:6>])<EOL>cells = DETAILS_XPATH(row_details)<EOL>data['<STR_LIT>'] = _clean_cell(cells[<NUM_LIT:0>])<EOL>data['<STR_LIT>'] = _clean_cell(cells[<NUM_LIT:3>]).replace('<STR_LIT:None>', '<STR_LIT>')<EOL>data['<STR_LIT>'] = _clean_cell(cells[<NUM_LIT:4>])<EOL>data['<STR_LIT>'] = _clean_cell(cells[<NUM_LIT:5>])<EOL>observations.append(data)<EOL><DEDENT>return observations<EOL>

Parses the HTML table into a list of dictionaries, each of which
represents a single observation.


page_number = <NUM_LIT:1><EOL>observations = []<EOL>while True:<EOL><INDENT>logger.info('<STR_LIT>', page_number)<EOL>response = requests.get(WEBOBS_RESULTS_URL, params={<EOL>'<STR_LIT>': observer_code,<EOL>'<STR_LIT>': <NUM_LIT:200>,<EOL>'<STR_LIT>': '<STR_LIT:all>',<EOL>'<STR_LIT>': page_number,<EOL>})<EOL>logger.debug(response.request.url)<EOL>parser = WebObsResultsParser(response.text)<EOL>observations.extend(parser.get_observations())<EOL>if '<STR_LIT>' not in response.text:<EOL><INDENT>break<EOL><DEDENT>page_number += <NUM_LIT:1><EOL><DEDENT>return observations<EOL>

Downloads all variable star observations by a given observer.

Performs a series of HTTP requests to AAVSO's WebObs search and
downloads the results page by page. Each page is then passed to
:py:class:`~pyaavso.parsers.webobs.WebObsResultsParser` and parse results
are added to the final observation list.


def __init__(self, aws_access_key=None, aws_secret_key=None, table_name=None, schema=None, read_units=None, write_units=None, auto_create_table=True, ):

self.conn = self.get_conn(aws_access_key, aws_secret_key)<EOL>self.table_name = table_name or self.table_name<EOL>self.schema = schema or self.schema<EOL>self.read_units = read_units or self.read_units<EOL>self.write_units = write_units or self.write_units<EOL>self.auto_create_table = auto_create_table<EOL>super(CounterPool, self).__init__()<EOL>

:aws_access_key:
    AWS Acccess Key ID with permissions to use DynamoDB
:aws_secret_key:
    AWS Access Secret Key for the given Access Key ID
:table_name:
    The DynamoDB table that should be used to store this pool's
    counters.  See http://bit.ly/DynamoDBModel for details on
    DynamoDB's data model.
:schema:
    The schema that will be used to create a table if one does not
    already exist.  See the `boto`<http://bit.ly/BotoCreateTable>_
    docs for details on what's expected for a schema.
:read_units:
    Read throughput to be set when a table is created.  See
    http://bit.ly/DynamoThoughput for details on Dynamo's provisioned
    throughput system.
:write_units:
    Write throughput to be set when a table is created.
:auto_create_table:
    Should Albertson create a dynamodb table if the provided
    `table_name` doesn't exist.


def get_conn(self, aws_access_key=None, aws_secret_key=None):

return boto.connect_dynamodb(<EOL>aws_access_key_id=aws_access_key,<EOL>aws_secret_access_key=aws_secret_key,<EOL>)<EOL>

Hook point for overriding how the CounterPool gets its connection to
AWS.


if not self.table_name:<EOL><INDENT>raise NotImplementedError(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>return self.table_name<EOL>

Hook point for overriding how the CounterPool determines the table name
to use.


if not self.schema:<EOL><INDENT>raise NotImplementedError(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>return self.conn.create_schema(**self.schema)<EOL>

Hook point for overriding how the CounterPool determines the schema
to be used when creating a missing table.


return self.read_units<EOL>

Hook point for overriding how the CounterPool determines the read
throughput units to set on a newly created table.


return self.write_units<EOL>

Hook point for overriding how the CounterPool determines the write
throughput units to set on a newly created table.


table = self.conn.create_table(<EOL>name=self.get_table_name(),<EOL>schema=self.get_schema(),<EOL>read_units=self.get_read_units(),<EOL>write_units=self.get_write_units(),<EOL>)<EOL>if table.status != '<STR_LIT>':<EOL><INDENT>table.refresh(wait_for_active=True, retry_seconds=<NUM_LIT:1>)<EOL><DEDENT>return table<EOL>

Hook point for overriding how the CounterPool creates a new table
in DynamooDB


if hasattr(self, '<STR_LIT>'):<EOL><INDENT>table = self._table<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>table = self.conn.get_table(self.get_table_name())<EOL><DEDENT>except boto.exception.DynamoDBResponseError:<EOL><INDENT>if self.auto_create_table:<EOL><INDENT>table = self.create_table()<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>self._table = table<EOL><DEDENT>return table<EOL>

Hook point for overriding how the CounterPool transforms table_name
into a boto DynamoDB Table object.