projectmesa / mesa

Mesa is an open-source Python library for agent-based modeling, ideal for simulating complex systems and exploring emergent behaviors.
https://mesa.readthedocs.io
Other
2.31k stars 847 forks source link

TypeError: Positional Arguments #715

Open gamzetuncay opened 4 years ago

gamzetuncay commented 4 years ago

Describe the bug When I remove 'model' parameter from Consumer in agents.py , the server opens, but the step and start buttons does not work

runfile('C:/Users/gamzetuncay/Desktop/ticket_sales/run.py', wdir='C:/Users/gamzetuncay/Desktop/ticket_sales')
Traceback (most recent call last):

  File "<ipython-input-1-c6dfca6f93a1>", line 1, in <module>
    runfile('C:/Users/gamzetuncay/Desktop/ticket_sales/run.py', wdir='C:/Users/gamzetuncay/Desktop/ticket_sales')

  File "C:\Users\gamzetuncay\Anaconda3\envs\pygeospatial\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile
    execfile(filename, namespace)

  File "C:\Users\gamzetuncay\Anaconda3\envs\pygeospatial\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/gamzetuncay/Desktop/ticket_sales/run.py", line 8, in <module>
    from server import server

  File "C:\Users\gamzetuncay\Desktop\ticket_sales\server.py", line 54, in <module>
    "Ticket Sales", model_params)

  File "C:\Users\gamzetuncay\Anaconda3\envs\pygeospatial\lib\site-packages\mesa\visualization\ModularVisualization.py", line 276, in __init__
    self.reset_model()

  File "C:\Users\gamzetuncay\Anaconda3\envs\pygeospatial\lib\site-packages\mesa\visualization\ModularVisualization.py", line 302, in reset_model
    self.model = self.model_cls(**model_params)

  File "C:\Users\gamzetuncay\Desktop\ticket_sales\model.py", line 48, in __init__
    consumer = Consumer((x, y), i, self)

  File "C:\Users\gamzetuncay\Desktop\ticket_sales\agents.py", line 29, in __init__
    super().__init__(pos, unique_id, model)

TypeError: __init__() takes 3 positional arguments but 4 were given

Expected behavior ---------agents.py

from mesa.visualization.modules import CanvasGrid, ChartModule
from mesa.visualization.ModularVisualization import ModularServer
from mesa.visualization.UserParam import UserSettableParameter

from model import TicketSalesModel
from agents import *

Shapes = {"Bought" : "images/consumer_bought.png",
          "Not Buy" : "images/consumer.png"}
Color = {"Bought" : "green",
          "Not Buy" : "blue"}
def ticket_sales_portrayal (agent):
    if agent is None:
        return
    portrayal = {}

    if type(agent) is Event:
        portrayal["Shape"] = "images/event.png"
        portrayal["scale"] = 0.4
        portrayal["Layer"] = 1
        (x,y) = agent.pos
        portrayal[x] = x
        portrayal[y] = y

    elif type(agent) is Consumer:
        portrayal["Shape"] = Shapes[agent.bought]
        portrayal["scale"] = 0.3
        portrayal["Layer"] = 2
        (x,y) = agent.pos
        portrayal[x] = x
        portrayal[y] = y

    return portrayal

canvas_element = CanvasGrid(ticket_sales_portrayal, 10, 10, 750, 750)
chart_element = ChartModule([{"Label": label, "Color": color} for (label,color) in Color.items()])

model_params = {
    "height": 10,
    "width": 10,
    "number_of_consumer": UserSettableParameter ('slider', 'number of consumers', 80, 0, 10000),
    "capacity": UserSettableParameter ('slider', 'capacity of venue', 10, 0, 200)
    }

server = ModularServer(TicketSalesModel, [canvas_element, chart_element],
                       "Ticket Sales", model_params)

---------model.py

from mesa import Model
from mesa.space import MultiGrid
from mesa.time import BaseScheduler
from mesa.datacollection import DataCollector

from agents import *

class TicketSalesModel (Model):
    """
    Ticket-Sales Predation Model
    """

    def __init__ (self, width=10, height=10,
                  number_of_consumer=80, capacity=10):
        super().__init__()

        self.height = height
        self.width = width
        self.number_of_consumer = number_of_consumer
        self.ticketsales = 0

        self.grid = MultiGrid(self.width, self.height, True)
        self.schedule = BaseScheduler(self)

        self.datacollector = DataCollector (
                {"Bought" : lambda consumer: self.count_type(consumer, "Not Buy")})

        # Create an event
        x = self.random.randrange(self.width)
        y = self.random.randrange(self.height)
        event = Event((x,y),self)
        self.grid._place_agent((x,y),event)
        self.schedule.add(event)

        # Create the consumers
        for i in range(self.number_of_consumer):
            #add the agent to a random grid cell
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            consumer = Consumer((x, y), i, self)
            print(consumer.unique_id)
            self.schedule.add(consumer)     
            self.grid._place_agent((x,y),consumer)

        self.running = True
        self.datacollector = DataCollector (
                {"Bought" : lambda consumer: self.count_type(consumer, "Bought")})

        #self.datacollector.collect(self)

    def step (self):
        self.schedule.step()
        self.datacollector.collect(self)
        print("n")
        self.ticketsales = 0

        if self.initial_capacity == self.ticketsales or self.count_type2(self) == 0:
            self.running = False            

    def run_model(self, step_count=20):
        for i in range (step_count):
            self.step()           

    def count_type(agent, condition):
        count =0
        consumers =[]
        if type(agent) == Consumer:
            consumers.append(agent) 
            for consumer in consumers:
                if consumer.bought == condition:
                    count += 1
        return count

---------server.py

from mesa.visualization.modules import CanvasGrid, ChartModule
from mesa.visualization.ModularVisualization import ModularServer
from mesa.visualization.UserParam import UserSettableParameter

from model import TicketSalesModel
from agents import *

Shapes = {"Bought" : "images/consumer_bought.png",
          "Not Buy" : "images/consumer.png"}
Color = {"Bought" : "green",
          "Not Buy" : "blue"}
def ticket_sales_portrayal (agent):
    if agent is None:
        return
    portrayal = {}

    if type(agent) is Event:
        portrayal["Shape"] = "images/event.png"
        portrayal["scale"] = 0.4
        portrayal["Layer"] = 1
        (x,y) = agent.pos
        portrayal[x] = x
        portrayal[y] = y

    elif type(agent) is Consumer:
        portrayal["Shape"] = Shapes[agent.bought]
        portrayal["scale"] = 0.3
        portrayal["Layer"] = 2
        (x,y) = agent.pos
        portrayal[x] = x
        portrayal[y] = y

    return portrayal

canvas_element = CanvasGrid(ticket_sales_portrayal, 10, 10, 750, 750)
chart_element = ChartModule([{"Label": label, "Color": color} for (label,color) in Color.items()])

model_params = {
    "height": 10,
    "width": 10,
    "number_of_consumer": UserSettableParameter ('slider', 'number of consumers', 80, 0, 10000),
    "capacity": UserSettableParameter ('slider', 'capacity of venue', 10, 0, 200)
    }

server = ModularServer(TicketSalesModel, [canvas_element, chart_element],
                       "Ticket Sales", model_params)

---------run.py

from server import server

server.port = 8503

server.launch()

To Reproduce

Additional context

Corvince commented 4 years ago

You can read your error from bottom to top to debug it yourself:

Last line:

TypeError: __init__() takes 3 positional arguments but 4 were given

You tried to call a function that takes 3 arguments with 4 arguments. But where?

second-to-last-line:

  File "C:\Users\gamzetuncay\Desktop\ticket_sales\agents.py", line 29, in __init__
    super().__init__(pos, unique_id, model)

So you called super().__init__ with pos, unique_id, model. Since this is a instance method you implicitly also pass self as a first argument, which makes it four arguments. I presume super refers to mesas agents base class, which is defined as follows:

class Agent:
    """ Base class for a model agent. """
    def __init__(self, unique_id, model):
        """ Create a new agent. """
        self.unique_id = unique_id
        self.model = model

So it only accepts the implicit argument self and id and model. But you also passed pos which it can't handle. Thus, your error.

However I don't know how this relates to

When I remove 'model' parameter from Consumer in agents.py , since you did not provide your agents.py, but only your server file twice.