We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Minor docstring clean-up needed on time.py and batchrunner.py
A couple of typos and minor content edit items for the two files.

Minor docstring clean-up needed on time.py and batchrunner.py
A couple of typos and minor content edit items for the two files.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mesa/batchrunner.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 Batchrunner
4 ===========
5 
6 A single class to manage a batch run or parameter sweep of a given model.
7 
8 """
9 from itertools import product
10 import pandas as pd
11 
12 
13 class BatchRunner:
14     """ This class is instantiated with a model class, and model parameters
15     associated with one or more values. It is also instantiated with model- and
16     agent-level reporters, dictionaries mapping a variable name to a function
17     which collects some data from the model or its agents at the end of the run
18     and stores it.
19 
20     Note that by default, the reporters only collect data at the *end* of the
21     run. To get step by step data, simply have a reporter store the model's
22     entire DataCollector object.
23 
24     """
25     def __init__(self, model_cls, parameter_values, iterations=1,
26                  max_steps=1000, model_reporters=None, agent_reporters=None):
27         """ Create a new BatchRunner for a given model with the given
28         parameters.
29 
30         Args:
31             model_cls: The class of model to batch-run.
32             parameter_values: Dictionary of parameters to their values or
33                 ranges of values. For example:
34                     {"param_1": range(5),
35                      "param_2": [1, 5, 10],
36                       "const_param": 100}
37             iterations: How many times to run the model at each combination of
38                 parameters.
39             max_steps: After how many steps to halt each run if it hasn't
40                 halted on its own.
41             model_reporters: Dictionary of variables to collect on each run at
42                 the end, with variable names mapped to a function to collect
43                 them. For example:
44                     {"agent_count": lambda m: m.schedule.get_agent_count()}
45             agent_reporters: Like model_reporters, but each variable is now
46                 collected at the level of each agent present in the model at
47                 the end of the run.
48 
49         """
50         self.model_cls = model_cls
51         self.parameter_values = {param: self.make_iterable(vals)
52                                  for param, vals in parameter_values.items()}
53         self.iterations = iterations
54         self.max_steps = max_steps
55 
56         self.model_reporters = model_reporters
57         self.agent_reporters = agent_reporters
58 
59         if self.model_reporters:
60             self.model_vars = {}
61 
62         if self.agent_reporters:
63             self.agent_vars = {}
64 
65     def run_all(self):
66         """ Run the model at all parameter combinations and store results. """
67         params = self.parameter_values.keys()
68         param_ranges = self.parameter_values.values()
69         run_count = 0
70         for param_values in list(product(*param_ranges)):
71             kwargs = dict(zip(params, param_values))
72             for _ in range(self.iterations):
73                 model = self.model_cls(**kwargs)
74                 self.run_model(model)
75                 # Collect and store results:
76                 if self.model_reporters:
77                     key = tuple(list(param_values) + [run_count])
78                     self.model_vars[key] = self.collect_model_vars(model)
79                 if self.agent_reporters:
80                     agent_vars = self.collect_agent_vars(model)
81                     for agent_id, reports in agent_vars.items():
82                         key = tuple(list(param_values) + [run_count, agent_id])
83                         self.agent_vars[key] = reports
84                 run_count += 1
85 
86     def run_model(self, model):
87         """ Run a model object to completion, or until reaching max steps.
88 
89         If your model runs in a non-standard way, this is the method to modify
90         in your subclass.
91 
92         """
93         while model.running and model.schedule.steps < self.max_steps:
94             model.step()
95 
96     def collect_model_vars(self, model):
97         """ Run reporters and collect model-level variables. """
98         model_vars = {}
99         for var, reporter in self.model_reporters.items():
100             model_vars[var] = reporter(model)
101         return model_vars
102 
103     def collect_agent_vars(self, model):
104         """ Run reporters and collect agent-level variables. """
105         agent_vars = {}
106         for agent in model.schedule.agents:
107             agent_record = {}
108             for var, reporter in self.agent_reporters.items():
109                 agent_record[var] = reporter(agent)
110             agent_vars[agent.unique_id] = agent_record
111         return agent_vars
112 
113     def get_model_vars_dataframe(self):
114         """ Generate a pandas DataFrame from the model-level collected
115         variables.
116 
117         """
118         index_col_names = list(self.parameter_values.keys())
119         index_col_names.append("Run")
120         records = []
121         for key, val in self.model_vars.items():
122             record = dict(zip(index_col_names, key))
123             for k, v in val.items():
124                 record[k] = v
125             records.append(record)
126         return pd.DataFrame(records)
127 
128     def get_agent_vars_dataframe(self):
129         """ Generate a pandas DataFrame from the agent-level variables
130         collected.
131 
132         """
133         index_col_names = list(self.parameter_values.keys())
134         index_col_names += ["Run", "AgentID"]
135         records = []
136         for key, val in self.agent_vars.items():
137             record = dict(zip(index_col_names, key))
138             for k, v in val.items():
139                 record[k] = v
140             records.append(record)
141         return pd.DataFrame(records)
142 
143     @staticmethod
144     def make_iterable(val):
145         """ Helper method to ensure a value is a non-string iterable. """
146         if hasattr(val, "__iter__") and not isinstance(val, str):
147             return val
148         else:
149             return [val]
150
```

Path: `mesa/time.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 Mesa Time Module
4 ================
5 
6 Objects for handling the time component of a model. In particular, this module
7 contains Schedulers, which handle agent activation. A Scheduler is an object
8 which controls when agents are called upon to act, and when.
9 
10 The activation order can have a serious impact on model behavior, so it's
11 important to specify it explicity. Example simple activation regimes include
12 activating all agents in the same order every step, shuffling the activation
13 order every time, activating each agent *on average* once per step, and more.
14 
15 Key concepts:
16     Step: Many models advance in 'steps'. A step may involve the activation of
17     all agents, or a random (or selected) subset of them. Each agent in turn
18     may have their own step() method.
19 
20     Time: Some models may simulate a continuous 'clock' instead of discrete
21     steps. However, by default, the Time is equal to the number of steps the
22     model has taken.
23 
24 
25 TODO: Have the schedulers use the model's randomizer, to keep random number
26 seeds consistent and allow for replication.
27 
28 """
29 import random
30 
31 
32 class BaseScheduler:
33     """ Simplest scheduler; activates agents one at a time, in the order
34     they were added.
35 
36     Assumes that each agent added has a *step* method, which accepts a model
37     object as its single argument.
38 
39     (This is explicitly meant to replicate the scheduler in MASON).
40 
41     """
42     model = None
43     steps = 0
44     time = 0
45     agents = []
46 
47     def __init__(self, model):
48         """ Create a new, empty BaseScheduler. """
49         self.model = model
50         self.steps = 0
51         self.time = 0
52         self.agents = []
53 
54     def add(self, agent):
55         """ Add an Agent object to the schedule.
56 
57         Args:
58             agent: An Agent to be added to the schedule. NOTE: The agent must
59             have a step(model) method.
60 
61         """
62         self.agents.append(agent)
63 
64     def remove(self, agent):
65         """ Remove all instances of a given agent from the schedule.
66 
67         Args:
68             agent: An agent object.
69 
70         """
71         while agent in self.agents:
72             self.agents.remove(agent)
73 
74     def step(self):
75         """ Execute the step of all the agents, one at a time. """
76         for agent in self.agents:
77             agent.step(self.model)
78         self.steps += 1
79         self.time += 1
80 
81     def get_agent_count(self):
82         """ Returns the current number of agents in the queue. """
83         return len(self.agents)
84 
85 
86 class RandomActivation(BaseScheduler):
87     """ A scheduler which activates each agent once per step, in random order,
88     with the order reshuffled every step.
89 
90     This is equivalent to the NetLogo 'ask agents...' and is generally the
91     default behavior for an ABM.
92 
93     Assumes that all agents have a step(model) method.
94 
95     """
96     def step(self):
97         """ Executes the step of all agents, one at a time, in
98         random order.
99 
100         """
101         random.shuffle(self.agents)
102 
103         for agent in self.agents:
104             agent.step(self.model)
105         self.steps += 1
106         self.time += 1
107 
108 
109 class SimultaneousActivation(BaseScheduler):
110     """ A scheduler to simulate the simultaneous activation of all the agents.
111 
112     This scheduler requires that each agent have two methods: step and advance.
113     step(model) activates the agent and stages any necessary changes, but does
114     not apply them yet. advance(model) then applies the changes.
115 
116     """
117     def step(self):
118         """ Step all agents, then advance them. """
119         for agent in self.agents:
120             agent.step(self.model)
121         for agent in self.agents:
122             agent.advance(self.model)
123         self.steps += 1
124         self.time += 1
125 
126 
127 class StagedActivation(BaseScheduler):
128     """ A scheduler which allows agent activation to be divided into several
129     stages instead of a single `step` method. All agents execute one stage
130     before moving on to the next.
131 
132     Agents must have all the stage methods implemented. Stage methods take a
133     model object as their only argument.
134 
135     This schedule tracks steps and time separately. Time advances in fractional
136     increments of 1 / (# of stages), meaning that 1 step = 1 unit of time.
137 
138     """
139     stage_list = []
140     shuffle = False
141     shuffle_between_stages = False
142     stage_time = 1
143 
144     def __init__(self, model, stage_list=["step"], shuffle=False,
145                  shuffle_between_stages=False):
146         """ Create an empty Staged Activation schedule.
147 
148         Args:
149             model: Model object associated with the schedule.
150             stage_list: List of strings of names of stages to run, in the
151                          order to run them in.
152             shuffle: If True, shuffle the order of agents each step.
153             shuffle_between_stages: If True, shuffle the agents after each
154                                     stage; otherwise, only shuffle at the start
155                                     of each step.
156 
157         """
158         super().__init__(model)
159         self.stage_list = stage_list
160         self.shuffle = shuffle
161         self.shuffle_between_stages = shuffle_between_stages
162         self.stage_time = 1 / len(self.stage_list)
163 
164     def step(self):
165         """ Executes all the stages of all agents. """
166         if self.shuffle:
167             random.shuffle(self.agents)
168         for stage in self.stage_list:
169             for agent in self.agents:
170                 getattr(agent, stage)(self.model)  # Run stage
171             if self.shuffle_between_stages:
172                 random.shuffle(self.agents)
173             self.time += self.stage_time
174 
175         self.steps += 1
176
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mesa/batchrunner.py b/mesa/batchrunner.py
--- a/mesa/batchrunner.py
+++ b/mesa/batchrunner.py
@@ -12,7 +12,7 @@
 
 class BatchRunner:
     """ This class is instantiated with a model class, and model parameters
-    associated with one or more values. It is also instantiated with model- and
+    associated with one or more values. It is also instantiated with model and
     agent-level reporters, dictionaries mapping a variable name to a function
     which collects some data from the model or its agents at the end of the run
     and stores it.
@@ -34,11 +34,11 @@
                     {"param_1": range(5),
                      "param_2": [1, 5, 10],
                       "const_param": 100}
-            iterations: How many times to run the model at each combination of
-                parameters.
-            max_steps: After how many steps to halt each run if it hasn't
-                halted on its own.
-            model_reporters: Dictionary of variables to collect on each run at
+            iterations: The total number of times to run the model for each
+                combination of parameters.
+            max_steps: The upper limit of steps above which each run will be halted
+                if it hasn't halted on its own.
+            model_reporters: The dictionary of variables to collect on each run at
                 the end, with variable names mapped to a function to collect
                 them. For example:
                     {"agent_count": lambda m: m.schedule.get_agent_count()}
@@ -111,8 +111,7 @@
         return agent_vars
 
     def get_model_vars_dataframe(self):
-        """ Generate a pandas DataFrame from the model-level collected
-        variables.
+        """ Generate a pandas DataFrame from the model-level variables collected.
 
         """
         index_col_names = list(self.parameter_values.keys())
diff --git a/mesa/time.py b/mesa/time.py
--- a/mesa/time.py
+++ b/mesa/time.py
@@ -8,7 +8,7 @@
 which controls when agents are called upon to act, and when.
 
 The activation order can have a serious impact on model behavior, so it's
-important to specify it explicity. Example simple activation regimes include
+important to specify it explicitly. Example simple activation regimes include
 activating all agents in the same order every step, shuffling the activation
 order every time, activating each agent *on average* once per step, and more.
 
@@ -162,7 +162,7 @@
         self.stage_time = 1 / len(self.stage_list)
 
     def step(self):
-        """ Executes all the stages of all agents. """
+        """ Executes all the stages for all agents. """
         if self.shuffle:
             random.shuffle(self.agents)
         for stage in self.stage_list:

{"golden_diff": "diff --git a/mesa/batchrunner.py b/mesa/batchrunner.py\n--- a/mesa/batchrunner.py\n+++ b/mesa/batchrunner.py\n@@ -12,7 +12,7 @@\n \n class BatchRunner:\n     \"\"\" This class is instantiated with a model class, and model parameters\n-    associated with one or more values. It is also instantiated with model- and\n+    associated with one or more values. It is also instantiated with model and\n     agent-level reporters, dictionaries mapping a variable name to a function\n     which collects some data from the model or its agents at the end of the run\n     and stores it.\n@@ -34,11 +34,11 @@\n                     {\"param_1\": range(5),\n                      \"param_2\": [1, 5, 10],\n                       \"const_param\": 100}\n-            iterations: How many times to run the model at each combination of\n-                parameters.\n-            max_steps: After how many steps to halt each run if it hasn't\n-                halted on its own.\n-            model_reporters: Dictionary of variables to collect on each run at\n+            iterations: The total number of times to run the model for each\n+                combination of parameters.\n+            max_steps: The upper limit of steps above which each run will be halted\n+                if it hasn't halted on its own.\n+            model_reporters: The dictionary of variables to collect on each run at\n                 the end, with variable names mapped to a function to collect\n                 them. For example:\n                     {\"agent_count\": lambda m: m.schedule.get_agent_count()}\n@@ -111,8 +111,7 @@\n         return agent_vars\n \n     def get_model_vars_dataframe(self):\n-        \"\"\" Generate a pandas DataFrame from the model-level collected\n-        variables.\n+        \"\"\" Generate a pandas DataFrame from the model-level variables collected.\n \n         \"\"\"\n         index_col_names = list(self.parameter_values.keys())\ndiff --git a/mesa/time.py b/mesa/time.py\n--- a/mesa/time.py\n+++ b/mesa/time.py\n@@ -8,7 +8,7 @@\n which controls when agents are called upon to act, and when.\n \n The activation order can have a serious impact on model behavior, so it's\n-important to specify it explicity. Example simple activation regimes include\n+important to specify it explicitly. Example simple activation regimes include\n activating all agents in the same order every step, shuffling the activation\n order every time, activating each agent *on average* once per step, and more.\n \n@@ -162,7 +162,7 @@\n         self.stage_time = 1 / len(self.stage_list)\n \n     def step(self):\n-        \"\"\" Executes all the stages of all agents. \"\"\"\n+        \"\"\" Executes all the stages for all agents. \"\"\"\n         if self.shuffle:\n             random.shuffle(self.agents)\n         for stage in self.stage_list:\n", "issue": "Minor docstring clean-up needed on time.py and batchrunner.py\nA couple of typos and minor content edit items for the two files.\n\nMinor docstring clean-up needed on time.py and batchrunner.py\nA couple of typos and minor content edit items for the two files.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nBatchrunner\n===========\n\nA single class to manage a batch run or parameter sweep of a given model.\n\n\"\"\"\nfrom itertools import product\nimport pandas as pd\n\n\nclass BatchRunner:\n    \"\"\" This class is instantiated with a model class, and model parameters\n    associated with one or more values. It is also instantiated with model- and\n    agent-level reporters, dictionaries mapping a variable name to a function\n    which collects some data from the model or its agents at the end of the run\n    and stores it.\n\n    Note that by default, the reporters only collect data at the *end* of the\n    run. To get step by step data, simply have a reporter store the model's\n    entire DataCollector object.\n\n    \"\"\"\n    def __init__(self, model_cls, parameter_values, iterations=1,\n                 max_steps=1000, model_reporters=None, agent_reporters=None):\n        \"\"\" Create a new BatchRunner for a given model with the given\n        parameters.\n\n        Args:\n            model_cls: The class of model to batch-run.\n            parameter_values: Dictionary of parameters to their values or\n                ranges of values. For example:\n                    {\"param_1\": range(5),\n                     \"param_2\": [1, 5, 10],\n                      \"const_param\": 100}\n            iterations: How many times to run the model at each combination of\n                parameters.\n            max_steps: After how many steps to halt each run if it hasn't\n                halted on its own.\n            model_reporters: Dictionary of variables to collect on each run at\n                the end, with variable names mapped to a function to collect\n                them. For example:\n                    {\"agent_count\": lambda m: m.schedule.get_agent_count()}\n            agent_reporters: Like model_reporters, but each variable is now\n                collected at the level of each agent present in the model at\n                the end of the run.\n\n        \"\"\"\n        self.model_cls = model_cls\n        self.parameter_values = {param: self.make_iterable(vals)\n                                 for param, vals in parameter_values.items()}\n        self.iterations = iterations\n        self.max_steps = max_steps\n\n        self.model_reporters = model_reporters\n        self.agent_reporters = agent_reporters\n\n        if self.model_reporters:\n            self.model_vars = {}\n\n        if self.agent_reporters:\n            self.agent_vars = {}\n\n    def run_all(self):\n        \"\"\" Run the model at all parameter combinations and store results. \"\"\"\n        params = self.parameter_values.keys()\n        param_ranges = self.parameter_values.values()\n        run_count = 0\n        for param_values in list(product(*param_ranges)):\n            kwargs = dict(zip(params, param_values))\n            for _ in range(self.iterations):\n                model = self.model_cls(**kwargs)\n                self.run_model(model)\n                # Collect and store results:\n                if self.model_reporters:\n                    key = tuple(list(param_values) + [run_count])\n                    self.model_vars[key] = self.collect_model_vars(model)\n                if self.agent_reporters:\n                    agent_vars = self.collect_agent_vars(model)\n                    for agent_id, reports in agent_vars.items():\n                        key = tuple(list(param_values) + [run_count, agent_id])\n                        self.agent_vars[key] = reports\n                run_count += 1\n\n    def run_model(self, model):\n        \"\"\" Run a model object to completion, or until reaching max steps.\n\n        If your model runs in a non-standard way, this is the method to modify\n        in your subclass.\n\n        \"\"\"\n        while model.running and model.schedule.steps < self.max_steps:\n            model.step()\n\n    def collect_model_vars(self, model):\n        \"\"\" Run reporters and collect model-level variables. \"\"\"\n        model_vars = {}\n        for var, reporter in self.model_reporters.items():\n            model_vars[var] = reporter(model)\n        return model_vars\n\n    def collect_agent_vars(self, model):\n        \"\"\" Run reporters and collect agent-level variables. \"\"\"\n        agent_vars = {}\n        for agent in model.schedule.agents:\n            agent_record = {}\n            for var, reporter in self.agent_reporters.items():\n                agent_record[var] = reporter(agent)\n            agent_vars[agent.unique_id] = agent_record\n        return agent_vars\n\n    def get_model_vars_dataframe(self):\n        \"\"\" Generate a pandas DataFrame from the model-level collected\n        variables.\n\n        \"\"\"\n        index_col_names = list(self.parameter_values.keys())\n        index_col_names.append(\"Run\")\n        records = []\n        for key, val in self.model_vars.items():\n            record = dict(zip(index_col_names, key))\n            for k, v in val.items():\n                record[k] = v\n            records.append(record)\n        return pd.DataFrame(records)\n\n    def get_agent_vars_dataframe(self):\n        \"\"\" Generate a pandas DataFrame from the agent-level variables\n        collected.\n\n        \"\"\"\n        index_col_names = list(self.parameter_values.keys())\n        index_col_names += [\"Run\", \"AgentID\"]\n        records = []\n        for key, val in self.agent_vars.items():\n            record = dict(zip(index_col_names, key))\n            for k, v in val.items():\n                record[k] = v\n            records.append(record)\n        return pd.DataFrame(records)\n\n    @staticmethod\n    def make_iterable(val):\n        \"\"\" Helper method to ensure a value is a non-string iterable. \"\"\"\n        if hasattr(val, \"__iter__\") and not isinstance(val, str):\n            return val\n        else:\n            return [val]\n", "path": "mesa/batchrunner.py"}, {"content": "# -*- coding: utf-8 -*-\n\"\"\"\nMesa Time Module\n================\n\nObjects for handling the time component of a model. In particular, this module\ncontains Schedulers, which handle agent activation. A Scheduler is an object\nwhich controls when agents are called upon to act, and when.\n\nThe activation order can have a serious impact on model behavior, so it's\nimportant to specify it explicity. Example simple activation regimes include\nactivating all agents in the same order every step, shuffling the activation\norder every time, activating each agent *on average* once per step, and more.\n\nKey concepts:\n    Step: Many models advance in 'steps'. A step may involve the activation of\n    all agents, or a random (or selected) subset of them. Each agent in turn\n    may have their own step() method.\n\n    Time: Some models may simulate a continuous 'clock' instead of discrete\n    steps. However, by default, the Time is equal to the number of steps the\n    model has taken.\n\n\nTODO: Have the schedulers use the model's randomizer, to keep random number\nseeds consistent and allow for replication.\n\n\"\"\"\nimport random\n\n\nclass BaseScheduler:\n    \"\"\" Simplest scheduler; activates agents one at a time, in the order\n    they were added.\n\n    Assumes that each agent added has a *step* method, which accepts a model\n    object as its single argument.\n\n    (This is explicitly meant to replicate the scheduler in MASON).\n\n    \"\"\"\n    model = None\n    steps = 0\n    time = 0\n    agents = []\n\n    def __init__(self, model):\n        \"\"\" Create a new, empty BaseScheduler. \"\"\"\n        self.model = model\n        self.steps = 0\n        self.time = 0\n        self.agents = []\n\n    def add(self, agent):\n        \"\"\" Add an Agent object to the schedule.\n\n        Args:\n            agent: An Agent to be added to the schedule. NOTE: The agent must\n            have a step(model) method.\n\n        \"\"\"\n        self.agents.append(agent)\n\n    def remove(self, agent):\n        \"\"\" Remove all instances of a given agent from the schedule.\n\n        Args:\n            agent: An agent object.\n\n        \"\"\"\n        while agent in self.agents:\n            self.agents.remove(agent)\n\n    def step(self):\n        \"\"\" Execute the step of all the agents, one at a time. \"\"\"\n        for agent in self.agents:\n            agent.step(self.model)\n        self.steps += 1\n        self.time += 1\n\n    def get_agent_count(self):\n        \"\"\" Returns the current number of agents in the queue. \"\"\"\n        return len(self.agents)\n\n\nclass RandomActivation(BaseScheduler):\n    \"\"\" A scheduler which activates each agent once per step, in random order,\n    with the order reshuffled every step.\n\n    This is equivalent to the NetLogo 'ask agents...' and is generally the\n    default behavior for an ABM.\n\n    Assumes that all agents have a step(model) method.\n\n    \"\"\"\n    def step(self):\n        \"\"\" Executes the step of all agents, one at a time, in\n        random order.\n\n        \"\"\"\n        random.shuffle(self.agents)\n\n        for agent in self.agents:\n            agent.step(self.model)\n        self.steps += 1\n        self.time += 1\n\n\nclass SimultaneousActivation(BaseScheduler):\n    \"\"\" A scheduler to simulate the simultaneous activation of all the agents.\n\n    This scheduler requires that each agent have two methods: step and advance.\n    step(model) activates the agent and stages any necessary changes, but does\n    not apply them yet. advance(model) then applies the changes.\n\n    \"\"\"\n    def step(self):\n        \"\"\" Step all agents, then advance them. \"\"\"\n        for agent in self.agents:\n            agent.step(self.model)\n        for agent in self.agents:\n            agent.advance(self.model)\n        self.steps += 1\n        self.time += 1\n\n\nclass StagedActivation(BaseScheduler):\n    \"\"\" A scheduler which allows agent activation to be divided into several\n    stages instead of a single `step` method. All agents execute one stage\n    before moving on to the next.\n\n    Agents must have all the stage methods implemented. Stage methods take a\n    model object as their only argument.\n\n    This schedule tracks steps and time separately. Time advances in fractional\n    increments of 1 / (# of stages), meaning that 1 step = 1 unit of time.\n\n    \"\"\"\n    stage_list = []\n    shuffle = False\n    shuffle_between_stages = False\n    stage_time = 1\n\n    def __init__(self, model, stage_list=[\"step\"], shuffle=False,\n                 shuffle_between_stages=False):\n        \"\"\" Create an empty Staged Activation schedule.\n\n        Args:\n            model: Model object associated with the schedule.\n            stage_list: List of strings of names of stages to run, in the\n                         order to run them in.\n            shuffle: If True, shuffle the order of agents each step.\n            shuffle_between_stages: If True, shuffle the agents after each\n                                    stage; otherwise, only shuffle at the start\n                                    of each step.\n\n        \"\"\"\n        super().__init__(model)\n        self.stage_list = stage_list\n        self.shuffle = shuffle\n        self.shuffle_between_stages = shuffle_between_stages\n        self.stage_time = 1 / len(self.stage_list)\n\n    def step(self):\n        \"\"\" Executes all the stages of all agents. \"\"\"\n        if self.shuffle:\n            random.shuffle(self.agents)\n        for stage in self.stage_list:\n            for agent in self.agents:\n                getattr(agent, stage)(self.model)  # Run stage\n            if self.shuffle_between_stages:\n                random.shuffle(self.agents)\n            self.time += self.stage_time\n\n        self.steps += 1\n", "path": "mesa/time.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nBatchrunner\n===========\n\nA single class to manage a batch run or parameter sweep of a given model.\n\n\"\"\"\nfrom itertools import product\nimport pandas as pd\n\n\nclass BatchRunner:\n    \"\"\" This class is instantiated with a model class, and model parameters\n    associated with one or more values. It is also instantiated with model and\n    agent-level reporters, dictionaries mapping a variable name to a function\n    which collects some data from the model or its agents at the end of the run\n    and stores it.\n\n    Note that by default, the reporters only collect data at the *end* of the\n    run. To get step by step data, simply have a reporter store the model's\n    entire DataCollector object.\n\n    \"\"\"\n    def __init__(self, model_cls, parameter_values, iterations=1,\n                 max_steps=1000, model_reporters=None, agent_reporters=None):\n        \"\"\" Create a new BatchRunner for a given model with the given\n        parameters.\n\n        Args:\n            model_cls: The class of model to batch-run.\n            parameter_values: Dictionary of parameters to their values or\n                ranges of values. For example:\n                    {\"param_1\": range(5),\n                     \"param_2\": [1, 5, 10],\n                      \"const_param\": 100}\n            iterations: The total number of times to run the model for each\n                combination of parameters.\n            max_steps: The upper limit of steps above which each run will be halted\n                if it hasn't halted on its own.\n            model_reporters: The dictionary of variables to collect on each run at\n                the end, with variable names mapped to a function to collect\n                them. For example:\n                    {\"agent_count\": lambda m: m.schedule.get_agent_count()}\n            agent_reporters: Like model_reporters, but each variable is now\n                collected at the level of each agent present in the model at\n                the end of the run.\n\n        \"\"\"\n        self.model_cls = model_cls\n        self.parameter_values = {param: self.make_iterable(vals)\n                                 for param, vals in parameter_values.items()}\n        self.iterations = iterations\n        self.max_steps = max_steps\n\n        self.model_reporters = model_reporters\n        self.agent_reporters = agent_reporters\n\n        if self.model_reporters:\n            self.model_vars = {}\n\n        if self.agent_reporters:\n            self.agent_vars = {}\n\n    def run_all(self):\n        \"\"\" Run the model at all parameter combinations and store results. \"\"\"\n        params = self.parameter_values.keys()\n        param_ranges = self.parameter_values.values()\n        run_count = 0\n        for param_values in list(product(*param_ranges)):\n            kwargs = dict(zip(params, param_values))\n            for _ in range(self.iterations):\n                model = self.model_cls(**kwargs)\n                self.run_model(model)\n                # Collect and store results:\n                if self.model_reporters:\n                    key = tuple(list(param_values) + [run_count])\n                    self.model_vars[key] = self.collect_model_vars(model)\n                if self.agent_reporters:\n                    agent_vars = self.collect_agent_vars(model)\n                    for agent_id, reports in agent_vars.items():\n                        key = tuple(list(param_values) + [run_count, agent_id])\n                        self.agent_vars[key] = reports\n                run_count += 1\n\n    def run_model(self, model):\n        \"\"\" Run a model object to completion, or until reaching max steps.\n\n        If your model runs in a non-standard way, this is the method to modify\n        in your subclass.\n\n        \"\"\"\n        while model.running and model.schedule.steps < self.max_steps:\n            model.step()\n\n    def collect_model_vars(self, model):\n        \"\"\" Run reporters and collect model-level variables. \"\"\"\n        model_vars = {}\n        for var, reporter in self.model_reporters.items():\n            model_vars[var] = reporter(model)\n        return model_vars\n\n    def collect_agent_vars(self, model):\n        \"\"\" Run reporters and collect agent-level variables. \"\"\"\n        agent_vars = {}\n        for agent in model.schedule.agents:\n            agent_record = {}\n            for var, reporter in self.agent_reporters.items():\n                agent_record[var] = reporter(agent)\n            agent_vars[agent.unique_id] = agent_record\n        return agent_vars\n\n    def get_model_vars_dataframe(self):\n        \"\"\" Generate a pandas DataFrame from the model-level variables collected.\n\n        \"\"\"\n        index_col_names = list(self.parameter_values.keys())\n        index_col_names.append(\"Run\")\n        records = []\n        for key, val in self.model_vars.items():\n            record = dict(zip(index_col_names, key))\n            for k, v in val.items():\n                record[k] = v\n            records.append(record)\n        return pd.DataFrame(records)\n\n    def get_agent_vars_dataframe(self):\n        \"\"\" Generate a pandas DataFrame from the agent-level variables\n        collected.\n\n        \"\"\"\n        index_col_names = list(self.parameter_values.keys())\n        index_col_names += [\"Run\", \"AgentID\"]\n        records = []\n        for key, val in self.agent_vars.items():\n            record = dict(zip(index_col_names, key))\n            for k, v in val.items():\n                record[k] = v\n            records.append(record)\n        return pd.DataFrame(records)\n\n    @staticmethod\n    def make_iterable(val):\n        \"\"\" Helper method to ensure a value is a non-string iterable. \"\"\"\n        if hasattr(val, \"__iter__\") and not isinstance(val, str):\n            return val\n        else:\n            return [val]\n", "path": "mesa/batchrunner.py"}, {"content": "# -*- coding: utf-8 -*-\n\"\"\"\nMesa Time Module\n================\n\nObjects for handling the time component of a model. In particular, this module\ncontains Schedulers, which handle agent activation. A Scheduler is an object\nwhich controls when agents are called upon to act, and when.\n\nThe activation order can have a serious impact on model behavior, so it's\nimportant to specify it explicitly. Example simple activation regimes include\nactivating all agents in the same order every step, shuffling the activation\norder every time, activating each agent *on average* once per step, and more.\n\nKey concepts:\n    Step: Many models advance in 'steps'. A step may involve the activation of\n    all agents, or a random (or selected) subset of them. Each agent in turn\n    may have their own step() method.\n\n    Time: Some models may simulate a continuous 'clock' instead of discrete\n    steps. However, by default, the Time is equal to the number of steps the\n    model has taken.\n\n\nTODO: Have the schedulers use the model's randomizer, to keep random number\nseeds consistent and allow for replication.\n\n\"\"\"\nimport random\n\n\nclass BaseScheduler:\n    \"\"\" Simplest scheduler; activates agents one at a time, in the order\n    they were added.\n\n    Assumes that each agent added has a *step* method, which accepts a model\n    object as its single argument.\n\n    (This is explicitly meant to replicate the scheduler in MASON).\n\n    \"\"\"\n    model = None\n    steps = 0\n    time = 0\n    agents = []\n\n    def __init__(self, model):\n        \"\"\" Create a new, empty BaseScheduler. \"\"\"\n        self.model = model\n        self.steps = 0\n        self.time = 0\n        self.agents = []\n\n    def add(self, agent):\n        \"\"\" Add an Agent object to the schedule.\n\n        Args:\n            agent: An Agent to be added to the schedule. NOTE: The agent must\n            have a step(model) method.\n\n        \"\"\"\n        self.agents.append(agent)\n\n    def remove(self, agent):\n        \"\"\" Remove all instances of a given agent from the schedule.\n\n        Args:\n            agent: An agent object.\n\n        \"\"\"\n        while agent in self.agents:\n            self.agents.remove(agent)\n\n    def step(self):\n        \"\"\" Execute the step of all the agents, one at a time. \"\"\"\n        for agent in self.agents:\n            agent.step(self.model)\n        self.steps += 1\n        self.time += 1\n\n    def get_agent_count(self):\n        \"\"\" Returns the current number of agents in the queue. \"\"\"\n        return len(self.agents)\n\n\nclass RandomActivation(BaseScheduler):\n    \"\"\" A scheduler which activates each agent once per step, in random order,\n    with the order reshuffled every step.\n\n    This is equivalent to the NetLogo 'ask agents...' and is generally the\n    default behavior for an ABM.\n\n    Assumes that all agents have a step(model) method.\n\n    \"\"\"\n    def step(self):\n        \"\"\" Executes the step of all agents, one at a time, in\n        random order.\n\n        \"\"\"\n        random.shuffle(self.agents)\n\n        for agent in self.agents:\n            agent.step(self.model)\n        self.steps += 1\n        self.time += 1\n\n\nclass SimultaneousActivation(BaseScheduler):\n    \"\"\" A scheduler to simulate the simultaneous activation of all the agents.\n\n    This scheduler requires that each agent have two methods: step and advance.\n    step(model) activates the agent and stages any necessary changes, but does\n    not apply them yet. advance(model) then applies the changes.\n\n    \"\"\"\n    def step(self):\n        \"\"\" Step all agents, then advance them. \"\"\"\n        for agent in self.agents:\n            agent.step(self.model)\n        for agent in self.agents:\n            agent.advance(self.model)\n        self.steps += 1\n        self.time += 1\n\n\nclass StagedActivation(BaseScheduler):\n    \"\"\" A scheduler which allows agent activation to be divided into several\n    stages instead of a single `step` method. All agents execute one stage\n    before moving on to the next.\n\n    Agents must have all the stage methods implemented. Stage methods take a\n    model object as their only argument.\n\n    This schedule tracks steps and time separately. Time advances in fractional\n    increments of 1 / (# of stages), meaning that 1 step = 1 unit of time.\n\n    \"\"\"\n    stage_list = []\n    shuffle = False\n    shuffle_between_stages = False\n    stage_time = 1\n\n    def __init__(self, model, stage_list=[\"step\"], shuffle=False,\n                 shuffle_between_stages=False):\n        \"\"\" Create an empty Staged Activation schedule.\n\n        Args:\n            model: Model object associated with the schedule.\n            stage_list: List of strings of names of stages to run, in the\n                         order to run them in.\n            shuffle: If True, shuffle the order of agents each step.\n            shuffle_between_stages: If True, shuffle the agents after each\n                                    stage; otherwise, only shuffle at the start\n                                    of each step.\n\n        \"\"\"\n        super().__init__(model)\n        self.stage_list = stage_list\n        self.shuffle = shuffle\n        self.shuffle_between_stages = shuffle_between_stages\n        self.stage_time = 1 / len(self.stage_list)\n\n    def step(self):\n        \"\"\" Executes all the stages for all agents. \"\"\"\n        if self.shuffle:\n            random.shuffle(self.agents)\n        for stage in self.stage_list:\n            for agent in self.agents:\n                getattr(agent, stage)(self.model)  # Run stage\n            if self.shuffle_between_stages:\n                random.shuffle(self.agents)\n            self.time += self.stage_time\n\n        self.steps += 1\n", "path": "mesa/time.py"}]}