Kala: agent-based econ games
Project description
Kala, agent-based econ games
This package defines a general framework to implement different agent-based models (ABMs). One of the most important things that we aim to support is a networked topology, with agents being represented as nodes that can only be matched against their neighbours. However, we also support games that do not include a network topology.
To begin with, we have used the framework to coded the model presented in Ernst, Ekkehard. ‘The Evolution of Time Horizons for Economic Development’, 2004. [Ernst04] (DOI). We added some extensions, including support for networks.
Installation
The package is published to PyPI and can be installed directly using
$ pip install kala-econ-games
User guide
The user-facing interface of the package is located under kala.models but the concrete classes have been added to the top-level package so that they can be imported directly.
Before going into more detail, we'll give and comment a full example that creates a working game.
We start with some imports
from kala import (
GamePlan,
get_gini_coefficient,
get_saver_agents,
get_summed_score,
init_savers_gamestate_from_netz,
play_game,
shocks,
)
We use Networkx to define the network topologies. There are a great deal of real-world networks the Netzschleuder repository and these can be downloaded directly and a new game can be initialised using
network_name = "dolphins"
game = init_savers_gamestate_from_netz(network_name, savers_share=0.5, memory_length=4)
agents = game.agents
We have implemented some shocks which are defined outside the game, and used as part of a GamePlan. A game and a game plan are passed directly to the play_game function which is the primary entry point to run the simulations. The game can be inspected directly (note for example the use of game.agents) and we provide some functions to retrieve basic statistics.
shocks = {
4: [shocks.RemovePlayer(agents[2])],
6: [shocks.SwapRandomEdge()],
}
game_plan = GamePlan(10, shocks=shocks)
for time, state in play_game(game, game_plan):
savers = get_saver_agents(state)
num_savers = len(savers)
total_score = get_summed_score(state.agents)
saver_score = get_summed_score(savers)
gini = get_gini_coefficient(state.agents)
print(f"Time {time}: num_agents={len(state.agents)}; num_savers={num_savers}")
print(f"\tTotal: {round(total_score, 2)}")
print(f"\tSavers: {round(saver_score, 2)}")
print(f"\tGini: {round(gini, 3)}")
More generally, it can be useful to work directly with networks and these can be downloaded and converted to a NetworkX graph using the NetzDatabase interface.
from kala import NetzDatabase
db = NetzDatabase()
graph = db.read_netzschleuder_network(network_name)
Agents
Agents should be the starting point of any model. Agents are created by passing arguments that are specific to the model, but that can be broken down into two categories (traits and properties). Once created, an agent should have all of the necessary information to call the update() method which for example adds a payoff to the running total of the agent.
In order to implement the models in [Ernst04], we define the class SaverAgent. Typically, one would initialise an instance using the init_saver_agent function.
Traits and properties
Traits and properties belong to agents. Roughly speaking, traits were thought as fixed and properties as changing in time, but the distinction is no longer clear-cut and in the future we might decide to deprecate one of the two classes.
Memory rules
Agents that have a memory can change their properties in response to the interactions they have had in the last turns. We control how they behave using an update or memory rule. We have added support for a single rule at the moment (SaverFlipAfterFractionLost) but we plan to add support for more.
Graphs
We use graphs directly from NetworkX, and we implement an AgentPlacementNetX which manages keeps track of where agents are placed in the Graph.
Strategies
A strategy encodes what two agents should do when they "encounter" and they play each other. The main method exposed is calculate_payoff().
Following [Ernst04], we coded the class SaverCooperationPayoffStrategy which draws payoffs from a log-normal distribution with mean 1.0 and a variance (and therefore risk) that depends on the specialization of each agent.
Games
A game (or more precisely a GameState) holds all the information of the graph, the agents, etc, at any given point.
The main way to interect with a game is to define a GamePlan which defines the number of steps that the game will go on for (and possibly shocks are applied and when), and call play_game.
Contributing
The package is written in Python (minimal version: 3.10).
We recommend that the installation is made inside a virtual environment.
While you can use conda or Python's built-in venv, we recommend uv (https://docs.astral.sh/uv/).
Local install with uv
If you don't have uv installed, follow the instructions on their documentation.
Once uv is installed, navigate to the project's root directory and run:
$ uv sync
This command creates a virtual environment in the .venv directory and installs all project dependencies.
You have two options for using the virtual environment:
- Activate the environment using:
$ source .venv/bin/activate
- Execute scripts or programs directly within the virtual environment by prefixing your commands with
uv run:
$ uv run python my_script.py
$ uv run pytest tests/
For more information on using uv, please refer to the official documentation.
Local install of the package
Once we are working inside an active virtual environment, we install (the dependencies and) the package by running
$ pip install -e .
Development Environment
The package uses several tools (linters, formatters, etc.) that automatically run checks and help correct simple problems.
The recommended way to set up your development environment is using uv.
To install all development tools and the package, run
$ uv sync --dev
We use just to manage common development tasks like linting, formatting, and testing.
With uv installed, the easiest way to install just is via the command
$ uv tool install rust-just
Once installed, to see all available commands run
$ just --list
Contributing with code
When contributing code, please create a new branch with a descriptive name, such as feat/add-super-custom-agent.
Once you're ready, create a pull request. We have automated checks that run on every pull request. Your code must pass these checks before it can be merged. If the checks fail, update your code and push the changes to re-trigger the checks. We also recommend requesting a code review from another maintainer before merging.
Before submitting a pull request, it's highly recommended to run the checks locally to catch any issues early. Run the following command to execute all checks:
$ just
You can format the code automatically by running
$ just format-all
Or only run the test suite with
just test
If the just command passes locally, it's highly likely that the automated CI/CD pipeline on GitHub will also pass.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kala_econ_games-1.0.0.tar.gz.
File metadata
- Download URL: kala_econ_games-1.0.0.tar.gz
- Upload date:
- Size: 99.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.30
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a9ed0da9e820a5a466ec4ff5347437735c145251ba6f350c2fe362007e9acc5
|
|
| MD5 |
9bb47aaff158a9cb86a42919b1c70e13
|
|
| BLAKE2b-256 |
1684a42d8f1f57aac28c65e2bf2c12a4f7f599d5e23883a2faeb60606bff1b8d
|
File details
Details for the file kala_econ_games-1.0.0-py3-none-any.whl.
File metadata
- Download URL: kala_econ_games-1.0.0-py3-none-any.whl
- Upload date:
- Size: 21.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.30
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2673e987dc08793d44defec8eef2af5db2a86ce9bcb594c64c8defb695751cf3
|
|
| MD5 |
6c9196f0b0917105eb88f02a429abcb3
|
|
| BLAKE2b-256 |
d399a2930d807eb3a247ae774aa4ff479e82144eefdc09d26da2787bf8cf0045
|