-1

I'm trying to create a program in Python that prints consecutive prime numbers.

estPrimes = [2, 3]
num = 3
run = True

while run == True:
    for i in range(estPrimes[0], estPrimes[(len(estPrimes) - 1)]):
        if i % num == 0:
            num += 2
            sleep(1)
        else:
            estPrimes.append(num)
            print(num)
            sleep(1)
            num += 2

It will only end up printing by twos, I know it has something to do with num += 2 but, why isn't it dividing by the estPrimes list?

FHTMitchell
  • 11,793
  • 2
  • 35
  • 47
  • "why isn't it dividing by the estPrimes list?" What exactly are you expecting there? – roganjosh Aug 24 '18 at 15:20
  • @PatrickHaugh that's not the issue, `i` is all numbers between the first and last prime. The bigger problem is that `num += 2` is executed no matter what on each iteration – FHTMitchell Aug 24 '18 at 15:24
  • See this lovely [debug](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) blog for help. If you insert a few tracing `print` commands to follow the values you're generating, you'll see the sequence of problems in this logic. – Prune Aug 24 '18 at 15:24
  • 1
    Also, you seem to be trying to implement [The Sieve](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes), but haven't researched the algorithm. There are *many* implementations of this in almost every computer language, as well as faster methods of generating primes. If you're trying to work this out as a programming exercise, then at least check the Wiki page for help with accurate logic. If not, simply understand one of the existing solutions and adapt that. – Prune Aug 24 '18 at 15:27
  • Possible duplicate of [Print series of prime numbers in python](https://stackoverflow.com/questions/11619942/print-series-of-prime-numbers-in-python) – LinkBerest Aug 24 '18 at 15:28

1 Answers1

1

Where to start?

  • You're editing a list while iterating over it. That is generally ill advised -- weird bugs can come of it.

  • You increment num no matter what happens in your condition -- this is your main issue

  • you're checking every number between the first and last primes you've found, not just the primes


here is a fix of your code

def print_primes_to(n):

    primes = [2,3]
    for prime in primes:
        print(prime)

    for num in range(5, n, 2):
        isprime = True
        for prime in primes:
            if num % prime == 0: #not prime
                isprime = False
                break
        if isprime:  # could replace with for/else
            primes.append(num)
            print(num)

test case

>>> print_primes_to(30)
2
3
5
7
11
13
17
19
23
29

There are better algorithms, here is one I have lying around:

import itertools as _itertools

def primelist(n):
    """Returns a list of all primes less than n."""
    if n <= 2:
        return []
    nums = [True]*(n - 2)
    for num in range(2, _rootp1(n)):
        for counter in _itertools.count(num):
            product = counter * num
            if product >= n:
                break
            nums[product - 2] = False
    return [index for index, val in enumerate(nums, 2) if val]

def _rootp1(n: float) -> int:
    """returns the truncated square root of n plus 1 for use in range"""
    return int(n**0.5) + 1

See how long it takes to generate all primes less that 1 million

%timeit primelist(1_000_000)  
1.33 s ± 30.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
FHTMitchell
  • 11,793
  • 2
  • 35
  • 47
  • I just had one question, what did you mean when you said that I was "editing a list while iterating over it"? – SuperNovaa411 Aug 24 '18 at 15:34
  • `lists` are "mutable" -- meaning we can manipulate the data in them after creation such as by `.append` or `.remove` (unlike strings or tuples). If you use one of these "mutating" methods while iterating (using in a `for` loop) then you can cause strange things to happen. See https://stackoverflow.com/questions/6260089/strange-result-when-removing-item-from-a-list – FHTMitchell Aug 24 '18 at 15:37