Skip to content

Commit

Permalink
Merge pull request #201 from sciris/rc1.1.2
Browse files Browse the repository at this point in the history
Rc1.2.0
  • Loading branch information
cliffckerr committed Jul 5, 2021
2 parents 48963c2 + 8031a1e commit fc992ac
Show file tree
Hide file tree
Showing 10 changed files with 469 additions and 90 deletions.
37 changes: 37 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ All notable changes to this project will be documented in this file.
By import convention, components of the Sciris library are listed beginning with ``sc.``, e.g. ``sc.odict()``.


Version 1.2.0 (2021-07-05)
--------------------------

New functions and methods
~~~~~~~~~~~~~~~~~~~~~~~~~
#. Added ``sc.figlayout()`` as an alias to both ``fig.set_tight_layout(True)`` and ``fig.subplots_adjust()``.
#. Added ``sc.midpointnorm()`` as an alias to Matplotlib's ``TwoSlopeNorm``; it can also be used in e.g. ``sc.vectocolor()``.
#. Added ``sc.dateformatter()``, which will (semi-)automatically format the x-axis using dates.
#. Added ``sc.getplatform()``, ``sc.iswindows()``, ``sc.islinux()``, and ``sc.ismac()``. These are all shortcuts for checking ``sys.platform`` output directly.
#. Added ``sc.cpu_count()`` as a simple alias for ``multiprocessing.cpu_count()``.

Bugfixes
~~~~~~~~
#. Fixed ``sc.checkmem()`` from failing when an attribute was ``None``.
#. Fixed a file handle that was being left open by ``sc.gitinfo()``.

``odict`` updates
~~~~~~~~~~~~~~~~~
#. Defined ``+`` for ``sc.odict`` and derived classes; adding two dictionaries is the same as calling ``sc.mergedicts()`` on them.
#. Updated nested dictionary functions, and added them as methods to ``sc.odict()`` and derived classes (like ``sc.objdict()``); for example, you can now do ``nestedobj = sc.objdict(); nestedobj.setnested(['a','b','c'], 4)``.
#. Added ``sc.odict.enumvalues()`` as an alias to ``sc.odict.enumvals()``.

Plotting updates
~~~~~~~~~~~~~~~~
#. Updated ``sc.commaticks()`` to use better formatting.
#. Removed the ``fig`` argument from ``sc.commaticks()`` and ``sc.SIticks()``; now, the first argument can be an ``Axes`` object, a ``Figure`` object, or a list of axes.
#. Updated ``sc.get_rows_cols()`` to optionally create subplots, rather than just return the number of rows/columns.
#. Removed ``sc.SItickformatter``; use ``sc.SIticks()`` instead.

Other updates
~~~~~~~~~~~~~
#. Updated ``sc.heading()`` to handle arguments the same way as ``print()``, e.g. ``sc.heading([1,2,3], 'is a list')``.
#. Allowed more flexibility with the ``ncpus`` argument of ``sc.parallelize()``: it can now be a fraction, representing a fraction of available CPUs. Also, it will now never exceed the number of tasks to be run.
#. Updated ``sc.suggest()`` to modify the threshold to be based on the length of the input word.



Version 1.1.1 (2021-03-17)
--------------------------
1. The implementations of ``sc.odict()`` and ``sc.objdict()`` have been updated, to allow for more flexible use of the ``defaultdict`` argument, including better nesting and subclassing.
Expand Down
2 changes: 1 addition & 1 deletion sciris/sc_fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def saveobj(filename=None, obj=None, compresslevel=5, verbose=0, folder=None, me
errormsg = 'No object was supplied to saveobj(), or the object was empty'
if die:
raise ValueError(errormsg)
else:
elif verbose:
print(errormsg)

# Actually save
Expand Down
2 changes: 1 addition & 1 deletion sciris/sc_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def findinds(arr, val=None, eps=1e-6, first=False, last=False, **kwargs):
warnings.warn(warnmsg, category=DeprecationWarning, stacklevel=2)

# Calculate matches
arr = np.array(arr)
arr = ut.promotetoarray(arr)
if val is None: # Check for equality
output = np.nonzero(arr) # If not, just check the truth condition
else:
Expand Down
46 changes: 43 additions & 3 deletions sciris/sc_odict.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,26 @@ def __repr__(self, maxlen=None, showmultilines=True, divider=False, dividerthres
def _repr_pretty_(self, p, cycle, *args, **kwargs): # pragma: no cover
''' Function to fix __repr__ in IPython'''
print(self.__repr__(*args, **kwargs))
return


def __add__(self, dict2):
'''
Allow two dictionaries to be added (merged).
**Example**::
dict1 = sc.odict(a=3, b=4)
dict2 = sc.odict(c=5, d=7)
dict3 = dict1 + dict2
'''
return ut.mergedicts(self, dict2)


def __radd__(self, dict2):
''' Allows sum() to work correctly '''
if not dict2: return self
else: return self.__add__(dict2)


def disp(self, maxlen=None, showmultilines=True, divider=False, dividerthresh=10, numindents=0, sigfigs=5, numformat=None, maxitems=20, **kwargs):
Expand All @@ -297,8 +317,7 @@ def disp(self, maxlen=None, showmultilines=True, divider=False, dividerthresh=10
**Example**::
import pylab as pl
z = odict().make(keys=['a','b','c'], vals=(10*pl.rand(3)).tolist())
z = sc.odict().make(keys=['a','b','c'], vals=[4.293487,3,6])
z.disp(sigfigs=3)
z.disp(numformat='%0.6f')
'''
Expand Down Expand Up @@ -868,6 +887,11 @@ def enumvals(self, transpose=False):
return iterator


def enumvalues(self, transpose=False):
''' Alias for enumvals(). New in version 1.2.0. '''
return self.enumvals(transpose=transpose)


def enumitems(self, transpose=False):
'''
Returns tuple of 3 things: index, key, value.
Expand Down Expand Up @@ -913,7 +937,7 @@ def values(self):
return list(OD.values(self))

def items(self, transpose=False):
""" Return a list of items, as in Python 2. """
""" Return a list of items (as in Python 2). """
iterator = list(OD.items(self))
if transpose: iterator = tuple(ut.transposelist(iterator))
return iterator
Expand All @@ -922,6 +946,22 @@ def iteritems(self, transpose=False):
""" Alias to items() """
return self.items(transpose=transpose)

def makenested(self, *args, **kwargs):
''' Alias to sc.makenested(odict); see sc.makenested() for full documentation. New in version 1.2.0. '''
return ut.makenested(self, *args, **kwargs)

def getnested(self, *args, **kwargs):
''' Alias to sc.getnested(odict); see sc.makenested() for full documentation. New in version 1.2.0. '''
return ut.getnested(self, *args, **kwargs)

def setnested(self, *args, **kwargs):
''' Alias to sc.setnested(odict); see sc.makenested() for full documentation. New in version 1.2.0. '''
return ut.setnested(self, *args, **kwargs)

def iternested(self, *args, **kwargs):
''' Alias to sc.iternested(odict); see sc.makenested() for full documentation. New in version 1.2.0. '''
return ut.iternested(self, *args, **kwargs)


class objdict(odict):
'''
Expand Down
13 changes: 11 additions & 2 deletions sciris/sc_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
### Parallelization functions
##############################################################################

__all__ = ['loadbalancer', 'parallelize', 'parallelcmd', 'parallel_progress']
__all__ = ['cpu_count', 'loadbalancer', 'parallelize', 'parallelcmd', 'parallel_progress']


def cpu_count():
''' Alias to mp.cpu_count() '''
return mp.cpu_count()


def loadbalancer(maxload=None, index=None, interval=None, maxtime=None, label=None, verbose=True):
Expand Down Expand Up @@ -102,7 +107,7 @@ def parallelize(func, iterarg=None, iterkwargs=None, args=None, kwargs=None, ncp
iterkwargs (dict): another way of providing variables to each process (see examples below)
args (list): positional arguments, the same for all processes
kwargs (dict): keyword arguments, the same for all processes
ncpus (int): number of CPUs to use (if None, use loadbalancer)
ncpus (int or float): number of CPUs to use (if <1, treat as a fraction of the total available; if None, use loadbalancer)
maxload (float): maximum CPU load to use (not used if ncpus is specified)
interval (float): number of seconds to pause between starting processes for checking load (not used if ncpus is specified)
parallelizer (func): alternate parallelization function instead of multiprocess.Pool.map()
Expand Down Expand Up @@ -184,6 +189,8 @@ def f(x,y):
# Handle maxload
if ncpus is None and maxload is None:
ncpus = mp.cpu_count()
if ncpus is not None and ncpus < 1: # Less than one, treat as a fraction of total
ncpus = int(mp.cpu_count()*ncpus)

# Handle kwargs
kwargs = ut.mergedicts(kwargs, func_kwargs)
Expand Down Expand Up @@ -252,6 +259,8 @@ def f(x,y):
if serial: # Run in serial
outputlist = list(map(_parallel_task, argslist))
elif parallelizer is None: # Standard usage: use the default map() function
if ncpus is not None:
ncpus = min(ncpus, len(argslist)) # Don't use more CPUs than there are things to process
multipool = mp.Pool(processes=ncpus)
outputlist = multipool.map(_parallel_task, argslist)
multipool.close()
Expand Down

0 comments on commit fc992ac

Please sign in to comment.