Interactive jupyter notebook Tutorial¶
You will learn how to:¶
Create Simulation & Agents¶
Run a simulation and advance time¶
Give Goods & Trade¶
Capturing Data and Pandas¶
Communication between Simulation and Agents¶
Interactive jupyter / IPython notebook Tutorial¶
This tutorial works on jupyter notebook. Please download examples from here: https://github.com/AB-CE/examples and load the jupyter_tutorial by changing in the examples/jupyter_tutorial
folder and typing jupyter notebook jupyter_tutorial.ipynb
. Then you can execute the notebook cell by cell and observe abcEconomics at work.
import abcEconomics
simulation = abcEconomics.Simulation(name='ipythonsimulation', processes=1)
Creating the Agent¶
We create a simple agent and intialize it. An agent is an object that has propeties and does things. In python that is a class. We create an agent that has a name, knows the world size and can say his name.
The agent needs to inherit from abcEconomics.Agents. The __init__
function should not be overwritten, instead create an init
function. The init function will be called during initialisation.
The agents gets two parameters. All agents get the parameters we will specify in the next round. From agent_parameters the agents get only agent_parameters[id], where id is the number of the agent.
Agents have for now only one function. They can say their name.
class Agent(abcEconomics.Agent):
def init(self, world_size, family_name):
self.family_name = family_name
self.world_size = world_size
print(world_size)
def say(self):
print("hello I am %s my id %i and my group is '%s', it is the %i round" % (self.family_name, self.id, self.group, self.round))
From the abstract agent, we create four concrete agents.
agents = simulation.build_agents(Agent, 'agent',
world_size=30,
agent_parameters=[{'family_name': 'fred'},
{'family_name': 'astaire'},
{'family_name': 'altair'},
{'family_name': 'deurich'}])
agents
allows you to call each agents in the agents group. Each agent in this group has a group name, which is 'agent' and an id. Further we give each of the agents a parameter a family_name.
We can now run the simulation and let all agents say their name:
for r in range(5):
simulation.advance_round(r)
agents.say()
It is necessary to tell the simulation when a new round starts. The parameter can be any representation of time.
Giving a Good¶
abcEconomics provide goods. Goods are things that can be given, sold or transformed. We create 5 agents, the first one has a balls the agents pass the ball around.
class Kid(abcEconomics.Agent):
def init(self, num_kids):
self.num_kids = num_kids
if self.id == 0:
self.create('ball', 1)
def whether_I_have_the_ball(self):
if self['ball'] > 0:
print('*', end="", flush=True)
else:
print('.', end="", flush=True)
def give_the_ball_to_the_next_kid(self):
next_kid = (self.id + 1) % self.num_kids # the id of the next kid, if I am the last the first kid
if self['ball'] >= 1:
self.give(('kid', next_kid), good='ball', quantity=1)
self.create, creates an object. self.possession, checks how much of one object an agent has. self.give, gives an object to another agent, specied by its group name and its id.
num_kids = 5
simulation = abcEconomics.Simulation(name='ipythonsimulation', processes=1)
kids = simulation.build_agents(Kid, 'kid', number=num_kids,
num_kids=num_kids)
When agent_parameters is not specified the numer of agents to be created needs to be spezified
for r in range(7):
simulation.advance_round(r)
kids.whether_I_have_the_ball()
print()
kids.give_the_ball_to_the_next_kid()
Trade¶
from random import randrange
Well in every school yard we have a drug dealer.
class NewKid(abcEconomics.Agent):
def init(self, num_dealers):
self.num_dealers = num_dealers
self.create('money', 100) # don't we all wish you'd this function in real live?
def buy_drugs(self):
drug_dealer_id = randrange(self.num_dealers)
self.buy(('drug_dealer', drug_dealer_id), good='drugs', quantity=1, price=10)
def print_possessions(self):
print(' ' + self.group + str(dict(self.possessions())))
The new kids, approach a random drug dealer and offer him 10 bucks.
class DrugDealer(abcEconomics.Agent):
def init(self):
self.create('drugs', 1)
def sell_to_customers(self):
for offer in self.get_offers('drugs'):
if offer.price >= 10 and self['drugs'] >= 1:
self.accept(offer)
def print_possessions(self):
print(' ' + self.group + str(dict(self.possessions())))
Drug dealer look at all the sell offers they get and decide to sell only to those kids that are willing to give them at least 10 dollars.
num_dealers = 1
simulation = abcEconomics.Simulation(name='school_yard', processes=1)
drug_dealers = simulation.build_agents(DrugDealer, 'drug_dealer', number=num_dealers)
customers = simulation.build_agents(NewKid, 'customer', number=1,
num_dealers=num_dealers)
builds 1 drug dealer and one customer.
kids = drug_dealers + customers
Groups of agents can be merged to 'super' groups. We will print the amount of drugs and money all kids have for each of the two kids
for r in range(2):
simulation.advance_round(r)
print('Customer offers 10 dollar:')
customers.buy_drugs()
kids.print_possessions()
print('Drug Dealer accepts or rejects the offer:')
drug_dealers.sell_to_customers()
kids.print_possessions()
print()
When looking at round one, one can see that after the customer offered 10 dollars, the 10 dollars are not available to the dealer until the deal has either been accepted or rejected. After the drug dealer accepts the offer in the 0 round, the money is transfered to the drug dealer and the drugs to the customer.
In round 1, where the drug dealer runs out of drugs the 10 dollars go back to the customer.
Lets capture data¶
There are three ways of capturing data. aggregate
and panel
collect data from a specified group at a specified point of time. This has the advantage that there is no logging code in the agent class. self.log('name', value)
saves a value under a certain name.
from math import sin
class DataDealer(abcEconomics.Agent):
def init(self):
self.count = 0
self.create('money', 0)
def counting(self):
self.count += 1
self.curve = sin(self.count / 100)
self.create('money', self.curve * self.id)
simulation = abcEconomics.Simulation(name='gatherdata', processes=1)
It is specified which agents group collects which variables and possessions.
datadealers = simulation.build_agents(DataDealer, 'datadealer', number=10)
Every round the groups need to be instructed to collect the according data. simulation.finalize() must be called after the simulation, to write the data! Otherwise the program hangs.
for r in range(100):
simulation.advance_round(r)
datadealers.counting()
datadealers.agg_log(variables=['count'])
datadealers.panel_log(goods=['money'], variables=['curve'])
simulation.finalize()
We can find the directory of the simulation data by using the simulation.path
property
print(simulation.path)
In that directory are the data files and a describtion.txt
import os
os.listdir(simulation.path)
Using statistical software¶
import pandas as pd
%matplotlib inline
df = pd.read_csv(simulation.path + '/panel_datadealer.csv')
df.head(20)
df.pivot(index='round', columns='id', values='money').plot()
Communication between Simulation and Agents¶
simulation = abcEconomics.Simulation()
class Communicator(abcEconomics.Agent):
def report_my_name(self):
return self.name
def do_as_told(self, time, text):
print("it is %i o'clock and I have to say %s" % (time, text))
communicators = simulation.build_agents(Communicator, 'communicator', number=3)
for time in range(3):
simulation.advance_round(time)
communicators.report_my_name()
communicators.do_as_told(time=time, text="Right says fred")
One caviat is that only keyword arguments work.