Skip to content
Tags give the ability to mark specific points in history as being important
  • v1.1.1.0
    BETSEE 1.1.1.0 (Nicer Nestor) released.
    
    Significant changes include:
    
    * Dependencies bumped:
      * PySide2 >= 5.12.3, the first official stable release of PySide2.
        This release is now supported by both the pip and conda packaging
        ecosystems and hence safely referenceable in this project.
    * Issues resolved:
      * Python 3.8 temporarily blacklisted. As discussed at upstream issue
        PYSIDE-939, PySide2 and thus BETSEE as well is currently
        incompatible with Python 3.8.
      * Install-time Python version enforced. The minimum mandatory version
        of Python required by this project is now enforced at
        setuptools-based install time via the recently introduced
        "python_requires" setup() key in our top-level "setup.py" installer.
      * pypa/pip#6163 and pypa/pip#6434. This commit circumvents a countably
        infinite number of issues introduced by both pip 19.0.0 and 19.1.0 -
        all pertaining to PEP 517 and 518, which is to say "pyproject.toml".
        The mere existence of a "pyproject.toml" file fundamentally breaks
        pip in inexplicable and horrifying ways: a significantly worse state
        of affairs than the pre-PEP 517 and 518 days of setuptools yore. Say
        what you will of setuptools ("...so much hate"), but at least it
        sorta worked. The same cannot be said of recent pip versions, which
        absolutely do not work whatsoever. "Die, pip! Die!" Specifically:
        * pypa/pip#6163 resolved. All files and subdirectories of the
          project directory containing the top-level "setup.py" script are
          now safely registered to be importable modules and packages.
          Technically, this should not be needed. The current build
          framework (e.g., pip, setuptools) should implicitly guarantee this
          to be the case. Indeed, the obsolete setuptools-based
          "easy_install" script does so. Sadly, pip >= 19.0.0 fails to do so
          for projects defining a top-level "pyproject.toml" file. Although
          upstream purports to have resolved this, the most recent stable
          release of pip continues to suffer this. This is suffering.
        * pypa/pip#6434 resolved. The top-level "pyproject.toml" file now
          explicitly declares a default value for the "build-backend" key.
          Doing so safeguards backward compatibility with pip 19.1.0, which
          erroneously violated PEP 51{7,8} by failing to fallback to a sane
          default value in the absence of this key. If this key is left
          undeclared, pip 19.1.0 fails on attempting to perform an editable
          (i.e., developer-specific) installation of this project.
      * tox-dev/tox#765 resolved. "tox" bundles an obsolete version of
        "virtualenv" itself bundling obsolete versions of both "pip" and
        "setuptools", which obstructs sanity. Our "tox.ini" configuration
        resolves this issue by instructing "tox" to manually update both
        "setuptools" and "virtualenv" to their most recent stable releases.
      * Entry points (i.e., wrapper scripts) resolved. Specifically:
        * Windows-specific entry points installable. Entry points yet again
          install as expected under non-WSL Windows variants (i.e., vanilla,
          Cygwin Windows).
        * Dependency entry points preserved. Long-standing issues with a
          custom monkey patch applied by our top-level "setup.py" script at
          setuptools-based application installation time have now been
          resolved. Previously, this patch globally applied to all
          dependencies installed by "easy_install" (but neither "pip" nor
          "conda", which fortuitously remain unaffected). Now, this monkey
          patch only locally applies to this project and downstream
          consumers of this project (e.g., BETSEE).
      * Setuptools validation relaxed. Validation of the currently installed
        version of setuptools has been relaxed to accept recent non-standard
        version strings (e.g., "41.6.0.post20191029").
      * "all" extras installable. The "all" extra listing the set of all
        optional dependencies required by this project is now safely
        installable, as required for "tox" integration.
    * Testing improved:
      * GitLab CI + "tox". Specifically:
        * Rewrote the top-level ".gitlab-ci.yml" file from the ground up to
          test both installation and runtime on all supported Python 3.x
          versions (rather than runtime on the most recent stable Python 3.x
          version) and leverage industry standards, including:
          * A test matrix exercising all official Python version-tagged
            Docker images rather than a single unofficial Python
            version-agnostic Docker image (i.e., "continuumio/anaconda3").
            Non-slim images are currently preferred to slim variants with
            names suffixed by "-slim" (e.g., "python:3.8-slim"), as the
            latter fail to include C and C++ compilers required to build and
            install wheels for Python packages both lacking official wheels
            and containing mandatory C extensions (e.g., "psutil").
          * The Python-specific "pip" and Debian-based "apt" package
            managers rather than the Anaconda-based "conda" package manager.
            An initial "apt" package cache is now explicitly created before
            attempting to install system-wide packages requiring this cache,
            including:
            * "libgl1-mesa-glx", providing the standard "libGL.so.1" shared
              library implicitly required by PySide2 Linux wheels.
          * The high-level "tox" wrapper rather than the lower-level
            "pytest" test harness.
          * The standard "virtualenv" package rather than GitLab-CI
            internals for isolating test results between different Python
            3.x versions.
          * YAML anchor-based key mapping interpolation rather than external
            scripts for resolving DRY between different Python 3.x versions.
        * Defined a top-level "tox.ini" configuration file, installing all
          optional runtime dependencies to maximize test coverage.
        * Removed the top-level "requirements-conda.txt" and
          "requirements-pip.txt" files, which were frankly superfluous.
    * Documentation revised:
      * Installation instructions rewritten. These instructions have been
        revised from the ground up for simplicity, consistency, and with an
        increased emphasis on the standard pip ecosystem rather than the
        increasingly non-standard Anaconda ecosystem. Specifically:
        * "README.rst" truncated. The top-level "README.rst" file now
          provides only minimal instructions for installing BETSEE under the
          two most popular platform-agnostic package managers: pip
          (recommeded) and Anaconda.
      * pip-based editable installation. The top-level "README.rst" file now
        advises developers to leverage pip rather than setuptools when
        performing an editable installation of this project.
      * "setup.cfg"-based PyPI documentation. The top-level "setup.cfg" file
        now transcludes the contents of the top-level "README.rst" file, a
        substantial improvement over the prior code-based approach strewn
        throughout the codebase (e.g., "setup.py", "betse_setup.buputil").
    * Git maintenance:
      * pip directories untracked. All top-level pip-specific temporary
        directories (e.g., "pip-wheel-metadata") are now ignored with
        respect to Git tracking.
    * API generalized:
      * Generalized the top-level "setup.py" script:
        * Called the newly defined
          betsee_setup.beuputil.die_unless_setuptools_version_at_least()
          validator to ensure the currently installed version of setuptools
          satisfies all installation-time requirements.
        * Added a new "test" key-value pair to the setuptools-specific
          "extras_require" dictionary, enabling "tox" to install all
          mandatory testing requirements of this application without
          duplicating those requirements in the top-level "tox.ini" file.
      * Refactored the "betsee_setup.beupbuild" submodule to defer to the
        new "betse.lib.setuptools.command.supcmdbuild" submodule.
      * Generalized the "betsee_setup.beuputil" submodule:
        * Minimized this submodule to the smallest set of requisite
          functions required by the top-level "setup.py" script.
        * Defined a new die_unless_setuptools_version_at_least() validator.
        * Generalized the die_unless_setuptools_version_at_least() function
          to use the general-purpose "distutils.version.LooseVersion" class
          rather than the strict "distutils.version.StrictVersion" class.
      * Defined a new placeholder "betsee_test.unit.test_noop" submodule,
        defining a single placeholder test_noop() unit test guaranteed to
        pass. This submodule will be removed after defining the first
        non-placeholder test submodule, but is currently required to avoid
        "tox" test-time failures.
    
    (Distortional contortionism exhibits surfactant bifurcations, unfurled!)
  • v1.1.0.0
    BETSEE 1.1.0.0 (Nice Nestor) released.
    
    Significant changes include:
    
    * Installation improvements:
      * BETSE 1.1.0 required. Each version of BETSEE now requires the same
        version of BETSE, excluding the trailing patch number of that
        version of BETSEE (e.g., BETSEE 1.1.0.0 and 1.1.0.1 both require
        BETSE 1.1.0). Since newer versions of BETSE typically break backward
        compatibility with older versions of BETSEE, this does not extend to
        newer versions of BETSE. Prior versions of BETSEE erroneously
        pretended to support arbitrary versions of BETSE.
    * Runtime improvements:
      * High-DPI scaling detection. Platforms natively supporting high-DPI
        scaling are now implicitly detected at application startup, thanks
        to the newly defined betse.util.os.displays.is_dpi_scaling() tester.
    * Testing improvements:
      * Top-level "test" shell script. This script has been imported
        verbatim from the BETSE codebase in preparation for eventual
        continuous integration (CI).
      * GitLab CI configuration. A first-draft implementation of a
        ".gitlab-ci.yml" file has been added to the repository. Note that
        this configuration lacks "pytest-xvfb" and "pytest-qt" support and
        hence is currently broken.
    * Fatal errors resolved:
      * PYSIDE-1092. pyside2uic 5.13.0 broke backward API compatibility by
        requiring that the public
        pyside2uic.Compiler.compiler.UICompiler.__init__() method now be
        passed a new mandatory "all_pyside2_modules" parameter. Since the
        pyside2uic.__init__.compileUi() function defaults this parameter to
        simply "PySide2.__all__" (i.e., the list of all compiled PySide2 C
        extensions), it would have been trivial for Qt engineers to render
        this parameter optional via the same default. They did not; ergo, we
        do. For further details, see also:
            https://bugreports.qt.io/browse/PYSIDE-1092
      * Application shutdown exception. A fatal (albeit technically
        innocuous) exception raised at application shutdown caused by the
        now-guaranteed closure of previously open logfile handles has been
        summarily resolved.
    * Deprecation warnings resolved:
      * A deprecation from the "betsee" script wrapper.
    * API generalizations:
      * Generalized the "betsee.guiappmeta" submodule:
        * Overrode the late-time and thus safe BetseeAppMeta.deinit() method
          to call the betsee.util.app.guiappwindow.unset_main_window()
          function (which effectively garbage collects the entire Qt object
          stack), previously called by the early-time and thus unsafe
          betsee.gui.window.guiwindow.QBetseeMainWindow.closeEvent() method.
      * Generalized the "betsee.util.io.log.guiloghandle" submodule:
        * Refactored the "LogHandlerSignal" subclass integrating the Python
          logging API with the Qt signals and slots API:
          * Overrode the standard logging.Handler.close() method to
            explicitly nullify the signal to which this subclass forwards
            logging messages.
          * Overrode the standard logging.Handler.emit() method to silently
            reduce to a noop when this signal is nullified (i.e., when the
            close() method has been called at least once).
  • v1.0.0.0
    BETSEE 1.0.0.0 (Mighty Maxwell) released.
    
    Significant changes include:
    
    * Custom tissue profiles. Users may now define an arbitrary number of
      custom tissue profiles (i.e., contiguous regions of the cell cluster),
      each of which assigns all cells residing in that region the same
      simulation configuration settings -- including membrane diffusion
      constants for all available ions (e.g., sodium, potassium, chloride).
    * Custom exports. Users may define an arbitrary number of custom exports
      (i.e., files saved to disk when one or more checkboxes beneath the
      "Export?" column in the "Phase Playlist" section are checked). For
      usability, the top-level tree widget now sports a nested subtree of
      export-specific tree items, complete with suitable vector-based
      iconography and human-readable tooltips. This includes:
      * Comma-separated value (CSV) files.
      * Cell cluster animations (i.e., compressed videos visualizing a
        single measurable quantity across the entire cell cluster at all
        simulation time steps).
      * Cell cluster plots (i.e., single images visualizing a single
        measurable quantity across the entire cell cluster at the last
        simulation time step).
      * Single cell plots (i.e., single images visualizing a single
        measurable quantity isolated to a single cell at all simulation time
        steps), where the cell to be visualized is selected by its uniquely
        identifying 0-based index in the currently generated cell cluster.
    * Global export settings. The top-level "Export" item enables settings
      globally applicable to all custom exports to be trivially configured,
      including:
      * Cell index-centric settings,  enabling end users to configure
        whether cell indices are displayed in cell cluster visuals and the
        index of the cell to be displayed in single cell plots.
      * Matplotlib colormaps. The matplotlib-specific colormaps used to
        associate measurable quantities visualized by plots and animations
        (e.g., transmembrane potential) with color values are now globally
        configurable. This includes the default colormaps for intrinsically
        diverging, sequential, streamline, and network data.
    * User-configurable tree list items. Predesignated parent items of the
      top-level tree widget (e.g., "Space/Tissue") now act as dynamically
      resizable lists of child items, each of which is associated with the
      same stacked widget page (e.g., "Custom Tissue Profile"). Likewise,
      end users may interactively add an arbitrary number of new child items
      and remove existing child items from such parent items. Additionally:
      * Automatic prepopulation and depopulation. Child tree items of such
        parent items are now dynamically added (i.e., prepopulated) and
        removed (i.e., depopulated) on opening and closing simulation
        configurations respectively.
      * Guaranteed success. Actions permitting users to append and remove
        child items to and from these lists are conditionally enabled and
        disabled, guaranteeing these actions to always succeed if enabled.
    * Issue resolutions, including:
      * Infinite recursion on pushing undo commands from editable widgets.
      * Overflow error raised by "libshoken" in relation to undo command
        request handling.
      * Erroneous exceptions raised on pushing the "Browse..." buttons
        associated with all dirnames edited by the "Paths" stacked widget
        page.
      * Exceptions with empty messages, which are now displayed in a mildly
        more meaningful manner.
      * "--sim-conf-file" failures. To do so, the newly defined
        QBetseeSimConf.unload() method now provides an orthogonal analogue
        to the existing QBetseeSimConf.load() method, eliminating numerous
        awkward edge cases and subtle chiken-and-egg issues throughout the
        codebase.
    * API generalizations, including:
      * The existing "betsee.gui.simconf.guisimconfundo" submodule, whose
        QBetseeSimConfUndoStack.push_undo_cmd_if_safe() method prevents undo
        commands from being pushed to this stack if no simulation
        configuration is currently open.
      * The existing "betsee.gui.simconf.stack.page" subpackage, which has
        been restructed for maintainability by:
        * Splitting all spatial-centric stacked widget pages into a new
          "betsee.gui.simconf.stack.page.space" subpackage.
        * Splitting all export-centric stacked widget pages into a new
          "betsee.gui.simconf.stack.page.export" subpackage.
      * The existing
        "betsee.gui.simconf.stack.page.space.guisimconfpagertis" submodule,
        which now defines a "QBetseeSimConfPagerTissueABC" superclass
        generally applicable to both default and custom tissue profile
        stacked widget pages.
      * The existing "betsee.gui.simconf.stack.widget.guisimconfcombobox"
        submodule. Notable new classes include:
        * "QBetseeSimConfComboBoxABC", the abstract base class of all
          simulation configuration-specific combo box subclasses.
        * "QBetseeSimConfComboBoxSequence", the concrete subclass of all
          simulation configuration-specific combo boxes backed by a simple
          sequence of raw strings.
      * The existing "betsee.gui.simconf.tree.guisimconftree" submodule,
        whose QBetseeSimConfTreeWidget._init_items() method efficiently and
        explicitly initializes all containers containing tree items,
        including those internally required by the corresponding
        "QBetseeSimConfStackedWidget" instance. This method obsoletes the
        the removed QBetseeSimConfStackedWidget._init_tree_to_stack() and
        QBetseeSimConfTreeWidget._init_items_list_root() methods.
      * The existing "betsee.util.widget.mixin.guiwdg" submodule, whose
        QBetseeObjectMixin.init() method now accepts an optional
        "is_reinitable" parameter permitting application-specific Qt objects
        to be reinitialized in a general-purpose manner. (This is strictly
        required for reinitializing each stacked widget page associated with
        a child tree item providing a dynamic list item immediately before
        that page is displayed on selecting that child tree item.)
      * The existing "betsee.util.widget.stock.tree.guitreewdg" submodule,
        whose "QBetseeTreeWidget" superclass now defines:
        * A get_item_current() method safely retrieving the currently
          selected tree item if any.
      * A new "betsee.gui.data.guidataicon" submodule, serving as an
        application-wide icon store efficiently caching instantiated icons.
        Notable functions include:
        * get_icon_dot(), caching a general-purpose bullet point icon.
      * A new "betsee.util.io.image.guiicon" submodule, providing a seamless
        cache for transparent creation, caching, and retrieval of SVG-based
        "QIcon" objects from arbitrary URIs. Notable functions include:
        * make_icon(), instantiating such icons.
      * A new "betsee.util.widget.abc.control" subpackage containing:
        * The prior "guicontrolabc" submodule, shifted for maintainability.
        * The new "guictlpagerabc" submodule, defining abstract base classes
          and mixins specific to pagers (i.e., stacked widget page
          controllers) -- all of which now subclass these abstract base
          classes and mixins as appropriate.
      * A new "betsee.util.widget.mixin.guiwdgedit" submodule, containing
        the "QBetseeEditWidgetMixin" superclass previously contained within
        the "betsee.util.widget.mixin.guiwdg" submodule. Subclasses of this
        superclass are now required to override the recursion-safe
        _init_safe() method rather than the recursion-unsafe init() method.
      * A new "betsee.util.widget.stock.guicombobox" submodule, whose
        "QBetseeComboBox" superclass generalizes the stock "QComboBox" API
        with improved Pythonics.
      * A new "betsee.util.widget.stock.tree.guitreeitem" submodule
        implementing a high-level tree widget item API encapsulating Qt's
        considerably lower-level "QTreeWidgetItem" API. Notable functions
        include:
        * get_child_item_with_text_path(), enabling callers to obtain
          arbitrary tree items via their absolute first-column text paths
          (i.e., the unique sequence of the first-column text of all items
          leading to the desired tree item, including itself).
        * get_item_preceding_or_none(), contextually retrieving the tree
          item preceding any arbitrary tree item.
      * A new "betsee.util.path.guipathenum" submodule, defining one global
        integer bit mask constant for each Qt-specific "QFileDialog::Option"
        enumeration member, enabling the codebase to trivially enable path
        dialag options in a Pythonic manner. Notably, the
        "betsee.util.path.guidir" and "betsee.util.path.guipath" submodules
        now leverage these constants.
  • v0.9.2.0
    BETSEE 0.9.2.0 (Luckiest Levin) released.
    
    Significant changes include:
    
    * Simulation configuration dialog improvements. Dialogs creating,
      opening, and saving simulation configuration files have been
      significantly sanitized, generalized, and improved across the board.
      Significant changes include:
      * Previously selected dirname persisted. The absolute dirname of the
        most recently selected directory (i.e., the directory containing the
        simulation configuration file selected by the most recent path
        dialog) is now globally persisted to the on-disk backing store of
        application settings and reused as the initially selected directory
        to which the next path dialog opens by default. This dirname is
        persisted across application invocations, effectively serving as a
        poor man's substitute for the traditional "File->Recent..." menu of
        recently opened files in standard desktop GUI applications,
        substantially improving usability.
      * Default selected basename sanitized. The basenames of the files
        opened and saved by the "File->New Simulation..." and "File->Save
        Simulation As..." dialogs now default to sanely YAML-compliant
        basenames (e.g., "sim_config.yaml"), improving usability.
      * Default selected directory safeguarded. The directory to which all
        path dialogs open by default is now effectively guaranteed to exist
        (ignoring filesystem race conditions), significantly improving
        sanity.
      * Simulation configurations creatable. Issue #5, kindly reported by
        the ever-faithful Eric Sinton in exhaustive detail, has now been
        resolved. The "File->New Simulation..." path dialog correctly
        creates new simulation configurations as expected. Thanks, Eric!
    * Dependency initialization sanitized. Third-party application
      dependencies (e.g., PySide2) are now initialized correctly by the
      object-oriented application metadata singleton (i.e., instance of the
      "betse.util.app.meta.metaappabc.MetaAppABC" superclass) rather than
      procedurely by the antiquated "betsee.lib.guilib" submodule.
    * Pip-based installation improved. Setuptools >= 38.2.0, which first
      introduced support for wheels, is now hard-required at installation
      time. Since the Qt Company necessarily distributes PySide2 (the
      principal mandatory dependency of this application) via universal
      wheels, this application always effectively required setuptools 38.2.0
      or newer at installation. This constraint is now contractually
      enforced, substantially improving end user experience (UX) under older
      systems.
    * Application settings API generalized. The existing
      "betsee.util.io.guisettings" submodule now offers the full gamut of
      exception handlers, testers, getters, and setters for manipulating
      individual settings persisted to this application's settings store.
  • v0.9.1.0
    BETSEE 0.9.1.0 (Luckier Levin) released.
    
    Significant changes include:
    
    * The "--cache-policy" command-line option, allowing developers, end
      users, and automated tests to enable alternative XML->Python caching
      strategies. Internally, BETSEE converts XML-formatted Qt
      (Creater|Designer) user interface (UI) files residing under the
      "betsee.data" subpackage into PySide2-based Python submodules residing
      under one of two subpackages:
      * "betsee.data.py", the application-wide cache containing the official
        versions of these submodules bundled with BETSEE itself.
      * "~/.betsee/py", the user-specific cache containing strictly
        unofficial versions of these submodules *NOT* bundled with BETSEE
        itself.
      In both cases, BETSEE itself dynamically regenerates these submodules
      at runtime as needed. The mandatory argument passed to this optional
      option dictates which of these submodules if any are actually
      regenerated:
      * "--cache-policy=dev", the developer-specific caching policy. Under
        this strategy, both the application-wide *AND* user-specific caches
        are regenerated as needed. Raised exceptions are treated as fatal
        errors.
      * "--cache-policy=dev", the end user-specific caching policy. Under
        this strategy, *ONLY* the user-specific cache is regenerated. If any
        exception is raised while doing so, that exception is logged as a
        non-fatal warning and the corresponding submodule from the
        application-wide cache is copied into the user-specific cache --
        ensuring that the latter always exists.
      * "--cache-policy=auto", the default caching policy. This strategy
        detects whether or not BETSEE is currently installed in development
        mode (i.e., tracked by a Git working tree), in which case the
        developer-specific caching policy is deferred to; else, the end
        user-specific caching policy is deferred to.
    * Issue #1 (i.e., "Startup Error") resolved. For both portability and
      efficiency reasons, BETSEE only officially supports the
      (Ana|Mini)conda Python distribution. This support is provided by the
      conda-forge "betsee-feedstock," which necessarily depends on the
      conda-forge "pyside2-feedstock," whose most recent release installs
      only the Qt 5.6.0 pre-pre-release version of PySide2, which predates
      the official Qt 5.11.2 "technical preview" pre-release version of
      PySide2 produced in late Septemeber of this year by the Qt Company.
      Unsurprisingly, the pre-pre-release version of PySide2 distributed by
      (Ana|Mini)conda suffers various game-breaking deficiencies, including
      the failure of the "pyside2uic" package to convert Qt
      (Creater|Designer) user interface (UI) XML files into working
      PySide2-based Python logic. This core defect is circumvented by the
      new by the new "--cache-policy" option, which contextually ignores
      failures during cache regeneration when run as an end user.
    * Issue #2 (i.e., "New Simulation Error") resolved. This release
      circumvents a trivial backward incompatibility with the Qt 5.6 API:
      notably, the failure of Qt < 5.7.0 to pass the "checked" boolean to
      slots connected to the prevalent "QAction.triggered" signal.
    * Caching API centralized. Caching-specific logic previously distributed
      throughout the codebase (e.g., the "betsee.gui.guicache" submodule,
      the "betsee.util.io.xml" subpackage) has now been centralized into the
      new "betse.lib.pyside2.cache" subpackage for maintainability.
    * Pathtree -> MetaAppABC API. The prior procedural-based
      "betsee.guipathtree" submodule has been refactored into the
      object-oriented "betsee.guimetaapp" submodule leveraging the newly
      minted "betse.util.meta.metaappabc" API, reducing DRY (i.e., "Don't
      Repeat Yourself") violations across both codebases.
    * Test suite planning. This release also adds the rudimentary outline
      for what will subsequently be developed into a full-blown continuous
      integration (CI) test suite. While currently non-working, something
      >>>>>>>> nothing.
    
    Thanks to Eric Sinton (@esinton) for voluminously documenting both
    issues and supplying an ad-hoc solution for the first issue. Our
    userbase rocks!
  • v0.9.0.0
    BETSEE 0.9.0.0 (Lucky Levin) released.
    
    Significant changes include:
    
    * Python >= 3.5 required. In accordance with the looming end-of-life
      (EOL) of Python 3.4, BETSEE now strictly requires at least Python 3.5.
    * Simulator phase queueing. Simulator phases (e.g., seed, simulation)
      may now be independently queued and dequeued such that the end user
      clicking the simulator-specific start button now sequentially runs
      each currently queued simulator phase.
    * Simulator phase running. Simulator phases (e.g., seed, simulation)
      may now be independently run, paused, resumed, and stopped in a robust
      manner leveraging our newly introduced thread pool API.
    * Simulator progress. Feedback metadata is now contextually displayed
      (in quasi-realtime) for the current simulator state:
      * Percentage-based progress.
      * Human-readable terse status.
      * Human-readable verbose substatus.
    * Simulator widget synchronization. The internal state of all simulator
      widgets is now explicitly synchronized against the external state of
      both the simulator as a whole and the currently running simulator
      phase if any, substantially improving the User eXperience (UX).
    * Placeholder text excised. Placeholder simulation configuration tree
      items (e.g., "Dynamic Channels", "Network") have now been dynamically
      pruned at runtime, dramatically improving usability.
    * Font sizes normalized. The BETSEE GUI was initially developed on a
      high-DPI system, which understandably resulted in substantially
      smaller font sizes than desirable on standard DPI systems. Font sizes
      are now normalized to conform to standard aesthetic expectations.
    * Stylesheet simplified. The global application stylesheet has now been
      sanitized, simplified, and streamlined: AKA, 3S.
    * Thread pool API. The new "betsee.util.thread.pool" subpackage now
      implements a rather efficient, portable, multithreaded framework for
      independently starting, stopping, pausing, and resuming an arbitrary
      number of arbitrary long-running threads. This framework largely
      obsoletes all prevailing low- and high-level Python and Qt
      parallelization APIs, including (but presumably not limited to):
      * "multiprocessing.dummy".
      * "threading".
      * "PySide2.QtConcurrent".
      * "PySide2.QtCore.QFuture".
      * "PySide2.QtCore.QRunnable".
      * "PySide2.QtCore.QThread".
      * "PySide2.QtCore.QThreadPool".
      Note that this framework is effectively unencumbered by the Global
      Interpreter Lock (GIL), assuming worker threads that routinely defer
      to the canonical QBetseeThreadPoolWorker._halt_work_if_requested()
      method to enable user responsiveness. Naturally, all BETSEE-specific
      worker threads satisfy this sensible constraint.
    * Installation instructions conda-fied. Installation instructions have
      been significantly streamlined to leverage the newly released Anaconda
      package for BETSEE, kindly hosted by the non-profit conda-forge
      organization. The obsolete Ubuntu-specific installation script has
      been removed.
  • v0.8.2.0
    BETSEE 0.8.2.0 (Kindest Kaufmann) released.
    
    Significant changes include:
    
    * Setuptools-based installation sanitized. PySide2 is no longer
      erroneously required at pre-installation time, thus resolving a
      significant blocker for distribution by PyPI and conda-forge.
    * Startup dependency validation sanitized. The application startup process
      now validates the satisfiability (i.e., the importability and sufficient
      version) of BETSE only once rather than twice, thus resolving
      discrepancies between setuptools-specific versioning for BETSE and the
      actual physical version of BETSE on developer machines.
    * Startup errors displayed graphically. Fatal exceptions raised on
      startup are now embedded within a PySide2-based message box.
  • v0.8.1.0
    BETSEE 0.8.1.0 (Kinder Kaufmann) released.
    
    This marks the first stable release of BETSEE. Significant features
    include:
    
    * Creatable simulations. New simulation configurations are trivially
      creatable from within the BETSEE GUI.
    * Loadable and savable simulations. Existing simulation configurations
      are trivially loaded and saved from within the BETSEE GUI.
    * Partially editable simulations. While numerous simulation
      configuration options remain unsupported, this initial release
      attempts to support the most essential such options (e.g., world size,
      simulation duration).
    * Partially runnable simulations. While running specific simulation
      phases (e.g., seed) remains unsupported, this initial release does
      support running all simulation phases in a sequential manner. Each
      such run is isolated to an effectively backgrounded thread preserving
      the usability of the foregrounded GUI.
    * Partially visualized simulation runs. Visualization of the currently
      running simulation phase is limited to:
      * Partially updated progress. A progress bar reflects the current
        state of work completed for the current phase. Only the seed,
        initialization, and simulation phases update progress; exporting
        phases (e.g., "betse plot seed") all ignore progress, currently.