diff --git a/docs/best-practices.md b/docs/best-practices.md index e7f695ac876..8fa2b87b81e 100644 --- a/docs/best-practices.md +++ b/docs/best-practices.md @@ -24,8 +24,6 @@ an `images` directory. The [Schelling](https://github.com/projectmesa/mesa-examples/tree/main/examples/schelling) model is a good example of a small well-packaged model. -It's easy to create a cookiecutter mesa model by running `mesa startproject` - ## Randomization If your model involves some random choice, you can use the built-in `random` diff --git a/docs/index.md b/docs/index.md index edf4c44d955..3a79b6e8ec8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -56,7 +56,7 @@ and [solara](https://solara.dev/) - **mesa[network]** installs mesa and [networkx](https://networkx.org/) - **mesa[viz]** installs, mesa, [matplotlib](https://matplotlib.org/stable/install/index.html) and [solara](https://solara.dev/) -- **mesa[dev]** installs mesa[rec], [ruff](https://docs.astral.sh/ruff/), [pytest](https://docs.pytest.org/en/stable/), [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/), [sphinx](https://www.sphinx-doc.org/en/master/man/sphinx-build.html#cmdoption-sphinx-build-e), [pytest-mock](https://pytest-mock.readthedocs.io/en/latest/), [cookiecutter](https://cookiecutter.readthedocs.io/en/stable/) +- **mesa[dev]** installs mesa[rec], [ruff](https://docs.astral.sh/ruff/), [pytest](https://docs.pytest.org/en/stable/), [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/), [sphinx](https://www.sphinx-doc.org/en/master/man/sphinx-build.html#cmdoption-sphinx-build-e), [pytest-mock](https://pytest-mock.readthedocs.io/en/latest/) - **mesa[examples]** installs mesa[rec], [pytest](https://docs.pytest.org/en/stable/), and [scipy](https://scipy.org/) - **mesa[docs]** installs mesa[rec], [sphinx](https://www.sphinx-doc.org/en/master/man/sphinx-build.html#cmdoption-sphinx-build-e), [ipython](https://ipython.readthedocs.io/en/stable/install/kernel_install.html), [pydata_sphinx_theme](https://pydata-sphinx-theme.readthedocs.io/en/stable/), [seaborn](https://seaborn.pydata.org/), [myst-nb](https://myst-nb.readthedocs.io/en/latest/), [myst-parser](https://myst-parser.readthedocs.io/en/latest/) diff --git a/mesa/cookiecutter-mesa/cookiecutter.json b/mesa/cookiecutter-mesa/cookiecutter.json deleted file mode 100644 index 91e05326aa8..00000000000 --- a/mesa/cookiecutter-mesa/cookiecutter.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "project": "Example Project", - "snake": "{{ cookiecutter.project.lower().replace(' ', '_') }}", - "camel": "{{ cookiecutter.project.title().replace(' ', '') }}", - "agent": "{{ cookiecutter.camel + 'Agent'}}", - "model": "{{ cookiecutter.camel + 'Model'}}", - "description": "Example short description of the project" -} diff --git a/mesa/cookiecutter-mesa/hooks/post_gen_project.py b/mesa/cookiecutter-mesa/hooks/post_gen_project.py deleted file mode 100644 index 1521594704b..00000000000 --- a/mesa/cookiecutter-mesa/hooks/post_gen_project.py +++ /dev/null @@ -1,13 +0,0 @@ -"""helper module.""" - -import glob -import os - -file_list = glob.glob("**/*.pytemplate", recursive=True) - -for file_path in file_list: - # Check if the file is a regular file - if not os.path.isfile(file_path): - continue - # Rename the file - os.rename(file_path, file_path.replace(".pytemplate", ".py")) diff --git a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md b/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md deleted file mode 100644 index c96aa5c33bd..00000000000 --- a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md +++ /dev/null @@ -1,4 +0,0 @@ -{{cookiecutter.project}} -======================== - -{{cookiecutter.description}} diff --git a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate b/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate deleted file mode 100644 index 04911cc0a37..00000000000 --- a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate +++ /dev/null @@ -1,27 +0,0 @@ -""" -Configure visualization elements and instantiate a server -""" -from mesa.visualization import SolaraViz - -from {{ cookiecutter.snake }}.model import {{ cookiecutter.model }}, {{ cookiecutter.agent }} # noqa - -import mesa - - -def circle_portrayal_example(agent): - return { - "size": 40, - # This is Matplotlib's color - "color": "tab:pink", - } - - -model_params = {"num_agents": 10, "width": 10, "height": 10} - -page = SolaraViz( - {{cookiecutter.model}}, - model_params, - measures=["num_agents"], - agent_portrayal=circle_portrayal_example -) -page # noqa diff --git a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate b/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate deleted file mode 100644 index a72014b21de..00000000000 --- a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -from setuptools import find_packages, setup - -requires = ["mesa"] - -setup( - name="{{cookiecutter.snake}}", - version="0.0.1", - packages=find_packages(), - install_requires=requires, -) diff --git a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py b/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py deleted file mode 100644 index dda29ba61af..00000000000 --- a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""helper modules.""" diff --git a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate b/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate deleted file mode 100644 index b33789a720a..00000000000 --- a/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate +++ /dev/null @@ -1,60 +0,0 @@ -import mesa - - -class {{cookiecutter.agent}}(mesa.Agent): # noqa - """ - An agent - """ - - def __init__(self, unique_id, model): - """ - Customize the agent - """ - self.unique_id = unique_id - super().__init__(unique_id, model) - - def step(self): - """ - Modify this method to change what an individual agent will do during each step. - Can include logic based on neighbors states. - """ - pass - - -class {{cookiecutter.model}}(mesa.Model): - """ - The model class holds the model-level attributes, manages the agents, and generally handles - the global level of our model. - - There is only one model-level parameter: how many agents the model contains. When a new model - is started, we want it to populate itself with the given number of agents. - - The scheduler is a special model component which controls the order in which agents are activated. - """ - - def __init__(self, num_agents, width, height): - super().__init__() - self.num_agents = num_agents - self.schedule = mesa.time.RandomActivation(self) - self.grid = mesa.space.MultiGrid(width=width, height=height, torus=True) - - for i in range(self.num_agents): - agent = {{cookiecutter.agent}}(i, self) - self.schedule.add(agent) - - x = self.random.randrange(self.grid.width) - y = self.random.randrange(self.grid.height) - self.grid.place_agent(agent, (x, y)) - - # example data collector - self.datacollector = mesa.datacollection.DataCollector({"num_agents": "num_agents"}) - - self.running = True - self.datacollector.collect(self) - - def step(self): - """ - A model step. Used for collecting data and advancing the schedule - """ - self.datacollector.collect(self) - self.schedule.step() diff --git a/mesa/main.py b/mesa/main.py deleted file mode 100644 index 1d65500ee4f..00000000000 --- a/mesa/main.py +++ /dev/null @@ -1,65 +0,0 @@ -"""main module for running mesa models with a server.""" - -import os -import sys -from pathlib import Path -from subprocess import call - -import click - -from mesa import __version__ - -PROJECT_PATH = click.Path( - exists=True, file_okay=False, dir_okay=True, resolve_path=True -) -COOKIECUTTER_DIR = "mesa/cookiecutter-mesa" -SCRIPTS_DIR = os.path.dirname(os.path.abspath(__file__)) -COOKIECUTTER_PATH = os.path.join(os.path.dirname(SCRIPTS_DIR), COOKIECUTTER_DIR) - -CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]} - - -@click.group(context_settings=CONTEXT_SETTINGS) -def cli(): - """Manage Mesa projects.""" - - -@cli.command() -@click.argument("project", type=PROJECT_PATH, default=".") -def runserver(project): - """Run mesa project PROJECT. - - PROJECT is the path to the directory containing `run.py`, or the current - directory if not specified. - """ - run_files = ["run.py", "server.py"] - for run_file in run_files: - run_path = Path(project) / run_file - if not run_path.exists(): - continue - args = [sys.executable, str(run_path)] - call(args) - sys.exit(f"ERROR: file run.py or server.py (in {Path(project)}) does not exist") - - -@click.command() -@click.option( - "--no-input", is_flag=True, help="Do not prompt user for custom mesa model input." -) -def startproject(no_input): - """Create a new mesa project.""" - args = ["cookiecutter", COOKIECUTTER_PATH] - if no_input: - args.append("--no-input") - call(args) - - -@click.command() -def version(): - """Show the version of mesa.""" - print(f"mesa {__version__}") - - -cli.add_command(runserver) -cli.add_command(startproject) -cli.add_command(version) diff --git a/pyproject.toml b/pyproject.toml index 600616a3ad9..b417ffdd91f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,6 @@ dev = [ "pytest-cov", "sphinx", "pytest-mock", - "cookiecutter", ] examples = [ "mesa[rec]", diff --git a/tests/test_scaffold.py b/tests/test_scaffold.py deleted file mode 100644 index 4d711b8b5a4..00000000000 --- a/tests/test_scaffold.py +++ /dev/null @@ -1,21 +0,0 @@ -# noqa: D100 -import os -import unittest - -from click.testing import CliRunner - -from mesa.main import cli - - -class ScaffoldTest(unittest.TestCase): - """Test mesa project scaffolding command.""" - - @classmethod - def setUpClass(cls): # noqa: D102 - cls.runner = CliRunner() - - def test_scaffold_creates_project_dir(self): # noqa: D102 - with self.runner.isolated_filesystem(): - assert not os.path.isdir("example_project") - self.runner.invoke(cli, ["startproject", "--no-input"]) - assert os.path.isdir("example_project")