April 29th, 2013, 01:45 PM

Code explanation
Hello. I have this bit of code, but I am not sure what is going on exactly. I know it is taking the multiples of 3 and 5 and adding them, but I am not sure how the code actually accomplishes it.
Code:
sum(i for i in range(1,1000) if (i % 3 == 0) or (i % 5 == 0))
Any explanation would be appreciated
April 29th, 2013, 01:54 PM

It is using a feature of python called list comprehension (google for that term).
Basically, try doing this:
Code:
print( [i for i in range(1,1000) if (i % 3 == 0) or (i % 5 == 0)] )
Basically, this expression:
[i for i in range(1,1000) if (i % 3 == 0) or (i % 5 == 0)]
says:
1. Take i from 1 to 999 (the "for i in range(1,1000)" bit)
2. Check if i is divisible by 3 or 5 (the "if (i % 3 == 0) or (i % 5 == 0)" bit)
3. If so, return i (the leading i in "i for i in ....")
4. Return every i that matches 1..3 in a list.
As a fun aside, try changing the code to:
Code:
print( [i*10 for i in range(1,20) if (i % 3 == 0) or (i % 5 == 0)] )
Note here that the results are i multiplied by 10 (since we have "i * 10" in the beginning).
Up the Irons
What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
"Death Before Dishonour, my Friends!!"  Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
Down with Sharon Osbourne
"I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website."  Nilpo
April 29th, 2013, 01:59 PM

Ooooh, so the leading "i" is basically the return value.
Thank you!!
April 29th, 2013, 04:55 PM

Wonderful. Project Euler #1. Keep going!
[code]
Code tags[/code] are essential for python code and Makefiles!
April 29th, 2013, 11:06 PM

Code:
def fib(n):
a, b = 1, 2
fib_list = [a]
for i in range(n):
a, b = b, a + b
fib_list.append(a)
return fib_list
print(sum(i for i in fib(31) if i % 2 == 0))
How's this for Euler 2? I feel like there should be a better way since I had to manually type in the range for 'fib(31)' until I noticed that 'a' in 'fib_list' was less than four million.
April 30th, 2013, 10:10 AM

A generator might be a better way.
Code:
'''
>>> for f in fib(2000): print('{:4d}'.format(f))
...
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
>>>
'''
def fib(maximum):
a, b = 1, 2
while a < maximum:
yield a
a, b = b, a + b
(I'd accept an argument for <= in place of < )
[code]
Code tags[/code] are essential for python code and Makefiles!
April 30th, 2013, 10:53 AM

"self discovery"
Matrix multiplication can also generate Fibonacci numbers, and it's a quick way to make large ones. numpy doesn't handle arbitrary precision integers; you'll need to write your own matrix multiplication routine. Don Knuth found other formulas for Fibonacci numbers.
Code:
>>> import numpy
>>> F = numpy.asarray(((0,1),(1,1)))
>>> F
array([[0, 1],
[1, 1]])
>>> F.dot(F)
array([[1, 1],
[1, 2]])
>>> F.dot(F).dot(F).dot(F).dot(F)
array([[3, 5],
[5, 8]])
>>> F.dot(F).dot(F).dot(F).dot(F).dot(F).dot(F).dot(F)
array([[13, 21],
[21, 34]])
>>> G = F.dot(F).dot(F).dot(F).dot(F)
>>> G.dot(G)
array([[34, 55],
[55, 89]])
>>>
[code]
Code tags[/code] are essential for python code and Makefiles!
April 30th, 2013, 06:49 PM

That is so cool. Thank you for showing it
April 30th, 2013, 07:59 PM

Hmmm. I don't quite understand 'yield'.
Is it returning a from the variable below? Or from above? And how does it create a list of numbers?
Any info would be awesome!!!
April 30th, 2013, 08:50 PM

in python3...
It could be the doctest you misunderstood. fib didn't make a list.
Code:
>>> fib(3)
<generator object fib at 0x7f5731a627d0>
>>> {'__next__', '__iter__'} . intersection(set(dir(fib))) # fib looks like a function
set()
>>> {'__next__', '__iter__'} . intersection(set(dir(fib(8888888)))) # calling fib gives an object that supports iteration.
{'__iter__', '__next__'}
Code:
def fib(maximum):
a, b = 1, 2
while a < maximum:
yield a
a, b = b, a + b
# we can make a list of Fibonacci numbers.
print([x for x in fib(22)]) # output is [1, 2, 3, 5, 8, 13, 21]
[code]
Code tags[/code] are essential for python code and Makefiles!