class Position():
    """An instance is a position in an org chart.

    Instance attributes:
        title (non-empty string): the title of this Position
        holder (lowercase string representing a netid, or int 0, or special
            value None): the netid of the person holding this Position, or
            int 0 if the position isn't vacant but a netid for the position
            holder is unspecified, or None if the position is vacant.
        sups (list of Positions, possibly empty): The list of Positions that
            are direct supervisors of this Position. There are no repeats in it.
        subs (list of Positions, possibly empty): The list of Positions that
            this Position directly supervises, i.e., its direct subordinates.
            There are no repeats in it.
        search_in_progress: bool, True if and only if there is a current search
            for that position

    Class invariant
    (i.e., must be true before and after every function/method call):
        Among any connected set of Positions, there are no supervisory cycles,

        Among any connected set of Positions, there is one and only one Position
            whose `sups` attribute is [].

        If Position pos1 has Position pos2 in its `sups` list, then pos2 has
            pos1 in its `subs` list.

        If Position pos1 has Position pos2 in its `subs` list, then pos2 has
            pos1 in in its `sups` list."""

    def __init__(self, t, in_sups, in_subs, search_in_progress=False):
        """A new Position with title t, sups set to (a shallow copy)
        of in_sups and subs set to (a shallow copy) of in_subs, any repeats
        excluded.

        The supervisors of any Positions in in_subs are updated to include this
        Position, and the subordinates of any Positions in in_sups are updated
        to include this Position.

        Preconditions:
            No supervisory cycles are introduced by this Position.
            All arguments are valid values for the respective parameters they
                will be assigned to.
        """
        self.title = t
        self.sups = []
        for sup in in_sups:
            self.become_sub_of(sup)

        self.subs = []
        for sub in in_subs:
            sub.become_sub_of(self)
        self.search_in_progress = search_in_progress

    def become_sub_of(self, sup):
        """Make self a direct subordinate of Position sup, if not already.
        """
        assert isinstance(sup, Position), 'bad value for sup: ' + repr(sup)

        if self not in sup.subs:
            sup.subs.append(self)
            self.sups.append(sup)

    def __str__(self):
        return self.title + "\n\n"

    def __repr__(self):
        return self.title


    def collapse_upwards(self):
        """ Collapses this Position into its supervisor Position.

        Preconditions: this Position has exactly one direct supervisor.

        Example: suppose this Position has title 'B',
        its single direct supervisor has title 'A',
        and its direct subordinates have titles 'C1' and 'C2'.
                A
                | \
           E    B  D?  [maybe there are other subs of A, who knows]
            \  / \
             C1  C2 [note that subordinates can have other supervisors]

        This method changes the situation to
          E     A
           \  / | \
            C1  C2  D

        (The order of the subordinates doesn't matter.)

        Thus, in our example,
          1. A is added to the sups list of C1 and C2
             (remember to avoid adding repeats)
          2. C1 and C2 are added to the subs list of A
             (remember to avoid adding repeats)
          3. B is removed from the subs list of A
             (recall that mylist.remove(x) removes first x from mylist)
          4. B is removed from the sups list of C1 and C2
          5. B's sups list becomes the empty list
          6. B's subs list becomes the empty list
          (Don't change anything else about B.)

        YOU MAY NOT MAKE USE OF PREDEFINED HELPERS FROM A4, but you may write
        your own, as long as you specify them carefully.
        Don't worry about or check for supervisory cycles being introduced."""

