docs: def max_flow_preflowpush(self, source, sink, algo = 'FIFO', display = None):
          '''
          API: max_flow_preflowpush(self, source, sink, algo = 'FIFO',
                                    display = None)
          Description:
          Finds maximum flow from source to sink by a depth-first search based
          augmenting path algorithm.
          Pre:
               Assumes a directed graph in which each arc has a 'capacity'
               attribute and for which there does does not exist both arcs (i,j)
               and (j,i) for any pair of nodes i and j.
          Input:
              source: Source node name.
              sink: Sink node name.
              algo: Algorithm choice, 'FIFO', 'SAP' or 'HighestLabel'.
              display: display method.
          Post:
              The 'flow' attribute of each arc gives a maximum flow.
          '''
          if display == None:
              display = self.attr['display']
          else:
              self.set_display_mode(display)
          nl = self.get_node_list()
          # set excess of all nodes to 0
          for n in nl:
              self.set_node_attr(n, 'excess', 0)
          # set flow of all edges to 0
          for e in self.edge_attr:
              self.edge_attr[e]['flow'] = 0
              if 'capacity' in self.edge_attr[e]:
                  capacity = self.edge_attr[e]['capacity']
                  self.edge_attr[e]['label'] = str(capacity)+'/0'
              else:
                  self.edge_attr[e]['capacity'] = INF
                  self.edge_attr[e]['label'] = 'INF/0'
          self.display()
          self.set_display_mode('off')
          self.search(sink, algo = 'UnweightedSPT', reverse = True)
          self.set_display_mode(display)
          disconnect = False
          for n in nl:
              if self.get_node_attr(n, 'distance') is None:
                  disconnect = True
                  self.set_node_attr(n, 'distance',
                                     2*len(nl) + 1)
          if disconnect:
              print('Warning: graph contains nodes not connected to the sink...')
          if algo == 'FIFO':
              q = Queue()
          elif algo == 'SAP':
              q = Stack()
          elif algo == 'HighestLabel':
              q = PriorityQueue()
          for n in self.get_neighbors(source):
              capacity = self.get_edge_attr(source, n, 'capacity')
              self.set_edge_attr(source, n, 'flow', capacity)
              self.set_node_attr(n, 'excess', capacity)
              excess = self.get_node_attr(source, 'excess')
              self.set_node_attr(source, 'excess', excess - capacity)
              if algo == 'FIFO' or algo == 'SAP':
                  q.push(n)
              elif algo == 'HighestLabel':
                  q.push(n, -1)
          self.set_node_attr(source, 'distance', len(nl))
          self.show_flow()
          while not q.isEmpty():
              relabel = True
              current = q.peek()
              neighbors = (self.get_neighbors(current) +
                           self.get_in_neighbors(current))
              for n in neighbors:
                  pushed = self.process_edge_flow(source, sink, current, n, algo,
                                                  q)
                  if pushed:
                      self.show_flow()
                      if algo == 'FIFO':
                          '''With FIFO, we need to add the neighbors to the queue
                          before the current is added back in or the nodes will
                          be out of order
                          '''
                          if q.peek(n) is None and n != source and n != sink:
                              q.push(n)
                          '''Keep pushing while there is excess'''
                          if self.get_node_attr(current, 'excess') > 0:
                              continue
                      '''If we were able to push, then there we should not
                      relabel
                      '''
                      relabel = False
                      break
              q.remove(current)
              if current != sink:
                  if relabel:
                      self.relabel(current)
                      self.show_flow()
                  if self.get_node_attr(current, 'excess') > 0:
                      if algo == 'FIFO' or algo == 'SAP':
                          q.push(current)
                      elif algo == 'HighestLabel':
                          q.push(current, -self.get_node_attr(current,
                                                              'distance'))
              if pushed and q.peek(n) is None and n != source:
                  if algo == 'SAP':
                      q.push(n)
                  elif algo == 'HighestLabel':
                      q.push(n, -self.get_node_attr(n, 'distance'))