opensistemas-hub / osbrain

osBrain - A general-purpose multi-agent system module written in Python
https://osbrain.readthedocs.io/en/stable/
Apache License 2.0
175 stars 43 forks source link

How to set the attributes using OPP? #351

Open jott123 opened 4 years ago

jott123 commented 4 years ago

Hello, I have a problem with the OOP in osbrain and need some help, please.

According to the documentation you can use on_init to set attributes. However, the attributes are not set in the respective agent (I looked up the parameters due to debugging) and can only be used within the function. I want to send the parameters between agents. Outside of OOP it worked with agent.set_attr(a=5) or in a function withself.a=5 very good to set the attributes and to send them (I can also provide some code if it's helpful). But that doesn't help me for further programming with other packages. (Further I want to set up an Environment with simpy to work with time and I hope OOP is the solution.)

Here my short example for better understanding:

class Tree(Agent):
     def on_init(self):
           self.bind('PUSH', alias='kanal1')
           self.height=30

if __name__ == '__main__':
     ns = run_nameserver()
     ev1 = run_agent('baum_01', base=Tree)

     print(ev1.height)

     ns.shutdown()

If I try to test if the parameter is set in the agent [print(agent.parameter)] I get the following error. (Of course I also get the error if I try to send the parameter to another agent.)

AttributeError: remote object 'PYRONAME:baum_01@[adress of the name server] has no exposed Attribute or method 'height'

So, I'm not sure, why the parameters aren't really set. I tried different possibilities like self.set_attribute(height=30), self.height=30, self.__setattr__('height, 30) , Tree.height=30, write and call a function or some things like return super().on_init(), but I'm not totally sure about this special thing.

I'm probably missing something obvious, but I have been stuck on it for awhile. Does anyone have any suggestions? Thanks so much!

Peque commented 4 years ago

Thanks for reporting this issue.

The parameter is set, only not exposed by Pyro. You can create your own method to get the parameter or use .get_attr():

from osbrain import Agent
from osbrain import run_agent
from osbrain import run_nameserver

class Tree(Agent):
    def on_init(self):
        self.bind('PUSH', alias='kanal1')
        self.height = 30

    def get_height(self):
        return self.height

if __name__ == '__main__':
     ns = run_nameserver()
     ev1 = run_agent('baum_01', base=Tree)
     print(ev1.get_attr('height'))
     print(ev1.get_height())
     ns.shutdown()

We should probably update the documentation with this information if it is not clear enough.

jott123 commented 4 years ago

Thank you very much for the explanantion and example.

I always looked in the Pyro Attributes for the parameters and thought it isn't set. Now it's working thanks to you, I also tried the sending to another agent. It would be great to update the documentation.