B
    [/                 @   s   d Z ddlmZm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dlmZmZ G dd deZd d	d
Zdd Zeedd d ZeejddZg adadd Zdd Zd!ddZd"ddZdd Zdd Z d#ddZ!dS )$z:Miscellaneous stuff that doesn't really fit anywhere else.    )print_functiondivisionN)filldedent)get_function_namerangec               @   s   e Zd ZdS )UndecidableN)__name__
__module____qualname__ r   r   3lib/python3.7/site-packages/sympy/utilities/misc.pyr      s   r   F   c             C   s   dt tt| d|d S )a)  
    Strips leading and trailing empty lines from a copy of `s`, then dedents,
    fills and returns it.

    Empty line stripping serves to deal with docstrings like this one that
    start with a newline after the initial triple quote, inserting an empty
    line at the beginning of the string.
)width)r   r   strstrip)swr   r   r   
filldedent   s    r   c             C   s   |  d}t|dkr"t|d S d| kd| kg}tdd |D sTd| ksTt|rd	g}| d}t|d }xJt|D ]>\}}||ks|r|t|d
d d  qz|t| qzW d|d S d|}|d rd| S d| S d
S )a  Return a cut-and-pastable string that, when printed, is equivalent
    to the input. The string returned is formatted so it can be indented
    nicely within tests; in some cases it is wrapped in the dedent
    function which has to be imported from textwrap.

    Examples
    ========

    Note: because there are characters in the examples below that need
    to be escaped because they are themselves within a triple quoted
    docstring, expressions below look more complicated than they would
    be if they were printed in an interpreter window.

    >>> from sympy.utilities.misc import rawlines
    >>> from sympy import TableForm
    >>> s = str(TableForm([[1, 10]], headings=(None, ['a', 'bee'])))
    >>> print(rawlines(s))
    (
        'a bee\n'
        '-----\n'
        '1 10 '
    )
    >>> print(rawlines('''this
    ... that'''))
    dedent('''\
        this
        that''')

    >>> print(rawlines('''this
    ... that
    ... '''))
    dedent('''\
        this
        that
        ''')

    >>> s = """this
    ... is a triple '''
    ... """
    >>> print(rawlines(s))
    dedent("""\
        this
        is a triple '''
        """)

    >>> print(rawlines('''this
    ... that
    ...     '''))
    (
        'this\n'
        'that\n'
        '    '
    )
    r      r   z'''z"""c             s   s   | ]}| d V  qdS ) N)endswith).0lir   r   r   	<genexpr>Z   s    zrawlines.<locals>.<genexpr>\(Nz\n'z
    z
)zdedent("""\
    %s""")zdedent('''\
    %s'''))	splitlenrepranyallr   	enumerateappendjoin)r   linesZtriplervZtrailingZlastir   r   r   r   rawlines   s"    7
"

r*   P   z-bithash_randomizationFc                s.   ddl m} |s S dd  fdd}|S )zIf SYMPY_DEBUG is True, it will print a nice execution tree with
    arguments and results of all decorated functions, else do nothing.
    r   )SYMPY_DEBUGc             _   sz   t }g a td7 add }| ||}td8 adt| ||f }t g krP||t 7 }|a t | tdkrvtt d  g a |S )Nr   c             S   s`   ddd}t | dkrdS g }x"| d d D ]}||| q,W ||| d d d|S )	Nr   c             S   s\   |  d}d|d  }x@|dd  D ]0}|dkr2q$|dkrH|d| 7 }q$|d| 7 }q$W |S )Nr   z+-%s
r   r    z| %s
z  %s
)r   )r   typexrar   r   r   indent   s    
z?debug_decorator.<locals>.maketree.<locals>.tree.<locals>.indentr   r/   r      )r   )r    r%   r&   )Zsubtreesr4   fr3   r   r   r   tree   s    
z/debug_decorator.<locals>.maketree.<locals>.treez
%s%s = %s
r   )
_debug_tmp_debug_iterr   r%   print)r6   argskwZoldtmpr7   r2   r   r   r   r   maketree~   s    

z!debug_decorator.<locals>.maketreec                 s    f| |S )Nr   )r;   kwargs)funcr=   r   r   	decorated   s    z"debug_decorator.<locals>.decorated)sympyr.   )r?   r.   r@   r   )r?   r=   r   debug_decoratoru   s    /rB   c              G   s$   ddl m} |r t| dtji dS )zB
    Print ``*args`` if SYMPY_DEBUG is True, else do nothing.
    r   )r.   fileN)rA   r.   r:   sysstderr)r;   r.   r   r   r   debug   s    rF   c       
      C   s   |dkrt jd }|t j}dg}t jdkrLt j| \}}|s| d } n@tjdkrt jd 	 t j}t j| \}}|	 |kr|}xT|D ]H}| | }t j
|r|S x*|D ]"}t j||}	t j
|	r|	S qW qW dS dS )zTry to find 'executable' in the directories listed in 'path' (a
    string listing directories separated by 'os.pathsep'; defaults to
    os.environ['PATH']).  Returns the complete filename or None if not
    found
    NPATHr/   Zos2z.exeZwin32ZPATHEXT)osenvironr   pathsepnamepathsplitextrD   platformlowerisfiler&   )

executablerL   pathsZextlistbaseZextZpathextZexecnamepr6   r   r   r   find_executable   s,    





rU   c             C   s   ddddddd}t | }t|drFt|d	d
 d	d }n*t|drpt|d	d
 d	d }tt| d| d|}|r|||}|S )a  Return function name of `x` (if defined) else the `type(x)`.
    If short is True and there is a shorter alias for the result,
    return the alias.

    Examples
    ========

    >>> from sympy.utilities.misc import func_name
    >>> from sympy.abc import x
    >>> func_name(x < 1)
    'StrictLessThan'
    >>> func_name(x < 1, short=True)
    'Lt'

    See Also
    ========
    sympy.core.compatibility get_function_name
    ZGeZGtZLeZLtZEqZNe)ZGreaterThanZStrictGreaterThanZLessThanZStrictLessThanZEqualityZ
Unequalityz<type ''r   r   z<class 'r?   r	   )r0   r   
startswithr   getattrget)r1   shortaliastypr(   r   r   r   	func_name   s    r]   c                sH   sdd S fdd t ddd  D t j fddS )aU  Return a function that can make the replacements, given in
    ``reps``, on a string. The replacements should be given as mapping.

    Examples
    ========

    >>> from sympy.utilities.misc import _replace
    >>> f = _replace(dict(foo='bar', d='t'))
    >>> f('food')
    'bart'
    >>> f = _replace({})
    >>> f('food')
    'food'
    c             S   s   | S )Nr   )r1   r   r   r   <lambda>  s    z_replace.<locals>.<lambda>c                s    |  d S )Nr   )group)match)repsr   r   r^     s    |c             S   s   g | ]\}}t |qS r   )_reescape)r   kvr   r   r   
<listcomp>  s    z_replace.<locals>.<listcomp>c                s     | S )N)sub)string)Dpatternr   r   r^     s    )rc   compiler&   itemsM)ra   r   )rj   rk   ra   r   _replace  s    ro   c             G   sF   t |dkr2|d }t|tkr&|}q:| j| S nt|}t|| S )ab  Return ``string`` with all keys in ``reps`` replaced with
    their corresponding values, longer strings first, irrespective
    of the order they are given.  ``reps`` may be passed as tuples
    or a single mapping.

    Examples
    ========

    >>> from sympy.utilities.misc import replace
    >>> replace('foo', {'oo': 'ar', 'f': 'b'})
    'bar'
    >>> replace("spamham sha", ("spam", "eggs"), ("sha","md5"))
    'eggsham md5'

    There is no guarantee that a unique answer will be
    obtained if keys in a mapping overlap (i.e. are the same
    length and have some identical sequence at the
    beginning/end):

    >>> reps = [
    ...     ('ab', 'x'),
    ...     ('bc', 'y')]
    >>> replace('abc', *reps) in ('xc', 'ay')
    True

    References
    ==========

    .. [1] http://stackoverflow.com/questions/6116978/python-replace-multiple-strings
    r   r   )r    r0   dictreplacero   )ri   ra   Zkvr   r   r   rq     s    rq   c             C   sf  ddl m}m} i }|dkr>|dks(t|s0| S |}d }}nt|tkri }x>t| D ].}t|dkr\t|| dkr\|	|||< q\W |}|}|rdd tt
|  D \}}qd }}nt|t|kst|r|r| |dd|} t| |} | |||S |rt|}i }	xFtddt| dD ].}
t||
 d	kr6d|	||
 < |	|
 q6W | dd|} t| |	} |rt|}t|}xVtddt| dD ]>}
t||
 d	kst||
 d	kr|	|
||	|
< qW d|}d|}t| |} |||}t|tkrBt| tkrB| |} n| td
d t|D } | S dS )a  Return ``s`` where characters have been replaced or deleted.

    SYNTAX
    ======

    translate(s, None, deletechars):
        all characters in ``deletechars`` are deleted
    translate(s, map [,deletechars]):
        all characters in ``deletechars`` (if provided) are deleted
        then the replacements defined by map are made; if the keys
        of map are strings then the longer ones are handled first.
        Multicharacter deletions should have a value of ''.
    translate(s, oldchars, newchars, deletechars)
        all characters in ``deletechars`` are deleted
        then each character in ``oldchars`` is replaced with the
        corresponding character in ``newchars``

    Examples
    ========

    >>> from sympy.utilities.misc import translate
    >>> from sympy.core.compatibility import unichr
    >>> abc = 'abc'
    >>> translate(abc, None, 'a')
    'bc'
    >>> translate(abc, {'a': 'x'}, 'c')
    'xb'
    >>> translate(abc, {'abc': 'x', 'a': 'y'})
    'x'

    >>> translate('abcd', 'ac', 'AC', 'd')
    'AbC'

    There is no guarantee that a unique answer will be
    obtained if keys in a mapping overlap are the same
    length and have some identical sequences at the
    beginning/end:

    >>> translate(abc, {'ab': 'x', 'bc': 'y'}) in ('xc', 'ay')
    True
    r   )	maketransPY3Nr/   r   c             S   s   g | ]}d  |qS )r/   )r&   )r   r)   r   r   r   rg     s    ztranslate.<locals>.<listcomp>r      c             S   s   g | ]\}}|t |fqS r   )ord)r   r)   cr   r   r   rg     s    )sympy.core.compatibilityrr   rs   AssertionErrorr0   rp   listkeysr    popziprm   	translaterq   r   ru   r&   r   r$   )r   r3   brv   rr   rs   ZmrrZ   re   Zremr)   tabler   r   r   r}   E  s`    *
 


$



r}   )r   )N)F)NN)"__doc__Z
__future__r   r   rD   rH   rerc   Zstructtextwrapr   r   rw   r   r   
ValueErrorr   r   r*   r   ZcalcsizeZARCHrX   flagsZHASH_RANDOMIZATIONr8   r9   rB   rF   rU   r]   ro   rq   r}   r   r   r   r   <module>   s*   
M>	
"
&*