# py2.py
#
# Project Euler
# Problem 2
#
# Each new term in the Fibonacci sequence is generated by adding the previous
# two terms. By starting with 1 and 2, the first 10 terms will be:
# 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
#
# By considering the terms in the Fibonacci sequence whose values do not
# exceed four million, find the sum of the even-valued terms.

# ALGORITHM
# Get a list containing all the fib numbers less than 4 mil. Then sum up
# only the elements that are even. This algorithm does not store the fib
# sequence for future reference; a new list is calculated every time the
# fubSequenceBelowValue() function is called.

class NoSequenceElementsBelowGivenParameter(Exception): pass
class EmptySequenceError(Exception): pass

def fibSequenceBelowValue(n):
    '''Returns list containing Fibonacci sequence with [1,2] as the
    initial values.'''
    
    fib = [1,2]
    
    if 1 < n <= 2:
        return [1]
    
    if not isinstance(n, int):
        raise TypeError, "Parameter is not an integer."
    if not n > 1: # Number requested is too low to return non-empty sequence
        raise NoSequenceElementsBelowGivenParameter
    
    while fib[-1] + fib[-2] < n:
        fib.append(fib[-2] + fib[-1])
    
    return fib

def sumEvenElements(seq):
    sum = 0
    for i in seq:
        if not isinstance(i, int):
            raise TypeError, 'The object %s is not an integer' % i
        if  i < 0:
            raise TypeError, 'The integer %d is not positive' % i
        if i % 2 == 0:
            sum += i
    return sum

if __name__ == '__main__':
    seq = fibSequenceBelowValue(int(4e6))
    sum = sumEvenElements(seq)
    print "The answer to problem 2 is %d" % sum