[Python-ideas] Consider adding clip or clamp function to math

Chris Kaynor ckaynor at zindagigames.com
Thu Aug 4 16:21:27 EDT 2016


On Thu, Aug 4, 2016 at 6:20 AM, Steven D'Aprano <steve at pearwood.info> wrote:

> Think about why you're clamping. It's unlikely to be used just once, for
> a single calculation. You're likely to be clamping a whole series of
> values, with a fixed lower and upper bounds. The bounds are unlikely to
> be known at compile-time, but they aren't going to change from clamping
> to clamping. Something like this:
>
> lower, upper = get_bounds()
> for x in values():
>     y = some_calculation(x)
>     y = clamp(y, lower, upper)
>     do_something_with(y)
>
>
> is the most likely use-case, I think.
>

I was curious about what the likely cases are in many cases, so I ran a
quick sample from a professional project I am working on, and found the
following results:

clamping to [0, 1]: 50 instances, almost always dealing with percentages
lower is 0: 44 instances, almost all were clamping an index to list bounds,
though a few outliers existed
lower is 1: 4 instances, 3 were clamping a 1-based index, the other was
some safety code to ensure a computed wait time falls within certain bounds
to avoid both stalling and spamming
both values were constant, but with no real specific values: 11 instances
(two of these are kinda 0,1 limits, but a log is being done for volume
calculations, so 0 is invalid, but the number is very close to 0)
one value was constant, with some arbitrary limit and the other was
computed: 0
both values were computed: 20 instances (many instances have the clamping
pulled from data, which is generally constant but can be changed easier
than code)

Any given call to clamp was put into the first of the categories it
matched. "computed" is fairly general, it includes cases where the value is
user-input with no actual math done.

As would be expected, all cases were using computed value as the input,
only the min/max were ever constant.

The project in this case is a video game's game logic code, written in C#.
None of the shaders or engine code is included. There may be additional
clamping using min/max combinations, rather than the provided clamp helpers
that were not included, however the search did find two instances, where
they were commented as being clamps, which were included.

Basically all of the cases will repeat fairly often, either every frame,
move, or level. Most are not in loops outside of the frame/game loop.


> If lower happens to be greater than upper, that's clearly a mistake. Its
> better to get an exception immediately, rather than run through a
> million calculations and only then discover that you've ended up with a
> million NANs. It's okay if you get a few NANs, that simply indicates
> that one of your x values was a NAN, or a calculation produced a NAN.
> But if *every* calculation produces a NAN, well, that's a sign of
> breakage. Hence, better to raise straight away.
>

I personally don't have much opinion on NAN behaviour in general - I don't
think I've ever actually used them in any of my code, and the few cases
they show up, it is due to a bug or corrupted data that I want caught early.

Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160804/b6df15e4/attachment-0001.html>


More information about the Python-ideas mailing list