Mesa 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of Mesa might be problematic. Click here for more details.

Files changed (41) hide show
  1. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/LICENSE +1 -1
  2. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/METADATA +15 -14
  3. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/RECORD +41 -41
  4. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/WHEEL +1 -1
  5. mesa/__init__.py +8 -9
  6. mesa/agent.py +2 -3
  7. mesa/batchrunner.py +19 -28
  8. mesa/datacollection.py +15 -28
  9. mesa/main.py +4 -4
  10. mesa/model.py +2 -6
  11. mesa/space.py +379 -286
  12. mesa/time.py +21 -22
  13. mesa/visualization/ModularVisualization.py +11 -9
  14. mesa/visualization/TextVisualization.py +0 -3
  15. mesa/visualization/UserParam.py +8 -11
  16. mesa/visualization/__init__.py +0 -1
  17. mesa/visualization/modules/BarChartVisualization.py +7 -8
  18. mesa/visualization/modules/CanvasGridVisualization.py +1 -3
  19. mesa/visualization/modules/ChartVisualization.py +2 -3
  20. mesa/visualization/modules/HexGridVisualization.py +1 -3
  21. mesa/visualization/modules/NetworkVisualization.py +1 -2
  22. mesa/visualization/modules/PieChartVisualization.py +2 -6
  23. mesa/visualization/templates/js/GridDraw.js +6 -10
  24. mesa/visualization/templates/js/HexDraw.js +5 -9
  25. mesa/visualization/templates/js/InteractionHandler.js +0 -2
  26. tests/test_batchrunner.py +3 -4
  27. tests/test_batchrunnerMP.py +4 -4
  28. tests/test_datacollector.py +2 -2
  29. tests/test_examples.py +8 -5
  30. tests/test_grid.py +104 -37
  31. tests/test_import_namespace.py +0 -1
  32. tests/test_lifespan.py +4 -3
  33. tests/test_main.py +5 -1
  34. tests/test_scaffold.py +2 -1
  35. tests/test_space.py +13 -20
  36. tests/test_time.py +44 -14
  37. tests/test_tornado.py +4 -2
  38. tests/test_usersettableparam.py +4 -3
  39. tests/test_visualization.py +4 -8
  40. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/entry_points.txt +0 -0
  41. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- Copyright 2021 Core Mesa Team and contributors
1
+ Copyright 2022 Core Mesa Team and contributors
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Mesa
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Agent-based modeling (ABM) in Python 3+
5
5
  Home-page: https://github.com/projectmesa/mesa
6
6
  Author: Project Mesa Team
@@ -12,7 +12,6 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Life
12
12
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
13
13
  Classifier: Intended Audience :: Science/Research
14
14
  Classifier: Programming Language :: Python :: 3 :: Only
15
- Classifier: Programming Language :: Python :: 3.7
16
15
  Classifier: Programming Language :: Python :: 3.8
17
16
  Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
@@ -20,7 +19,7 @@ Classifier: License :: OSI Approved :: Apache Software License
20
19
  Classifier: Operating System :: OS Independent
21
20
  Classifier: Development Status :: 3 - Alpha
22
21
  Classifier: Natural Language :: English
23
- Requires-Python: >=3.7
22
+ Requires-Python: >=3.8
24
23
  License-File: LICENSE
25
24
  Requires-Dist: click
26
25
  Requires-Dist: cookiecutter
@@ -31,8 +30,8 @@ Requires-Dist: tornado
31
30
  Requires-Dist: tqdm
32
31
  Provides-Extra: dev
33
32
  Requires-Dist: black ; extra == 'dev'
33
+ Requires-Dist: ruff ; extra == 'dev'
34
34
  Requires-Dist: coverage ; extra == 'dev'
35
- Requires-Dist: flake8 ; extra == 'dev'
36
35
  Requires-Dist: pytest (>=4.6) ; extra == 'dev'
37
36
  Requires-Dist: pytest-cov ; extra == 'dev'
38
37
  Requires-Dist: sphinx ; extra == 'dev'
@@ -55,7 +54,7 @@ Mesa: Agent-based modeling in Python 3+
55
54
  .. image:: https://img.shields.io/matrix/project-mesa:matrix.org?label=chat&logo=Matrix
56
55
  :target: https://matrix.to/#/#project-mesa:matrix.org
57
56
 
58
- It allows users to quickly create agent-based models using built-in core components (such as spatial grids and agent schedulers) or customized implementations; visualize them using a browser-based interface; and analyze their results using Python's data analysis tools. Its goal is to be the Python 3-based alternative to NetLogo, Repast, or MASON.
57
+ Mesa allows users to quickly create agent-based models using built-in core components (such as spatial grids and agent schedulers) or customized implementations; visualize them using a browser-based interface; and analyze their results using Python's data analysis tools. Its goal is to be the Python 3-based alternative to NetLogo, Repast, or MASON.
59
58
 
60
59
 
61
60
  .. image:: https://raw.githubusercontent.com/projectmesa/mesa/main/docs/images/Mesa_Screenshot.png
@@ -99,19 +98,21 @@ Or any other (development) branch on this repo or your own fork:
99
98
 
100
99
  $ pip install -U -e git+https://github.com/YOUR_FORK/mesa@YOUR_BRANCH#egg=mesa
101
100
 
102
- Take a look at the `examples <https://github.com/projectmesa/mesa/tree/main/examples>`_ folder for sample models demonstrating Mesa features.
101
+ For resources or help on using Mesa, check out the following:
103
102
 
104
- For more help on using Mesa, check out the following resources:
105
-
106
- * `Intro to Mesa Tutorial`_
107
- * `Docs`_
108
- * `Email list for users`_
109
- * `PyPI`_
103
+ * `Intro to Mesa Tutorial`_ (An introductory model, the Boltzmann Wealth Model, for beginners or those new to Mesa.)
104
+ * `Complexity Explorer Tutorial`_ (An advanced-beginner model, SugarScape with Traders, with instructional videos)
105
+ * `Mesa Examples`_ (A repository of seminal ABMs using Mesa and examples of employing specific Mesa Features)
106
+ * `Docs`_ (Mesa's documentation, API and useful snippets)
107
+ * `Discussions`_ (GitHub threaded discussions about Mesa)
108
+ * `Matrix Chat`_ (Chat Forum via Matrix to talk about Mesa)
110
109
 
111
110
  .. _`Intro to Mesa Tutorial` : http://mesa.readthedocs.org/en/main/tutorials/intro_tutorial.html
111
+ .. _`Complexity Explorer Tutorial` : https://www.complexityexplorer.org/courses/172-agent-based-models-with-python-an-introduction-to-mesa
112
+ .. _`Mesa Examples` : https://github.com/projectmesa/mesa-examples/tree/main/examples
112
113
  .. _`Docs` : http://mesa.readthedocs.org/en/main/
113
- .. _`Email list for users` : https://groups.google.com/d/forum/projectmesa
114
- .. _`PyPI` : https://pypi.python.org/pypi/Mesa/
114
+ .. _`Discussions` : https://github.com/projectmesa/mesa/discussions
115
+ .. _`Matrix Chat` : https://matrix.to/#/#project-mesa:matrix.org
115
116
 
116
117
  Running Mesa in Docker
117
118
  ------------------------
@@ -1,24 +1,24 @@
1
- mesa/__init__.py,sha256=ZBvL991ijKa2akO3puatGlNuh0zR2OWWuqLFFz_DqUk,617
2
- mesa/agent.py,sha256=aFlHd1o5_qXWnRGB2P0MHNN91kV4HMCm7hsd1LBnBpU,1094
3
- mesa/batchrunner.py,sha256=ipWDhncb8fEmoXFrq2JNdYgxgl-IgfLA2x2ugiwyhy0,28077
4
- mesa/datacollection.py,sha256=W6iJbcgunaqSXQZLSmc4bHOckRCikW1yr1DXOivBrg4,10111
5
- mesa/main.py,sha256=cDuhAJowWiS2xA-mLIMKLoDH7F5BeNRqGo4iUDYArpA,1141
6
- mesa/model.py,sha256=_ApMoFhyuWbG3bCPHPzR-G08fU_Fr5B29Bd7Bo3hVww,2611
7
- mesa/space.py,sha256=XCWtB-ROC7lghHXw_QpDo4WjAPQbH0fLjKXoUr-Pw4c,35277
8
- mesa/time.py,sha256=dT_tDPlnAqNRPhSd1-yh1w3n2LRktm2jiWOcxb8_U0E,10095
1
+ mesa/__init__.py,sha256=14vZcuboYtBmYU8mAk01zDJs7PzTvzX7McgKwHRniyY,664
2
+ mesa/agent.py,sha256=EtfTa33MMSkiZ66hXl0LBVSyFpbb1paf0CUUBQS7yao,1081
3
+ mesa/batchrunner.py,sha256=8a1Vw9Kz7VIPv6LCTOd02UZkY8TQSWTXhTMJB4bEbBE,27850
4
+ mesa/datacollection.py,sha256=jgwmvhH_1c8R0FX43DqOUrNLQ6KqTYWEjwb1G4V6Do4,10129
5
+ mesa/main.py,sha256=hy73jEXQSvq8z-0IIvC0lYGqQNLIrwZsWkvMP35KdLc,1147
6
+ mesa/model.py,sha256=lww4nK_A0K_zc5e_JL_dwDae1_2juvF3lZJ61yB7jeA,2595
7
+ mesa/space.py,sha256=dw4n5RNro2oA_yI6K0ZOmLTsRfXAyi0RsFyQq3340Y8,39673
8
+ mesa/time.py,sha256=ZTk9qkvPhgGfaKtX7DaOeeK8eabVutTKS9-iThNUEf4,10665
9
9
  mesa/cookiecutter-mesa/cookiecutter.json,sha256=tBSWli39fOWUXGfiDCTKd92M7uKaBIswXbkOdbUufYY,337
10
10
  mesa/flat/__init__.py,sha256=hSqQDjkfIgDu7B3aYtjPeNEUXdlKPHQuNN8HEV0XR6s,218
11
11
  mesa/flat/visualization.py,sha256=WC01m3B6dduwV7-85rP9BdH2cxiCv6RJrsltv_oEtb0,298
12
- mesa/visualization/ModularVisualization.py,sha256=YrwkaVF_UKkK6X_fdig4GyU1OtsUyI7qG9gs_M3ihJw,14483
13
- mesa/visualization/TextVisualization.py,sha256=-hfnEA1GyAmcrWFr-Vdpp8kD5JbwpbWcmU7kFAJrvhM,3795
14
- mesa/visualization/UserParam.py,sha256=_tncRcH5hQyW6fU2QYjNew4oElqWAs6_52dS8Zl_JxI,8722
15
- mesa/visualization/__init__.py,sha256=5D7_zDik-F85CiEVZuq02FG9jKwFA5iz7QvrxwJAvgg,269
16
- mesa/visualization/modules/BarChartVisualization.py,sha256=eUA4WAndtNd-yelqwstmnQx8biZJU1pBC4JNrctY0cM,3694
17
- mesa/visualization/modules/CanvasGridVisualization.py,sha256=WvcIIqlUJWY8eU2463mg3LU_KdgG8mmERaUncLeiUxE,4744
18
- mesa/visualization/modules/ChartVisualization.py,sha256=dcNvo7nryqsujOax6BBNAvs2_YluXpKM8itCjMo-xN0,3145
19
- mesa/visualization/modules/HexGridVisualization.py,sha256=az2SwypvG5s4r3T90kQNdGKWaaCOsrnHTgFHeX2lyw0,3543
20
- mesa/visualization/modules/NetworkVisualization.py,sha256=eUGY8QLbsII3r0tgT1B5U25BSqE1pdrxKQb6o2nkDPA,839
21
- mesa/visualization/modules/PieChartVisualization.py,sha256=35TvAAB86ua53Jd8rdEuqTe0FJIQ6PD7v-ykk6bBtFs,2454
12
+ mesa/visualization/ModularVisualization.py,sha256=0rcfkvtmEd7RXOW0H09Wea3fhZY0nepI1nPExd_po8A,14637
13
+ mesa/visualization/TextVisualization.py,sha256=qGlX6aROX9vyeygOwuGphK8ae0WfSF51qrgJ7YkHOnA,3792
14
+ mesa/visualization/UserParam.py,sha256=6eWCGJNhbS3avoOGc7n2h9QYRgwY1-_u2HOaZq64VyY,8688
15
+ mesa/visualization/__init__.py,sha256=E67QA_Aw2Prrr-uwKqWWtcl_7pNSLfpfJmt1dH6RlS8,268
16
+ mesa/visualization/modules/BarChartVisualization.py,sha256=0iFUT7itUWb6g_Op9DXbkPrW9LXViFr1Bxr3dGmYHuA,3698
17
+ mesa/visualization/modules/CanvasGridVisualization.py,sha256=O8m7OuvL8FvesLa2OOZwgS06NOpnQX4HilZlLZSykJc,4742
18
+ mesa/visualization/modules/ChartVisualization.py,sha256=qql1EzfaRaIx30GlHB9i_LRBIUzula4yqHXsqI3Lv2k,3144
19
+ mesa/visualization/modules/HexGridVisualization.py,sha256=e0gaxkwolnMb97PUFCidNRGgaix2K1URS1jpAouzay8,3541
20
+ mesa/visualization/modules/NetworkVisualization.py,sha256=HQeBsWwmxL1zNsWRYI_im88doa7sjaxWpvNXN4WIr78,838
21
+ mesa/visualization/modules/PieChartVisualization.py,sha256=v3tBnxdxVBXMp9P9nNRGzp_SR7w0FrMJgm6s3z1ynMg,2450
22
22
  mesa/visualization/modules/__init__.py,sha256=GfB3QILVF6FmEY1Kdz6uZ8AToRAUfv_URR_3jALyNsc,726
23
23
  mesa/visualization/templates/modular_template.html,sha256=0ZBBTVGI5jbBlT7hBJhMum8qI7cXvpdvBfnzPDrtg18,4546
24
24
  mesa/visualization/templates/css/visualization.css,sha256=vOjdwmVKb7PTbqljH7dvosbnk3ycoOvVxZ_PgSu2HmI,377
@@ -136,9 +136,9 @@ mesa/visualization/templates/js/BarChartModule.js,sha256=kmR2dgssnXLyE7WOFqoyGGA
136
136
  mesa/visualization/templates/js/CanvasHexModule.js,sha256=XzUf5zPPl3xjVqi1Dw3aNgJn_1kiTQ6CNZicV4k9QqY,1610
137
137
  mesa/visualization/templates/js/CanvasModule.js,sha256=BxPirbRJPH41m5tqOklNf8BKlzzgh93AmzDD3D7LeL4,1689
138
138
  mesa/visualization/templates/js/ChartModule.js,sha256=wAFHZlTfqtYv_S6Ajx0gswK4F-l2fxPAa59QrgZOydI,2175
139
- mesa/visualization/templates/js/GridDraw.js,sha256=uaZN7339kqGYlsQX3e9qD1xUxPUkrfJLsYCO0ylEFsA,12964
140
- mesa/visualization/templates/js/HexDraw.js,sha256=W9Los9LGbqMWMSRfrkJn-sUJqRPMguO7OX1504mnFWs,8647
141
- mesa/visualization/templates/js/InteractionHandler.js,sha256=XmUMssDwNrYOaoIDMF7RTsaPxVUwxetZvypf7Bn84k8,5422
139
+ mesa/visualization/templates/js/GridDraw.js,sha256=sm2_WFfqaG5jVSQtOLVvoPnROipO1G8w-i9DTa_DfLI,12943
140
+ mesa/visualization/templates/js/HexDraw.js,sha256=gfaqLDLdpe7-eV_qbBNwYACC4uC1Q63gHQe179WEb6o,8609
141
+ mesa/visualization/templates/js/InteractionHandler.js,sha256=89JxZtBeROT0y78guQmrTrmXdmelvpbAz1dwqkgOf-g,5295
142
142
  mesa/visualization/templates/js/NetworkModule_d3.js,sha256=E7_qrYufXKMHPtgO-Ezqxxyo3UQGYCoWJNoWxZLAgR4,3002
143
143
  mesa/visualization/templates/js/PieChartModule.js,sha256=WZFevQ3DPmOYNm48TjF03XtxvKvAlke9VRhXrGckNN4,2826
144
144
  mesa/visualization/templates/js/TextModule.js,sha256=bCTQkGrJiQ64EwzaxlkHciyk8ekUomWUgnGKUjvxm3o,327
@@ -147,24 +147,24 @@ mesa/visualization/templates/js/external/chart-3.6.1.min.js,sha256=bj8JMRF_ShthP
147
147
  mesa/visualization/templates/js/external/d3-7.4.3.min.js,sha256=-MpQAOeqA18DtHk7JETZadE17KoMl0jCS89tlo6OWGM,277072
148
148
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
149
  tests/test_batch_run.py,sha256=WyfwEPKG-E4E6mH6ASjKSNXTRVog3UfB-vNRnZUcPx8,5052
150
- tests/test_batchrunner.py,sha256=WDBOAkhjvXmW8B_wQceJYVhZ54FI9ipSaOzsfj3DOe8,11435
151
- tests/test_batchrunnerMP.py,sha256=OhQR0u_SCU__eAw2qOF9le3QRMBNjAYSR_J4B9Vv1fM,9107
152
- tests/test_datacollector.py,sha256=h3Y4MEcSIWCqkPyGhfvipG1mzSJNByULALMISkvVzXo,6615
153
- tests/test_examples.py,sha256=WaJzl2r0O6UrkTVHokmdYOowdGPIsAbnUtdyO4g9OwY,2388
154
- tests/test_grid.py,sha256=L-8v-uGU_BV1lmBLZkpkA2Bvjy2Bpgq3gGCMoOo_SSU,14159
155
- tests/test_import_namespace.py,sha256=KeRyDxJGaTdj0-LEz8xkrNJWkedW03HMZK6DFAzqUX4,725
156
- tests/test_lifespan.py,sha256=M0HSz1U_S02bF8_3OeHDAsc1eqX15blMXPoJ6MON44c,2833
157
- tests/test_main.py,sha256=fa96N40soKTpI-RCT0qka0qwU-jTOezrIEj0Pyg_ROA,855
150
+ tests/test_batchrunner.py,sha256=3G--CpUmBA7dr1fKCbzOhocufaUM2QeoQ_mkftMe4x0,11434
151
+ tests/test_batchrunnerMP.py,sha256=G2rXmD2HG9gfgY6GzJEshDFqh-uFPCpP8XtjMUo3UyU,9107
152
+ tests/test_datacollector.py,sha256=-SDMwmEzXRzL1a7I5X7WFWHk_BVJiW98Qsi2W0K5rjU,6616
153
+ tests/test_examples.py,sha256=kiNZfkXjJnrEV4Z5m78itnxv-N3TLII_O52-KzlU_eo,2506
154
+ tests/test_grid.py,sha256=ZOk_bJKrpZ-Ug_mYUDjaSdzwCraQ6U_iYYz8YziIeSI,16738
155
+ tests/test_import_namespace.py,sha256=OZ94QiaCKVsl64-rjWLfh1QYMpYokfpeRcfK_OwvI8w,724
156
+ tests/test_lifespan.py,sha256=5x4sNx19hEKVd4HHMEjIn5Jrk7rvMufKfp0iVA1MCfI,2834
157
+ tests/test_main.py,sha256=bAKTUPj4MWd7oDr6pNEyQoJrvJfeGEeCd6Jkl2GXT8U,984
158
158
  tests/test_model.py,sha256=IyVs2IL1F_Pn54oEfSIDcU5b7kbi2AOSwFs8c4vpmg8,970
159
- tests/test_scaffold.py,sha256=WTRn6NkkRyDiOJOUqgVQjQm6AujrDPkjkt6ZJvf3IJs,538
160
- tests/test_space.py,sha256=LUH12D2rKEtCSLYqUCpIa3l9LXg3arvXopqp2x-Ithg,15947
161
- tests/test_time.py,sha256=B99onwbZD-0LBbeCmYwgkFLEyZS9VSkZ2ArHA-BYMb4,7444
162
- tests/test_tornado.py,sha256=Lb9ps4T3oEkTIM1e96hItfk8HAXkz7-eWEkFxav_FTw,1268
163
- tests/test_usersettableparam.py,sha256=hvRw-fb-5Fp4lGsLg_jeXsfNfZnrI87NOobgxbzsPHg,2563
164
- tests/test_visualization.py,sha256=SuPZUg9vIj4lec5Ly7XUKvqd6Qp_D6NdOaxshXcU85o,2778
165
- Mesa-1.1.0.dist-info/LICENSE,sha256=rxtnAxuPsHGYe6lyt17l216OSHFUrjcINiqzhSOyhsE,572
166
- Mesa-1.1.0.dist-info/METADATA,sha256=De21atDXlykwYVkf9SUDKQMcSCUG0ocTwCfa4idc7ww,6672
167
- Mesa-1.1.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
168
- Mesa-1.1.0.dist-info/entry_points.txt,sha256=IOcQtetGF8l4wHpOs_hGb19Rz-FS__BMXOJR10IBPsA,39
169
- Mesa-1.1.0.dist-info/top_level.txt,sha256=VYd8OkxFUc18-7nokv6pPVD0L_gwvqHDbacL8peWqXM,11
170
- Mesa-1.1.0.dist-info/RECORD,,
159
+ tests/test_scaffold.py,sha256=kZa0PGlCaZCxEYdFurcWEudSG3IaQdZnrHvcukmiBm0,539
160
+ tests/test_space.py,sha256=ZHMbzNAHtmp5j69wOiSA6KLUE137r4N1xZ02pEwW3FY,15928
161
+ tests/test_time.py,sha256=r25vm0ATW3YfQreBP8avkENJrBI56yBwHgWe3Y7RNyo,8561
162
+ tests/test_tornado.py,sha256=DInrFEL2n7k9x5S-ZClEFno4OlitjzyDk45lZ9Lgs5g,1270
163
+ tests/test_usersettableparam.py,sha256=NdEFjSrNvXuvkWvWInRtZ4u0aLO3DDxURHjW2ePJeRw,2564
164
+ tests/test_visualization.py,sha256=yMwzx2GrNpdqpGT3k6dh9DmBHrnrvTrIZh8-lViTe50,2783
165
+ Mesa-1.2.0.dist-info/LICENSE,sha256=rgf5rJXcrpdESYDM17Gew0097eH4JdWjqQ2EnLHnFHE,572
166
+ Mesa-1.2.0.dist-info/METADATA,sha256=c0AUmaRqoLepPzRed99vb62IwswvKUtxUF6gbDQbsdU,7156
167
+ Mesa-1.2.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
168
+ Mesa-1.2.0.dist-info/entry_points.txt,sha256=IOcQtetGF8l4wHpOs_hGb19Rz-FS__BMXOJR10IBPsA,39
169
+ Mesa-1.2.0.dist-info/top_level.txt,sha256=VYd8OkxFUc18-7nokv6pPVD0L_gwvqHDbacL8peWqXM,11
170
+ Mesa-1.2.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.37.1)
2
+ Generator: bdist_wheel (0.38.4)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
mesa/__init__.py CHANGED
@@ -2,18 +2,16 @@
2
2
  Mesa Agent-Based Modeling Framework
3
3
 
4
4
  Core Objects: Model, and Agent.
5
-
6
5
  """
7
6
  import datetime
8
7
 
9
- from mesa.model import Model
10
- from mesa.agent import Agent
11
-
12
- import mesa.time as time
13
- import mesa.space as space
14
8
  import mesa.flat.visualization as visualization
9
+ import mesa.space as space
10
+ import mesa.time as time
11
+ from mesa.agent import Agent
12
+ from mesa.batchrunner import batch_run
15
13
  from mesa.datacollection import DataCollector
16
- from mesa.batchrunner import batch_run # noqa
14
+ from mesa.model import Model
17
15
 
18
16
  __all__ = [
19
17
  "Model",
@@ -26,6 +24,7 @@ __all__ = [
26
24
  ]
27
25
 
28
26
  __title__ = "mesa"
29
- __version__ = "1.1.0"
27
+ __version__ = "1.2.0"
30
28
  __license__ = "Apache 2.0"
31
- __copyright__ = f"Copyright {datetime.date.today().year} Project Mesa Team"
29
+ _this_year = datetime.datetime.now(tz=datetime.timezone.utc).date().year
30
+ __copyright__ = f"Copyright {_this_year} Project Mesa Team"
mesa/agent.py CHANGED
@@ -2,15 +2,15 @@
2
2
  The agent class for Mesa framework.
3
3
 
4
4
  Core Objects: Agent
5
-
6
5
  """
7
6
  # Mypy; for the `|` operator purpose
8
7
  # Remove this __future__ import once the oldest supported Python is 3.10
9
8
  from __future__ import annotations
10
9
 
10
+ from random import Random
11
+
11
12
  # mypy
12
13
  from typing import TYPE_CHECKING
13
- from random import Random
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  # We ensure that these are not imported during runtime to prevent cyclic
@@ -35,7 +35,6 @@ class Agent:
35
35
 
36
36
  def step(self) -> None:
37
37
  """A single step of the agent."""
38
- pass
39
38
 
40
39
  def advance(self) -> None:
41
40
  pass
mesa/batchrunner.py CHANGED
@@ -3,16 +3,13 @@ Batchrunner
3
3
  ===========
4
4
 
5
5
  A single class to manage a batch run or parameter sweep of a given model.
6
-
7
6
  """
8
7
  import copy
9
8
  import itertools
10
9
  import random
11
- from collections import OrderedDict
12
10
  from functools import partial
13
11
  from itertools import count, product
14
12
  from multiprocessing import Pool, cpu_count
15
- from warnings import warn
16
13
  from typing import (
17
14
  Any,
18
15
  Dict,
@@ -24,6 +21,7 @@ from typing import (
24
21
  Type,
25
22
  Union,
26
23
  )
24
+ from warnings import warn
27
25
 
28
26
  import pandas as pd
29
27
  from tqdm import tqdm
@@ -285,14 +283,13 @@ class FixedBatchRunner:
285
283
  collected at the level of each agent present in the model at
286
284
  the end of the run.
287
285
  display_progress: Display progress bar with time estimation?
288
-
289
286
  """
290
287
  self.model_cls = model_cls
291
288
  if parameters_list is None:
292
289
  parameters_list = []
293
290
  self.parameters_list = list(parameters_list)
294
291
  self.fixed_parameters = fixed_parameters or {}
295
- self._include_fixed = len(self.fixed_parameters.keys()) > 0
292
+ self._include_fixed = len(self.fixed_parameters) > 0
296
293
  self.iterations = iterations
297
294
  self.max_steps = max_steps
298
295
 
@@ -310,9 +307,8 @@ class FixedBatchRunner:
310
307
  if self.agent_reporters:
311
308
  self.agent_vars = {}
312
309
 
313
- # Make Compatible with Python 3.5
314
- self.datacollector_model_reporters = OrderedDict()
315
- self.datacollector_agent_reporters = OrderedDict()
310
+ self.datacollector_model_reporters = {}
311
+ self.datacollector_agent_reporters = {}
316
312
 
317
313
  self.display_progress = display_progress
318
314
 
@@ -361,7 +357,7 @@ class FixedBatchRunner:
361
357
  model = self.model_cls(**kwargs)
362
358
  results = self.run_model(model)
363
359
  if param_values is not None:
364
- model_key = tuple(param_values) + (run_count,)
360
+ model_key = (*tuple(param_values), run_count)
365
361
  else:
366
362
  model_key = (run_count,)
367
363
 
@@ -370,7 +366,7 @@ class FixedBatchRunner:
370
366
  if self.agent_reporters:
371
367
  agent_vars = self.collect_agent_vars(model)
372
368
  for agent_id, reports in agent_vars.items():
373
- agent_key = model_key + (agent_id,)
369
+ agent_key = (*model_key, agent_id)
374
370
  self.agent_vars[agent_key] = reports
375
371
  # Collects data from datacollector object in model
376
372
  if results is not None:
@@ -395,7 +391,6 @@ class FixedBatchRunner:
395
391
 
396
392
  If your model runs in a non-standard way, this is the method to modify
397
393
  in your subclass.
398
-
399
394
  """
400
395
  while model.running and model.schedule.steps < self.max_steps:
401
396
  model.step()
@@ -407,19 +402,19 @@ class FixedBatchRunner:
407
402
 
408
403
  def collect_model_vars(self, model):
409
404
  """Run reporters and collect model-level variables."""
410
- model_vars = OrderedDict()
411
- for var, reporter in self.model_reporters.items():
412
- model_vars[var] = reporter(model)
413
-
405
+ model_vars = {
406
+ var: reporter(model) for var, reporter in self.model_reporters.items()
407
+ }
414
408
  return model_vars
415
409
 
416
410
  def collect_agent_vars(self, model):
417
411
  """Run reporters and collect agent-level variables."""
418
- agent_vars = OrderedDict()
412
+ agent_vars = {}
419
413
  for agent in model.schedule._agents.values():
420
- agent_record = OrderedDict()
421
- for var, reporter in self.agent_reporters.items():
422
- agent_record[var] = getattr(agent, reporter)
414
+ agent_record = {
415
+ var: getattr(agent, reporter)
416
+ for var, reporter in self.agent_reporters.items()
417
+ }
423
418
  agent_vars[agent.unique_id] = agent_record
424
419
  return agent_vars
425
420
 
@@ -471,12 +466,10 @@ class FixedBatchRunner:
471
466
 
472
467
  df = pd.DataFrame(records)
473
468
  rest_cols = set(df.columns) - set(index_cols)
474
- ordered = df[index_cols + list(sorted(rest_cols))]
469
+ ordered = df[index_cols + sorted(rest_cols)]
475
470
  ordered.sort_values(by="Run", inplace=True)
476
471
  if self._include_fixed:
477
- for param in self.fixed_parameters.keys():
478
- val = self.fixed_parameters[param]
479
-
472
+ for param, val in self.fixed_parameters.items():
480
473
  # avoid error when val is an iterable
481
474
  vallist = [val for i in range(ordered.shape[0])]
482
475
  ordered[param] = vallist
@@ -539,7 +532,6 @@ class BatchRunner(FixedBatchRunner):
539
532
  Note that by default, the reporters only collect data at the *end* of the
540
533
  run. To get step by step data, simply have a reporter store the model's
541
534
  entire DataCollector object.
542
-
543
535
  """
544
536
 
545
537
  def __init__(
@@ -582,7 +574,6 @@ class BatchRunner(FixedBatchRunner):
582
574
  collected at the level of each agent present in the model at
583
575
  the end of the run.
584
576
  display_progress: Display progress bar with time estimation?
585
-
586
577
  """
587
578
  warn(
588
579
  "BatchRunner class has been replaced by batch_run function. Please see documentation.",
@@ -722,7 +713,7 @@ class BatchRunnerMP(BatchRunner): # pragma: no cover
722
713
  if self.agent_reporters:
723
714
  agent_vars = self.collect_agent_vars(model)
724
715
  for agent_id, reports in agent_vars.items():
725
- agent_key = model_key + (agent_id,)
716
+ agent_key = (*model_key, agent_id)
726
717
  self.agent_vars[agent_key] = reports
727
718
  if hasattr(model, "datacollector"):
728
719
  if model.datacollector.model_reporters is not None:
@@ -735,9 +726,9 @@ class BatchRunnerMP(BatchRunner): # pragma: no cover
735
726
  ] = model.datacollector.get_agent_vars_dataframe()
736
727
 
737
728
  # Make results consistent
738
- if len(self.datacollector_model_reporters.keys()) == 0:
729
+ if len(self.datacollector_model_reporters) == 0:
739
730
  self.datacollector_model_reporters = None
740
- if len(self.datacollector_agent_reporters.keys()) == 0:
731
+ if len(self.datacollector_agent_reporters) == 0:
741
732
  self.datacollector_agent_reporters = None
742
733
 
743
734
  def run_all(self):
mesa/datacollection.py CHANGED
@@ -33,13 +33,13 @@ The default DataCollector here makes several assumptions:
33
33
  * The model has a schedule object called 'schedule'
34
34
  * The schedule has an agent list called agents
35
35
  * For collecting agent-level variables, agents must have a unique_id
36
-
37
36
  """
38
- from functools import partial
39
37
  import itertools
38
+ import types
39
+ from functools import partial
40
40
  from operator import attrgetter
41
+
41
42
  import pandas as pd
42
- import types
43
43
 
44
44
 
45
45
  class DataCollector:
@@ -50,11 +50,8 @@ class DataCollector:
50
50
  functions which actually collect them. When the collect(...) method is
51
51
  called, it collects these attributes and executes these functions one by
52
52
  one and stores the results.
53
-
54
53
  """
55
54
 
56
- model = None
57
-
58
55
  def __init__(self, model_reporters=None, agent_reporters=None, tables=None):
59
56
  """Instantiate a DataCollector with lists of model and agent reporters.
60
57
  Both model_reporters and agent_reporters accept a dictionary mapping a
@@ -87,13 +84,13 @@ class DataCollector:
87
84
  Model reporters can take four types of arguments:
88
85
  lambda like above:
89
86
  {"agent_count": lambda m: m.schedule.get_agent_count() }
90
- method with @property decorators
91
- {"agent_count": schedule.get_agent_count()
92
- class attributes of model
87
+ method of a class/instance:
88
+ {"agent_count": self.get_agent_count} # self here is a class instance
89
+ {"agent_count": Model.get_agent_count} # Model here is a class
90
+ class attributes of a model
93
91
  {"model_attribute": "model_attribute"}
94
92
  functions with parameters that have placed in a list
95
93
  {"Model_Function":[function, [param_1, param_2]]}
96
-
97
94
  """
98
95
  self.model_reporters = {}
99
96
  self.agent_reporters = {}
@@ -122,8 +119,6 @@ class DataCollector:
122
119
  reporter: Attribute string, or function object that returns the
123
120
  variable when given a model instance.
124
121
  """
125
- if type(reporter) is str:
126
- reporter = partial(self._getattr, reporter)
127
122
  self.model_reporters[name] = reporter
128
123
  self.model_vars[name] = []
129
124
 
@@ -134,7 +129,6 @@ class DataCollector:
134
129
  name: Name of the agent-level variable to collect.
135
130
  reporter: Attribute string, or function object that returns the
136
131
  variable when given a model instance.
137
-
138
132
  """
139
133
  if type(reporter) is str:
140
134
  attribute_name = reporter
@@ -148,7 +142,6 @@ class DataCollector:
148
142
  Args:
149
143
  table_name: Name of the new table.
150
144
  table_columns: List of columns to add to the table.
151
-
152
145
  """
153
146
  new_table = {column: [] for column in table_columns}
154
147
  self.tables[table_name] = new_table
@@ -156,7 +149,7 @@ class DataCollector:
156
149
  def _record_agents(self, model):
157
150
  """Record agents data in a mapping of functions and agents."""
158
151
  rep_funcs = self.agent_reporters.values()
159
- if all([hasattr(rep, "attribute_name") for rep in rep_funcs]):
152
+ if all(hasattr(rep, "attribute_name") for rep in rep_funcs):
160
153
  prefix = ["model.schedule.steps", "unique_id"]
161
154
  attributes = [func.attribute_name for func in rep_funcs]
162
155
  get_reports = attrgetter(*prefix + attributes)
@@ -170,25 +163,23 @@ class DataCollector:
170
163
  agent_records = map(get_reports, model.schedule.agents)
171
164
  return agent_records
172
165
 
173
- def _reporter_decorator(self, reporter):
174
- return reporter()
175
-
176
166
  def collect(self, model):
177
167
  """Collect all the data for the given model object."""
178
168
  if self.model_reporters:
179
-
180
169
  for var, reporter in self.model_reporters.items():
181
170
  # Check if Lambda operator
182
171
  if isinstance(reporter, types.LambdaType):
183
172
  self.model_vars[var].append(reporter(model))
184
173
  # Check if model attribute
185
- elif isinstance(reporter, partial):
186
- self.model_vars[var].append(reporter(model))
174
+ elif isinstance(reporter, str):
175
+ self.model_vars[var].append(getattr(model, reporter, None))
187
176
  # Check if function with arguments
188
177
  elif isinstance(reporter, list):
189
178
  self.model_vars[var].append(reporter[0](*reporter[1]))
179
+ # TODO: Check if method of a class, as of now it is assumed
180
+ # implicitly if the other checks fail.
190
181
  else:
191
- self.model_vars[var].append(self._reporter_decorator(reporter))
182
+ self.model_vars[var].append(reporter())
192
183
 
193
184
  if self.agent_reporters:
194
185
  agent_records = self._record_agents(model)
@@ -202,7 +193,6 @@ class DataCollector:
202
193
  row: A dictionary of the form {column_name: value...}
203
194
  ignore_missing: If True, fill any missing columns with Nones;
204
195
  if False, throw an error if any columns are missing
205
-
206
196
  """
207
197
  if table_name not in self.tables:
208
198
  raise Exception("Table does not exist.")
@@ -225,7 +215,6 @@ class DataCollector:
225
215
 
226
216
  The DataFrame has one column for each model variable, and the index is
227
217
  (implicitly) the model tick.
228
-
229
218
  """
230
219
  return pd.DataFrame(self.model_vars)
231
220
 
@@ -234,16 +223,15 @@ class DataCollector:
234
223
 
235
224
  The DataFrame has one column for each variable, with two additional
236
225
  columns for tick and agent_id.
237
-
238
226
  """
239
227
  all_records = itertools.chain.from_iterable(self._agent_records.values())
240
228
  rep_names = list(self.agent_reporters)
241
229
 
242
230
  df = pd.DataFrame.from_records(
243
231
  data=all_records,
244
- columns=["Step", "AgentID"] + rep_names,
232
+ columns=["Step", "AgentID", *rep_names],
233
+ index=["Step", "AgentID"],
245
234
  )
246
- df = df.set_index(["Step", "AgentID"])
247
235
  return df
248
236
 
249
237
  def get_table_dataframe(self, table_name):
@@ -251,7 +239,6 @@ class DataCollector:
251
239
 
252
240
  Args:
253
241
  table_name: The name of the table to convert.
254
-
255
242
  """
256
243
  if table_name not in self.tables:
257
244
  raise Exception("No such table.")
mesa/main.py CHANGED
@@ -1,8 +1,9 @@
1
- import sys
2
1
  import os
3
- import click
2
+ import sys
4
3
  from subprocess import call
5
4
 
5
+ import click
6
+
6
7
  PROJECT_PATH = click.Path(
7
8
  exists=True, file_okay=False, dir_okay=True, resolve_path=True
8
9
  )
@@ -14,7 +15,6 @@ COOKIECUTTER_PATH = os.path.join(os.path.dirname(SCRIPTS_DIR), COOKIECUTTER_DIR)
14
15
  @click.group()
15
16
  def cli():
16
17
  "Manage Mesa projects"
17
- pass
18
18
 
19
19
 
20
20
  @cli.command()
@@ -30,7 +30,7 @@ def runserver(project):
30
30
 
31
31
  with open("run.py") as f:
32
32
  code = compile(f.read(), "run.py", "exec")
33
- exec(code, {}, {})
33
+ exec(code, {}, {}) # noqa: S102
34
34
 
35
35
 
36
36
  @click.command()
mesa/model.py CHANGED
@@ -2,7 +2,6 @@
2
2
  The model class for Mesa framework.
3
3
 
4
4
  Core Objects: Model
5
-
6
5
  """
7
6
  # Mypy; for the `|` operator purpose
8
7
  # Remove this __future__ import once the oldest supported Python is 3.10
@@ -10,11 +9,11 @@ from __future__ import annotations
10
9
 
11
10
  import random
12
11
 
13
- from mesa.datacollection import DataCollector
14
-
15
12
  # mypy
16
13
  from typing import Any
17
14
 
15
+ from mesa.datacollection import DataCollector
16
+
18
17
 
19
18
  class Model:
20
19
  """Base class for models."""
@@ -33,7 +32,6 @@ class Model:
33
32
  Attributes:
34
33
  schedule: schedule object
35
34
  running: a bool indicating if the model should continue running
36
-
37
35
  """
38
36
 
39
37
  self.running = True
@@ -43,14 +41,12 @@ class Model:
43
41
  def run_model(self) -> None:
44
42
  """Run the model until the end condition is reached. Overload as
45
43
  needed.
46
-
47
44
  """
48
45
  while self.running:
49
46
  self.step()
50
47
 
51
48
  def step(self) -> None:
52
49
  """A single step. Fill in here."""
53
- pass
54
50
 
55
51
  def next_id(self) -> int:
56
52
  """Return the next unique ID for agents, increment current_id"""