code: def label_boundary_cells(network=None, boundary_faces=None):
      r
      f = boundary_faces
      if f is not None:
          coords = network['pore.coords']
          condition = coords[~network['pore.boundary']]
          dic = {'left': 0, 'right': 0, 'front': 1, 'back': 1,
                 'top': 2, 'bottom': 2}
          if all(coords[:, 2] == 0):
              dic['top'] = 1
              dic['bottom'] = 1
          for i in f:
              if i in ['left', 'front', 'bottom']:
                  network['pore.{}'.format(i)] = (coords[:, dic[i]] <
                                                  min(condition[:, dic[i]]))
              elif i in ['right', 'back', 'top']:
                  network['pore.{}'.format(i)] = (coords[:, dic[i]] >
                                                  max(condition[:, dic[i]]))
  
      return network
docs: r"""
      Takes 2D or 3D network and assign labels to boundary pores
  
      Parameters
      ----------
      network : dictionary
          A dictionary as produced by the SNOW network extraction algorithms
          containing edge/vertex, site/bond, node/link information.
  
      boundary_faces : list of strings
          The user can choose ‘left’, ‘right’, ‘top’, ‘bottom’, ‘front’ and
          ‘back’ face labels to assign boundary nodes. If no label is
          assigned then all six faces will be selected as boundary nodes
          automatically which can be trimmed later on based on user requirements.
  
      Returns
      -------
      The same dictionar s pass ing, but containing boundary nodes labels.  For
      example network['pore.left'], network['pore.right'], network['pore.top'],
      network['pore.bottom'] etc.
  
      Notes
      -----
      The dictionary names use the OpenPNM convention so it may be converted
      directly to an OpenPNM network object using the ``update`` command.