{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import param\n",
    "import panel as pn\n",
    "\n",
    "from bokeh.sampledata.iris import flowers\n",
    "from bokeh.sampledata.autompg import autompg_clean\n",
    "from bokeh.sampledata.population import data\n",
    "\n",
    "pn.extension(sizing_mode=\"stretch_width\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example demonstrates Panel's reactive programming paradigm using the Param library to express parameters, plus methods with computation depending on those parameters. This pattern can be used to update the displayed views whenever a parameter value changes, without re-running computation unnecessarily."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ReactiveTables(param.Parameterized):\n",
    "    \n",
    "    dataset = param.ObjectSelector(default='iris', objects=['iris', 'autompg', 'population'])\n",
    "    \n",
    "    rows = param.Integer(default=10, bounds=(0, 19))\n",
    "    \n",
    "    @param.depends('dataset')\n",
    "    def data(self):\n",
    "        if self.dataset == 'iris':\n",
    "            return flowers\n",
    "        elif self.dataset == 'autompg':\n",
    "            return autompg_clean\n",
    "        else:\n",
    "            return data\n",
    "\n",
    "    @param.depends('data')\n",
    "    def summary(self):\n",
    "        return self.data().describe()\n",
    "    \n",
    "    @param.depends('data', 'rows')\n",
    "    def table(self):\n",
    "        return self.data().iloc[:self.rows]\n",
    "    \n",
    "    def panel(self):\n",
    "        return pn.Row(\n",
    "            pn.Param(self, name=\"Settings\", width=300, sizing_mode=\"fixed\"),\n",
    "            pn.Column(\"## Description\", self.summary, \"## Table\", self.table),\n",
    "            min_height=1000)\n",
    "    \n",
    "component = ReactiveTables().panel()\n",
    "component"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## App\n",
    "\n",
    "Lets wrap it into nice template that can be served via `panel serve reactive_tables.ipynb`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.template.FastListTemplate(site=\"Panel\", title=\"Reactive Data Tables\", \n",
    "                             main=[\n",
    "                                 \"This example demonstrates [Panel's](https://panel.holoviz.org) reactive programming paradigm using the [Param](https://param.holoviz.org) library to express parameters, plus methods with computation depending on those parameters. \\n\\nThis pattern can be used to update the plots and tables whenever a parameter value changes, without re-running computations unnecessarily.\",\n",
    "                                 component \n",
    "                             ]).servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
