code: def calculate_proba(
      df: Union[pd.DataFrame, np.ndarray],
      col_0: Hashable,
      col_1: Hashable,
  ) -> Tuple[float, float]:
      if isinstance(df, pd.DataFrame):
          marginal_0 = df[col_0].mean()
          marginal_1 = df[col_1].mean()
          joint_proba = (df[col_0] * df[col_1]).mean()
      else:
          marginal_0 = df[:, col_0].mean()
          marginal_1 = df[:, col_1].mean()
          joint_proba = (df[:, col_0] * df[:, col_1]).mean()
  
      factored_proba = marginal_0 * marginal_1
      return joint_proba, factored_proba
  
imports: import operator
  from typing import Hashable, Tuple, Union
  import networkx
  import numpy
  import pandas
  import pytest
  from networkx.algorithms.dag import is_directed_acyclic_graph
  from sklearn.gaussian_process.kernels import RBF
  from causalnex.structure.data_generators.core import _sample_binary_from_latent, _sample_count_from_latent, _sample_poisson, generate_structure, nonlinear_sem_generator, sem_generator
  from causalnex.structure.structuremodel import StructureModel
label_desc: Use image node_id 3 for calling a global function with example usage: calculate_proba(df, col_0, col_1) and returns: joint_proba,  factored_proba