code: def pack_rectangles(rectangles, sheet_size, shuffle=False):
      
      offset = np.zeros((len(rectangles), 2))
      inserted = np.zeros(len(rectangles), dtype=np.bool)
      box_order = np.argsort(np.sum(rectangles**2, axis=1))[::-1]
      area = 0.0
      density = 0.0
  
      if shuffle:
          shuffle_len = int(np.random.random() * len(rectangles)) - 1
          box_order[0:shuffle_len] = np.random.permutation(
              box_order[0:shuffle_len])
  
      sheet = RectangleBin(size=sheet_size)
      for index in box_order:
          insert_location = sheet.insert(rectangles[index])
          if insert_location is not None:
              area += np.prod(rectangles[index])
              offset[index] += insert_location
              inserted[index] = True
  
      consumed_box = np.max((offset + rectangles)[inserted], axis=0)
      density = area / np.product(consumed_box)
  
      return density, offset[inserted], inserted, consumed_box
docs: Pack smaller rectangles onto a larger rectangle, using a binary
      space partition tree.
  
      Parameters
      ----------
      rectangles : (n, 2) float
        An array of (width, height) pairs
        representing the rectangles to be packed.
      sheet_size : (2,) float
        Width, height of rectangular sheet
      shuffle : bool
        Whether or not to shuffle the insert order of the
        smaller rectangles, as the final packing density depends
        on insertion order.
  
      Returns
      ---------
      density : float
        Area filled over total sheet area
      offset :  (m,2) float
        Offsets to move rectangles to their packed location
      inserted : (n,) bool
        Which of the original rectangles were packed
      consumed_box : (2,) float
        Bounding box size of packed result