import copy


def deep_copy(*args):
    """ Auxiliary function to perform a deep copy

    Since python ``pass'' some values by reference and also make some
    attributions by reference (swallow copy), without performing a deep copy of
    some variables (like the grid matrix) we may face unexpected results by
    having another class/method/function messing up with our data

    Because of that, we provide you this auxiliary function to allow a
    friendly copy.deepcopy interface. However, you are completely free to use
    copy.deepcopy directly or even create your own deepcopy function/method

    :Example:

    >>> grid1 = [[1,2], [0,3]]
    >>> var1 = 10
    >>> var2 = 'OK'
    >>> sw_grid = grid1
    >>> sw_var1 = var1
    >>> sw_var2 = var2
    >>> dp_grid, dp_var1, dp_var2 = deep_copy(grid1, var1, var2)
    >>> grid1
    [[1, 2], [0, 3]]
    >>> sw_grid
    [[1, 2], [0, 3]]
    >>> dp_grid
    [[1, 2], [0, 3]]
    >>> grid1[0][0] = 1000
    >>> grid1
    [[1000, 2], [0, 3]]
    >>> sw_grid
    [[1000, 2], [0, 3]]
    >>> dp_grid
    [[1, 2], [0, 3]]
    """
    final_result = []
    for elem in args:
        new = copy.deepcopy(elem)
        final_result.append(new)
    return tuple(final_result)