<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def orthonorm_check(a, tol=_DEF.ORTHONORM_TOL, report=False):
 """Checks orthonormality of the column vectors of a matrix. If a one-dimensional |nparray| is passed to `a`, it is treated as a single column vector, rather than a row matrix of length-one column vectors. The matrix `a` does not need to be square, though it must have at least as many rows as columns, since orthonormality is only possible in N-space with a set of no more than N vectors. (This condition is not directly checked.) Parameters a R x S |npfloat_| -- 2-D array of column vectors to be checked for orthonormality. tol |npfloat_|, optional -- Tolerance for deviation of dot products from one or zero. Default value is :data:`opan.const.DEF.ORTHONORM_TOL`. report |bool|, optional -- Whether to record and return vectors / vector pairs failing the orthonormality condition. Default is |False|. Returns ------- o |bool| -- Indicates whether column vectors of `a` are orthonormal to within tolerance `tol`. n_fail |list| of |int|, or |None| -- If `report` == |True|: A list of indices of column vectors failing the normality condition, or an empty list if all vectors are normalized. If `report` == |False|: |None| o_fail |list| of 2-tuples of |int|, or |None| -- If `report` == |True|: A list of 2-tuples of indices of column vectors failing the orthogonality condition, or an empty list if all vectors are orthogonal. If `report` == |False|: |None| """


    # Imports
    import numpy as np
    from .base import delta_fxn

    #!TODO? orthonorm_check Must add traps to ensure a is a single array,
    #    that it is 2D, that it's all real? To enforce the limits stated
    #    in the docstring?

    # Initialize return variables
    orth = True
    n_fail = []
    o_fail = []

    # Coerce to float_ matrix. Must treat 1-D vector as column vector.
    #  Should raise an exception for any objects with more than
    #  two dimensions; real and all-numeric are still not yet checked, but
    #  will probably be run-time caught if too bad an object is passed.
    if len(a.shape) == 1:
        a_mx = np.matrix(a, dtype=np.float_).T
    else:
        a_mx = np.matrix(a, dtype=np.float_)

    # Split matrix into separate vectors for convenient indexing.
    a_split = np.hsplit(a_mx, a_mx.shape[1])

    # Loop over vectors and check orthonormality.
    for iter1 in range(a_mx.shape[1]):
        for iter2 in range(iter1,a_mx.shape[1]):
            if not abs((a_split[iter1].T * a_split[iter2])[0,0] -
                        np.float_(delta_fxn(iter1, iter2))) <= tol:
                orth = False
                if report:
                    if iter1 == iter2:
                        n_fail.append(iter1)
                    else:
                        o_fail.append((iter1, iter2))

    # Return results
    if report:
        return orth, n_fail, o_fail
    else:
        return orth, None, None