Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Bounds checking

Reply
Thread Tools

Bounds checking

 
 
Martin De Kauwe
Guest
Posts: n/a
 
      03-18-2011
Hi,

if one has a set of values which should never step outside certain
bounds (for example if the values were negative then they wouldn't be
physically meaningful) is there a nice way to bounds check? I
potentially have 10 or so values I would like to check at the end of
each iteration. However as the loop is over many years I figured I
probably want to be as optimal as possible with my check. Any
thoughts?

e.g. this is my solution

# module contain data
# e.g. print state.something might produce 4.0
import state as state

def main():
for i in xrange(num_days):
# do stuff

# bounds check at end of iteration
bounds_check(state)


def bounds_check(state):
""" check state values are > 0 """
for attr in dir(state):
if not attr.startswith('__') and getattr(state, attr) < 0.0:
print "Error state values < 0: %s" % (attr)
sys.exit()

if __name__ == "__main__":
sys.exit(main())

thanks

Martin
 
Reply With Quote
 
 
 
 
Jean-Michel Pichavant
Guest
Posts: n/a
 
      03-18-2011
Martin De Kauwe wrote:
> Hi,
>
> if one has a set of values which should never step outside certain
> bounds (for example if the values were negative then they wouldn't be
> physically meaningful) is there a nice way to bounds check? I
> potentially have 10 or so values I would like to check at the end of
> each iteration. However as the loop is over many years I figured I
> probably want to be as optimal as possible with my check. Any
> thoughts?
>
> e.g. this is my solution
>
> # module contain data
> # e.g. print state.something might produce 4.0
> import state as state
>
> def main():
> for i in xrange(num_days):
> # do stuff
>
> # bounds check at end of iteration
> bounds_check(state)
>
>
> def bounds_check(state):
> """ check state values are > 0 """
> for attr in dir(state):
> if not attr.startswith('__') and getattr(state, attr) < 0.0:
> print "Error state values < 0: %s" % (attr)
> sys.exit()
>
> if __name__ == "__main__":
> sys.exit(main())
>
> thanks
>
> Martin
>

Don't check for bounds, fix any bug in the code that would set your
values out of bounds and use asserts while debugging.

Otherwise if you really need dynamic checks, it will cost you cpu, for
sure. Howeverver you could for instance override the __setatttr__ of
state object, and call the attribute's associated function.

class State(object):
funcTable = {
'foo': lambda x: x >= 0.0
}

def __init__(self):
self.foo = 0

def __setattr__(self, attribute, value):
if not self.funcTable.get(attribute, lambda x: True)(value):
sys.exit('error out of bound')
return object.__setattr(self, attribute, value)


Untested, however it's just an idea. I'm not even sure that would be
less cpu consuming
That way only attributes in functable execute a (cpu consuming ?) test
function, all other attributes will execute 'lambda x: True'.

The check occurs everytime you set an attribute however.

JM
 
Reply With Quote
 
 
 
 
Mel
Guest
Posts: n/a
 
      03-18-2011
Jean-Michel Pichavant wrote:
> Martin De Kauwe wrote:


> Don't check for bounds, fix any bug in the code that would set your
> values out of bounds and use asserts while debugging.

[ ... ]
> def __setattr__(self, attribute, value):
> if not self.funcTable.get(attribute, lambda x: True)(value):
> sys.exit('error out of bound')
> return object.__setattr(self, attribute, value)


Offhand, my only quibble is that sys.exit is not helpful for debugging.
Much better to raise an error:

if not self.funcTable.get(attribute, lambda x: True)(value):
raise ValueError ('error out of bound')

or define a subclass of ValueError just for this purpose. On error, the
program will stop just as dead, but you'll get a trace.

Mel.
 
Reply With Quote
 
Martin De Kauwe
Guest
Posts: n/a
 
      03-18-2011

> Don't check for bounds, fix any bug in the code that would set your
> values out of bounds and use asserts while debugging.
>


whilst that is a nice idea in practice this just is not a practical
solution.


> Otherwise if you really need dynamic checks, it will cost you cpu, for
> sure.


Yes I agree and I hadn't decided whether to add it or not as there
aren't any current issues. However I can see that the check would
overall be safer. I was just wondering if there was some super smartie
pants solution


Howeverver you could for instance override the __setatttr__ of
> state object, and call the attribute's associated function.
>
> class State(object):
> * * funcTable = {
> * * * *'foo': lambda x: x >= 0.0
> * * }
>
> * * def __init__(self):
> * * * *self.foo = 0
>
> * * def __setattr__(self, attribute, value):
> * * * *if not self.funcTable.get(attribute, lambda x: True)(value):
> * * * * * *sys.exit('error out of bound')
> * * * *return object.__setattr(self, attribute, value)
>
> Untested, however it's just an idea. I'm not even sure that would be
> less cpu consuming


thanks I will look at what you suggested.


 
Reply With Quote
 
Martin De Kauwe
Guest
Posts: n/a
 
      03-18-2011

> Offhand, my only quibble is that sys.exit is not helpful for debugging. *
> Much better to raise an error:
>
> * * * * if not self.funcTable.get(attribute, lambda x: True)(value):
> * * * * * * raise ValueError ('error out of bound')
>
> or define a subclass of ValueError just for this purpose. *On error, the
> program will stop just as dead, but you'll get a trace.
>
> * * * * Mel.


I think generally I prefer my code to die and as long as I know where
(from the statement) the error occurred I know generally what point I
have to debug up until. Can you explain how your solution would be
easier with a trace as I don't tend to use the raise/assert
functionality so I am interested.

thanks
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      03-19-2011
On 3/18/2011 10:24 AM, Martin De Kauwe wrote:

> def bounds_check(state):
> """ check state values are> 0 """
> for attr in dir(state):
> if not attr.startswith('__') and getattr(state, attr)< 0.0:
> print "Error state values< 0: %s" % (attr)


dir() has to do a bit a computation. I would be tempted to give 'state'
a set of attributes to check. Call it 'nonnegatives'.
for attr in nonnegatives:
if ...

This allows for attributes not subject to that check.

--
Terry Jan Reedy

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      03-19-2011
On Fri, 18 Mar 2011 07:24:33 -0700, Martin De Kauwe wrote:

> Hi,
>
> if one has a set of values which should never step outside certain
> bounds (for example if the values were negative then they wouldn't be
> physically meaningful) is there a nice way to bounds check? I
> potentially have 10 or so values I would like to check at the end of
> each iteration.


assert all(x >= 0 for x in (a, b, c, d, e, f, g, h, i, j))


> However as the loop is over many years I figured I
> probably want to be as optimal as possible with my check. Any thoughts?
>
> e.g. this is my solution
>
> # module contain data
> # e.g. print state.something might produce 4.0 import state as state
>
> def main():
> for i in xrange(num_days):
> # do stuff
>
> # bounds check at end of iteration
> bounds_check(state)


Why don't you do the range check *before* storing it in state? That way
you can identify the calculation that was wrong, instead of merely
noticing that at some point some unknown calculation went wrong.


> def bounds_check(state):
> """ check state values are > 0 """
> for attr in dir(state):
> if not attr.startswith('__') and getattr(state, attr) < 0.0:


You're looking at every single attribute, including those of super
classes, when you only want to check "10 or so" attributes. That's
probably not wise. At the very least, dir() will be a fairly expensive
call.

If you insist on checking state *after* the value is stored, instead of
preventing it from being stored in the first place, it is better to make
the state object responsible for doing it's own bounds checking. That way
only the state object needs to be updated when you change those ten
attributes, instead of some arbitrary number of places scattered all
throughout your code.


> print "Error state values < 0: %s" % (attr)
> sys.exit()


Python already has a mechanism for printing an error message and exiting:
raise.

if condition:
raise ValueError("attribute %s is negative" % name)

This will still halt the application, but it does so without stomping all
over normal conventions for command line applications (error messages
should go to stderr, not stdout; the return result should be non-zero) as
well as normal conventions for Python code (the caller should be able to
easily catch the exception -- catching sys.exit can be done, but it is a
pretty unusual thing to do).


--
Steven
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      03-19-2011
On Fri, 18 Mar 2011 15:35:40 -0700, Martin De Kauwe wrote:

>> Don't check for bounds, fix any bug in the code that would set your
>> values out of bounds and use asserts while debugging.
>>
>>

> whilst that is a nice idea in practice this just is not a practical
> solution.


Sorry, are you trying to say that it is not practical to write correct
code that isn't buggy? Well, you're honest, at least, still I can't help
but feel that you're admitting defeat before even starting.


>> Otherwise if you really need dynamic checks, it will cost you cpu, for
>> sure.

>
> Yes I agree and I hadn't decided whether to add it or not as there
> aren't any current issues. However I can see that the check would
> overall be safer. I was just wondering if there was some super smartie
> pants solution


Make each of the attributes a computed attribute with a setter that
raises an exception if you try to store a negative value. That way each
attribute is responsible for ensuring that itself is never negative.

Here's a toy example:


>>> class Demo(object):

.... def __init__(self, x):
.... self.x = x
.... def _getx(self):
.... return self._x
.... def _setx(self, value):
.... if value < 0:
.... raise ValueError('attempt to set x to negative value')
.... self._x = value
.... x = property(_getx, _setx)
....
>>> d = Demo(-42)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
File "<stdin>", line 8, in _setx
ValueError: attempt to set x to negative value
>>> d = Demo(42)
>>> d.x

42
>>> d.x = -23

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in _setx
ValueError: attempt to set x to negative value
>>> d.x = 23
>>> d.x

23


--
Steven
 
Reply With Quote
 
Martin De Kauwe
Guest
Posts: n/a
 
      03-19-2011

> dir() has to do a bit a computation. I would be tempted to give 'state'
> a set of attributes to check. Call it 'nonnegatives'.
> * * for attr in nonnegatives:
> * * * *if ...
>
> This allows for attributes not subject to that check.
>
> --
> Terry Jan Reedy


Agreed. I was trying to just write a dummy example quickly to go with
my question and that was just the way that came to mind so that I
could loop over them to test. It wasn't a great example sorry! In
reality I would just have like you said a subset a list I guess of the
ones I would check.
 
Reply With Quote
 
Martin De Kauwe
Guest
Posts: n/a
 
      03-19-2011

> assert all(x >= 0 for x in (a, b, c, d, e, f, g, h, i, j))


yep neat!



> Why don't you do the range check *before* storing it in state? That way
> you can identify the calculation that was wrong, instead of merely
> noticing that at some point some unknown calculation went wrong.


I guess no reason really. I suppose in my mind I was thinking it was
an unlikely safeguard but I liked the idea of adding so would just do
it at the end of a time step. In reality I think there is practically
no difference and this way it is done once, in a single location vs.
potential 10 separate checks? I don't see the advantage?

> You're looking at every single attribute, including those of super
> classes, when you only want to check "10 or so" attributes. That's
> probably not wise. At the very least, dir() will be a fairly expensive
> call.


yes your right, sorry I was just trying to post a quick example to go
with my question. I would use a list of the attributes to check.

>
> If you insist on checking state *after* the value is stored, instead of
> preventing it from being stored in the first place, it is better to make
> the state object responsible for doing it's own bounds checking. That way
> only the state object needs to be updated when you change those ten
> attributes, instead of some arbitrary number of places scattered all
> throughout your code.


yes I think this is what I was getting at, I will look at your
suggestion thanks.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
To increase speed on manipulating big arrays in Java with minimal bounds checking, ... Casey Hawthorne Java 16 09-01-2005 06:33 AM
Array bounds checking Chris Java 5 07-06-2005 07:23 AM
I thought that array bounds checking needed two comparisons; however, ... Casey Hawthorne Java 21 06-05-2004 08:04 PM
Bounds Checking? Julian Zhang C Programming 3 01-20-2004 11:56 PM
Macro argument bounds checking? Jim Cook C Programming 7 09-22-2003 02:50 AM



Advertisments