param icon indicating copy to clipboard operation
param copied to clipboard

Param with bounds should default to lower bound

Open ahuang11 opened this issue 1 year ago • 7 comments

import param
class Test(param.Parameterized):

    fps = param.Integer(
        bounds=(1, None),
        doc="The number of frames per second to use for the output.",
    )


Test()

ValueError: Integer parameter 'fps' must be at least 1, not 0.

ahuang11 avatar Mar 02 '24 23:03 ahuang11

I'm not sure. What should this default to?

class Test(param.Parameterized):
    fps = param.Integer(bounds=(None, -1))

maximlt avatar Mar 18 '24 10:03 maximlt

I don't think most people would have a strong expectation about what the default would be in either of those cases, so I'd recommend to users that they specify the default explicitly for clarity.

Still, having defaults be automatic is convenient, especially in a notebook context for quick exploratory mini-apps. My gut preference would be to take the midpoint of the two bounds (as the "most typical" value), or if there's only one specified, take that one. But I believe the current practice is to take the lower bound (alas!), so I guess taking the lower bound (if present) and then falling back to the upper bound (if present) is the best we could do.

All that's to say is that I don't object to this proposal, but I also wouldn't mind if other people want to mark it wontfix.

jbednar avatar Mar 19 '24 01:03 jbednar

If it's marked as wontfix I think it should not default to 0 outside the bounds of fps.

ahuang11 avatar Mar 19 '24 01:03 ahuang11

If I could choose I'd prefer Param not to set any default values at all, for all Parameters, so I'm not going to advocate for automatically computing smart default values 🙃

But if you want to go down that route, you'll have to define how this new logic behaves in a class inheritance scenario:

import param

class A(param.Parameterized):
    fps = param.Integer(bounds=(1, None))

class B(A):
    fps = param.Integer(bounds=(10, 20))

a = A()
b = B()
print(a.fps, b.fps)  # ?

maximlt avatar Mar 19 '24 02:03 maximlt

My first instinct is 1 and 10, but I don't mind it being wontfix, as long as the default is None (right now it's 0 if I recall).

ahuang11 avatar Mar 19 '24 02:03 ahuang11

My first instinct is 1 and 10, but I don't mind it being wontfix, as long as the default is None (right now it's 0 if I recall).

In principle I'm in full agreement but in practice this is a extremely difficult change to make because many users may implicitly be depending on the default being there.

philippjfr avatar Mar 19 '24 09:03 philippjfr

Maybe the most conservative approach is to raise an explicit error when the computed default is invalid for the range, telling the user they need to set an appropriate default.

jbednar avatar Mar 19 '24 14:03 jbednar