import intseqdb

# a function that returns a function defining a generator
# for the even number 0, 2, 4, 6, ..
def even_numbers_gen():
    def wrapper_even_numbers_gen():
        i = 0
        while True:
            yield i
            i = i+2
    return wrapper_even_numbers_gen

# a function that returns a function defining a generator
# for the even number 1, 3, 5, 7, ...
def odd_numbers_gen():
    def wrapper_odd_numbers_gen():
        i = 1
        while True:
            yield i
            i = i+2
    return wrapper_odd_numbers_gen

# a function that return a function defining a generator
# for the Fibonacci nimbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
# http://fr.wikipedia.org/wiki/Suite_de_Fibonacci
def fibonacci_gen():
	def wrapper_fibonacci_gen():
		f_n_1 = 1  # F_{-1} = 1
		f_n = 0    # F_0 = 0
		yield f_n
		while True:
			f_n_1, f_n = f_n, f_n + f_n_1
			yield f_n
	return wrapper_fibonacci_gen

# a function that returns a function defining a generator
# for the Catalan numbers: 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, ...
# http://fr.wikipedia.org/wiki/Nombre_de_Catalan
def catalan_gen():
	def wrapper_catalan_gen():
		i = 0
		val = 1
		while True:
			yield val
			val = val * (2 * (2*i + 1)) / (i + 2)
			i   = i + 1
        # only return the function defining the generator
	return wrapper_catalan_gen

# a function that returns a function defining a generator
# for the powers of n: n^0, n^1, n^2, n^3, ...
def power_gen(n):
	def wrapper_power_gen():
		val = 1
		while True:
			yield val
			val = val * n
	# only return the function defining the generator
	return wrapper_power_gen

# create a database (only print the 10 first elements of each sequence)
db = intseqdb.Database(10)

# add some integer sequences into the database
db.add_sequence(intseqdb.Sequence("Even numbers", even_numbers_gen()))
db.add_sequence(intseqdb.Sequence("Odd numbers", odd_numbers_gen()))
db.add_sequence(intseqdb.Sequence("Powers of 1", power_gen(1)))
db.add_sequence(intseqdb.Sequence("Powers of 2", power_gen(2)))
db.add_sequence(intseqdb.Sequence("Powers of 4", power_gen(4)))
db.add_sequence(intseqdb.Sequence("Catalan numbers", catalan_gen()))
db.add_sequence(intseqdb.Sequence("Fibonacci numbers", fibonacci_gen()))

print '=*=*=*=*=*=*=*=*=*=*=*=*='
print "number of sequences in the database: %d" % len(db)
print 'iter(db) must be a generator:', iter(db)
for sequence in db:
    print sequence

print '=*=*=*=*=*=*=*=*=*=*=*=*='
print 'all sequences which description contains \'Powers\' in their description'
print 'Database.search_by_name() returns a generator:', db.search_by_name('Power')
for sequence in db.search_by_name('Power'):
    print sequence

print '=*=*=*=*=*=*=*=*=*=*=*=*='
print 'all sequences that begin as 1, 1'
print 'Database.search_by_seq():', db.search_by_seq([1, 1])
for sequence in db.search_by_seq([1, 1]):
    print sequence

print '=*=*=*=*=*=*=*=*=*=*=*=*='
print 'all sequences that begin as 1, 1, 2'
for sequence in db.search_by_seq([1, 1, 2]):
    print sequence

print '=*=*=*=*=*=*=*=*=*=*=*=*='
print 'all sequences that begin as 1, 1, 2, 3'
for sequence in db.search_by_seq([1, 1, 2, 3]):
    print sequence
    
print '=*=*=*=*=*=*=*=*=*=*=*=*='
print 'all sequences that begin as 1, 2 with maximum shift 3'
for sequence in db.search_by_seq_with_shift([1, 2], 3):
    print sequence
    
print '=*=*=*=*=*=*=*=*=*=*=*=*='
print 'all pairs of sequences that begin with the same 2 integers'
i = 1
for (sequence1, sequence2) in db.find_duplicates(2):
    print "pair %d" % (i, )
    i = i+1
    print sequence1
    print sequence2
    
print '=*=*=*=*=*=*=*=*=*=*=*=*='
print 'delete all sequences that  bagins as 1, 1'
n = db.delete_sequences([1,1])
print 'we just deleted %d sequences' % (n,)
print "number of sequences in the database: %d" % len(db)
for sequence in db:
    print sequence
