[Tutor] Verifying a data...

Timothy M. Brauch tbrauch@tbrauch.com
Wed, 10 Jul 2002 23:38:13 -0400


Danny enlightened us with:
>
> 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.

Aargh, when I was programming in Java (my other, albeit less, familiar
language) indentation didn't matter as long as I closed the }.  But then
again, I got stuck in the counting braces and ended up indenting anyway.

> 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!

Okay, now I've got it working.  And, I'm done with all the simple matrix
operations, such as addition, scalar multiplication and matrix
multiplication.  And, I still have two months to pour over my algorithms
books and linear algebra texts to finish up some of the features.  Then to
unleash this beast on my students and pray they don't break it, too badly.

 - Tim