Repository: projectmesa/mesa

Issue:
No public version of NetworkGrid._remove_agent, though code exists


Currently it is not possible to remove an Agent from a NetworkGrid using a **public** function. Currently, you can do the following:

```python
...
model.grid = NetworkGrid(G)
...
a = Agent(...)
model.grid._remove_agent(a, a.pos)
...
```
But this function is a private function, therefore it isn't shown in documentation or in your editor. I'd like to be able to remove agents like with the other space modules.


**Describe the solution you'd like**
I'd like a similar solution as used for the other space modules:

Solution in space.Grid:
```python
def remove_agent(self, agent: Agent) -> None:  # solution in space.Grid
        """ Remove the agent from the grid and set its pos variable to None. """
        pos = agent.pos
        self._remove_agent(pos, agent)
        agent.pos = None

```
Solution for NetworkGrid:
```python
def remove_agent(self, agent: Agent) -> None:  # New solution
        """ Remove the agent from the network and set its pos variable to None. """
        pos = agent.pos
        self._remove_agent(agent, pos)
        agent.pos = None

```

**Additional context**
The _remove_agent function in NetworkGrid
```python
def _remove_agent(self, agent: Agent, node_id: int) -> None:
        """ Remove an agent from a node. """

        self.G.nodes[node_id]["agent"].remove(agent)
```

Comments:

Patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index 315c12f..f67babe 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -3,6 +3,14 @@
 Release History
 ---------------
 
+
+0.8.9 (TBD) Oro Valley
++++++++++++++++++++++++++++++++++++++++++++
+
+*Note: Master branch was renamed to Main on 03/13/2021*
+
+
+
 0.8.8 (2020-11-27) Nogales
 +++++++++++++++++++++++++++++++++++++++++++
 
diff --git a/mesa/space.py b/mesa/space.py
index 37716c5..2544d75 100644
--- a/mesa/space.py
+++ b/mesa/space.py
@@ -950,6 +950,12 @@ class NetworkGrid:
 
         self.G.nodes[node_id]["agent"].remove(agent)
 
+    def remove_agent(self, agent: Agent) -> None:
+        """ Remove the agent from the network and set its pos variable to None. """
+        pos = agent.pos
+        self._remove_agent(agent, pos)
+        agent.pos = None
+
     def is_cell_empty(self, node_id: int) -> bool:
         """ Returns a bool of the contents of a cell. """
         return not self.G.nodes[node_id]["agent"]


Test patch:
diff --git a/tests/test_space.py b/tests/test_space.py
index d9f1017..38520b3 100644
--- a/tests/test_space.py
+++ b/tests/test_space.py
@@ -357,6 +357,15 @@ class TestSingleNetworkGrid(unittest.TestCase):
         assert _agent not in self.space.G.nodes[initial_pos]["agent"]
         assert _agent in self.space.G.nodes[final_pos]["agent"]
 
+    def test_remove_agent(self):
+        for i, pos in enumerate(TEST_AGENTS_NETWORK_SINGLE):
+            a = self.agents[i]
+            assert a.pos == pos
+            assert a in self.space.G.nodes[pos]["agent"]
+            self.space.remove_agent(a)
+            assert a.pos is None
+            assert a not in self.space.G.nodes[pos]["agent"]
+
     def test_is_cell_empty(self):
         assert not self.space.is_cell_empty(0)
         assert self.space.is_cell_empty(TestSingleNetworkGrid.GRAPH_SIZE - 1)