"""
Functions on a 2d list of numbers

Author: Walker M. White (wmw2)
Date:   September 20, 2017 (Python 3 Version)
"""

def istable(table):
    """
    Returns: True if table is a rectangle 2d list of numbers

    Parameter table: The candidate table to check
    Preconditions: None
    """
    if type(table) != list or len(table) == 0:
        return False

    # Make sure a table and get the # of columns
    if type(table[0]) != list or len(table[0]) == 0:
        return False

    cols = len(table[0])
    for row in table:
        # Make sure table is rectangular
        if type(row) != list or len(row) != cols:
            return False

        # Walk through the row
        for item in row:
            if not type(item) in [int,float]:
                # Comment to show alignment
                return False

    return True # We made it to the end


def transpose(table):
    """
    Returns: copy of table with rows and columns swapped

    Example:
           1  2          1  3  5
           3  4    =>    2  4  6
           5  6

    Parameter table: the table to transpose
    Precondition: table is a rectangular 2d List of numbers
    """
    assert istable(table), repr(table)+' is not a rectangular table'

    # Find the size of the (non-ragged) table
    numrows = len(table)
    numcols = len(table[0]) # All rows have same no. cols

    # Build the table
    result = [] # Result accumulator
    for m in range(numcols):

        # Make a single row
        row = [] # Single row accumulator
        for n in range(numrows):
            row.append(table[n][m])

        #Add the result to the table
        result.append(row)

    return result


def determinant(table):
    """
    Returns: determinant of a 2x2 matrix

    Example:
           1  2  =>  1*4 - 3*2 = -2
           3  4

    Parameter table: the table to transpose
    Precondition: table is a 2x2 matrix of numbers
    """
    assert istable(table), repr(table)+' is not a rectangular table'
    assert len(table) == 2, repr(table)+' is not a 2x2 matrix'
    assert len(table[0]) == 2, repr(table)+' is not a 2x2 matrix'

    return table[0][0]*table[1][1]-table[0][1]*table[1][0]
