Glad you got it working.
A couple of observations:

> This is the working version of my visualization:

> class Agent:
>    def __init__ (self, x=100, y=100):
>        self.name = random.randint(0, 100000)
>        self.x = x
>        self.y = y
>
>    def __repr__ (self):
>        return str(self.name)
>
>    def display(self, canvas, x, y):
>        """Display an image of this Agent on the canvas."""
>        canvas.coords(self.ID, x, y)

You don't need the x,y since its your own x,y, so you could just use:

canvas.coords(self.ID,self.x,self.y)

This is better OO practice that the Environment extracting
the x,y from the agent and passing them back as parameters.
Objects should "do it to themselves" to summarize a principle
known as the Law of Demeter...

>    def rand_vec(self):
>        return random.randint(-5, 5), random.randint(-5, 5)
>
>
> class Environment:
>    def __init__ (self):
>        self.alive_agents = []
>
>    def step(self):
>        for obj in self.alive_agents:
>            old_x, old_y = obj.x, obj.y
>            change_x, change_y = obj.rand_vec()
>            obj.x, obj.y = old_x + change_x, old_y + change_y
> #            print obj.name, '\t:\t ', old_x, old_y,' -> ', obj.x, 
> obj.y

Similarl;y you have the Environment changing the objects
coordinates, but really the coords belong to the object
therefore the object should change them itself.
After all there is nothing in the algorithm that relies on Environment
data - and even if there were the Environment should pass that to
obj as arguments...

Thus Environment should just call

obj.set_coords()

And the algorithm above moves into the Agent method set_coords()

The golden rule is that whichever object owns the data being changed
should be the one that does the changing. If you ever find yourself
accessing another objects data so as to change it then there is
something wrong with your design.

>    def add_agent(self, agent):
> #        print agent.name, ' was added to environment'
>        self.alive_agents.append(agent)
>
> class GraphEnvironment(Tkinter.Frame):
>    def __init__ (self, root):
>        self.root = root
>        self.background = Tkinter.Canvas(self.root, width=200, 
> height=200,
> background="white")
>
>        for agent in env.alive_agents:
>            agent.ID=self.background.create_image (100, 100, anchor=
> Tkinter.NW, image=picture)

And this is a good example of an exception to the rule.
Purists would argue that you should create an Agent.setID
method but it would only be a simple assignment so this is ok.
The assignment uses Environment data so I'd be happy to
leave as-is.

>        self.background.pack(fill=Tkinter.BOTH,expand=Tkinter.YES)
>        self.root.after(100,self.NextDay)
>
>    def NextDay(self):
>        env.step()
>        for agent in env.alive_agents:
>            agent.display(self.background, agent.x, agent.y)
>        self.root.after(200,self.NextDay)
>
> print '\tBORN'
> env = Environment()
> for obj in range(100):
>    child = Agent()
> #    print child, ' was born'
>    env.add_agent(child)

You could just:

      env.add_agent(Agent())

However these are minor points of OOP style.
I'm glad you got it working.

Alan G. 

_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to