docstr: Performs a binary search between continuous features of a CF and corresponding values
  in query_instance until the prediction class changes.
code: def do_binary_search(
      self,
      diff,
      decimal_prec,
      query_instance,
      cf_ix,
      feature,
      final_cfs_sparse,
      current_pred,
  ):
      """Performs a binary search between continuous features of a CF and corresponding values
      in query_instance until the prediction class changes."""
  
      old_val = final_cfs_sparse.at[cf_ix, feature]
      final_cfs_sparse.at[cf_ix, feature] = query_instance[feature].iat[
          0
      ]
      # Prediction of the query instance
      current_pred = self.predict_fn_for_sparsity(
          final_cfs_sparse.loc[[cf_ix]][
              self.data_interface.feature_names
          ]
      )
  
      # first check if assigning query_instance values to a CF is required.
      if self.is_cf_valid(current_pred):
          return final_cfs_sparse
      else:
          final_cfs_sparse.at[cf_ix, feature] = old_val
  
      # move the CF values towards the query_instance
      if diff > 0:
          left = final_cfs_sparse.at[cf_ix, feature]
          right = query_instance[feature].iat[0]
  
          while left <= right:
              current_val = left + ((right - left) / 2)
              current_val = round(current_val, decimal_prec[feature])
  
              final_cfs_sparse.at[cf_ix, feature] = current_val
              current_pred = self.predict_fn_for_sparsity(
                  final_cfs_sparse.loc[[cf_ix]][
                      self.data_interface.feature_names
                  ]
              )
  
              if current_val == right or current_val == left:
                  break
  
              if self.is_cf_valid(current_pred):
                  left = current_val + (10 ** -decimal_prec[feature])
              else:
                  right = current_val - (10 ** -decimal_prec[feature])
  
      else:
          left = query_instance[feature].iat[0]
          right = final_cfs_sparse.at[cf_ix, feature]
  
          while right >= left:
              current_val = right - ((right - left) / 2)
              current_val = round(current_val, decimal_prec[feature])
  
              final_cfs_sparse.at[cf_ix, feature] = current_val
              current_pred = self.predict_fn_for_sparsity(
                  final_cfs_sparse.loc[[cf_ix]][
                      self.data_interface.feature_names
                  ]
              )
  
              if current_val == right or current_val == left:
                  break
  
              if self.is_cf_valid(current_pred):
                  right = current_val - (10 ** -decimal_prec[feature])
              else:
                  left = current_val + (10 ** -decimal_prec[feature])
  
      return final_cfs_sparse
  
imports: import pickle
  from abc import ABC, abstractmethod
  from collections.abc import Iterable
  from typing import Any, List
  import numpy
  import pandas
  from raiutils.exceptions import UserConfigValidationException
  from sklearn.neighbors import KDTree
  from tqdm import tqdm
  from dice_ml.constants import ModelTypes, _PostHocSparsityTypes
  from dice_ml.counterfactual_explanations import CounterfactualExplanations
label_desc: Use image node_id 15 for calling the ExplainerBase obj's underlying member method code with example usage: obj.do_binary_search(diff, decimal_prec, query_instance, cf_ix, feature, final_cfs_sparse, current_pred) and returns: final_cfs_sparse, final_cfs_sparse