import itertools as it

def take(n, iterable):
    "Return first n items of the iterable as a list"
    return list(it.islice(iterable, n))

class Sequence(object):
    "A integer sequence"

    def __init__(self, description, generator, rep_len = 5):
        """create an integer sequence from a string description,
        a generator describing its elements, and an optional integer
        specfying how many elements are printed in a string representation
        (default is 5)"""
        self.description = description
        self.generator   = generator  
        self.rep_len     = rep_len    

    def set_rep_len(self, rep_len):
        """how many elements of this integer sequence are printed in
        a string representation?"""
        self.rep_len = rep_len

    def __str__(self):
        """string representation of an integer sequence: description +
        the first rep_len elements"""
        str_rep = ', '.join((str(i)
                            for i in take(self.rep_len, self.generator())))
        return '%s : %s, ...' % (self.description, str_rep)

    def __iter__(self):
        """return a generator to iterate over the elements of this
        integer sequence"""
        return self.generator()

class Database(object):
    "A database to store and query integer sequences"

    def __init__(self, rep_len):
        """create an empty database (when needed, print the first
        rep_len elements of each sequence"""
        self.catalogue = []
        self.rep_len = rep_len

    def __len__(self):
        "return the number of integer sequences in the database"
        return len(self.catalogue)

    def __iter__(self):
        """return an iterator over this database, i.e., all the
        integer sequences stored in the database"""
        return (sequence for sequence in self.catalogue)

    def add_sequence(self, sequence):
        "add an integer sequence (object Sequence) to the database"
        sequence.set_rep_len(self.rep_len)
        self.catalogue.append(sequence)

    def search(self, ints):
        "return a generator over all sequences that begin as ints"
        return (sequence for sequence in self.catalogue
                if take(len(ints), sequence) == ints)		

    def search_seq(self, sequence, cpm_len):
        """return a generator over all sequences that begin as
        Sequence sequence for the first cmp_len elements"""
        return (other_sequence for other_sequence in self.catalogue
                if take(cmp_len, other_sequence) == take(cmp_len, sequence))

			

