code: def insert(self, insertion_point, no_to_insert, axis, tab=None):
          
  
          if not 0 <= axis <= len(self.shape):
              raise ValueError("Axis not in grid dimensions")
  
          if insertion_point > self.shape[axis] or \
             insertion_point < -self.shape[axis]:
              raise IndexError("Insertion point not in grid")
  
          new_keys = {}
          del_keys = []
  
          for key in self.dict_grid.keys():
              if key[axis] > insertion_point and (tab is None or tab == key[2]):
                  new_key = list(key)
                  new_key[axis] += no_to_insert
                  if 0 <= new_key[axis] < self.shape[axis]:
                      new_keys[tuple(new_key)] = self(key)
                  del_keys.append(key)
  
          # Now re-insert moved keys
  
          for key in del_keys:
              if key not in new_keys and self(key) is not None:
                  self.pop(key)
  
          self._adjust_rowcol(insertion_point, no_to_insert, axis, tab=tab)
          self._adjust_cell_attributes(insertion_point, no_to_insert, axis, tab)
  
          for key in new_keys:
              self.__setitem__(key, new_keys[key])
docs: Inserts no_to_insert rows/cols/tabs/... before insertion_point
  
          Parameters
          ----------
  
          insertion_point: Integer
          \tPont on axis, before which insertion takes place
          no_to_insert: Integer >= 0
          \tNumber of rows/cols/tabs that shall be inserted
          axis: Integer
          \tSpecifies number of dimension, i.e. 0 == row, 1 == col, ...
          tab: Integer, defaults to None
          \tIf given then insertion is limited to this tab for axis < 2