Verifying and reducing Latin squares with Python 3 Similar to my previous post, I'm completing this challenge, which is to verify whether an n × n grid is a Latin square. I have also solved the bonus problem, which is to rearrange a valid Latin square so that its first row and first column are in order.

It is intended that both functions could be used independently. Any feedback is appreciated.

from itertools import chain

def is_latin(n, numbers):
    assert type(numbers) is str
    assert type(n) is str or type(n) is int

    n = int(n)
    list_numbers = [int(m) for m in numbers.split(" ")]

    valid_combination = set(range(1, n+1))
    rows = (set(list_numbers[m:m + n]) for m in range(0, n ** 2, n))
    columns = (set(list_numbers[m::n]) for m in range(n))

    for line in chain(rows, columns):
        if not(line == valid_combination):
            return False
        elif line == valid_combination:
            continue
        else:
            raise Exception("{}{}".format(line, valid_combination))
    return True

def reduce_latin(n, numbers):
    assert type(numbers) is str
    assert type(n) is str or type(n) is int

    n = int(n)
    latin = is_latin(n, numbers)
    if latin:
        return [[((i+m)%n)+1 for i in range(n)] for m in range(n)]
    elif not latin:
        return None
    else:
        raise Exception("{}{}".format(latin, numbers))

if __name__ == "__main__":
    print(reduce_latin("5", "1 2 3 4 5 5 1 2 3 4 4 5 1 2 3 3 4 5 1 2 2 3 4 5 1"))
You can make few minor improvements like:-


For comparing types use isinstance instead of comparing types using is. is won't work in case of multiple-inheritance. Plus for comparing against multiple types you can do isinstance(n, (str, int)). Read: Differences between isinstance() and type() in python

The elif and else block in is_latin function look redundant to me, you only need to check for mismatch there. Plus if line != valid_combination is more readable than: if not(line == valid_combination).
The else block in reduce_latin is also unreachable and you can remove it too.
Your code has couple of PEP 8 errors that you could check here: http://pep8online.com/