# Path: bartpy/errors.py
# class NoSplittableVariableException(Exception):
#     pass
# 
# Path: bartpy/splitcondition.py
# class SplitCondition(object):
#     """
#     A representation of a split in feature space.
#     The two main components are:
# 
#         - splitting_variable: which variable is being split on
#         - splitting_value: the value being split on
#                            all values less than or equal to this go left, all values greater go right
# 
#     """
# 
#     def __init__(self, 
#                  splitting_variable: int, 
#                  splitting_value: float, 
#                  operator: Callable[[float, float], bool], 
#                  condition=None,
#                  carry_y_sum=None,
#                  carry_n_obsv=None):
#         self.splitting_variable = splitting_variable
#         self.splitting_value = splitting_value
#         self._condition = condition
#         self.operator = operator
# 
#         self.carry_y_sum = carry_y_sum
#         self.carry_n_obsv = carry_n_obsv
# 
#     def __str__(self):
#         return str(self.splitting_variable) + ": " + str(self.splitting_value)
# 
#     def __eq__(self, other: 'SplitCondition'):
#         return self.splitting_variable == other.splitting_variable and self.splitting_value == other.splitting_value and self.operator == other.operator


from operator import gt, le
from typing import Any, List, Optional, Union
from bartpy.errors import NoSplittableVariableException
from bartpy.splitcondition import SplitCondition
import numpy as np
import pandas as pd
        Return a random value of a variable
        Useful for choosing a variable to split on

        Parameters
        ----------
        variable - str
            Name of the variable to split on

        Returns
        -------
        Any

        Notes
        -----
          - Won't create degenerate splits, all splits will have at least one row on both sides of the split
        """
        if variable not in self.splittable_variables():
            raise NoSplittableVariableException()
        max_value = self.max_value_of_column(variable)
        candidate = np.random.choice(self.get_column(variable))
        while candidate == max_value:
            candidate = np.random.choice(self.get_column(variable))
        return candidate

    def proportion_of_value_in_variable(self, variable: int, value: float) -> float:
        if self.is_column_unique(variable):
            return 1. / self.n_obsv
        else:
            return float(np.mean(self.get_column(variable) == value))


# Path: bartpy/errors.py
# class NoSplittableVariableException(Exception):
#     pass
# 
# Path: bartpy/splitcondition.py
# class SplitCondition(object):
#     """
#     A representation of a split in feature space.
#     The two main components are:
# 
#         - splitting_variable: which variable is being split on
#         - splitting_value: the value being split on
#                            all values less than or equal to this go left, all values greater go right
# 
#     """
# 
#     def __init__(self, 
#                  splitting_variable: int, 
#                  splitting_value: float, 
#                  operator: Callable[[float, float], bool], 
#                  condition=None,
#                  carry_y_sum=None,
#                  carry_n_obsv=None):
#         self.splitting_variable = splitting_variable
#         self.splitting_value = splitting_value
#         self._condition = condition
#         self.operator = operator
# 
#         self.carry_y_sum = carry_y_sum
#         self.carry_n_obsv = carry_n_obsv
# 
#     def __str__(self):
#         return str(self.splitting_variable) + ": " + str(self.splitting_value)
# 
#     def __eq__(self, other: 'SplitCondition'):
#         return self.splitting_variable == other.splitting_variable and self.splitting_value == other.splitting_value and self.operator == other.operator


# Path: bartpy/data.py
from operator import gt, le
from typing import Any, List, Optional, Union
from bartpy.errors import NoSplittableVariableException
from bartpy.splitcondition import SplitCondition
import numpy as np
import pandas as pd

        Return a random value of a variable
        Useful for choosing a variable to split on

        Parameters
        ----------
        variable - str
            Name of the variable to split on

        Returns
        -------
        Any

        Notes
        -----
          - Won't create degenerate splits, all splits will have at least one row on both sides of the split
        """
        if variable not in self.splittable_variables():
            raise NoSplittableVariableException()
        max_value = self.max_value_of_column(variable)
        candidate = np.random.choice(self.get_column(variable))
        while candidate == max_value:
            candidate = np.random.choice(self.get_column(variable))
        return candidate

    def proportion_of_value_in_variable(self, variable: int, value: float) -> float:
        if self.is_column_unique(variable):
            return 1. / self.n_obsv
        else:
            return float(np.mean(self.get_column(variable) == value))


    def update_mask(self, other: SplitCondition) -> np.ndarray: