[Tutor] Verifying a data...

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Wed, 10 Jul 2002 17:18:18 -0700 (PDT)


On Wed, 10 Jul 2002, Timothy M. Brauch wrote:

> I've run into a snag in one of my programs.  I am attempting to write a
> program for matrices, from scratch no less.  In part to help me learn python
> and in part so that features are not available that I do not want students
> to have.
>
> So far, I can do many matrix manipulations; however, the part that is
> causing problems is verifying that what was entered was an actual valid
> matrix.  I want the matrix to be able to be a single row of integers (or
> floats now that I think about it), or a list of lists of integers.  Of
> course, I need all the rows to be the same length.  As long as it is a valid
> matrix, all my other operations work as expected.
>
> What I have so far to verifiy, but does not work correctly, is:
>
> def verify_matrix(mtrx):
> ## check if first item is integer
>     if type(mtrx[0]) == type(1):
>         ## if integer, all must integers
>         for r in mtrx:
>             if type(r) != type(1):
>                 return __dimensionError__('dimension mismatch in creation')
>             else: return mtrx
              ^^^^^^^^^^^^^^^^^
Hi Timothy,

The last line here causes the bug: it's returning too quickly, convinced
that the matrix is good, even though it doesn't look through the whole
array.  It's a subtle bug, and all too easy to make, so don't worry too
much about it.


To correct this, pull the 'return mtrx' step out of the for loop: if we
get up to the return statement, that means that all of the other matrix
elements checked out fine:

###
# Within the verifymatrix() definition:

    for r in mtrx:
        if type(r) != type(1):
            return __dimensionError__('dimension mismatch in creation')
    return mtrx

###



Because it's easy to get caught by this bug, it might be better to use a
little functional programming to make the code clearer.  Here's one way to
rewrite that code:

###
def any(boolean_function, sequence):
    """Returns true if any element within our sequences satisfies our
boolean_function"""
    for s in sequence:
        if boolean_function(s):
            return 1
    return 0
###


This 'any()' function works across any sequence type.  Here are some
examples of how it works:

###
>>> def isEven(x): return x % 2 == 0
...
>>> any(isEven, [1, 3, 5, 6, 9])
1
>>> any(isEven, [1, 3, 5, 7, 9])
0
###

Here, it makes it easy to ask "Are there any elements in this list that
are even?"  No need to our code to use loops, since it's handled
internally by any()



Using this, now we can easily ask: "are any of the following list elements
non-integers?"

###
def isInteger(thing): return type(thing) == type(1)
def isNonInteger(thing): return not isInteger(thing)


def verify_matrix(mtrx):
## check if first item is integer
    if type(mtrx[0]) == type(1) and any(isNonInteger, mtrx):
        return __dimensionError__('dimension mismatch in creation')
    # ... [put rest of code here]
###



If you have more questions, please feel free to ask.  Hope this helps!