{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "import numpy as np\n",
    "pn.extension(sizing_mode=\"stretch_width\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example creates a **random number generator** that periodically updates every two seconds, or with a click of a button.\n",
    "\n",
    "This demonstrates how to add a **periodic callback** and how to link a button and a toggle to a couple callbacks. The button to manually generate a random number and the toggle to toggle periodic generation of a random number."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_random_number(event=None):\n",
    "    static_text.value = np.random.randint(low=100000, high=200000)\n",
    "\n",
    "def toggle_periodic_callback(event):\n",
    "    if event.new is True:\n",
    "        periodic_cb.start()\n",
    "        periodic_toggle.name=\"STOP Periodic Generation\"\n",
    "    else:\n",
    "        periodic_cb.stop()\n",
    "        periodic_toggle.name=\"START Periodic Generation\"\n",
    "        \n",
    "def update_period(event):\n",
    "    periodic_cb.period = event.new\n",
    "\n",
    "static_text = pn.widgets.StaticText(name='Periodic Random Number Generator',\n",
    "                                    value='000000')\n",
    "\n",
    "generate_button = pn.widgets.Button(name='GENERATE New Number')\n",
    "generate_button.on_click(generate_random_number)\n",
    "\n",
    "periodic_toggle = pn.widgets.Toggle(name='START Periodic Generation',\n",
    "                                    value=False, button_type='primary')\n",
    "periodic_toggle.param.watch(toggle_periodic_callback, 'value')\n",
    "\n",
    "period = pn.widgets.Spinner(name=\"Period (ms)\", value=500, step=50, start=50)\n",
    "period.param.watch(update_period, 'value')\n",
    "\n",
    "periodic_cb = pn.state.add_periodic_callback(\n",
    "    generate_random_number, period=period.value, start=False)\n",
    "\n",
    "col = pn.Column(generate_button, period, periodic_toggle, static_text)\n",
    "col"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## App\n",
    "\n",
    "Lets wrap it into nice template that can be served via `panel serve random_number_generator.ipynb`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.template.FastListTemplate(\n",
    "    site=\"Panel\", \n",
    "    title=\"Random Number Generator\", \n",
    "    main=[\n",
    "        \"This example creates a **random number generator** that updates periodically or with the click of a button.\\n\\nThis demonstrates how to add a **periodic callback** and how to link a button and a toggle to a couple of callbacks.\",\n",
    "        col,\n",
    "    ], main_max_width=\"768px\",\n",
    ").servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
