code: def density(G, t=None):
      r
      n = number_of_nodes(G, t)
      m = number_of_interactions(G, t)
      if m == 0 or m is None or n <= 1:
          return 0
  
      d = m / (n * (n - 1))
      if not G.is_directed():
          d *= 2
      return d
docs: r"""Return the density of a graph at timestamp t.
          The density for undirected graphs is
  
          .. math::
             d = \frac{2m}{n(n-1)},
  
          and for directed graphs is
  
          .. math::
             d = \frac{m}{n(n-1)},
  
          where `n` is the number of nodes and `m`  is the number of edges in `G`.
  
          Parameters
          ----------
  
          G : Graph opject
              DyNetx graph object
  
  
          t : snapshot id (default=None)
              If None the density will be computed on the flattened graph.
  
  
          Notes
          -----
  
          The density is 0 for a graph without edges and 1 for a complete graph.
  
          Self loops are counted in the total number of edges so graphs with self
          loops can have density higher than 1.