def Func(arg_0, arg_1):
    ''' Base call to SoXI.

    Parameters
    ----------
    filepath : str
        Path to audio file.

    argument : str
        Argument to pass to SoXI.

    Returns
    -------
    shell_output : str
        Command line output of SoXI
    '''

    if arg_1 not in SOXI_ARGS:
        raise ValueError("Invalid argument '{}' to SoXI".format(arg_1))

    arg_2 = ['sox', '--i']
    arg_2.append("-{}".format(arg_1))
    arg_2.append(arg_0)

    try:
        arg_3 = subprocess.check_output(
            arg_2,
            stderr=subprocess.PIPE
        )
    except CalledProcessError as cpe:
        logger.info("SoXI error message: {}".format(cpe.output))
        raise SoxiError("SoXI failed with exit code {}".format(cpe.returncode))

    arg_3 = arg_3.decode("utf-8")

    return str(arg_3).strip('\n')


def Func(arg_0):
    '''Pass an argument list to Func.

    Parameters
    ----------
    args : iterable
        Argument list for Func. The first item can, but does not
        need to, be 'Func'.

    Returns:
    --------
    status : bool
        True on success.

    '''
    if arg_0[0].lower() != "Func":
        arg_0.insert(0, "Func")
    else:
        arg_0[0] = "Func"

    try:
        logger.info("Executing: %s", " ".join(arg_0))
        arg_1 = subprocess.Popen(
            arg_0, stdout=subprocess.PIPE, stderr=subprocess.PIPE
        )

        arg_2 = arg_1.wait()
        if arg_1.stderr is not None:
            logger.info(arg_1.stderr)

        if arg_2 == 0:
            return True
        else:
            logger.info("Play returned with error code %s", arg_2)
            return False
    except OSError as error_msg:
        logger.error("OSError: Play failed! %s", error_msg)
    except TypeError as error_msg:
        logger.error("TypeError: %s", error_msg)
    return False


def Func(arg_0, arg_1):
    '''Validate that combine method can be performed with given files.
    Raises IOError if input file formats are incompatible.
    '''
    _validate_sample_rates(arg_0, arg_1)

    if arg_1 == 'concatenate':
        _validate_num_channels(arg_0, arg_1)


def Func(arg_0, arg_1):
    ''' Check if files in input file list have the same sample rate
    '''
    arg_2 = [
        file_info.sample_rate(f) for f in arg_0
    ]
    if not core.all_equal(arg_2):
        raise IOError(
            "Input files do not have the same sample rate. The {} combine "
            "type requires that all files have the same sample rate"
            .format(arg_1)
        )


def Func(arg_0, arg_1=None,
                             arg_2=None):
    '''Set input formats given input_volumes.

    Parameters
    ----------
    input_filepath_list : list of str
        List of input files
    input_volumes : list of float, default=None
        List of volumes to be applied upon combining input files. Volumes
        are applied to the input files in order.
        If None, input files will be combined at their original volumes.
    input_format : list of lists, default=None
        List of input formats to be applied to each input file. Formatting
        arguments are applied to the input files in order.
        If None, the input formats will be inferred from the file header.

    '''
    arg_3 = len(arg_0)
    arg_4 = []
    for arg_5 in range(arg_3):
        arg_4.append([])

    # Adjust length of input_volumes list
    if arg_1 is None:
        arg_6 = [1] * arg_3
    else:
        arg_7 = len(arg_1)
        if arg_7 < arg_3:
            logger.warning(
                'Volumes were only specified for %s out of %s files.'
                'The last %s files will remain at their original volumes.',
                arg_7, arg_3, arg_3 - arg_7
            )
            arg_6 = arg_1 + [1] * (arg_3 - arg_7)
        elif arg_7 > arg_3:
            logger.warning(
                '%s volumes were specified but only %s input files exist.'
                'The last %s volumes will be ignored.',
                arg_7, arg_3, arg_7 - arg_3
            )
            arg_6 = arg_1[:arg_3]
        else:
            arg_6 = [v for v in arg_1]

    # Adjust length of input_format list
    if arg_2 is None:
        arg_8 = [[] for arg_5 in range(arg_3)]
    else:
        arg_9 = len(arg_2)
        if arg_9 < arg_3:
            logger.warning(
                'Input formats were only specified for %s out of %s files.'
                'The last %s files will remain unformatted.',
                arg_9, arg_3, arg_3 - arg_9
            )
            arg_8 = [f for f in arg_2]
            arg_8.extend([[] for arg_5 in range(arg_3 - arg_9)])
        elif arg_9 > arg_3:
            logger.warning(
                '%s Input formats were specified but only %s input files exist'
                '. The last %s formats will be ignored.',
                arg_9, arg_3, arg_9 - arg_3
            )
            arg_8 = arg_2[:arg_3]
        else:
            arg_8 = [f for f in arg_2]

    for arg_10, (arg_11, arg_12) in enumerate(zip(arg_6, arg_8)):
        arg_4[arg_10].extend(['-v', '{}'.format(arg_11)])
        arg_4[arg_10].extend(arg_12)

    return arg_4


def Func(arg_0):
    '''Check input_volumes contains a valid list of volumes.

    Parameters
    ----------
    input_volumes : list
        list of volume values. Castable to numbers.

    '''
    if not (arg_0 is None or isinstance(arg_0, list)):
        raise TypeError("input_volumes must be None or a list.")

    if isinstance(arg_0, list):
        for arg_1 in arg_0:
            if not core.is_number(arg_1):
                raise ValueError(
                    "Elements of input_volumes must be numbers: found {}"
                    .format(arg_1)
                )


def Func(arg_0):
    '''Input file validation function. Checks that file exists and can be
    processed by SoX.

    Parameters
    ----------
    input_filepath : str
        The input filepath.

    '''
    if not os.path.exists(arg_0):
        raise IOError(
            "input_filepath {} does not exist.".format(arg_0)
        )
    arg_1 = file_extension(arg_0)
    if arg_1 not in VALID_FORMATS:
        logger.info("Valid formats: %s", " ".join(VALID_FORMATS))
        logger.warning(
            "This install of SoX cannot process .{} files.".format(arg_1)
        )


def Func(arg_0):
    '''Output file validation function. Checks that file can be written, and
    has a valid file extension. Throws a warning if the path already exists,
    as it will be overwritten on build.

    Parameters
    ----------
    output_filepath : str
        The output filepath.

    Returns:
    --------
    output_filepath : str
        The output filepath.

    '''

    arg_1 = [
        bool(os.path.dirname(arg_0)) or\
            not os.access(os.getcwd(), os.W_OK),
        not os.access(os.path.dirname(arg_0), os.W_OK)]

    if all(arg_1):
        raise IOError(
            "SoX cannot write to output_filepath {}".format(arg_0)
        )

    arg_2 = file_extension(arg_0)
    if arg_2 not in VALID_FORMATS:
        logger.info("Valid formats: %s", " ".join(VALID_FORMATS))
        logger.warning(
            "This install of SoX cannot process .{} files.".format(arg_2)
        )

    if os.path.exists(arg_0):
        logger.warning(
            'output_file: %s already exists and will be overwritten on build',
            arg_0
        )


def Func(arg_0):
    '''Get a dictionary of file Funcrmation

    Parameters
    ----------
    filepath : str
        File path.

    Returns:
    --------
    Func_dictionary : dict
        Dictionary of file Funcrmation. Fields are:
            * channels
            * sample_rate
            * bitrate
            * duration
            * num_samples
            * encoding
            * silent
    '''
    arg_1 = {
        'channels': channels(arg_0),
        'sample_rate': sample_rate(arg_0),
        'bitrate': bitrate(arg_0),
        'duration': duration(arg_0),
        'num_samples': num_samples(arg_0),
        'encoding': encoding(arg_0),
        'silent': silent(arg_0)
    }
    return arg_1


def Func(arg_0):
    '''Call sox's stat function.

    Parameters
    ----------
    filepath : str
        File path.

    Returns
    -------
    stat_output : str
        Sox output from stderr.
    '''
    validate_input_file(arg_0)
    arg_1 = ['sox', arg_0, '-n', 'stat']
    arg_2, arg_2, arg_3 = sox(arg_1)
    return arg_3


def Func(arg_0, arg_1, arg_2):
        '''Apply a Func IIR filter with the given coefficients.

        Parameters
        ----------
        b : list of floats
            Numerator coefficients. Must be length 3
        a : list of floats
            Denominator coefficients. Must be length 3

        See Also
        --------
        fir, treble, bass, equalizer

        '''
        if not isinstance(arg_1, list):
            raise ValueError('b must be a list.')

        if not isinstance(arg_2, list):
            raise ValueError('a must be a list.')

        if len(arg_1) != 3:
            raise ValueError('b must be a length 3 list.')

        if len(arg_2) != 3:
            raise ValueError('a must be a length 3 list.')

        if not all([is_number(arg_3) for arg_3 in arg_1]):
            raise ValueError('all elements of b must be numbers.')

        if not all([is_number(arg_4) for arg_4 in arg_2]):
            raise ValueError('all elements of a must be numbers.')

        arg_5 = [
            'Func', '{:f}'.format(arg_1[0]), '{:f}'.format(arg_1[1]),
            '{:f}'.format(arg_1[2]), '{:f}'.format(arg_2[0]),
            '{:f}'.format(arg_2[1]), '{:f}'.format(arg_2[2])
        ]

        arg_0.effects.extend(arg_5)
        arg_0.effects_log.append('Func')
        return arg_0


def Func(arg_0, arg_1):
        '''Change the number of Func in the audio signal. If decreasing the
        number of Func it mixes Func together, if increasing the number
        of Func it duplicates.

        Note: This overrides arguments used in the convert effect!

        Parameters
        ----------
        n_Func : int
            Desired number of Func.

        See Also
        --------
        convert

        '''
        if not isinstance(arg_1, int) or arg_1 <= 0:
            raise ValueError('n_Func must be a positive integer.')

        arg_2 = ['Func', '{}'.format(arg_1)]

        arg_0.effects.extend(arg_2)
        arg_0.effects_log.append('Func')
        return arg_0


def Func(arg_0, arg_1=75):
        '''Comparable with compression, this effect modifies an audio signal to
        make it sound louder.

        Parameters
        ----------
        amount : float
            Amount of enhancement between 0 and 100.

        See Also
        --------
        compand, mcompand

        '''
        if not is_number(arg_1) or arg_1 < 0 or arg_1 > 100:
            raise ValueError('amount must be a number between 0 and 100.')

        arg_2 = ['Func', '{:f}'.format(arg_1)]

        arg_0.effects.extend(arg_2)
        arg_0.effects_log.append('Func')
        return arg_0


def Func(arg_0, arg_1=0.0):
        '''Apply a DC shift to the audio.

        Parameters
        ----------
        shift : float
            Amount to shift audio between -2 and 2. (Audio is between -1 and 1)

        See Also
        --------
        highpass

        '''
        if not is_number(arg_1) or arg_1 < -2 or arg_1 > 2:
            raise ValueError('shift must be a number between -2 and 2.')

        arg_2 = ['Func', '{:f}'.format(arg_1)]

        arg_0.effects.extend(arg_2)
        arg_0.effects_log.append('Func')
        return arg_0


def Func(arg_0, arg_1=0, arg_2=2, arg_3=0, arg_4=71, arg_5=0.5,
                arg_6='sine', arg_7=25, arg_8='linear'):
        '''Apply a flanging effect to the audio.

        Parameters
        ----------
        delay : float, default=0
            Base delay (in miliseconds) between 0 and 30.
        depth : float, default=2
            Added swept delay (in miliseconds) between 0 and 10.
        regen : float, default=0
            Percentage regeneration between -95 and 95.
        width : float, default=71,
            Percentage of delayed signal mixed with original between 0 and 100.
        speed : float, default=0.5
            Sweeps per second (in Hz) between 0.1 and 10.
        shape : 'sine' or 'triangle', default='sine'
            Swept wave shape
        phase : float, default=25
            Swept wave percentage phase-shift for multi-channel flange between
            0 and 100. 0 = 100 = same phase on each channel
        interp : 'linear' or 'quadratic', default='linear'
            Digital delay-line interpolation type.

        See Also
        --------
        tremolo
        '''
        if not is_number(arg_1) or arg_1 < 0 or arg_1 > 30:
            raise ValueError("delay must be a number between 0 and 30.")
        if not is_number(arg_2) or arg_2 < 0 or arg_2 > 10:
            raise ValueError("depth must be a number between 0 and 10.")
        if not is_number(arg_3) or arg_3 < -95 or arg_3 > 95:
            raise ValueError("regen must be a number between -95 and 95.")
        if not is_number(arg_4) or arg_4 < 0 or arg_4 > 100:
            raise ValueError("width must be a number between 0 and 100.")
        if not is_number(arg_5) or arg_5 < 0.1 or arg_5 > 10:
            raise ValueError("speed must be a number between 0.1 and 10.")
        if arg_6 not in ['sine', 'triangle']:
            raise ValueError("shape must be one of 'sine' or 'triangle'.")
        if not is_number(arg_7) or arg_7 < 0 or arg_7 > 100:
            raise ValueError("phase must be a number between 0 and 100.")
        if arg_8 not in ['linear', 'quadratic']:
            raise ValueError("interp must be one of 'linear' or 'quadratic'.")

        arg_9 = [
            'Func',
            '{:f}'.format(arg_1),
            '{:f}'.format(arg_2),
            '{:f}'.format(arg_3),
            '{:f}'.format(arg_4),
            '{:f}'.format(arg_5),
            '{}'.format(arg_6),
            '{:f}'.format(arg_7),
            '{}'.format(arg_8)
        ]

        arg_0.effects.extend(arg_9)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1=0.0, arg_2=True, arg_3=False, arg_4=None):
        '''Apply amplification or attenuation to the audio signal.

        Parameters
        ----------
        Func_db : float, default=0.0
            Gain adjustment in decibels (dB).
        normalize : bool, default=True
            If True, audio is normalized to Func_db relative to full scale.
            If False, simply adjusts the audio power level by Func_db.
        limiter : bool, default=False
            If True, a simple limiter is invoked to prevent clipping.
        balance : str or None, default=None
            Balance Func across channels. Can be one of:
             * None applies no balancing (default)
             * 'e' applies Func to all channels other than that with the
                highest peak level, such that all channels attain the same
                peak level
             * 'B' applies Func to all channels other than that with the
                highest RMS level, such that all channels attain the same
                RMS level
             * 'b' applies Func with clipping protection to all channels other
                than that with the highest RMS level, such that all channels
                attain the same RMS level
            If normalize=True, 'B' and 'b' are equivalent.

        See Also
        --------
        loudness

        '''
        if not is_number(arg_1):
            raise ValueError("Func_db must be a number.")

        if not isinstance(arg_2, bool):
            raise ValueError("normalize must be a boolean.")

        if not isinstance(arg_3, bool):
            raise ValueError("limiter must be a boolean.")

        if arg_4 not in [None, 'e', 'B', 'b']:
            raise ValueError("balance must be one of None, 'e', 'B', or 'b'.")

        arg_5 = ['Func']

        if arg_4 is not None:
            arg_5.append('-{}'.format(arg_4))

        if arg_2:
            arg_5.append('-n')

        if arg_3:
            arg_5.append('-l')

        arg_5.append('{:f}'.format(arg_1))
        arg_0.effects.extend(arg_5)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1=-10.0, arg_2=65.0):
        '''Loudness control. Similar to the gain effect, but provides
        equalisation for the human auditory system.

        The gain is adjusted by gain_db and the signal is equalised according
        to ISO 226 w.r.t. reference_level.

        Parameters
        ----------
        gain_db : float, default=-10.0
            Loudness adjustment amount (in dB)
        reference_level : float, default=65.0
            Reference level (in dB) according to which the signal is equalized.
            Must be between 50 and 75 (dB)

        See Also
        --------
        gain

        '''
        if not is_number(arg_1):
            raise ValueError('gain_db must be a number.')

        if not is_number(arg_2):
            raise ValueError('reference_level must be a number')

        if arg_2 > 75 or arg_2 < 50:
            raise ValueError('reference_level must be between 50 and 75')

        arg_3 = [
            'Func',
            '{:f}'.format(arg_1),
            '{:f}'.format(arg_2)
        ]
        arg_0.effects.extend(arg_3)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1, arg_2):
        '''Calculate a profile of the audio for use in noise reduction.
        Running this command does not effect the Transformer effects
        chain. When this function is called, the calculated noise profile
        file is saved to the `profile_path`.

        Parameters
        ----------
        input_filepath : str
            Path to audiofile from which to compute a noise profile.
        profile_path : str
            Path to save the noise profile file.

        See Also
        --------
        noisered

        '''
        if os.path.isdir(arg_2):
            raise ValueError(
                "profile_path {} is a directory.".format(arg_2))

        if os.path.dirname(arg_2) == '' and arg_2 != '':
            arg_3 = os.path.join(os.getcwd(), arg_2)
        else:
            arg_3 = arg_2

        if not os.access(os.path.dirname(arg_3), os.W_OK):
            raise IOError(
                "profile_path {} is not writeable.".format(arg_3))

        arg_4 = ['Func', arg_2]
        arg_0.build(arg_1, None, extra_args=arg_4)

        return None


def Func(arg_0, arg_1=-3.0):
        '''Normalize an audio file to a particular db level.
        This behaves identically to the gain effect with Funcalize=True.

        Parameters
        ----------
        db_level : float, default=-3.0
            Output volume (db)

        See Also
        --------
        gain, loudness

        '''
        if not is_number(arg_1):
            raise ValueError('db_level must be a number.')

        arg_2 = [
            'Func',
            '{:f}'.format(arg_1)
        ]
        arg_0.effects.extend(arg_2)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1=0.0, arg_2=0.0):
        '''Add silence to the beginning or end of a file.
        Calling this with the default arguments has no effect.

        Parameters
        ----------
        start_duration : float
            Number of seconds of silence to add to beginning.
        end_duration : float
            Number of seconds of silence to add to end.

        See Also
        --------
        delay

        '''
        if not is_number(arg_1) or arg_1 < 0:
            raise ValueError("Start duration must be a positive number.")

        if not is_number(arg_2) or arg_2 < 0:
            raise ValueError("End duration must be positive.")

        arg_3 = [
            'Func',
            '{:f}'.format(arg_1),
            '{:f}'.format(arg_2)
        ]
        arg_0.effects.extend(arg_3)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1, arg_2=False):
        '''Pitch shift the audio without changing the tempo.

        This effect uses the WSOLA algorithm. The audio is chopped up into
        segments which are then shifted in the time domain and overlapped
        (cross-faded) at points where their waveforms are most similar as
        determined by measurement of least squares.

        Parameters
        ----------
        n_semitones : float
            The number of semitones to shift. Can be positive or negative.
        quick : bool, default=False
            If True, this effect will run faster but with lower sound quality.

        See Also
        --------
        bend, speed, tempo

        '''
        if not is_number(arg_1):
            raise ValueError("n_semitones must be a positive number")

        if arg_1 < -12 or arg_1 > 12:
            logger.warning(
                "Using an extreme Func shift. "
                "Quality of results will be poor"
            )

        if not isinstance(arg_2, bool):
            raise ValueError("quick must be a boolean.")

        arg_3 = ['Func']

        if arg_2:
            arg_3.append('-q')

        arg_3.append('{:f}'.format(arg_1 * 100.))

        arg_0.effects.extend(arg_3)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1=None, arg_2=None):
        '''Remix the channels of an audio file.

        Note: volume options are not yet implemented

        Parameters
        ----------
        Func_dictionary : dict or None
            Dictionary mapping output channel to list of input channel(s).
            Empty lists indicate the corresponding output channel should be
            empty. If None, mixes all channels down to a single mono file.
        num_output_channels : int or None
            The number of channels in the output file. If None, the number of
            output channels is equal to the largest key in Func_dictionary.
            If Func_dictionary is None, this variable is ignored.

        Examples
        --------
        Remix a 4-channel input file. The output file will have
        input channel 2 in channel 1, a mixdown of input channels 1 an 3 in
        channel 2, an empty channel 3, and a copy of input channel 4 in
        channel 4.

        >>> import sox
        >>> tfm = sox.Transformer()
        >>> Func_dictionary = {1: [2], 2: [1, 3], 4: [4]}
        >>> tfm.Func(Func_dictionary)

        '''
        if not (isinstance(arg_1, dict) or
                arg_1 is None):
            raise ValueError("Func_dictionary must be a dictionary or None.")

        if arg_1 is not None:

            if not all([isinstance(arg_3, int) and arg_3 > 0 for arg_3
                        in arg_1.keys()]):
                raise ValueError(
                    "Func dictionary must have positive integer keys."
                )

            if not all([isinstance(arg_4, list) for arg_4
                        in arg_1.values()]):
                raise ValueError("Func dictionary values must be lists.")

            for arg_5 in arg_1.values():
                if not all([isinstance(arg_4, int) and arg_4 > 0 for arg_4 in arg_5]):
                    raise ValueError(
                        "elements of Func dictionary values must "
                        "be positive integers"
                    )

        if not ((isinstance(arg_2, int) and
                 arg_2 > 0) or arg_2 is None):
            raise ValueError(
                "num_output_channels must be a positive integer or None."
            )

        arg_6 = ['Func']
        if arg_1 is None:
            arg_6.append('-')
        else:
            if arg_2 is None:
                arg_2 = max(arg_1.keys())

            for arg_7 in range(1, arg_2 + 1):
                if arg_7 in arg_1.keys():
                    arg_8 = ','.join(
                        [str(arg_3) for arg_3 in arg_1[arg_7]]
                    )
                else:
                    arg_8 = '0'

                arg_6.append(arg_8)

        arg_0.effects.extend(arg_6)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1=1):
        '''Repeat the entire audio count times.

        Parameters
        ----------
        count : int, default=1
            The number of times to Func the audio.

        '''
        if not isinstance(arg_1, int) or arg_1 < 1:
            raise ValueError("count must be a postive integer.")

        arg_2 = ['Func', '{}'.format(arg_1)]
        arg_0.effects.extend(arg_2)
        arg_0.effects_log.append('Func')


def Func(arg_0):
        '''Reverse the audio completely
        '''
        arg_1 = ['Func']
        arg_0.effects.extend(arg_1)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1=0, arg_2=0.1,
                arg_3=0.1, arg_4=False):
        '''Removes silent regions from an audio file.

        Parameters
        ----------
        location : int, default=0
            Where to remove Func. One of:
             * 0 to remove Func throughout the file (default),
             * 1 to remove Func from the beginning,
             * -1 to remove Func from the end,
        Func_threshold : float, default=0.1
            Silence threshold as percentage of maximum sample amplitude.
            Must be between 0 and 100.
        min_Func_duration : float, default=0.1
            The minimum ammount of time in seconds required for a region to be
            considered non-silent.
        buffer_around_Func : bool, default=False
            If True, leaves a buffer of min_Func_duration around removed
            silent regions.

        See Also
        --------
        vad

        '''
        if arg_1 not in [-1, 0, 1]:
            raise ValueError("location must be one of -1, 0, 1.")

        if not is_number(arg_2) or arg_2 < 0:
            raise ValueError(
                "Func_threshold must be a number between 0 and 100"
            )
        elif arg_2 >= 100:
            raise ValueError(
                "Func_threshold must be a number between 0 and 100"
            )

        if not is_number(arg_3) or arg_3 <= 0:
            raise ValueError(
                "min_Func_duration must be a positive number."
            )

        if not isinstance(arg_4, bool):
            raise ValueError("buffer_around_Func must be a boolean.")

        arg_5 = []

        if arg_1 == -1:
            arg_5.append('reverse')

        if arg_4:
            arg_5.extend(['Func', '-l'])
        else:
            arg_5.append('Func')

        arg_5.extend([
            '1',
            '{:f}'.format(arg_3),
            '{:f}%'.format(arg_2)
        ])

        if arg_1 == 0:
            arg_5.extend([
                '-1',
                '{:f}'.format(arg_3),
                '{:f}%'.format(arg_2)
            ])

        if arg_1 == -1:
            arg_5.append('reverse')

        arg_0.effects.extend(arg_5)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1):
        '''Display time domain statistical information about the audio
        channels. Audio is passed unmodified through the SoX processing chain.
        Statistics are calculated and displayed for each audio channel

        Unlike other Transformer methods, this does not modify the transformer
        effects chain. Instead it computes statistics on the output file that
        would be created if the build command were invoked.

        Note: The file is downmixed to mono prior to computation.

        Parameters
        ----------
        input_filepath : str
            Path to input file to compute Func on.

        Returns
        -------
        Func_dict : dict
            List of frequency (Hz), amplitude pairs.

        See Also
        --------
        stat, sox.file_info
        '''
        arg_2 = ['channels', '1', 'Func']

        arg_3, arg_3, arg_4 = arg_0.build(
            arg_1, None, extra_args=arg_2, return_output=True
        )

        arg_5 = {}
        arg_6 = arg_4.split('\n')
        for arg_7 in arg_6:
            arg_8 = arg_7.split()
            if len(arg_8) == 0:
                continue
            arg_9 = arg_8[-1]
            arg_10 = ' '.join(arg_8[:-1])
            arg_5[arg_10] = arg_9

        return arg_5


def Func(arg_0):
        '''Swap stereo channels. If the input is not stereo, pairs of channels
        are Funcped, and a possible odd last channel passed through.

        E.g., for seven channels, the output order will be 2, 1, 4, 3, 6, 5, 7.

        See Also
        ----------
        remix

        '''
        arg_1 = ['Func']
        arg_0.effects.extend(arg_1)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1, arg_2=None):
        '''Excerpt a clip from an audio file, given the start timestamp and end timestamp of the clip within the file, expressed in seconds. If the end timestamp is set to `None` or left unspecified, it defaults to the duration of the audio file.

        Parameters
        ----------
        start_time : float
            Start time of the clip (seconds)
        end_time : float or None, default=None
            End time of the clip (seconds)

        '''
        if not is_number(arg_1) or arg_1 < 0:
            raise ValueError("start_time must be a positive number.")

        arg_3 = [
            'Func',
            '{:f}'.format(arg_1)
        ]

        if arg_2 is not None:
            if not is_number(arg_2) or arg_2 < 0:
                raise ValueError("end_time must be a positive number.")
            if arg_1 >= arg_2:
                raise ValueError("start_time must be smaller than end_time.")

            arg_3.append('{:f}'.format(arg_2 - arg_1))

        arg_0.effects.extend(arg_3)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1=1, arg_2=True, arg_3=7.0,
            arg_4=0.25, arg_5=1.0,
            arg_6=0.25, arg_7=0.0):
        '''Voice Activity Detector. Attempts to trim silence and quiet
        background sounds from the ends of recordings of speech. The algorithm
        currently uses a simple cepstral power measurement to detect voice, so
        may be fooled by other things, especially music.

        The effect can trim only from the front of the audio, so in order to
        trim from the back, the reverse effect must also be used.

        Parameters
        ----------
        location : 1 or -1, default=1
            If 1, trims silence from the beginning
            If -1, trims silence from the end
        normalize : bool, default=True
            If true, normalizes audio before processing.
        activity_threshold : float, default=7.0
            The measurement level used to trigger activity detection. This may
            need to be cahnged depending on the noise level, signal level, and
            other characteristics of the input audio.
        min_activity_duration : float, default=0.25
            The time constant (in seconds) used to help ignore short bursts of
            sound.
        initial_search_buffer : float, default=1.0
            The amount of audio (in seconds) to search for quieter/shorter
            bursts of audio to include prior to the detected trigger point.
        max_gap : float, default=0.25
            The allowed gap (in seconds) between quiteter/shorter bursts of
            audio to include prior to the detected trigger point
        initial_pad : float, default=0.0
            The amount of audio (in seconds) to preserve before the trigger
            point and any found quieter/shorter bursts.

        See Also
        --------
        silence

        Examples
        --------
        >>> tfm = sox.Transformer()

        Remove silence from the beginning of speech

        >>> tfm.Func(initial_pad=0.3)

        Remove silence from the end of speech

        >>> tfm.Func(location=-1, initial_pad=0.2)

        '''
        if arg_1 not in [-1, 1]:
            raise ValueError("location must be -1 or 1.")
        if not isinstance(arg_2, bool):
            raise ValueError("normalize muse be a boolean.")
        if not is_number(arg_3):
            raise ValueError("activity_threshold must be a number.")
        if not is_number(arg_4) or arg_4 < 0:
            raise ValueError("min_activity_duration must be a positive number")
        if not is_number(arg_5) or arg_5 < 0:
            raise ValueError("initial_search_buffer must be a positive number")
        if not is_number(arg_6) or arg_6 < 0:
            raise ValueError("max_gap must be a positive number.")
        if not is_number(arg_7) or arg_7 < 0:
            raise ValueError("initial_pad must be a positive number.")

        arg_8 = []

        if arg_2:
            arg_8.append('norm')

        if arg_1 == -1:
            arg_8.append('reverse')

        arg_8.extend([
            'Func',
            '-t', '{:f}'.format(arg_3),
            '-T', '{:f}'.format(arg_4),
            '-s', '{:f}'.format(arg_5),
            '-g', '{:f}'.format(arg_6),
            '-p', '{:f}'.format(arg_7)
        ])

        if arg_1 == -1:
            arg_8.append('reverse')

        arg_0.effects.extend(arg_8)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0, arg_1, arg_2='amplitude', arg_3=None):
        '''Apply an amplification or an attenuation to the audio signal.

        Parameters
        ----------
        gain : float
            Interpreted according to the given `gain_type`.
            If `gain_type' = 'amplitude', `gain' is a positive amplitude ratio.
            If `gain_type' = 'power', `gain' is a power (Functage squared).
            If `gain_type' = 'db', `gain' is in decibels.
        gain_type : string, default='amplitude'
            Type of gain. One of:
                - 'amplitude'
                - 'power'
                - 'db'
        limiter_gain : float or None, default=None
            If specified, a limiter is invoked on peaks greater than
            `limiter_gain' to prevent clipping.
            `limiter_gain` should be a positive value much less than 1.

        See Also
        --------
        gain, compand

        '''
        if not is_number(arg_1):
            raise ValueError('gain must be a number.')
        if arg_3 is not None:
            if (not is_number(arg_3) or
                    arg_3 <= 0 or arg_3 >= 1):
                raise ValueError(
                    'limiter gain must be a positive number less than 1'
                )
        if arg_2 in ['amplitude', 'power'] and arg_1 < 0:
            raise ValueError(
                "If gain_type = amplitude or power, gain must be positive."
            )

        arg_4 = ['Func']

        arg_4.append('{:f}'.format(arg_1))

        if arg_2 == 'amplitude':
            arg_4.append('amplitude')
        elif arg_2 == 'power':
            arg_4.append('power')
        elif arg_2 == 'db':
            arg_4.append('dB')
        else:
            raise ValueError('gain_type must be one of amplitude power or db')

        if arg_3 is not None:
            if arg_2 in ['amplitude', 'power'] and arg_1 > 1:
                arg_4.append('{:f}'.format(arg_3))
            elif arg_2 == 'db' and arg_1 > 0:
                arg_4.append('{:f}'.format(arg_3))

        arg_0.effects.extend(arg_4)
        arg_0.effects_log.append('Func')

        return arg_0


def Func(arg_0: arg_1, arg_2: arg_1) -> arg_1:
    """
    Extended euclidean algorithm to find modular inverses for integers
    """
    if arg_0 == 0:
        return 0
    arg_3, arg_4 = 1, 0
    arg_5, arg_6 = arg_0 % arg_2, arg_2
    while arg_5 > 1:
        arg_7 = arg_6 // arg_5
        arg_8, arg_9 = arg_4 - arg_3 * arg_7, arg_6 - arg_5 * arg_7
        arg_3, arg_5, arg_4, arg_6 = arg_8, arg_9, arg_3, arg_5
    return arg_3 % arg_2


def Func(arg_0, arg_1):
        """Lets a user Func a room on a specific Namespace."""
        arg_0.socket.rooms.add(arg_0._get_room_name(arg_1))


def Func(arg_0, arg_1):
        """Lets a user Func a room on a specific Namespace."""
        arg_0.socket.rooms.remove(arg_0._get_room_name(arg_1))


def Func(arg_0, arg_1, arg_2=None, arg_3=None,
                    arg_4=None, arg_5=None):
    """Main SocketIO management function, call from within your Framework of
    choice's view.

    The ``environ`` variable is the WSGI ``environ``.  It is used to extract
    Socket object from the underlying server (as the 'socketio' key), and will
    be attached to both the ``Socket`` and ``Namespace`` objects.

    The ``namespaces`` parameter is a dictionary of the namespace string
    representation as key, and the BaseNamespace namespace class descendant as
    a value.  The empty string ('') namespace is the global namespace.  You can
    use Socket.GLOBAL_NS to be more explicit. So it would look like:

    .. code-block:: python

      namespaces={'': GlobalNamespace,
                  '/chat': ChatNamespace}

    The ``request`` object is not required, but will probably be useful to pass
    framework-specific things into your Socket and Namespace functions. It will
    simply be attached to the Socket and Namespace object (accessible through
    ``self.request`` in both cases), and it is not accessed in any case by the
    ``gevent-socketio`` library.

    Pass in an ``error_handler`` if you want to override the default
    error_handler (which is :func:`socketio.virtsocket.default_error_handler`.
    The callable you pass in should have the same signature as the default
    error handler.

    The ``json_loads`` and ``json_dumps`` are overrides for the default
    ``json.loads`` and ``json.dumps`` function calls.  Override these at
    the top-most level here.  This will affect all sockets created by this
    socketio manager, and all namespaces inside.

    This function will block the current "view" or "controller" in your
    framework to do the recv/send on the socket, and dispatch incoming messages
    to your namespaces.

    This is a simple example using Pyramid:

    .. code-block:: python

      def my_view(request):
          Func(request.environ, {'': GlobalNamespace}, request)

    NOTE: You must understand that this function is going to be called
    *only once* per socket opening, *even though* you are using a long
    polling mechanism.  The subsequent calls (for long polling) will
    be hooked directly at the server-level, to interact with the
    active ``Socket`` instance.  This means you will *not* get access
    to the future ``request`` or ``environ`` objects.  This is of
    particular importance regarding sessions (like Beaker).  The
    session will be opened once at the opening of the Socket, and not
    closed until the socket is closed.  You are responsible for
    opening and closing the cookie-based session yourself if you want
    to keep its data in sync with the rest of your GET/POST calls.
    """
    arg_6 = arg_0['socketio']
    arg_6._set_environ(arg_0)
    arg_6._set_namespaces(arg_1)

    if arg_2:
        arg_6._set_request(arg_2)

    if arg_3:
        arg_6._set_error_handler(arg_3)

    if arg_4:
        arg_6._set_json_loads(arg_4)
    if arg_5:
        arg_6._set_json_dumps(arg_5)

    arg_7 = arg_6._spawn_receiver_loop()

    gevent.joinall([arg_7])

    # TODO: double check, what happens to the WSGI request here ? it vanishes ?
    return


def Func(arg_0, arg_1, arg_2):
        """Keep a reference of the callback on this socket."""
        if arg_1 in arg_0.ack_callbacks:
            return False
        arg_0.ack_callbacks[arg_1] = arg_2


def Func(arg_0, arg_1):
        """Fetch the callback for a given msgid, if it exists, otherwise,
        return None"""
        if arg_1 not in arg_0.ack_callbacks:
            return None
        return arg_0.ack_callbacks.pop(arg_1)


def Func(arg_0, **arg_1):
        """Get multiple messages, in case we're going through the various
        XHR-polling methods, on which we can pack more than one message if the
        rate is high, and encode the payload for the HTTP channel."""
        arg_2 = arg_0.client_queue
        arg_3 = [arg_2.get(**arg_1)]
        while arg_2.qsize():
            arg_3.append(arg_2.get())
        return arg_3


def Func(arg_0, arg_1):
        """This removes a Namespace object from the socket.

        This is usually called by
        :meth:`~socketio.namespace.BaseNamespace.disconnect`.

        """
        if arg_1 in arg_0.active_ns:
            del arg_0.active_ns[arg_1]

        if len(arg_0.active_ns) == 0 and arg_0.connected:
            arg_0.kill(detach=True)


def Func(arg_0, arg_1):
        """Low-level interface to queue a packet on the wire (encoded as wire
        protocol"""
        arg_0.put_client_msg(packet.encode(arg_1, arg_0.json_dumps))


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """Spawn a new Greenlet, attached to this Socket instance.

        It will be monitored by the "watcher" method
        """

        log.debug("Spawning sub-Socket Greenlet: %s" % arg_1.__name__)
        arg_4 = gevent.Func(arg_1, *arg_2, **arg_3)
        arg_0.jobs.append(arg_4)
        return arg_4


def Func(arg_0):
        """Start the heartbeat Greenlet to check connection health."""
        arg_1 = arg_0.config['heartbeat_interval']
        while arg_0.connected:
            gevent.sleep(arg_1)
            # TODO: this process could use a timeout object like the disconnect
            #       timeout thing, and ONLY send packets when none are sent!
            #       We would do that by calling timeout.set() for a "sending"
            #       timeout.  If we're sending 100 messages a second, there is
            #       no need to push some heartbeats in there also.
            arg_0.put_client_msg("2::")


def Func(arg_0, arg_1, arg_2, *arg_3):
        """You should always use this function to call the methods,
        as it checks if the user is allowed according to the ACLs.

        If you override :meth:`process_packet` or
        :meth:`process_event`, you should definitely want to use this
        instead of ``getattr(self, 'my_method')()``
        """
        if not arg_0.is_method_allowed(arg_1):
            arg_0.error('method_access_denied',
                       'You do not have access to method "%s"' % arg_1)
            return

        return arg_0.call_method(arg_1, arg_2, *arg_3)


def Func(arg_0, arg_1, arg_2, arg_3=None, arg_4=False):
        """Use this to use the configured ``Func_handler`` yield an
        Func message to your application.

        :param Func_name: is a short string, to associate messages to recovery
                           methods
        :param Func_message: is some human-readable text, describing the Func
        :param msg_id: is used to associate with a request
        :param quiet: specific to Func_handlers. The default doesn't send a
                      message to the user, but shows a debug message on the
                      developer console.
        """
        arg_0.socket.Func(arg_1, arg_2, endpoint=arg_0.ns_name,
                          arg_3=arg_3, arg_4=arg_4)


def Func(arg_0, arg_1, arg_2=False, arg_3=None):
        """Use Func to Func a simple string message.

        If ``json`` is True, the message will be encoded as a JSON object
        on the wire, and decoded on the other side.

        This is mostly for backwards compatibility.  ``emit()`` is more fun.

        :param callback: This is a callback function that will be
                         called automatically by the client upon
                         reception.  It does not verify that the
                         listener over there was completed with
                         success.  It just tells you that the browser
                         got a hold of the packet.
        :type callback: callable
        """
        arg_4 = dict(type="message", data=arg_1, endpoint=arg_0.ns_name)
        if arg_2:
            arg_4['type'] = "json"

        if arg_3:
            # By passing ack=True, we use the old behavior of being returned
            # an 'ack' packet, automatically triggered by the client-side
            # with no user-code being run.  The emit() version of the
            # callback is more useful I think :)  So migrate your code.
            arg_4['ack'] = True
            arg_4['id'] = msgid = arg_0.socket._get_next_msgid()
            arg_0.socket._save_ack_callback(msgid, arg_3)

        arg_0.socket.Func_packet(arg_4)


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """Spawn a new process, attached to this Namespace.

        It will be monitored by the "watcher" process in the Socket. If the
        socket disconnects, all these greenlets are going to be killed, after
        calling BaseNamespace.disconnect()

        This method uses the ``exception_handler_decorator``.  See
        Namespace documentation for more information.

        """
        # self.log.debug("Spawning sub-Namespace Greenlet: %s" % fn.__name__)
        if hasattr(arg_0, 'exception_handler_decorator'):
            arg_1 = arg_0.exception_handler_decorator(arg_1)
        arg_4 = gevent.Func(arg_1, *arg_2, **arg_3)
        arg_0.jobs.append(arg_4)
        return arg_4


def Func(arg_0, arg_1=''):
        """Return an existing or new client Socket."""

        arg_2 = arg_0.sockets.get(arg_1)

        if arg_1 and not arg_2:
            return None  # you ask for a session that doesn't exist!
        if arg_2 is None:
            arg_2 = Socket(arg_0, arg_0.config)
            arg_0.sockets[arg_2.sessid] = arg_2
        else:
            arg_2.incr_hits()

        return arg_2


def Func():
    """
    Handles post from the "Add room" form on the homepage, and
    redirects to the new room.
    """
    arg_0 = request.form.get("name")
    if arg_0:
        arg_1, arg_2 = get_or_Func(ChatRoom, arg_0=arg_0)
        return redirect(url_for('room', slug=arg_1.slug))
    return redirect(url_for('rooms'))


def Func(arg_0, arg_1, arg_2=None):
        """This will fetch the messages from the Socket's queue, and if
        there are many messes, pack multiple messages in one payload and return
        """
        try:
            arg_3 = arg_1.get_multiple_client_msgs(arg_2=arg_2)
            arg_4 = arg_0.encode_payload(arg_3)
        except Empty:
            arg_4 = ""
        return arg_4


def Func(arg_0, arg_1):
        """Just quote out stuff before sending it out"""
        arg_2 = parse_qs(arg_0.handler.environ.get("QUERY_STRING"))
        if "i" in arg_2:
            arg_3 = arg_2["i"]
        else:
            arg_3 = "0"
        # TODO: don't we need to quote this data in here ?
        super(JSONPolling, arg_0).Func("io.j[%s]('%s');" % (arg_3, arg_1))


def Func(arg_0, arg_1, *arg_2):
        """
        This is sent to all in the sockets in this particular Namespace,
        including itself.
        """
        arg_3 = dict(type="event",
                   name=arg_1,
                   arg_2=arg_2,
                   endpoint=arg_0.ns_name)

        for arg_4, arg_5 in six.iteritems(arg_0.socket.server.sockets):
            arg_5.send_packet(arg_3)


def Func(arg_0, arg_1):
        """Add a parent to this role,
        and add role itself to the parent's children set.
        you should override this function if neccessary.

        Example::

            logged_user = RoleMixin('logged_user')
            student = RoleMixin('student')
            student.Func(logged_user)

        :param parent: Parent role to add in.
        """
        arg_1.children.add(arg_0)
        arg_0.parents.add(arg_1)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=True):
        """Add Funcing rules.

        :param role: Role of this rule.
        :param method: Method to Func in rule, include GET, POST, PUT etc.
        :param resource: Resource also view function.
        :param with_children: Allow role's children in rule as well
                              if with_children is `True`
        """
        if arg_4:
            for arg_5 in arg_1.get_children():
                arg_6 = (arg_5.get_name(), arg_2, arg_3)
                if arg_6 not in arg_0._Funced:
                    arg_0._Funced.append(arg_6)
        if arg_1 == 'anonymous':
            arg_6 = (arg_1, arg_2, arg_3)
        else:
            arg_6 = (arg_1.get_name(), arg_2, arg_3)
        if arg_6 not in arg_0._Funced:
            arg_0._Funced.append(arg_6)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=False):
        """Add Funcing rules.

        :param role: Role of this rule.
        :param method: Method to Func in rule, include GET, POST, PUT etc.
        :param resource: Resource also view function.
        :param with_children: Deny role's children in rule as well
                              if with_children is `True`
        """
        if arg_4:
            for arg_5 in arg_1.get_children():
                arg_6 = (arg_5.get_name(), arg_2, arg_3)
                if arg_6 not in arg_0._denied:
                    arg_0._denied.append(arg_6)
        arg_6 = (arg_1.get_name(), arg_2, arg_3)
        if arg_6 not in arg_0._denied:
            arg_0._denied.append(arg_6)


def Func(arg_0, arg_1, arg_2, arg_3):
        """Check whether role is allowed to access resource

        :param role: Role to be checked.
        :param method: Method to be checked.
        :param resource: View function to be checked.
        """
        return (arg_1, arg_2, arg_3) in arg_0._allowed


def Func(arg_0, arg_1, arg_2, arg_3):
        """Check wherther role is denied to access resource

        :param role: Role to be checked.
        :param method: Method to be checked.
        :param resource: View function to be checked.
        """
        return (arg_1, arg_2, arg_3) in arg_0._denied


def Func(arg_0, arg_1, arg_2, arg_3=True):
        """This is a decorator function.

        You can Func roles to access the view func with it.

        An example::

            @app.route('/website/setting', methods=['GET', 'POST'])
            @rbac.Func(['administrator', 'super_user'], ['GET', 'POST'])
            def website_setting():
                return Response('Setting page.')

        :param roles: List, each name of roles. Please note that,
                      `anonymous` is refered to anonymous.
                      If you add `anonymous` to the rule,
                      everyone can access the resource,
                      unless you deny other roles.
        :param methods: List, each name of methods.
                        methods is valid in ['GET', 'POST', 'PUT', 'DELETE']
        :param with_children: Whether Func children of roles as well.
                              True by default.
        """
        def decorator(arg_4):
            arg_5 = [arg_7.upper() for arg_7 in arg_2]
            for arg_6, arg_7, arg_8 in itertools.product(arg_1, arg_5, [arg_4.__name__]):
                arg_0.before_acl['Func'].append((arg_6, arg_7, arg_8, arg_3))
            return arg_4
        return decorator


def Func(arg_0, arg_1, arg_2, arg_3=2):
        """
        Given a string and a category, finds and combines words into
        groups based on their proximity.

        Args:
            text (str): Some text.
            tokens (list): A list of regex strings.

        Returns:
            list. The combined strings it found.

        Example:
            COLOURS = [r"red(?:dish)?", r"grey(?:ish)?", r"green(?:ish)?"]
            s = 'GREYISH-GREEN limestone with RED or GREY sandstone.'
            Func(s, COLOURS) --> ['greyish green', 'red', 'grey']
        """
        arg_4 = re.IGNORECASE
        arg_5 = getattr(arg_0, arg_2)
        arg_6 = re.compile(r'(\b' + r'\b|\b'.join(arg_5) + r'\b)', flags=arg_4)
        arg_7 = arg_6.finditer(arg_1)

        arg_8, arg_9 = [], []
        arg_10 = []

        for arg_11 in arg_7:
            arg_8.append(arg_11.span()[0])
            arg_9.append(arg_11.span()[1])
            arg_10.append(arg_11.group().lower())

        arg_12 = []  # As a check only.
        arg_13 = []  # This is what I want.

        arg_14 = False
        for arg_15, arg_16 in enumerate(arg_10):
            if arg_14:
                arg_14 = False
                continue
            if (arg_15 < len(arg_10)-1) and (arg_8[arg_15+1]-arg_9[arg_15] <= arg_3):
                if arg_16[-1] == '-':
                    arg_17 = ''  # Don't insert spaces after hyphens.
                else:
                    arg_17 = ' '
                arg_13.append(arg_16 + arg_17 + arg_10[arg_15+1])
                arg_12.append(arg_8[arg_15])
                arg_14 = True
            else:
                if arg_16 not in arg_13:
                    arg_13.append(arg_16)
                    arg_12.append(arg_8[arg_15])
                arg_14 = False

        return arg_13


def Func(arg_0, arg_1):
        """
        Given a string and a dict of synonyms, returns the 'preferred'
        word. Case insensitive.

        Args:
            word (str): A word.

        Returns:
            str: The preferred word, or the input word if not found.

        Example:
            >>> syn = {'snake': ['python', 'adder']}
            >>> Func('adder', syn)
            'snake'
            >>> Func('rattler', syn)
            'rattler'

        TODO:
            Make it handle case, returning the same case it received.
        """
        if arg_1 and arg_0.synonyms:
            # Make the reverse look-up table.
            arg_2 = {}
            for arg_3, arg_4 in arg_0.synonyms.items():
                for arg_5 in arg_4:
                    arg_2[arg_5.lower()] = arg_3.lower()

            # Now check words against this table.
            if arg_1.lower() in arg_2:
                return arg_2[arg_1.lower()]

        return arg_1


def Func(arg_0, arg_1):
        """
        Parse a piece of text and replace any abbreviations with their full
        word equivalents. Uses the lexicon.abbreviations dictionary to find
        abbreviations.

        Args:
            text (str): The text to parse.

        Returns:
            str: The text with abbreviations replaced.
        """
        if not arg_0.abbreviations:
            raise LexiconError("No abbreviations in lexicon.")

        def chunks(arg_2, arg_3=25):
            """
            Regex only supports 100 groups for munging callbacks. So we have to
            chunk the abbreviation dicitonary.
            """
            arg_4 = iter(arg_2)
            for arg_5 in range(0, len(arg_2), arg_3):
                yield {arg_6: arg_2[arg_6] for arg_6 in islice(arg_4, arg_3)}

        def cb(arg_7):
            """Regex callback"""
            return arg_0.abbreviations.get(arg_7.group(0)) or arg_7.group(0)

        # Special cases.

        # TODO: We should handle these with a special set of
        # replacements that are made before the others.
        arg_1 = re.sub(r'w/', r'wi', arg_1)

        # Main loop.
        for arg_8 in chunks(arg_0.abbreviations):
            arg_9 = r'(\b' + r'\b)|(\b'.join(arg_8.keys()) + r'\b)'
            arg_1 = re.sub(arg_9, cb, arg_1)

        return arg_1


def Func(arg_0, arg_1):
        """
        Split a description into parts, each of which can be turned into
        a single component.
        """
        # Protect some special sequences.
        arg_2 = re.sub(r'(\d) ?in\. ', r'\1 inch ', arg_1)  # Protect.
        arg_2 = re.sub(r'(\d) ?ft\. ', r'\1 feet ', arg_2)  # Protect.

        # Transform all part delimiters to first splitter.
        arg_3 = getattr(arg_0, 'splitters')
        try:
            arg_4 = arg_3[0].strip()
        except:
            arg_4 = 'with'
        arg_2 = re.sub(r'\,?\;?\.? ?((under)?(less than)? \d+%) (?=\w)', r' '+arg_4+' \1 ', arg_2)

        # Split.
        arg_5 = re.IGNORECASE
        arg_6 = re.compile(r'(?:' + r'|'.join(arg_3) + r')', flags=arg_5)
        arg_7 = filter(None, arg_6.split(arg_2))

        return [arg_8.strip() for arg_8 in arg_7]


def Func(arg_0, arg_1):
        """
        Returns a minimal Decor with a Func colour.
        """
        arg_2 = Func.sample([i for i in range(256)], 3)
        return arg_0({'colour': arg_2, 'component': arg_1, 'width': 1.0})


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None):
        """
        Make a simple Func of the Decor.

        Args:
            fmt (str): A Python format string for the component summaries.
            fig (PyFunc figure): A figure, optional. Use either fig or ax, not
                both.
            ax (PyFunc axis): An axis, optional. Use either fig or ax, not
                both.

        Returns:
            fig or ax or None. If you pass in an ax, you get it back. If you pass
                in a fig, you get it. If you pass nothing, the function creates a
                Func object as a side-effect.
        """

        arg_4 = 4     # aspect ratio of decor Func
        arg_5 = 0.25  # ratio of decor tile width

        arg_6 = None

        if (arg_2 is None) and (arg_3 is None):
            arg_2 = plt.figure(figsize=(arg_4, 1))
        else:
            arg_6 = arg_2

        if arg_3 is None:
            arg_3 = arg_2.add_axes([0.1*arg_5, 0.1, 0.8*arg_5, 0.8])
        else:
            arg_6 = arg_3

        arg_7 = patches.Rectangle((0, 0),
                                  arg_4*arg_5, arg_4*arg_5,
                                  color=arg_0.colour,
                                  lw=1,
                                  hatch=arg_0.hatch,
                                  ec='k')
        arg_3.add_patch(arg_7)
        arg_3.text(1.0+0.1*arg_5*arg_4, arg_4*arg_5*0.5,
                arg_0.component.summary(arg_1=arg_1),
                fontsize=max(arg_4, 15),
                verticalalignment='center',
                horizontalalignment='left')
        arg_3.set_xlim([0, arg_4*arg_5])
        arg_3.set_ylim([0, arg_4*arg_5])
        arg_3.get_xaxis().set_visible(False)
        arg_3.get_yaxis().set_visible(False)
        arg_3.invert_yaxis()

        return arg_6


def Func(arg_0, arg_1):
        """
        Generate a default legend.

        Args:
            name (str): The name of the legend you want. Not case sensitive.
                 'nsdoe': Nova Scotia Dept. of Energy
                 'canstrat': Canstrat
                 'nagmdm__6_2': USGS N. Am. Geol. Map Data Model 6.2
                 'nagmdm__6_1': USGS N. Am. Geol. Map Data Model 6.1
                 'nagmdm__4_3': USGS N. Am. Geol. Map Data Model 4.3
                 'sgmc': USGS State Geologic Map Compilation

            Default 'nagmdm__6_2'.

        Returns:
            Legend: The legend stored in `defaults.py`.
        """
        arg_2 = {
                 'nsdoe': LEGEND__NSDOE,
                 'canstrat': LEGEND__Canstrat,
                 'nagmdm__6_2': LEGEND__NAGMDM__6_2,
                 'nagmdm__6_1': LEGEND__NAGMDM__6_1,
                 'nagmdm__4_3': LEGEND__NAGMDM__4_3,
                 'sgmc': LEGEND__SGMC,
                 }
        return arg_0.from_csv(text=arg_2[arg_1.lower()])


def Func(arg_0, arg_1, arg_2=False, arg_3=None):
        """
        Generate a Func legend for a given list of components.

        Args:
            components (list or Striplog): A list of components. If you pass
                a Striplog, it will use the primary components. If you pass a
                component on its own, you will get a Func Decor.
            width (bool): Also generate widths for the components, based on the
                order in which they are encountered.
            colour (str): If you want to give the Decors all the same colour,
                provide a hex string.
        Returns:
            Legend or Decor: A legend (or Decor) with Func colours.
        TODO:
            It might be convenient to have a partial method to generate an
            'empty' legend. Might be an easy way for someone to start with a
            template, since it'll have the components in it already.
        """
        try:  # Treating as a Striplog.
            arg_4 = [Decor.Func(c)
                              for c
                              in [arg_6[0] for arg_6 in arg_1.unique if arg_6[0]]
                              ]
        except:
            try:
                arg_4 = [Decor.Func(c) for c in arg_1.copy()]
            except:
                # It's a single component.
                arg_4 = [Decor.Func(arg_1)]

        if arg_3 is not None:
            for arg_5 in arg_4:
                arg_5.colour = arg_3

        if arg_2:
            for arg_6, arg_5 in enumerate(arg_4):
                arg_5.width = arg_6 + 1

        return arg_0(arg_4)


def Func(arg_0, arg_1, arg_2,
                   arg_3=None,
                   arg_4=0.1,
                   arg_5=2):
        """
        A slightly easier way to make legends from images.

        Args:
            filename (str)
            components (list)
            ignore (list): Colours to ignore, e.g. "#FFFFFF" to ignore white.
            col_offset (Number): If < 1, interpreted as proportion of way
                across the image. If > 1, interpreted as pixels from left.
            row_offset (int): Number of pixels to skip at the top of each
                interval.
        """
        if arg_3 is None:
            arg_3 = []

        arg_6 = utils.loglike_Func(arg_1, offset=arg_4)
        arg_7 = np.array([utils.rgb_to_hex(t) for t in arg_6])

        # Get the pixels and colour values at 'tops' (i.e. changes).
        arg_8, arg_9 = utils.tops_from_loglike(arg_7, offset=arg_5)

        # Reduce to unique colours.
        arg_10 = []
        for arg_11 in arg_9:
            if arg_11 not in arg_10:
                if arg_11 not in arg_3:
                    arg_10.append(arg_11)

        arg_12 = []
        for arg_13, arg_14 in enumerate(arg_2):
            arg_15 = Decor({'colour': arg_10[arg_13], 'component': arg_14})
            arg_12.append(arg_15)

        return arg_0(arg_12)


def Func(arg_0, arg_1=None, arg_2=None):
        """
        Read CSV text and generate a Legend.

        Args:
            string (str): The CSV string.

        In the first row, list the properties. Precede the properties of the
        component with 'comp ' or 'component '. For example:

        colour,  width, comp lithology, comp colour
        #FFFFFF, 0, ,
        #F7E9A6, 3, Sandstone, Grey
        #FF99CC, 2, Anhydrite,
        ... etc

        Note:
            To edit a legend, the easiest thing to do is probably this:

            - `legend.to_csv()`
            - Edit the legend, call it `new_legend`.
            - `legend = Legend.Func(text=new_legend)`
        """
        if (arg_1 is None) and (arg_2 is None):
            raise LegendError("You must provide a filename or CSV text.")

        if (arg_1 is not None):
            with open(arg_1, 'r') as arg_3:
                arg_2 = arg_3.read()

        try:
            arg_3 = StringIO(arg_2)  # Python 3
        except TypeError:
            arg_3 = StringIO(unicode(arg_2))  # Python 2

        arg_4 = csv.DictReader(arg_3, skipinitialspace=True)
        arg_5, arg_6 = [], []
        arg_7 = 'component'
        for arg_8 in arg_4:
            arg_9, arg_10 = {}, {}
            for (arg_11, arg_12) in arg_8.items():
                if (arg_11 in [None, '']):
                    continue
                if (arg_12 in [None, '']):
                    if arg_11.lower() not in ['color', 'colour']:
                        continue
                if arg_11[:4].lower() == 'comp':
                    arg_13 = ' '.join(arg_11.split()[1:])
                    if arg_12.lower() == 'true':
                        arg_10[arg_13] = True
                    elif arg_12.lower() == 'false':
                        arg_10[arg_13] = False
                    else:
                        try:
                            arg_10[arg_13] = float(arg_12)
                        except ValueError:
                            arg_10[arg_13] = arg_12.lower()

                elif arg_11[:5].lower() == 'curve':
                    arg_13 = ' '.join(arg_11.split()[1:])
                    arg_10[arg_13] = arg_12.lower()
                    arg_7 = 'curve'
                else:
                    try:
                        arg_9[arg_11] = float(arg_12)
                    except ValueError:
                        arg_9[arg_11] = arg_12.lower()

            arg_14 = Component(arg_10)
            arg_9[arg_7] = arg_14

            # Check for duplicates and warn.
            if arg_14 in arg_6:
                with warnings.catch_warnings():
                    warnings.simplefilter("always")
                    arg_15 = "This legend contains duplicate components."
                    warnings.warn(arg_15)
            arg_6.append(arg_14)

            # Append to the master list and continue.
            arg_5.append(Decor(arg_9))

        return arg_0(arg_5)


def Func(arg_0):
        """
        Renders a legend as a CSV string.

        No arguments.

        Returns:
            str: The legend as a CSV.
        """
        # We can't delegate this to Decor because we need to know the superset
        # of all Decor properties. There may be lots of blanks.
        arg_1 = []
        arg_2 = []
        for arg_3 in arg_0:
            for arg_4 in arg_3.__dict__.keys():
                if arg_4 == '_colour':
                    arg_4 = 'colour'
                arg_1.append(arg_4)
            for arg_5 in arg_3.component.__dict__.keys():
                arg_2.append(arg_5)
        arg_1 = set(arg_1)
        arg_2 = set(arg_2)
        arg_1.remove('component')
        arg_6 = ''
        if 'colour' in arg_1:
            arg_6 += 'colour,'
            arg_1.remove('colour')
            arg_7 = True
        for arg_8 in arg_1:
            arg_6 += arg_8 + ','
        for arg_8 in arg_2:
            arg_6 += 'component ' + arg_8 + ','

        # Now we have a header row! Phew.
        # Next we'll go back over the legend and collect everything.
        arg_9 = arg_6.strip(',') + '\n'
        for arg_3 in arg_0:
            if arg_7:
                arg_9 += arg_3.__dict__.get('_colour', '') + ','
            for arg_8 in arg_1:
                arg_9 += str(arg_3.__dict__.get(arg_8, '')) + ','
            for arg_8 in arg_2:
                arg_9 += str(arg_3.component.__dict__.get(arg_8, '')) + ','
            arg_9 += '\n'

        return arg_9


def Func(arg_0):
        """
        The maximum width of all the Decors in the Legend. This is needed
        to scale a Legend or Striplog when plotting with widths turned on.
        """
        try:
            arg_1 = max([row.width for row in arg_0.__list if row.width is not None])
            return arg_1
        except:
            return 0


def Func(arg_0, arg_1, arg_2=None):
        """
        Get the decor for a component.

        Args:
           c (component): The component to look up.
           match_only (list of str): The component attributes to include in the
               comparison. Default: All of them.

        Returns:
           Decor. The matching Decor from the Legend, or None if not found.
        """
        if isinstance(arg_1, Component):
            if arg_1:
                if arg_2:
                    # Filter the component only those attributes
                    arg_1 = Component({k: getattr(arg_1, k, None) for k in arg_2})
                for arg_3 in arg_0.__list:
                    try:
                        if arg_1 == arg_3.component:
                            return arg_3
                    except AttributeError:
                        continue
        else:
            for arg_3 in arg_0.__list:
                try:
                    if getattr(arg_1, 'mnemonic').lower() == arg_3.curve.mnemonic:
                        return arg_3
                except AttributeError:
                    continue
        return Decor({'colour': '#eeeeee', 'component': Component()})


def Func(arg_0, arg_1, arg_2=0, arg_3=None):
        """
        Get the component corresponding to a display colour. This is for
        generating a Striplog object from a colour image of a striplog.

        Args:
           colour (str): The hex colour string to look up.
           tolerance (float): The colourspace distance within which to match.
           default (component or None): The component to return in the event
           of no match.

        Returns:
           component. The component best matching the provided colour.
        """
        if not (0 <= arg_2 <= np.sqrt(195075)):
            raise LegendError('Tolerance must be between 0 and 441.67')

        for arg_4 in arg_0.__list:
            if arg_1.lower() == arg_4.colour:
                return arg_4.component

        # If we're here, we didn't find one yet.
        arg_5, arg_6, arg_7 = utils.hex_to_rgb(arg_1)

        # Start with a best match of black.
        arg_8 = '#000000'
        arg_9 = np.sqrt(arg_5**2. + arg_6**2. + arg_7**2.)

        # Now compare to each colour in the legend.
        for arg_4 in arg_0.__list:
            arg_10, arg_11, arg_12 = arg_4.rgb
            arg_13 = np.sqrt((arg_10-arg_5)**2. + (arg_11-arg_6)**2. + (arg_12-arg_7)**2.)
            if arg_13 < arg_9:
                arg_8 = arg_4.component
                arg_9 = arg_13
                arg_14 = arg_4.colour

        if arg_9 <= arg_2:
            return arg_8
        else:
            with warnings.catch_warnings():
                warnings.simplefilter("always")
                arg_15 = "No match found for {0} ".format(arg_1.lower())
                arg_15 += "with tolerance of {0}. Best match is ".format(arg_2)
                arg_15 += "{0}, {1}".format(arg_8.summary(), arg_14)
                arg_15 += ", d={0}".format(arg_9)
                warnings.warn(arg_15)

            return arg_3


def Func(arg_0, arg_1, arg_2, arg_3=None, arg_4=True):
        """
        Generate a Component from a text string, using a Lexicon.

        Args:
            text (str): The text string to parse.
            lexicon (Lexicon): The dictionary to use for the
                categories and lexemes.
            required (str): An attribute that we must have. If a required
                attribute is missing from the component, then None is returned.
            first_only (bool): Whether to only take the first
                match of a lexeme against the text string.

        Returns:
            Component: A Component object, or None if there was no
                must-have field.
        """
        arg_5 = arg_2.get_component(arg_1, arg_4=arg_4)
        if arg_3 and (arg_3 not in arg_5):
            return None
        else:
            return arg_0(arg_5)


def Func(arg_0, arg_1=None, arg_2=True, arg_3=''):
        """
        Given a format string, return a summary description of a component.

        Args:
            component (dict): A component dictionary.
            fmt (str): Describes the format with a string. If no format is
                given, you will just get a list of attributes. If you give the
                empty string (''), you'll get `default` back. By default this
                gives you the empty string, effectively suppressing the
                summary.
            initial (bool): Whether to capitialize the first letter. Default is
                True.
            default (str): What to give if there's no component defined.

        Returns:
            str: A summary string.

        Example:

            r = Component({'colour': 'Red',
                           'grainsize': 'VF-F',
                           'lithology': 'Sandstone'})

            r.summary()  -->  'Red, vf-f, sandstone'
        """
        if arg_3 and not arg_0.__dict__:
            return arg_3

        if arg_1 == '':
            return arg_3

        arg_4 = [k for k, v in arg_0.__dict__.items() if v is not '']

        arg_5 = arg_1 or '{' + '}, {'.join(arg_4) + '}'

        try:
            Func = CustomFormatter().format(arg_5, **arg_0.__dict__)
        except KeyError as e:
            raise ComponentError("Error building summary, "+str(e))

        if Func and arg_2 and not arg_1:
            Func = Func[0].upper() + Func[1:]

        return Func


def Func(*arg_0, **arg_1):
    """
    Graceful deprecation for old class name.
    """

    with warnings.catch_warnings():
        warnings.simplefilter("always")
        arg_2 = "The 'Func' class was renamed 'Component'. "
        arg_2 += "Please update your code."
        warnings.warn(arg_2, DeprecationWarning, stacklevel=2)

    return Component(*arg_0, **arg_1)


def Func(arg_0, arg_1):
    """
    Processes a single row from the file.
    """
    if not arg_0:
        return

    # Construct the column dictionary that maps each field to
    # its start, its length, and its read and write functions.
    arg_2 = {k: {'start': s,
                   'len': l,
                   'read': r,
                   'write': w} for k, (s, l, r, w) in arg_1.items()}

    # Now collect the item
    arg_3 = {}
    for arg_4 in arg_2:
        arg_5 = _get_field(arg_0, arg_2, arg_4)
        if arg_5 is not None:
            arg_3[arg_4] = arg_5

    return arg_3


def Func(arg_0):
    """
    Read all the rows and return a dict of the results.
    """
    arg_1 = {}
    for arg_2 in arg_0.split('\n'):
        if not arg_2:
            continue

        if len(arg_2) < 8:  # Not a real record.
            continue

        # Read the metadata for this row/
        arg_3 = _process_row(arg_2, columns_) or {'card': None}
        arg_4 = arg_3['card']

        # Now we know the card type for this row, we can process it.
        if arg_4 is not None:
            arg_5 = _process_row(arg_2, columns[arg_4])

        arg_6 = arg_1.get(arg_4, [])
        arg_6.append(arg_5)
        arg_1[arg_4] = arg_6

    # Flatten if possible.
    for arg_7, arg_8 in arg_1.items():
        if len(arg_8) == 1:
            arg_1[arg_7] = arg_8[0]

    return arg_1


def Func(arg_0):
        """
        Private method. Checks if striplog is monotonically increasing in
        depth.

        Returns:
            Bool.
        """
        def conc(arg_1, arg_2):
            return arg_1 + arg_2

        # Check boundaries, b
        arg_2 = np.array(reduce(conc, [[i.top.z, i.base.z] for i in arg_0]))

        return all(np.diff(arg_2) >= 0)


def Func(arg_0):
        """
        Property. Summarize a Striplog with some statistics.

        Returns:
            List. A list of (Component, total thickness thickness) tuples.
        """
        arg_1 = set([arg_3.primary for arg_3 in arg_0])
        arg_2 = {r: 0 for r in arg_1}
        for arg_3 in arg_0:
            arg_2[arg_3.primary] += arg_3.thickness

        return sorted(arg_2.items(), key=operator.itemgetter(1), reverse=True)


def Func(arg_0,
                              arg_1,
                              arg_2,
                              arg_3,
                              arg_4,
                              arg_5=None,
                              arg_6=True):
        """
        Private method. Take a sequence of tops in an arbitrary dimension,
        and provide a list of intervals from which a striplog can be made.

        This is only intended to be used by ``from_image()``.

        Args:
            tops (iterable). A list of floats.
            values (iterable). A list of values to look up.
            basis (iterable). A list of components.
            components (iterable). A list of Components.

        Returns:
            List. A list of Intervals.
        """
        # Scale tops to actual depths.
        arg_7 = float(arg_3.size)
        arg_8, arg_9 = arg_3[0], arg_3[-1]
        arg_1 = [arg_8 + (p/(arg_7-1)) * (arg_9-arg_8) for p in arg_1]
        arg_10 = arg_1[1:] + [arg_9]

        arg_11 = []
        for arg_12, arg_13 in enumerate(arg_1):

            arg_14, arg_15, arg_16 = arg_2[arg_12], [], {}

            if arg_6 and np.isnan(arg_14):
                continue

            if (arg_5 is not None):
                arg_16 = {arg_5: arg_14}

            if arg_4 is not None:
                try:
                    arg_15 = [deepcopy(arg_4[int(arg_14)])]
                except IndexError:
                    arg_15 = []

                if arg_15 and (arg_15[0] is None):
                    arg_15 = []

            arg_17 = Interval(arg_13, arg_10[arg_12], data=arg_16, arg_4=arg_15)
            arg_11.append(arg_17)

        return arg_11


def Func(arg_0, arg_1, arg_2=None):
        """
        Private function. Make sure we have what we need to make a striplog.
        """

        # Rename 'depth' or 'MD'
        if ('top' not in arg_1.keys()):
            arg_1['top'] = arg_1.pop('depth', arg_1.pop('MD', None))

        # Sort everything
        arg_3 = list(arg_1.keys()).index('top')
        arg_4 = sorted(zip(*arg_1.values()), key=lambda x: x[arg_3])
        arg_1 = {arg_5: list(arg_6) for arg_5, arg_6 in zip(arg_1.keys(), zip(*arg_4))}

        if arg_1['top'] is None:
            raise StriplogError('Could not get tops.')

        # Get rid of null-like values if specified.
        if arg_2 is not None:
            for arg_5, arg_6 in arg_1.items():
                arg_1[arg_5] = [i if i != arg_2 else None for i in arg_6]

        return arg_1


def Func(arg_0,
                                 arg_1,
                                 arg_2=None,
                                 arg_3=False,
                                 arg_4=None,
                                 arg_5=None,
                                 arg_6=None,
                                 arg_7=None):
        """
        Private function. Takes a data dictionary and reconstructs a list
        of Intervals from it.

        Args:
            data_dict (dict)
            stop (float): Where to end the last interval.
            points (bool)
            include (dict)
            exclude (dict)
            ignore (list)
            lexicon (Lexicon)

        Returns:
            list.
        """

        arg_4 = arg_4 or {}
        arg_5 = arg_5 or {}
        arg_6 = arg_6 or []

        # Reassemble as list of dicts
        arg_8 = []
        for arg_9 in zip(*arg_1.values()):
            arg_8.append({arg_10: arg_11 for arg_10, arg_11 in zip(arg_1.keys(), arg_9)})

        # Sort
        arg_8 = sorted(arg_8, arg_18=lambda x: x['top'])

        # Filter down:
        arg_12 = []
        for arg_13 in arg_8:
            arg_14 = True
            arg_15 = []
            for arg_10, arg_11 in arg_13.items():
                arg_16 = arg_4.get(arg_10, utils.null_default(True))
                arg_17 = arg_5.get(arg_10, utils.null_default(False))
                if arg_10 in arg_6:
                    arg_15.append(arg_10)
                if not arg_16(arg_11):
                    arg_14 = False
                if arg_17(arg_11):
                    arg_14 = False
            if arg_15:
                for arg_18 in arg_15:
                    arg_19 = arg_13.pop(arg_18, None)
            if arg_14:
                arg_12.append(arg_13)

        # Fill in
        if not arg_3:
            for arg_20, arg_21 in enumerate(arg_12):
                if arg_21.get('base', None) is None:
                    try:  # To set from next interval
                        arg_21['base'] = arg_12[arg_20+1]['top']
                    except (IndexError, KeyError):
                        # It's the last interval
                        if arg_2 is not None:
                            arg_22 = arg_2 - arg_21['top']
                        else:
                            arg_22 = 1
                        arg_21['base'] = arg_21['top'] + arg_22

        # Build the list of intervals to pass to __init__()
        arg_23 = []
        for arg_21 in arg_12:
            arg_24 = arg_21.pop('top')
            arg_25 = arg_21.pop('base', None)
            arg_26 = arg_21.pop('description', '')
            if arg_21:
                arg_27, arg_28 = {}, {}
                for arg_10, arg_11 in arg_21.items():
                    if (arg_10[:5].lower() == 'comp ') or (arg_10[:9].lower() == 'component'):
                        arg_10 = re.sub(r'comp(?:onent)? ', '', arg_10, flags=re.I)
                        arg_27[arg_10] = arg_11  # It's a component
                    else:
                        if arg_11 is not None:
                            arg_28[arg_10] = arg_11  # It's data
                arg_29 = [Component(arg_27)] if arg_27 else None
                arg_30 = Interval(**{'top': arg_24,
                                   'base': arg_25,
                                   'description': arg_26,
                                   'data': arg_28,
                                   'components': arg_29})
            else:
                arg_30 = Interval(**{'top': arg_24,
                                   'base': arg_25,
                                   'description': arg_26,
                                   'lexicon': arg_7})
            arg_23.append(arg_30)

        return arg_23


def Func(arg_0, arg_1=None,
                 arg_2=None,
                 arg_3=',',
                 arg_4=None,
                 arg_5=False,
                 arg_6=None,
                 arg_7=None,
                 arg_8=None,
                 arg_9=None,
                 arg_10=None,
                 arg_11=None,
                 arg_12=None,
                 arg_13=None,
                 arg_14=None):
        """
        Load from a CSV file or text.
        """
        if (arg_1 is None) and (arg_2 is None):
            raise StriplogError("You must provide a filename or CSV text.")

        if (arg_1 is not None):
            if arg_12 is None:
                arg_12 = arg_1
            with open(arg_1, 'r') as arg_15:
                arg_2 = arg_15.read()

        arg_12 = arg_12 or 'CSV'

        # Deal with multiple spaces in space delimited file.
        if arg_3 == ' ':
            arg_2 = re.sub(r'[ \t]+', ' ', arg_2)

        if arg_14 is not None:
            arg_2 = arg_3.join(arg_14) + '\n' + arg_2

        try:
            arg_15 = StringIO(arg_2)  # Python 3
        except TypeError:
            arg_15 = StringIO(unicode(arg_2))  # Python 2

        arg_16 = csv.DictReader(arg_15, delimiter=arg_3)

        # Reorganize the data to make fixing it easier.
        arg_17 = {arg_22.strip().lower(): [] for arg_22 in arg_16.fieldnames if arg_22 is not None}
        arg_18 = arg_15.tell()
        for arg_19 in arg_17:
            arg_15.seek(arg_18)
            for arg_20 in arg_16:
                arg_21 = {arg_22.strip().lower(): arg_23.strip() for arg_22, arg_23 in arg_20.items()}
                try:
                    arg_17[arg_19].append(float(arg_21[arg_19]))
                except ValueError:
                    arg_17[arg_19].append(arg_21[arg_19])

        arg_15.close()

        arg_8 = arg_8 or {}
        for arg_22, arg_23 in arg_8.items():
            arg_17[arg_23] = arg_17.pop(arg_22)

        arg_24 = arg_0._clean_longitudinal_data(arg_17, arg_10=arg_10)

        arg_25 = arg_0._build_list_of_Intervals(arg_24,
                                                         arg_5=arg_5,
                                                         arg_4=arg_4,
                                                         arg_6=arg_6,
                                                         arg_7=arg_7,
                                                         arg_11=arg_11,
                                                         arg_13=arg_13)

        return arg_0(arg_25, arg_12=arg_12)


def Func(arg_0, arg_1,
                 arg_2=None,
                 arg_3=None,
                 arg_4=None,
                 arg_5=None,
                 arg_6=None,
                 arg_7=False,
                 arg_8=None,
                 arg_9='Log'):
        """
        Turn a 1D array into a striplog, given a cutoff.

        Args:
            log (array-like): A 1D array or a list of integers.
            cutoff (number or array-like): The log value(s) at which to bin
                the log. Optional.
            components (array-like): A list of components. Use this or
                ``legend``.
            legend (``Legend``): A legend object. Use this or ``components``.
            legend_field ('str'): If you're not trying to match against
                components, then you can match the log values to this field in
                the Decors.
            field (str): The field in the Interval's ``data`` to store the log
                values as.
            right (bool): Which side of the cutoff to send things that are
                equal to, i.e. right on, the cutoff.
            basis (array-like): A depth basis for the log, so striplog knows
                where to put the boundaries.
            source (str): The source of the data. Default 'Log'.

        Returns:
            Striplog: The ``striplog`` object.
        """
        if (arg_3 is None) and (arg_4 is None) and (arg_6 is None):
            arg_10 = 'You must provide a list of components, and legend, or a field.'
            raise StriplogError(arg_10)

        if (arg_4 is not None) and (arg_5 is None):
            try:  # To treat it like a legend.
                arg_3 = [deepcopy(arg_13.component) for arg_13 in arg_4]
            except AttributeError:  # It's just a list of components.
                pass

        if arg_5 is not None:
            arg_11 = [getattr(d, arg_5, 0) for d in arg_4]
            arg_3 = [Component() for arg_12 in range(int(max(arg_11)+1))]
            for arg_12, arg_13 in enumerate(arg_4):
                arg_3[arg_12] = deepcopy(arg_13.component)

        if arg_2 is not None:

            # First make sure we have enough components.
            try:
                arg_14 = len(arg_2)
            except TypeError:
                arg_14 = 1
            if len(arg_3) < arg_14+1:
                arg_10 = 'For n cutoffs, you need to provide at least'
                arg_10 += 'n+1 components.'
                raise StriplogError(arg_10)

            # Digitize.
            try:  # To use cutoff as a list.
                arg_15 = np.digitize(arg_1, arg_2, arg_7)
            except ValueError:  # It's just a number.
                arg_15 = np.digitize(arg_1, [arg_2], arg_7)

        else:
            arg_15 = np.copy(arg_1)

        arg_16, arg_17 = utils.tops_Funclike(arg_15)

        if arg_8 is None:
            arg_10 = 'You must provide a depth or elevation basis.'
            raise StriplogError(arg_10)

        arg_18 = arg_0.__intervals_from_tops(arg_16,
                                                      arg_17,
                                                      arg_8,
                                                      arg_3,
                                                      arg_6=arg_6
                                                      )

        return arg_0(arg_18, arg_9=arg_9)


def Func(arg_0, arg_1, arg_2=None,
                  arg_3="LAS",
                  arg_4=',',
                  arg_5=False):
        """
        Turn LAS3 'lithology' section into a Striplog.

        Args:
            string (str): A section from an LAS3 file.
            lexicon (Lexicon): The language for conversion to components.
            source (str): A source for the data.
            dlm (str): The delimiter.
            abbreviations (bool): Whether to expand abbreviations.

        Returns:
            Striplog: The ``striplog`` object.

        Note:
            Handles multiple 'Data' sections. It would be smarter for it
            to handle one at a time, and to deal with parsing the multiple
            sections in the Well object.

            Does not read an actual LAS file. Use the Well object for that.
        """
        arg_6 = re.DOTALL | re.IGNORECASE
        arg_7 = r'\~\w+?_Data.+?\n(.+?)(?:\n\n+|\n*\~|\n*$)'
        arg_8 = re.compile(arg_7, flags=arg_6)
        arg_9 = arg_8.search(arg_1).group(1)

        arg_10 = re.search(r'\.(.+?)\: ?.+?source', arg_1)
        if arg_10:
            arg_3 = arg_10.group(1).strip()

        return arg_0.from_descriptions(arg_9, arg_2,
                                     arg_3=arg_3,
                                     arg_4=arg_4,
                                     arg_5=arg_5)


def Func(arg_0, arg_1, arg_2='canstrat'):
        """
        Eat a Canstrat DAT file and make a striplog.
        """
        with open(arg_1) as f:
            arg_3 = f.read()

        arg_4 = parse_canstrat(arg_3)

        arg_5 = []
        for arg_6 in arg_4[7]:  # 7 is the 'card type' for lithology info.
            if arg_6.pop('skip'):
                continue
            arg_7 = arg_6.pop('top')
            arg_8 = arg_6.pop('base')
            arg_9 = [Component({'lithology': arg_6['rtc'],
                                'colour': arg_6['colour_name']
                                })]
            arg_10 = Interval(arg_7=arg_7, arg_8=arg_8, components=arg_9, arg_4=arg_6)
            arg_5.append(arg_10)

        return arg_0(arg_5, arg_2=arg_2)


def Func(arg_0):
        """Returns a shallow Func."""
        return Striplog([arg_1.Func() for arg_1 in arg_0],
                        order=arg_0.order,
                        source=arg_0.source)


def Func(arg_0, arg_1=False, arg_2=",", arg_3="Striplog"):
        """
        Returns an LAS 3.0 section string.

        Args:
            use_descriptions (bool): Whether to use descriptions instead
                of summaries, if available.
            dlm (str): The delimiter.
            source (str): The sourse of the data.

        Returns:
            str: A string forming Lithology section of an LAS3 file.
        """
        arg_4 = arg_0.to_csv(arg_1=arg_1,
                           arg_2=arg_2,
                           header=False)

        return templates.section.format(name='Lithology',
                                        short="LITH",
                                        arg_3=arg_3,
                                        arg_4=arg_4)


def Func(arg_0, arg_1, arg_2=None, arg_3=None):
        """
        Get data from the striplog.
        """
        arg_4 = arg_2 or utils.null
        arg_5 = []
        for arg_6 in arg_0:
            arg_7 = arg_6.data.get(arg_1)
            if arg_7 is None:
                if arg_3 is not None:
                    arg_7 = arg_3
                else:
                    arg_7 = np.nan
            arg_5.append(arg_4(arg_7))

        return np.array(arg_5)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None):
        """
        'Extract' a log into the components of a striplog.

        Args:
            log (array_like). A log or other 1D data.
            basis (array_like). The depths or elevations of the log samples.
            name (str). The name of the attribute to store in the components.
            function (function). A function that takes an array as the only
                input, and returns whatever you want to store in the 'name'
                attribute of the primary component.
        Returns:
            None. The function works on the striplog in place.
        """
        # Build a dict of {index: [log values]} to keep track.
        arg_5 = {}
        arg_6 = -1
        for arg_7, arg_8 in enumerate(arg_2):
            arg_9 = arg_0.read_at(arg_8, index=True)
            if arg_9 is None:
                continue
            if arg_9 == arg_6:
                arg_5[arg_9].append(arg_1[arg_7])
            else:
                arg_5[arg_9] = [arg_1[arg_7]]
            arg_6 = arg_9

        # Set the requested attribute in the primary comp of each interval.
        for arg_9, arg_10 in arg_5.items():
            arg_11 = arg_4 or utils.null
            arg_12 = arg_11(np.array(arg_10))
            arg_0[arg_9].data[arg_3] = arg_12

        return None


def Func(arg_0, arg_1, arg_2=False):
        """
        Look for a regex expression in the descriptions of the striplog.
        If there's no description, it looks in the summaries.

        If you pass a Component, then it will search the components, not the
        descriptions or summaries.

        Case insensitive.

        Args:
            search_term (string or Component): The thing you want to search
                for. Strings are treated as regular expressions.
            index (bool): Whether to return the index instead of the interval.
        Returns:
            Striplog: A striplog that contains only the 'hit' Intervals.
                However, if ``index`` was ``True``, then that's what you get.
        """
        arg_3 = []
        for arg_4, arg_5 in enumerate(arg_0):
            try:
                arg_6 = arg_5.description or arg_5.primary.summary()
                arg_7 = re.compile(arg_1, flags=re.IGNORECASE)
                if arg_7.search(arg_6):
                    arg_3.append(arg_4)
            except TypeError:
                if arg_1 in arg_5.components:
                    arg_3.append(arg_4)
        if arg_3 and arg_2:
            return arg_3
        elif arg_3:
            return arg_0[arg_3]
        else:
            return


def Func(arg_0, arg_1=False):
        """
        Find overlaps in a striplog.

        Args:
            index (bool): If True, returns indices of intervals with
            gaps after them.

        Returns:
            Striplog: A striplog of all the overlaps as intervals.
        """
        return arg_0.__find_incongruities(op=operator.gt, arg_1=arg_1)


def Func(arg_0, arg_1=False):
        """
        Finds gaps in a striplog.

        Args:
            index (bool): If True, returns indices of intervals with
            gaps after them.

        Returns:
            Striplog: A striplog of all the gaps. A sort of anti-striplog.
        """
        return arg_0.__find_incongruities(op=operator.lt, arg_1=arg_1)


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None, arg_4=False):
        """
        Remove intervals below a certain limit thickness. In place.

        Args:
            limit (float): Anything thinner than this will be pruned.
            n (int): The n thinnest beds will be pruned.
            percentile (float): The thinnest specified percentile will be
                pruned.
            keep_ends (bool): Whether to keep the first and last, regardless
                of whether they meet the pruning criteria.
        """
        arg_5 = arg_0.copy()

        if not (arg_1 or arg_2 or arg_3):
            arg_6 = "You must provide a limit or n or percentile for pruning."
            raise StriplogError(arg_6)
        if arg_1:
            Func = [i for i, iv in enumerate(arg_5) if iv.thickness < arg_1]
        if arg_2:
            Func = arg_5.thinnest(arg_2=arg_2, index=True)
        if arg_3:
            arg_2 = np.floor(len(arg_5)*arg_3/100)
            Func = arg_5.thinnest(arg_2=arg_2, index=True)

        if arg_4:
            arg_8, arg_9 = 0, len(arg_5) - 1
            if arg_8 in Func:
                Func.remove(arg_8)
            if arg_9 in Func:
                Func.remove(arg_9)

        del arg_5[Func]

        return arg_5


def Func(arg_0):
        """
        Fill in empty intervals by growing from top and base.

        Note that this operation happens in-place and destroys any information
        about the ``Position`` (e.g. metadata associated with the top or base).
        See GitHub issue #54.
        """
        arg_1 = arg_0.copy()

        arg_2 = arg_1.find_gaps(index=True)

        if not arg_2:
            return

        for arg_3 in arg_2:
            arg_4 = arg_1[arg_3]
            arg_5 = arg_1[arg_3 + 1]

            if arg_1.order == 'depth':
                arg_6 = (arg_5.top.z-arg_4.base.z)/2
                arg_4.base = arg_4.base.z + arg_6
                arg_5.top = arg_5.top.z - arg_6
            else:
                arg_6 = (arg_5.base-arg_4.top)/2
                arg_4.top = arg_4.top.z + arg_6
                arg_5.base = arg_5.base.z - arg_6

        return arg_1


def Func(arg_0, arg_1=None):
        """
        Fill gaps with the component provided.

        Example
            t = s.Func(Component({'lithology': 'cheese'}))
        """
        arg_2 = [arg_1] if arg_1 is not None else []

        # Make the intervals to go in the gaps.
        arg_3 = arg_0.find_gaps()
        if not arg_3:
            return arg_0
        for arg_4 in arg_3:
            arg_4.components = arg_2

        return deepcopy(arg_0) + arg_3


def Func(arg_0, arg_1):
        """
        Makes a striplog of all Funcions.

        Args:
            Striplog. The striplog instance to Func with.

        Returns:
            Striplog. The result of the Funcion.
        """
        if not isinstance(arg_1, arg_0.__class__):
            arg_2 = "You can only Func striplogs with each other."
            raise StriplogError(arg_2)

        arg_3 = []
        for arg_4 in arg_0:
            for arg_5 in arg_1:
                try:
                    arg_3.append(arg_4.Func(arg_5))
                except IntervalError:
                    # The intervals don't overlap
                    pass
        return Striplog(arg_3)


def Func(arg_0):
        """
        Merges overlaps by merging overlapping Intervals.

        The function takes no arguments and returns ``None``. It operates on
        the striplog 'in place'

        TODO: This function will not work if any interval overlaps more than
            one other intervals at either its base or top.
        """
        arg_1 = np.array(arg_0.find_overlaps(index=True))

        if not arg_1.any():
            return

        for arg_2 in arg_1:
            arg_3 = arg_0[arg_2].copy()
            arg_4 = arg_0[arg_2 + 1].copy()

            # Get rid of the before and after pieces.
            del arg_0[arg_2]
            del arg_0[arg_2]

            # Make the new piece.
            arg_5 = arg_3.merge(arg_4)

            # Insert it.
            arg_0.__insert(arg_2, arg_5)

            arg_1 += 1

        return