PyEuler

bearophileHUGS at lycos.com bearophileHUGS at lycos.com
Mon Feb 25 11:25:09 EST 2008


This is the first time I write something that looks like a little
rant :-) Surely I'll be wrong in many points, but I presume this isn't
going to damage people, so...

Here there are some functional Python solutions to some Euler
problems:
http://pyeuler.wikidot.com/

Some pieces of that code:

def takenth(n, iterable):
    "Returns the nth item"
    return list(islice(iterable, n, n+1))[0]

def euler1(end, nums):
    isanymultiple = lambda x: any((x % y == 0) for y in nums)
    return sum(filter(isanymultiple, xrange(end)))

euler1(1000, [3,5])

#Find the sum of all the even-valued terms in the Fibonacci sequence
which do not exceed one million.

def fibonacci(n):
    """Return nth element of the fibonacci serie"""
    if n == 0 or n == 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

def euler2(end):
    genfib = imap(fibonacci, count())
    candidates = takewhile(lambda n: n<end, genfib)
    return sum(ifilter(lambda n: n%2, candidates))


def least_common_multiple(nums):
    """Return least common multiples of nums"""
    factorized = dict((n, dict(factorize(n))) for n in nums)
    union = lambda lst: reduce(set.union, map(set, lst))
    all_factors = union(factorized.values())
    getexponent = lambda factor: (factorized[n].get(factor, 0) for n
in nums)
    return mul(factor**(max(getexponent(factor))) for factor in
all_factors)

What I think about such code:
- It's not much readable (but usually it can be read).
- it's not much Pythonic. Python is only partially functional, if you
try to use it in a very functional way you go against the language,
its coding practices, and the net result may be slow/little readable.
If you want to write almost fully functional code it's better to use a
fitter language, like Haskell.
- In some situations it seems to just show lack of knowledge of
Python.
- In various points it's not much efficient in speed and/or space.
- It's not even short, there are many ways to shorten that code, often
keeping or even increasing its readability; one of the most common
ways is to use generators and list comps more often.
- It lacks tests, like doctests.
- It has small pedagogical value too, because this is a bad way to
learn Python, and programming in general too.
- It has shown me when to use takewhile(), and some of the
mathematical insights it contains are interesting :-)

Bye,
bearophile



More information about the Python-list mailing list