Instruction:
Given the following Python 3 function, write the documentation
def fit_gaussian(samples, ddof=0):
    if len(samples.shape) == 1:
        return np.mean(samples), np.std(samples, ddof=ddof)
    return np.mean(samples, axis=1), np.std(samples, axis=1, ddof=ddof)

Response: Calculates the mean and standard deviation of the given samples.


Instruction:
How would you code a function in Python 3 to
compute the circular mean for samples in a range of samples.

Response:
def fit_circular_gaussian(samples, high=np.pi, low=0):
    """Compute the circular mean for samples in a range

    Args:
        samples (ndarray): a one or two dimensional array. If one dimensional we calculate the fit using all
            values. If two dimensional, we fit the Gaussian for every set of samples over the first dimension.
        high (float): The maximum wrap point
        low (float): The minimum wrap point
    """
    cl_func = SimpleCLFunction.from_string('''
        void compute(global mot_float_type* samples,
                     global mot_float_type* means,
                     global mot_float_type* stds,
                     int nmr_samples,
                     int low,
                     int high){

            double cos_mean = 0;
            double sin_mean = 0;
            double ang;

            for(uint i = 0; i < nmr_samples; i++){
                ang = (samples[i] - low)*2*M_PI / (high - low);

                cos_mean += (cos(ang) - cos_mean) / (i + 1);
                sin_mean += (sin(ang) - sin_mean) / (i + 1);
            }

            double R = hypot(cos_mean, sin_mean);
            if(R > 1){
                R = 1;
            }

            double stds = 1/2. * sqrt(-2 * log(R));

            double res = atan2(sin_mean, cos_mean);
            if(res < 0){
                 res += 2 * M_PI;
            }

            *(means) = res*(high - low)/2.0/M_PI + low;
            *(stds) = ((high - low)/2.0/M_PI) * sqrt(-2*log(R));
        }
    ''')

    def run_cl(samples):
        data = {'samples': Array(samples, 'mot_float_type'),
                'means': Zeros(samples.shape[0], 'mot_float_type'),
                'stds': Zeros(samples.shape[0], 'mot_float_type'),
                'nmr_samples': Scalar(samples.shape[1]),
                'low': Scalar(low),
                'high': Scalar(high),
                }

        cl_func.evaluate(data, samples.shape[0])
        return data['means'].get_data(), data['stds'].get_data()

    if len(samples.shape) == 1:
        mean, std = run_cl(samples[None, :])
        return mean[0], std[0]
    return run_cl(samples)


Instruction:
Can you implement a function in Python 3 that
fits a truncated Gaussian distribution on the given samples.

Response:
def fit_truncated_gaussian(samples, lower_bounds, upper_bounds):
    """Fits a truncated gaussian distribution on the given samples.

    This will do a maximum likelihood estimation of a truncated Gaussian on the provided samples, with the
    truncation points given by the lower and upper bounds.

    Args:
        samples (ndarray): a one or two dimensional array. If one dimensional we fit the truncated Gaussian on all
            values. If two dimensional, we calculate the truncated Gaussian for every set of samples over the
            first dimension.
        lower_bounds (ndarray or float): the lower bound, either a scalar or a lower bound per problem (first index of
            samples)
        upper_bounds (ndarray or float): the upper bound, either a scalar or an upper bound per problem (first index of
            samples)

    Returns:
        mean, std: the mean and std of the fitted truncated Gaussian
    """
    if len(samples.shape) == 1:
        return _TruncatedNormalFitter()((samples, lower_bounds, upper_bounds))

    def item_generator():
        for ind in range(samples.shape[0]):
            if is_scalar(lower_bounds):
                lower_bound = lower_bounds
            else:
                lower_bound = lower_bounds[ind]

            if is_scalar(upper_bounds):
                upper_bound = upper_bounds
            else:
                upper_bound = upper_bounds[ind]

            yield (samples[ind], lower_bound, upper_bound)

    results = np.array(multiprocess_mapping(_TruncatedNormalFitter(), item_generator()))
    return results[:, 0], results[:, 1]


Instruction:
How would you code a function in Python 3 to
compute the overlapping coefficient of two Gaussian continuous_distributions.

Response:
def gaussian_overlapping_coefficient(means_0, stds_0, means_1, stds_1, lower=None, upper=None):
    """Compute the overlapping coefficient of two Gaussian continuous_distributions.

    This computes the :math:`\int_{-\infty}^{\infty}{\min(f(x), g(x))\partial x}` where
    :math:`f \sim \mathcal{N}(\mu_0, \sigma_0^{2})` and :math:`f \sim \mathcal{N}(\mu_1, \sigma_1^{2})` are normally
    distributed variables.

    This will compute the overlap for each element in the first dimension.

    Args:
        means_0 (ndarray): the set of means of the first distribution
        stds_0 (ndarray): the set of stds of the fist distribution
        means_1 (ndarray): the set of means of the second distribution
        stds_1 (ndarray): the set of stds of the second distribution
        lower (float): the lower limit of the integration. If not set we set it to -inf.
        upper (float): the upper limit of the integration. If not set we set it to +inf.
    """
    if lower is None:
        lower = -np.inf
    if upper is None:
        upper = np.inf

    def point_iterator():
        for ind in range(means_0.shape[0]):
            yield np.squeeze(means_0[ind]), np.squeeze(stds_0[ind]), np.squeeze(means_1[ind]), np.squeeze(stds_1[ind])

    return np.array(list(multiprocess_mapping(_ComputeGaussianOverlap(lower, upper), point_iterator())))


Instruction:
Make a summary of the following Python 3 code
def truncated_normal_log_likelihood(params, low, high, data):
        mu = params[0]
        sigma = params[1]
        if sigma == 0:
            return np.inf
        ll = np.sum(norm.logpdf(data, mu, sigma))
        ll -= len(data) * np.log((norm.cdf(high, mu, sigma) - norm.cdf(low, mu, sigma)))
        return -ll

Response: Calculate the log likelihood of the truncated normal distribution.


Instruction:
Given the following Python 3 function, write the documentation
def truncated_normal_ll_gradient(params, low, high, data):
        if params[1] == 0:
            return np.array([np.inf, np.inf])

        return np.array([_TruncatedNormalFitter.partial_derivative_mu(params[0], params[1], low, high, data),
                         _TruncatedNormalFitter.partial_derivative_sigma(params[0], params[1], low, high, data)])

Response: Returns the gradient of the log likelihood of the truncated normal at the given position.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def partial_derivative_mu(mu, sigma, low, high, data):
        pd_mu = np.sum(data - mu) / sigma ** 2
        pd_mu -= len(data) * ((norm.pdf(low, mu, sigma) - norm.pdf(high, mu, sigma))
                              / (norm.cdf(high, mu, sigma) - norm.cdf(low, mu, sigma)))
        return -pd_mu

Response: The partial derivative of the log - likelihood at a given point.


Instruction:
Here you have a function in Python 3, explain what it does
def get_kernel_data(self):
        return {
            'nmsimplex_scratch': LocalMemory(
                'mot_float_type', self._nmr_parameters * 2 + (self._nmr_parameters + 1) ** 2 + 1),
            'initial_simplex_scale': LocalMemory('mot_float_type', self._nmr_parameters)
        }

Response: Get the kernel data needed for this optimization routine to work.


Instruction:
Can you tell what is the following Python 3 function doing
def get_kernel_data(self):
        return {
            'subplex_scratch_float': LocalMemory(
                'mot_float_type', 4 + self._var_replace_dict['NMR_PARAMS'] * 2
                                    + self._var_replace_dict['MAX_SUBSPACE_LENGTH'] * 2
                                    + (self._var_replace_dict['MAX_SUBSPACE_LENGTH'] * 2
                                       + self._var_replace_dict['MAX_SUBSPACE_LENGTH']+1)**2 + 1),
            'subplex_scratch_int': LocalMemory(
                'int', 2 + self._var_replace_dict['NMR_PARAMS']
                         + (self._var_replace_dict['NMR_PARAMS'] // self._var_replace_dict['MIN_SUBSPACE_LENGTH'])),
            'initial_simplex_scale': LocalMemory('mot_float_type', self._var_replace_dict['NMR_PARAMS'])
        }

Response: Get the kernel data needed for this optimization routine to work.


Instruction:
Write a Python 3 function for
getting the kernel data needed for this optimization routine to work.

Response:
def get_kernel_data(self):
        """Get the kernel data needed for this optimization routine to work."""
        return {
            'scratch_mot_float_type': LocalMemory(
                'mot_float_type', 8 +
                                  2 * self._var_replace_dict['NMR_OBSERVATIONS'] +
                                  5 * self._var_replace_dict['NMR_PARAMS'] +
                                  self._var_replace_dict['NMR_PARAMS'] * self._var_replace_dict['NMR_OBSERVATIONS']),
            'scratch_int': LocalMemory('int', self._var_replace_dict['NMR_PARAMS'])
        }


Instruction:
Given the following Python 3 function, write the documentation
def _bounds_to_array(bounds):
    elements = []
    for value in bounds:
        if all_elements_equal(value):
            elements.append(Scalar(get_single_value(value), ctype='mot_float_type'))
        else:
            elements.append(Array(value, ctype='mot_float_type', as_scalar=True))
    return CompositeArray(elements, 'mot_float_type', address_space='local')

Response: Create a CompositeArray to hold the bounds.


Instruction:
Write a Python 3 script to
return a dictionary with the default options for the given minimization method.

Response:
def get_minimizer_options(method):
    """Return a dictionary with the default options for the given minimization method.

    Args:
        method (str): the name of the method we want the options off

    Returns:
        dict: a dictionary with the default options
    """
    if method == 'Powell':
        return {'patience': 2,
                'patience_line_search': None,
                'reset_method': 'EXTRAPOLATED_POINT'}

    elif method == 'Nelder-Mead':
        return {'patience': 200,
                'alpha': 1.0, 'beta': 0.5, 'gamma': 2.0, 'delta': 0.5, 'scale': 0.1,
                'adaptive_scales': True}

    elif method == 'Levenberg-Marquardt':
        return {'patience': 250, 'step_bound': 100.0, 'scale_diag': 1, 'usertol_mult': 30}

    elif method == 'Subplex':
        return {'patience': 10,
                'patience_nmsimplex': 100,
                'alpha': 1.0, 'beta': 0.5, 'gamma': 2.0, 'delta': 0.5, 'scale': 1.0, 'psi': 0.0001, 'omega': 0.01,
                'adaptive_scales': True,
                'min_subspace_length': 'auto',
                'max_subspace_length': 'auto'}

    raise ValueError('Could not find the specified method "{}".'.format(method))


Instruction:
Can you tell what is the following Python 3 function doing
def _clean_options(method, provided_options):
    provided_options = provided_options or {}
    default_options = get_minimizer_options(method)

    result = {}

    for name, default in default_options.items():
        if name in provided_options:
            result[name] = provided_options[name]
        else:
            result[name] = default_options[name]
    return result

Response: Clean the given input options.


Instruction:
Implement a function in Python 3 to
minimize the Powell algorithm.

Response:
def _minimize_powell(func, x0, cl_runtime_info, lower_bounds, upper_bounds,
                     constraints_func=None, data=None, options=None):
    """
    Options:
        patience (int): Used to set the maximum number of iterations to patience*(number_of_parameters+1)
        reset_method (str): one of 'EXTRAPOLATED_POINT' or 'RESET_TO_IDENTITY' lower case or upper case.
        patience_line_search (int): the patience of the searching algorithm. Defaults to the
            same patience as for the Powell algorithm itself.
    """
    options = options or {}
    nmr_problems = x0.shape[0]
    nmr_parameters = x0.shape[1]

    penalty_data, penalty_func = _get_penalty_function(nmr_parameters, constraints_func)

    eval_func = SimpleCLFunction.from_string('''
        double evaluate(local mot_float_type* x, void* data){
            double penalty = _mle_penalty(
                x,
                ((_powell_eval_func_data*)data)->data,
                ((_powell_eval_func_data*)data)->lower_bounds,
                ((_powell_eval_func_data*)data)->upper_bounds,
                ''' + str(options.get('penalty_weight', 1e30)) + ''',
                ((_powell_eval_func_data*)data)->penalty_data
            );

            double func_val = ''' + func.get_cl_function_name() + '''(x, ((_powell_eval_func_data*)data)->data, 0);

            if(isnan(func_val)){
                return INFINITY;
            }

            return func_val + penalty;
        }
    ''', dependencies=[func, penalty_func])

    optimizer_func = Powell(eval_func, nmr_parameters, **_clean_options('Powell', options))

    kernel_data = {'model_parameters': Array(x0, ctype='mot_float_type', mode='rw'),
                   'data': Struct({'data': data,
                                   'lower_bounds': lower_bounds,
                                   'upper_bounds': upper_bounds,
                                   'penalty_data': penalty_data}, '_powell_eval_func_data')}
    kernel_data.update(optimizer_func.get_kernel_data())

    return_code = optimizer_func.evaluate(
        kernel_data, nmr_problems,
        use_local_reduction=all(env.is_gpu for env in cl_runtime_info.cl_environments),
        cl_runtime_info=cl_runtime_info)

    return OptimizeResults({'x': kernel_data['model_parameters'].get_data(),
                            'status': return_code})


Instruction:
Write a Python 3 function for
getting a numerical differentiated Jacobian function. This computes the Jacobian of the observations (function vector) with respect to the parameters. Args: eval_func (mot.lib.cl_function.CLFunction): the evaluation function nmr_params (int): the number of parameters nmr_observations (int): the number of observations (the length of the function vector). Returns: mot.lib.cl_function.CLFunction: CL function for numerically estimating the Jacobian.

Response:
def _lm_numdiff_jacobian(eval_func, nmr_params, nmr_observations):
    """Get a numerical differentiated Jacobian function.

    This computes the Jacobian of the observations (function vector) with respect to the parameters.

    Args:
        eval_func (mot.lib.cl_function.CLFunction): the evaluation function
        nmr_params (int): the number of parameters
        nmr_observations (int): the number of observations (the length of the function vector).

    Returns:
        mot.lib.cl_function.CLFunction: CL function for numerically estimating the Jacobian.
    """
    return SimpleCLFunction.from_string(r'''
        /**
         * Compute the Jacobian for use in the Levenberg-Marquardt optimization routine.
         *
         * This should place the output in the ``fjac`` matrix.
         *
         * Parameters:
         *
         *   model_parameters: (nmr_params,) the current point around which we want to know the Jacobian
         *   data: the current modeling data, used by the objective function
         *   fvec: (nmr_observations,), the function values corresponding to the current model parameters
         *   fjac: (nmr_parameters, nmr_observations), the memory location for the Jacobian
         */
        void _lm_numdiff_jacobian(local mot_float_type* model_parameters,
                                  void* data,
                                  local mot_float_type* fvec,
                                  local mot_float_type* const fjac){

            const uint nmr_params = ''' + str(nmr_params) + ''';
            const uint nmr_observations = ''' + str(nmr_observations) + ''';

            local mot_float_type* lower_bounds = ((_lm_eval_func_data*)data)->lower_bounds;
            local mot_float_type* upper_bounds = ((_lm_eval_func_data*)data)->upper_bounds;
            local mot_float_type* jacobian_x_tmp = ((_lm_eval_func_data*)data)->jacobian_x_tmp;

            mot_float_type step_size = 30 * MOT_EPSILON;

            for (int i = 0; i < nmr_params; i++) {
                if(model_parameters[i] + step_size > upper_bounds[i]){
                    _lm_numdiff_jacobian_backwards(model_parameters, i, step_size, data, fvec,
                                                   fjac + i*nmr_observations, jacobian_x_tmp);
                }
                else if(model_parameters[i] - step_size < lower_bounds[i]){
                    _lm_numdiff_jacobian_forwards(model_parameters, i, step_size, data, fvec,
                                                  fjac + i*nmr_observations, jacobian_x_tmp);
                }
                else{
                    _lm_numdiff_jacobian_centered(model_parameters, i, step_size, data, fvec,
                                                  fjac + i*nmr_observations, jacobian_x_tmp);
                }
            }
        }
    ''', dependencies=[eval_func, SimpleCLFunction.from_string('''
        void _lm_numdiff_jacobian_centered(
                local mot_float_type* model_parameters,
                uint px,
                float step_size,
                void* data,
                local mot_float_type* fvec,
                local mot_float_type* const fjac,
                local mot_float_type* fjac_tmp){

            const uint nmr_observations = ''' + str(nmr_observations) + ''';

            uint observation_ind;
            mot_float_type temp;

            uint local_id = get_local_id(0);
            uint workgroup_size = get_local_size(0);

            // F(x + h)
            if(get_local_id(0) == 0){
                temp = model_parameters[px];
                model_parameters[px] = temp + step_size;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
            ''' + eval_func.get_cl_function_name() + '''(model_parameters, data, fjac);

            // F(x - h)
            if(get_local_id(0) == 0){
                model_parameters[px] = temp - step_size;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
            ''' + eval_func.get_cl_function_name() + '''(model_parameters, data, fjac_tmp);

            // combine
            for(int i = 0; i < (nmr_observations + workgroup_size - 1) / workgroup_size; i++){
                observation_ind = i * workgroup_size + local_id;
                if(observation_ind < nmr_observations){
                    fjac[observation_ind] = (fjac[observation_ind] - fjac_tmp[observation_ind]) / (2 * step_size);
                }
            }

            // restore parameter vector
            if(get_local_id(0) == 0){
                model_parameters[px] = temp;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
        }
    '''), SimpleCLFunction.from_string('''
        void _lm_numdiff_jacobian_backwards(
               local mot_float_type* model_parameters,
               uint px,
               float step_size,
               void* data,
               local mot_float_type* fvec,
               local mot_float_type* const fjac,
               local mot_float_type* fjac_tmp){

            const uint nmr_observations = ''' + str(nmr_observations) + ''';

            uint observation_ind;
            mot_float_type temp;

            uint local_id = get_local_id(0);
            uint workgroup_size = get_local_size(0);

            // F(x - h)
            if(get_local_id(0) == 0){
               temp = model_parameters[px];
               model_parameters[px] = temp - step_size;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
            ''' + eval_func.get_cl_function_name() + '''(model_parameters, data, fjac);

            // F(x - 2*h)
            if(get_local_id(0) == 0){
               model_parameters[px] = temp - 2 * step_size;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
            ''' + eval_func.get_cl_function_name() + '''(model_parameters, data, fjac_tmp);

            // combine
            for(int i = 0; i < (nmr_observations + workgroup_size - 1) / workgroup_size; i++){
               observation_ind = i * workgroup_size + local_id;
               if(observation_ind < nmr_observations){
                   fjac[observation_ind] = (  3 * fvec[observation_ind]
                                            - 4 * fjac[observation_ind]
                                            + fjac_tmp[observation_ind]) / (2 * step_size);
               }
            }

            // restore parameter vector
            if(get_local_id(0) == 0){
               model_parameters[px] = temp;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
        }
    '''), SimpleCLFunction.from_string('''
        void _lm_numdiff_jacobian_forwards(
               local mot_float_type* model_parameters,
               uint px,
               float step_size,
               void* data,
               local mot_float_type* fvec,
               local mot_float_type* const fjac,
               local mot_float_type* fjac_tmp){

            const uint nmr_observations = ''' + str(nmr_observations) + ''';

            uint observation_ind;
            mot_float_type temp;

            uint local_id = get_local_id(0);
            uint workgroup_size = get_local_size(0);

            // F(x + h)
            if(get_local_id(0) == 0){
               temp = model_parameters[px];
               model_parameters[px] = temp + step_size;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
            ''' + eval_func.get_cl_function_name() + '''(model_parameters, data, fjac);

            // F(x + 2*h)
            if(get_local_id(0) == 0){
               model_parameters[px] = temp + 2 * step_size;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
            ''' + eval_func.get_cl_function_name() + '''(model_parameters, data, fjac);

            // combine
            for(int i = 0; i < (nmr_observations + workgroup_size - 1) / workgroup_size; i++){
               observation_ind = i * workgroup_size + local_id;
               if(observation_ind < nmr_observations){
                   fjac[observation_ind] = (- 3 * fvec[observation_ind]
                                            + 4 * fjac[observation_ind]
                                            - fjac_tmp[observation_ind]) / (2 * step_size);
               }
            }

            // restore parameter vector
            if(get_local_id(0) == 0){
               model_parameters[px] = temp;
            }
            barrier(CLK_LOCAL_MEM_FENCE);
        }
    ''')])


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _get_penalty_function(nmr_parameters, constraints_func=None):
    dependencies = []
    data_requirements = {'scratch': LocalMemory('double', 1)}
    constraints_code = ''

    if constraints_func and constraints_func.get_nmr_constraints() > 0:
        nmr_constraints = constraints_func.get_nmr_constraints()
        dependencies.append(constraints_func)
        data_requirements['constraints'] = LocalMemory('mot_float_type', nmr_constraints)

        constraints_code = '''
            local mot_float_type* constraints = ((_mle_penalty_data*)scratch_data)->constraints;

            ''' + constraints_func.get_cl_function_name() + '''(x, data, constraints);

            for(int i = 0; i < ''' + str(nmr_constraints) + '''; i++){
                *penalty_sum += pown(max((mot_float_type)0, constraints[i]), 2);
            }
        '''

    data = Struct(data_requirements, '_mle_penalty_data')
    func = SimpleCLFunction.from_string('''
        double _mle_penalty(
                local mot_float_type* x,
                void* data,
                local mot_float_type* lower_bounds,
                local mot_float_type* upper_bounds,
                float penalty_weight,
                void* scratch_data){

            local double* penalty_sum = ((_mle_penalty_data*)scratch_data)->scratch;

            if(get_local_id(0) == 0){
                *penalty_sum = 0;

                // boundary conditions
                for(int i = 0; i < ''' + str(nmr_parameters) + '''; i++){
                    if(isfinite(upper_bounds[i])){
                        *penalty_sum += pown(max((mot_float_type)0, x[i] - upper_bounds[i]), 2);
                    }
                    if(isfinite(lower_bounds[i])){
                        *penalty_sum += pown(max((mot_float_type)0, lower_bounds[i] - x[i]), 2);
                    }
                }
            }
            barrier(CLK_LOCAL_MEM_FENCE);

            // constraints
            ''' + constraints_code + '''

            return penalty_weight * *penalty_sum;
        }
    ''', dependencies=dependencies)
    return data, func

Response: Returns a function to compute the penalty term for the boundary conditions.


Instruction:
Make a summary of the following Python 3 code
def from_string(cls, cl_function, dependencies=(), nmr_constraints=None):
        return_type, function_name, parameter_list, body = split_cl_function(cl_function)
        return SimpleConstraintFunction(return_type, function_name, parameter_list, body, dependencies=dependencies,
                                        nmr_constraints=nmr_constraints)

Response: Parse the given string into a SimpleCLFunction object.


Instruction:
Can you write a function in Python 3 where it
validates the schema of a dict containing a top - level lane or a branch - level lane.

Response:
def validate_schema(yaml_def, branch=False):
    """Validates the schema of a dict

    Parameters
    ----------
    yaml_def : dict
        dict whose schema shall be validated
    branch : bool
        Indicates whether `yaml_def` is a dict of a top-level lane, or of a branch
        inside a lane (needed for recursion)

    Returns
    -------
    bool
        True if validation was successful
    """
    schema = Schema({
        'lane' if not branch else 'branch': {
            Optional('name'): str,
            Optional('run_parallel'): bool,
            'tasks': list
        }
    })

    schema.validate(yaml_def)
    from schema import And, Use
    task_schema = Schema({
        'class': str,
        Optional('kwargs'): Or({str: object}),
        Optional('args'): Or([object], And(Use(lambda a: isinstance(a, dict)), False))
    })

    def validate_tasks(tasks):  # pylint: disable=missing-docstring
        for task in tasks:
            try:
                Schema({'branch': dict}).validate(task)
                validate_schema(task, True)
            except SchemaError:
                task_schema.validate(task)

        return True

    return validate_tasks(yaml_def['lane']['tasks'] if not branch else yaml_def['branch']['tasks'])


Instruction:
Make a summary of the following Python 3 code
def validate_params(cls, mtd_name, *args, **kwargs):
    mtd = getattr(cls, mtd_name)

    py3_mtd_condition = (not (inspect.isfunction(mtd) or inspect.ismethod(mtd))
                         and hasattr(cls, mtd_name))
    py2_mtd_condition = (not inspect.ismethod(mtd)
                         and not isinstance(cls.__dict__[mtd_name], staticmethod))
    if (PY3 and py3_mtd_condition) or (PY2 and py2_mtd_condition):
        raise TypeError('Attribute `%s` of class `%s` must be a method. Got type `%s` instead.'
                        % (mtd_name, cls.__name__, type(mtd)))

    req_params, opt_params = arg_spec(cls, mtd_name)
    n_params = len(req_params) + len(opt_params)
    n_args_kwargs = len(args) + len(kwargs)

    for k in kwargs:
        if k not in req_params and k not in opt_params:
            raise TaskInitializationError('kwarg `%s` is not a parameter of callable `%s`.'
                                          % (k, mtd.__name__))

    if n_args_kwargs < len(req_params):
        raise TaskInitializationError('Not enough args/kwargs supplied for callable `%s`. '
                                      'Required args: %s' % (mtd.__name__, str(req_params)))
    if len(args) > n_params or n_args_kwargs > n_params or len(kwargs) > n_params:
        raise TaskInitializationError('Too many args/kwargs supplied for callable `%s`. '
                                      'Required args: %s' % (mtd.__name__, str(req_params)))

    redundant_p = [p for p in kwargs if p not in req_params[len(args):] + opt_params]
    if redundant_p:
        raise TaskInitializationError('Supplied one or more kwargs that in the signature of '
                                      'callable `%s`. Redundant kwargs: %s'
                                      % (mtd.__name__, str(redundant_p)))

    needed_kwargs = req_params[len(args):]
    if not all([True if p in kwargs else False for p in needed_kwargs]):
        raise TaskInitializationError('Not enough args/kwargs supplied for callable `%s`. '
                                      'Required args: %s' % (mtd.__name__, str(req_params)))

Response: Validates if the given args and kwargs match the method signature.


Instruction:
Write a Python 3 script to
cross - version argument signature inspection.

Response:
def arg_spec(cls, mtd_name):
    """Cross-version argument signature inspection

    Parameters
    ----------
    cls : class
    mtd_name : str
        Name of the method to be inspected

    Returns
    -------
    required_params : list of str
        List of required, positional parameters
    optional_params : list of str
        List of optional parameters, i.e. parameters with a default value
    """
    mtd = getattr(cls, mtd_name)

    required_params = []
    optional_params = []

    if hasattr(inspect, 'signature'):  # Python 3
        params = inspect.signature(mtd).parameters  # pylint: disable=no-member

        for k in params.keys():
            if params[k].default == inspect.Parameter.empty:  # pylint: disable=no-member
                # Python 3 does not make a difference between unbound methods and functions, so the
                # only way to distinguish if the first argument is of a regular method, or a class
                # method, is to look for the conventional argument name. Yikes.
                if not (params[k].name == 'self' or params[k].name == 'cls'):
                    required_params.append(k)
            else:
                optional_params.append(k)
    else:  # Python 2
        params = inspect.getargspec(mtd)  # pylint: disable=deprecated-method
        num = len(params[0]) if params[0] else 0
        n_opt = len(params[3]) if params[3] else 0
        n_req = (num - n_opt) if n_opt <= num else 0
        for i in range(0, n_req):
            required_params.append(params[0][i])
        for i in range(n_req, num):
            optional_params.append(params[0][i])

        if inspect.isroutine(getattr(cls, mtd_name)):
            bound_mtd = cls.__dict__[mtd_name]
            if not isinstance(bound_mtd, staticmethod):
                del required_params[0]

    return required_params, optional_params


Instruction:
Implement a Python 3 function for
drawing random samples from the Uniform distribution.

Response:
def uniform(nmr_distributions, nmr_samples, low=0, high=1, ctype='float', seed=None):
    """Draw random samples from the Uniform distribution.

    Args:
        nmr_distributions (int): the number of unique continuous_distributions to create
        nmr_samples (int): The number of samples to draw
        low (double): The minimum value of the random numbers
        high (double): The minimum value of the random numbers
        ctype (str): the C type of the output samples
        seed (float): the seed for the RNG

    Returns:
        ndarray: A two dimensional numpy array as (nmr_distributions, nmr_samples).
    """
    if is_scalar(low):
        low = np.ones((nmr_distributions, 1)) * low
    if is_scalar(high):
        high = np.ones((nmr_distributions, 1)) * high

    kernel_data = {'low': Array(low, as_scalar=True),
                   'high': Array(high, as_scalar=True)}

    kernel = SimpleCLFunction.from_string('''
        void compute(double low, double high, global uint* rng_state, global ''' + ctype + '''* samples){

            rand123_data rand123_rng_data = rand123_initialize_data((uint[]){
                rng_state[0], rng_state[1], rng_state[2], rng_state[3],
                rng_state[4], rng_state[5], 0});
            void* rng_data = (void*)&rand123_rng_data;

            for(uint i = 0; i < ''' + str(nmr_samples) + '''; i++){
                double4 randomnr = rand4(rng_data);
                samples[i] = (''' + ctype + ''')(low + randomnr.x * (high - low));
            }
        }
    ''', dependencies=[Rand123()])

    return _generate_samples(kernel, nmr_distributions, nmr_samples, ctype, kernel_data, seed=seed)


Instruction:
Create a Python 3 function for
drawing random samples from the Gaussian distribution.

Response:
def normal(nmr_distributions, nmr_samples, mean=0, std=1, ctype='float', seed=None):
    """Draw random samples from the Gaussian distribution.

    Args:
        nmr_distributions (int): the number of unique continuous_distributions to create
        nmr_samples (int): The number of samples to draw
        mean (float or ndarray): The mean of the distribution
        std (float or ndarray): The standard deviation or the distribution
        ctype (str): the C type of the output samples
        seed (float): the seed for the RNG

    Returns:
        ndarray: A two dimensional numpy array as (nmr_distributions, nmr_samples).
    """
    if is_scalar(mean):
        mean = np.ones((nmr_distributions, 1)) * mean
    if is_scalar(std):
        std = np.ones((nmr_distributions, 1)) * std

    kernel_data = {'mean': Array(mean, as_scalar=True),
                   'std': Array(std, as_scalar=True)}

    kernel = SimpleCLFunction.from_string('''
        void compute(double mean, double std, global uint* rng_state, global ''' + ctype + '''* samples){
            rand123_data rand123_rng_data = rand123_initialize_data((uint[]){
                rng_state[0], rng_state[1], rng_state[2], rng_state[3],
                rng_state[4], rng_state[5], 0});
            void* rng_data = (void*)&rand123_rng_data;

            for(uint i = 0; i < ''' + str(nmr_samples) + '''; i++){
                double4 randomnr = randn4(rng_data);
                samples[i] = (''' + ctype + ''')(mean + randomnr.x * std);
            }
        }
    ''', dependencies=[Rand123()])

    return _generate_samples(kernel, nmr_distributions, nmr_samples, ctype, kernel_data, seed=seed)


Instruction:
Write a Python 3 script for
taking additional samples from the given likelihood and prior using this sampler.

Response:
def sample(self, nmr_samples, burnin=0, thinning=1):
        """Take additional samples from the given likelihood and prior, using this sampler.

        This method can be called multiple times in which the sample state is stored in between.

        Args:
            nmr_samples (int): the number of samples to return
            burnin (int): the number of samples to discard before returning samples
            thinning (int): how many sample we wait before storing a new one. This will draw extra samples such that
                    the total number of samples generated is ``nmr_samples * (thinning)`` and the number of samples
                    stored is ``nmr_samples``. If set to one or lower we store every sample after the burn in.

        Returns:
            SamplingOutput: the sample output object
        """
        if not thinning or thinning < 1:
            thinning = 1
        if not burnin or burnin < 0:
            burnin = 0

        max_samples_per_batch = max(1000 // thinning, 100)

        with self._logging(nmr_samples, burnin, thinning):
            if burnin > 0:
                for batch_start, batch_end in split_in_batches(burnin, max_samples_per_batch):
                    self._sample(batch_end - batch_start, return_output=False)
            if nmr_samples > 0:
                outputs = []
                for batch_start, batch_end in split_in_batches(nmr_samples, max_samples_per_batch):
                    outputs.append(self._sample(batch_end - batch_start, thinning=thinning))
                return SimpleSampleOutput(*[np.concatenate([o[ind] for o in outputs], axis=-1) for ind in range(3)])


Instruction:
Given the following Python 3 function, write the documentation
def _sample(self, nmr_samples, thinning=1, return_output=True):
        kernel_data = self._get_kernel_data(nmr_samples, thinning, return_output)
        sample_func = self._get_compute_func(nmr_samples, thinning, return_output)
        sample_func.evaluate(kernel_data, self._nmr_problems,
                             use_local_reduction=all(env.is_gpu for env in self._cl_runtime_info.cl_environments),
                             cl_runtime_info=self._cl_runtime_info)
        self._sampling_index += nmr_samples * thinning
        if return_output:
            return (kernel_data['samples'].get_data(),
                    kernel_data['log_likelihoods'].get_data(),
                    kernel_data['log_priors'].get_data())

Response: Sample the given number of samples with the given thinning.


Instruction:
Implement a Python 3 function for
initializing the likelihood and prior using the given positions.

Response:
def _initialize_likelihood_prior(self, positions, log_likelihoods, log_priors):
        """Initialize the likelihood and the prior using the given positions.

        This is a general method for computing the log likelihoods and log priors for given positions.

        Subclasses can use this to instantiate secondary chains as well.
        """
        func = SimpleCLFunction.from_string('''
            void compute(global mot_float_type* chain_position,
                         global mot_float_type* log_likelihood,
                         global mot_float_type* log_prior,
                         local mot_float_type* x_tmp,
                         void* data){

                bool is_first_work_item = get_local_id(0) == 0;

                if(is_first_work_item){
                    for(uint i = 0; i < ''' + str(self._nmr_params) + '''; i++){
                        x_tmp[i] = chain_position[i];
                    }
                    *log_prior = _computeLogPrior(x_tmp, data);
                }
                barrier(CLK_LOCAL_MEM_FENCE);

                *log_likelihood = _computeLogLikelihood(x_tmp, data);
            }
        ''', dependencies=[self._get_log_prior_cl_func(), self._get_log_likelihood_cl_func()])

        kernel_data = {
            'chain_position': Array(positions, 'mot_float_type', mode='rw', ensure_zero_copy=True),
            'log_likelihood': Array(log_likelihoods, 'mot_float_type', mode='rw', ensure_zero_copy=True),
            'log_prior': Array(log_priors, 'mot_float_type', mode='rw', ensure_zero_copy=True),
            'x_tmp': LocalMemory('mot_float_type', self._nmr_params),
            'data': self._data
        }

        func.evaluate(kernel_data, self._nmr_problems,
                      use_local_reduction=all(env.is_gpu for env in self._cl_runtime_info.cl_environments),
                      cl_runtime_info=self._cl_runtime_info)


Instruction:
Explain what the following Python 3 code does
def _get_kernel_data(self, nmr_samples, thinning, return_output):
        kernel_data = {
            'data': self._data,
            'method_data': self._get_mcmc_method_kernel_data(),
            'nmr_iterations': Scalar(nmr_samples * thinning, ctype='ulong'),
            'iteration_offset': Scalar(self._sampling_index, ctype='ulong'),
            'rng_state': Array(self._rng_state, 'uint', mode='rw', ensure_zero_copy=True),
            'current_chain_position': Array(self._current_chain_position, 'mot_float_type',
                                            mode='rw', ensure_zero_copy=True),
            'current_log_likelihood': Array(self._current_log_likelihood, 'mot_float_type',
                                            mode='rw', ensure_zero_copy=True),
            'current_log_prior': Array(self._current_log_prior, 'mot_float_type',
                                       mode='rw', ensure_zero_copy=True),
        }

        if return_output:
            kernel_data.update({
                'samples': Zeros((self._nmr_problems, self._nmr_params, nmr_samples), ctype='mot_float_type'),
                'log_likelihoods': Zeros((self._nmr_problems, nmr_samples), ctype='mot_float_type'),
                'log_priors': Zeros((self._nmr_problems, nmr_samples), ctype='mot_float_type'),
            })
        return kernel_data

Response: This method is used to get the kernel data for the current entry of the current entry in the MCMC sampler.


Instruction:
Create a Python 3 function to
get the MCMC algorithm as a computable function.

Response:
def _get_compute_func(self, nmr_samples, thinning, return_output):
        """Get the MCMC algorithm as a computable function.

        Args:
            nmr_samples (int): the number of samples we will draw
            thinning (int): the thinning factor we want to use
            return_output (boolean): if the kernel should return output

        Returns:
            mot.lib.cl_function.CLFunction: the compute function
        """
        cl_func = '''
            void compute(global uint* rng_state,
                         global mot_float_type* current_chain_position,
                         global mot_float_type* current_log_likelihood,
                         global mot_float_type* current_log_prior,
                         ulong iteration_offset,
                         ulong nmr_iterations,
                         ''' + ('''global mot_float_type* samples,
                                   global mot_float_type* log_likelihoods,
                                   global mot_float_type* log_priors,''' if return_output else '') + '''
                         void* method_data,
                         void* data){

                bool is_first_work_item = get_local_id(0) == 0;

                rand123_data rand123_rng_data = rand123_initialize_data((uint[]){
                    rng_state[0], rng_state[1], rng_state[2], rng_state[3],
                    rng_state[4], rng_state[5], 0, 0});
                void* rng_data = (void*)&rand123_rng_data;

                for(ulong i = 0; i < nmr_iterations; i++){
        '''
        if return_output:
            cl_func += '''
                    if(is_first_work_item){
                        if(i % ''' + str(thinning) + ''' == 0){
                            log_likelihoods[i / ''' + str(thinning) + '''] = *current_log_likelihood;
                            log_priors[i / ''' + str(thinning) + '''] = *current_log_prior;

                            for(uint j = 0; j < ''' + str(self._nmr_params) + '''; j++){
                                samples[(ulong)(i / ''' + str(thinning) + ''') // remove the interval
                                        + j * ''' + str(nmr_samples) + '''  // parameter index
                                ] = current_chain_position[j];
                            }
                        }
                    }
        '''
        cl_func += '''
                    _advanceSampler(method_data, data, i + iteration_offset, rng_data,
                                    current_chain_position, current_log_likelihood, current_log_prior);
                }

                if(is_first_work_item){
                    uint state[8];
                    rand123_data_to_array(rand123_rng_data, state);
                    for(uint i = 0; i < 6; i++){
                        rng_state[i] = state[i];
                    }
                }
            }
        '''
        return SimpleCLFunction.from_string(
            cl_func,
            dependencies=[Rand123(), self._get_log_prior_cl_func(),
                          self._get_log_likelihood_cl_func(),
                          SimpleCLCodeObject(self._get_state_update_cl_func(nmr_samples, thinning, return_output))])


Instruction:
Implement a function in Python 3 to
return the CL log prior compute function.

Response:
def _get_log_prior_cl_func(self):
        """Get the CL log prior compute function.

        Returns:
            str: the compute function for computing the log prior.
        """
        return SimpleCLFunction.from_string('''
            mot_float_type _computeLogPrior(local const mot_float_type* x, void* data){
                return ''' + self._log_prior_func.get_cl_function_name() + '''(x, data);
            }
        ''', dependencies=[self._log_prior_func])


Instruction:
Can you write a function in Python 3 where it
returns the CL log likelihood compute function.

Response:
def _get_log_likelihood_cl_func(self):
        """Get the CL log likelihood compute function.

        This uses local reduction to compute the log likelihood for every observation in CL local space.
        The results are then summed in the first work item and returned using a pointer.

        Returns:
            str: the CL code for the log likelihood compute func.
        """
        return SimpleCLFunction.from_string('''
            double _computeLogLikelihood(local const mot_float_type* current_position, void* data){
                return ''' + self._ll_func.get_cl_function_name() + '''(current_position, data);
            }
        ''', dependencies=[self._ll_func])


Instruction:
Write a Python 3 script to
get the mcmc method kernel data elements. Used by _get_mcmc_method_kernel_data.

Response:
def _get_mcmc_method_kernel_data_elements(self):
        """Get the mcmc method kernel data elements. Used by :meth:`_get_mcmc_method_kernel_data`."""
        return {'proposal_stds': Array(self._proposal_stds, 'mot_float_type', mode='rw', ensure_zero_copy=True),
                'x_tmp': LocalMemory('mot_float_type', nmr_items=1 + self._nmr_params)}


Instruction:
Implement a function in Python 3 to
calculate and return the log likelihood of the given model for the given parameters.

Response:
def compute_log_likelihood(ll_func, parameters, data=None, cl_runtime_info=None):
    """Calculate and return the log likelihood of the given model for the given parameters.

    This calculates the log likelihoods for every problem in the model (typically after optimization),
    or a log likelihood for every sample of every model (typically after sample). In the case of the first (after
    optimization), the parameters must be an (d, p) array for d problems and p parameters. In the case of the
    second (after sample), you must provide this function with a matrix of shape (d, p, n) with d problems,
    p parameters and n samples.

    Args:
        ll_func (mot.lib.cl_function.CLFunction): The log-likelihood function. A CL function with the signature:

                .. code-block:: c

                        double <func_name>(local const mot_float_type* const x, void* data);

        parameters (ndarray): The parameters to use in the evaluation of the model. This is either an (d, p) matrix
            or (d, p, n) matrix with d problems, p parameters and n samples.
        data (mot.lib.kernel_data.KernelData): the user provided data for the ``void* data`` pointer.
        cl_runtime_info (mot.configuration.CLRuntimeInfo): the runtime information

    Returns:
        ndarray: per problem the log likelihood, or, per problem and per sample the log likelihood.
    """

    def get_cl_function():
        nmr_params = parameters.shape[1]

        if len(parameters.shape) > 2:
            return SimpleCLFunction.from_string('''
                void compute(global mot_float_type* parameters,
                             global mot_float_type* log_likelihoods,
                             void* data){

                    local mot_float_type x[''' + str(nmr_params) + '''];

                    for(uint sample_ind = 0; sample_ind < ''' + str(parameters.shape[2]) + '''; sample_ind++){
                        for(uint i = 0; i < ''' + str(nmr_params) + '''; i++){
                            x[i] = parameters[i *''' + str(parameters.shape[2]) + ''' + sample_ind];
                        }

                        double ll = ''' + ll_func.get_cl_function_name() + '''(x, data);
                        if(get_local_id(0) == 0){
                            log_likelihoods[sample_ind] = ll;
                        }
                    }
                }
            ''', dependencies=[ll_func])

        return SimpleCLFunction.from_string('''
            void compute(local mot_float_type* parameters,
                         global mot_float_type* log_likelihoods,
                         void* data){

                double ll = ''' + ll_func.get_cl_function_name() + '''(parameters, data);
                if(get_local_id(0) == 0){
                    *(log_likelihoods) = ll;
                }
            }
        ''', dependencies=[ll_func])

    kernel_data = {'data': data,
                   'parameters': Array(parameters, 'mot_float_type', mode='r')}

    shape = parameters.shape
    if len(shape) > 2:
        kernel_data.update({
            'log_likelihoods': Zeros((shape[0], shape[2]), 'mot_float_type'),
        })
    else:
        kernel_data.update({
            'log_likelihoods': Zeros((shape[0],), 'mot_float_type'),
        })

    get_cl_function().evaluate(kernel_data, parameters.shape[0], use_local_reduction=True,
                               cl_runtime_info=cl_runtime_info)

    return kernel_data['log_likelihoods'].get_data()


Instruction:
Make a summary of the following Python 3 code
def compute_objective_value(objective_func, parameters, data=None, cl_runtime_info=None):
    return objective_func.evaluate({'data': data, 'parameters': Array(parameters, 'mot_float_type', mode='r')},
                                   parameters.shape[0], use_local_reduction=True, cl_runtime_info=cl_runtime_info)

Response: Calculate and return the objective function value of the given model for the given parameters.


Instruction:
Here you have a function in Python 3, explain what it does
def get_log(username):
    redis = get_redis_client()
    log_key = 'log:{}'.format(username)
    raw_log = redis.lrange(log_key, 0, -1)
    log = []
    for raw_item in raw_log:
        item = json.loads(raw_item.decode())
        item['datetime'] = convert_timestamp(item.pop('time'))
        log.append(item)
    return log

Response: Get a list of page views for a given user.


Instruction:
Write a Python 3 script for
obtaining an access token that can be passed to a websocket client.

Response:
def get_token(username, length=20, timeout=20):
    """
    Obtain an access token that can be passed to a websocket client.
    """
    redis = get_redis_client()
    token = get_random_string(length)
    token_key = 'token:{}'.format(token)
    redis.set(token_key, username)
    redis.expire(token_key, timeout)
    return token


Instruction:
Given the following Python 3 function, write the documentation
def get_log(self, request, response):
        return {
            'method': request.method,
            'path': request.get_full_path(),
            'code': response.status_code,
            'time': time.time(),
        }

Response: Return a dict of data to log for a given request and response.


Instruction:
Can you create a Python 3 function that
downloads a song from a Google Music library.

Response:
def download(self, song):
		"""Download a song from a Google Music library.

		Parameters:
			song (dict): A song dict.

		Returns:
			tuple: Song content as bytestring, suggested filename.
		"""

		song_id = song['id']

		response = self._call(
			mm_calls.Export,
			self.uploader_id,
			song_id)
		audio = response.body
		suggested_filename = unquote(
			response.headers['Content-Disposition'].split("filename*=UTF-8''")[-1]
		)

		return (audio, suggested_filename)


Instruction:
How would you code a function in Python 3 to
get the uploaded track count and allowance.

Response:
def quota(self):
		"""Get the uploaded track count and allowance.

		Returns:
			tuple: Number of uploaded tracks, number of tracks allowed.
		"""

		response = self._call(
			mm_calls.ClientState,
			self.uploader_id
		)
		client_state = response.body.clientstate_response

		return (client_state.total_track_count, client_state.locker_track_limit)


Instruction:
How would you code a function in Python 3 to
get a listing of Music Library songs.

Response:
def songs(self, *, uploaded=True, purchased=True):
		"""Get a listing of Music Library songs.

		Returns:
			list: Song dicts.
		"""

		if not uploaded and not purchased:
			raise ValueError("'uploaded' and 'purchased' cannot both be False.")

		if purchased and uploaded:
			song_list = []
			for chunk in self.songs_iter(export_type=1):
				song_list.extend(chunk)
		elif purchased:
			song_list = []
			for chunk in self.songs_iter(export_type=2):
				song_list.extend(chunk)
		elif uploaded:
			purchased_songs = []
			for chunk in self.songs_iter(export_type=2):
				purchased_songs.extend(chunk)

			song_list = [
				song
				for chunk in self.songs_iter(export_type=1)
				for song in chunk
				if song not in purchased_songs
			]

		return song_list


Instruction:
Can you write a function in Python 3 where it
gets a paged iterator of Music Library songs.

Response:
def songs_iter(self, *, continuation_token=None, export_type=1):
		"""Get a paged iterator of Music Library songs.

		Parameters:
			continuation_token (str, Optional): The token of the page to return.
				Default: Not sent to get first page.
			export_type (int, Optional): The type of tracks to return. 1 for all tracks, 2 for promotional and purchased.
				Default: ``1``

		Yields:
			list: Song dicts.
		"""

		def track_info_to_dict(track_info):
			return dict(
				(field.name, value)
				for field, value in track_info.ListFields()
			)

		while True:
			response = self._call(
				mm_calls.ExportIDs,
				self.uploader_id,
				continuation_token=continuation_token,
				export_type=export_type
			)

			items = [
				track_info_to_dict(track_info)
				for track_info in response.body.download_track_info
			]

			if items:
				yield items

			continuation_token = response.body.continuation_token

			if not continuation_token:
				break


Instruction:
Can you generate the documentation for the following Python 3 function
def upload(
		self,
		song,
		*,
		album_art_path=None,
		no_sample=False
	):
		"""Upload a song to a Google Music library.

		Parameters:
			song (os.PathLike or str or audio_metadata.Format):
				The path to an audio file or an instance of :class:`audio_metadata.Format`.
			album_art_path (os.PathLike or str, Optional):
				The relative filename or absolute filepath to external album art.
			no_sample(bool, Optional):
				Don't generate an audio sample from song;
				send empty audio sample.
				Default: Create an audio sample using ffmpeg/avconv.

		Returns:
			dict: A result dict with keys: ``'filepath'``, ``'success'``, ``'reason'``, and ``'song_id'`` (if successful).
		"""

		if not isinstance(song, audio_metadata.Format):
			try:
				song = audio_metadata.load(song)
			except audio_metadata.UnsupportedFormat:
				raise ValueError("'song' must be FLAC, MP3, or WAV.")

		if album_art_path:
			album_art_path = Path(album_art_path).resolve()

			if album_art_path.is_file():
				with album_art_path.open('rb') as image_file:
					external_art = image_file.read()
			else:
				external_art = None
		else:
			external_art = None

		result = {'filepath': Path(song.filepath)}

		track_info = mm_calls.Metadata.get_track_info(song)
		response = self._call(
			mm_calls.Metadata,
			self.uploader_id,
			[track_info]
		)

		metadata_response = response.body.metadata_response

		if metadata_response.signed_challenge_info:  # Sample requested.
			sample_request = metadata_response.signed_challenge_info[0]

			try:
				track_sample = mm_calls.Sample.generate_sample(
					song,
					track_info,
					sample_request,
					external_art=external_art,
					no_sample=no_sample
				)
				response = self._call(
					mm_calls.Sample,
					self.uploader_id,
					[track_sample]
				)
				track_sample_response = response.body.sample_response.track_sample_response[0]
			except (OSError, ValueError, subprocess.CalledProcessError):
				raise  # TODO
		else:
			track_sample_response = metadata_response.track_sample_response[0]

		response_code = track_sample_response.response_code

		if response_code == upload_pb2.TrackSampleResponse.MATCHED:
			result.update(
				{
					'success': True,
					'reason': 'Matched',
					'song_id': track_sample_response.server_track_id
				}
			)
		elif response_code == upload_pb2.TrackSampleResponse.UPLOAD_REQUESTED:
			server_track_id = track_sample_response.server_track_id

			self._call(
				mm_calls.UploadState,
				self.uploader_id,
				'START'
			)

			attempts = 0
			should_retry = True

			while should_retry and attempts <= 10:
				# Call with tenacity.retry_with to disable automatic retries.
				response = self._call.retry_with(stop=stop_after_attempt(1))(
					self,
					mm_calls.ScottyAgentPost,
					self.uploader_id,
					server_track_id,
					track_info,
					song,
					external_art=external_art,
					total_song_count=1,
					total_uploaded_count=0
				)

				session_response = response.body

				if 'sessionStatus' in session_response:
					break

				try:
					# WHY, GOOGLE?! WHY???????????
					status_code = session_response['errorMessage']['additionalInfo'][
						'uploader_service.GoogleRupioAdditionalInfo'
					]['completionInfo']['customerSpecificInfo'][
						'ResponseCode'
					]
				except KeyError:
					status_code = None

				if status_code == 503:  # Upload server still syncing.
					should_retry = True
					reason = "Server syncing"
				elif status_code == 200:  # Song is already uploaded.
					should_retry = False
					reason = "Already uploaded"
				elif status_code == 404:  # Rejected.
					should_retry = False
					reason = "Rejected"
				else:
					should_retry = True
					reason = "Unkown error"

				attempts += 1

				time.sleep(2)  # Give the server time to sync.
			else:
				result.update(
					{
						'success': False,
						'reason': f'Could not get upload session: {reason}'
					}
				)

			if 'success' not in result:
				transfer = session_response['sessionStatus']['externalFieldTransfers'][0]

				upload_url = transfer['putInfo']['url']
				content_type = transfer.get('content_type', 'audio/mpeg')
				original_content_type = track_info.original_content_type

				transcode = (
					isinstance(song, audio_metadata.WAV)
					or original_content_type != locker_pb2.Track.MP3
				)

				if (
					transcode
					or original_content_type == locker_pb2.Track.MP3
				):
					if transcode:
						audio_file = transcode_to_mp3(song, quality='320k')
					else:
						with open(song.filepath, 'rb') as f:
							audio_file = f.read()

					# Google Music allows a maximum file size of 300 MiB.
					if len(audio_file) >= 300 * 1024 * 1024:
						result.update(
							{
								'success': False,
								'reason': 'Maximum allowed file size is 300 MiB.'
							}
						)
					else:
						upload_response = self._call(
							mm_calls.ScottyAgentPut,
							upload_url,
							audio_file,
							content_type=content_type
						).body

						if upload_response.get('sessionStatus', {}).get('state'):
							result.update(
								{
									'success': True,
									'reason': 'Uploaded',
									'song_id': track_sample_response.server_track_id
								}
							)
						else:
							result.update(
								{
									'success': False,
									'reason': upload_response  # TODO: Better error details.
								}
							)
				else:
					# Do not upload files if transcode option set to False.
					result.update(
						{
							'success': False,
							'reason': 'Transcoding disabled for file type.'
						}
					)

				self._call(mm_calls.UploadState, self.uploader_id, 'STOPPED')
		else:
			response_codes = upload_pb2._TRACKSAMPLERESPONSE.enum_types[0]
			response_type = response_codes.values_by_number[
				track_sample_response.response_code
			].name

			reason = response_type

			result.update(
				{
					'success': False,
					'reason': f'{reason}'
				}
			)

			if response_type == 'ALREADY_EXISTS':
				result['song_id'] = track_sample_response.server_track_id

		return result

Response: Upload a song to a Google Music library.


Instruction:
Write a Python 3 function that can
log in to Google Music.

Response:
def login(self, username, *, token=None):
		"""Log in to Google Music.

		Parameters:
			username (str, Optional): Your Google Music username.
				Used for keeping stored OAuth tokens for multiple accounts separate.
			device_id (str, Optional): A mobile device ID or music manager uploader ID.
				Default: MAC address is used.
			token (dict, Optional): An OAuth token compatible with ``requests-oauthlib``.

		Returns:
			bool: ``True`` if successfully authenticated, ``False`` if not.
		"""

		self._username = username
		self._oauth(username, token=token)

		return self.is_authenticated


Instruction:
Can you write a function in Python 3 where it
logs in to Google Music with a different user.

Response:
def switch_user(self, username='', *, token=None):
		"""Log in to Google Music with a different user.

		Parameters:
			username (str, Optional): Your Google Music username.
				Used for keeping stored OAuth tokens for multiple accounts separate.
			token (dict, Optional): An OAuth token compatible with ``requests-oauthlib``.

		Returns:
			bool: ``True`` if successfully authenticated, ``False`` if not.
		"""

		if self.logout():
			return self.login(username, token=token)

		return False


Instruction:
Explain what the following Python 3 code does
def gen_tau(S, K, delta):
    pivot = floor(K/S)
    return [S/K * 1/d for d in range(1, pivot)] \
            + [S/K * log(S/delta)] \
            + [0 for d in range(pivot, K)]

Response: The Robust part of the RSD


Instruction:
Can you generate a brief explanation for the following Python 3 code
def gen_mu(K, delta, c):

    S = c * log(K/delta) * sqrt(K)
    tau = gen_tau(S, K, delta)
    rho = gen_rho(K)
    normalizer = sum(rho) + sum(tau)
    return [(rho[d] + tau[d])/normalizer for d in range(K)]

Response:
The Robust Soliton Distribution on the degree of
    transmitted blocks


Instruction:
Here you have a function in Python 3, explain what it does
def gen_rsd_cdf(K, delta, c):

    mu = gen_mu(K, delta, c)
    return [sum(mu[:d+1]) for d in range(K)]

Response:
The CDF of the RSD on block degree precomputed for
    sampling speed


Instruction:
Given the following Python 3 function, write the documentation
def _get_next(self):

        self.state = PRNG_A * self.state % PRNG_M
        return self.state

Response:
Executes the next iteration of the PRNG
        evolution process and returns the result.


Instruction:
Write a Python 3 script to
sample degree given the precomputed distributions above and the linear PRNG output .

Response:
def _sample_d(self):
        """Samples degree given the precomputed
        distributions above and the linear PRNG output
        """

        p = self._get_next() / PRNG_MAX_RAND
        for ix, v in enumerate(self.cdf):
            if v > p:
                return ix + 1
        return ix + 1


Instruction:
Explain what the following Python 3 code does
def run(fn, blocksize, seed, c, delta):

    with open(fn, 'rb') as f:
        for block in encode.encoder(f, blocksize, seed, c, delta):
            sys.stdout.buffer.write(block)

Response: Run the encoder until the file is broken


Instruction:
Can you generate the documentation for the following Python 3 function
def is_subscribed(self):

		subscribed = next(
			(
				config_item['value'] == 'true'
				for config_item in self.config()
				if config_item['key'] == 'isNautilusUser'
			),
			None
		)

		if subscribed:
			self.tier = 'aa'
		else:
			self.tier = 'fr'

		return subscribed

Response: Returns the subscription status of the account linked to the MobileClient instance.


Instruction:
Make a summary of the following Python 3 code
def album(self, album_id, *, include_description=True, include_songs=True):

		response = self._call(
			mc_calls.FetchAlbum,
			album_id,
			include_description=include_description,
			include_tracks=include_songs
		)
		album_info = response.body

		return album_info

Response: Get information about an album.


Instruction:
How would you code a function in Python 3 to
get information about an artist.

Response:
def artist(
		self, artist_id, *, include_albums=True, num_related_artists=5, num_top_tracks=5
	):
		"""Get information about an artist.

		Parameters:
			artist_id (str): An artist ID. Artist IDs start with an 'A'.
			include_albums (bool, Optional): Include albums by the artist in returned dict.
				Default: ``True``.
			num_related_artists (int, Optional): Include up to given number of related artists in returned dict.
				Default: ``5``.
			num_top_tracks (int, Optional): Include up to given number of top tracks in returned dict.
				Default: ``5``.

		Returns:
			dict: Artist information.
		"""

		response = self._call(
			mc_calls.FetchArtist,
			artist_id,
			include_albums=include_albums,
			num_related_artists=num_related_artists,
			num_top_tracks=num_top_tracks
		)
		artist_info = response.body

		return artist_info


Instruction:
Explain what the following Python 3 code does
def browse_podcasts(self, podcast_genre_id='JZCpodcasttopchartall'):

		response = self._call(
			mc_calls.PodcastBrowse,
			podcast_genre_id=podcast_genre_id
		)
		podcast_series_list = response.body.get('series', [])

		return podcast_series_list

Response: Get the podcasts for a genre from the Podcasts browse tab.


Instruction:
Explain what the following Python 3 code does
def browse_podcasts_genres(self):

		response = self._call(
			mc_calls.PodcastBrowseHierarchy
		)
		genres = response.body.get('groups', [])

		return genres

Response: Get the genres from the Podcasts browse tab dropdown.


Instruction:
Create a Python 3 function to
get the stations for a category from Browse Stations.

Response:
def browse_stations(self, station_category_id):
		"""Get the stations for a category from Browse Stations.

		Parameters:
			station_category_id (str): A station category ID as
				found with :meth:`browse_stations_categories`.

		Returns:
			list: Station dicts.
		"""

		response = self._call(
			mc_calls.BrowseStations,
			station_category_id
		)
		stations = response.body.get('stations', [])

		return stations


Instruction:
Write a Python 3 script for
getting the categories from Browse Stations.

Response:
def browse_stations_categories(self):
		"""Get the categories from Browse Stations.

		Returns:
			list: Station categories that can contain subcategories.
		"""

		response = self._call(
			mc_calls.BrowseStationCategories
		)
		station_categories = response.body.get('root', {}).get('subcategories', [])

		return station_categories


Instruction:
Make a summary of the following Python 3 code
def config(self):

		response = self._call(
			mc_calls.Config
		)
		config_list = response.body.get('data', {}).get('entries', [])

		return config_list

Response: Get a listing of mobile client configuration settings.


Instruction:
Here you have a function in Python 3, explain what it does
def device_set(self, device):

		if device['id'].startswith('0x'):
			self.device_id = device['id'][2:]
		elif device['id'].startswith('ios:'):
			self.device_id = device['id'].replace(':', '')
		else:
			self.device_id = device['id']

Response: Set device used by MobileClient instance.


Instruction:
How would you explain what the following Python 3 function does
def devices(self):

		response = self._call(
			mc_calls.DeviceManagementInfo
		)
		registered_devices = response.body.get('data', {}).get('items', [])

		return registered_devices

Response: Get a listing of devices registered to the Google Music account.


Instruction:
Implement a Python 3 function for
getting a listing of song genres.

Response:
def explore_genres(self, parent_genre_id=None):
		"""Get a listing of song genres.

		Parameters:
			parent_genre_id (str, Optional): A genre ID.
				If given, a listing of this genre's sub-genres is returned.

		Returns:
			list: Genre dicts.
		"""

		response = self._call(
			mc_calls.ExploreGenres,
			parent_genre_id
		)
		genre_list = response.body.get('genres', [])

		return genre_list


Instruction:
Can you generate the documentation for the following Python 3 function
def explore_tabs(self, *, num_items=100, genre_id=None):

		response = self._call(
			mc_calls.ExploreTabs,
			num_items=num_items,
			genre_id=genre_id
		)
		tab_list = response.body.get('tabs', [])

		explore_tabs = {}
		for tab in tab_list:
			explore_tabs[tab['tab_type'].lower()] = tab

		return explore_tabs

Response: Get a listing of explore tabs.


Instruction:
Implement a function in Python 3 to
get a listing of items dismissed from Listen Now tab.

Response:
def listen_now_dismissed_items(self):
		"""Get a listing of items dismissed from Listen Now tab."""

		response = self._call(
			mc_calls.ListenNowGetDismissedItems
		)
		dismissed_items = response.body.get('items', [])

		return dismissed_items


Instruction:
Can you generate a brief explanation for the following Python 3 code
def listen_now_items(self):

		response = self._call(
			mc_calls.ListenNowGetListenNowItems
		)
		listen_now_item_list = response.body.get('listennow_items', [])

		listen_now_items = defaultdict(list)
		for item in listen_now_item_list:
			type_ = f"{ListenNowItemType(item['type']).name}s"
			listen_now_items[type_].append(item)

		return dict(listen_now_items)

Response: Get a listing of Listen Now items.


Instruction:
Can you create a Python 3 function that
gets information about a playlist song.

Response:
def playlist_song(self, playlist_song_id):
		"""Get information about a playlist song.

		Note:
			This returns the playlist entry information only.
			For full song metadata, use :meth:`song` with
			the ``'trackId'`` field.

		Parameters:
			playlist_song_id (str): A playlist song ID.

		Returns:
			dict: Playlist song information.
		"""

		playlist_song_info = next(
			(
				playlist_song
				for playlist in self.playlists(include_songs=True)
				for playlist_song in playlist['tracks']
				if playlist_song['id'] == playlist_song_id
			),
			None
		)

		return playlist_song_info


Instruction:
Make a summary of the following Python 3 code
def playlist_song_add(
		self,
		song,
		playlist,
		*,
		after=None,
		before=None,
		index=None,
		position=None
	):
		"""Add a song to a playlist.

		Note:
			* Provide no optional arguments to add to end.
			* Provide playlist song dicts for ``after`` and/or ``before``.
			* Provide a zero-based ``index``.
			* Provide a one-based ``position``.

			Songs are inserted *at* given index or position.
			It's also possible to add to the end by using
			``len(songs)`` for index or ``len(songs) + 1`` for position.

		Parameters:
			song (dict): A song dict.
			playlist (dict): A playlist dict.
			after (dict, Optional): A playlist song dict ``songs`` will follow.
			before (dict, Optional): A playlist song dict ``songs`` will precede.
			index (int, Optional): The zero-based index position to insert ``song``.
			position (int, Optional): The one-based position to insert ``song``.

		Returns:
			dict: Playlist dict including songs.
		"""

		prev, next_ = get_ple_prev_next(
			self.playlist_songs(playlist),
			after=after,
			before=before,
			index=index,
			position=position
		)

		if 'storeId' in song:
			song_id = song['storeId']
		elif 'trackId' in song:
			song_id = song['trackId']
		else:
			song_id = song['id']

		mutation = mc_calls.PlaylistEntriesBatch.create(
			song_id, playlist['id'],
			preceding_entry_id=prev.get('id'),
			following_entry_id=next_.get('id')
		)
		self._call(mc_calls.PlaylistEntriesBatch, mutation)

		return self.playlist(playlist['id'], include_songs=True)

Response: Add a song to a playlist.


Instruction:
Can you tell what is the following Python 3 function doing
def playlist_songs_add(
		self,
		songs,
		playlist,
		*,
		after=None,
		before=None,
		index=None,
		position=None
	):
		"""Add songs to a playlist.

		Note:
			* Provide no optional arguments to add to end.
			* Provide playlist song dicts for ``after`` and/or ``before``.
			* Provide a zero-based ``index``.
			* Provide a one-based ``position``.

			Songs are inserted *at* given index or position.
			It's also possible to add to the end by using
			``len(songs)`` for index or ``len(songs) + 1`` for position.

		Parameters:
			songs (list): A list of song dicts.
			playlist (dict): A playlist dict.
			after (dict, Optional): A playlist song dict ``songs`` will follow.
			before (dict, Optional): A playlist song dict ``songs`` will precede.
			index (int, Optional): The zero-based index position to insert ``songs``.
			position (int, Optional): The one-based position to insert ``songs``.

		Returns:
			dict: Playlist dict including songs.
		"""

		playlist_songs = self.playlist_songs(playlist)

		prev, next_ = get_ple_prev_next(
			playlist_songs,
			after=after,
			before=before,
			index=index,
			position=position
		)

		songs_len = len(songs)
		for i, song in enumerate(songs):
			if 'storeId' in song:
				song_id = song['storeId']
			elif 'trackId' in song:
				song_id = song['trackId']
			else:
				song_id = song['id']

			mutation = mc_calls.PlaylistEntriesBatch.create(
				song_id, playlist['id'],
				preceding_entry_id=prev.get('id'),
				following_entry_id=next_.get('id')
			)
			response = self._call(mc_calls.PlaylistEntriesBatch, mutation)
			result = response.body['mutate_response'][0]

			# TODO: Proper exception on failure.
			if result['response_code'] != 'OK':
				break

			if i < songs_len - 1:
				while True:
					prev = self.playlist_song(result['id'])
					if prev:
						break

		return self.playlist(playlist['id'], include_songs=True)

Response: Add songs to a playlist.


Instruction:
Here you have a function in Python 3, explain what it does
def playlist_song_delete(self, playlist_song):

		self.playlist_songs_delete([playlist_song])

		return self.playlist(playlist_song['playlistId'], include_songs=True)

Response: Delete a song from a playlist.


Instruction:
How would you explain what the following Python 3 function does
def playlist_songs_delete(self, playlist_songs):

		if not more_itertools.all_equal(
			playlist_song['playlistId']
			for playlist_song in playlist_songs
		):
			raise ValueError(
				"All 'playlist_songs' must be from the same playlist."
			)

		mutations = [mc_calls.PlaylistEntriesBatch.delete(playlist_song['id']) for playlist_song in playlist_songs]
		self._call(mc_calls.PlaylistEntriesBatch, mutations)

		return self.playlist(playlist_songs[0]['playlistId'], include_songs=True)

Response: Delete songs from playlist.


Instruction:
How would you code a function in Python 3 to
move a song in a playlist.

Response:
def playlist_song_move(
		self,
		playlist_song,
		*,
		after=None,
		before=None,
		index=None,
		position=None
	):
		"""Move a song in a playlist.

		Note:
			* Provide no optional arguments to move to end.
			* Provide playlist song dicts for ``after`` and/or ``before``.
			* Provide a zero-based ``index``.
			* Provide a one-based ``position``.

			Songs are inserted *at* given index or position.
			It's also possible to move to the end by using
			``len(songs)`` for index or ``len(songs) + 1`` for position.

		Parameters:
			playlist_song (dict): A playlist song dict.
			after (dict, Optional): A playlist song dict ``songs`` will follow.
			before (dict, Optional): A playlist song dict ``songs`` will precede.
			index (int, Optional): The zero-based index position to insert ``song``.
			position (int, Optional): The one-based position to insert ``song``.

		Returns:
			dict: Playlist dict including songs.
		"""

		playlist_songs = self.playlist(
			playlist_song['playlistId'],
			include_songs=True
		)['tracks']

		prev, next_ = get_ple_prev_next(
			playlist_songs,
			after=after,
			before=before,
			index=index,
			position=position
		)

		mutation = mc_calls.PlaylistEntriesBatch.update(
			playlist_song,
			preceding_entry_id=prev.get('id'),
			following_entry_id=next_.get('id')
		)
		self._call(mc_calls.PlaylistEntriesBatch, mutation)

		return self.playlist(playlist_song['playlistId'], include_songs=True)


Instruction:
Create a Python 3 function for
moving songs in a playlist.

Response:
def playlist_songs_move(
		self,
		playlist_songs,
		*,
		after=None,
		before=None,
		index=None,
		position=None
	):
		"""Move songs in a playlist.

		Note:
			* Provide no optional arguments to move to end.
			* Provide playlist song dicts for ``after`` and/or ``before``.
			* Provide a zero-based ``index``.
			* Provide a one-based ``position``.

			Songs are inserted *at* given index or position.
			It's also possible to move to the end by using
			``len(songs)`` for index or ``len(songs) + 1`` for position.

		Parameters:
			playlist_songs (list): A list of playlist song dicts.
			after (dict, Optional): A playlist song dict ``songs`` will follow.
			before (dict, Optional): A playlist song dict ``songs`` will precede.
			index (int, Optional): The zero-based index position to insert ``songs``.
			position (int, Optional): The one-based position to insert ``songs``.

		Returns:
			dict: Playlist dict including songs.
		"""

		if not more_itertools.all_equal(
			playlist_song['playlistId']
			for playlist_song in playlist_songs
		):
			raise ValueError(
				"All 'playlist_songs' must be from the same playlist."
			)

		playlist = self.playlist(
			playlist_songs[0]['playlistId'],
			include_songs=True
		)

		prev, next_ = get_ple_prev_next(
			playlist['tracks'],
			after=after,
			before=before,
			index=index,
			position=position
		)

		playlist_songs_len = len(playlist_songs)
		for i, playlist_song in enumerate(playlist_songs):
			mutation = mc_calls.PlaylistEntriesBatch.update(
				playlist_song,
				preceding_entry_id=prev.get('id'),
				following_entry_id=next_.get('id')
			)
			response = self._call(mc_calls.PlaylistEntriesBatch, mutation)
			result = response.body['mutate_response'][0]

			# TODO: Proper exception on failure.
			if result['response_code'] != 'OK':
				break

			if i < playlist_songs_len - 1:
				while True:
					prev = self.playlist_song(result['id'])
					if prev:
						break

		return self.playlist(playlist_songs[0]['playlistId'], include_songs=True)


Instruction:
Write a Python 3 script for
getting a listing of songs from a playlist.

Response:
def playlist_songs(self, playlist):
		"""Get a listing of songs from a playlist.

		Paramters:
			playlist (dict): A playlist dict.

		Returns:
			list: Playlist song dicts.
		"""

		playlist_type = playlist.get('type')

		playlist_song_list = []
		if playlist_type in ('USER_GENERATED', None):
			start_token = None
			playlist_song_list = []
			while True:
				response = self._call(
					mc_calls.PlaylistEntryFeed,
					max_results=49995,
					start_token=start_token
				)
				items = response.body.get('data', {}).get('items', [])

				if items:
					playlist_song_list.extend(items)

				start_token = response.body.get('nextPageToken')
				if start_token is None:
					break
		elif playlist_type == 'SHARED':
			playlist_share_token = playlist['shareToken']

			start_token = None
			playlist_song_list = []
			while True:
				response = self._call(
					mc_calls.PlaylistEntriesShared,
					playlist_share_token,
					max_results=49995,
					start_token=start_token
				)
				entry = response.body['entries'][0]
				items = entry.get('playlistEntry', [])

				if items:
					playlist_song_list.extend(items)

				start_token = entry.get('nextPageToken')
				if start_token is None:
					break

		playlist_song_list.sort(key=itemgetter('absolutePosition'))

		return playlist_song_list


Instruction:
Here you have a function in Python 3, explain what it does
def playlist(self, playlist_id, *, include_songs=False):

		playlist_info = next(
			(
				playlist
				for playlist in self.playlists(include_songs=include_songs)
				if playlist['id'] == playlist_id
			),
			None
		)

		return playlist_info

Response: Get information about a playlist.


Instruction:
Create a Python 3 function for
creating a playlist. Parameters: name (str): Name to give the playlist. description (str): Description to give the playlist. make_public (bool, Optional): If ``True`` and account has a subscription, make playlist public. Default: ``False`` songs (list, Optional): A list of song dicts to add to the playlist. Returns: dict: Playlist information.

Response:
def playlist_create(
		self,
		name,
		description='',
		*,
		make_public=False,
		songs=None
	):
		"""Create a playlist.

		Parameters:
			name (str): Name to give the playlist.
			description (str): Description to give the playlist.
			make_public (bool, Optional): If ``True`` and account has a subscription,
				make playlist public.
				Default: ``False``
			songs (list, Optional): A list of song dicts to add to the playlist.

		Returns:
			dict: Playlist information.
		"""

		share_state = 'PUBLIC' if make_public else 'PRIVATE'

		playlist = self._call(
			mc_calls.PlaylistsCreate,
			name,
			description,
			share_state
		).body

		if songs:
			playlist = self.playlist_songs_add(songs, playlist)

		return playlist


Instruction:
Here you have a function in Python 3, explain what it does
def playlist_edit(self, playlist, *, name=None, description=None, public=None):

		if all(
			value is None
			for value in (name, description, public)
		):
			raise ValueError(
				'At least one of name, description, or public must be provided'
			)

		playlist_id = playlist['id']
		playlist = self.playlist(playlist_id)

		name = name if name is not None else playlist['name']
		description = (
			description if description is not None else playlist['description']
		)
		share_state = 'PUBLIC' if public else playlist['accessControlled']

		playlist = self._call(
			mc_calls.PlaylistsUpdate,
			playlist_id,
			name,
			description,
			share_state
		).body

		return playlist

Response:
Edit playlist(s).

		Parameters:
			playlist (dict): A playlist dict.
			name (str): Name to give the playlist.
			description (str, Optional): Description to give the playlist.
			make_public (bool, Optional): If ``True`` and account has a subscription,
				make playlist public.
				Default: ``False``

		Returns:
			dict: Playlist information.


Instruction:
Write a Python 3 script to
subscribe to a public playlist.

Response:
def playlist_subscribe(self, playlist):
		"""Subscribe to a public playlist.

		Parameters:
			playlist (dict): A public playlist dict.

		Returns:
			dict: Playlist information.
		"""

		mutation = mc_calls.PlaylistBatch.create(
			playlist['name'],
			playlist['description'],
			'SHARED',
			owner_name=playlist.get('ownerName', ''),
			share_token=playlist['shareToken']
		)

		response_body = self._call(
			mc_calls.PlaylistBatch,
			mutation
		).body

		playlist_id = response_body['mutate_response'][0]['id']

		return self.playlist(playlist_id)


Instruction:
Write a Python 3 script to
get a listing of library playlists.

Response:
def playlists(self, *, include_songs=False):
		"""Get a listing of library playlists.

		Parameters:
			include_songs (bool, Optional): Include songs in the returned playlist dicts.
				Default: ``False``.

		Returns:
			list: A list of playlist dicts.
		"""

		playlist_list = []
		for chunk in self.playlists_iter(page_size=49995):
			for playlist in chunk:
				if include_songs:
					playlist['tracks'] = self.playlist_songs(playlist)

				playlist_list.append(playlist)

		return playlist_list


Instruction:
Can you create a Python 3 function that
gets a paged iterator of library playlists.

Response:
def playlists_iter(self, *, start_token=None, page_size=250):
		"""Get a paged iterator of library playlists.

		Parameters:
			start_token (str): The token of the page to return.
				Default: Not sent to get first page.
			page_size (int, Optional): The maximum number of results per returned page.
				Max allowed is ``49995``.
				Default: ``250``

		Yields:
			list: Playlist dicts.
		"""

		start_token = None

		while True:
			response = self._call(
				mc_calls.PlaylistFeed,
				max_results=page_size,
				start_token=start_token
			)
			items = response.body.get('data', {}).get('items', [])

			if items:
				yield items

			start_token = response.body.get('nextPageToken')
			if start_token is None:
				break


Instruction:
Implement a function in Python 3 to
get information about a podcast series.

Response:
def podcast(self, podcast_series_id, *, max_episodes=50):
		"""Get information about a podcast series.

		Parameters:
			podcast_series_id (str): A podcast series ID.
			max_episodes (int, Optional): Include up to given number of episodes in returned dict.
				Default: ``50``

		Returns:
			dict: Podcast series information.
		"""

		podcast_info = self._call(
			mc_calls.PodcastFetchSeries,
			podcast_series_id,
			max_episodes=max_episodes
		).body

		return podcast_info


Instruction:
Given the following Python 3 function, write the documentation
def podcasts(self, *, device_id=None):

		if device_id is None:
			device_id = self.device_id

		podcast_list = []
		for chunk in self.podcasts_iter(device_id=device_id, page_size=49995):
			podcast_list.extend(chunk)

		return podcast_list

Response: Get a listing of subsribed podcast series.


Instruction:
Can you tell what is the following Python 3 function doing
def podcasts_iter(self, *, device_id=None, page_size=250):

		if device_id is None:
			device_id = self.device_id

		start_token = None
		prev_items = None

		while True:
			response = self._call(
				mc_calls.PodcastSeries,
				device_id,
				max_results=page_size,
				start_token=start_token
			)
			items = response.body.get('data', {}).get('items', [])

			# Google does some weird shit.
			if items != prev_items:
				subscribed_podcasts = [
					item
					for item in items
					if item.get('userPreferences', {}).get('subscribed')
				]

				yield subscribed_podcasts

				prev_items = items
			else:
				break

			start_token = response.body.get('nextPageToken')
			if start_token is None:
				break

Response: Get a paged iterator of subscribed podcast series.


Instruction:
Make a summary of the following Python 3 code
def podcast_episode(self, podcast_episode_id):

		response = self._call(
			mc_calls.PodcastFetchEpisode,
			podcast_episode_id
		)
		podcast_episode_info = [
			podcast_episode
			for podcast_episode in response.body
			if not podcast_episode['deleted']
		]

		return podcast_episode_info

Response: Get information about a podcast episode.


Instruction:
Here you have a function in Python 3, explain what it does
def podcast_episodes(self, *, device_id=None):

		if device_id is None:
			device_id = self.device_id

		podcast_episode_list = []
		for chunk in self.podcast_episodes_iter(
			device_id=device_id,
			page_size=49995
		):
			podcast_episode_list.extend(chunk)

		return podcast_episode_list

Response: Get a listing of podcast episodes for all subscribed podcasts.


Instruction:
Here you have a function in Python 3, explain what it does
def podcast_episodes_iter(self, *, device_id=None, page_size=250):

		if device_id is None:
			device_id = self.device_id

		start_token = None
		prev_items = None

		while True:
			response = self._call(
				mc_calls.PodcastEpisode,
				device_id,
				max_results=page_size,
				start_token=start_token
			)
			items = response.body.get('data', {}).get('items', [])

			# Google does some weird shit.
			if items != prev_items:
				yield items

				prev_items = items
			else:
				break

			start_token = response.body.get('nextPageToken')
			if start_token is None:
				break

Response: Get a paged iterator of podcast episode for all subscribed podcasts.


Instruction:
Can you create a Python 3 function that
searches Google Music and library for content.

Response:
def search(self, query, *, max_results=100, **kwargs):
		"""Search Google Music and library for content.

		Parameters:
			query (str): Search text.
			max_results (int, Optional): Maximum number of results per type per
				location to retrieve. I.e up to 100 Google and 100 library
				for a total of 200 for the default value.
				Google only accepts values up to 100.
				Default: ``100``
			kwargs (bool, Optional): Any of ``albums``, ``artists``, ``genres``,
				``playlists``, ``podcasts``, ``situations``, ``songs``, ``stations``,
				``videos`` set to ``True`` will include that result type in the
				returned dict.
				Setting none of them will include all result types in the returned dict.

		Returns:
			dict: A dict of results separated into keys: ``'albums'``, ``'artists'``,
				``'genres'``, ``'playlists'``, ```'podcasts'``, ``'situations'``,
				``'songs'``, ``'stations'``, ``'videos'``.

		Note:
			Free account search is restricted so may not contain hits for all result types.
		"""

		results = defaultdict(list)

		for type_, results_ in self.search_library(
			query,
			max_results=max_results,
			**kwargs
		).items():
			results[type_].extend(results_)

		for type_, results_ in self.search_google(
			query,
			max_results=max_results,
			**kwargs
		).items():
			results[type_].extend(results_)

		return dict(results)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def search_google(self, query, *, max_results=100, **kwargs):

		response = self._call(
			mc_calls.Query,
			query,
			max_results=max_results,
			**kwargs
		)

		clusters = response.body.get('clusterDetail', [])
		results = defaultdict(list)

		for cluster in clusters:
			result_type = QueryResultType(cluster['cluster']['type']).name

			entries = cluster.get('entries', [])
			if len(entries) > 0:
				for entry in entries:
					item_key = next(
						key
						for key in entry
						if key not in ['cluster', 'score', 'type']
					)
					results[f"{result_type}s"].append(entry[item_key])

		return dict(results)

Response: Search Google Music for content.


Instruction:
Given the following Python 3 function, write the documentation
def search_library(self, query, *, max_results=100, **kwargs):

		def match_fields(item, fields):
			return any(
				query.casefold() in item.get(field, '').casefold()
				for field in fields
			)

		types = [
			(
				'playlists',
				['description', 'name'],
				self.playlists
			),
			(
				'podcasts',
				['author', 'description', 'title'],
				self.podcasts
			),
			(
				'songs',
				['album', 'albumArtist', 'artist', 'composer', 'genre', 'title'],
				self.songs
			),
			(
				'stations',
				['byline', 'description', 'name'],
				self.stations
			),
		]

		results = {}

		for type_, fields, func in types:
			if (not kwargs) or (type_ in kwargs):
				results[type_] = [
					item
					for item in func()
					if match_fields(item, fields)
				][:max_results]

		return results

Response: Search Google Music for content.


Instruction:
Explain what the following Python 3 code does
def search_suggestion(self, query):

		response = self._call(
			mc_calls.QuerySuggestion,
			query
		)
		suggested_queries = response.body.get('suggested_queries', [])

		return [
			suggested_query['suggestion_string']
			for suggested_query in suggested_queries
		]

Response: Get search query suggestions for query.


Instruction:
Write a Python 3 function that can
get a listing of album songs.

Response:
def shuffle_album(
		self, album, *, num_songs=100, only_library=False, recently_played=None
	):
		"""Get a listing of album shuffle/mix songs.

		Parameters:
			album (dict): An album dict.
			num_songs (int, Optional): The maximum number of songs to return from the station.
				Default: ``100``
			only_library (bool, Optional): Only return content from library.
				Default: False
			recently_played (list, Optional): A list of dicts in the form of {'id': '', 'type'}
				where ``id`` is a song ID and ``type`` is 0 for a library song and 1 for a store song.

		Returns:
			list: List of album shuffle/mix songs.
		"""

		station_info = {
			'seed': {
				'albumId': album['albumId'],
				'seedType': StationSeedType.album.value
			},
			'num_entries': num_songs,
			'library_content_only': only_library,
		}

		if recently_played is not None:
			station_info['recently_played'] = recently_played

		response = self._call(
			mc_calls.RadioStationFeed,
			station_infos=[station_info]
		)
		station_feed = response.body.get('data', {}).get('stations', [])

		try:
			station = station_feed[0]
		except IndexError:
			station = {}

		return station.get('tracks', [])


Instruction:
Can you implement a function in Python 3 that
gets a listing of artist shuffle/mix songs. Parameters: artist (dict): An artist dict. num_songs (int, Optional): The maximum number of songs to return from the station. Default: ``100`` only_library (bool, Optional): Only return content from library. Default: False recently_played (list, Optional): A list of dicts in the form of {'id': '', 'type'} where ``id`` is a song ID and ``type`` is 0 for a library song and 1 for a store song. only_artist (bool, Optional): If ``True``, only return songs from the artist, else return songs from artist and related artists. Default: ``False`` Returns: list: List of artist shuffle/mix songs.

Response:
def shuffle_artist(
		self,
		artist,
		*,
		num_songs=100,
		only_library=False,
		recently_played=None,
		only_artist=False
	):
		"""Get a listing of artist shuffle/mix songs.

		Parameters:
			artist (dict): An artist dict.
			num_songs (int, Optional): The maximum number of songs to return from the station.
				Default: ``100``
			only_library (bool, Optional): Only return content from library.
				Default: False
			recently_played (list, Optional): A list of dicts in the form of {'id': '', 'type'}
				where ``id`` is a song ID and ``type`` is 0 for a library song and 1 for a store song.
			only_artist (bool, Optional): If ``True``, only return songs from the artist,
					else return songs from artist and related artists.
					Default: ``False``

		Returns:
			list: List of artist shuffle/mix songs.
		"""

		station_info = {
			'num_entries': num_songs,
			'library_content_only': only_library
		}

		if only_artist:
			station_info['seed'] = {
				'artistId': artist['artistId'],
				'seedType': StationSeedType.artist_only.value
			}
		else:
			station_info['seed'] = {
				'artistId': artist['artistId'],
				'seedType': StationSeedType.artist_related.value
			}

		if recently_played is not None:
			station_info['recently_played'] = recently_played

		response = self._call(
			mc_calls.RadioStationFeed,
			station_infos=[station_info]
		)
		station_feed = response.body.get('data', {}).get('stations', [])

		try:
			station = station_feed[0]
		except IndexError:
			station = {}

		return station.get('tracks', [])


Instruction:
Given the following Python 3 function, write the documentation
def shuffle_song(
		self, song, *, num_songs=100, only_library=False, recently_played=None
	):
		"""Get a listing of song shuffle/mix songs.

		Parameters:
			song (dict): A song dict.
			num_songs (int, Optional): The maximum number of songs to return from the station.
				Default: ``100``
			only_library (bool, Optional): Only return content from library.
				Default: False
			recently_played (list, Optional): A list of dicts in the form of {'id': '', 'type'}
				where ``id`` is a song ID and ``type`` is 0 for a library song and 1 for a store song.

		Returns:
			list: List of artist shuffle/mix songs.
		"""

		station_info = {
			'num_entries': num_songs,
			'library_content_only': only_library
		}

		if 'storeId' in song:
			station_info['seed'] = {
				'trackId': song['storeId'],
				'seedType': StationSeedType.store_track.value
			}
		else:
			station_info['seed'] = {
				'trackLockerId': song['id'],
				'seedType': StationSeedType.library_track.value
			}

		if recently_played is not None:
			station_info['recently_played'] = recently_played

		response = self._call(mc_calls.RadioStationFeed, station_infos=[station_info])
		station_feed = response.body.get('data', {}).get('stations', [])

		try:
			station = station_feed[0]
		except IndexError:
			station = {}

		return station.get('tracks', [])

Response: Get a listing of a song shuffle or mix songs.


Instruction:
Can you generate the documentation for the following Python 3 function
def situations(self, *, tz_offset=None):

		response = self._call(
			mc_calls.ListenNowSituations,
			tz_offset
		)
		situation_list = response.body.get('situations', [])

		return situation_list

Response: Get a listing of situations.


Instruction:
Can you write a function in Python 3 where it
gets information about a song.

Response:
def song(self, song_id):
		"""Get information about a song.

		Parameters:
			song_id (str): A song ID.

		Returns:
			dict: Song information.
		"""

		if song_id.startswith('T'):
			song_info = self._call(
				mc_calls.FetchTrack,
				song_id
			).body
		else:
			song_info = next(
				(
					song
					for song in self.songs()
					if song['id'] == song_id
				),
				None
			)

		return song_info


Instruction:
Implement a Python 3 function for
adding store songs to your library.

Response:
def songs_add(self, songs):
		"""Add store songs to your library.

		Parameters:
			songs (list): A list of store song dicts.

		Returns:
			list: Songs' library IDs.
		"""

		mutations = [mc_calls.TrackBatch.add(song) for song in songs]
		response = self._call(
			mc_calls.TrackBatch,
			mutations
		)

		success_ids = [
			res['id']
			for res in response.body['mutate_response']
			if res['response_code'] == 'OK'
		]

		return success_ids


Instruction:
How would you explain what the following Python 3 function does
def songs_delete(self, songs):

		mutations = [mc_calls.TrackBatch.delete(song['id']) for song in songs]
		response = self._call(
			mc_calls.TrackBatch,
			mutations
		)

		success_ids = [
			res['id']
			for res in response.body['mutate_response']
			if res['response_code'] == 'OK'
		]

		# TODO: Report failures.
		# failure_ids = [
		# 	res['id']
		# 	for res in response.body['mutate_response']
		# 	if res['response_code'] != 'OK'
		# ]

		return success_ids

Response: Delete songs from library.


Instruction:
Can you implement a function in Python 3 that
adds play to song play count.

Response:
def song_play(self, song):
		"""Add play to song play count.

		Parameters:
			song (dict): A song dict.

		Returns:
			bool: ``True`` if successful, ``False`` if not.
		"""

		if 'storeId' in song:
			song_id = song['storeId']
		elif 'trackId' in song:
			song_id = song['trackId']
		else:
			song_id = song['id']

		song_duration = song['durationMillis']

		event = mc_calls.ActivityRecordRealtime.play(song_id, song_duration)
		response = self._call(
			mc_calls.ActivityRecordRealtime,
			event
		)

		return True if response.body['eventResults'][0]['code'] == 'OK' else False