New restrain builtin function?

Pierre Rouleau prouleau at impathnetworks.com
Sat Mar 20 18:25:26 EST 2004


Robert Brewer wrote:
> Pierre Rouleau wrote:
> 
>>In several occasions, I found myself looking for a function 
>>that would take a value and restrict is within a specified
>>set of boundaries...
>>
>>def restrain(value, theMin, theMax) :
>>
>>     assert(theMax >= theMin)
>>     return min(max(value,theMin),theMax)
>>
> 
> 
> I'd find a limit() function more useful, where either min or max is
> optional:
> 
> def limit(value, lower=None, upper=None):
>     """Return value limited by lower and/or upper bounds."""
>     
>     if upper is not None:
>         value = min(value, upper)
>     if lower is not None:
>         value = max(value, lower)
>     return value
> 
> This allows for single-boundary limits:
> 
> 
>>>>limit(3, 5)
> 
> 5
> 
>>>>limit(3, upper=1)
> 
> 1
> 
> And a no-op:
> 
> 
>>>>limit(3)
> 
> 3
> 
I was trying to make it as fast as possible but the additional 
flexibility is nice. The word 'limit' is probably closer to min and max 
and easier to read.  I wonder if the word limit would clash with more 
existing programs though.

> Also, you don't need to assert that upper >= lower; in fact, if upper is
> less than lower, you can use the same function for exclusive boundaries:
> 
> 
>>>>limit(3, 5, 1)
> 
> 5
True, however, the reason for such a function, instead of the inline 
min(max()) was to provide for some protection in some defensive 
programming way.

> 
> However, I find both restrain(3, 1, 5) and limit(3, 1, 5) difficult to
> read. It would be nice to produce the same thing with some other syntax.
I agree that the way it reads leaves me wishing for some Smalltalkish 
way of saying:  limit value to min,max

> If we did it in C, we could at least write: limit(lower=None, value,
> upper=None). But perhaps there's some other means I'm not thinking of.
> It'd be nice to have "value" look different than upper and lower. Maybe
> something like: limit(value, (lower, upper)), or even value.limit(lower,
> upper) using a __limit__ customizable method. Hmm.

However, if upper and lower are inside a tuple, then restrain (or limit) 
could not be used to restrain or limit multi-dimensional values like 
tuple and list like in:

 >>> map(restrain, (10,15,20) , (11,14,19) , (12,18, 20))
[11, 15, 20]






More information about the Python-list mailing list