A little app to understand how precedence works

Hi all,

I was trying to figure out how the precedence attribute of a Parameter controls the display of its associated widget in a Param pane. I came up with a little app that made things easier to understand for me.

class PrecedenceTutorial(param.Parameterized):
    x = param.Number(precedence=4)
    y = param.Number(precedence=8)
    z = param.Number(precedence=-2)

    x_precedence = param.Number(default=2, bounds=(-10, 10), step=1)
    y_precedence = param.Number(default=3, bounds=(-10, 10), step=1)
    z_precedence = param.Number(default=4, bounds=(-10, 10), step=1)

    display_threshold = param.Number(default=1, bounds=(-10, 10), step=1)
    
    def __init__(self, **params):
        super().__init__(**params)
        self.param_pane = pn.Param(
            self,
            parameters=["x", "y", "z"],
            widgets={
                "x": {"background": "#ffecd6"},
                "y": {"background": "#a3fd7e"},
                "z": {"background": "#7e83fd"},
            },
            show_name=False
        )


    @param.depends("display_threshold", "x_precedence", "y_precedence", "z_precedence", watch=True)
    def update_display_threshold(self):
        self.param.x.precedence = self.x_precedence
        self.param.y.precedence = self.y_precedence        
        self.param.z.precedence = self.z_precedence     
        self.param_pane.display_threshold = self.display_threshold

    def view(self):
        return pn.Column(
            "## Understanding `precedence` in a `Param` pane",
            "This little app allows to interactively change the `precedence` value of "
            " three parameters *x*, *y* and *z*. A parameter will be hidden if its "
            "precedence is lower than the `display_threshold` attribute of a `Param` pane. "
            "Also, the closer the `precedence` value of a parameter is to `display_threshold`, "
            "the higher it will be displayed in the layout.",
            pn.Row(
                pn.Param(
                    self.param,
                    parameters=["x_precedence", "y_precedence", "z_precedence", "display_threshold"],
                    widgets={
                        "x_precedence": {"background": "#ffecd6"},
                        "y_precedence": {"background": "#a3fd7e"},
                        "z_precedence": {"background": "#7e83fd"},
                    },
                    show_name=False
                ),
                self.param_pane
            )
        )

app = PrecedenceTutorial().view()
app.app()

This is what you’ll get!

I hope this can help some of you.

(I’m still not so sure why I had to add super().__init__(**params) at the top of the __init__ method).

1 Like

Awesome stuff @maximlt

Regarding super

"Like in other object-oriented languages, it allows you to call methods of the superclass in your subclass. The primary use case of this is to extend the functionality of the inherited method. "

You need to call it because otherwise all the magic that the super class param.Parameterized does in its __init__ function will not be run.

See https://realpython.com/python-super/ for more.

Thx @Marc, now you say it using super here completely makes sense. For sure a Parameterized class must do black magic in its __init__ !

@philippjfr I’d be happy to add this little app to the Param doc of panel if you like it.

1 Like

Sure, make a PR and add it to examples/gallery/param/precedence.ipynb.

1 Like