0

I am working on my first python project, a tower defense game called Ants vs Bees. I need some assistance understanding one aspect of the starter code, namely the implementation of tracking the entrances of a specific place.

import random
from ucb import main, interact, trace
from collections import OrderedDict


class Place(object):
    """A Place holds insects and has an exit to another Place."""

    def __init__(self, name, exit=None):
        """Create a Place with the given NAME and EXIT.
        name -- A string; the name of this Place.
        exit -- The Place reached by exiting this Place (may be None).
        """
        self.name = name
        self.exit = exit
        self.bees = []  # A list of Bees
        self.ant = None  # An Ant
        self.entrance = None  # A Place
        # Phase 1: Add an entrance to the exit
        if self.exit is not None:
            exit.entrance = self

I do not understand Phase 1, i.e. the last two lines of this starter code. How can we use dot notation to put one instance variable in front of another instance variable? What does equating it to self do? I have tried isolating this class, making objects and then printing both attributes individually but it throws me errors, leading me to suspect that perhaps the starter code is faulty? It would mean a huge deal to me to you might assist me in understanding how they are adding an entrance to the exit using exit.entrance = self?

8
  • 1
    In exit.entrance = self, it's not referring to entrance as a local variable at all, it's just describing what property of exit to set. The fact that you also have a local variable named entrance is just coincidence. Commented Jun 16, 2021 at 14:54
  • exit.entrance means set the value of entrance in exit object to self. Its not checking equality, rather assigning the value to entrance Dot Notation Commented Jun 16, 2021 at 14:54
  • That is to say, it's equivalent to setattr(exit, 'entrance', self), not setattr(exit, entrance, self). Commented Jun 16, 2021 at 14:55
  • Remember that self has nt special meaning. It's just the name of the local variable that happens to hold a reference the Place instance being initialized. In your code, self and exit are two independent Place instances. Writing self.entrance references the entrance attribute of self; writing exit.entrance references the entrance attribute of exit. Commented Jun 16, 2021 at 15:03
  • Whenever your initialize a Place instance, you have the option of specifying an additional Place instance via the exit parameter to serve as the "exit" of the new place. If an exit Place is provided, then the new Place (aka, self) is assigned to the entrance attribute of the exit. Commented Jun 16, 2021 at 15:04

1 Answer 1

1

Here is an example :

class Place:
    def __init__(self, name, exit=None):
        self.name = name
        self.exit = exit
        self.entrance = None
        # if this place is connected to another one, it means that exiting this place leads to the other
        # so if we have an exit,
        if self.exit is not None:
            # it means that for this exit Place, we are an entrance to it
            exit.entrance = self
            # so the entrance for the Exit Place is this Place we are instantiating
            # print(f"the exit of the {name!s} is the {exit.name!s}, so the entrance of the {exit.name!s} is the {name!s}")

    # I'm defining these two functions to help readability later
    def __str__(self) -> str:
        return self.name
    def __repr__(self) -> str:
        entrance_name = self.entrance.name if self.entrance is not None else "None"
        exit_name = self.exit.name if self.exit is not None else "None"
        return f"Place({self.name!r}, entrance={entrance_name!s}, exit={exit_name!s})"


plain = Place("plain")  # at first we define a plain
print(repr(plain), "\n")
forest = Place("forest", exit=plain)  # we can go from the forest to the plain
print(repr(plain))
print(repr(forest), "\n")
lake = Place("lake", exit=forest)  # and we can go from the lake to the forest
print(repr(plain))
print(repr(forest))
print(repr(lake), "\n")

whose output is :

Place('plain', entrance=None, exit=None) 

Place('plain', entrance=forest, exit=None)
Place('forest', entrance=None, exit=plain) 

Place('plain', entrance=forest, exit=None)
Place('forest', entrance=lake, exit=plain)
Place('lake', entrance=None, exit=forest) 

At first we have a plain with no entrance nor exit.
After adding the forest, whose exit is the plain, the entrance to the plain becomes the forest. After adding the tree, whose exit is the forest, the entrance to the forest becomes the tree.

It makes a linking : plain <--exit----entrance--> forest <--exit----entrance--> lake.
In the context of the forest (self), the plain (exit) entrance is the forest (self).
In the context of the lake (self), the forest (exit) entrance is the lake (self).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.