1

I am trying to implement the Sieve of Euler (as described on programmingpraxis.com).I have code that runs fine on the first iteration, however on the next iteration my multiplication is skipped for some reason that escapes me (probably just missing some python-behavior there that is common sense to a more experienced programmer) I am running this:

import numpy as np
#set up parameters
primes = [2]
startval = 2
stopval = 10000
firstrun = True
candidates = np.arange(start=startval,stop=stopval+1,step=1)
#actual program
for idx in range(int(np.ceil(np.sqrt(stopval)))): #only up until sqrt(n) needs checking
    print('pos1')
    print(candidates)
    print(candidates[0])
    times = candidates[0]*candidates
    print(times)
    diffset = list(set(candidates)^set(times))
    if len(diffset) is not 0: #to make sure the program quits properly if diffset=[]
        primes.append(diffset.pop(0))
        print('pos2')
        print(diffset)
        candidates = diffset
        print('pos3')
        print(candidates)
    else:
        break
print(primes)

The various print statements are just so i can get a grasp on whats going on. Note the first outputs are fine, the interesting part starts the second time pos1 is printed. my candidates are updated just as I want them to, the new first element is also correct. So my question is:

Why is times = candidates[0]*candidatesapparently skipped on the second iteration?

Please note: I am not asking for a "scratch your code, copy this working and faster, better, nicer code" answer. There are plenty of python implementations out there, I want to do this myself. I think I am missing a fairly important concept of python here, and thats why my code doesn't behave.

(Should anyone ask: No, this is not a homework assignment. I am using a bit of python at my workplace and like to do these sorts of things at home to get better at coding)

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Andreas_B
  • 113
  • 5
  • It seems that on the first iteration candidates is a "numpy.ndarray" object but on the second it is a list. if you convert the diffset to a numpy.ndarray before assigning it to the candidates variable does it help? – Karl Graham Feb 21 '18 at 09:56
  • That was exactly the issue, as FlyingTeller pointed out as well. Thanks – Andreas_B Feb 21 '18 at 10:14

1 Answers1

0

I just ran your code. Looking at the output of times in line 14 you can see that after the first iteration the operation is performed, but not in the way you intended to. The list times is just three times the list candidates put after one another. To elaborate:

1st iteration

candidates = np.arange(start=startval,stop=stopval+1,step=1)

so candidates is a numpy array. Doing

candidates*candidates[0]

is the same as candidates*2, which is "numpy_array*number", which is just element-wise multiplication. Now further down you do

diffset = list(set(candidates) ^ set(times))
....
candidates = diffset

which sets up:

2nd iteration candidates is now a list (see above). Doing

candidates*candidates[0]

is just candidates*3 which is now "list*number" which in python is not "multiply each list element by number", but instead: "create new list as being original list concatenated number times with itself". This is why you don't see the output you expected.

To fix this, simply do:

candidates = np.array(diffset)
FlyingTeller
  • 17,638
  • 3
  • 38
  • 53
  • Ahh, well spotted, thanks for clarifying! That indeed is a difference, and I should've noticed that. Accepting. EDIT: shows no error. Reading is important :) Read np.ndarray instad of np.array – Andreas_B Feb 21 '18 at 10:10
  • You might have to filter the elements from diffset that are larger than stopval. For example if you have candidates = 2...100 in the first iteration, then times will contain 4...200 and diffset will contain all values from 102...200 that you don't want – FlyingTeller Feb 21 '18 at 10:18
  • Additionally, I think your candidates list will not be empty in the end, but might contain values > sqrt(stopval) that are valid primes and need to be added to the list – FlyingTeller Feb 21 '18 at 10:21
  • Oh yes. another (should be) obvious flaw of my code. Thanks again for the assistance. consider my problems solved for now. – Andreas_B Feb 21 '18 at 10:34