Cartesian product of two tuples - python
If you can use the built-in itertools module, then itertools.product is probably the easiest, but it probably not allowed.  itertools.product creates an iterable of the cartesion product of two sequences.  Since you want it with both the tup1 element first and the tup2 element first, you need to do it twice:

def cartesian_product_itertools(tup1, tup2):
    return tuple(product(tup1, tup2))+tuple(product(tup2, tup1))


The second approach would be to roll your own generator-based solution, using the yield statement.  This can then be converted to a tuple in the same way.  You need an inner function to handle the generator, and an outer function to convert it to a tuple:

def cartesian_product_iter(tup1, tup2):
    def cartesian_product_iter_inner(tup1, tup2):
        for t1 in tup1:
            for t2 in tup2:
                yield t1, t2
                yield t2, t1
    return tuple(cartesian_product_iter(tup1, tup2))


You can also do a similar looping version:

def cartesian_product_loop(tup1, tup2):
    res = ()
    for t1 in tup1:
        for t2 in tup2:
            res += ((t1, t2), (t2, t1))
    return res


For a recursive version, you can greatly simplify by using slices instead of indexes:

def cartesian_product_recursive(tup_1, tup_2):
    res = ((tup_1[0], tup_2[0]), (tup_2[0], tup_1[0]))
    if len(tup_2) == 1:
        return res
    res += cartesian_product_recursive(tup_1[:1], tup_2[1:])
    if len(tup_1) == 1:
        return res
    res += cartesian_product_recursive(tup_1[1:], tup_2)
    return res


I prefer short-circuiting, hence the returns.  If you prefer if...else, here is an equivalent implementation:

def cartesian_product_recursive_2(tup_1, tup_2):
    res = ((tup_1[0], tup_2[0]), (tup_2[0], tup_1[0]))
    if len(tup_2) &gt; 1:
        res += cartesian_product_recursive_2(tup_1[:1], tup_2[1:])
    if len(tup_1) &gt; 1:
        res += cartesian_product_recursive_2(tup_1[1:], tup_2)
    return res