code: def interactions(problem, Y, print_to_console=False):
      
  
      names = problem['names']
      num_vars = problem['num_vars']
  
      X = generate_contrast(problem)
  
      ie_names = []
      IE = []
  
      for col in range(X.shape[1]):
          for col_2 in range(col):
              x = X[:, col] * X[:, col_2]
              var_names = (names[col_2], names[col])
              ie_names.append(var_names)
              IE.append((1. / (2 * num_vars)) * np.dot(Y, x))
      if print_to_console:
          [print('%s %f' % (n, i)) for (n, i) in zip(ie_names, IE)]
  
      return ie_names, IE
docs: Computes the second order effects
  
      Computes the second order effects (interactions) between
      all combinations of pairs of input factors
  
      Arguments
      ---------
      problem: dict
          The problem definition
      Y: numpy.array
          The NumPy array containing the model outputs
      print_to_console: bool, default=False
          Print results directly to console
  
      Returns
      -------
      ie_names: list
          The names of the interaction pairs
      IE: list
          The sensitivity indices for the pairwise interactions