コード例 #1
0
    def test_add_and_discard(self):
        numbers = OrderedSet([1, 2, 3])
        numbers.add(3)
        self.assertEqual(len(numbers), 3)
        numbers.add(4)
        self.assertEqual(len(numbers), 4)
        numbers.discard(4)
        self.assertEqual(len(numbers), 3)
        numbers.discard(4)
        self.assertEqual(len(numbers), 3)

        # Make sure the add method is efficient too!
        setup = "numbers = OrderedSet([])"
        time = partial(timeit, setup=setup, globals=globals(), number=100)
        small_set_time = time(
            dedent("""
            add = numbers.add
            for n in [9999 for _ in range(1000)]:
                add(n)
        """))
        large_set_time = time(
            dedent("""
            add = numbers.add
            for n in [9999 + i for i in range(1000)]:
                add(n)
        """))
        self.assertGreater(small_set_time * 30, large_set_time)
コード例 #2
0
 def test_add_and_discard(self):
     numbers = OrderedSet([1, 2, 3])
     numbers.add(3)
     self.assertEqual(len(numbers), 3)
     numbers.add(4)
     self.assertEqual(len(numbers), 4)
     numbers.discard(4)
     self.assertEqual(len(numbers), 3)
     numbers.discard(4)
     self.assertEqual(len(numbers), 3)
コード例 #3
0
    class __TransactionSet:
        def __init__(self):
            """Initialize transaction store."""
            self.store = OrderedSet()

        def add(self, transaction):
            self.store.add(transaction)

        def add_multiple(self, transaction_list):
            """Add multiple transactions to the set.

            Since the transactions are re-added to the set (they were in it once),
            we add them at the front of the existing set.
            """
            transaction_list = OrderedSet(transaction_list)
            self.store = transaction_list.union(self.store)

        def contains(self, transaction):
            return self.store.__contains__(transaction)

        def pop(self):
            """Remove and return a transaction from the set."""
            try:
                return self.store.pop(0)
            # Catch KeyError if set is empty
            except KeyError:
                return None

        def discard(self, transaction):
            """Remove the transaction if it was present in the set."""
            self.store.discard(transaction)

        def discard_multiple(self, transaction_list):
            """Remove multiple transactions from the set."""
            [self.discard(tx) for tx in transaction_list]

        def clear(self):
            """Remove all transactions from the set."""
            self.store.clear()

        def __len__(self):
            return len(self.store)

        def __iter__(self):
            yield from self.store

        def __repr__(self):
            return self.store.__repr__()
コード例 #4
0
    def test_add_and_discard(self):
        numbers = OrderedSet([1, 2, 3])
        numbers.add(3)
        self.assertEqual(len(numbers), 3)
        numbers.add(4)
        self.assertEqual(len(numbers), 4)
        numbers.discard(4)
        self.assertEqual(len(numbers), 3)
        numbers.discard(4)
        self.assertEqual(len(numbers), 3)

        # Make sure the add method is efficient too!
        with Timer() as small_set_timer:
            numbers = OrderedSet([])
            for n in [9999 for _ in range(2000)]:
                numbers.add(n)
        with Timer() as large_set_timer:
            numbers2 = OrderedSet([])
            for n in [9999 + i for i in range(2000)]:
                numbers2.add(n)
コード例 #5
0
class Simulation:
    """Agent-based simulation."""

    time: Timestamp
    agents: Set[TrafficDynamicAgent]
    active: Set[TrafficDynamicAgent]
    ready_buffer: int
    _queue: Deque[Tuple[Callable, Tuple]]
    _listeners = List[Listener]

    def __init__(self):
        self.time = 0
        self.agents = OrderedSet()
        self.active = OrderedSet()
        self.ready_buffer = 0
        self._queue = deque()
        self._listeners = []

    @property
    def target_buffer(self) -> int:
        """Get index of current target buffer."""
        return (self.ready_buffer + 1) % 2

    def add(self, agent: TrafficDynamicAgent):
        """Add agent to the simulation."""
        self.agents.add(agent)
        self.update_active_set(agent)
        self.raise_event('new_agent')

    def update(self, dt: Duration):
        """Update the simulation with time step of `dt`."""
        ready = self.ready_buffer
        target = (ready + 1) % 2

        for agent in self.active:
            agent.update(dt, ready, target)

        while self._queue:
            callable_, args = self._queue.popleft()
            callable_(*args)

        old_time = self.time
        self.time += dt
        self.flip_buffer()
        self.raise_event('simulation_step', dt)
        self._check_time_events(old_time)

    def _check_time_events(self, old_time: Timestamp):
        """Raise time events when appropriate."""
        old_time, time = floor(old_time), floor(self.time)
        if old_time == time:
            return
        self.raise_event('passed_second')

        for timespan, event in TIME_EVENTS:
            if old_time // timespan == time // timespan:
                return
            self.raise_event(event)

    def flip_buffer(self):
        """Flip ready buffer index."""
        self.ready_buffer = self.target_buffer

    def update_active_set(self, agent: TrafficDynamicAgent):
        """Activate or deactivate agent according to its `active` attribute.

        When an agent is activated or deactivated during update, this should be
        called instead of adding or removing directly from the active set,
        because the set is being iterated and cannot change during iteration.
        """
        def _update_active_set():
            if agent.active:
                self.active.add(agent)
            else:
                self.active.discard(agent)

        self.enqueue(_update_active_set)
        self.raise_event('active_set_updated')

    def remove(self, agent: TrafficDynamicAgent):
        """Remove agent from simulation."""
        if agent in self.agents:
            self.agents.remove(agent)
            self.raise_event('removed_agent', agent)

    def enqueue(self, callable_: Callable, args: Tuple = ()):
        """Enqueue function to be called after update loop ends."""
        self._queue.append((callable_, args))

    def register_listener(self, listener: Listener):
        """Register listener to receive raised events."""
        if listener not in self._listeners:
            self._listeners.append(listener)

    def raise_event(self, name: str, *args):
        """Raise event to all registered listeners."""
        for listener in self._listeners:
            listener(name, *args)
コード例 #6
0
class GraphBase(object):
    __metaclass__ = ABCMeta

    def __init__(self, name, master, namespace):
        assert isinstance(name, str)
        assert isinstance(master, Master)
        assert isinstance(namespace, GraphNamespaceMixin)

        self.name = "g"+name
        self.master = master
        self.namespace = namespace

        self.start_nodes = OrderedSet()
        self.end_nodes = OrderedSet()
        self.nodes = OrderedSet()
        self.edges = OrderedSet()

    def __repr_marks__(self):
        return ""

    def __repr__(self):
        return ("<%s#%s: %d(%d,%d) nodes, %d edges, in %s%s>"
                    % (self.__class__.__name__,
                       self.name,
                       len(self.nodes),
                       len(self.start_nodes),
                       len(self.end_nodes),
                       len(self.edges),
                       self.namespace.ns_name,
                       self.__repr_marks__()))

    def __str_parsenode__(self, node, included, ret_str):
        assert isinstance(node, NodeBase)
        assert isinstance(included, set)
        assert isinstance(ret_str, str)
        if node in included:
            return ret_str
        assert node.graph is self
        included.add(node)
        # print node
        blank = [" ", " "]
        if node.is_start:
            blank[0] = "+"
        if node.is_end:
            blank[1] = "-"
        ret_str += "\n%s%s" %("".join(blank), node.__repr_graph__())
        # print edge
        for edge in node.edges:
            assert edge.graph is self
            ret_str += "\n    %s" % edge.__repr_graph__()
        # recursive
        for edge in node.edges:
            ret_str = self.__str_parsenode__(edge.node, included, ret_str)
        return ret_str

    def __str__(self):
        ret_str = "%r:" % self

        included = set()
        for sn in self.start_nodes:
            ret_str = self.__str_parsenode__(sn, included, ret_str)
        if included-self.nodes:
            ret_str += "\nERROR EXTRA NODES: " +\
                    ",".join(n.name for n in included-self.nodes)
        if self.nodes-included:
            ret_str += "\nERROR UNSEEN NODES: " +\
                    ",".join(n.name for n in self.nodes-included)

        return ret_str

    @abstractmethod
    def _create_node_override(self, id_):
        pass

    @abstractmethod
    def _create_edge_override(self, to_node, payload):
        pass

    def create_edge_withnode(self, to_node, payload):
        assert isinstance(to_node, NodeBase)
        assert to_node.graph is self
        edge = self._create_edge_override(to_node, payload)
        self.edges.add(edge)
        return edge

    def create_edge_withnid(self, tonode_id, payload):
        to_node = self._create_node_override(tonode_id)
        self.nodes.add(to_node)

        edge = self.create_edge_withnode(to_node, payload)
        self.end_nodes.add(to_node)
        return edge, to_node

    def register_edge(self, from_node, edge):
        assert from_node in self.nodes
        assert edge in self.edges
        self.namespace._ns_register_edge(from_node, edge)
        self.end_nodes.discard(from_node)