Delete unneeded directory
[jabaws.git] / website / archive / binaries / mac / src / globplot / biopython-1.50 / Bio / Seq.py
diff --git a/website/archive/binaries/mac/src/globplot/biopython-1.50/Bio/Seq.py b/website/archive/binaries/mac/src/globplot/biopython-1.50/Bio/Seq.py
deleted file mode 100644 (file)
index d32d8e7..0000000
+++ /dev/null
@@ -1,1633 +0,0 @@
-# Copyright 2000-2002 Brad Chapman.
-# Copyright 2004-2005 by M de Hoon.
-# Copyright 2007-2009 by Peter Cock.
-# All rights reserved.
-# This code is part of the Biopython distribution and governed by its
-# license.  Please see the LICENSE file that should have been included
-# as part of this package.
-"""Provides objects to represent biological sequences with alphabets.
-
-See also U{http://biopython.org/wiki/Seq} and the chapter in our tutorial:
- - U{http://biopython.org/DIST/docs/tutorial/Tutorial.html}
- - U{http://biopython.org/DIST/docs/tutorial/Tutorial.pdf}
-"""
-__docformat__ ="epytext en" #Don't just use plain text in epydoc API pages!
-
-import string #for maketrans only
-import array
-import sys
-
-#TODO - Remove this work around once we drop python 2.3 support
-try:
-    set = set
-except NameError:
-    from sets import Set as set
-
-import Alphabet
-from Alphabet import IUPAC
-from Data.IUPACData import ambiguous_dna_complement, ambiguous_rna_complement
-from Bio.Data import CodonTable
-
-def _maketrans(complement_mapping) :
-    """Makes a python string translation table (PRIVATE).
-
-    Arguments:
-     - complement_mapping - a dictionary such as ambiguous_dna_complement
-       and ambiguous_rna_complement from Data.IUPACData.
-
-    Returns a translation table (a string of length 256) for use with the
-    python string's translate method to use in a (reverse) complement.
-    
-    Compatible with lower case and upper case sequences.
-
-    For internal use only.
-    """
-    before = ''.join(complement_mapping.keys())
-    after  = ''.join(complement_mapping.values())
-    before = before + before.lower()
-    after  = after + after.lower()
-    return string.maketrans(before, after)
-
-_dna_complement_table = _maketrans(ambiguous_dna_complement)
-_rna_complement_table = _maketrans(ambiguous_rna_complement)
-
-class Seq(object):
-    """A read-only sequence object (essentially a string with an alphabet).
-
-    Like normal python strings, our basic sequence object is immutable.
-    This prevents you from doing my_seq[5] = "A" for example, but does allow
-    Seq objects to be used as dictionary keys.
-
-    The Seq object provides a number of string like methods (such as count,
-    find, split and strip), which are alphabet aware where appropriate.
-
-    The Seq object also provides some biological methods, such as complement,
-    reverse_complement, transcribe, back_transcribe and translate (which are
-    not applicable to sequences with a protein alphabet).
-    """
-    def __init__(self, data, alphabet = Alphabet.generic_alphabet):
-        """Create a Seq object.
-
-        Arguments:
-         - seq      - Sequence, required (string)
-         - alphabet - Optional argument, an Alphabet object from Bio.Alphabet
-        
-        You will typically use Bio.SeqIO to read in sequences from files as
-        SeqRecord objects, whose sequence will be exposed as a Seq object via
-        the seq property.
-
-        However, will often want to create your own Seq objects directly:
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import IUPAC
-        >>> my_seq = Seq("MKQHKAMIVALIVICITAVVAALVTRKDLCEVHIRTGQTEVAVF",
-        ...              IUPAC.protein)
-        >>> my_seq
-        Seq('MKQHKAMIVALIVICITAVVAALVTRKDLCEVHIRTGQTEVAVF', IUPACProtein())
-        >>> print my_seq
-        MKQHKAMIVALIVICITAVVAALVTRKDLCEVHIRTGQTEVAVF
-        """
-        # Enforce string storage
-        assert (type(data) == type("") or # must use a string
-                type(data) == type(u""))  # but can be a unicode string
-        self._data = data
-        self.alphabet = alphabet  # Seq API requirement
-    # A data property is/was a Seq API requirement
-    def _set_data(self, value) :
-        #TODO - In the next release, actually raise an exception?
-        #The Seq object is like a python string, it should be read only!
-        import warnings
-        warnings.warn("Writing to the Seq object's .data propery is deprecated.",
-                      DeprecationWarning)
-        self._data = value
-    data = property(fget= lambda self : str(self),
-                    fset=_set_data,
-                    doc="Sequence as a string (DEPRECATED)")
-
-    def __repr__(self):
-        """Returns a (truncated) representation of the sequence for debugging."""
-        if len(self) > 60 :
-            #Shows the last three letters as it is often useful to see if there
-            #is a stop codon at the end of a sequence.
-            #Note total length is 54+3+3=60
-            return "%s('%s...%s', %s)" % (self.__class__.__name__,
-                                   str(self)[:54], str(self)[-3:],
-                                   repr(self.alphabet))
-        else :
-            return "%s(%s, %s)" % (self.__class__.__name__,
-                                  repr(self.data),
-                                   repr(self.alphabet))
-    def __str__(self):
-        """Returns the full sequence as a python string.
-
-        Note that Biopython 1.44 and earlier would give a truncated
-        version of repr(my_seq) for str(my_seq).  If you are writing code
-        which need to be backwards compatible with old Biopython, you
-        should continue to use my_seq.tostring() rather than str(my_seq).
-        """
-        return self._data
-
-    """
-    TODO - Work out why this breaks test_Restriction.py
-    (Comparing Seq objects would be nice to have.  May need to think about
-    hashes and the in operator for when have list/dictionary of Seq objects...)
-    def __cmp__(self, other):
-        if hasattr(other, "alphabet") :
-            #other should be a Seq or a MutableSeq
-            if not Alphabet._check_type_compatible([self.alphabet,
-                                                    other.alphabet]) :
-                raise TypeError("Incompatable alphabets %s and %s" \
-                                % (repr(self.alphabet), repr(other.alphabet)))
-            #They should be the same sequence type (or one of them is generic)
-            return cmp(str(self), str(other))
-        elif isinstance(other, basestring) :
-            return cmp(str(self), other)
-        else :
-            raise TypeError
-    """
-
-    def __len__(self): return len(self._data)       # Seq API requirement
-
-    def __getitem__(self, index) :                 # Seq API requirement
-        #Note since Python 2.0, __getslice__ is deprecated
-        #and __getitem__ is used instead.
-        #See http://docs.python.org/ref/sequence-methods.html
-        if isinstance(index, int) :
-            #Return a single letter as a string
-            return self._data[index]
-        else :
-            #Return the (sub)sequence as another Seq object
-            return Seq(self._data[index], self.alphabet)
-
-    def __add__(self, other):
-        """Add another sequence or string to this sequence."""
-        if hasattr(other, "alphabet") :
-            #other should be a Seq or a MutableSeq
-            if not Alphabet._check_type_compatible([self.alphabet,
-                                                    other.alphabet]) :
-                raise TypeError("Incompatable alphabets %s and %s" \
-                                % (repr(self.alphabet), repr(other.alphabet)))
-            #They should be the same sequence type (or one of them is generic)
-            a = Alphabet._consensus_alphabet([self.alphabet, other.alphabet])
-            return self.__class__(str(self) + str(other), a)
-        elif isinstance(other, basestring) :
-            #other is a plain string - use the current alphabet
-            return self.__class__(str(self) + other, self.alphabet)
-        else :
-            raise TypeError
-
-    def __radd__(self, other):
-        if hasattr(other, "alphabet") :
-            #other should be a Seq or a MutableSeq
-            if not Alphabet._check_type_compatible([self.alphabet,
-                                                    other.alphabet]) :
-                raise TypeError("Incompatable alphabets %s and %s" \
-                                % (repr(self.alphabet), repr(other.alphabet)))
-            #They should be the same sequence type (or one of them is generic)
-            a = Alphabet._consensus_alphabet([self.alphabet, other.alphabet])
-            return self.__class__(str(other) + str(self), a)
-        elif isinstance(other, basestring) :
-            #other is a plain string - use the current alphabet
-            return self.__class__(other + str(self), self.alphabet)
-        else :
-            raise TypeError
-
-    def tostring(self):                            # Seq API requirement
-        """Returns the full sequence as a python string.
-
-        Although not formally deprecated, you are now encouraged to use
-        str(my_seq) instead of my_seq.tostring()."""
-        return str(self)
-    
-    def tomutable(self):   # Needed?  Or use a function?
-        """Returns the full sequence as a MutableSeq object.
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import IUPAC
-        >>> my_seq = Seq("MKQHKAMIVALIVICITAVVAAL",
-        ...              IUPAC.protein)
-        >>> my_seq
-        Seq('MKQHKAMIVALIVICITAVVAAL', IUPACProtein())
-        >>> my_seq.tomutable()
-        MutableSeq('MKQHKAMIVALIVICITAVVAAL', IUPACProtein())
-
-        Note that the alphabet is preserved.
-        """
-        return MutableSeq(str(self), self.alphabet)
-
-    def _get_seq_str_and_check_alphabet(self, other_sequence) :
-        """string/Seq/MutableSeq to string, checking alphabet (PRIVATE).
-
-        For a string argument, returns the string.
-
-        For a Seq or MutableSeq, it checks the alphabet is compatible
-        (raising an exception if it isn't), and then returns a string.
-        """
-        try :
-            other_alpha = other_sequence.alphabet
-        except AttributeError :
-            #Assume other_sequence is a string
-            return other_sequence
-
-        #Other should be a Seq or a MutableSeq
-        if not Alphabet._check_type_compatible([self.alphabet, other_alpha]) :
-            raise TypeError("Incompatable alphabets %s and %s" \
-                            % (repr(self.alphabet), repr(other_alpha)))
-        #Return as a string
-        return str(other_sequence)
-    
-    def count(self, sub, start=0, end=sys.maxint):
-        """Non-overlapping count method, like that of a python string.
-
-        This behaves like the python string method of the same name,
-        which does a non-overlapping count!
-
-        Returns an integer, the number of occurrences of substring
-        argument sub in the (sub)sequence given by [start:end].
-        Optional arguments start and end are interpreted as in slice
-        notation.
-    
-        Arguments:
-         - sub - a string or another Seq object to look for
-         - start - optional integer, slice start
-         - end - optional integer, slice end
-
-        e.g.
-
-        >>> from Bio.Seq import Seq
-        >>> my_seq = Seq("AAAATGA")
-        >>> print my_seq.count("A")
-        5
-        >>> print my_seq.count("ATG")
-        1
-        >>> print my_seq.count(Seq("AT"))
-        1
-        >>> print my_seq.count("AT", 2, -1)
-        1
-
-        HOWEVER, please note because python strings and Seq objects (and
-        MutableSeq objects) do a non-overlapping search, this may not give
-        the answer you expect:
-
-        >>> "AAAA".count("AA")
-        2
-        >>> print Seq("AAAA").count("AA")
-        2
-
-        A non-overlapping search would give the answer as three!
-        """
-        #If it has one, check the alphabet:
-        sub_str = self._get_seq_str_and_check_alphabet(sub)
-        return str(self).count(sub_str, start, end)
-
-    def find(self, sub, start=0, end=sys.maxint):
-        """Find method, like that of a python string.
-
-        This behaves like the python string method of the same name.
-
-        Returns an integer, the index of the first occurrence of substring
-        argument sub in the (sub)sequence given by [start:end].
-
-        Arguments:
-         - sub - a string or another Seq object to look for
-         - start - optional integer, slice start
-         - end - optional integer, slice end
-
-        Returns -1 if the subsequence is NOT found.
-
-        e.g. Locating the first typical start codon, AUG, in an RNA sequence:
-
-        >>> from Bio.Seq import Seq
-        >>> my_rna = Seq("GUCAUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAGUUG")
-        >>> my_rna.find("AUG")
-        3
-        """
-        #If it has one, check the alphabet:
-        sub_str = self._get_seq_str_and_check_alphabet(sub)
-        return str(self).find(sub_str, start, end)
-
-    def rfind(self, sub, start=0, end=sys.maxint):
-        """Find from right method, like that of a python string.
-
-        This behaves like the python string method of the same name.
-
-        Returns an integer, the index of the last (right most) occurrence of
-        substring argument sub in the (sub)sequence given by [start:end].
-
-        Arguments:
-         - sub - a string or another Seq object to look for
-         - start - optional integer, slice start
-         - end - optional integer, slice end
-
-        Returns -1 if the subsequence is NOT found.
-
-        e.g. Locating the last typical start codon, AUG, in an RNA sequence:
-
-        >>> from Bio.Seq import Seq
-        >>> my_rna = Seq("GUCAUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAGUUG")
-        >>> my_rna.rfind("AUG")
-        15
-        """
-        #If it has one, check the alphabet:
-        sub_str = self._get_seq_str_and_check_alphabet(sub)
-        return str(self).rfind(sub_str, start, end)
-
-    def startswith(self, prefix, start=0, end=sys.maxint) :
-        """Does the Seq start with the given prefix?  Returns True/False.
-
-        This behaves like the python string method of the same name.
-
-        Return True if the sequence starts with the specified prefix
-        (a string or another Seq object), False otherwise.
-        With optional start, test sequence beginning at that position.
-        With optional end, stop comparing sequence at that position.
-        prefix can also be a tuple of strings to try.  e.g.
-        
-        >>> from Bio.Seq import Seq
-        >>> my_rna = Seq("GUCAUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAGUUG")
-        >>> my_rna.startswith("GUC")
-        True
-        >>> my_rna.startswith("AUG")
-        False
-        >>> my_rna.startswith("AUG", 3)
-        True
-        >>> my_rna.startswith(("UCC","UCA","UCG"),1)
-        True
-        """
-        #If it has one, check the alphabet:
-        if isinstance(prefix, tuple) :
-            #TODO - Once we drop support for Python 2.4, instead of this
-            #loop offload to the string method (requires Python 2.5+).
-            #Check all the alphabets first...
-            prefix_strings = [self._get_seq_str_and_check_alphabet(p) \
-                              for p in prefix]
-            for prefix_str in prefix_strings :
-                if str(self).startswith(prefix_str, start, end) :
-                    return True
-            return False
-        else :
-            prefix_str = self._get_seq_str_and_check_alphabet(prefix)
-            return str(self).startswith(prefix_str, start, end)
-
-    def endswith(self, suffix, start=0, end=sys.maxint) :
-        """Does the Seq end with the given suffix?  Returns True/False.
-
-        This behaves like the python string method of the same name.
-
-        Return True if the sequence ends with the specified suffix
-        (a string or another Seq object), False otherwise.
-        With optional start, test sequence beginning at that position.
-        With optional end, stop comparing sequence at that position.
-        suffix can also be a tuple of strings to try.  e.g.
-
-        >>> from Bio.Seq import Seq
-        >>> my_rna = Seq("GUCAUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAGUUG")
-        >>> my_rna.endswith("UUG")
-        True
-        >>> my_rna.endswith("AUG")
-        False
-        >>> my_rna.endswith("AUG", 0, 18)
-        True
-        >>> my_rna.endswith(("UCC","UCA","UUG"))
-        True
-        """        
-        #If it has one, check the alphabet:
-        if isinstance(suffix, tuple) :
-            #TODO - Once we drop support for Python 2.4, instead of this
-            #loop offload to the string method (requires Python 2.5+).
-            #Check all the alphabets first...
-            suffix_strings = [self._get_seq_str_and_check_alphabet(p) \
-                              for p in suffix]
-            for suffix_str in suffix_strings :
-                if str(self).endswith(suffix_str, start, end) :
-                    return True
-            return False
-        else :
-            suffix_str = self._get_seq_str_and_check_alphabet(suffix)
-            return str(self).endswith(suffix_str, start, end)
-
-
-    def split(self, sep=None, maxsplit=-1) :
-        """Split method, like that of a python string.
-
-        This behaves like the python string method of the same name.
-
-        Return a list of the 'words' in the string (as Seq objects),
-        using sep as the delimiter string.  If maxsplit is given, at
-        most maxsplit splits are done.  If maxsplit is ommited, all
-        splits are made.
-
-        Following the python string method, sep will by default be any
-        white space (tabs, spaces, newlines) but this is unlikely to
-        apply to biological sequences.
-        
-        e.g.
-
-        >>> from Bio.Seq import Seq
-        >>> my_rna = Seq("GUCAUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAGUUG")
-        >>> my_aa = my_rna.translate()
-        >>> my_aa
-        Seq('VMAIVMGR*KGAR*L', HasStopCodon(ExtendedIUPACProtein(), '*'))
-        >>> my_aa.split("*")
-        [Seq('VMAIVMGR', HasStopCodon(ExtendedIUPACProtein(), '*')), Seq('KGAR', HasStopCodon(ExtendedIUPACProtein(), '*')), Seq('L', HasStopCodon(ExtendedIUPACProtein(), '*'))]
-        >>> my_aa.split("*",1)
-        [Seq('VMAIVMGR', HasStopCodon(ExtendedIUPACProtein(), '*')), Seq('KGAR*L', HasStopCodon(ExtendedIUPACProtein(), '*'))]
-
-        See also the rsplit method:
-
-        >>> my_aa.rsplit("*",1)
-        [Seq('VMAIVMGR*KGAR', HasStopCodon(ExtendedIUPACProtein(), '*')), Seq('L', HasStopCodon(ExtendedIUPACProtein(), '*'))]
-        """
-        #If it has one, check the alphabet:
-        sep_str = self._get_seq_str_and_check_alphabet(sep)
-        #TODO - If the sep is the defined stop symbol, or gap char,
-        #should we adjust the alphabet?
-        return [Seq(part, self.alphabet) \
-                for part in str(self).split(sep_str, maxsplit)]
-
-    def rsplit(self, sep=None, maxsplit=-1) :
-        """Right split method, like that of a python string.
-
-        This behaves like the python string method of the same name.
-
-        Return a list of the 'words' in the string (as Seq objects),
-        using sep as the delimiter string.  If maxsplit is given, at
-        most maxsplit splits are done COUNTING FROM THE RIGHT.
-        If maxsplit is ommited, all splits are made.
-
-        Following the python string method, sep will by default be any
-        white space (tabs, spaces, newlines) but this is unlikely to
-        apply to biological sequences.
-        
-        e.g. print my_seq.rsplit("*",1)
-
-        See also the split method.
-        """
-        #If it has one, check the alphabet:
-        sep_str = self._get_seq_str_and_check_alphabet(sep)
-        try :
-            return [Seq(part, self.alphabet) \
-                    for part in str(self).rsplit(sep_str, maxsplit)]
-        except AttributeError :
-            #Python 2.3 doesn't have a string rsplit method, which we can
-            #word around by reversing the sequence, using (left) split,
-            #and then reversing the answer. Not very efficient!
-            words = [Seq(word[::-1], self.alphabet) for word \
-                     in str(self)[::-1].split(sep_str[::-1], maxsplit)]
-            words.reverse()
-            return words
-
-    def strip(self, chars=None) :
-        """Returns a new Seq object with leading and trailing ends stripped.
-
-        This behaves like the python string method of the same name.
-
-        Optional argument chars defines which characters to remove.  If
-        ommitted or None (default) then as for the python string method,
-        this defaults to removing any white space.
-        
-        e.g. print my_seq.strip("-")
-
-        See also the lstrip and rstrip methods.
-        """
-        #If it has one, check the alphabet:
-        strip_str = self._get_seq_str_and_check_alphabet(chars)
-        return Seq(str(self).strip(strip_str), self.alphabet)
-
-    def lstrip(self, chars=None) :
-        """Returns a new Seq object with leading (left) end stripped.
-
-        This behaves like the python string method of the same name.
-
-        Optional argument chars defines which characters to remove.  If
-        ommitted or None (default) then as for the python string method,
-        this defaults to removing any white space.
-        
-        e.g. print my_seq.lstrip("-")
-
-        See also the strip and rstrip methods.
-        """
-        #If it has one, check the alphabet:
-        strip_str = self._get_seq_str_and_check_alphabet(chars)
-        return Seq(str(self).lstrip(strip_str), self.alphabet)
-
-    def rstrip(self, chars=None) :
-        """Returns a new Seq object with trailing (right) end stripped.
-
-        This behaves like the python string method of the same name.
-
-        Optional argument chars defines which characters to remove.  If
-        ommitted or None (default) then as for the python string method,
-        this defaults to removing any white space.
-        
-        e.g. Removing a nucleotide sequence's polyadenylation (poly-A tail):
-
-        >>> from Bio.Alphabet import IUPAC
-        >>> from Bio.Seq import Seq
-        >>> my_seq = Seq("CGGTACGCTTATGTCACGTAGAAAAAA", IUPAC.unambiguous_dna)
-        >>> my_seq
-        Seq('CGGTACGCTTATGTCACGTAGAAAAAA', IUPACUnambiguousDNA())
-        >>> my_seq.rstrip("A")
-        Seq('CGGTACGCTTATGTCACGTAG', IUPACUnambiguousDNA())
-
-        See also the strip and lstrip methods.
-        """
-        #If it has one, check the alphabet:
-        strip_str = self._get_seq_str_and_check_alphabet(chars)
-        return Seq(str(self).rstrip(strip_str), self.alphabet)
-
-    def complement(self):
-        """Returns the complement sequence. New Seq object.
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import IUPAC
-        >>> my_dna = Seq("CCCCCGATAG", IUPAC.unambiguous_dna)
-        >>> my_dna
-        Seq('CCCCCGATAG', IUPACUnambiguousDNA())
-        >>> my_dna.complement()
-        Seq('GGGGGCTATC', IUPACUnambiguousDNA())
-
-        You can of course used mixed case sequences,
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import generic_dna
-        >>> my_dna = Seq("CCCCCgatA-GD", generic_dna)
-        >>> my_dna
-        Seq('CCCCCgatA-GD', DNAAlphabet())
-        >>> my_dna.complement()
-        Seq('GGGGGctaT-CH', DNAAlphabet())
-
-        Note in the above example, ambiguous character D denotes
-        G, A or T so its complement is H (for C, T or A).
-        
-        Trying to complement a protein sequence raises an exception.
-
-        >>> my_protein = Seq("MAIVMGR", IUPAC.protein)
-        >>> my_protein.complement()
-        Traceback (most recent call last):
-           ...
-        ValueError: Proteins do not have complements!
-        """
-        base = Alphabet._get_base_alphabet(self.alphabet)
-        if isinstance(base, Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins do not have complements!")
-        if isinstance(base, Alphabet.DNAAlphabet) :
-            ttable = _dna_complement_table
-        elif isinstance(base, Alphabet.RNAAlphabet) :
-            ttable = _rna_complement_table
-        elif ('U' in self._data or 'u' in self._data) \
-        and ('T' in self._data or 't' in self._data):
-            #TODO - Handle this cleanly?
-            raise ValueError("Mixed RNA/DNA found")
-        elif 'U' in self._data or 'u' in self._data:
-            ttable = _rna_complement_table
-        else:
-            ttable = _dna_complement_table
-        #Much faster on really long sequences than the previous loop based one.
-        #thx to Michael Palmer, University of Waterloo
-        return Seq(str(self).translate(ttable), self.alphabet)
-
-    def reverse_complement(self):
-        """Returns the reverse complement sequence. New Seq object.
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import IUPAC
-        >>> my_dna = Seq("CCCCCGATAGNR", IUPAC.ambiguous_dna)
-        >>> my_dna
-        Seq('CCCCCGATAGNR', IUPACAmbiguousDNA())
-        >>> my_dna.reverse_complement()
-        Seq('YNCTATCGGGGG', IUPACAmbiguousDNA())
-
-        Note in the above example, since R = G or A, its complement
-        is Y (which denotes  C or T).
-
-        You can of course used mixed case sequences,
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import generic_dna
-        >>> my_dna = Seq("CCCCCgatA-G", generic_dna)
-        >>> my_dna
-        Seq('CCCCCgatA-G', DNAAlphabet())
-        >>> my_dna.reverse_complement()
-        Seq('C-TatcGGGGG', DNAAlphabet())
-
-        Trying to complement a protein sequence raises an exception:
-
-        >>> my_protein = Seq("MAIVMGR", IUPAC.protein)
-        >>> my_protein.reverse_complement()
-        Traceback (most recent call last):
-           ...
-        ValueError: Proteins do not have complements!
-        """
-        #Use -1 stride/step to reverse the complement
-        return self.complement()[::-1]
-
-    def transcribe(self):
-        """Returns the RNA sequence from a DNA sequence. New Seq object.
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import IUPAC
-        >>> coding_dna = Seq("ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG",
-        ...                  IUPAC.unambiguous_dna)
-        >>> coding_dna
-        Seq('ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG', IUPACUnambiguousDNA())
-        >>> coding_dna.transcribe()
-        Seq('AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG', IUPACUnambiguousRNA())
-
-        Trying to transcribe a protein or RNA sequence raises an exception:
-
-        >>> my_protein = Seq("MAIVMGR", IUPAC.protein)
-        >>> my_protein.transcribe()
-        Traceback (most recent call last):
-           ...
-        ValueError: Proteins cannot be transcribed!
-        """
-        base = Alphabet._get_base_alphabet(self.alphabet)
-        if isinstance(base, Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins cannot be transcribed!")
-        if isinstance(base, Alphabet.RNAAlphabet) :
-            raise ValueError("RNA cannot be transcribed!")
-
-        if self.alphabet==IUPAC.unambiguous_dna:
-            alphabet = IUPAC.unambiguous_rna
-        elif self.alphabet==IUPAC.ambiguous_dna:
-            alphabet = IUPAC.ambiguous_rna
-        else:
-            alphabet = Alphabet.generic_rna
-        return Seq(str(self).replace('T','U').replace('t','u'), alphabet)
-    
-    def back_transcribe(self):
-        """Returns the DNA sequence from an RNA sequence. New Seq object.
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import IUPAC
-        >>> messenger_rna = Seq("AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG",
-        ...                     IUPAC.unambiguous_rna)
-        >>> messenger_rna
-        Seq('AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG', IUPACUnambiguousRNA())
-        >>> messenger_rna.back_transcribe()
-        Seq('ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG', IUPACUnambiguousDNA())
-
-        Trying to back-transcribe a protein or DNA sequence raises an
-        exception:
-
-        >>> my_protein = Seq("MAIVMGR", IUPAC.protein)
-        >>> my_protein.back_transcribe()
-        Traceback (most recent call last):
-           ...
-        ValueError: Proteins cannot be back transcribed!
-        """
-        base = Alphabet._get_base_alphabet(self.alphabet)
-        if isinstance(base, Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins cannot be back transcribed!")
-        if isinstance(base, Alphabet.DNAAlphabet) :
-            raise ValueError("DNA cannot be back transcribed!")
-
-        if self.alphabet==IUPAC.unambiguous_rna:
-            alphabet = IUPAC.unambiguous_dna
-        elif self.alphabet==IUPAC.ambiguous_rna:
-            alphabet = IUPAC.ambiguous_dna
-        else:
-            alphabet = Alphabet.generic_dna
-        return Seq(str(self).replace("U", "T").replace("u", "t"), alphabet)
-
-    def translate(self, table="Standard", stop_symbol="*", to_stop=False):
-        """Turns a nucleotide sequence into a protein sequence. New Seq object.
-
-        This method will translate DNA or RNA sequences, and those with a
-        nucleotide or generic alphabet.  Trying to translate a protein
-        sequence raises an exception.
-
-        Arguments:
-         - table - Which codon table to use?  This can be either a name
-                   (string) or an NCBI identifier (integer).  This defaults
-                   to the "Standard" table.
-         - stop_symbol - Single character string, what to use for terminators.
-                         This defaults to the asterisk, "*".
-         - to_stop - Boolean, defaults to False meaning do a full translation
-                     continuing on past any stop codons (translated as the
-                     specified stop_symbol).  If True, translation is
-                     terminated at the first in frame stop codon (and the
-                     stop_symbol is not appended to the returned protein
-                     sequence).
-
-        e.g. Using the standard table:
-
-        >>> coding_dna = Seq("GTGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG")
-        >>> coding_dna.translate()
-        Seq('VAIVMGR*KGAR*', HasStopCodon(ExtendedIUPACProtein(), '*'))
-        >>> coding_dna.translate(stop_symbol="@")
-        Seq('VAIVMGR@KGAR@', HasStopCodon(ExtendedIUPACProtein(), '@'))
-        >>> coding_dna.translate(to_stop=True)
-        Seq('VAIVMGR', ExtendedIUPACProtein())
-
-        Now using NCBI table 2, where TGA is not a stop codon:
-
-        >>> coding_dna.translate(table=2)
-        Seq('VAIVMGRWKGAR*', HasStopCodon(ExtendedIUPACProtein(), '*'))
-        >>> coding_dna.translate(table=2, to_stop=True)
-        Seq('VAIVMGRWKGAR', ExtendedIUPACProtein())
-
-        If the sequence has no in-frame stop codon, then the to_stop argument
-        has no effect:
-
-        >>> coding_dna2 = Seq("TTGGCCATTGTAATGGGCCGC")
-        >>> coding_dna2.translate()
-        Seq('LAIVMGR', ExtendedIUPACProtein())
-        >>> coding_dna2.translate(to_stop=True)
-        Seq('LAIVMGR', ExtendedIUPACProtein())
-
-        NOTE - Ambiguous codons like "TAN" or "NNN" could be an amino acid
-        or a stop codon.  These are translated as "X".  Any invalid codon
-        (e.g. "TA?" or "T-A") will throw a TranslationError.
-
-        NOTE - Does NOT support gapped sequences.
-
-        NOTE - This does NOT behave like the python string's translate
-        method.  For that use str(my_seq).translate(...) instead.
-        """
-        try:
-            table_id = int(table)
-        except ValueError:
-            table_id = None
-        if isinstance(table, str) and len(table)==256 :
-            raise ValueError("The Seq object translate method DOES NOT take " \
-                             + "a 256 character string mapping table like " \
-                             + "the python string object's translate method. " \
-                             + "Use str(my_seq).translate(...) instead.")
-        if isinstance(Alphabet._get_base_alphabet(self.alphabet),
-                      Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins cannot be translated!")
-        if self.alphabet==IUPAC.unambiguous_dna:
-            #Will use standard IUPAC protein alphabet, no need for X
-            if table_id is None:
-                codon_table = CodonTable.unambiguous_dna_by_name[table]
-            else:
-                codon_table = CodonTable.unambiguous_dna_by_id[table_id]
-        #elif self.alphabet==IUPAC.ambiguous_dna:
-        #    if table_id is None:
-        #        codon_table = CodonTable.ambiguous_dna_by_name[table]
-        #    else:
-        #        codon_table = CodonTable.ambiguous_dna_by_id[table_id]
-        elif self.alphabet==IUPAC.unambiguous_rna:
-            #Will use standard IUPAC protein alphabet, no need for X
-            if table_id is None:
-                codon_table = CodonTable.unambiguous_rna_by_name[table]
-            else:
-                codon_table = CodonTable.unambiguous_rna_by_id[table_id]
-        #elif self.alphabet==IUPAC.ambiguous_rna:
-        #    if table_id is None:
-        #        codon_table = CodonTable.ambiguous_rna_by_name[table]
-        #    else:
-        #        codon_table = CodonTable.ambiguous_rna_by_id[table_id]
-        else:
-            #This will use the extend IUPAC protein alphabet with X etc.
-            #The same table can be used for RNA or DNA (we use this for
-            #translating strings).
-            if table_id is None:
-                codon_table = CodonTable.ambiguous_generic_by_name[table]
-            else:
-                codon_table = CodonTable.ambiguous_generic_by_id[table_id]
-        protein = _translate_str(str(self), codon_table, stop_symbol, to_stop)
-        if stop_symbol in protein :
-            alphabet = Alphabet.HasStopCodon(codon_table.protein_alphabet,
-                                             stop_symbol = stop_symbol)
-        else :
-            alphabet = codon_table.protein_alphabet
-        return Seq(protein, alphabet)
-
-class UnknownSeq(Seq):
-    """A read-only sequence object of known length but unknown contents.
-
-    If you have an unknown sequence, you can represent this with a normal
-    Seq object, for example:
-
-    >>> my_seq = Seq("N"*5)
-    >>> my_seq
-    Seq('NNNNN', Alphabet())
-    >>> len(my_seq)
-    5
-    >>> print my_seq
-    NNNNN
-
-    However, this is rather wasteful of memory (especially for large
-    sequences), which is where this class is most usefull:
-
-    >>> unk_five = UnknownSeq(5)
-    >>> unk_five
-    UnknownSeq(5, alphabet = Alphabet(), character = '?')
-    >>> len(unk_five)
-    5
-    >>> print(unk_five)
-    ?????
-
-    You can add unknown sequence together, provided their alphabets and
-    characters are compatible, and get another memory saving UnknownSeq:
-
-    >>> unk_four = UnknownSeq(4)
-    >>> unk_four
-    UnknownSeq(4, alphabet = Alphabet(), character = '?')
-    >>> unk_four + unk_five
-    UnknownSeq(9, alphabet = Alphabet(), character = '?')
-
-    If the alphabet or characters don't match up, the addition gives an
-    ordinary Seq object:
-    
-    >>> unk_nnnn = UnknownSeq(4, character = "N")
-    >>> unk_nnnn
-    UnknownSeq(4, alphabet = Alphabet(), character = 'N')
-    >>> unk_nnnn + unk_four
-    Seq('NNNN????', Alphabet())
-
-    Combining with a real Seq gives a new Seq object:
-
-    >>> known_seq = Seq("ACGT")
-    >>> unk_four + known_seq
-    Seq('????ACGT', Alphabet())
-    >>> known_seq + unk_four
-    Seq('ACGT????', Alphabet())
-    """
-    def __init__(self, length, alphabet = Alphabet.generic_alphabet, character = None) :
-        """Create a new UnknownSeq object.
-
-        If character is ommited, it is determed from the alphabet, "N" for
-        nucleotides, "X" for proteins, and "?" otherwise.
-        """
-        self._length = int(length)
-        if self._length < 0 :
-            #TODO - Block zero length UnknownSeq?  You can just use a Seq!
-            raise ValueError("Length must not be negative.")
-        self.alphabet = alphabet
-        if character :
-            if len(character) != 1 :
-                raise ValueError("character argument should be a single letter string.")
-            self._character = character
-        else :
-            base = Alphabet._get_base_alphabet(alphabet)
-            #TODO? Check the case of the letters in the alphabet?
-            #We may have to use "n" instead of "N" etc.
-            if isinstance(base, Alphabet.NucleotideAlphabet) :
-                self._character = "N"
-            elif isinstance(base, Alphabet.ProteinAlphabet) :
-                self._character = "X"
-            else :
-                self._character = "?"
-
-    def __len__(self) :
-        """Returns the stated length of the unknown sequence."""
-        return self._length
-    
-    def __str__(self) :
-        """Returns the unknown sequence as full string of the given length."""
-        return self._character * self._length
-
-    def __repr__(self):
-        return "UnknownSeq(%i, alphabet = %s, character = %s)" \
-               % (self._length, repr(self.alphabet), repr(self._character))
-
-    def __add__(self, other) :
-        if isinstance(other, UnknownSeq) \
-        and other._character == self._character :
-            #TODO - Check the alphabets match
-            return UnknownSeq(len(self)+len(other),
-                              self.alphabet, self._character)
-        #Offload to the base class...
-        return Seq(str(self), self.alphabet) + other
-
-    def __radd__(self, other) :
-        if isinstance(other, UnknownSeq) \
-        and other._character == self._character :
-            #TODO - Check the alphabets match
-            return UnknownSeq(len(self)+len(other),
-                              self.alphabet, self._character)
-        #Offload to the base class...
-        return other + Seq(str(self), self.alphabet)
-
-    def __getitem__(self, index):
-        if isinstance(index, int) :
-            #TODO - Check the bounds without wasting memory
-            return str(self)[index]
-        else :
-            #TODO - Work out the length without wasting memory
-            return UnknownSeq(len(("#"*self._length)[index]),
-                              self.alphabet, self._character)
-
-    def count(self, sub, start=0, end=sys.maxint):
-        """Non-overlapping count method, like that of a python string.
-
-        This behaves like the python string (and Seq object) method of the
-        same name, which does a non-overlapping count!
-
-        Returns an integer, the number of occurrences of substring
-        argument sub in the (sub)sequence given by [start:end].
-        Optional arguments start and end are interpreted as in slice
-        notation.
-    
-        Arguments:
-         - sub - a string or another Seq object to look for
-         - start - optional integer, slice start
-         - end - optional integer, slice end
-
-        >>> "NNNN".count("N")
-        4
-        >>> Seq("NNNN").count("N")
-        4
-        >>> UnknownSeq(4, character="N").count("N")
-        4
-        >>> UnknownSeq(4, character="N").count("A")
-        0
-        >>> UnknownSeq(4, character="N").count("AA")
-        0
-
-        HOWEVER, please note because that python strings and Seq objects (and
-        MutableSeq objects) do a non-overlapping search, this may not give
-        the answer you expect:
-
-        >>> UnknownSeq(4, character="N").count("NN")
-        2
-        >>> UnknownSeq(4, character="N").count("NNN")
-        1
-        """
-        sub_str = self._get_seq_str_and_check_alphabet(sub)
-        if len(sub_str) == 1 :
-            if str(sub_str) == self._character :
-                if start==0 and end >= self._length :
-                    return self._length
-                else :
-                    #This could be done more cleverly...
-                    return str(self).count(sub_str, start, end)
-            else :
-                return 0
-        else :
-            if set(sub_str) == set(self._character) :
-                if start==0 and end >= self._length :
-                    return self._length // len(sub_str)
-                else :
-                    #This could be done more cleverly...
-                    return str(self).count(sub_str, start, end)
-            else :
-                return 0
-
-    def complement(self) :
-        """The complement of an unknown nucleotide equals itself.
-
-        >>> my_nuc = UnknownSeq(8)
-        >>> my_nuc
-        UnknownSeq(8, alphabet = Alphabet(), character = '?')
-        >>> print my_nuc
-        ????????
-        >>> my_nuc.complement()
-        UnknownSeq(8, alphabet = Alphabet(), character = '?')
-        >>> print my_nuc.complement()
-        ????????
-        """
-        if isinstance(Alphabet._get_base_alphabet(self.alphabet),
-                      Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins do not have complements!")
-        return self
-
-    def reverse_complement(self) :
-        """The reverse complement of an unknown nucleotide equals itself.
-
-        >>> my_nuc = UnknownSeq(10)
-        >>> my_nuc
-        UnknownSeq(10, alphabet = Alphabet(), character = '?')
-        >>> print my_nuc
-        ??????????
-        >>> my_nuc.reverse_complement()
-        UnknownSeq(10, alphabet = Alphabet(), character = '?')
-        >>> print my_nuc.reverse_complement()
-        ??????????
-        """
-        if isinstance(Alphabet._get_base_alphabet(self.alphabet),
-                      Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins do not have complements!")
-        return self
-
-    def transcribe(self) :
-        """Returns unknown RNA sequence from an unknown DNA sequence.
-
-        >>> my_dna = UnknownSeq(10, character="N")
-        >>> my_dna
-        UnknownSeq(10, alphabet = Alphabet(), character = 'N')
-        >>> print my_dna
-        NNNNNNNNNN
-        >>> my_rna = my_dna.transcribe()
-        >>> my_rna
-        UnknownSeq(10, alphabet = RNAAlphabet(), character = 'N')
-        >>> print my_rna
-        NNNNNNNNNN
-        """
-        #Offload the alphabet stuff
-        s = Seq(self._character, self.alphabet).transcribe()
-        return UnknownSeq(self._length, s.alphabet, self._character)
-
-    def back_transcribe(self) :
-        """Returns unknown DNA sequence from an unknown RNA sequence.
-
-        >>> my_rna = UnknownSeq(20, character="N")
-        >>> my_rna
-        UnknownSeq(20, alphabet = Alphabet(), character = 'N')
-        >>> print my_rna
-        NNNNNNNNNNNNNNNNNNNN
-        >>> my_dna = my_rna.back_transcribe()
-        >>> my_dna
-        UnknownSeq(20, alphabet = DNAAlphabet(), character = 'N')
-        >>> print my_dna
-        NNNNNNNNNNNNNNNNNNNN
-        """
-        #Offload the alphabet stuff
-        s = Seq(self._character, self.alphabet).back_transcribe()
-        return UnknownSeq(self._length, s.alphabet, self._character)
-
-    def translate(self, **kwargs) :
-        """Translate an unknown nucleotide sequence into an unknown protein.
-
-        e.g.
-
-        >>> my_seq = UnknownSeq(11, character="N")
-        >>> print my_seq
-        NNNNNNNNNNN
-        >>> my_protein = my_seq.translate()
-        >>> my_protein
-        UnknownSeq(3, alphabet = ProteinAlphabet(), character = 'X')
-        >>> print my_protein
-        XXX
-
-        In comparison, using a normal Seq object:
-
-        >>> my_seq = Seq("NNNNNNNNNNN")
-        >>> print my_seq
-        NNNNNNNNNNN
-        >>> my_protein = my_seq.translate()
-        >>> my_protein
-        Seq('XXX', ExtendedIUPACProtein())
-        >>> print my_protein
-        XXX
-
-        """
-        if isinstance(Alphabet._get_base_alphabet(self.alphabet),
-                      Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins cannot be translated!")
-        return UnknownSeq(self._length//3, Alphabet.generic_protein, "X")
-
-
-class MutableSeq(object):
-    """An editable sequence object (with an alphabet).
-
-    Unlike normal python strings and our basic sequence object (the Seq class)
-    which are immuatable, the MutableSeq lets you edit the sequence in place.
-    However, this means you cannot use a MutableSeq object as a dictionary key.
-
-    >>> from Bio.Seq import MutableSeq
-    >>> from Bio.Alphabet import generic_dna
-    >>> my_seq = MutableSeq("ACTCGTCGTCG", generic_dna)
-    >>> my_seq
-    MutableSeq('ACTCGTCGTCG', DNAAlphabet())
-    >>> my_seq[5]
-    'T'
-    >>> my_seq[5] = "A"
-    >>> my_seq
-    MutableSeq('ACTCGACGTCG', DNAAlphabet())
-    >>> my_seq[5]
-    'A'
-    >>> my_seq[5:8] = "NNN"
-    >>> my_seq
-    MutableSeq('ACTCGNNNTCG', DNAAlphabet())
-    >>> len(my_seq)
-    11
-
-    Note that the MutableSeq object does not support as many string-like
-    or biological methods as the Seq object.
-    """
-    def __init__(self, data, alphabet = Alphabet.generic_alphabet):
-        if type(data) == type(""):
-            self.data = array.array("c", data)
-        else:
-            self.data = data   # assumes the input is an array
-        self.alphabet = alphabet
-    
-    def __repr__(self):
-        """Returns a (truncated) representation of the sequence for debugging."""
-        if len(self) > 60 :
-            #Shows the last three letters as it is often useful to see if there
-            #is a stop codon at the end of a sequence.
-            #Note total length is 54+3+3=60
-            return "%s('%s...%s', %s)" % (self.__class__.__name__,
-                                   str(self[:54]), str(self[-3:]),
-                                   repr(self.alphabet))
-        else :
-            return "%s('%s', %s)" % (self.__class__.__name__,
-                                   str(self),
-                                   repr(self.alphabet))
-
-    def __str__(self):
-        """Returns the full sequence as a python string.
-
-        Note that Biopython 1.44 and earlier would give a truncated
-        version of repr(my_seq) for str(my_seq).  If you are writing code
-        which needs to be backwards compatible with old Biopython, you
-        should continue to use my_seq.tostring() rather than str(my_seq).
-        """
-        #See test_GAQueens.py for an historic usage of a non-string alphabet!
-        return "".join(self.data)
-
-    def __cmp__(self, other):
-        """Compare the sequence for to another sequence or a string.
-
-        If compared to another sequence the alphabets must be compatible.
-        Comparing DNA to RNA, or Nucleotide to Protein will raise an
-        exception.
-
-        Otherwise only the sequence itself is compared, not the precise
-        alphabet.
-
-        This method indirectly supports ==, < , etc."""
-        if hasattr(other, "alphabet") :
-            #other should be a Seq or a MutableSeq
-            if not Alphabet._check_type_compatible([self.alphabet,
-                                                    other.alphabet]) :
-                raise TypeError("Incompatable alphabets %s and %s" \
-                                % (repr(self.alphabet), repr(other.alphabet)))
-            #They should be the same sequence type (or one of them is generic)
-            if isinstance(other, MutableSeq):
-                #See test_GAQueens.py for an historic usage of a non-string
-                #alphabet!  Comparing the arrays supports this.
-                return cmp(self.data, other.data)
-            else :
-                return cmp(str(self), str(other))
-        elif isinstance(other, basestring) :
-            return cmp(str(self), other)
-        else :
-            raise TypeError
-
-    def __len__(self): return len(self.data)
-
-    def __getitem__(self, index) :
-        #Note since Python 2.0, __getslice__ is deprecated
-        #and __getitem__ is used instead.
-        #See http://docs.python.org/ref/sequence-methods.html
-        if isinstance(index, int) :
-            #Return a single letter as a string
-            return self.data[index]
-        else :
-            #Return the (sub)sequence as another Seq object
-            return MutableSeq(self.data[index], self.alphabet)
-
-    def __setitem__(self, index, value):
-        #Note since Python 2.0, __setslice__ is deprecated
-        #and __setitem__ is used instead.
-        #See http://docs.python.org/ref/sequence-methods.html
-        if isinstance(index, int) :
-            #Replacing a single letter with a new string
-            self.data[index] = value
-        else :
-            #Replacing a sub-sequence
-            if isinstance(value, MutableSeq):
-                self.data[index] = value.data
-            elif isinstance(value, type(self.data)):
-                self.data[index] = value
-            else:
-                self.data[index] = array.array("c", str(value))
-
-    def __delitem__(self, index):
-        #Note since Python 2.0, __delslice__ is deprecated
-        #and __delitem__ is used instead.
-        #See http://docs.python.org/ref/sequence-methods.html
-        
-        #Could be deleting a single letter, or a slice
-        del self.data[index]
-    
-    def __add__(self, other):
-        """Add another sequence or string to this sequence.
-
-        Returns a new MutableSeq object."""
-        if hasattr(other, "alphabet") :
-            #other should be a Seq or a MutableSeq
-            if not Alphabet._check_type_compatible([self.alphabet,
-                                                    other.alphabet]) :
-                raise TypeError("Incompatable alphabets %s and %s" \
-                                % (repr(self.alphabet), repr(other.alphabet)))
-            #They should be the same sequence type (or one of them is generic)
-            a = Alphabet._consensus_alphabet([self.alphabet, other.alphabet])
-            if isinstance(other, MutableSeq):
-                #See test_GAQueens.py for an historic usage of a non-string
-                #alphabet!  Adding the arrays should support this.
-                return self.__class__(self.data + other.data, a)
-            else :
-                return self.__class__(str(self) + str(other), a)
-        elif isinstance(other, basestring) :
-            #other is a plain string - use the current alphabet
-            return self.__class__(str(self) + str(other), self.alphabet)
-        else :
-            raise TypeError
-
-    def __radd__(self, other):
-        if hasattr(other, "alphabet") :
-            #other should be a Seq or a MutableSeq
-            if not Alphabet._check_type_compatible([self.alphabet,
-                                                    other.alphabet]) :
-                raise TypeError("Incompatable alphabets %s and %s" \
-                                % (repr(self.alphabet), repr(other.alphabet)))
-            #They should be the same sequence type (or one of them is generic)
-            a = Alphabet._consensus_alphabet([self.alphabet, other.alphabet])
-            if isinstance(other, MutableSeq):
-                #See test_GAQueens.py for an historic usage of a non-string
-                #alphabet!  Adding the arrays should support this.
-                return self.__class__(other.data + self.data, a)
-            else :
-                return self.__class__(str(other) + str(self), a)
-        elif isinstance(other, basestring) :
-            #other is a plain string - use the current alphabet
-            return self.__class__(str(other) + str(self), self.alphabet)
-        else :
-            raise TypeError
-
-    def append(self, c):
-        self.data.append(c)
-
-    def insert(self, i, c):
-        self.data.insert(i, c)
-
-    def pop(self, i = (-1)):
-        c = self.data[i]
-        del self.data[i]
-        return c
-
-    def remove(self, item):
-        for i in range(len(self.data)):
-            if self.data[i] == item:
-                del self.data[i]
-                return
-        raise ValueError("MutableSeq.remove(x): x not in list")
-
-    def count(self, sub, start=0, end=sys.maxint):
-        """Non-overlapping count method, like that of a python string.
-
-        This behaves like the python string method of the same name,
-        which does a non-overlapping count!
-
-        Returns an integer, the number of occurrences of substring
-        argument sub in the (sub)sequence given by [start:end].
-        Optional arguments start and end are interpreted as in slice
-        notation.
-    
-        Arguments:
-         - sub - a string or another Seq object to look for
-         - start - optional integer, slice start
-         - end - optional integer, slice end
-
-        e.g.
-        
-        >>> from Bio.Seq import MutableSeq
-        >>> my_mseq = MutableSeq("AAAATGA")
-        >>> print my_mseq.count("A")
-        5
-        >>> print my_mseq.count("ATG")
-        1
-        >>> print my_mseq.count(Seq("AT"))
-        1
-        >>> print my_mseq.count("AT", 2, -1)
-        1
-        
-        HOWEVER, please note because that python strings, Seq objects and
-        MutableSeq objects do a non-overlapping search, this may not give
-        the answer you expect:
-
-        >>> "AAAA".count("AA")
-        2
-        >>> print MutableSeq("AAAA").count("AA")
-        2
-
-        A non-overlapping search would give the answer as three!
-        """
-        try :
-            #TODO - Should we check the alphabet?
-            search = sub.tostring()
-        except AttributeError :
-            search = sub
-
-        if not isinstance(search, basestring) :
-            raise TypeError("expected a string, Seq or MutableSeq")
-
-        if len(search) == 1 :
-            #Try and be efficient and work directly from the array.
-            count = 0
-            for c in self.data[start:end]:
-                if c == search: count += 1
-            return count
-        else :
-            #TODO - Can we do this more efficiently?
-            return self.tostring().count(search, start, end)
-
-    def index(self, item):
-        for i in range(len(self.data)):
-            if self.data[i] == item:
-                return i
-        raise ValueError("MutableSeq.index(x): x not in list")
-
-    def reverse(self):
-        """Modify the mutable sequence to reverse itself.
-
-        No return value.
-        """
-        self.data.reverse()
-
-    def complement(self):
-        """Modify the mutable sequence to take on its complement.
-
-        Trying to complement a protein sequence raises an exception.
-
-        No return value.
-        """
-        if isinstance(Alphabet._get_base_alphabet(self.alphabet),
-                      Alphabet.ProteinAlphabet) :
-            raise ValueError("Proteins do not have complements!")
-        if self.alphabet in (IUPAC.ambiguous_dna, IUPAC.unambiguous_dna):
-            d = ambiguous_dna_complement
-        elif self.alphabet in (IUPAC.ambiguous_rna, IUPAC.unambiguous_rna):
-            d = ambiguous_rna_complement
-        elif 'U' in self.data and 'T' in self.data :
-            #TODO - Handle this cleanly?
-            raise ValueError("Mixed RNA/DNA found")
-        elif 'U' in self.data:
-            d = ambiguous_rna_complement
-        else:
-            d = ambiguous_dna_complement
-        c = dict([(x.lower(), y.lower()) for x,y in d.iteritems()])
-        d.update(c)
-        self.data = map(lambda c: d[c], self.data)
-        self.data = array.array('c', self.data)
-        
-    def reverse_complement(self):
-        """Modify the mutable sequence to take on its reverse complement.
-
-        Trying to reverse complement a protein sequence raises an exception.
-
-        No return value.
-        """
-        self.complement()
-        self.data.reverse()
-
-    ## Sorting a sequence makes no sense.
-    # def sort(self, *args): self.data.sort(*args)
-    
-    def extend(self, other):
-        if isinstance(other, MutableSeq):
-            for c in other.data:
-                self.data.append(c)
-        else:
-            for c in other:
-                self.data.append(c)
-
-    def tostring(self):
-        """Returns the full sequence as a python string.
-
-        Although not formally deprecated, you are now encouraged to use
-        str(my_seq) instead of my_seq.tostring().
-
-        Because str(my_seq) will give you the full sequence as a python string,
-        there is often no need to make an explicit conversion.  For example,
-        
-        print "ID={%s}, sequence={%s}" % (my_name, my_seq)
-
-        On Biopython 1.44 or older you would have to have done this:
-
-        print "ID={%s}, sequence={%s}" % (my_name, my_seq.tostring())
-        """
-        return "".join(self.data)
-
-    def toseq(self):
-        """Returns the full sequence as a new immutable Seq object.
-
-        >>> from Bio.Seq import Seq
-        >>> from Bio.Alphabet import IUPAC
-        >>> my_mseq = MutableSeq("MKQHKAMIVALIVICITAVVAAL", \
-                                 IUPAC.protein)
-        >>> my_mseq
-        MutableSeq('MKQHKAMIVALIVICITAVVAAL', IUPACProtein())
-        >>> my_mseq.toseq()
-        Seq('MKQHKAMIVALIVICITAVVAAL', IUPACProtein())
-
-        Note that the alphabet is preserved.
-        """
-        return Seq("".join(self.data), self.alphabet)
-
-# The transcribe, backward_transcribe, and translate functions are
-# user-friendly versions of the corresponding functions in Bio.Transcribe
-# and Bio.Translate. The functions work both on Seq objects, and on strings.
-
-def transcribe(dna):
-    """Transcribes a DNA sequence into RNA.
-
-    If given a string, returns a new string object.
-
-    Given a Seq or MutableSeq, returns a new Seq object with an RNA alphabet.
-
-    Trying to transcribe a protein or RNA sequence raises an exception.
-
-    e.g.
-    
-    >>> transcribe("ACTGN")
-    'ACUGN'
-    """
-    if isinstance(dna, Seq) :
-        return dna.transcribe()
-    elif isinstance(dna, MutableSeq):
-        return dna.toseq().transcribe()
-    else:
-        return dna.replace('T','U').replace('t','u')
-
-def back_transcribe(rna):
-    """Back-transcribes an RNA sequence into DNA.
-
-    If given a string, returns a new string object.
-    
-    Given a Seq or MutableSeq, returns a new Seq object with an RNA alphabet.
-
-    Trying to transcribe a protein or DNA sequence raises an exception.
-
-    e.g.
-
-    >>> back_transcribe("ACUGN")
-    'ACTGN'
-    """
-    if isinstance(rna, Seq) :
-        return rna.back_transcribe()
-    elif isinstance(rna, MutableSeq):
-        return rna.toseq().back_transcribe()
-    else:
-        return rna.replace('U','T').replace('u','t')
-    
-def _translate_str(sequence, table, stop_symbol="*",
-                   to_stop=False, pos_stop="X") :
-    """Helper function to translate a nucleotide string (PRIVATE).
-
-    Arguments:
-     - sequence    - a string
-     - table       - a CodonTable object (NOT a table name or id number)
-     - stop_symbol - a single character string, what to use for terminators.
-     - to_stop     - boolean, should translation terminate at the first
-                     in frame stop codon?  If there is no in-frame stop codon
-                     then translation continues to the end.
-     - pos_stop    - a single character string for a possible stop codon
-                     (e.g. TAN or NNN)
-
-    Returns a string.
-
-    e.g.
-
-    >>> from Bio.Data import CodonTable
-    >>> table = CodonTable.ambiguous_dna_by_id[1]
-    >>> _translate_str("AAA", table)
-    'K'
-    >>> _translate_str("TAR", table)
-    '*'
-    >>> _translate_str("TAN", table)
-    'X'
-    >>> _translate_str("TAN", table, pos_stop="@")
-    '@'
-    >>> _translate_str("TA?", table)
-    Traceback (most recent call last):
-       ...
-    TranslationError: Codon 'TA?' is invalid
-    """
-    sequence = sequence.upper()
-    amino_acids = []
-    forward_table = table.forward_table
-    stop_codons = table.stop_codons
-    if table.nucleotide_alphabet.letters is not None :
-        valid_letters = set(table.nucleotide_alphabet.letters.upper())
-    else :
-        #Assume the worst case, ambiguous DNA or RNA:
-        valid_letters = set(IUPAC.ambiguous_dna.letters.upper() + \
-                            IUPAC.ambiguous_rna.letters.upper())
-
-    n = len(sequence)
-    for i in xrange(0,n-n%3,3) :
-        codon = sequence[i:i+3]
-        try :
-            amino_acids.append(forward_table[codon])
-        except (KeyError, CodonTable.TranslationError) :
-            #Todo? Treat "---" as a special case (gapped translation)
-            if codon in table.stop_codons :
-                if to_stop : break
-                amino_acids.append(stop_symbol)
-            elif valid_letters.issuperset(set(codon)) :
-                #Possible stop codon (e.g. NNN or TAN)
-                amino_acids.append(pos_stop)
-            else :
-                raise CodonTable.TranslationError(\
-                    "Codon '%s' is invalid" % codon)
-    return "".join(amino_acids)
-
-def translate(sequence, table="Standard", stop_symbol="*", to_stop=False):
-    """Translate a nucleotide sequence into amino acids.
-
-    If given a string, returns a new string object. Given a Seq or
-    MutableSeq, returns a Seq object with a protein alphabet.
-
-    Arguments:
-     - table - Which codon table to use?  This can be either a name
-               (string) or an NCBI identifier (integer).  Defaults
-               to the "Standard" table.
-     - stop_symbol - Single character string, what to use for any
-                     terminators, defaults to the asterisk, "*".
-     - to_stop - Boolean, defaults to False meaning do a full
-                 translation continuing on past any stop codons
-                 (translated as the specified stop_symbol).  If
-                 True, translation is terminated at the first in
-                 frame stop codon (and the stop_symbol is not
-                 appended to the returned protein sequence).
-
-    A simple string example using the default (standard) genetic code:
-    
-    >>> coding_dna = "GTGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG"
-    >>> translate(coding_dna)
-    'VAIVMGR*KGAR*'
-    >>> translate(coding_dna, stop_symbol="@")
-    'VAIVMGR@KGAR@'
-    >>> translate(coding_dna, to_stop=True)
-    'VAIVMGR'
-     
-    Now using NCBI table 2, where TGA is not a stop codon:
-
-    >>> translate(coding_dna, table=2)
-    'VAIVMGRWKGAR*'
-    >>> translate(coding_dna, table=2, to_stop=True)
-    'VAIVMGRWKGAR'
-
-    Note that if the sequence has no in-frame stop codon, then the to_stop
-    argument has no effect:
-
-    >>> coding_dna2 = "GTGGCCATTGTAATGGGCCGC"
-    >>> translate(coding_dna2)
-    'VAIVMGR'
-    >>> translate(coding_dna2, to_stop=True)
-    'VAIVMGR'
-    
-    NOTE - Ambiguous codons like "TAN" or "NNN" could be an amino acid
-    or a stop codon.  These are translated as "X".  Any invalid codon
-    (e.g. "TA?" or "T-A") will throw a TranslationError.
-
-    NOTE - Does NOT support gapped sequences.
-    
-    It will however translate either DNA or RNA.
-    """
-    if isinstance(sequence, Seq) :
-        return sequence.translate(table, stop_symbol, to_stop)
-    elif isinstance(sequence, MutableSeq):
-        #Return a Seq object
-        return sequence.toseq().translate(table, stop_symbol, to_stop)
-    else:
-        #Assume its a string, return a string
-        try :
-            codon_table = CodonTable.ambiguous_generic_by_id[int(table)]
-        except ValueError :
-            codon_table = CodonTable.ambiguous_generic_by_name[table]
-        return _translate_str(sequence, codon_table, stop_symbol, to_stop)
-      
-def reverse_complement(sequence):
-    """Returns the reverse complement sequence of a nucleotide string.
-
-    If given a string, returns a new string object.
-    Given a Seq or a MutableSeq, returns a new Seq object with the same alphabet.
-
-    Supports unambiguous and ambiguous nucleotide sequences.
-
-    e.g.
-
-    >>> reverse_complement("ACTG-NH")
-    'DN-CAGT'
-    """
-    if isinstance(sequence, Seq) :
-        #Return a Seq
-        return sequence.reverse_complement()
-    elif isinstance(sequence, MutableSeq) :
-        #Return a Seq
-        #Don't use the MutableSeq reverse_complement method as it is 'in place'.
-        return sequence.toseq().reverse_complement()
-
-    #Assume its a string.
-    #In order to avoid some code duplication, the old code would turn the string
-    #into a Seq, use the reverse_complement method, and convert back to a string.
-    #This worked, but is over five times slower on short sequences!
-    if ('U' in sequence or 'u' in sequence) \
-    and ('T' in sequence or 't' in sequence):
-        raise ValueError("Mixed RNA/DNA found")
-    elif 'U' in sequence or 'u' in sequence:
-        ttable = _rna_complement_table
-    else:
-        ttable = _dna_complement_table
-    return sequence.translate(ttable)[::-1]
-
-def _test():
-    """Run the Bio.Seq module's doctests."""
-    print "Runing doctests..."
-    import doctest
-    doctest.testmod()
-    print "Done"
-
-if __name__ == "__main__":
-    _test()