Returns a generator of n-length chunks of an input iterable, with appropriate padding at the end.

    Example: grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')

    Inputs: - iterable: The source iterable that needs to be chunkified.
            - n: The size of the chunks.
            - pad_value: The value with which the last chunk will be padded.

    Output: - chunk_gen: A generator of n-length chunks of an input iterable.

def grouper(iterable, n, pad_value=None):
    """
    Returns a generator of n-length chunks of an input iterable, with appropriate padding at the end.

    Example: grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')

    Inputs: - iterable: The source iterable that needs to be chunkified.
            - n: The size of the chunks.
            - pad_value: The value with which the last chunk will be padded.

    Output: - chunk_gen: A generator of n-length chunks of an input iterable.
    """
    chunk_gen = (chunk for chunk in zip_longest(*[iter(iterable)]*n, fillvalue=pad_value))
    return chunk_gen