# Buggy code
def abcd_normalize(A=None, B=None, C=None, D=None):
    """Check state-space matrices and ensure they are rank-2."""
    A, B, C, D = map(_none_to_empty, (A, B, C, D))
    A, B, C, D = map(atleast_2d, (A, B, C, D))

    if (
        (len(A.shape) > 2)
        or (len(B.shape) > 2)
        or (len(C.shape) > 2)
        or (len(D.shape) > 2)
    ):
        raise ValueError("A, B, C, D arrays can be no larger than rank-2.")

    MA, NA = A.shape
    MB, NB = B.shape
    MC, NC = C.shape
    MD, ND = D.shape

    if (MC == 0) and (NC == 0) and (MD != 0) and (NA != 0):
        MC, NC = MD, NA
        C = zeros((MC, NC))
    if (MB == 0) and (NB == 0) and (MA != 0) and (ND != 0):
        MB, NB = MA, ND
        B = zeros((MB, NB))
    if (MD == 0) and (ND == 0) and (MC != 0) and (NB != 0):
        MD, ND = MC, NB
        D = zeros((MD, ND))
    if (MA == 0) and (NA == 0) and (MB != 0) and (NC != 0):
        MA, NA = MB, NC
        A = zeros((MA, NA))

    if MA != NA:
        raise ValueError("A must be square.")
    if MA != MB:
        raise ValueError("A and B must have the same number of rows.")
    if NA != NC:
        raise ValueError("A and C must have the same number of columns.")
    if MD != MC:
        raise ValueError("C and D must have the same number of rows.")
    if ND != NB:
        raise ValueError("B and D must have the same number of columns.")

    return A, B, C, D


# Traceback (ValueError)
In [21]: a = [[1.0, 2.0], [3.0, 4.0]]

In [22]: b = [[-1.0], [5.0]]

In [23]: c = [[4.0, 5.0]]

In [24]: d = [[2.5]]

In [25]: abcd_normalize(A=a, B=b, C=c)   # Expect fourth array to be [[0.0]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

/Users/warren/<ipython console> in <module>()

/Users/warren/local_tmp/lib/python2.7/site-packages/scipy/signal/ltisys.pyc in abcd_normalize(A, B, C, D)
120         raise ValueError("C and D must have the same number of rows.")
121     if ND != NB:
--> 122         raise ValueError("B and D must have the same number of columns.")
123
124     return A, B, C, D

ValueError: B and D must have the same number of columns.

In [26]: abcd_normalize(A=a, B=b, D=d)   # Expect third array to be [[0.0, 0.0]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

/Users/warren/<ipython console> in <module>()

/Users/warren/local_tmp/lib/python2.7/site-packages/scipy/signal/ltisys.pyc in abcd_normalize(A, B, C, D)
116         raise ValueError("A and B must have the same number of rows.")
117     if NA != NC:
--> 118         raise ValueError("A and C must have the same number of columns.")
119     if MD != MC:
120         raise ValueError("C and D must have the same number of rows.")

ValueError: A and C must have the same number of columns.

In [27]: abcd_normalize(A=a, C=c, D=d)   # Expect second array to be [[0.0], [0.0]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

/Users/warren/<ipython console> in <module>()

/Users/warren/local_tmp/lib/python2.7/site-packages/scipy/signal/ltisys.pyc in abcd_normalize(A, B, C, D)
114         raise ValueError("A must be square.")
115     if MA != MB:
--> 116         raise ValueError("A and B must have the same number of rows.")
117     if NA != NC:
118         raise ValueError("A and C must have the same number of columns.")

ValueError: A and B must have the same number of rows.

In [28]: abcd_normalize(B=b, C=c, D=d)   # Expect first array to be [[0.0, 0.0], [0.0, 0.0]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

/Users/warren/<ipython console> in <module>()

/Users/warren/local_tmp/lib/python2.7/site-packages/scipy/signal/ltisys.pyc in abcd_normalize(A, B, C, D)
112
113     if MA != NA:
--> 114         raise ValueError("A must be square.")
115     if MA != MB:
116         raise ValueError("A and B must have the same number of rows.")

ValueError: A must be square.

# Fixed code
def abcd_normalize(A=None, B=None, C=None, D=None):
    """Check state-space matrices and ensure they are rank-2.

    If enough information on the system is provided, that is, enough
    properly-shaped arrays are passed to the function, the missing ones
    are built from this information, ensuring the correct number of
    rows and columns. Otherwise a ValueError is raised.

    Parameters
    ----------
    A, B, C, D : array_like, optional
        State-space matrices. All of them are None (missing) by default.

    Returns
    -------
    A, B, C, D : array
        Properly shaped state-space matrices.

    Raises
    ------
    ValueError
        If not enough information on the system was provided.

    """
    A, B, C, D = map(_none_to_empty_2d, (A, B, C, D))
    A, B, C, D = map(atleast_2d, (A, B, C, D))

    MA, NA = A.shape
    MB, NB = B.shape
    MC, NC = C.shape
    MD, ND = D.shape

    p = MA or MB or NC
    q = NB or ND
    r = MC or MD

    if (p == 0) or (q == 0) or (r == 0):
        raise ValueError("Not enough information on the system.")

    A = _restore(A, (p, p))
    B = _restore(B, (p, q))
    C = _restore(C, (r, p))
    D = _restore(D, (r, q))

    return A, B, C, D