{ "cells": [ { "cell_type": "markdown", "id": "6f716cf0", "metadata": {}, "source": [ "<img src=\"https://raw.githubusercontent.com/holoviz/param/main/doc/_static/logo_horizontal.png\" style=\"display:block;margin-left:auto;margin-right:auto;width:50%;max-width:500px\">" ] }, { "cell_type": "markdown", "id": "fbaa7540", "metadata": {}, "source": [ "# Introduction" ] }, { "cell_type": "markdown", "id": "cddd48c6", "metadata": {}, "source": [ "**Param is a library providing Parameters:**<br>\n", "<div style=\"padding-left:1cm;\">\n", "\n", "Python attributes extended to have features such as\n", "* type and range checking\n", "* dynamically generated values\n", "* documentation strings\n", "* default values\n", "* events\n", "</div>\n", "\n", "**Param enables you to write robust and powerful applications in just a few lines of code**.\n", "\n", "**Param is free, open source, small, and has no external dependencies**, so that it can easily be included as part of other projects." ] }, { "cell_type": "markdown", "id": "aee0b3e3", "metadata": {}, "source": [ "# Example: A Parameterized Class" ] }, { "cell_type": "markdown", "id": "3d689222", "metadata": {}, "source": [ "The [Pythagorean Theorem](https://en.wikipedia.org/wiki/Pythagorean_theorem) is one of the world's most famous equations.\n", "<img src=\"https://miro.medium.com/max/658/1*SsN2DG__Z5DyOI0uf7hbwQ.png\" style=\"display:block;margin-top:0.5cm;margin-left:2cm;margin-right:auto;width:40%;max-width:700px;border: 2px solid black;\">\n", "\n", "<br>\n", "\n", "**We will illustrate how powerful Param is** by building a model of the Pythagorean Theorem." ] }, { "cell_type": "markdown", "id": "0e23597c", "metadata": {}, "source": [ "### **Pythagorean Theorem Class**" ] }, { "cell_type": "code", "execution_count": null, "id": "5e1b9718", "metadata": {}, "outputs": [], "source": [ "import param, math, time" ] }, { "cell_type": "code", "execution_count": null, "id": "d32f4629", "metadata": {}, "outputs": [], "source": [ "class PythagoreanTheorem(param.Parameterized):\n", " \"\"\"Model of the Pythagorean Theorem\"\"\"\n", "\n", " a = param.Number(default=0, bounds=(0,None), doc=\"Length of side a\")\n", " b = param.Number(default=0, bounds=(0,None), doc=\"Length of side b\")\n", " c = param.Number(default=0, bounds=(0,None), doc=\"Length of the hypotenuse c\",\n", " constant=True)\n", "\n", "\n", " def __init__(self, **params):\n", " super().__init__(**params) # Sets values a and b if provided in the params\n", " \n", " self._update_hypotenuse() # Sets the value c\n", "\n", "\n", " @param.depends(\"a\", \"b\", watch=True) # Triggers a run of the function whenever a or b is changed\n", " def _update_hypotenuse(self):\n", " \"\"\"Updates the length of the hypotenuse\"\"\"\n", " with param.edit_constant(self):\n", " self.c = math.sqrt(self.a**2+self.b**2)" ] }, { "cell_type": "markdown", "id": "6644582b", "metadata": {}, "source": [ "### **Pythagorean Theorem Object**" ] }, { "cell_type": "markdown", "id": "90d79024", "metadata": {}, "source": [ "**Lets try to use the model**" ] }, { "cell_type": "code", "execution_count": null, "id": "dc521631", "metadata": {}, "outputs": [], "source": [ "pythagoras = PythagoreanTheorem(a=3, b=4) # create an object with initial values for the parameters a and b\n", "pythagoras.c # print the result for c" ] }, { "cell_type": "markdown", "id": "f8cf6a71", "metadata": {}, "source": [ "### **Using the Parameters**" ] }, { "cell_type": "markdown", "id": "92c716bf", "metadata": {}, "source": [ "We will now **take a closer look** at what these few lines of code provide us:" ] }, { "cell_type": "markdown", "id": "3701b783", "metadata": {}, "source": [ "#### **Param Provides Parameter Validation**" ] }, { "cell_type": "code", "execution_count": null, "id": "c35d3cb2", "metadata": {}, "outputs": [], "source": [ "# check admissible parameter values\n", "try:\n", " pythagoras1 = PythagoreanTheorem(a=-1, b=4)\n", "except Exception as ex:\n", " print(ex)" ] }, { "cell_type": "code", "execution_count": null, "id": "8f4f72ac", "metadata": {}, "outputs": [], "source": [ "# check parameter types\n", "try:\n", " pythagoras2 = PythagoreanTheorem(a=\"length is 3\", b=4)\n", "except Exception as ex:\n", " print(ex)" ] }, { "cell_type": "markdown", "id": "504d07f4", "metadata": {}, "source": [ "Param contains a wide range of useful parameter types, including\n", "* `String`\n", "* `Integer`\n", "* `Float`\n", "* `Bool`\n", "* `DataFrame`" ] }, { "cell_type": "markdown", "id": "0a90d64b", "metadata": {}, "source": [ "#### **Param Provides Constant Parameters**" ] }, { "cell_type": "code", "execution_count": null, "id": "47e2e544", "metadata": {}, "outputs": [], "source": [ "# constant values cannot be changed\n", "try:\n", " pythagoras.c = 3\n", "except Exception as ex:\n", " print(ex)" ] }, { "cell_type": "markdown", "id": "7b79b3b7", "metadata": {}, "source": [ "#### **Param Provides Default Values**" ] }, { "cell_type": "code", "execution_count": null, "id": "1ea6f981", "metadata": {}, "outputs": [], "source": [ "print( f\"{pythagoras.param.a.name} = {pythagoras.param.a.default}\")" ] }, { "cell_type": "markdown", "id": "31978876", "metadata": {}, "source": [ "#### **Param Provides Documentation**" ] }, { "cell_type": "code", "execution_count": null, "id": "5254cd8f", "metadata": {}, "outputs": [], "source": [ "?pythagoras" ] }, { "cell_type": "code", "execution_count": null, "id": "1f403192", "metadata": {}, "outputs": [], "source": [ "# more extensive documentation\n", "help(pythagoras)" ] }, { "cell_type": "markdown", "id": "b2968d3e", "metadata": {}, "source": [ "#### **Param Provides Events**" ] }, { "cell_type": "markdown", "id": "c3b96a84", "metadata": {}, "source": [ "You can **use events to react to parameter changes.**" ] }, { "cell_type": "markdown", "id": "aeaddec1", "metadata": {}, "source": [ "We have already reacted to events by using the `@param.depends(\"a\", \"b\", watch=True)` annotation<br>\n", "$\\quad$ to react to `a` or `b` changing by updating the calculated hypotenuse.\n", "\n", "Here we will use the alternative **`param.watch`** to just watch for changes to the hypotenuse `c` and print the event raised." ] }, { "cell_type": "code", "execution_count": null, "id": "92cdbf02", "metadata": {}, "outputs": [], "source": [ "def print_event(event):\n", " print(event, end='\\n\\n')\n", "\n", "watcher = pythagoras.param.watch(print_event, \"c\")" ] }, { "cell_type": "code", "execution_count": null, "id": "f0677602", "metadata": {}, "outputs": [], "source": [ "for _ in range(3):\n", " pythagoras.b += 1\n", " time.sleep(1)" ] }, { "cell_type": "markdown", "id": "881f0acb", "metadata": {}, "source": [ "We can also **stop watching** again:" ] }, { "cell_type": "code", "execution_count": null, "id": "7ff52ca7", "metadata": {}, "outputs": [], "source": [ "pythagoras.param.unwatch(watcher)" ] }, { "cell_type": "markdown", "id": "811ee5fc", "metadata": {}, "source": [ "## **Param Makes it Easy to Create GUIs**" ] }, { "cell_type": "markdown", "id": "5cd8053b", "metadata": {}, "source": [ "On top of param you can **quickly build interactive applications and graphical user interfaces.**" ] }, { "cell_type": "markdown", "id": "2fe8fe4e", "metadata": {}, "source": [ "The whole [HoloViz](https://holoviz.org) ecosystem is built in this way! \n", "\n", "<table>\n", "<tr style=\"background-color:transparent\">\n", " <td> <a href=\"https://panel.holoviz.org\"><img style=\"height:100px;margin-right:1em;margin-left: 1em\" src=\"https://holoviz.org/assets/panel.png\"/></a></td>\n", " <td> <a href=\"https://hvplot.holoviz.org\"><img style=\"height:100px;margin-right:1em;margin-left: 1em\" src=\"https://holoviz.org/assets/hvplot.png\"/></a></td>\n", " <td> <a href=\"https://holoviews.org\"><img style=\"height:100px;margin-right:1em;margin-left: 1em\" src=\"https://holoviz.org/assets/holoviews.png\"/></a></td>\n", " <td> <a href=\"https://geoviews.org\"><img style=\"height:100px;margin-right:1em;margin-left: 1em\" src=\"https://holoviz.org/assets/geoviews.png\"/></a></td>\n", " <td> <a href=\"https://datashader.org\"><img style=\"height:100px;margin-right:1em;margin-left: 1em\" src=\"https://holoviz.org/assets/datashader.png\"/></a></td>\n", " <td> <a href=\"https://param.holoviz.org\"><img style=\"height:100px;margin-right:1em;margin-left: 1em\" src=\"https://holoviz.org/assets/param.png\"/></a></td>\n", " <td> <a href=\"https://colorcet.holoviz.org\"><img style=\"height:100px;margin-right:1em;margin-left: 1em\" src=\"https://holoviz.org/assets/colorcet.png\"/></a></td>\n", "</tr>\n", "</table>" ] }, { "cell_type": "markdown", "id": "f5987dd3", "metadata": {}, "source": [ "Let's use **[Panel](https://panel.holoviz.org/) to illustrate how powerful this is.**" ] }, { "cell_type": "code", "execution_count": null, "id": "72a42b5c", "metadata": {}, "outputs": [], "source": [ "import panel as pn\n", "pn.extension()" ] }, { "cell_type": "code", "execution_count": null, "id": "dd27729a", "metadata": {}, "outputs": [], "source": [ "pn.Param(pythagoras)" ] }, { "cell_type": "markdown", "id": "7a0df37c", "metadata": {}, "source": [ "# Visit the Param Website" ] }, { "cell_type": "markdown", "id": "5ffe786d", "metadata": {}, "source": [ "**Please visit [Param's website](https://param.holoviz.org) for more information** like official releases, installation instructions, documentation, and examples.\n", "\n", "And **join the community** on the [HoloViz Discourse](https://discourse.holoviz.org/)." ] }, { "cell_type": "markdown", "id": "ef3afcd5", "metadata": {}, "source": [ "[<img src=\"assets/param-is-powerful.png\" style=\"display:block;margin-left:1cm;margin-right:auto;width:80%;max-width:1000px;border:2px solid black;\">](https://discourse.holoviz.org/)" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 5 }