--------------------------
This major update (and official release!) includes many new utilities adopted from the `Covasim <http://covasim.org>`__ and `Atomica <http://atomica.tools>`__ libraries, as well as important improvements and bugfixes for parallel processing, object representation, and file I/O.
New functions
~~~~~~~~~~~~~
Math functions
^^^^^^^^^^^^^^
1. ``sc.findfirst()`` and ``sc.findlast()`` return the first and last indices, respectively, of what ``sc.findinds()`` would return. These keywords (``first`` and ``last``) can also be passed directly to ``sc.findinds()``.
2. ``sc.randround()`` probabilistically rounds numbers to the nearest integer; e.g. 1.2 will round down 80% of the time.
3. ``sc.cat()`` is a generalization of ``np.append()``/``np.concatenate()`` that handles arbitrary types and numbers of inputs.
4. ``sc.isarray()`` checks if the object is a Numpy array.
Plotting functions
^^^^^^^^^^^^^^^^^^
1. A new diverging colormap, ``'orangeblue'``, has been added (courtesy Prashanth Selvaraj). It is rather pretty; you should try it out.
2. ``sc.get_rows_cols()`` solves the small but annoying issue of trying to figure out how many rows and columns you need to plot *N* axes. It is similar to ``np.unravel_index()``, but allows the desired aspect ratio to be varied.
3. ``sc.maximize()`` maximizes the current figure window.
Date functions
^^^^^^^^^^^^^^
1. ``sc.date()`` will convert practically anything to a date.
2. ``sc.day()`` will convert practically anything to an integer number of days from a starting point; for example, ``sc.day(sc.now())`` returns the number of days since Jan. 1st.
3. ``sc.daydiff()`` computes the number of days between two or more start and end dates.
4. ``sc.daterange()`` returns a list of date strings or date objects between the start and end dates.
5. ``sc.datetoyear()`` converts a date to a decimal year (from Romesh Abeysuriya via Atomica).
Other functions
^^^^^^^^^^^^^^^
1. The "flagship" functions ``sc.loadobj()``/``sc.saveobj()`` now have shorter aliases: ``sc.load()``/``sc.save()``. These functions can be used interchangeably.
2. A convenience function, ``sc.toctic()``, has been added that does ``sc.toc(); sc.tic()``, i.e. for sequentially timing multiple blocks of code.
3. ``sc.checkram()`` reports the current process' RAM usage at the current moment in time; useful for debugging memory leaks.
4. ``sc.getcaller()`` returns the name and line number of the calling function; useful for logging and version control purposes.
5. ``sc.nestedloop()`` iterates over lists in the specified order (from Romesh Abeysuriya via Atomica).
6. ``sc.parallel_progress()`` runs a function in parallel whilst displaying a single progress bar across all processes (from Romesh Abeysuriya via Atomica).
7. An experimental function, ``sc.asobj()``, has been added that lets any dictionary-like object be used with attributes instead (i.e. ``foo.bar`` instead of ``foo['bar']``).
Bugfixes and other improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. ``sc.parallelize()`` now uses the ``multiprocess`` library instead of ``multiprocessing``. This update fixes bugs with trying to run parallel processing in certain environments (e.g., in Jupyter notebooks). This function also returns a more helpful error message when running in the wrong context on Windows.
2. ``sc.prepr()`` has been updated to use a simpler method of parsing objects for display; this should be faster and more robust. A default 3 second time limit has also been added.
3. ``sc.savejson()`` now uses an indent of 2 by default, leading to much more human-readable JSON files.
4. ``sc.gitinfo()`` has been updated to use the code from Atomica's ``fast_gitinfo()`` instead (courtesy Romesh Abeysuriya).
5. ``sc.thisdir()`` now no longer requires the ``__file__`` argument to be supplied to get the current folder.
6. ``sc.readdate()`` can now handle a list of dates.
7. ``sc.getfilelist()`` now has more options, such as to return the absolute path or no path, as well as handling file matching patterns more flexibly.
8. ``sc.Failed`` and ``sc.Empty``, which may be encountered when loading a corrupted pickle file, are now exposed to the user (before they could only be accessed via ``sc.sc_fileio.Failed``).
9. ``sc.perturb()`` can now use either uniform or normal perturbations via the ``normal`` argument.
Renamed/removed functions
~~~~~~~~~~~~~~~~~~~~~~~~~
1. The function ``sc.quantile()`` has been removed. Please use ``np.quantile()`` instead (though admittedly, it is extremely unlikely you were using it to begin with).
2. The function ``sc.scaleratio()`` has been renamed ``sc.normsum()``, since it normalizes an array by the sum.
Other updates
~~~~~~~~~~~~~
1. Module imports were moved to inside functions, improving Sciris loading time by roughly 30%.
2. All tests were refactored to be in consistent format, increasing test coverage by roughly 50%.
3. Continuous integration testing was updated to use GitHub Actions instead of Travis/Tox.