docs: def remove_node(self, node):
          """Removes a node and its attributes from the hypergraph. Removes
          every hyperedge that contains this node.
  
          :param node: reference to the node being added.
          :raises: ValueError -- No such node exists.
  
          Examples:
          ::
  
              >>> H = UndirectedHypergraph()
              >>> H.add_node("A", label="positive")
              >>> H.remove_node("A")
  
          """
          if not self.has_node(node):
              raise ValueError("No such node exists.")
  
          # Loop over every hyperedge in the star of the node;
          # i.e., over every hyperedge that contains the node
          for hyperedge_id in self._star[node]:
              frozen_nodes = \
                  self._hyperedge_attributes[hyperedge_id]["__frozen_nodes"]
              # Remove the node set composing the hyperedge
              del self._node_set_to_hyperedge[frozen_nodes]
              # Remove this hyperedge's attributes
              del self._hyperedge_attributes[hyperedge_id]
  
          # Remove node's star
          del self._star[node]
  
          # Remove node's attributes dictionary
          del self._node_attributes[node]