code: def posthoc_tukey(
      a: Union[list, np.ndarray, DataFrame],
      val_col: str = None,
      group_col: str = None,
      sort: bool = False,
  ) -> DataFrame:
      """Performs Tukey's all-pairs comparisons test for normally distributed data
      with equal group variances. For all-pairs comparisons in an
      one-factorial layout with normally distributed residuals and equal variances
      Tukey's test can be performed. A total of m = k(k-1)/2 hypotheses can be
      tested. The null hypothesis is tested in the two-tailed test against
      the alternative hypothesis [1]_, [2]_.
  
      Parameters
      ----------
      a : Union[list, np.ndarray, DataFrame]
          An array, any object exposing the array interface or a pandas
          DataFrame.
  
      val_col : str, optional
          Name of a DataFrame column that contains dependent variable values (test
          or response variable). Values should have a non-nominal scale. Must be
          specified if `a` is a pandas DataFrame object.
  
      group_col : str, optional
          Name of a DataFrame column that contains independent variable values
          (grouping or predictor variable). Values should have a nominal scale
          (categorical). Must be specified if `a` is a pandas DataFrame object.
  
      sort : bool, optional
          If True, sort data by block and group columns.
  
      Returns
      -------
      result : pandas.DataFrame
          P values.
  
      Notes
      -----
      The p values are computed from the Tukey-distribution.
  
      References
      ----------
      .. [1] L. Sachs (1997) Angewandte Statistik, New York: Springer.
      .. [2] J. Tukey (1949) Comparing Individual Means in the Analysis of Variance,
          Biometrics 5, 99-114.
  
      Examples
      --------
      >>> import scikit_posthocs as sp
      >>> import pandas as pd
      >>> x = pd.DataFrame({"a": [1,2,3,5,1], "b": [12,31,54,62,12], "c": [10,12,6,74,11]})
      >>> x = x.melt(var_name='groups', value_name='values')
      >>> sp.posthoc_tukey(x, val_col='values', group_col='groups')
      """
      x, _val_col, _group_col = __convert_to_df(a, val_col, group_col)
      x = x.sort_values(by=[_group_col], ascending=True) if sort else x
      groups = x[_group_col].unique()
      x_grouped = x.groupby(_group_col)[_val_col]
  
      ni = x_grouped.count()
      n = ni.sum()
      xi = x_grouped.mean()
      si = x_grouped.var()
      sin = 1.0 / (n - groups.size) * np.sum(si * (ni - 1))
  
      def compare(i, j):
          dif = xi[i] - xi[j]
          A = sin * 0.5 * (1.0 / ni.loc[i] + 1.0 / ni.loc[j])
          q_val = dif / np.sqrt(A)
          return q_val
  
      vs = np.zeros((groups.size, groups.size), dtype=float)
      tri_upper = np.triu_indices(vs.shape[0], 1)
      tri_lower = np.tril_indices(vs.shape[0], -1)
      vs[:, :] = 0
  
      combs = it.combinations(range(groups.size), 2)
  
      for i, j in combs:
          vs[i, j] = compare(groups[i], groups[j])
  
      vs[tri_upper] = psturng(
          np.abs(vs[tri_upper]), groups.size, n - groups.size
      )
      vs[tri_lower] = np.transpose(vs)[tri_lower]
  
      np.fill_diagonal(vs, 1)
      return DataFrame(vs, index=groups, columns=groups)
  
imports: import itertools
  from typing import Tuple, Union
  import numpy
  import scipy.stats
  from statsmodels.sandbox.stats.multicomp import multipletests
  from statsmodels.stats.multicomp import pairwise_tukeyhsd
  from statsmodels.stats.libqsturng import psturng
  from pandas import DataFrame
label_desc: Use image node_id 21 for calling a global function with example usage: posthoc_tukey(a, val_col, group_col, sort) and returns: DataFrame, q_val