<jupyter_start><jupyter_text>Collecting Data In this quick demo, we'll use the `datacollection` module in Mesa to extract information on the agent or model level. We'll use this to develop the Schelling Model code that we wrote last time. Ultimately, we'll take these capabilities and use them to create a fun little app for visualizing the Schelling model. Here's our base code:<jupyter_code>from mesa.space import SingleGrid
from mesa import Model, Agent
from mesa.time import RandomActivation
import numpy as np
import pandas as pd

class SchellingAgent(Agent):
    
    # adding a pos instance variable so that each agent can remember
    # where they are. Note that the pos can take the place of the name. 
    def __init__(self, pos, agent_type, homophily, model):
        super().__init__(pos, model)
        self.pos = pos
        self.type = agent_type
        self.homophily = homophily
    
    def step(self):
        
        pct_similar_neighbors = np.mean([
            self.type == other.type for other in self.model.grid.neighbor_iter(self.pos)
        ])
        
        if pct_similar_neighbors < self.homophily:
            self.model.grid.move_to_empty(self)
            self.model.moved += 1   
        
class SchellingModel(Model):
    
    # need to specify width, height, and density of agents
    # in the grid. 
    def __init__(self, width, height, density, homophily):
        
        self.schedule = RandomActivation(self)
        
        # create the grid
        self.grid = SingleGrid(width, height, torus=True)
        
        # loop through the grid, and add agents so that the 
        # overall density is roughly equal to the passed 
        # density
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if self.random.random() < density:
                
                agent_type = np.random.choice(["triangle", "square"])
                
                agent = SchellingAgent(pos = (x, y), 
                                 agent_type = agent_type, 
                                 homophily = homophily, 
                                 model = self)
                
                self.schedule.add(agent)    
                self.grid.position_agent(agent, (x, y))
            
    # this doesn't change, except that we will add a counter for the number of happy agents
    # who don't move in this timestep
    def step(self):
        self.moved = 0
        self.schedule.step()
        print(f"{self.moved} agents moved in this timestep")
SM = SchellingModel(20, 20, 0.9, 0.5)
SM.step()<jupyter_output>131 agents moved in this timestep
{'fraction_non_alphanumeric': 0.07450832072617247, 'fraction_numerical': 0.0056732223903177, 'mean_word_length': 1.9719101123595506, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '184568', 'license': 'MIT', 'n_tokens_mistral': 760, 'n_tokens_neox': 725, 'n_words': 256, 'path': 'lectures/abm/abm-2/data-collection-example-live.ipynb', 'repo_name': 'mimozairtem/PIC16B', 'size': '2644'}