code: def get_hyperedge_id(self, tail, head):
          
          frozen_tail = frozenset(tail)
          frozen_head = frozenset(head)
  
          if not self.has_hyperedge(frozen_tail, frozen_head):
              raise ValueError("No such hyperedge exists.")
  
          return self._successors[frozen_tail][frozen_head]
docs: From a tail and head set of nodes, returns the ID of the hyperedge
          that these sets comprise.
  
          :param tail: iterable container of references to nodes in the
                      tail of the hyperedge to be added
          :param head: iterable container of references to nodes in the
                      head of the hyperedge to be added
          :returns: str -- ID of the hyperedge that has that the specified
                  tail and head sets comprise.
          :raises: ValueError -- No such hyperedge exists.
  
          Examples:
          ::
  
              >>> H = DirectedHypergraph()
              >>> hyperedge_list = (["A"], ["B", "C"]),
                                    (("A", "B"), ("C"), {weight: 2}),
                                    (set(["B"]), set(["A", "C"])))
              >>> hyperedge_ids = H.add_hyperedges(hyperedge_list)
              >>> x = H.get_hyperedge_id(["A"], ["B", "C"])