예제 #1
0
파일: misc.py 프로젝트: gamechanger98/sympy
def translate(s, a, b=None, c=None):
    """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
    """
    from sympy.core.compatibility import maketrans, PY3

    mr = {}
    if a is None:
        assert c is None
        if not b:
            return s
        c = b
        a = b = ''
    else:
        if type(a) is dict:
            short = {}
            for k in list(a.keys()):
                if len(k) == 1 and len(a[k]) == 1:
                    short[k] = a.pop(k)
            mr = a
            c = b
            if short:
                a, b = [''.join(i) for i in list(zip(*short.items()))]
            else:
                a = b = ''
        else:
            assert len(a) == len(b)
    if PY3:
        if c:
            s = s.translate(maketrans('', '', c))
        s = replace(s, mr)
        return s.translate(maketrans(a, b))
    else:
        # when support for Python 2 is dropped, this if-else-block
        # can be replaced with the if-clause
        if c:
            c = list(c)
            rem = {}
            for i in range(-1, -1 - len(c), -1):
                if ord(c[i]) > 255:
                    rem[c[i]] = ''
                    c.pop(i)
            s = s.translate(None, ''.join(c))
            s = replace(s, rem)
            if a:
                a = list(a)
                b = list(b)
                for i in range(-1, -1 - len(a), -1):
                    if ord(a[i]) > 255 or ord(b[i]) > 255:
                        mr[a.pop(i)] = b.pop(i)
                a = ''.join(a)
                b = ''.join(b)
        s = replace(s, mr)
        table = maketrans(a, b)
        # s may have become unicode which uses the py3 syntax for translate
        if type(table) is str and type(s) is str:
            s = s.translate(table)
        else:
            s = s.translate(dict(
                [(i, ord(c)) for i, c in enumerate(table)]))
        return s
예제 #2
0
def translate(s, a, b=None, c=None):
    """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
    """
    from sympy.core.compatibility import maketrans, PY3

    mr = {}
    if a is None:
        if c is not None:
            raise ValueError(
                'c should be None when a=None is passed, instead got %s' % c)
        if b is None:
            return s
        c = b
        a = b = ''
    else:
        if type(a) is dict:
            short = {}
            for k in list(a.keys()):
                if len(k) == 1 and len(a[k]) == 1:
                    short[k] = a.pop(k)
            mr = a
            c = b
            if short:
                a, b = [''.join(i) for i in list(zip(*short.items()))]
            else:
                a = b = ''
        elif len(a) != len(b):
            raise ValueError('oldchars and newchars have different lengths')
    if PY3:
        if c:
            s = s.translate(maketrans('', '', c))
        s = replace(s, mr)
        return s.translate(maketrans(a, b))
    else:
        # when support for Python 2 is dropped, this if-else-block
        # can be replaced with the if-clause
        if c:
            c = list(c)
            rem = {}
            for i in range(-1, -1 - len(c), -1):
                if ord(c[i]) > 255:
                    rem[c[i]] = ''
                    c.pop(i)
            s = s.translate(None, ''.join(c))
            s = replace(s, rem)
            if a:
                a = list(a)
                b = list(b)
                for i in range(-1, -1 - len(a), -1):
                    if ord(a[i]) > 255 or ord(b[i]) > 255:
                        mr[a.pop(i)] = b.pop(i)
                a = ''.join(a)
                b = ''.join(b)
        s = replace(s, mr)
        table = maketrans(a, b)
        # s may have become unicode which uses the py3 syntax for translate
        if isinstance(table, str) and isinstance(s, str):
            s = s.translate(table)
        else:
            s = s.translate(dict([(i, ord(c)) for i, c in enumerate(table)]))
        return s