diff --git a/.gitmodules b/.gitmodules index b58b0f260..e69de29bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "doc/builder"] - path = doc/builder - url = https://github.com/ioam/ioam-builder.git diff --git a/.travis.yml b/.travis.yml index 89a02911a..4fc2f0ef1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,8 @@ stages: if: tag =~ ^v(\d+|\.)*[a-z]\d*$ OR (branch = master AND type != pull_request) - name: conda_package if: tag =~ ^v(\d+|\.)*[^a-z]\d*$ + - name: doc + if: branch = use_nbsite jobs: fast_finish: true @@ -110,3 +112,32 @@ jobs: tags: true user: $PYPI_USER password: $PYPI_PWD + + - <<: *default + addons: + apt: + packages: + - graphviz + stage: doc + before_install: + - apt-get install + - pip install graphviz + install: + - pip install --upgrade --pre --index-url=https://test.pypi.org/simple --extra-index-url=https://pypi.org/simple nbsite sphinx_ioam_theme + - pip install -e . + script: + - nbsite generate-rst --org ioam --project-name param --repo param --examples=./examples --doc=./doc + # should be option of generate-rst + - mkdir doc/Reference_Manual && nbsite_generate_modules.py param -d ./doc/Reference_Manual -n param -e tests + - nbsite build --what=html --examples=examples --doc=doc --output=builtdocs --examples-assets='' + - touch ./builtdocs/.nojekyll # for github pages + - nbsite_cleandisthtml.py ./builtdocs take_a_chance + deploy: + - provider: pages + skip_cleanup: true + github_token: $GITHUB_TOKEN + local_dir: ./builtdocs + repo: ioam-docs/param-tmp + on: + all_branches: true + condition: $TRAVIS_BRANCH != master diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 5c7137afb..000000000 --- a/doc/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# Makefile for Sphinx documentation -# - -PROJECT = 'Param' -MODULE = 'param' - -include ./builder/Makefile -export - -%: - $(MAKE) -f ./builder/Makefile $(CFLAGS) diff --git a/doc/_static/favicon.ico b/doc/_static/favicon.ico new file mode 100755 index 000000000..a53ea1798 Binary files /dev/null and b/doc/_static/favicon.ico differ diff --git a/doc/_static/logo.png b/doc/_static/logo.png new file mode 100644 index 000000000..6f49507e5 Binary files /dev/null and b/doc/_static/logo.png differ diff --git a/doc/_templates/page.html b/doc/_templates/page.html deleted file mode 100644 index f6a39cd09..000000000 --- a/doc/_templates/page.html +++ /dev/null @@ -1,47 +0,0 @@ -{% extends "!page.html" %} -{# add our custom css and js #} -{% set css_files = css_files + ["_static/custom.css"] %} -{% set script_files = script_files + ["_static/custom.js"] %} - -{% if 'Tutorial' in pagename %} -{% set abs_path = "http://ioam.github.io/param/" %} -{% else %} -{% set abs_path = "" %} -{% endif %} - -{# the menu at the top #} -{% block rootrellink %} -
  • Param Home
  • -
  • Reference Manual
  • -{# display "Current section:" when in a manual subpage #} -{% if parents %} -
  • -{% endif %} -{% endblock %} - -{% block sidebarsourcelink %} -

    {{ _('This Page') }}

    - -{% endblock %} - -{% block sidebartoc %} -

    Param

    - -

    {{ _('Table Of Contents') }}

    -{{ toc }} -{% endblock %} diff --git a/doc/builder b/doc/builder deleted file mode 160000 index fbcf226bc..000000000 --- a/doc/builder +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fbcf226bca33ea061b343d94d4b3a4cd33d43fb8 diff --git a/doc/conf.py b/doc/conf.py index a38ecb57e..a8eadbe68 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,73 +1,39 @@ # -*- coding: utf-8 -*- -import sys, os -sys.path.append(os.path.dirname(os.path.abspath(__file__))) +from nbsite.shared_conf import * -from builder.shared_conf import * # pyflakes:ignore (API import) - -paths = ['.', '..'] -add_paths(paths) - -# General information about the project. project = u'Param' -copyright = u'\u00a9 2003-2018, IOAM' -ioam_project = 'param' -from param import __version__ - - -# The version info for the project being documented, defining |version| -# and |release| and used in various other places throughout the built -# documents. Assumes __version__ is a param.version.Version object. -# -# The short X.Y.Z version. -version = __version__.abbrev() - -# The full version, including alpha/beta/rc/dev tags. -release = __version__.abbrev(dev_suffix="-dev") - - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static', 'builder/_shared_static'] - -# Output file base name for HTML help builder. -htmlhelp_basename = project + 'doc' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', project+'.tex', project + ' Documentation', - u'IOAM', 'manual'), -] - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', ioam_project, project + ' Documentation', - [u'IOAM'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', project, project + ' Documentation', - u'IOAM', project, 'One line description of project.', - 'Miscellaneous'), -] - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} +authors = u'PyViz authors' +copyright = u'\u00a9 2005-2018, ' + authors +description = 'Declarative Python programming using Parameters.' + +import param +version = release = param.__version__ + +html_static_path += ['_static'] +html_theme = 'sphinx_ioam_theme' +html_theme_options = { + 'logo':'logo.png', + 'favicon':'favicon.ico', +# 'css':'site.css' +} + +_NAV = ( + ('API', 'Reference_Manual/param'), + ('About', 'About'), +) + +html_context.update({ + 'PROJECT': project, + 'DESCRIPTION': description, + 'AUTHOR': authors, + # canonical URL (for search engines); can ignore for local builds + 'WEBSITE_SERVER': 'https://param.pyviz.org', + 'VERSION': version, + 'NAV': _NAV, + 'LINKS': _NAV, + 'SOCIAL': ( + ('Gitter', '//gitter.im/ioam/holoviews'), + ('Github', '//github.com/ioam/param'), + ) +}) diff --git a/doc/index.rst b/doc/index.rst index 8b8ecf370..002594201 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -1,270 +1,20 @@ +.. + Originally generated by nbsite (0.4.4a13+gdbf7de7-dirty): + nbsite generate-rst --org ioam --project param --repo param --examples-path examples --doc-path doc + Will not subsequently be overwritten by nbsite, so can be edited. + ***** Param ***** -Param is a library providing Parameters: Python attributes extended to -have features such as type and range checking, dynamically generated -values, documentation strings, default values, etc., each of which is -inherited from parent classes if not specified in a subclass. Param -lets you program declaratively in Python, by just stating facts about -each of your parameters, and then using them throughout your code. -With Parameters, error checking will be automatic, which eliminates -huge amounts of boilerplate code that would otherwise be required to -verify or test user-supplied values. - -Param-based programs tend to contain much less code than other Python -programs, instead just having easily readable and maintainable -manifests of Parameters for each object or function. This way your -remaining code can be much simpler and clearer, while users can also -easily see how to use it properly. - -What is a Parameter? -==================== -A Parameter is a special type of Python attribute extended to have features such as type and range checking, dynamically generated values, documentation strings, default values, etc., each of which is inherited from parent classes if not specified in a subclass. - - ->>> import param,random ->>> class A(param.Parameterized): -... a = param.Number(0.5,bounds=(0,1),doc="Probability that...") -... b = param.Boolean(False,doc="Enable feature...") - ->>> class B(A): -... b = param.Boolean(True) - ->>> x = B(a=lambda: random.uniform(0,1)) - ->>> x.a -0.37053399325641945 - ->>> x.a -0.64907392300071842 - - -Parameters provide optional range and type checking -___________________________________________________ - - ->>> x.a=5 -[...] -ValueError: Parameter 'a' must be at most 1 - ->>> x.a="0.5" -[...] -ValueError: Parameter 'a' only takes numeric values - -Parameters have docstrings -__________________________ - - ->>> help(x) -[...] -class B(A) -[...] - Data descriptors defined here: - b - Enable feature... -[...] - Data descriptors inherited from A: - a - Probability that... - -Param is lightweight -____________________ - -Param consists of two required BSD-licensed Python files, with no -dependencies outside of the standard library, and so it can easily be -included as part of larger projects without adding external dependencies. - - -Parameters make GUI programming simpler -_______________________________________ - -Parameters make it simple to generate GUIs by separating your semantic -information (what is this parameter? what type can it have? does it -have bounds?) from anything to do with a particular GUI library. To -use Parameters in a particular GUI toolkit, you just need to write a -simple set of interfaces that indicate how a given Parameter type -should be displayed, and what widgets to generate for it. Currently, -interfaces are provided for use in Jupyter Notebooks (`ParamNB -`_) -or in Tk (`ParamTk `_), both of which -make it simple to provide a property sheet that automatically -generates a set of widgets for viewing and editing an object's -Parameters. - - -Optional dynamic parameter values using `numbergen` -_______________________________________ - -Providing random or other types of varying values for parameters can -be tricky, because unnamed ("lambda") functions as used above cannot -easily be pickled, causing problems for people who wish to store -Parameterized objects containing random state. To avoid users having -to write a separate function for each random value, Param includes an -optional set of value-generating objects that are easily configured -and support pickling. These objects are available if you import the -optional `numbergen` module. If you wish to use numbergen, the above -example can be rewritten as: - ->>> import param,numbergen ->>> class A(param.Parameterized): -... a = param.Number(0.5,bounds=(0,1),doc="Probability that...") -... b = param.Boolean(False,doc="Enable feature...") - ->>> class B(A): -... b = param.Boolean(True) - ->>> x = B(a=numbergen.UniformRandom()) - -Numbergen objects support the usual arithmetic operations like +, -, -\*, /, //, %, \*\*, and abs(), and so they can be freely combined with -each other or with mathematical constants: - ->>> y = B(a=2.0*numbergen.UniformRandom()/(numbergen.NormalRandom()+1.5)) - -Note that unlike the lambda-function approach, all varying numbergen -objects respect `param.Dynamic.time_fn`, e.g. to ensure that new -values will be generated only when Param's time has changed. -Parameterized programs can define a time function to maintain a -logical/simulated time, such as the state of a simulator, which -allows all Parameter values to be kept synchronized without -any special coordination code. - - -Installation -============ - -Param has no required dependencies outside of Python's standard -library. - -Official releases of Param are available on -`Anaconda `_ and -`PyPI `_, and can be installed via -``conda install -c ioam param``, ``pip install --user param``, or -``pip install param``. - -The very latest changes can be obtained via ``conda install -c pyviz/label/dev -param`` or ``pip install -https://github.com/ioam/param/archive/master.zip``. - -For development, the `git repository `_ -can be cloned and then 'develop installed' (``pip install -e .`` or -``python setup.py develop``). Tests can be run via `tox -`_: ``tox`` for all tests, or -e.g. ``tox -e coverage`` to run unit tests with coverage for the -currently active python. Alternatively, unit tests can be run via -``nosetests`` (after installing `nose -`_). - - -Comparison to other packages -============================ - -Param was first developed in 2003, in the context of the Topographica brain simulator project, and -was made into a separate package in 2012. In the interim other parameter libraries were -developed, including `Traits `_ and -`Traitlets `_. These libraries have broadly similar goals, -but each differs in important ways: - -**Dependencies**: - Traits is a much more heavyweight solution, requiring - installation of a large suite of tools, including C code, which makes it difficult to include in - separate projects. In contrast, Param and Traitlets are both pure Python projects, with minimal dependencies. - -**GUI toolkits**: - Although any of the packages could in principle add support for any - GUI toolkit, the toolkits actually provided differ: Traits (via the - separate TraitsUI package) supports wxWidgets and QT, while Param - supports Tkinter (via the separate ParamTk package) and - browser-based IPython widgets (via the separate ParamNB package), - while Traitlets only supports IPython widgets. - -.. >>> from time import time - >>> import traitlets as tr - >>> class A(tr.HasTraits): - ... instantiation_time = tr.Float() - ... @tr.default('instantiation_time') - ... def _look_up_time(self): - ... return time() - ... - >>> a=A() - >>> a.instantiation_time - 1475587151.967874 - >>> a.instantiation_time - 1475587151.967874 - >>> b=A() - >>> b.instantiation_time - 1475587164.750875 - -**Dynamic values**: - Param, Traits, and Traitlets all allow any Python expression to be - supplied for initializing parameters, allowing parameter default - values to be computed at the time a module is first loaded. Traits - and Traitlets also allow a class author to add code for a given - parameter to compute a default value on first access. Param does - not provide any special support for programmatic default values, - instead allowing fully dynamic values for *any* numeric Parameter - instance: - - >>> from time import time - >>> import param - >>> class A(param.Parameterized): - ... val=param.Number(0) - ... - >>> a=A() - >>> a.val - 0 - >>> a.val=lambda:time() - >>> a.val - 1475587455.437027 - >>> a.val - 1475587456.501314 - - Note that here it is the *user* of a Parameterized class, not the - author of the class, that decides whether any particular value is - dynamic, without writing any new methods or other code. All the - usual type checking, etc. is done on dynamic values when they are - computed, and so the rest of the code does not need to know or care - whether the user has set a particular parameter to a dynamic value. - This approach provides an enormous amount of power to the user, - without making the code more complex. - -**On_change callbacks** - Traitlets and Traits allow the author of a HasTraits-derived class - to specify code to run when a specific parameter used in that class - instance is modified. Param supports similar capabilities, but not - at the Parameterized class level, only at the Parameter class level - or as part of ParamNB. I.e., a class author needs to first write a - new Parameter class, adding methods to implement checking on - changes, and then add it to a Parameterized class, or else such - functionality can be added as callbacks at the whole-object level, - using ParamNB. Each approach has advantages and disadvantages, and - per-parameter on_change callbacks could be added in the future if - there are clear use cases. - -All of these packages also overlap in functionality with Python -properties, which were added to the language after Traits and Param -were developed. Like parameters and traits, properties act like -attributes with possible method-like actions, and so they can all be -used to provide the same user-visible functionality. However, -implementing Param/Traits-like functionality using properties would -require vastly more code (multiple method definitions for *every* -parameter in a class), and so in practice Parameters and Traits are -much more practical for the use cases that they cover. - - -Release notes -============= - -Recent release notes are available on `GitHub -`_. - -For older releases, see our `historical release notes -`_. - +.. notebook:: param ../examples/index.ipynb + :offset: 0 -Support -======= +.. toctree:: + :titlesonly: + :maxdepth: 2 -Questions and comments are welcome at https://github.com/ioam/param/issues. + Introduction + API + About diff --git a/doc/site_map.rst b/doc/site_map.rst deleted file mode 100644 index 3dd3bb8b9..000000000 --- a/doc/site_map.rst +++ /dev/null @@ -1,8 +0,0 @@ -************************* -Map of the Param Site -************************* - -.. toctree:: - index - Reference_Manual/param-module - historical_release_notes diff --git a/examples/About.ipynb b/examples/About.ipynb new file mode 100644 index 000000000..5906209ee --- /dev/null +++ b/examples/About.ipynb @@ -0,0 +1,19 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Param is part of [PyViz](http://pyviz.org), a collaborative project to produce a coherent solution to a wide range of Python visualization problems." + ] + } + ], + "metadata": { + "language_info": { + "name": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/index.ipynb b/examples/index.ipynb new file mode 100644 index 000000000..152175fc2 --- /dev/null +++ b/examples/index.ipynb @@ -0,0 +1,300 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Param is a library providing Parameters: Python attributes extended to\n", + "have features such as type and range checking, dynamically generated\n", + "values, documentation strings, default values, etc., each of which is\n", + "inherited from parent classes if not specified in a subclass. Param\n", + "lets you program declaratively in Python, by just stating facts about\n", + "each of your parameters, and then using them throughout your code.\n", + "With Parameters, error checking will be automatic, which eliminates\n", + "huge amounts of boilerplate code that would otherwise be required to\n", + "verify or test user-supplied values.\n", + "\n", + "Param-based programs tend to contain much less code than other Python\n", + "programs, instead just having easily readable and maintainable\n", + "manifests of Parameters for each object or function. This way your\n", + "remaining code can be much simpler and clearer, while users can also\n", + "easily see how to use it properly." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# What is a Parameter?\n", + "\n", + "A Parameter is a special type of Python attribute extended to have features such as type and range checking, dynamically generated values, documentation strings, default values, etc., each of which is inherited from parent classes if not specified in a subclass.\n", + "\n", + "```python\n", + ">>> import param,random\n", + ">>> class A(param.Parameterized):\n", + "... a = param.Number(0.5,bounds=(0,1),doc=\"Probability that...\")\n", + "... b = param.Boolean(False,doc=\"Enable feature...\")\n", + "\n", + ">>> class B(A):\n", + "... b = param.Boolean(True)\n", + "\n", + ">>> x = B(a=lambda: random.uniform(0,1))\n", + "\n", + ">>> x.a\n", + "0.37053399325641945\n", + "\n", + ">>> x.a\n", + "0.64907392300071842\n", + "```\n", + "\n", + "## Parameters provide optional range and type checking\n", + "\n", + "```python\n", + ">>> x.a=5\n", + "[...]\n", + "ValueError: Parameter 'a' must be at most 1\n", + "\n", + ">>> x.a=\"0.5\"\n", + "[...]\n", + "ValueError: Parameter 'a' only takes numeric values\n", + "```\n", + "\n", + "## Parameters have docstrings\n", + "\n", + "```python\n", + ">>> help(x)\n", + "[...]\n", + "class B(A)\n", + "[...]\n", + " Data descriptors defined here:\n", + " b\n", + " Enable feature...\n", + "[...]\n", + " Data descriptors inherited from A:\n", + " a\n", + " Probability that...\n", + "```\n", + "\n", + "## Param is lightweight\n", + "\n", + "Param consists of two required BSD-licensed Python files, with no\n", + "dependencies outside of the standard library, and so it can easily be\n", + "included as part of larger projects without adding external dependencies.\n", + "\n", + "\n", + "## Parameters make GUI programming simpler\n", + "\n", + "Parameters make it simple to generate GUIs by separating your semantic\n", + "information (what is this parameter? what type can it have? does it\n", + "have bounds?) from anything to do with a particular GUI library. To\n", + "use Parameters in a particular GUI toolkit, you just need to write a\n", + "simple set of interfaces that indicate how a given Parameter type\n", + "should be displayed, and what widgets to generate for it. Currently,\n", + "interfaces are provided for use in Jupyter Notebooks ([ParamNB]\n", + "(https://github.com/ioam/paramnb)) \n", + "or in Tk ([ParamTk](http://ioam.github.com/paramtk)), both of which\n", + "make it simple to provide a property sheet that automatically\n", + "generates a set of widgets for viewing and editing an object's\n", + "Parameters.\n", + "\n", + "\n", + "## Optional dynamic parameter values using `numbergen`\n", + "\n", + "Providing random or other types of varying values for parameters can\n", + "be tricky, because unnamed (\"lambda\") functions as used above cannot\n", + "easily be pickled, causing problems for people who wish to store\n", + "Parameterized objects containing random state. To avoid users having\n", + "to write a separate function for each random value, Param includes an\n", + "optional set of value-generating objects that are easily configured\n", + "and support pickling. These objects are available if you import the\n", + "optional `numbergen` module. If you wish to use numbergen, the above\n", + "example can be rewritten as:\n", + "\n", + "```python\n", + ">>> import param,numbergen\n", + ">>> class A(param.Parameterized):\n", + "... a = param.Number(0.5,bounds=(0,1),doc=\"Probability that...\")\n", + "... b = param.Boolean(False,doc=\"Enable feature...\")\n", + "\n", + ">>> class B(A):\n", + "... b = param.Boolean(True)\n", + "\n", + ">>> x = B(a=numbergen.UniformRandom())\n", + "``` \n", + "\n", + "Numbergen objects support the usual arithmetic operations like `+`, `-`,\n", + "`*`, `/`, `//`, `%`, `**`, and `abs()`, and so they can be freely combined with\n", + "each other or with mathematical constants:\n", + "\n", + "```python\n", + ">>> y = B(a=2.0*numbergen.UniformRandom()/(numbergen.NormalRandom()+1.5))\n", + "```\n", + "\n", + "Note that unlike the lambda-function approach, all varying numbergen\n", + "objects respect `param.Dynamic.time_fn`, e.g. to ensure that new\n", + "values will be generated only when Param's time has changed. \n", + "Parameterized programs can define a time function to maintain a\n", + "logical/simulated time, such as the state of a simulator, which\n", + "allows all Parameter values to be kept synchronized without\n", + "any special coordination code.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Installation\n", + "\n", + "Param has no required dependencies outside of Python's standard\n", + "library.\n", + "\n", + "Official releases of Param are available on\n", + "[Anaconda](https://anaconda.org/ioam/param) and\n", + "[PyPI](http://pypi.python.org/pypi/param), and can be installed via\n", + "`conda install -c ioam param`, `pip install --user param`, or \n", + "`pip install param`.\n", + "\n", + "The very latest changes can be obtained via `conda install -c pyviz/label/dev\n", + "param` or `pip install\n", + "https://github.com/ioam/param/archive/master.zip`.\n", + "\n", + "For development, the [git repository](http://github.com/ioam/param)\n", + "can be cloned and then 'develop installed' (`pip install -e .` or\n", + "`python setup.py develop`). Tests can be run via [tox]\n", + "(https://tox.readthedocs.io/en/latest/): `tox` for all tests, or\n", + "e.g. `tox -e coverage` to run unit tests with coverage for the\n", + "currently active python. Alternatively, unit tests can be run via\n", + "`nosetests` (after installing [nose](http://nose.readthedocs.io/en/latest)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Comparison to other packages\n", + "\n", + "Param was first developed in 2003, in the context of the Topographica brain simulator project, and\n", + "was made into a separate package in 2012. In the interim other parameter libraries were\n", + "developed, including [Traits](http://code.enthought.com/projects/traits) and \n", + "[Traitlets](https://github.com/ipython/traitlets/). These libraries have broadly similar goals,\n", + "but each differs in important ways:\n", + "\n", + "**Dependencies**: \n", + " Traits is a much more heavyweight solution, requiring \n", + " installation of a large suite of tools, including C code, which makes it difficult to include in \n", + " separate projects. In contrast, Param and Traitlets are both pure Python projects, with minimal dependencies. \n", + "\n", + "**GUI toolkits**: \n", + " Although any of the packages could in principle add support for any\n", + " GUI toolkit, the toolkits actually provided differ: Traits (via the\n", + " separate TraitsUI package) supports wxWidgets and QT, while Param\n", + " supports Tkinter (via the separate ParamTk package) and\n", + " browser-based IPython widgets (via the separate ParamNB package),\n", + " while Traitlets only supports IPython widgets.\n", + "\n", + " ```python\n", + " >>> from time import time\n", + " >>> import traitlets as tr\n", + " >>> class A(tr.HasTraits):\n", + " ... instantiation_time = tr.Float()\n", + " ... @tr.default('instantiation_time')\n", + " ... def _look_up_time(self):\n", + " ... return time()\n", + " ... \n", + " >>> a=A()\n", + " >>> a.instantiation_time\n", + " 1475587151.967874\n", + " >>> a.instantiation_time\n", + " 1475587151.967874\n", + " >>> b=A()\n", + " >>> b.instantiation_time\n", + " 1475587164.750875\n", + " ```\n", + "\n", + "**Dynamic values**:\n", + " Param, Traits, and Traitlets all allow any Python expression to be\n", + " supplied for initializing parameters, allowing parameter default\n", + " values to be computed at the time a module is first loaded. Traits\n", + " and Traitlets also allow a class author to add code for a given\n", + " parameter to compute a default value on first access. Param does\n", + " not provide any special support for programmatic default values,\n", + " instead allowing fully dynamic values for *any* numeric Parameter\n", + " instance:\n", + "\n", + " ```python\n", + " >>> from time import time\n", + " >>> import param\n", + " >>> class A(param.Parameterized):\n", + " ... val=param.Number(0)\n", + " ... \n", + " >>> a=A()\n", + " >>> a.val\n", + " 0\n", + " >>> a.val=lambda:time()\n", + " >>> a.val\n", + " 1475587455.437027\n", + " >>> a.val\n", + " 1475587456.501314\n", + " ```\n", + " \n", + " Note that here it is the *user* of a Parameterized class, not the\n", + " author of the class, that decides whether any particular value is\n", + " dynamic, without writing any new methods or other code. All the\n", + " usual type checking, etc. is done on dynamic values when they are\n", + " computed, and so the rest of the code does not need to know or care\n", + " whether the user has set a particular parameter to a dynamic value.\n", + " This approach provides an enormous amount of power to the user,\n", + " without making the code more complex.\n", + "\n", + "**On_change callbacks**\n", + " Traitlets and Traits allow the author of a HasTraits-derived class\n", + " to specify code to run when a specific parameter used in that class\n", + " instance is modified. Param supports similar capabilities, but not\n", + " at the Parameterized class level, only at the Parameter class level\n", + " or as part of ParamNB. I.e., a class author needs to first write a\n", + " new Parameter class, adding methods to implement checking on\n", + " changes, and then add it to a Parameterized class, or else such\n", + " functionality can be added as callbacks at the whole-object level,\n", + " using ParamNB. Each approach has advantages and disadvantages, and\n", + " per-parameter on_change callbacks could be added in the future if\n", + " there are clear use cases.\n", + "\n", + "All of these packages also overlap in functionality with Python\n", + "properties, which were added to the language after Traits and Param\n", + "were developed. Like parameters and traits, properties act like\n", + "attributes with possible method-like actions, and so they can all be\n", + "used to provide the same user-visible functionality. However,\n", + "implementing Param/Traits-like functionality using properties would\n", + "require vastly more code (multiple method definitions for *every*\n", + "parameter in a class), and so in practice Parameters and Traits are\n", + "much more practical for the use cases that they cover.\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Release notes\n", + "\n", + "Recent release notes are available on [GitHub](https://github.com/ioam/param/releases).\n", + "\n", + "For older releases, see our [historical release notes](historical_release_notes.html).\n", + "\n", + "\n", + "# Support\n", + "\n", + "Questions and comments are welcome at https://github.com/ioam/param/issues." + ] + } + ], + "metadata": { + "language_info": { + "name": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}