
    J-jO                        d Z ddlmZmZmZ ddlZddlZddlZddlZddl	Z	ddl
ZddlZddlmZmZ [[[dZd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd>dZd?dZd?dZd Zd Z d Z!d Z"	 	 	 d@dZ#d Z$d Z% ejL                  e'      Z(	 	 dAdZ)	 	 dBdZ*	 	 dBdZ+dCdZ,dDdZ-dEd Z.dFd!Z/ G d" d#e0      Z1 G d$ d%e2      Z3 G d& d'e2      Z4 G d( d)ejj                        Z6 G d* d+e6      Z7 G d, d-ejL                        Z8 G d. d/e9      Z: G d0 d1e0      Z; G d2 d3e0      Z< G d4 d5e2      Z= G d6 d7e9      Z> G d8 d9e0      Z? G d: d;e9      Z@ G d< d=e0      ZAy)Gz-various utilities not related to optimization    )absolute_importdivisionprint_functionN   )abcrangec                     | S N )xargskwargss      a/Users/jameslopez/projects/TradingBot25/.venv/lib/python3.12/site-packages/cma/utilities/utils.py_idr      s    H    c                 P    	 t        |       rdS dS # t        $ r | rdcY S dcY S w xY w)a  intuitive handling of variable truth value also for `numpy` arrays.

    Return `True` for any non-empty container, otherwise the truth value of the
    scalar `var`.

    Caveat of the most unintuitive case: [0] evaluates to True, like [0, 0].

    >>> import numpy as np
    >>> from cma.utilities.utils import is_
    >>> is_({}) or is_(()) or is_(0) or is_(None) or is_(np.array(0))
    False
    >>> is_({0:0}) and is_((0,)) and is_(np.array([0]))
    True

    TF)len	TypeErrorvars    r   is_r      s4     &3xt*U* &t%%&s     %%%c                 p    t        j                  t        j                  |       dk(        S #  | dk(  cY S xY w)z&return True if var == 1 or ones vectorr   )npallasarrayr   s    r   is_oner   2   s+    rzz#!+,	,3!8Os   *, 5c                     t        |        S )z	see `is_`r   r   s    r   is_notr   6   s    3x<r   c                 &    t        d | D              S )z(return ``any(is_(v) for v in var_list)``c              3   2   K   | ]  }t        |        y wr
   r   .0r   s     r   	<genexpr>zis_any.<locals>.<genexpr>;        ,8Cs3x8   )anyvar_lists    r   is_anyr*   9       ,8,,,r   c                 &    t        d | D              S )z(return ``all(is_(v) for v in var_list)``c              3   2   K   | ]  }t        |        y wr
   r   r"   s     r   r$   zis_all.<locals>.<genexpr>>   r%   r&   )r   r(   s    r   is_allr.   <   r+   r   c                     t        | d      S )z`bytes` (in Python 3) also fit the bill.

    >>> from cma.utilities.utils import is_str
    >>> assert is_str(b'a') * is_str('a') * is_str(u'a') * is_str(r'b')
    >>> assert not is_str([1]) and not is_str(1)

    
startswith)hasattrr   s    r   is_strr2   ?   s     3%%r   c                 L    	 t        j                  |       S # t        $ r Y yw xY w)z;return ``np.isnan(var)`` or `False` if `var` is not numericF)r   isnanr   r   s    r   is_nanr5   H   s'    xx} s    	##c                 H    	 t        j                  | d   d         S #  Y yxY w)zmake an educated guess whether ``x`` is a list of vectors.

    >>> from cma.utilities.utils import is_vector_list as ivl
    >>> assert ivl([[0], [0]]) and not ivl([1,2,3])

    r   F)r   isscalarr   s    r   is_vector_listr9   O   s(    {{1Q47##s    !c                 .    t        |       r| d fS | gd fS )a\  a tool to handle a vector or a list of vectors in the same way,
    return a list of vectors and a function to revert the "list making".

    Useful when we might either have a single solution vector or a
    set/list/population of vectors to deal with.

    Namely, this function allows to replace a slightly more verbose::

        was_list = utils.is_vector_list(X)
        X = X if was_list else [X]
        # work work work on X, e.g.
        res = [x[0] + 1 for x in X]
        res = res if was_list else res[0]

    with::

        X, revert = utils.as_vector_list(X)
        # work work work on X, e.g.
        res = [x[0] + 2 for x in X]
        res, ... = revert(res, ...)  # also allows to revert X, if desired

    Testing:

    >>> from cma.utilities import utils
    >>> X = [3]  # a single vector
    >>> X, revert_vlist = utils.as_vector_list(X)  # BEGIN
    >>> assert X == [[3]]  # a list with one element
    >>> # work work work on X as a list of vectors, e.g.
    >>> res = [x[0] + 1 for x in X]
    >>> X, res = revert_vlist(X, res)  # END
    >>> assert res == 4
    >>> assert X[0] == 3

    c                     | S r
   r   r8   s    r   <lambda>z as_vector_list.<locals>.<lambda>   s    Ar   c                  @    t        |       dk(  r| d   d   S d | D        S )Nr   r   c              3   &   K   | ]	  }|d      yw)r   Nr   )r#   args     r   r$   z3as_vector_list.<locals>.<lambda>.<locals>.<genexpr>   s      E<6:sCFds   r   )r   s    r   r<   z as_vector_list.<locals>.<lambda>   s/    D	Q$q'!* #< E<6:E< #<r   )r9   )Xs    r   as_vector_listrB   [   s+    F a+~s < < 	<r   c                 *    t        t        |             S )zBreturn generator ``range(len(.))`` with shortcut ``rglen(.)``
    r   r   )ars    r   rglenrF      s     R>r   c                    	 t        |       }|	 t        |      }||k(  r| S ||k  r| d| S ||kD  r+t        j                  t	        |       ||z
  | d   gz  z         S y# t        $ r | cY S w xY w# t        $ r | d   cY S w xY w)zreturn ``vec`` with the last element recycled to ``dim`` if
    ``len(vec)`` doesn't fail, else ``vec``.

    If ``dim`` is not given, ``len(as_)`` is used if available, else a
    scalar is returned.
    Nr   )r   r   r   r   list)vecdimas_len_s       r   recycledrN      s    3x {	c(C d{
	t4Cy	tzz$s)sTzc"gY&>>?? 
  

  	q6M	s"   A A. A+*A+.A?>A?c                 V    t        t        t        |             | j                  |      S )zreturn index list to get `a` in order, ie
    ``a[argsort(a)[i]] == sorted(a)[i]``, which leads to unexpected
    results with `np.nan` entries, because any comparison with `np.nan`
    is `False`.
    )keyreverse)sortedr   r   __getitem__)arQ   s     r   argsortrU      s     %A-Q]]GDDr   c                     t        |       }t        t        |            D cg c]5  }|r t        |      dz
  |j                  |      z
  n|j                  |      7 c}S c c}w )zreturn ranks of entries starting with zero based on Pythons `sorted`.

    This leads to unreasonable results with `np.nan` values.
    r   )rU   r   r   index)rT   rQ   idxis       r   ranksrZ      s^    
 !*C3s8_&$ ,3CHqL399Q<'		!D$& & &s   :Ac                 J    |D ]  }t        j                  | |         | |<    | S )zPmodify ``a[i]`` to ``round(a[i])`` for i in `indices` and return `a`, never used)r   round)rT   indicesrY   s      r   round_indicesr^      s&    xx!~! Hr   c                 X    	 | j                         S # t        $ r t        |       cY S w xY w)z@return ``a.tolist()`` if applicable else ``list(a)``, never used)tolistAttributeErrorrI   )rT   s    r   r`   r`      s+    xxz Aws    ))c              #      K   d}|t        |       k  r]| |   dk(  r@|}|t        |       k  r$| |   dk(  r|dz  }|t        |       k  r	| |   dk(  r||f |dz   }n|dz  }|t        |       k  r\yyw)a  generate increasing index pairs ``(i, j)`` with ``all(diffs[i:j] == 0)``

    and ``diffs[j] != 0 or j == len(diffs)``, thereby identifying "flat
    spots/areas" in `diffs`.

    Returns the respective generator type.

    Not anymore used to smoothen ECDFs.

    Example:

    >>> from cma.utilities.utils import zero_values_indices
    >>> for i, j in zero_values_indices([0, 0.1, 0, 0, 3.2, 0, 2.1]):
    ...     print((i, j))
    (0, 1)
    (2, 4)
    (5, 6)

    r   r   Nr@   )diffsrY   js      r   zero_values_indicesre      s     ( 	
A
c%j.8q=Ac%j.U1X]Q c%j.U1X]Q$JAAFA c%j.s   AA1A1/A1c           	      p   	 ddl }|j                  |        y# t        $ r t        | t              rkt	        d       | j                         D ]@  \  }}t	        t        |      |k(  rd|z   dz   n|dt        |      |k(  rd|z   dz   n|d       B t	        d       Y yt	        d	       t	        |        Y yw xY w)
znicely formated printr   N{':  )sep}z5could not import pprint module, appling regular print)pprintImportError
isinstancedictprintitemsstr)to_be_printedppkvs       r   rm   rm      s    ! 			-  !mT*#J%++-1s1v{cAgm'*1v{cAgm .
 #JIJ- !s    BB5B54B5c           	         | dk(  ry|dkD  st        dt        |      z        | dk  }| }t        t        j                  |             } t        t        j                  t        j                  |                   }	d|dz
  |	z
  z  }
t        j                  |
| z        |
z  }|	dz   |k\  r,t        t        |r|nt        j                  |                   }nt        |      }d}|t        |      k  r"||   dv r|dz  }|t        |      k  r||   dv r||z   |j                  d      |kD  z   }| |k7  r"t        |      |k  r|d|t        |      z
  z  z  }| |k(  r|r|d   dk(  r|dd }|d   dk(  r|d   dk(  r|dd }|rd	nd
|z   }dt        |dz
        z   dz   | z  }t        j                  |      | k(  rO|j                  d      dkD  r;|j                  d      dkD  r'|j                  dd      }|j                  d      dkD  r'|j                  dd      }|j                  dd      }|j                  d      dkD  r'|j                  dd      }|j                  d      dkD  r'|j                  d      dkD  r'|j                  dd      }|j                  d      dkD  r'|d   dk(  r|dd }|rd	nd
|z   }t        |      t        |      k  s;|j                  dd|dz   z  z         dkD  st        j                  |      d|dz   z  k\  r|}n|}|rpd
}t        |      |k  r`t        |      t        |      k  rI|}t        |||z   t        |      z
  ||||d      }t        |      |k  rt        |      t        |      k  rI|S )a  returns the shortest string representation.

    Generally, display either ``significant_digits`` digits or its true
    value, whichever is shorter.

    ``force_rounding`` shows no more than the desired number of significant
    digits, which means, e.g., ``12345``  becomes ``12000``.

    ``remove_trailing_zeros`` removes zeros, if and only if the value is
    exactly.

    ``desired_length`` adds digits up to the desired length.

    >>> from cma.utilities import utils
    >>> print([utils.num2str(val) for val in [12345, 1234.5, 123.45,
    ...       12.345, 1.2345, .12345, .012345, .0012345]])
    ['12345', '1234', '123', '12', '1.2', '0.12', '0.012', '1.2e-3']

    r   0zneed significant_digits=%s > 0
   r   )-ry   .r|   rH   r{   rj   z%.e0ez.eze+e0ze-0ze-Nz0.)desired_length)
ValueErrorrs   floatr   absintfloorlog10r\   r   findastliteral_evalreplacenum2str)valsignificant_digitsforce_roundingmax_predecimal_digitsmax_postdecimal_leading_zerosremove_trailing_zerosr   is_negativeoriginal_valueorder_of_magnitudefacval_roundedsidx1idx2s_floats_exps_rets_olds                      r   r   r      s   , ax!9123 4 	4'KN
s
CRXXbhhsm45
!A%(::
;C((39%+K A!33>Krxx}EFSVm$? :AID SVm$? :((AFF3K$,>? +1v}SD3q6M**+"7B%3,aG B%3,R5C<!BA!srQ.G 
&*+	+c	1S8A
c!affSkAoffTlQ		$$A ffTlQ			$A			$A
&&,
IIdC  &&,

&&-!
IIeT" &&-!
u|crFSR1,E
 	E
S\!TC#@1#DEEFK
{r$9A$=>>%j>)c%j3u:.EEN)N:SZG%,4,&*,E %j>)c%j3u:.E Lr   c                     t        | j                  d      |j                  d            D ]7  \  }}t        |      t        |      k  r yt        |      t        |      kD  s7 y y)z.return -1 if v1 < v2 else +1 if v1 > v2 else 0r|   rH   r   r   )zipsplitr   )v1v2n1n2s       r   version_diffr   T  sR    bhhsmRXXc]3Br7SWr7SW	 4
 r   c                      ddl m}  | j                  t        j                  j                  d             d| j                         j                  _        y)z'created a new figure without the headerr   Ng   Ј BF)	matplotlib.pyplotpyplotfigurer   randomrandintgcfcanvasheader_visible)plts    r   r   r   ]  s4    #JJryy  %&&+CGGI#r   c                 t   |t         }|/t        | xx   dz  cc<   t        |    |kD  ryt        |    |k(  r| dz  } |dk\  rzt        j                  | dj	                  t        j                         dd       z   |rdt        |      z  ndz   |rd	t        |      z  ndz   |rd
t        |      z  ndz   dz   fi | yy)z+Poor man's maxwarns: msg must match exactlyNr   & (further warnings will be suppressed)	 (time={}   	 class=%srj   
 method=%s iteration=%s))global_verbositywarnings_counterwarningswarnformattimeasctimers   )msgmethod_name
class_name	iterationverbosemaxwarnskwargs_for_warns          r   print_warningr   e  s     ""C 8+C H,;;C"}cK..t||~ab/ABB0:{S_,D2=|c+..2G 4=Y/"F 	 	& %		& r   c                 8   |/t         | xx   dz  cc<   t         |    |kD  ryt         |    |k(  r| dz  } | dj                  t        j                         dd       z   |rdt	        |      z  ndz   |rdt	        |      z  ndz   |rd	t	        |      z  z   d
z   S dz   d
z   S )a~  Poor man's maxwarns: msg must match exactly.

    Copy-paste of `print_warning` to get better location information than
    `print_warning`. Calling `warnings.warn` here makes the warning
    location information meaningless, hence we format only a string here.
    Usage could be like::

        m = utils.format_warning(some_message
                ); m and warnings.warn(m)

    Nr   rj   r   r   r   r   r   r   r   )r   r   r   r   rs   )r   r   r   r   r   s        r   format_warningr   v  s     "C 8+C H,;;C+$$T\\^AB%788.8[3z?*bB0;\C,,E 2;_s9~-D 	  ACD 	 r   c                     |t         }|dk\  rIt        d|rdt        |      z   ndz   |rdt        |      z   ndz   |dt        |      z   ndz   dz   |        y y )Nr   zNOTE (module=cmaz, class=rj   z	, method=z, iteration=z): )r   rq   rs   )r   r   r   r   r   s        r   print_messager     sz    "!| /9zC
O+rC1<{S--"F 3<2G~I.RQ 	 		 r   c                     |r| dj                  |j                        z   } d}d|dz  z   }t        |       D ]*  \  }}||z   }|dk(  s||dz   kD  s|dv s|dz   |dz  z   }|}, |dz   }|S )z)put line breaks and trailing white spacesz [iteration={0}]r   z

 
F   )r   )r   	countiter	enumerate)r   esspacesrd   r   rY   cs          r   format_messager     s    	&--bll;;	A#A#1E9AF
qEzD6C<'AA	 
 	
DAHr   c                     |r7t        | ||j                                t        | |      j                  dd       |j	                         D ]  \  }}|dk7  st        | ||        y)a@  assign, for example, all arguments given to an ``__init__``
    method to attributes in ``self`` or ``self.params`` or ``self.args``.

    If ``initial_params_dict_name`` is given, ``dict_`` is also copied
    into an attribute of ``self`` with name ``initial_params_dict_name``::

        setattr(self, initial_params_dict_name, dict_.copy())

    and the ``self`` key is removed from the copied `dict` if present.

    >>> from cma.utilities.utils import set_attributes_from_dict
    >>> class C(object):
    ...     def __init__(self, arg1, arg2, arg3=None):
    ...         assert len(locals()) == 4  # arguments are locally visible
    ...         set_attributes_from_dict(self, locals())
    >>> c = C(1, 22)
    >>> assert c.arg1 == 1 and c.arg2 == 22 and c.arg3 is None
    >>> assert len(c.__dict__) == 3 and not hasattr(c, 'self')

    Details:

    - The entry ``dict_['self']`` is always ignored.

    - Alternatively::

        self.args = locals().copy()
        self.args.pop('self', None)  # not strictly necessary

      puts all arguments into ``self.args: dict``.

    selfN)setattrcopygetattrpoprr   )r   dict_initial_params_dict_namerP   r   s        r   set_attributes_from_dictr     sZ    @  .

=./33FDAKKMS&=D#s# "r   c                 B   dd l }|,| j                  t        j                  j                        d   }t        t        j                  j                  ||      d      5 }|j                  |j                  |       j                                d d d        y # 1 sw Y   y xY w)Nr   rH   wb)
urllib2r   ospathrk   openjoinwriteurlopenread)url
target_dirtarget_namer   fs        r   download_filer     sk    ii,R0	bggll:{3T	:a	$))+, 
;	:	:s   /BBc           	         ddl }d}|+|j                  j                  |       j                  |       yddl}|j                  j                  |       j                  |       |j                  t        j                  j                  ||      t        j                  j                  ||j                  t        j                  j                        d                |j                  |       y)z(filename must be a valid path in the tarr   Nz._tmp_rH   )tarfileTarFilegzopen
extractallshutilcopy2r   r   r   r   rk   rmtree)tarnamefilenamer   r   tmp_dirr   s         r   extract_targzr     s    Gw'22:>w'227;RWW\\'84WW\\*hnnRWW[[.I".MN	Pgr   c                       e Zd ZdZy)
BlancClassae  blanc container class to have a collection of attributes.

    For rapid shell- or prototyping. In the process of improving the code
    this class might/can/will at some point be replaced with a more
    tailored class.

    Usage:

    >>> from cma.utilities.utils import BlancClass
    >>> p = BlancClass()
    >>> p.value1 = 0
    >>> p.value2 = 1

    N)__name__
__module____qualname____doc__r   r   r   r   r     s    r   r   c                       e Zd ZdZd Zd Zy)	DictClassa  A class wrapped over `dict` to use class .-notation.

    Not clear whether tab completion works?

    >>> from cma.utilities.utils import DictClass
    >>> dict_ = dict((2 * char, char) for char in 'abcd')
    >>> d = DictClass(dict_)
    >>> assert d.__dict__ == dict_ == d
    >>> assert d.aa == 'a' and len(d) == 4
    >>> d.new = 33
    >>> assert 'new' in d
    >>> d['nnew'] = 44
    >>> assert d.nnew == 44
    >>> assert len(d) == 6

c                 D    t        j                  | g|i | | | _        y r
   )rp   __init____dict__)r   r   r   s      r   r  zDictClass.__init__  s    d,T,V,r   c                 "    | j                         S r
   )keysr   s    r   __dir__zDictClass.__dir__  s    yy{r   N)r   r   r   r   r  r  r   r   r   r  r    s     r   r  c                       e Zd ZdZd Zy)
DictClass2a   A dictionary that allows `.` attribute read access of its entries.

    Assigning an attribute instead of the dictionary entry does not assign
    (or create) a dictionary value and separates the attribute value from
    the dictionary value permanently (in contrast to `DictClass`). This may
    be useful to let the dictionary entry store the initial value and work
    with the attribute value only, to access the current and possibly
    changed value.

    If neither the attribute nor the dictionary entry exist, an attempted
    attribute access raises an `AttributeError` as to be expected.

    By design, this class DOES NOT HAVE INTERACTIVE TAB COMPLETION for
    attributes derived from the dictionary!?

    Implementation detail: this class is less "intrusive" than `DictClass`
    and should be entirely safe from under-the-hood surprises. It only
    relies on the behavior of `__getattr__`: access of a nonexisting
    attribute triggers (by Python convention) a call of `__getattr__`
    which is here defined to return the dictionary entry value.

    >>> from cma.utilities.utils import DictClass2
    >>> d = DictClass2((2 * char, char) for char in 'abcd')
    >>> list(d)
    ['aa', 'bb', 'cc', 'dd']
    >>> assert d.aa == 'a' and len(d) == 4, (list(d.values()), d.__dict__)
    >>> d.new = 33  # does not go in the dict
    >>> assert 'new' not in d and len(d) == 4, (list(d.values()), d.__dict__)
    >>> d['new'] = 55
    >>> assert (d.new, d['new']) == (33, 55)
    >>> d['nnew'] = 44
    >>> assert d.nnew == 44
    >>> assert len(d) == 6

c                 \    || vr$t        dj                  |t        |                   | |   S )z8called when ``self.name`` would raise an attribute errorz-`{0}` is not an attribute. Attributes are {1})ra   r   rI   )r   names     r   __getattr__zDictClass2.__getattr__,  s4    t !P"(&tDz":< <Dzr   N)r   r   r   r   r  r   r   r   r
  r
    s    "Fr   r
  c                   F     e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
 xZS )	DerivedDictBaseas  for conveniently adding methods/functionality to a dictionary.

    The actual dictionary is in ``self.data``. Derive from this
    class and copy-paste and modify setitem, getitem, and delitem,
    if necessary.

    Details: This is the clean way to subclass the build-in dict, however
    it depends on `MutableMapping` (since 2.6 but has significantly evolved).

    c                    t         t        |           t        j                  dk\  rt        |i || _        y 	 t        j                         | _        | j                  j                  t        j                  |i |       y # t        $ r6 t               | _        | j                  j                  t        |i |       Y y w xY w)N)      )superr  r  sysversion_inforp   datacollectionsOrderedDictupdate	Exceptionr   r   r   	__class__s      r   r  zDerivedDictBase.__init__>  s    ot-/v%d-f-DI8'335			  !8!8$!I&!IJ 8 F			  t!6v!678s   AB <C ?C c                 ,    t        | j                        S r
   )r   r  r  s    r   __len__zDerivedDictBase.__len__K  s    499~r   c                     || j                   v S r
   r  r   rP   s     r   __contains__zDerivedDictBase.__contains__M  s    diir   c                 ,    t        | j                        S r
   )iterr  r  s    r   __iter__zDerivedDictBase.__iter__O  s    DIIr   c                 "    || j                   |<   y)define ``self[key] = value``Nr   )r   rP   values      r   __setitem__zDerivedDictBase.__setitem__Q  s    		#r   c                      | j                   |   S zdefine access ``self[key]``r   r!  s     r   rS   zDerivedDictBase.__getitem__T  s    yy~r   c                     | j                   |= y r
   r   r!  s     r   __delitem__zDerivedDictBase.__delitem__W  s    IIcNr   )r   r   r   r   r  r  r"  r%  r)  rS   r-  __classcell__r  s   @r   r  r  3  s+    	8 r   r  c                   R     e Zd ZdZ fdZd Z fdZd Zd Zd Z	d Z
d
d	Z xZS )SolutionDicta  dictionary with computation of an hash key.

    The hash key is generated from the inserted solution and a stack of
    previously inserted same solutions is provided. Each entry is meant
    to store additional information related to the solution.

    >>> import cma.utilities.utils as utils, numpy as np
    >>> d = utils.SolutionDict()
    >>> x = np.array([1,2,4])
    >>> d[x] = {'f': sum(x**2), 'iteration': 1}
    >>> assert d[x]['iteration'] == 1
    >>> assert d.get(x) == (d[x] if d.key(x) in d.keys() else None)
    >>> y = [1,2,4]
    >>> d[y] = {'f': sum([n ** 2 for n in y]), 'iteration': 1}
    >>> assert d[y]['iteration'] == 1
    >>> assert d.get(y) == (d[y] if d.key(y) in d.keys() else None)
    >>> d[2] = 3
    >>> assert d[2] == 3

    `data_with_same_key` behaves (in contrast to the order of ``keys()``)
    like a stack (see setitem and delitem). Thereby the last assignment
    ``self[key] = ...`` determines, as to be expected, the value of
    ``self[key]`` even when ``self.data_with_same_key[key]`` is not empty.
    If the attribute `behave_as_queue` is set to True, it behaves like a
    queue (FIFO).

    Technical detail: after a same-key item was removed, ``self[key]``
    returns the stacked (or queued) previous value, however
    ``self._unhashed_keys[key]`` still returns the last unhashed key which
    could be a different object than the previous but with the same hash
    key. However, the object has most likely the correct content because
    the hash was the same. This happens because only the last unhashed key
    is kept. As long as the content of ``self._unhashed_keys[key]`` is not
    changed, this should be fine.

    TODO: in `.truncate`, the iteration key is used to clean up without
    error management.

    c                 d    t        t        | 
  |i | i | _        i | _        d| _        d| _        y )Nr   F)r  r1  r  data_with_same_key_unhashed_keyslast_iterationbehave_as_queuer  s      r   r  zSolutionDict.__init__  s7    lD*D;F;"$ $r   c                 |   t        |t              r|S t        |t        j                        r	 t	        |j                               S 	 t	        |      S # t        $ r< |j                  dk  rt	        t        |            cY S t	        t        |            cY S w xY w# t        $ r t	        t        |            cY S w xY w)zcompute key of ``x``g     @)ro   r   r   ndarrayhashtobytesra   sizetuplebytesr   )r   r   s     r   rP   zSolutionDict.key  s    aH2::&*AIIK((&Aw " *66C<a>)a>)	*  &E!H~%&s)   A 
B ,BBBB;:B;c                 H    t         t        |   | j                  |            S r
   )r  r1  r"  rP   )r   rP   r  s     r   r"  zSolutionDict.__contains__  s    \45dhhsmDDr   c                    || j                  |      }}|| j                  |<   | j                  r]|| j                  vr|| j                  |<   y|| j                  vr|g| j                  |<   y| j                  |   j                  d|       y|| j                  v r&| j                  |xx   | j                  |   gz  cc<   n+|| j                  v r| j                  |   g| j                  |<   || j                  |<   y)r'  r   N)rP   r4  r6  r  r3  insert)r   rP   r(  unhashed_keys       r   r)  zSolutionDict.__setitem__  s    #c#/C $))#!&		#D33305w'','',33Au=d---'',30@@,		!04		#/?'',"DIIcNr   c                 >    | j                   | j                  |         S r+  )r  rP   r!  s     r   rS   zSolutionDict.__getitem__  s    yy#''r   c                    | j                  |      }|| j                  v rst        | j                  |         dk(  r,| j                  j                  |      d   | j                  |<   y| j                  |   j                  d      | j                  |<   y|| j                  v r)|| j
                  v r| j
                  |= | j                  |= yy)z9remove only most current key-entry of list with same keysr   r   rH   N)rP   r3  r   r   r  r4  r!  s     r   r-  zSolutionDict.__delitem__  s    hhsm$)))4**3/0A5!%!8!8!<!<S!A!!D		#!%!8!8!=!A!A"!E		#DIId)))'',		# r   c                     t        |       |k  ry|dk(  r| j                          yt        | j                               D ]  }| |= t        |       |k  s y y)z5truncate to length `len_` removing the oldest entriesNr   r   clearrI   r  )r   rM   rv   s      r   truncate_tozSolutionDict.truncate_to  sO    t919JJLdiik"AQ4yD  #r   c                     t        |       |k  ry|dk(  r| j                          yt        | j                               D ]%  }|| |   d   |k  r| |= t        |       |dz  k  s% y y)a$  truncate to ``max_len/2`` when ``len(self) > max_len``.

        Only truncate entries with ``'iteration'`` key smaller than
        `min_iter` if given.

        This looks overdesigned given the `dict` is ordered and chunk
        deletion is not available. See also `truncate_to`.
        Nr   r      rE  )r   max_lenmin_iterrv   s       r   truncatezSolutionDict.truncate  sk     t9a<JJLdiik"A47;#7(#BG4y7Q;& #r   r
   )r   r   r   r   r  rP   r"  r)  rS   r-  rG  rL  r.  r/  s   @r   r1  r1  Z  s2    &N%&&E#"(r   r1  c                   :    e Zd ZdZd	dZd Zd ZefdZd Z	d Z
y)
DataDictza dictionary of lists (of data)c                 6   || _         t        j                  j                  | t               t
        j                  j                  | j                         r| j                          y t        dj                  | j                                | j                          y )Nzcreating file {0})r   r  defaultdictr  rI   r   r   existsloadrq   r   save)r   r   s     r   r  zDataDict.__init__  s]     ((t477>>$--(IIK%,,T]];<IIKr   c                     t        | j                  d      5 }t        j                  |j	                               }ddd       | j                         | S # 1 sw Y   xY w)zelement-wise append/merge data of loaded `dict` to self,

        by calling `update`.

        To load cleanly without merge use `clear` + `load` or the class
        constructor with a new `filename`.
        rtN)r   r   r   r   r   r  )r   r   dds      r   rR  zDataDict.load  sH     $--&!!!!&&(+B 'B '&s   $AAc                 4    |D ]  }| |xx   ||   z  cc<    | S )z4append data of entries in `dict_` to entries in selfr   )r   r   rv   s      r   r  zDataDict.update  s#    AGuQxG r   c                 z    | D ]5  }t        t        | |               D ]  } || |   |   ||      | |   |<    7 | S )zreplace all entries with the return value of `replace_function`.

        The `replace_function` gets the original value, the key, and the
        list index as arguments.
        )rP   rW   rD   )r   replace_functionrv   rY   s       r   r   zDataDict.replace  sJ     A3tAw<(-d1gajaqIQ
 )  r   c                     t        | j                  d      5 }|j                  t        t	        |                    d d d        y # 1 sw Y   y xY w)Nwt)r   r   r   reprrp   )r   r   s     r   rS  zDataDict.save  s3    $--&!GGDd$% '&&s   $AAc                 @    | D cg c]  }| c}D ]  }| |=  | S c c}w r
   r   )r   rv   rP   s      r   rF  zDataDict.clear  s,    #$t!At$CS	 % %s   	N)z_data.py)r   r   r   r   r  rR  r  r   r   rS  rF  r   r   r   rN  rN    s(    ) (+ 	&r   rN  c                       e Zd ZdZd Zy)ExclusionListOfVectorsz'For delayed selective mirrored samplingc           	          | D ]l  }dt        j                  ||      t        t        j                  |      dz        t        t        j                  |      dz        z  dz  z  cxk  rdk  sj y n y)Ngv?rI  g      ?g0D   ?TF)r   dotsumr   )r   rJ   rw   s      r   r"  z#ExclusionListOfVectors.__contains__  sh    A"&&C.C

1q0@,AC

SVYZHZD[,[^a+aaldll m  r   N)r   r   r   r   r"  r   r   r   r_  r_    s
    1r   r_  c                   j    e Zd ZdZddZd Zd Zd Zed        Z	ed        Z
ed        Zed	        Zy
)ElapsedWCTimea  measure elapsed cumulative time while not paused since creation.

    To control the timer, use attribute `tic` and methods `pause` () and
    `reset` (). To see timing results, use attributes `toc` (since last
    `tic`) and `elapsed` (since creation).

    >>> import cma
    >>> e = cma.utilities.utils.ElapsedWCTime().pause()  # (re)start later
    >>> assert e.paused and e.elapsed == e.toc < 0.1
    >>> assert e.toc == e.tic < 0.1  # timer starts here
    >>> assert e.toc <= e.tic  # toc is usually a few microseconds smaller
    >>> assert not e.paused    # the timer is now running due to tic

    Details: the attribute ``paused`` equals to the time [s] when paused or
    to zero when the timer is running.
    c                 T    || _         | j                          | j                  | _        y)z+add time offset in seconds and start timingN)_time_offsetreset_time_at_reset_time_at_creation)r   time_offsets     r   r  zElapsedWCTime.__init__*  s!    '

!%!4!4r   c                     | j                   | _        d| _        	 t        j                         | _        | j                  | _        | j                  | _        | S )z'reset to initial state and start timingr   )rf  cum_timepausedr   last_tic	_last_tocrh  r  s    r   rg  zElapsedWCTime.reset/  sB    ))1		"mmr   c                 P    | j                   st        j                         | _         | S )zpause timer, resume with `tic`)rm  r   r  s    r   pausezElapsedWCTime.pause8  s    {{))+DKr   c                     t               )zFdepreciated return elapsed time (for backwards compatibility)
        )DeprecationWarningelapsedr  s    r   __call__zElapsedWCTime.__call__=  s     !""r   c                    | j                   }| j                  r}| j                  | j                  k  r7t        d| j                  | j                  fz  dd       | j                  | _        | xj                  | j                  | j                  z
  z  c_        n4| xj                  t        j
                         | j                  z
  z  c_        d| _        t        j
                         | _        |S )zgreturn `toc` and restart tic/toc last-round-timer.

        In case, also resume from `pause`.
        z~paused time=%f < last_tic=%f, which
                should never happen, but has been observed at least once.
                ticrd  r   )tocrm  rn  r   rl  r   )r   return_s     r   rw  zElapsedWCTime.ticB  s     ((;;{{T]]* {{DMM23 $_6 #mmMMT[[4==88MMMTYY[4==88M		r   c                 4    | j                   | j                  z   S )zhelapsed time since last `reset` while not paused.

        Details: this triggers a `toc` call.
        )rl  rx  r  s    r   rt  zElapsedWCTime.elapsedV  s     }}txx''r   c                     t        j                          | _        | j                  r| j                  | j                  z
  S | j                  | j                  z
  S )z-elapsed time since last `tic` or `pause` call)r   ro  rm  rn  r  s    r   rx  zElapsedWCTime.toc]  s>     ;;;;..~~--r   c                 4    | j                   | j                  z
  S )zOnever used: time between last `reset` and last `toc` (i.e. last usage)
        )ro  rh  r  s    r   	wallclockzElapsedWCTime.wallclockd  s     ~~ 3 333r   N)r   )r   r   r   r   r  rg  rq  ru  propertyrw  rt  rx  r}  r   r   r   rd  rd    sk     5


  & ( ( . . 4 4r   rd  c                       e Zd ZdZd Zd Zy)TimingWrapperzwrap a timer around a callable.

    Attribute ``timer`` collects the timing data in an `ElapsedWCTime`
    class instance, in particular the overall elapsed time in
    ``timer.elapsed`` and the time of the last call in ``timer.toc``.
    c                 L    || _         t               j                         | _        y)z7``callable_`` is the `callable` to be timed when calledN)	_callablerd  rq  timer)r   	callable_s     r   r  zTimingWrapper.__init__q  s    ""_**,
r   c                     | j                   j                    | j                  |i |}| j                   j                          |S r
   )r  rw  r  rq  )r   r   r   ress       r   ru  zTimingWrapper.__call__u  s7    

dnnd-f-


r   Nr   r   r   r   r  ru  r   r   r   r  r  j  s    -r   r  c                   n     e Zd ZdZ fdZ	 	 d	 fd	Zed        Zd Zed        Z	ed        Z
d Z xZS )
DictFromTagsInStringa  read from a string or file all key-value pairs within all
    ``<python>...</python>`` tags and return a `dict`.

    Within the tags valid Python code is expected: either a list of
    key-value pairs ``[[key1, value1], [key2, value2], ...]`` or a
    dictionary ``{ key1: value1, key2: value2, ...}``. A key can be any
    immutable object, while it is often a string or a number.

    The `as_python_tag` attribute provides the respective (tagged) string.
    The ``tag_string`` attribute defines the tag identifier, 'python' by
    default, and can be change if desired at any time.

    >>> from cma.utilities.utils import DictFromTagsInString
    >>> s = '<python> [[33, 44], ["annotations", [None, 2]]] </python>'
    >>> s += '<python> {"annotations": [2, 3]} </python>'
    >>> d = DictFromTagsInString(s)
    >>> # now d.update can be used to read more tagged strings/files/...
    >>> assert d.tag_string == 'python'  # can be set to any other value
    >>> d.tag_string = 'pyt'
    >>> # now 'pyt' tags can/will be read (only)
    >>> assert str(d).startswith('<pyt>{') and str(d).endswith('}</pyt>')
    >>> assert len(d) == 2 and d[33] == 44 and d['annotations'] == [2, 3]

    When the same key appears several times, its value is overwritten.
    c                     t         t        |           d| _        t	        |      st	        |      r | j
                  |i | yy)z#for input args see `update` method.pythonN)r  r  r  
tag_stringr   r  r  s      r   r  zDictFromTagsInString.__init__  s=    "D24"t9FDKK(( $r   c                 R   d|du |du z   |du z   |du z   z
  }|st        d      |dkD  rt        d      ||| _        |t        |d      j                         }n*||j                         }n|t        t
        |   |       | S t        t
        |   | j                  |             | S )zonly one of the first four arguments is accepted at a time,
        return ``self``.

        If the first argument has no keyword, it is assumed to be a string
        to be parsed for tags.
        r   Nznothing to updater   zs
                use either string_ or filename or file_ or dict_ as
                input, but not several of themr)r   r  r   r   r  r  r  _eval_python_tag)r   string_r   file_r   r  r   r  s          r   r  zDictFromTagsInString.update  s     W_T)9:"'4-1 2455!8 2 3 3 !(DO8S)..0GjjlG&$K"	009:r   c                 ^    | j                   t        t        |             z   | j                  z   S r
   )_startr\  rp   _endr  s    r   as_python_tagz"DictFromTagsInString.as_python_tag  s#    {{T$t*--		99r   c                     | j                   S r
   )r  r  s    r   __repr__zDictFromTagsInString.__repr__  s    !!!r   c                 &    d| j                   z   dz   S )N<>r  r  s    r   r  zDictFromTagsInString._start  s    T__$s**r   c                 &    d| j                   z   dz   S )Nz</r  r  r  s    r   r  zDictFromTagsInString._end  s    doo%++r   c                    i }|j                         }|j                  | j                        }|dk\  r|t        | j                        z  }|j                  | j                  |      }|j                  t        j                  ||| j                                      |j                  | j                  |dz         }|dk\  r|S )a  read [key, value] pairs from a `list` or a `dict` within all
        ``<self.tag_str>`` tags in ``str_`` and return a `dict`.

        >>> from cma.utilities.utils import DictFromTagsInString
        >>> s = '<py> [[33, 44], ["annotations", []]] </py>'
        >>> s += '<py>[["annotations", [1,2,3]]] </py>'
        >>> d = DictFromTagsInString()
        >>> assert len(d) == 0
        >>> d.update(s)  # still empty as default tag is not <py>
        <python>{}</python>
        >>> assert len(d) == 0
        >>> d.tag_string = "py"  # set desired tag
        >>> d.update(s)  # doctest:+ELLIPSIS
        <py>{...
        >>> assert len(d) == 2
        >>> assert d[33] == 44 and len(d["annotations"]) == 3

        r   r   )	lowerr   r  r   r  r  r   r   strip)r   str_values	str_lowerstartends         r   r  z%DictFromTagsInString._eval_python_tag  s    & JJL	t{{+qjS%%E..E2CMM#**4c?+@+@+BCDNN4;;	:E	 qj
 r   NNNNN)r   r   r   r   r  r  r~  r  r  r  r  r  r.  r/  s   @r   r  r  {  s^    2) EI< : :"+ +, ,r   r  c                       e Zd ZdZd Zd Zy)MoreToWritez0make sure that this list does not grow unboundedc                     g | _         y r
   )_lenhistr  s    r   r  zMoreToWrite.__init__  s	    r   c                     | xj                   t        |       gz  c_         t        | j                         dkD  r8t        t        j                  | j                         dkD        r| d d = g | _         y y )Nr  r   )r  r   r   r   diffr  s    r   checkzMoreToWrite.check  sT    #d)$t}}!2774==)A-.GDM "r   N)r   r   r   r   r  r  r   r   r   r  r    s    :r   r  c                   (    e Zd ZdZd Zd Zd Zd Zy)DefaultSettingsa   resembling somewhat `types.SimpleNamespace` from Python >=3.3
    but with instantiation and resembling even more the `dataclass` decorator
    from Python >=3.7.

    ``MyClassSettings(DefaultSettings)`` is preferably used by assigning a settings
    attribute in ``__init__`` like:

    >>> class MyClass:
    ...     def __init__(self, a, b=None, param1=None, c=3):
    ...         self.settings = MyClassSettings(locals(), 1, self)

    The `1` signals, purely for consistency checking, that one parameter defined
    in ``MyClassSettings`` is to be set from ``locals()``. ``MyClassSettings``
    doesn't use any names which are already defined in ``self.__dict__``. The
    settings are defined in a derived parameter class like

    >>> from cma.fitness_models import DefaultSettings
    >>> class MyClassSettings(DefaultSettings):
    ...     param1 = 123
    ...     val2 = False
    ...     another_par = None  # we need to assign at least None always

    The main purpose is, with the least effort, (i) to separate
    parameters/settings of a class from its remaining attributes, and (ii) to be
    flexible as to which of these parameters are arguments to ``__init__``.
    Parameters can always be modified after instantiation. Further advantages
    are (a) no typing of ``self.`` to assign the default value or the passed
    parameter value (the latter are assigned "automatically") and (b) no
    confusing name change between the passed option and attribute name is
    possible.

    The class does not allow to overwrite the default value with `None`.

    Now any of these parameters can be used or re-assigned like

    >>> c = MyClass(0.1)
    >>> c.settings.param1 == 123
    True
    >>> c = MyClass(2, param1=False)
    >>> c.settings.param1 is False
    True

    c                     t        |      | _        || _        || _        | j                  j	                  dd       | j                          | j                          y)a  Overwrite default settings in case.

        :param params: A dictionary (usually locals()) containing the parameters to set/overwrite
        :param number_of_params: Number of parameters to set/overwrite
        :param obj: elements of obj.__dict__ are in the ignore list.
        r   N)rp   inparams_number_of_paramsobjr   _set_from_defaults_set_from_input)r   paramsnumber_of_paramsr  s       r   r  zDefaultSettings.__init__  sJ     V!1&$'!r   c                 Z    ddj                  d | j                         D              z   dz   S )Nrg   r   c              3   T   K   | ]   \  }}t        |      d t        |       " yw)ri   N)rs   )r#   rv   rw   s      r   r$   z*DefaultSettings.__str__.<locals>.<genexpr>(  s"     VASVSV <s   &(rl   )r   rr   r  s    r   __str__zDefaultSettings.__str__&  s(    diiVVVVY\\]r   c                     | j                   j                  d t        |       j                   j                         D               y)z,defaults are taken from the class attributesc              3   L   K   | ]  \  }}|j                  d       s||f  yw)_N)r0   )r#   rP   r   s      r   r$   z5DefaultSettings._set_from_defaults.<locals>.<genexpr>,  s,      :0K*3%(^^C%8  #Cj0Ks   "$N)r  r  typerr   r  s    r   r  z"DefaultSettings._set_from_defaults*  s4     :04T
0C0C0I0I0K: 	;r   c           	         i }t        | j                        D ]q  }|| j                  vs|| j                  j                  v r| j                  j	                  |      ||<   H| j                  |   Xt        | || j                  |          s t        | j                        | j                  k7  rTt        j                  dt        t        |             | j                  t        | j                        t        |      fz         t        | d       y)aQ  Only existing parameters/attributes and non-None values are set.

        The number of parameters is cross-checked.

        Remark: we could select only the last arguments
        of obj.__init__.__func__.__code__.co_varnames
        which have defaults obj.__init__.__func__.__defaults__ (we do
        not need the defaults)
        Nz8%s: %d parameters desired; remaining: %s; discarded: %s r  )rI   r  r  r  r   r   r   r  r   r   rs   r  delattr)r   	discardedrP   s      r   r  zDefaultSettings._set_from_input/  s     	&C$--'3$((2C2C+C!%!2!23!7	#s#/c4==#56	 '
 t}}!7!77MMT d_d.D.Dc$--FX ^-- . 	er   N)r   r   r   r   r  r  r  r  r   r   r   r  r    s    *V^;
r   r  c                       e Zd ZdZd Zd Zy)ListOfCallablesal  A `list` of callables that can be called like a single `callable`.

    The simplest usecase of this minitool is single-shot usage like::

        res = ListOfCallables(callable_or_list_of_callables)(args)

    as a one-line simplification of either::

        if callable(callable_or_list_of_callables):
            res = [callable_or_list_of_callables(args)]
        else:
            res = [c(args) for c in callable_or_list_of_callables]

    or::

        try:
            res = [c(args) for c in callable_or_list_of_callables]
        except TypeError:
            res = [callable_or_list_of_callables(args)]

    c                     || _         |g }t        |      r|g}	 |D ]$  }t        |      rt        dt        |      z         	 t
        j                  | |       y# t        $ r t        dt        |      z        w xY w)a  return a list of callables as a `callable` itself.

        ``callback`` can be a `callable` or a `list` (or iterable) of
        callables. Otherwise a `ValueError` exception is raised.

        Possible usecase: termination callback(s) of CMA-ES::

            self.opts['termination_callback'](self)

        becomes::

            ListOfCallables(self.opts['termination_callback'])(self)

        Nz<callback argument %s is not
                        callablezcallback argument must be a `callable` or
                an iterable (e.g. a list) of callables, after some
                processing it was %s)_input_callbackcallabler   rs   r   rI   r  )r   callbackr   s      r   r  zListOfCallables.__init__\  s      (HH zH	9{$ &$&)!f&- . .  	dH%	  	9 (*-h-8 9 9	9s   A A !A=c                     | D cg c]
  } ||i | }}ddk  r| j                   t        |      dk(  sJ yddk  r<t        | j                         r't        |       t        |      cxk(  rdk(  sJ  J |d   S |S c c}w )zIcall each element of the list and return a list of return values
           r  Nr   r   )r  r   r  )r   r   r   r   r  s        r   ru  zListOfCallables.__call__{  s     ,004aq$!&!406d**2s8q= =6ht334t9C-A-----q6M
 1s   A;Nr  r   r   r   r  r  F  s    *&>
r   r  c                   :    e Zd ZdZdZddZ	 	 	 	 d	dZd
dZd Zy)ShowInFoldera*  callable instance to save and show figures from `matplotlib`.

    Saves figures to a folder ``'figs-...'`` with incremental filenames
    allowing to conveniently view and compare these figures.

    Each call of the instance saves the current `matplotlib` figure and
    switches the focus to the save folder by calling the `open_path`
    method.

    Example::

        >> import cma, matplotlib.pyplot as plt
        >> show = cma.utilities.utils.ShowInline('01')  # use './figs-01' folder
        >>
        >> plt.plot([1,2,3])
        >> show()  # save current plot with a unique name in figs-01 folder
        >>         # and switch focus to the folder

    Under macOS, `open_path` invokes Finder where the figures can be
    conveniently explored and compared using the space and up/down keys.
    zfigs-c                    t         j                  |z   | _        	 | _        d| _        	 || _        	 || j
                  d<   d| _        	 t        j                  j                  | j                        r]t        fdt        j                  | j                        D              }|r)t        |d   j                  dz         d         | _        yyy)zsave figures to folder ``'figs-' + name``.

        pdf are smaller than png and not pixeliated. The type can be
        changed at any time be reassigning the `type` attribute.

        `dpi` and `kwargs` are passed to `plt.savefig`.
        z{0:04d}.dpir   c              3      K   | ]A  }|d    t        d      D cg c]  }t        |       c}v r|j                  dz         r| C yc c}w w)r   rz   r|   N)r   rs   endswith)r#   nrY   r  s      r   r$   z(ShowInFolder.__init__.<locals>.<genexpr>  sP      W#8atb	:	1A	::qzz#PT*?U #8:s   AA
$ArH   r|   N)r  folder_prefixr   r  format_stringr   numberr   rQ  rR   listdirr   r   )r   r  r  r  r   lss     `   r   r  zShowInFolder.__init__  s     "//$6	 	'$' E@77>>$))$ W2::dii#8 W WB!"R&,,sTz":1"=>  %r   Nc                    |rddl m} t        j                  j	                  | j                        si| j
                  dk7  r;t        j                  | j                  dj                  | j
                        z          t        j                  | j                         |G| xj
                  dz  c_        | j                  j                  | j
                        | j                  z   }t        j                  j                  | j                  |      }|rJ|j                         j                         }	|j                         j                  |||	d   z  |	d   z          |j                   |fddi| j"                   || _        |xs |j'                          |xr | j)                          | j
                  r|r| j+                  |       | S )zsave current figure and show folder and/or image in notebook.

        Uses `IPython.display.Image` to show the image in the notebook.
        r   )r   z= not found even though number={0} (which should ever happen).r   bbox_inchestight)
matplotlibr   r   r   rQ  r  r   r   r   mkdirr  r  r   r   get_size_inchesset_size_inchessavefigr   _last_savedclose	open_pathshow_in_notebook)
r   keepr  show_in_folderrS  
width_save
width_showr  r   old_sizes
             r   ru  zShowInFolder.__call__  sZ    077>>$)),;;!#MM$)) /X#)6$++#6#7 8 #|q ))00=		I77<<		40D779446	))**4x{*BXa[*PR CKKA'AT[[A#DCIIK+4>>+;;+!!*-r   c                     	 ddl } |j                  j                  | j                  fd|i|S #  t	        dj                  | j                               Y yxY w)z=display last saved figure in notebook (doesn't work with pdf)r   Nwidthz{0} could not be displayed)IPython.displaydisplayImager  rq   r   )r   r  kwargs_showIPythons       r   r  zShowInFolder.show_in_notebook  sT    	I"(7??(()9)9VV+VV	I.55d6F6FGHs	   ,/ &Ac                 H    t        j                  d| j                  z          y )Nzopen )r   systemr   r  s    r   r  zShowInFolder.open_path  s    
		'DII%&r   )pdfi  )TFTTNNNr
   )	r   r   r   r   r  r  ru  r  r  r   r   r   r  r    s2    * M?2 .3+/-1	 DI'r   r  )NN)F)rI  F   r   TNr  )NNNN)N   r
   )r|   N)Nr|   )Br   
__future__r   r   r   r   r  r   r   r   numpyr   r  python3for2r   r   r   r   r   r   r   r*   r.   r2   r5   r9   rB   rF   rN   rU   rZ   r^   r`   re   rm   r   r   r   rP  r   r   r   r   r   r   r   r   r   objectr   rp   r  r
  MutableMappingr  r1  rN  rI   r_  rd  r  r  r  r  r  r  r   r   r   <module>r     s   3     
   #X~ &(--&
'<R
@.E&>!( 7<CD7;aF, +;**3/ DH*.&" FJ 0 EI	%$N-   .) )V%c(( %NC? CJ0{&& 0dT O4F O4bF "d4 dL	$ 	Xf Xt?d ?BZ'6 Z'r   