Ticket #6519: old_pickle_support.patch

File old_pickle_support.patch, 61.8 KB (added by saliola, 12 years ago)

DO NOT APPLY!

  • new file sage/combinat/words/utils.py

    # HG changeset patch
    # User Franco Saliola <saliola@gmail.com>
    # Date 1247865591 -7200
    # Node ID 3ba698f579d60b3012f878bd351bb28e047ea7fc
    # Parent  dc22b8baa725a961a260c720b1a7244cc3111188
    imported patch words_ng-picklejar-support.patch
    
    diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/utils.py
    - +  
     1"""
     2Word utilities (DEPRECATED)
     3
     4.. note::
     5
     6    This module will be deleted in a future version of Sage. Most of the
     7    commands here have been already deleted; only the commands needed for
     8    unpickling word objects saved with older versions of Sage (pre 4.1) have
     9    been kept (for now).
     10
     11"""
     12#*****************************************************************************
     13#       Copyright (C) 2008 Arnaud Bergeron <abergeron@gmail.com>
     14#
     15#  Distributed under the terms of the GNU General Public License version 2 (GPLv2)
     16#
     17#  The full text of the GPLv2 is available at:
     18#
     19#                  http://www.gnu.org/licenses/
     20#*****************************************************************************
     21from itertools import islice, tee, izip, starmap, imap, ifilter, ifilterfalse
     22from copy import copy
     23
     24def copy_it(it):
     25    r"""
     26    This function is deprecated and will be deleted in a future
     27    version of Sage.
     28
     29    Copy an iterator using its builtin __copy__ method if
     30    available, otherwise use itertools.tee(). Define __copy__ for
     31    your iterators. (See PEP 323)
     32   
     33    TESTS::
     34   
     35        sage: from sage.combinat.words.utils import copy_it
     36        sage: it = iter([1, 2, 3, 4, 5])
     37        sage: it, it2 = copy_it(it)
     38        sage: list(it)
     39        [1, 2, 3, 4, 5]
     40        sage: it2.next()
     41        1
     42        sage: it2, it3 = copy_it(it2)
     43        sage: list(it2)
     44        [2, 3, 4, 5]
     45        sage: it3.next()
     46        2
     47    """
     48    it = iter(it)
     49    if hasattr(it, '__copy__'):
     50        return (it, copy(it))
     51    else:   
     52        return tee(it)
     53
     54def slice_it(it, l, key):
     55    r"""
     56    This function is deprecated and will be deleted in a future
     57    version of Sage.
     58
     59    Slice an iterator, supporting negative step sizes by expliciting
     60    the elements if needed.
     61   
     62    NOTE: The iterator returned depends on it. You must pass in a copy
     63    of your iterator if you intend to keep using the original
     64    iterator.
     65   
     66    TESTS::
     67   
     68        sage: from sage.combinat.words.utils import slice_it
     69        sage: list(slice_it(iter(range(5)), 5, slice(None)))
     70        [0, 1, 2, 3, 4]
     71        sage: list(slice_it(iter(range(5)), 5, slice(3)))
     72        [0, 1, 2]
     73        sage: list(slice_it(iter(range(5)), 5, slice(-1)))
     74        [0, 1, 2, 3]
     75        sage: list(slice_it(iter(range(5)), 5, slice(2, 4)))
     76        [2, 3]
     77        sage: list(slice_it(iter(range(5)), 5, slice(3, 1, -1)))
     78        [3, 2]
     79    """
     80    start, stop, step = key.start, key.stop, key.step
     81    if step is None:
     82        step = 1
     83    if step == 0:
     84        raise ValueError, "attempt to use 0 as step value"
     85    elif step > 0:
     86        return islice(it, *slice_indices(key, l))
     87    else:
     88        return tuple(islice(it, l))[key]
     89
     90def peek_it(it):
     91    r"""
     92    This function is deprecated and will be deleted in a future
     93    version of Sage.
     94
     95    Returns the first element of an iterator and returns an iterator at
     96    the same position as the original iterator
     97   
     98    EXAMPLES::
     99   
     100        sage: from sage.combinat.words.utils import peek_it
     101        sage: it = iter([1, 2, 3])
     102        sage: it, n = peek_it(it); n
     103        1
     104        sage: it.next()
     105        1
     106    """
     107    it, cp = copy_it(it)
     108    return it, cp.next()
     109
     110def len_it(it):
     111    r"""
     112    This function is deprecated and will be deleted in a future
     113    version of Sage.
     114
     115    Returns the number of elements in it.
     116   
     117    This function will modify the iterator, so if you want to access
     118    the elements later, make a copy of the iterator and pass it to this
     119    function.
     120   
     121    EXAMPLES::
     122   
     123        sage: from sage.combinat.words.utils import len_it
     124        sage: len_it(iter([1, 2, 3]))
     125        3
     126    """
     127    n = 0
     128    try:
     129        while True:
     130            it.next()
     131            n += 1
     132    except StopIteration:
     133        return n
     134
     135def haslen(obj):
     136    r"""
     137    This function is deprecated and will be deleted in a future
     138    version of Sage.
     139
     140    Returns true if obj has a properly defined length
     141   
     142    EXAMPLES::
     143   
     144        sage: from sage.combinat.words.utils import haslen
     145        sage: haslen([1, 2, 3])
     146        True
     147        sage: haslen(33)
     148        False
     149   
     150    TESTS::
     151   
     152        sage: class test(object):
     153        ...     def __len__(self):
     154        ...         return -1
     155        ...
     156        sage: haslen(test())
     157        False
     158    """
     159    try:
     160        len(obj)
     161    except:
     162        return False
     163    return True
     164   
     165def sliceable(obj):
     166    r"""
     167    This function is deprecated and will be deleted in a future
     168    version of Sage.
     169
     170    Returns true if obj is completely sliceable, including negative
     171    step sizes
     172   
     173    EXAMPLES::
     174   
     175        sage: from sage.combinat.words.utils import sliceable
     176        sage: sliceable([1, 2, 3])
     177        True
     178        sage: sliceable(33)
     179        False
     180   
     181    TESTS::
     182   
     183        sage: class test(object):
     184        ...     def __getitem__(self, key):
     185        ...         return islice(iter([1]), *key)
     186        ...
     187        sage: sliceable(test())
     188        False
     189    """
     190    try:
     191        obj[0:0:-1]
     192    except:
     193        return False
     194    return True
     195
     196def isint(obj):
     197    r"""
     198    This function is deprecated and will be deleted in a future
     199    version of Sage.
     200
     201    Returns True if obj is an integer or a custom object representing
     202    an integer and False otherwise.
     203   
     204    EXAMPLES::
     205   
     206        sage: from sage.combinat.words.utils import isint
     207        sage: isint(1)
     208        True
     209        sage: isint("2")
     210        False
     211        sage: isint(1.0)
     212        False
     213    """
     214    return hasattr(obj, '__index__')
     215
     216def is_iterable(obj):
     217    r"""
     218    This function is deprecated and will be deleted in a future
     219    version of Sage.
     220
     221    Returns true if the obj is iterable.
     222   
     223    EXAMPLES::
     224   
     225        sage: from sage.combinat.words.utils import is_iterable
     226        sage: is_iterable('123')
     227        True
     228        sage: is_iterable([1, 2, 3])
     229        True
     230        sage: is_iterable(xrange(1, 4))
     231        True
     232        sage: is_iterable(33)
     233        False
     234    """
     235    try:
     236        iter(obj)
     237        return True
     238    except:
     239        return False
     240
     241def slice_ok(part):
     242    r"""
     243    This function is deprecated and will be deleted in a future
     244    version of Sage.
     245
     246    Returns true if part is a slice and doesn't have funny values.
     247   
     248    EXAMPLES::
     249   
     250        sage: from sage.combinat.words.utils import slice_ok
     251        sage: slice_ok(slice(None))
     252        True
     253        sage: slice_ok(slice(2))
     254        True
     255        sage: slice_ok(slice(1, 2, 3))
     256        True
     257        sage: slice_ok(slice(None, 2, 3))
     258        True
     259        sage: slice_ok(slice(1, None, 3))
     260        True
     261        sage: slice_ok(slice(1, 2, None))
     262        True
     263        sage: slice_ok(slice("a"))
     264        False
     265        sage: slice_ok(slice("a", 1))
     266        False
     267        sage: slice_ok(slice(1, 2, "a"))
     268        False
     269        sage: slice_ok(1)
     270        False
     271    """
     272    return isinstance(part, slice) and \
     273           (part.start is None or isint(part.start)) and \
     274           (part.stop is None or isint(part.stop)) and \
     275           (part.step is None or isint(part.step))
     276
     277def slice_indices(s, l):
     278    r"""
     279    This function is deprecated and will be deleted in a future
     280    version of Sage.
     281
     282    Implement slice.indices without bugs.
     283   
     284    TESTS::
     285   
     286        sage: from sage.combinat.words.utils import slice_indices
     287        sage: slice_indices(slice(None), 8)
     288        (0, 8, 1)
     289        sage: slice_indices(slice(1), 8)
     290        (0, 1, 1)
     291        sage: slice_indices(slice(10), 8)
     292        (0, 8, 1)
     293        sage: slice_indices(slice(-4), 8)
     294        (0, 4, 1)
     295        sage: slice_indices(slice(-10), 8)
     296        (0, 0, 1)
     297        sage: slice_indices(slice(1, None), 8)
     298        (1, 8, 1)
     299        sage: slice_indices(slice(10, None), 8)
     300        (8, 8, 1)
     301        sage: slice_indices(slice(-4, None), 8)
     302        (4, 8, 1)
     303        sage: slice_indices(slice(-10, None), 8)
     304        (0, 8, 1)
     305        sage: slice_indices(slice(None, None, 2), 8)
     306        (0, 8, 2)
     307        sage: slice_indices(slice(None, None, -2), 8)
     308        (7, -1, -2)
     309    """
     310    start, stop, step = s.indices(l)
     311    if stop*step < start*step:
     312        stop = start
     313    return start, stop, step
     314
     315def reverse_map(d):
     316    r"""
     317    This function is deprecated and will be deleted in a future
     318    version of Sage.
     319
     320    Return a new dict with swapped keys and values
     321   
     322    EXAMPLES::
     323   
     324        sage: from sage.combinat.words.utils import reverse_map
     325        sage: reverse_map({'a': 1, 'b': 2}) == {1: 'a', 2: 'b'}
     326        True
     327    """
     328    return dict(izip(d.itervalues(), d))
     329
     330def id_f(x):
     331    r"""
     332    This function is deprecated and will be deleted in a future
     333    version of Sage.
     334
     335    Dummy identity function for when a function is required but none is
     336    desired.
     337   
     338    .. note::
     339
     340       This function is needed required so that words saved in earlier versions
     341       of Sage can be loaded; and will be deleted in a future version of Sage.
     342
     343    TESTS::
     344   
     345        sage: from sage.combinat.words.utils import id_f
     346        sage: l = [1, 2, 3]
     347        sage: l is id_f(l)
     348        True
     349    """
     350    return x
     351
     352def clamp(x, min, max):
     353    r"""
     354    This function is deprecated and will be deleted in a future
     355    version of Sage.
     356
     357    Clamp a value between a maximum and a minimum.
     358   
     359    EXAMPLES::
     360   
     361        sage: from sage.combinat.words.utils import clamp
     362        sage: clamp(0, -1, 1)
     363        0
     364        sage: clamp(-2, 0, 4)
     365        0
     366        sage: clamp(10, 0, 4)
     367        4
     368    """
     369    if x < min:
     370        return min
     371    elif x > max:
     372        return max
     373    else:
     374        return x
     375
     376from sage.combinat.words.word import Factorization
     377
  • sage/combinat/words/word.py

    diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/word.py
    a b  
    366366            datatype = "callable"
    367367        elif hasattr(data,"__iter__"):
    368368            datatype = "iter"
     369        elif isinstance(data, WordContent):
     370            # For backwards compatibility (picklejar)
     371            return _word_from_word_content(data=data, parent=alphabet)
    369372        else:
    370373            raise ValueError, "Cannot guess a datatype; please specify one"
    371374    else:
     
    378381                                "callable", "iter"):
    379382            raise ValueError, "Unknown datatype"
    380383
    381     #print 'datatype:', datatype
    382 
    383384    # Create the parent object
    384385    from words import Words
    385386    parent = Words() if alphabet is None else Words(alphabet)
     
    436437
    437438###########################################################################
    438439##### DEPRECATION WARNINGS ################################################
    439 ##### Added 10 February 2008 ##############################################
     440##### Added July 2009 #####################################################
    440441###########################################################################
    441442
    442443def is_Word(obj):
     
    10841085
    10851086            sage: w = Word('abaccefa')
    10861087            sage: w._word_content
    1087             doctest:492: DeprecationWarning: _word_content is deprecated! try to_integer_word instead! See the documentation for more information
     1088            doctest:...: DeprecationWarning: _word_content is deprecated! try to_integer_word instead! See the documentation for more information
    10881089            word: 01022340
    10891090        """
    10901091        from sage.misc.misc import deprecation
     
    14601461
    14611462    ###########################################################################
    14621463    ##### DEPRECATION WARNINGS (next 4 functions) #############################
    1463     ##### Added 23 February 2008 ##############################################
     1464    ##### Added July 2009 #####################################################
    14641465    ###########################################################################
    14651466    def is_suffix_of(self, other):
    14661467        r"""
     
    14981499            sage: W = Word
    14991500            sage: W('23').is_proper_suffix_of(W('123'))
    15001501            doctest:1: DeprecationWarning: is_proper_suffix_of is deprecated, use is_proper_suffix instead!
    1501             doctest:1604: DeprecationWarning: is_suffix_of is deprecated, use is_suffix instead!
     1502            doctest:...: DeprecationWarning: is_suffix_of is deprecated, use is_suffix instead!
    15021503            True
    15031504            sage: W('12').is_proper_suffix_of(W('12'))
    15041505            False
     
    15451546            sage: W = Word
    15461547            sage: W('12').is_proper_prefix_of(W('123'))
    15471548            doctest:1: DeprecationWarning: is_proper_prefix_of is deprecated, use is_proper_prefix instead!
    1548             doctest:1689: DeprecationWarning: is_prefix_of is deprecated, use is_prefix instead!
     1549            doctest:...: DeprecationWarning: is_prefix_of is deprecated, use is_prefix instead!
    15491550            True
    15501551            sage: W('12').is_proper_prefix_of(W('12'))
    15511552            False
     
    23922393           
    23932394    ###########################################################################
    23942395    ##### DEPRECATION WARNINGS ################################################
    2395     ##### Added 12 February 2008 ##############################################
     2396    ##### Added July 2009 #####################################################
    23962397    ###########################################################################
    23972398    def _lps(self, l=None, f=None):
    23982399        r"""
     
    36393640
    36403641    ###########################################################################
    36413642    ##### DEPRECATION WARNINGS ################################################
    3642     ##### Added 23 February 2008 ##############################################
     3643    ##### Added July 2009 #####################################################
    36433644    ###########################################################################
    36443645    def last_position_table(self):
    36453646        r"""
     
    37213722
    37223723    ###########################################################################
    37233724    ##### DEPRECATION WARNINGS ################################################
    3724     ##### Added 23 February 2008 ##############################################
     3725    ##### Added July 2009 #####################################################
    37253726    ###########################################################################
    37263727    def is_factor_of(self, other):
    37273728        r"""
     
    39933994       
    39943995    ###########################################################################
    39953996    ##### DEPRECATION WARNINGS ################################################
    3996     ##### Added 23 February 2008 ##############################################
     3997    ##### Added July 2009 #####################################################
    39973998    ###########################################################################
    39983999    def _quasiperiods_list(self):
    39994000        r"""
     
    41154116
    41164117    ###########################################################################
    41174118    ##### DEPRECATION WARNINGS ################################################
    4118     ##### Added 23 February 2008 ##############################################
     4119    ##### Added July 2009 #####################################################
    41194120    ###########################################################################
    41204121    def freq(self):
    41214122        r"""
     
    45034504
    45044505    ###########################################################################
    45054506    ##### DEPRECATION WARNINGS ################################################
    4506     ##### Added 23 February 2008 ##############################################
     4507    ##### Added July 2009 #####################################################
    45074508    ###########################################################################
    45084509    def iterated_palindromic_closure(self, side='right', f=None):
    45094510        r"""
     
    57635764#                                                                     #
    57645765#######################################################################
    57655766
     5767def _word_from_word_content(data, parent):
     5768    r"""
     5769    Create a word with the given parent from a :class:`WordContent` object.
     5770
     5771    .. note::
     5772
     5773       :class:`WordContent` is deprecated and will be deleted in a future
     5774       version of Sage. This function exists to maintain backwards
     5775       compatibility for unpickling objects saved with older versions of Sage.
     5776
     5777    TESTS::
     5778
     5779        sage: from sage.combinat.words.word import _word_from_word_content
     5780        sage: import sage.combinat.words.word_content as word_content
     5781        sage: cl = word_content.WordContentFromList([0, 1, 1, 2, 1])
     5782        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     5783        sage: _word_from_word_content(cl,Words([0,1,2]))
     5784        word: 01121
     5785        sage: _word_from_word_content(cl,Words([2,1,0]))
     5786        word: 21101
     5787
     5788    ::
     5789
     5790        sage: cf = word_content.WordContentFromFunction(lambda x : x)[:10]
     5791        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     5792        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     5793        sage: _word_from_word_content(cf, Words())
     5794        word: 0123456789
     5795
     5796    ::
     5797
     5798        sage: from itertools import count
     5799        sage: ci = word_content.WordContentFromIterator(count(3))[:5]
     5800        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     5801        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     5802        sage: _word_from_word_content(ci, Words())
     5803        word: 34567
     5804
     5805    ::
     5806
     5807        sage: cc = word_content.ConcatenateContent((cl, cf, ci))
     5808        doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     5809        doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     5810        sage: _word_from_word_content(cc, Words())
     5811        word: 01121012345678934567
     5812
     5813    """
     5814    from sage.combinat.words import word_content
     5815    # extract data from WordContent object
     5816    length = None
     5817    if isinstance(data, word_content.WordContentFromList):
     5818        unranker = parent.alphabet().unrank
     5819        data = map(unranker, data._list)
     5820        datatype = 'list'
     5821    elif isinstance(data, word_content.WordContentFromIterator):
     5822        data = data._get_it()
     5823        datatype = 'iter'
     5824    elif isinstance(data, word_content.WordContentFromFunction):
     5825        length = data._len
     5826        data = data._func
     5827        datatype = 'callable'
     5828    elif isinstance(data, word_content.ConcatenateContent):
     5829        l = map(_word_from_word_content, data)
     5830        data = CallableFromListOfWords(l)
     5831        datatype = 'callable'
     5832    else:
     5833        raise TypeError, 'data is not an instance of WordContent'
     5834    return Word(data=data, alphabet=parent, datatype=datatype, length=length)
     5835
    57665836class DeprecatedWordClass(SageObject):
    5767     def __new__(cls, parent, word, mapping=None, format=None, part=slice(None)):
    5768         from sage.misc.misc import deprecation
    5769         deprecation("%s is deprecated, use %s instead!" % (cls.__name__,
    5770             cls.__bases__[1].__name__))
    5771         return parent(data=word, format=format, part=part)
    5772 
    5773 class AbstractWord(DeprecatedWordClass, Word_class):
    5774     pass
    5775 
    5776 class AbstractFiniteWord(DeprecatedWordClass, FiniteWord_class):
     5837    def __setstate__(self, data):
     5838        from sage.misc.misc import deprecation
     5839        cls = self.__class__
     5840        deprecation('Your word object is saved in an old file format '
     5841            'since %s is deprecated and will be deleted in a future version '
     5842            'of Sage (you can use %s instead). You can re-save your word by '
     5843            'typing "word.save(filename)" to ensure that it will load in '
     5844            'future versions of Sage.''' %
     5845            (cls.__name__, cls.__bases__[1].__name__))
     5846        parent = data['_parent']
     5847        del data['_parent']
     5848        wordcontent = data.get('_word_content', None)
     5849        del data['_word_content']
     5850        w = _word_from_word_content(wordcontent, parent)
     5851        self.__class__ = type(w)
     5852        self.__init__(parent, list(w))
     5853        for key, item in data.iteritems():
     5854            setattr(self, key, item)
     5855
     5856class AbstractWord(DeprecatedWordClass, FiniteWord_list):
     5857    pass
     5858
     5859class AbstractFiniteWord(DeprecatedWordClass, FiniteWord_list):
    57775860    pass
    57785861
    57795862class AbstractInfiniteWord(DeprecatedWordClass, InfiniteWord_class):
    57805863    pass
    57815864
    5782 class Word_over_Alphabet(DeprecatedWordClass, Word_class):
    5783     pass
    5784 
    5785 class Word_over_OrderedAlphabet(DeprecatedWordClass, Word_class):
    5786     pass
    5787 
    5788 class FiniteWord_over_Alphabet(DeprecatedWordClass, FiniteWord_class):
    5789     pass
    5790 
    5791 class FiniteWord_over_OrderedAlphabet(DeprecatedWordClass, FiniteWord_class):
     5865class Word_over_Alphabet(DeprecatedWordClass, FiniteWord_list):
     5866    pass
     5867
     5868class Word_over_OrderedAlphabet(DeprecatedWordClass, FiniteWord_list):
     5869    pass
     5870
     5871class FiniteWord_over_Alphabet(DeprecatedWordClass, FiniteWord_list):
     5872    pass
     5873
     5874class FiniteWord_over_OrderedAlphabet(DeprecatedWordClass, FiniteWord_list):
    57925875    pass
    57935876
    57945877class InfiniteWord_over_Alphabet(DeprecatedWordClass, InfiniteWord_class):
  • new file sage/combinat/words/word_content.py

    diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/word_content.py
    - +  
     1# coding=utf-8
     2"""
     3Word contents (DEPRECATED)
     4
     5.. note::
     6
     7    This module will be deleted in a future version of Sage. Most of the
     8    commands here have been already deleted; only the commands needed for
     9    unpickling word objects saved with older versions of Sage (pre 4.1) have
     10    been kept (for now).
     11
     12"""
     13#*****************************************************************************
     14#       Copyright (C) 2008 Arnaud Bergeron <abergeron@gmail.com>,
     15#
     16#  Distributed under the terms of the GNU General Public License version 2 (GPLv2)
     17#
     18#  The full text of the GPLv2 is available at:
     19#
     20#                  http://www.gnu.org/licenses/
     21#*****************************************************************************
     22from itertools import imap, izip, count
     23from sage.rings.infinity import Infinity
     24from sage.combinat.words.utils import *
     25
     26def BuildWordContent(obj, mapping=id_f, format=None, part=slice(None)):
     27    r"""
     28    Builds the content for a word.
     29   
     30    INPUT:
     31   
     32   
     33    -  ``obj`` - a function, an iterator or a list,
     34       potentially with a length defined
     35   
     36    -  ``mapping`` - function, a map sending elements of
     37       the iterable to nonnegative integers.
     38   
     39    -  ``format`` - string (default None), the explicit
     40       type of obj. Can be either 'empty', 'list', 'function' or
     41       'iterator'. If set to None (the default), the type will be guessed
     42       from the properties of obj.
     43   
     44    -  ``part`` - slice (default slice(None)), the portion
     45       of the object to use
     46   
     47   
     48    OUTPUT:
     49   
     50   
     51    -  ``word content`` - an object respecting the word
     52       content protocol wrapping obj
     53   
     54   
     55    TESTS::
     56   
     57        sage: from sage.combinat.words.word_content import BuildWordContent
     58        sage: from itertools import count, imap, repeat
     59        sage: len(BuildWordContent(None))
     60        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     61        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     62        0
     63        sage: len(BuildWordContent(None, format='empty'))
     64        0
     65        sage: c = BuildWordContent(['a', 'b'], format='empty')
     66        Traceback (most recent call last):
     67        ...
     68        TypeError: trying to build an empty word with something other than None
     69        sage: len(BuildWordContent(['0', '1', '1'], int))
     70        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     71        3
     72        sage: len(BuildWordContent(['0', '1', '1'], int, format='list'))
     73        3
     74        sage: BuildWordContent(10, format='list')
     75        Traceback (most recent call last):
     76        ...
     77        TypeError: trying to build a word backed by a list with a sequence not providing the required operations
     78        sage: c = BuildWordContent(lambda x: x%2)
     79        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     80        doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     81        sage: len(BuildWordContent(lambda x: x%3, part=slice(0,10)))
     82        10
     83        sage: c = BuildWordContent(repeat(1))
     84        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     85        doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     86        sage: len(BuildWordContent(count(), part=slice(10)))
     87        10
     88        sage: len(BuildWordContent(count(), part=slice(10, 0, -2)))
     89        doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     90        5
     91    """
     92    if format is None:
     93        if isinstance(obj, WordContent):
     94            return obj[part]
     95        elif obj is None:
     96            format = 'empty'
     97        elif is_iterable(obj):
     98            if haslen(obj):
     99                format = 'list'
     100            else:
     101                format = 'iterator'
     102        elif callable(obj):
     103            format = 'function'
     104        else:
     105            pass # Don't set format if we don't know
     106
     107    if format == 'empty':
     108        if obj is not None:
     109            raise TypeError, "trying to build an empty word with something other than None"
     110        return WordContentFromList((), mapping)[part]
     111    elif format == 'list' or format == 'string':
     112        if not (is_iterable(obj) and haslen(obj)):
     113            raise TypeError, "trying to build a word backed by a list with a sequence not providing the required operations"
     114        return WordContentFromList(obj, mapping)[part]
     115    elif format == 'function':
     116        if not callable(obj):
     117            raise TypeError, "trying to build a word backed by a function with a non-callable"
     118        return WordContentFromFunction(obj, mapping)[part]
     119    elif format == 'iterator':
     120        if not is_iterable(obj):
     121            raise TypeError, "trying to build a word backed by an iterator with a non-iterable"
     122        return WordContentFromIterator(obj, mapping)[part]
     123    raise NotImplementedError
     124
     125def is_WordContent(obj):
     126    r"""
     127    Returns True if obj is the content of a word.
     128   
     129    EXAMPLES::
     130   
     131        sage: from sage.combinat.words.word_content import BuildWordContent, is_WordContent
     132        sage: is_WordContent(33)
     133        False
     134        sage: is_WordContent(BuildWordContent([0, 1, 0], lambda x : x))
     135        True
     136    """
     137    return isinstance(obj, WordContent)
     138
     139class WordContent(object):
     140    def __cmp__(self, other):
     141        r"""
     142        Compares two contents according to the data they contain.
     143       
     144        The types of the contents doesn't matter.
     145       
     146        TESTS::
     147       
     148            sage: c1 = sage.combinat.words.word_content.WordContentFromList([1, 2, 1, 1])
     149            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     150            sage: c2 = sage.combinat.words.word_content.WordContentFromList([1, 2, 3])
     151            sage: c3 = sage.combinat.words.word_content.WordContentFromList([1, 4])
     152            sage: c2.__cmp__(c1) > 0
     153            True
     154            sage: c2.__cmp__(c2) == 0
     155            True
     156            sage: c2.__cmp__(c3) < 0
     157            True
     158        """
     159        if not is_WordContent(other):
     160            return NotImplemented
     161        if haslen(self) and haslen(other):
     162            for (i, j) in izip(self, other):
     163                if i != j:
     164                    return i - j
     165            return len(self) - len(other)
     166        return NotImplemented
     167   
     168    def concatenate(self, other):
     169        r"""
     170        Method to concatenate two contents together.
     171       
     172        TESTS::
     173       
     174            sage: from sage.combinat.words.word_content import BuildWordContent
     175            sage: list(BuildWordContent([1]).concatenate(BuildWordContent([2, 3, 4])))
     176            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     177            [1, 2, 3, 4]
     178        """
     179        if not (haslen(self) and haslen(other)):
     180            raise ValueError, "cannot concatenate infinite words"
     181        return ConcatenateContent(self._get_list() + other._get_list())
     182   
     183    def _get_list(self):
     184        r"""
     185        Returns self as a list of contents suitable for concatenate
     186       
     187        TESTS::
     188       
     189            sage: type(sage.combinat.words.word_content.BuildWordContent([1, 2, 3])._get_list())
     190            <type 'tuple'>
     191        """
     192        return (self,)
     193   
     194    def _check_getitem_args(self, key):
     195        r"""
     196        Does all the type and range checking for the key argument to
     197        __getitem__(). Also takes care of normalizing the ranges
     198        specified by slicing to values suitable for xrange() or similar in
     199        the finite case. In the infinite case a stop value of None, will
     200        stay as None since no end can be defined.
     201       
     202        TESTS: Generic Cases
     203       
     204        ::
     205       
     206            sage: w = sage.combinat.words.word_content.WordContent()
     207            sage: w._check_getitem_args(1)
     208            1
     209            sage: w._check_getitem_args("abc")
     210            Traceback (most recent call last):
     211            ...
     212            TypeError: word indices must be integers
     213            sage: w._check_getitem_args(slice(1, 2, 3))
     214            slice(1, 2, 3)
     215            sage: w._check_getitem_args(slice("a"))
     216            Traceback (most recent call last):
     217            ...
     218            TypeError: word indices must be integers
     219            sage: w._check_getitem_args(slice("a", 1))
     220            Traceback (most recent call last):
     221            ...
     222            TypeError: word indices must be integers
     223            sage: w._check_getitem_args(slice(1, 1, "a"))
     224            Traceback (most recent call last):
     225            ...
     226            TypeError: word indices must be integers
     227       
     228        Finite Cases
     229       
     230        ::
     231       
     232            sage: f = sage.combinat.words.word_content.WordContentFromList(range(10))
     233            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     234            sage: f._check_getitem_args(slice(None, None, None))
     235            slice(0, 10, 1)
     236            sage: f._check_getitem_args(slice(None, 0, None))
     237            slice(0, 0, 1)
     238            sage: f._check_getitem_args(slice(None, 1, None))
     239            slice(0, 1, 1)
     240            sage: f._check_getitem_args(slice(None, -1, None))
     241            slice(0, 9, 1)
     242            sage: f._check_getitem_args(slice(None, 11, None))
     243            slice(0, 10, 1)
     244            sage: f._check_getitem_args(slice(None, 10, None))
     245            slice(0, 10, 1)
     246            sage: f._check_getitem_args(slice(None, 9, None))
     247            slice(0, 9, 1)
     248            sage: f._check_getitem_args(slice(None, -9, None))
     249            slice(0, 1, 1)
     250            sage: f._check_getitem_args(slice(None, -10, None))
     251            slice(0, 0, 1)
     252            sage: f._check_getitem_args(slice(None, -11, None))
     253            slice(0, 0, 1)
     254            sage: f._check_getitem_args(slice(0, None, None))
     255            slice(0, 10, 1)
     256            sage: f._check_getitem_args(slice(1, None, None))
     257            slice(1, 10, 1)
     258            sage: f._check_getitem_args(slice(-1, None, None))
     259            slice(9, 10, 1)
     260            sage: f._check_getitem_args(slice(11, None, None))
     261            slice(10, 10, 1)
     262            sage: f._check_getitem_args(slice(10, None, None))
     263            slice(10, 10, 1)
     264            sage: f._check_getitem_args(slice(9, None, None))
     265            slice(9, 10, 1)
     266            sage: f._check_getitem_args(slice(-9, None, None))
     267            slice(1, 10, 1)
     268            sage: f._check_getitem_args(slice(-10, None, None))
     269            slice(0, 10, 1)
     270            sage: f._check_getitem_args(slice(-11, None, None))
     271            slice(0, 10, 1)
     272            sage: f._check_getitem_args(slice(None, None, -1))
     273            slice(9, -1, -1)
     274            sage: f._check_getitem_args(slice(None, 0, -1))
     275            slice(9, 0, -1)
     276            sage: f._check_getitem_args(slice(None, 1, -1))
     277            slice(9, 1, -1)
     278            sage: f._check_getitem_args(slice(None, -1, -1))
     279            slice(9, 9, -1)
     280            sage: f._check_getitem_args(slice(None, 11, -1))
     281            slice(9, 9, -1)
     282            sage: f._check_getitem_args(slice(None, 10, -1))
     283            slice(9, 9, -1)
     284            sage: f._check_getitem_args(slice(None, 9, -1))
     285            slice(9, 9, -1)
     286            sage: f._check_getitem_args(slice(None, -10, -1))
     287            slice(9, 0, -1)
     288            sage: f._check_getitem_args(slice(None, -11, -1))
     289            slice(9, -1, -1)
     290            sage: f._check_getitem_args(slice(None, -12, -1))
     291            slice(9, -1, -1)
     292            sage: f._check_getitem_args(slice(0, None, -1))
     293            slice(0, -1, -1)
     294            sage: f._check_getitem_args(slice(1, None, -1))
     295            slice(1, -1, -1)
     296            sage: f._check_getitem_args(slice(-1, None, -1))
     297            slice(9, -1, -1)
     298            sage: f._check_getitem_args(slice(10, None, -1))
     299            slice(9, -1, -1)
     300            sage: f._check_getitem_args(slice(9, None, -1))
     301            slice(9, -1, -1)
     302            sage: f._check_getitem_args(slice(8, None, -1))
     303            slice(8, -1, -1)
     304            sage: f._check_getitem_args(slice(-10, None, -1))
     305            slice(0, -1, -1)
     306            sage: f._check_getitem_args(slice(-11, None, -1))
     307            slice(-1, -1, -1)
     308            sage: f._check_getitem_args(slice(-12, None, -1))
     309            slice(-1, -1, -1)
     310            sage: f._check_getitem_args(slice(None, None, 0))
     311            Traceback (most recent call last):
     312            ...
     313            ValueError: slice step cannot be zero
     314            sage: f._check_getitem_args(9)
     315            9
     316            sage: f._check_getitem_args(10)
     317            Traceback (most recent call last):
     318            ...
     319            IndexError: word index out of range
     320            sage: f._check_getitem_args(0)
     321            0
     322            sage: f._check_getitem_args(-1)
     323            9
     324            sage: f._check_getitem_args(-10)
     325            0
     326            sage: f._check_getitem_args(-11)
     327            Traceback (most recent call last):
     328            ...
     329            IndexError: word index out of range
     330       
     331        Infinite Cases
     332       
     333        ::
     334       
     335            sage: from itertools import count
     336            sage: i = sage.combinat.words.word_content.WordContentFromIterator(count())
     337            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     338            sage: i._check_getitem_args(slice(None, None, None))
     339            slice(0, None, 1)
     340            sage: i._check_getitem_args(slice(None, 0, None))
     341            slice(0, 0, 1)
     342            sage: i._check_getitem_args(slice(None, 1, None))
     343            slice(0, 1, 1)
     344            sage: i._check_getitem_args(slice(None, -1, None))
     345            Traceback (most recent call last):
     346            ...
     347            IndexError: negative index on infinite word
     348            sage: i._check_getitem_args(slice(0, None, None))
     349            slice(0, None, 1)
     350            sage: i._check_getitem_args(slice(1, None, None))
     351            slice(1, None, 1)
     352            sage: i._check_getitem_args(slice(-1, None, None))
     353            Traceback (most recent call last):
     354            ...
     355            IndexError: negative index on infinite word
     356            sage: i._check_getitem_args(slice(None, None, -1))
     357            Traceback (most recent call last):
     358            ...
     359            ValueError: negative step and no defined start
     360            sage: i._check_getitem_args(slice(None, 0, -1))
     361            Traceback (most recent call last):
     362            ...
     363            ValueError: negative step and no defined start
     364            sage: i._check_getitem_args(slice(None, -1, -1))
     365            Traceback (most recent call last):
     366            ...
     367            ValueError: negative step and no defined start
     368            sage: i._check_getitem_args(slice(0, None, -1))
     369            slice(0, -1, -1)
     370            sage: i._check_getitem_args(slice(-1, None, -1))
     371            Traceback (most recent call last):
     372            ...
     373            IndexError: negative index on infinite word
     374            sage: i._check_getitem_args(slice(None, None, 0))
     375            Traceback (most recent call last):
     376            ...
     377            ValueError: slice step cannot be zero
     378            sage: i._check_getitem_args(1)
     379            1
     380            sage: i._check_getitem_args(-1)
     381            Traceback (most recent call last):
     382            ...
     383            IndexError: negative index on infinite word
     384        """
     385        if slice_ok(key):
     386            start, stop, step = key.start, key.stop, key.step
     387            if step is None:
     388                step = 1
     389            if step == 0:
     390                raise ValueError, "slice step cannot be zero"
     391            if haslen(self):
     392                if start is None:
     393                    if step < 0:
     394                        start = len(self) - 1
     395                    else:
     396                        start = 0
     397                else:
     398                    if start < 0:
     399                        start += len(self)
     400                    if step < 0:
     401                        start = clamp(start, -1, len(self) - 1)
     402                    else:
     403                        start = clamp(start, 0, len(self))
     404                if stop is None:
     405                    if step < 0:
     406                        stop = -1
     407                    else:
     408                        stop = len(self)
     409                else:
     410                    if stop < 0:
     411                        stop += len(self)
     412                    if step < 0:
     413                        stop = clamp(stop, -1, len(self) - 1)
     414                    else:
     415                        stop = clamp(stop, 0, len(self))
     416            else:
     417                if start is None:
     418                    if step < 0:
     419                        raise ValueError, "negative step and no defined start"
     420                    else:
     421                        start = 0
     422                else:
     423                    start = self._check_getitem_args(start)
     424                if stop is None:
     425                    if step < 0:
     426                       stop = -1
     427                else:
     428                    stop = self._check_getitem_args(stop)
     429            return slice(start, stop, step)
     430        elif isint(key):
     431            key = int(key)
     432            if haslen(self):
     433                if key < 0:
     434                    key += len(self)
     435                if key < 0 or key >= len(self):
     436                    raise IndexError, "word index out of range"
     437            else:
     438                if key < 0:
     439                    raise IndexError, "negative index on infinite word"
     440            return key
     441        else:
     442            raise TypeError, "word indices must be integers"
     443
     444class WordContentFromList(WordContent):
     445    def __init__(self, l, trans=id_f):
     446        r"""
     447        INPUT:
     448       
     449       
     450        -  ``l`` - list
     451       
     452        -  ``trans`` - function (default identity), defines a
     453           mapping between the objects in l and the nonnegative integers
     454       
     455       
     456        TESTS::
     457       
     458            sage: c = sage.combinat.words.word_content.WordContentFromList([0, 1, 1, 2, 1])
     459            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     460            sage: c == loads(dumps(c))
     461            True
     462        """
     463        from sage.misc.misc import deprecation
     464        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
     465        self._list = map(trans, l)
     466   
     467    def __iter__(self):
     468        r"""
     469        TESTS::
     470       
     471            sage: list(sage.combinat.words.word_content.WordContentFromList('012345', int)) # indirect test
     472            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     473            [0, 1, 2, 3, 4, 5]
     474        """
     475        return iter(self._list)
     476   
     477    def __len__(self):
     478        r"""
     479        TESTS::
     480       
     481            sage: len(sage.combinat.words.word_content.WordContentFromList([0, 1, 0, 0, 1]))
     482            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     483            5
     484        """
     485        return len(self._list)
     486   
     487    def __getitem__(self, key):
     488        r"""
     489        TESTS::
     490       
     491            sage: from sage.combinat.words.word_content import WordContentFromList
     492            sage: w = WordContentFromList('012345', int)
     493            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     494            sage: e = WordContentFromList('', int)
     495            sage: w__2 = WordContentFromList('45', int)
     496            sage: w_2 = WordContentFromList('01', int)
     497            sage: w__1 = WordContentFromList('01234', int)
     498            sage: w_s2 = WordContentFromList('024', int)
     499            sage: w_s_2 = WordContentFromList('531', int)
     500            sage: w[:] == w
     501            True
     502            sage: w[0:] == w
     503            True
     504            sage: w[10:] == e
     505            True
     506            sage: w[-2:] == w__2
     507            True
     508            sage: w[-10:] == w
     509            True
     510            sage: w[:0] == e
     511            True
     512            sage: w[:2] == w_2
     513            True
     514            sage: w[:10] == w
     515            True
     516            sage: w[:-1] == w__1
     517            True
     518            sage: w[:-10] == e
     519            True
     520            sage: w[::2] == w_s2
     521            True
     522            sage: w[::-2] == w_s_2
     523            True
     524            sage: w[::0]
     525            Traceback (most recent call last):
     526            ...
     527            ValueError: slice step cannot be zero
     528            sage: w[0]
     529            0
     530            sage: w[5]
     531            5
     532            sage: w[6]
     533            Traceback (most recent call last):
     534            ...
     535            IndexError: word index out of range
     536            sage: w[-1]
     537            5
     538            sage: w[-6]
     539            0
     540            sage: w[-7]
     541            Traceback (most recent call last):
     542            ...
     543            IndexError: word index out of range
     544        """
     545        key = self._check_getitem_args(key)
     546        if isinstance(key, slice):
     547            if key.stop == -1:
     548                key = slice(key.start, None, key.step)
     549            return WordContentFromList(self._list[key])
     550        else:
     551            return self._list[key]
     552
     553class WordContentFromFunction(WordContent):
     554    def __init__(self, func, trans=id_f):
     555        r"""
     556        INPUT:
     557       
     558       
     559        -  ``func`` - callable
     560       
     561        -  ``trans`` - callable (default: identity), defines a
     562           mapping between the objects returned by func and the nonnegative
     563           integers.
     564       
     565       
     566        NOTE: Unnamed functions do not pickle. And if you arbitrarily slice
     567        this type of container then it may use lambdas and break pickling.
     568       
     569        TESTS::
     570       
     571            sage: c = sage.combinat.words.word_content.WordContentFromFunction(sage.combinat.words.utils.id_f)[:10]
     572            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     573            sage: c == loads(dumps(c))
     574            True
     575        """
     576        from sage.misc.misc import deprecation
     577        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
     578        self._func = func
     579        self._len = Infinity
     580        self._trans = trans
     581   
     582    def __iter__(self):
     583        r"""
     584        TESTS::
     585       
     586            sage: list(sage.combinat.words.word_content.WordContentFromFunction(sage.combinat.words.utils.id_f)[:6]) # indirect test
     587            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     588            [0, 1, 2, 3, 4, 5]
     589        """
     590        for i in xrange(self._len) if haslen(self) else count():
     591            yield self._trans(self._func(i))
     592   
     593    def __len__(self):
     594        r"""
     595        TESTS::
     596       
     597            sage: c = sage.combinat.words.word_content.WordContentFromFunction(sage.combinat.words.utils.id_f)
     598            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     599            sage: len(c)
     600            Traceback (most recent call last):
     601            ...
     602            TypeError: an integer is required
     603            sage: c = c[:10]
     604            sage: len(c)
     605            10
     606        """
     607        return self._len
     608   
     609    def __getitem__(self, key):
     610        r"""
     611        TESTS::
     612       
     613            sage: from sage.combinat.words.utils import id_f
     614            sage: from sage.combinat.words.word_content import WordContentFromFunction, WordContentFromList
     615            sage: w = WordContentFromFunction(id_f);
     616            doctest:...: DeprecationWarning: WordContentFromFunction is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     617            sage: e = WordContentFromList('', int)
     618            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     619            sage: w__2 = WordContentFromList('45', int)
     620            sage: w_2 = WordContentFromList('01', int)
     621            sage: w__1 = WordContentFromList('01234', int)
     622            sage: w_s2 = WordContentFromList('024', int)
     623            sage: w_s_2 = WordContentFromList('531', int)
     624            sage: w[:]          # random results
     625            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499c30>
     626            sage: w[0:]         # random results
     627            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499c50>
     628            sage: w[1:]         # random results
     629            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499c30>
     630            sage: w[:0] == e
     631            True
     632            sage: w[:5] == w__1
     633            True
     634            sage: w[::2]        # random results
     635            <sage.combinat.words.word_content.WordContentFromFunction object at 0xe499bf0>
     636            sage: w[::0]
     637            Traceback (most recent call last):
     638            ...
     639            ValueError: slice step cannot be zero
     640            sage: w[5]
     641            5
     642            sage: w[-1]
     643            Traceback (most recent call last):
     644            ...
     645            IndexError: negative index on infinite word
     646            sage: w._len = 6
     647            sage: w[:] == w
     648            True
     649            sage: w[0:] == w
     650            True
     651            sage: w[10:] == e
     652            True
     653            sage: w[-2:] == w__2
     654            True
     655            sage: w[-10:] == w
     656            True
     657            sage: w[:0] == e
     658            True
     659            sage: w[:2] == w_2
     660            True
     661            sage: w[:10] == w
     662            True
     663            sage: w[:-1] == w__1
     664            True
     665            sage: w[:-10] == e
     666            True
     667            sage: w[::2] == w_s2
     668            True
     669            sage: w[::-2] == w_s_2
     670            True
     671            sage: w[::0]
     672            Traceback (most recent call last):
     673            ...
     674            ValueError: slice step cannot be zero
     675            sage: w[0]
     676            0
     677            sage: w[5]
     678            5
     679            sage: w[6]
     680            Traceback (most recent call last):
     681            ...
     682            IndexError: word index out of range
     683            sage: w[-1]
     684            5
     685            sage: w[-6]
     686            0
     687            sage: w[-7]
     688            Traceback (most recent call last):
     689            ...
     690            IndexError: word index out of range
     691        """
     692        key = self._check_getitem_args(key)
     693        if isinstance(key, slice):
     694            if key.start != 0 or key.step != 1:
     695                # TODO: maybe use an accessory class for the slicing
     696                fn = lambda x: self._func(key.start + x*key.step)
     697            else:
     698                fn = self._func
     699            res = WordContentFromFunction(fn, self._trans)
     700            if key.stop is not None:
     701                res._len = int((key.stop - key.start)/key.step)
     702            return res
     703        else:
     704            return self._trans(self._func(key))
     705
     706class WordContentFromIterator(WordContent):
     707    def __init__(self, it, trans=id_f):
     708        r"""
     709        INPUT:
     710       
     711       
     712        -  ``it`` - iterator
     713       
     714        -  ``trans`` - function (default identity), defines a
     715           mapping between the objects returned by it and the nonnegative
     716           integers.
     717       
     718       
     719        NOTE: It appears that islice does not pickle correctly causing
     720        various errors when reloading. Also, most iterators do not support
     721        copying and should not support pickling by extension.
     722       
     723        TESTS::
     724       
     725            sage: from itertools import count
     726            sage: c = sage.combinat.words.word_content.WordContentFromIterator(count())[:10]
     727            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     728       
     729        ::
     730       
     731            #sage: c == loads(dumps(c)) # broken because of islice
     732            #True
     733        """
     734        from sage.misc.misc import deprecation
     735        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
     736        self._iter = iter(it)
     737        self._len = Infinity
     738        self._trans = trans
     739   
     740    def __iter__(self):
     741        r"""
     742        TESTS::
     743       
     744            sage: from itertools import count
     745            sage: list(sage.combinat.words.word_content.WordContentFromIterator(count())[:6]) # indirect test
     746            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     747            [0, 1, 2, 3, 4, 5]
     748        """
     749        return imap(self._trans, self._get_it())
     750   
     751    def _get_it(self):
     752        r"""
     753        TESTS::
     754       
     755            sage: from itertools import count
     756            sage: c = sage.combinat.words.word_content.WordContentFromIterator(count())
     757            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     758            sage: it1 = c._get_it()
     759            sage: it2 = c._get_it()
     760            sage: it1.next()
     761            0
     762            sage: it2.next()
     763            0
     764            sage: list(c[:4])
     765            [0, 1, 2, 3]
     766            sage: it1.next()
     767            1
     768            sage: it2.next()
     769            1
     770        """
     771        self._iter, new = copy_it(self._iter)
     772        return new
     773   
     774    def __len__(self):
     775        r"""
     776        TESTS::
     777       
     778            sage: from itertools import count
     779            sage: c = sage.combinat.words.word_content.WordContentFromIterator(count())
     780            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     781            sage: len(c)
     782            Traceback (most recent call last):
     783            ...
     784            TypeError: an integer is required
     785            sage: c = c[:10]
     786            sage: len(c)
     787            10
     788        """
     789        return self._len
     790   
     791    def __getitem__(self, key):
     792        r"""
     793        TESTS::
     794       
     795            sage: from itertools import count
     796            sage: from sage.combinat.words.word_content import WordContentFromIterator, WordContentFromList
     797            sage: w = WordContentFromIterator(count())
     798            doctest:...: DeprecationWarning: WordContentFromIterator is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     799            sage: e = WordContentFromList('', int)
     800            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     801            sage: w__2 = WordContentFromList('45', int)
     802            sage: w_2 = WordContentFromList('01', int)
     803            sage: w__1 = WordContentFromList('01234', int)
     804            sage: w_s2 = WordContentFromList('024', int)
     805            sage: w_s_2 = WordContentFromList('531', int)
     806            sage: w[:]          # random results
     807            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499c30>
     808            sage: w[0:]         # random results
     809            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499c50>
     810            sage: w[1:]         # random results
     811            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499c30>
     812            sage: w[:0] == e
     813            True
     814            sage: w[:5] == w__1
     815            True
     816            sage: w[::2]        # random results
     817            <sage.combinat.words.word_content.WordContentFromIterator object at 0xe499bf0>
     818            sage: w[::0]
     819            Traceback (most recent call last):
     820            ...
     821            ValueError: slice step cannot be zero
     822            sage: w[5]
     823            5
     824            sage: w[-1]
     825            Traceback (most recent call last):
     826            ...
     827            IndexError: negative index on infinite word
     828            sage: w._len = 6
     829            sage: w[:] == w
     830            True
     831            sage: w[0:] == w
     832            True
     833            sage: w[10:] == e
     834            True
     835            sage: w[-2:] == w__2
     836            True
     837            sage: w[-10:] == w
     838            True
     839            sage: w[:0] == e
     840            True
     841            sage: w[:2] == w_2
     842            True
     843            sage: w[:10] == w
     844            True
     845            sage: w[:-1] == w__1
     846            True
     847            sage: w[:-10] == e
     848            True
     849            sage: w[::2] == w_s2
     850            True
     851            sage: w[::-2] == w_s_2
     852            doctest:...: DeprecationWarning: WordContentFromList is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     853            True
     854            sage: w[::0]
     855            Traceback (most recent call last):
     856            ...
     857            ValueError: slice step cannot be zero
     858            sage: w[0]
     859            0
     860            sage: w[5]
     861            5
     862            sage: w[6]
     863            Traceback (most recent call last):
     864            ...
     865            IndexError: word index out of range
     866            sage: w[-1]
     867            5
     868            sage: w[-6]
     869            0
     870            sage: w[-7]
     871            Traceback (most recent call last):
     872            ...
     873            IndexError: word index out of range
     874        """
     875        key = self._check_getitem_args(key)
     876        if isinstance(key, slice):
     877            if key.step < 0:
     878                if key.stop == -1:
     879                    key = slice(key.start, None, key.step)
     880                if haslen(self):
     881                    return WordContentFromList(slice_it(self, len(self), key))
     882                else:
     883                    return WordContentFromList(slice_it(self, \
     884                                int(key.start - key.stop), key))
     885            else:
     886                res = WordContentFromIterator(islice(self._get_it(), key.start, \
     887                                              key.stop, key.step), self._trans)
     888                if key.stop is not None:
     889                    res._len = int((key.stop - key.start)/key.step)
     890                return res
     891        else:
     892            return islice(self, key, None).next()
     893
     894class ConcatenateContent(WordContentFromFunction):
     895    r"""
     896    Class that acts as a function to concatenate contents.
     897    """
     898    def __init__(self, l):
     899        r"""
     900        TESTS::
     901       
     902            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
     903            sage: c = ConcatenateContent((BuildWordContent([1, 2]),))
     904            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     905            sage: len(c)
     906            2
     907            sage: c = ConcatenateContent((BuildWordContent('1221', int), BuildWordContent('2112', int)))
     908            sage: len(c)
     909            8
     910        """
     911        from sage.misc.misc import deprecation
     912        deprecation('%s is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives' % self.__class__.__name__)
     913        self._list = l
     914        super(ConcatenateContent, self).__init__(self)
     915        self._len = sum(imap(len, self._list))
     916   
     917    def __iter__(self):
     918        r"""
     919        TESTS::
     920       
     921            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
     922            sage: list(ConcatenateContent((BuildWordContent('012', int), BuildWordContent([3, 4, 5])))) # indirect test
     923            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     924            [0, 1, 2, 3, 4, 5]
     925        """
     926        for c in self._list:
     927            for s in c:
     928                yield s
     929   
     930    def _get_list(self):
     931        r"""
     932        Optimization: for ConcatenateContents return the internal list.
     933       
     934        TESTS::
     935       
     936            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
     937            sage: type(ConcatenateContent((BuildWordContent([1, 2]),))._get_list())
     938            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     939            <type 'tuple'>
     940        """
     941        return self._list
     942   
     943    def __call__(self, key):
     944        r"""
     945        Returns the character at position key in the word.
     946       
     947        EXAMPLES::
     948       
     949            sage: from sage.combinat.words.word_content import ConcatenateContent, BuildWordContent
     950            sage: c = ConcatenateContent((BuildWordContent('1221', int), BuildWordContent('2112', int)))
     951            doctest:...: DeprecationWarning: ConcatenateContent is deprecated and will be deleted in a future version of Sage; see sage.combinat.words.word_datatypes for alternatives
     952            sage: c(0)
     953            1
     954            sage: c(7)
     955            2
     956        """
     957        for c in self._list:
     958            if (key - len(c) < 0):
     959                return c[key]
     960            key -= len(c)
  • sage/combinat/words/words.py

    diff -r dc22b8baa725 -r 3ba698f579d6 sage/combinat/words/words.py
    a b  
    10071007
    10081008###########################################################################
    10091009##### DEPRECATION WARNINGS ################################################
    1010 ##### Added 5 February 2008 ###############################################
     1010##### Added July 2009 #####################################################
    10111011###########################################################################
    10121012
    10131013def is_Words(obj):