docs: def change(sc=None, app_name='customSpark', master=None, wait='ips', min_cores=None, min_ips=None, timeout=30,
             refresh_rate=0.5, fail_on_timeout=False, **kwargs):
      """ Returns a new Spark Context (sc) object with added properties set
  
      :param sc: current SparkContext if None will create a new one
      :param app_name: name of new spark app
      :param master: url to master, if None will get from current sc
      :param wait: when to return after asking for a new sc (or max of timeout seconds):
       'ips': wait for all the previous ips that were connected to return (needs sc to not be None)
       'cores': wait for min_cores
       None: return immediately
      :param min_cores: when wait is 'cores' will wait until defaultParallelism is back to at least this value.
       if None will be set to defaultParallelism.
      :param min_ips: when wait is 'ips' will wait until number of unique executor ips is back to at least this value.
       if None will be set to the what the original sc had.
      :param timeout: max time in seconds to wait for new sc if wait is 'ips' or 'cores'
      :param fail_on_timeout: whether to fail if timeout has reached
      :param refresh_rate: how long to wait in seconds between each check of defaultParallelism
      :param kwargs:  added properties to set. In the form of key value pairs (replaces '.' with '_' in key)
                      examples: spark_task_cores='1', spark_python_worker_memory='8g'
                      see: http://spark.apache.org/docs/latest/configuration.html
      :return: a new SparkContext
      """
      # checking input
      if master is None and sc is None:
          raise ValueError('Both master and sc are None')
      if master is None:
          master = sc.getConf().get(u'spark.master')
      if wait == 'ips':
          if sc is None:
              if min_ips is None:
                  min_ips = 1
          elif min_ips is None:
              min_ips = len(executor_ips(sc))
      elif wait == 'cores':
          if min_cores is None:
              if sc is None:
                  logging.getLogger('pySparkUtils').info('Both sc and min_cores are None: setting target_cores to 2')
                  min_cores = 2
              else:
                  min_cores = sc.defaultParallelism
                  logging.getLogger('pySparkUtils').info('min_cores is None: setting target_cores to: %d' % min_cores)
      elif wait is not None:
          raise ValueError("wait should be: ['ips','cores',None] got: %s" % wait)
  
      if sc is not None:
          logging.getLogger('pySparkUtils').info('Stopping original sc with %d cores and %d executors' %
                                                 (sc.defaultParallelism, len(executor_ips(sc))))
          sc.stop()
  
      # building a new configuration with added arguments
      conf = SparkConf().setMaster(master).setAppName(app_name)
      for key in kwargs.keys():
          name = key.replace('_', '.', 100)
          value = kwargs[key]
          conf = conf.set(name, value)
          logging.getLogger('pySparkUtils').info('Setting %s to: %s' % (name, value))
  
      # starting the new context and waiting for defaultParallelism to get back to original value
      sc = SparkContext(conf=conf)
      if wait == 'cores':
          total_time = 0
          while sc.defaultParallelism < min_cores and total_time < timeout:
              time.sleep(refresh_rate)
              total_time += refresh_rate
          if fail_on_timeout and total_time >= timeout:
              sc.stop()
              raise RuntimeError('Time out reached when changing sc')
      elif wait == 'ips':
          total_time = 0
          while len(executor_ips(sc)) < min_ips and total_time < timeout:
              time.sleep(refresh_rate)
              total_time += refresh_rate
          if fail_on_timeout and total_time >= timeout:
              sc.stop()
              raise RuntimeError('Time out reached when changing sc')
      logging.getLogger('pySparkUtils').info('Returning new sc with %d cores and %d executors' %
                                             (sc.defaultParallelism, len(executor_ips(sc))))
      return sc