The Repo on GitHub

We’ve agreed not to cater to client-server at all, to the degree we can manage it. As a first start, we’ve removed the World-Client variant classes and will simply be working with Biots sending messages to the World, and the World sending messages back. We’ll see how that goes. I have one concern. Well, one that I care to mention.

Our tests are much as they were, just simplified a bit in view of the new simpler scheme:

class TestCase:
    def test_something(self):
        assert True is True

    def test_create_biot(self):
        biot = Biot()
        assert isinstance(biot, Biot)

    def test_starting_location(self):
        biot = Biot()
        assert biot.location == Point(0, 0)

    def test_biot_in_world(self):
        biot = Biot()
        world = World()
        world.add(biot)
        point = Point(10, 10)
        assert biot.id == 101
        assert biot.location == point

    def test_move(self):
        world = World()
        biot = Biot()
        world.add(biot)
        point = biot.location
        world.move(biot.id, 10, 0)
        new_point = biot.location
        assert new_point == Point(point.x + 10, point.y)

The basic scheme is that Biots are created with no parameters and they add themselves to the world. When that happens, the world sets their id and location. I think the final test is wrong, that we should pass the biot, not the id to the move method. I guess we didn’t notice that this morning.

Anyway, on the move, the world sets the biot to a new location. The code for add and move is this:

class World:
    def __init__(self):
        self.biots = Entities()

    def add(self, biot):
        location = Point(10, 10)
        biot.id = 101
        biot.location = location
        self.biots.place(biot)

    def move(self, biot_id, dx, dy):
        biot = self.biots.contents[biot_id]
        location = biot.location
        biot.location = Point(location.x + dx, location.y + dy)

Let’s fix that test right now. I think Bryan will forgive me.

    def test_move(self):
        world = World()
        biot = Biot()
        world.add(biot)
        point = biot.location
        world.move(biot, 10, 0)
        new_point = biot.location
        assert new_point == Point(point.x + 10, point.y)

And …

    def move(self, biot, dx, dy):
        biot = self.biots.contents[biot.id]
        location = biot.location
        biot.location = Point(location.x + dx, location.y + dy)

Green, Commit: Fixed test and move code that was passing id not biot.

Here’s Biot:

class Biot:
    def __init__(self):
        self.id = None
        self.location = Point(0, 0)

In the fullness of time, I imagine that we’ll replace those member variables and direct access with accessors, “properties” as Python calls them, but for now this is just what we want.

Concern

I do have one concern: as presently conceived, when the Biot asks the World to do something like move the Biot, the World sends a number of messages back. So far, it just sends id and location (which are really direct setters but think “method”). As such, while the Biot is still executing its code that asked for the move, it will be receiving messages that explicitly change its state.

One might expect something more like send the move request, get back a result of some kind, use the result inside Biot to update your own state. I’m honestly not sure whether there is a horrible drawback to the world just updating the Biot as it sees fit, in essence while still processing the Biot’s call. So that move might properly be called move_and_update_me or something of that kind.

We’ll discuss this concern, Bryan and I, and surely we’ll bring it up on the Zoom.

Anyway, that’s my report for the day.