# Buggy code
def sample(
    self,
    n=None,
    frac=None,
    replace=False,
    weights=None,
    random_state=None,
    axis=None,
):
    """Returns a random sample of items from an axis of object.

    Args:
        n: Number of items from axis to return. Cannot be used with frac.
            Default = 1 if frac = None.
        frac: Fraction of axis items to return. Cannot be used with n.
        replace: Sample with or without replacement. Default = False.
        weights: Default 'None' results in equal probability weighting.
            If passed a Series, will align with target object on index.
            Index values in weights not found in sampled object will be
            ignored and index values in sampled object not in weights will
            be assigned weights of zero. If called on a DataFrame, will
            accept the name of a column when axis = 0. Unless weights are
            a Series, weights must be same length as axis being sampled.
            If weights do not sum to 1, they will be normalized to sum
            to 1. Missing values in the weights column will be treated as
            zero. inf and -inf values not allowed.
        random_state: Seed for the random number generator (if int), or
            numpy RandomState object.
        axis: Axis to sample. Accepts axis number or name.

    Returns:
        A new Dataframe
    """
    axis = self._get_axis_number(axis) if axis is not None else 0
    if axis:
        axis_labels = self.columns
        axis_length = len(axis_labels)
    else:
        # Getting rows requires indices instead of labels. RangeIndex provides this.
        axis_labels = pandas.RangeIndex(len(self.index))
        axis_length = len(axis_labels)
    if weights is not None:
        # Index of the weights Series should correspond to the index of the
        # Dataframe in order to sample
        if isinstance(weights, BasePandasDataset):
            weights = weights.reindex(self.axes[axis])
        # If weights arg is a string, the weights used for sampling will
        # the be values in the column corresponding to that string
        if isinstance(weights, str):
            if axis == 0:
                try:
                    weights = self[weights]
                except KeyError:
                    raise KeyError("String passed to weights not a valid column")
            else:
                raise ValueError(
                    "Strings can only be passed to "
                    "weights when sampling from rows on "
                    "a DataFrame"
                )
        weights = pandas.Series(weights, dtype="float64")

        if len(weights) != axis_length:
            raise ValueError("Weights and axis to be sampled must be of same length")
        if (weights == np.inf).any() or (weights == -np.inf).any():
            raise ValueError("weight vector may not include `inf` values")
        if (weights < 0).any():
            raise ValueError("weight vector many not include negative values")
        # weights cannot be NaN when sampling, so we must set all nan
        # values to 0
        weights = weights.fillna(0)
        # If passed in weights are not equal to 1, renormalize them
        # otherwise numpy sampling function will error
        weights_sum = weights.sum()
        if weights_sum != 1:
            if weights_sum != 0:
                weights = weights / weights_sum
            else:
                raise ValueError("Invalid weights: weights sum to zero")
        weights = weights.values

    if n is None and frac is None:
        # default to n = 1 if n and frac are both None (in accordance with
        # Pandas specification)
        n = 1
    elif n is not None and frac is None and n % 1 != 0:
        # n must be an integer
        raise ValueError("Only integers accepted as `n` values")
    elif n is None and frac is not None:
        # compute the number of samples based on frac
        n = int(round(frac * axis_length))
    elif n is not None and frac is not None:
        # Pandas specification does not allow both n and frac to be passed
        # in
        raise ValueError("Please enter a value for `frac` OR `n`, not both")
    if n < 0:
        raise ValueError(
            "A negative number of rows requested. Please provide positive value."
        )
    if n == 0:
        # This returns an empty object, and since it is a weird edge case that
        # doesn't need to be distributed, we default to pandas for n=0.
        return self._default_to_pandas(
            "sample",
            n=n,
            frac=frac,
            replace=replace,
            weights=weights,
            random_state=random_state,
            axis=axis,
        )
    if random_state is not None:
        # Get a random number generator depending on the type of
        # random_state that is passed in
        if isinstance(random_state, int):
            random_num_gen = np.random.RandomState(random_state)
        elif isinstance(random_state, np.random.randomState):
            random_num_gen = random_state
        else:
            # random_state must be an int or a numpy RandomState object
            raise ValueError(
                "Please enter an `int` OR a np.random.RandomState for random_state"
            )
        # choose random numbers and then get corresponding labels from
        # chosen axis
        sample_indices = random_num_gen.choice(
            np.arange(0, axis_length), size=n, replace=replace, p=weights
        )
        samples = axis_labels[sample_indices]
    else:
        # randomly select labels from chosen axis
        samples = np.random.choice(a=axis_labels, size=n, replace=replace, p=weights)
    if axis:
        query_compiler = self._query_compiler.getitem_column_array(samples)
        return self.__constructor__(query_compiler=query_compiler)
    else:
        query_compiler = self._query_compiler.getitem_row_array(samples)
        return self.__constructor__(query_compiler=query_compiler)


# Traceback (AttributeError)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-667e79aa734e> in <module>
1 rng = np.random.RandomState(42)
2 df = mpd.DataFrame(np.random.rand(100, 3))
----> 3 df = df.sample(n=50, random_state=rng)

/export/home/software/anaconda3/lib/python3.7/site-packages/modin/pandas/base.py in sample(self, n, frac, replace, weights, random_state, axis)
2481             if isinstance(random_state, int):
2482                 random_num_gen = np.random.RandomState(random_state)
-> 2483             elif isinstance(random_state, np.random.randomState):
2484                 random_num_gen = random_state
2485             else:

AttributeError: module 'numpy.random' has no attribute 'randomState'

# Fixed code
def sample(
    self,
    n=None,
    frac=None,
    replace=False,
    weights=None,
    random_state=None,
    axis=None,
):
    """Returns a random sample of items from an axis of object.

    Args:
        n: Number of items from axis to return. Cannot be used with frac.
            Default = 1 if frac = None.
        frac: Fraction of axis items to return. Cannot be used with n.
        replace: Sample with or without replacement. Default = False.
        weights: Default 'None' results in equal probability weighting.
            If passed a Series, will align with target object on index.
            Index values in weights not found in sampled object will be
            ignored and index values in sampled object not in weights will
            be assigned weights of zero. If called on a DataFrame, will
            accept the name of a column when axis = 0. Unless weights are
            a Series, weights must be same length as axis being sampled.
            If weights do not sum to 1, they will be normalized to sum
            to 1. Missing values in the weights column will be treated as
            zero. inf and -inf values not allowed.
        random_state: Seed for the random number generator (if int), or
            numpy RandomState object.
        axis: Axis to sample. Accepts axis number or name.

    Returns:
        A new Dataframe
    """
    axis = self._get_axis_number(axis) if axis is not None else 0
    if axis:
        axis_labels = self.columns
        axis_length = len(axis_labels)
    else:
        # Getting rows requires indices instead of labels. RangeIndex provides this.
        axis_labels = pandas.RangeIndex(len(self.index))
        axis_length = len(axis_labels)
    if weights is not None:
        # Index of the weights Series should correspond to the index of the
        # Dataframe in order to sample
        if isinstance(weights, BasePandasDataset):
            weights = weights.reindex(self.axes[axis])
        # If weights arg is a string, the weights used for sampling will
        # the be values in the column corresponding to that string
        if isinstance(weights, str):
            if axis == 0:
                try:
                    weights = self[weights]
                except KeyError:
                    raise KeyError("String passed to weights not a valid column")
            else:
                raise ValueError(
                    "Strings can only be passed to "
                    "weights when sampling from rows on "
                    "a DataFrame"
                )
        weights = pandas.Series(weights, dtype="float64")

        if len(weights) != axis_length:
            raise ValueError("Weights and axis to be sampled must be of same length")
        if (weights == np.inf).any() or (weights == -np.inf).any():
            raise ValueError("weight vector may not include `inf` values")
        if (weights < 0).any():
            raise ValueError("weight vector many not include negative values")
        # weights cannot be NaN when sampling, so we must set all nan
        # values to 0
        weights = weights.fillna(0)
        # If passed in weights are not equal to 1, renormalize them
        # otherwise numpy sampling function will error
        weights_sum = weights.sum()
        if weights_sum != 1:
            if weights_sum != 0:
                weights = weights / weights_sum
            else:
                raise ValueError("Invalid weights: weights sum to zero")
        weights = weights.values

    if n is None and frac is None:
        # default to n = 1 if n and frac are both None (in accordance with
        # Pandas specification)
        n = 1
    elif n is not None and frac is None and n % 1 != 0:
        # n must be an integer
        raise ValueError("Only integers accepted as `n` values")
    elif n is None and frac is not None:
        # compute the number of samples based on frac
        n = int(round(frac * axis_length))
    elif n is not None and frac is not None:
        # Pandas specification does not allow both n and frac to be passed
        # in
        raise ValueError("Please enter a value for `frac` OR `n`, not both")
    if n < 0:
        raise ValueError(
            "A negative number of rows requested. Please provide positive value."
        )
    if n == 0:
        # This returns an empty object, and since it is a weird edge case that
        # doesn't need to be distributed, we default to pandas for n=0.
        return self._default_to_pandas(
            "sample",
            n=n,
            frac=frac,
            replace=replace,
            weights=weights,
            random_state=random_state,
            axis=axis,
        )
    if random_state is not None:
        # Get a random number generator depending on the type of
        # random_state that is passed in
        if isinstance(random_state, int):
            random_num_gen = np.random.RandomState(random_state)
        elif isinstance(random_state, np.random.RandomState):
            random_num_gen = random_state
        else:
            # random_state must be an int or a numpy RandomState object
            raise ValueError(
                "Please enter an `int` OR a np.random.RandomState for random_state"
            )
        # choose random numbers and then get corresponding labels from
        # chosen axis
        sample_indices = random_num_gen.choice(
            np.arange(0, axis_length), size=n, replace=replace, p=weights
        )
        samples = axis_labels[sample_indices]
    else:
        # randomly select labels from chosen axis
        samples = np.random.choice(a=axis_labels, size=n, replace=replace, p=weights)
    if axis:
        query_compiler = self._query_compiler.getitem_column_array(samples)
        return self.__constructor__(query_compiler=query_compiler)
    else:
        query_compiler = self._query_compiler.getitem_row_array(samples)
        return self.__constructor__(query_compiler=query_compiler)