<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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]