human
Complete this python program:
def build_act_with_param_noise(make_obs_ph, q_func, num_actions, scope='deepq', reuse=None, param_noise_filter_func=None):
assistant
#Here is the Python program you requested.

    """Creates the act function with support for parameter space noise exploration (https://arxiv.org/abs/1706.01905):
    Parameters
    make_obs_ph: str -> tf.placeholder or TfInput
    a function that take a name and creates a placeholder of input with that name
    q_func: (tf.Variable, int, str, bool) -> tf.Variable
    the model that takes the following inputs:
    observation_in: object
    the output of observation placeholder
    num_actions: int
    number of actions
    scope: str
    reuse: bool
    should be passed to outer variable scope
    and returns a tensor of shape (batch_size, num_actions) with values of every action.
    num_actions: int
    number of actions.
    scope: str or VariableScope
    optional scope for variable_scope.
    reuse: bool or None
    whether or not the variables should be reused. To be able to reuse the scope must be given.
    param_noise_filter_func: tf.Variable -> bool
    function that decides whether or not a variable should be perturbed. Only applicable
    if param_noise is True. If set to None, default_param_noise_filter is used by default.
    Returns
    act: (tf.Variable, bool, float, bool, float, bool) -> tf.Variable
    function to select and action given observation.
    `       See the top of the file for details.
    """
    if (param_noise_filter_func is None):
        param_noise_filter_func = default_param_noise_filter
    with tf.variable_scope(scope, reuse=reuse):
        observations_ph = U.ensure_tf_input(make_obs_ph('observation'))
        stochastic_ph = tf.placeholder(tf.bool, (), name='stochastic')
        update_eps_ph = tf.placeholder(tf.float32, (), name='update_eps')
        update_param_noise_threshold_ph = tf.placeholder(tf.float32, (), name='update_param_noise_threshold')
        update_param_noise_scale_ph = tf.placeholder(tf.bool, (), name='update_param_noise_scale')
        reset_ph = tf.placeholder(tf.bool, (), name='reset')
        eps = tf.get_variable('eps', (), initializer=tf.constant_initializer(0))
        param_noise_scale = tf.get_variable('param_noise_scale', (), initializer=tf.constant_initializer(0.01), trainable=False)
        param_noise_threshold = tf.get_variable('param_noise_threshold', (), initializer=tf.constant_initializer(0.05), trainable=False)
        q_values = q_func(observations_ph.get(), num_actions, scope='q_func')
        q_values_perturbed = q_func(observations_ph.get(), num_actions, scope='perturbed_q_func')
        def perturb_vars(original_scope, perturbed_scope):
            all_vars = U.scope_vars(U.absolute_scope_name('q_func'))
            all_perturbed_vars = U.scope_vars(U.absolute_scope_name('perturbed_q_func'))
            assert (len(all_vars) == len(all_perturbed_vars))
            perturb_ops = []
            for (var, perturbed_var) in zip(all_vars, all_perturbed_vars):
                if param_noise_filter_func(perturbed_var):
                    op = tf.assign(perturbed_var, (var + tf.random_normal(shape=tf.shape(var), mean=0.0, stddev=param_noise_scale)))
                else:
                    op = tf.assign(perturbed_var, var)
                perturb_ops.append(op)
            assert (len(perturb_ops) == len(all_vars))
            return tf.group(*perturb_ops)
        q_values_adaptive = q_func(observations_ph.get(), num_actions,...