class WackyQueue(): '''This class represents a WackyQueue A WackyQUeue is queue that operates with WackyNodes It stores its data in two linked lists. Every odd object is in a list. And the other holds every even object ''' def __init__(self): '''(WackyQueue) -> None This method instanciates a WackyQueue ''' # Representation Invariant # _size is how many objects the Queue contains # _head is the head of the one of the WackyQueues # _head2 is the second head of the WackyWueues # The hgher the number, the greater its priority # Which ever head holds 0 as its priority is the head of the odd # list # if self._head.get_priority is 0, it is the head of the odd list # if self._head2.get_priority is 0, it is the head of the odd list # END OF REPRESENTATION INVARIANT # Now cretaed the WackyHeads holding no information and # pointing to nothing # Make self._head's priotiry 0 by defualt to be the head of the odd # list, you will see why later. self._head = WackyNode(None, 0) self._head2 = WackyNode(None, 1) def insert(self, obj, pri): '''(WackyQueue, object, int) -> None This method puts an object in the Wacky Queue depending on its priority ''' # Create the new node new_node = WackyNode(obj, pri) # First you want to find the spot where the new node will go. 'in-head' # means the operation is currently in self._head and is loking for # where to insert the item # We also want to start comparing items from the top of the list if self._head.get_priority() is 0: current_check = 'in-head' current_node = self._head.get_next() elif self._head2.get_priority() is 0: current_check = 'in-head2' current_node = self._head2.get_next() # Next you want to make sure that the current node is not None if current_node is not None: current_pri = current_node.get_priority() # You want to keep track of what node was visited last in each list last_head_node = self._head last_head2_node = self._head2 # Loop through BOTH lists, by alternating until you find the spot while (current_node is not None) and (pri <= current_pri): # create a condition that does alternate checking if current_check == 'in-head': # Keep track of both current and LAST Nodes last_head_node = current_node current_node = last_head2_node.get_next() # Next you want to make sure that the current node is not None if current_node is not None: current_pri = current_node.get_priority() # Now to alternate make the current check to point to head2 current_check = 'in-head2' elif current_check == 'in-head2': # Keep track of both current and LAST Nodes last_head2_node = current_node current_node = last_head_node.get_next() if current_node is not None: current_pri = current_node.get_priority() # Now to alternate make the current check to point to head2 current_check = 'in-head' # When the spot is found, depending on the obj of the head, that is # where you inserting it # Do not forget to push all the other items down the list # If the current_check is 'in-head', then you want to PUT the new node # in head if current_check == 'in-head': # Get the next node of the last node you visited in head2 # Make the new node point to that new_node.set_next(last_head2_node.get_next()) # Make the last node you visited in head2 point to the current node last_head2_node.set_next(current_node) # Make the last node you visited in head point to the new node last_head_node.set_next(new_node) # If the current_check is 'in-head2', then you want to PUT the new node # in head2 elif current_check == 'in-head2': # Then get the next node of the last node you visited in head # Point the new node to the next node of the last node you visited # in head new_node.set_next(last_head_node.get_next()) # Now point the last node you visited in head and point it to the # current node last_head_node.set_next(current_node) # Also, get the last node you visited before the current node, # then point that node to the new node. last_head2_node.set_next(new_node) def extracthigh(self): '''(WackyQueue) -> object This method removes and returns the first item in the WackyQueue. The object with the largest priority and inputed first amognst its equal priority is removed first REQ: The Queue is not empty ''' # You want to extract from the top of the head that has the highest # priority in the queue if self._head.get_priority() is 0: top_item = self._head.get_next() new_top_item = top_item.get_next() # Now make head point to the new top item self._head.set_next(new_top_item) # Remember to change the priority of the head, because the new top # item is now in the other head self._head.set_priority(1) self._head2.set_priority(0) elif self._head2.get_priority() is 0: top_item = self._head2.get_next() new_top_item = top_item.get_next() # Now make head2 point to the new top item self._head2.set_next(new_top_item) # Now remember to change the priority of both heads self._head.set_priority(0) self._head2.set_priority(1) return top_item.get_item() def is_empty(self): '''(WackyQueue) -> bool This method returns True if the WackyQueue is empty and False if it is not ''' # This part is simple, just get the next item to the dummy node # and check if it is None or a Node check_odd = self._head.get_next() check_even = self._head2.get_next() return check_odd is check_even is None def changepriority(self, obj, pri): '''(WackyQueue) -> None This method finds the first object of this priority and changes it to the priority that is given. Nothing is done if the object is not found ''' # Now you want to find the first apperance of that object # start with the top of the list if self._head.get_priority() is 0: current_check = 'in-head' current_node = self._head.get_next() elif self._head2.get_priority() is 0: current_check = 'in-head2' current_node = self._head2.get_next() current_item = current_node.get_item() last_head_node = self._head last_head2_node = self._head2 # Now you want to loop until you have found the object you are looking # for while (current_item is not obj) and (current_node is not None): # Again just like in insert, you want to start with the top of the # Queue if current_check == 'in-head': last_head_node = current_node current_node = last_head2_node.get_next() if current_node is not None: current_item = current_node.get_item() current_check = 'in-head2' elif current_check == 'in-head2': last_head2_node = current_node current_node = last_head_node.get_next() if current_node is not None: current_item = current_node.get_item() current_check = 'in-head' # Check if the current node is None first if ((current_node is not None) and (current_node.get_priority is not pri)): # After you have found the node that contains the object you need # to re-arrange the list if current_check == 'in-head': # So first if you left off at head, that is where you are # removing the node from # Get the previous head item you visited and point it to the # next item of the last head2 item you visited last_head_node.set_next(last_head2_node.get_next()) # Now get the previous head2 item you visited and point it to # the next node of the current node last_head2_node.set_next(current_node.get_next()) self.insert(obj, pri) # If you left off at head2, this is where you are removing the # item from elif current_check == 'in-head2': # get the previos head2 node and point it to the next item of # the previous head node you visited last_head2_node.set_next(last_head_node.get_next()) # Then get the previous head node you visited to point it the # next item of the current node last_head_node.set_next(current_node.get_next()) # Now you need to put back the new node into the list # use the insert method self.insert(obj, pri) def negate_all(self): '''(WackyQueue) -> None This method reveres the entry time of all the objects ''' # Since your methods should be independent of the items in the list # when retrieving them, You want to 'just' flip both the odd and even # lists, luckily you have a helper function for this self._head = flip(self._head) self._head2 = flip(self._head2) # Now to get to the purpose of the function you have to negate all # the priorities in the Queue current_node = self._head.get_next() while current_node is not None: pri = current_node.get_priority() pri = pri * -1 current_node.set_priority(pri) if current_node is not None: current_node = current_node.get_next() # Repeat the same steps for head2 current_node = self._head2.get_next() while current_node is not None: pri = current_node.get_priority() pri = pri * -1 current_node.set_priority(pri) if current_node is not None: current_node = current_node.get_next() # For the final step, since you do not remember what the last object # in the queue is. You need to check for the highest if (self._head.get_next() and self._head2.get_next() is not None): head_top_pri = self._head.get_next().get_priority() head2_top_pri = self._head2.get_next().get_priority() # Now you need see if you need a new top Node if head_top_pri > head2_top_pri: self._head.set_priority(0) self._head2.set_priority(1) elif head2_top_pri > head_top_pri: self._head2.set_priority(0) self._head.set_priority(1) def getoddlist(self): '''(WackyQueue) -> WackyNode This function returns a node that points to all the odd items in the queue ''' # You know the first item on the list is the list is the one that has # priority 0 if self._head.get_priority() is 0: odd_list = self._head.get_next() elif self._head2.get_priority() is 0: odd_list = self._head2.get_next() return odd_list def getevenlist(self): '''(WackyQueue) -> WackyNode This function returns a node that points to all the even items in the list ''' # You know that which ever head whose priority is 1 has all the even # items if self._head.get_priority() is 1: even_list = self._head.get_next() elif self._head2.get_priority() is 1: even_list = self._head2.get_next() return even_list def __str__(self): '''(WackyQueue) -> str This method prints the contents of the WackyQueue ''' current_node = self._head.get_next() current_node2 = self._head2.get_next() head_str = '' head2_str = '' top_head_str = '' top_head2_str = '' while current_node is not None: current_obj = current_node.get_item() head_str = head_str + str(current_obj) + ', ' current_node = current_node.get_next() while current_node2 is not None: current_obj2 = current_node2.get_item() head2_str = head2_str + str(current_obj2) + ', ' current_node2 = current_node2.get_next() # Check which head has the higher priority if self._head.get_priority() is 0: top_head_str = 'ODD-LIST -> ' top_head2_str = 'EVEN-LIST -> ' elif self._head2.get_priority() is 0: top_head2_str = 'ODD-LIST -> ' top_head_str = 'EVEN-LIST -> '
""" ANNOTATION 1: How do the priorities work? """ Insert an item with a priority into the Wacky Queue. Duplicates are allowed - wacky queue may contain same copies of obj with same or different priorities. """ END ANNOTATION 1 """ ''' # Create a new node that will be inserted into the wacky queue new_node = WackyNode(item, priority) # If the WackyQueue is empty, add the new node to the first position of # WackyQueue (first position of odd linked list) if self._odd_head is None: self._odd_head = new_node # If the WackyQueue contains only one node and if the new node has a # priority greater than the first node, elif ((self._even_head is None) and (new_node.get_priority() > self._odd_head.get_priority())): # Switch the first node to the second node's position and insert # new node to first node's position self._even_head = self._odd_head self._odd_head = new_node # If the WackyQueue contains only one node and if the priority of new # node is lesser than that of first node, elif self._even_head is None: # Add the new node to the second position of WackyQueue # (ie. 1st position of even linked list) self._even_head = new_node # Else, loop through both linked lists till we find a priority lesser # than the priority of new node else: # Set temporary variables to represent the nodes in the linked list
def insert(self, obj, pri): '''(WackyQueue, obj, int) -> NoneType Creates a new WackyNode and inserts it into the WackyQueue sorted descendingly. Items with the same priority are sorted according to which item was added first. ''' # Create node node = WackyNode(obj, pri) # Insert first item if self._odd is None: self._odd = node # Insert the second item if # it has less priority than first elif self._even is None and node.get_priority( ) <= self._odd.get_priority(): self._even = node # Switch the first and second if # second node has greater priority elif self._even is None and node.get_priority( ) > self._odd.get_priority(): self._even = self._odd self._odd = node # Insert the nth item, where n > 2 else: # Store the first and second nodes cur_node1 = self._odd cur_node2 = self._even # Keep track of the size of both lists sizeodd = 1 sizeeven = 1 # Take the nodes with the highest possible # priority from both lists while ( cur_node1.get_next() is not None and (cur_node1.get_next().get_priority() >= node.get_priority())): sizeodd += 1 cur_node1 = cur_node1.get_next() while ( cur_node2.get_next() is not None and (cur_node2.get_next().get_priority() >= node.get_priority())): sizeeven += 1 cur_node2 = cur_node2.get_next() # First Case: # The current nodes priorities taken from the # even and odd lists are greater than or equal # to the node priority if (cur_node1.get_priority() >= node.get_priority() and cur_node2.get_priority() >= node.get_priority()): # Find greater value between two current nodes # By default assume the odd list contains the higher node greatest = cur_node1 lowest = cur_node2 if cur_node1.get_priority() < cur_node2.get_priority(): greatest = cur_node2 lowest = cur_node1 elif cur_node1.get_priority() == cur_node2.get_priority(): # If odd list is longer, add node to the even list if sizeodd > sizeeven: greatest = cur_node2 lowest = cur_node1 temp = greatest.get_next() greatest.set_next(node) node.set_next(lowest.get_next()) lowest.set_next(temp) # Second Case: # The node priority is strictly inbetween the two # priorities or equal to the first odd node's priority elif (cur_node1.get_priority() >= node.get_priority() and cur_node2.get_priority() < node.get_priority()): # Insert in between temp = cur_node1.get_next() cur_node1.set_next(cur_node2) self._even = node node.set_next(temp) # Third Case: # The node priority is strictly greater than both elif (cur_node1.get_priority() < node.get_priority() and cur_node2.get_priority() < node.get_priority()): # Insert at the beginning temp = cur_node1 self._odd = node node.set_next(cur_node2) self._even = temp