Hamza
Hamza

Reputation: 75

Is dot notation between two separate instance variables allowed? How does it work?

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?

Upvotes: 0

Views: 190

Answers (1)

Lenormju
Lenormju

Reputation: 4368

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).

Upvotes: 1

Related Questions