2

I'm new to Python. I am trying to count the prime numbers in a given range. Some of the answers that developers have shared are like this:

import math
def count_primes(num):
    out = []

    for i in range(3,num,2):
        if all(i%j!=0 for j in range(3,int(math.sqrt(i))+1,2)):
            out.append(i)

    print(out)

I wrote a one like this:

import math
def count_primes(num):
    out = []
    for i in range(3,num,2):
        for j in range(3, int(math.sqrt(i))+1,2):
            if i%j != 0:
                out.append(i)           
        print(out)

but it doesn't work. Could somebody please help me. Appreciated!

cdlane
  • 33,404
  • 4
  • 23
  • 63
  • 2
    You need to test all the numbers in the j for loop before append I to out. You're currently appending after the first non-divisor of i. – DarrylG Jun 24 '20 at 21:57
  • 2
    Your first code checks if *all* possible divisors return a non-zero remainder. Your second only checks until *one* divisor returns a non-zero remainder. – Mark Ransom Jun 24 '20 at 21:58
  • 2
    P.S. Check into the [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes), it's a much faster way to generate a list of primes. – Mark Ransom Jun 24 '20 at 22:00
  • https://stackoverflow.com/q/2068372/238704 – President James K. Polk Jun 25 '20 at 12:49

5 Answers5

2

Neither of your example count_primes() functions actually counts primes -- they simply print odd primes. Let's implement a working version of your trial division code, not using confusing booleans and a bad algorithm, but rather taking advantage of Python's else clause on for loops:

def collect_odd_primes(number):
    primes = []

    for candidate in range(3, number, 2):
        for divisor in range(3, int(candidate ** 0.5) + 1, 2):
            if candidate % divisor == 0:
                break
        else:  # no break
            primes.append(candidate)

    return primes

print(collect_odd_primes(40))

OUTPUT

> python3 test.py
[3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
>

As @MarkRansom comments, the Sieve of Eratosthenes is the better way to go. (+1) Now, let's convert our code to count odd primes instead:

def count_odd_primes(number):
    count = 0

    for candidate in range(3, number, 2):
        for divisor in range(3, int(candidate ** 0.5) + 1, 2):
            if candidate % divisor == 0:
                break
        else:  # no break
            count += 1

    return count

print(count_odd_primes(40))

OUTPUT

> python3 test.py
11
> 
cdlane
  • 33,404
  • 4
  • 23
  • 63
1

Something like this should work. You have to set a variable, because 15%9 != 0, outputs True.

import math
def count_primes(num):
    out = []
    for i in range(3,num,2):
        prime = True
        for j in range(3, int(math.sqrt(i))+1,2):
            if i%j == 0:
                prime = False
        if prime:
            out.append(i)
    print(out)
    
count_primes(15)
KetZoomer
  • 1,880
  • 2
  • 7
  • 26
1

The reason your code and the other is is different is because their use of the all() method. Have a look at how i implemented the method using bools:

import math
def count_primes(num):
    out = []
    for i in range(3,num,2):
        f = True
        for j in range(3,int(math.sqrt(i))+1,2):
            if i%j==0:
                f = False
                break
        if f:
            out.append(i)

    print(out)
    
count_primes(20)

Output:

[3, 5, 7, 11, 13, 17, 19]
Ann Zen
  • 17,892
  • 6
  • 20
  • 39
0

You’re appending to the result of the module is unequal to zero. However, it’s only a prime number if all modulo are unequal to zero (there is an all statement missing in your code).

Dorian
  • 1,208
  • 1
  • 7
  • 21
0

Depending on what program you're running for your code-writing, an alternative method—as opposed to the other answers to this question—would be to write:

    n = int(input("Write an integer:"))
    m = 2

    if n == 1:
        print(n, "is a prime number!")

    if n == 2:
        print(n, "is not a prime number.")

    while n > m:
        if n % m == 0:
            m = m + 1
            print(n, "is not a prime number.")
            break

        if n > n % m > 0:
            m = m + 1
            print(n, "is a prime number!")
            break

It may not be the most efficient, but it gives you a really nice, straight answer to whether or not "x" is a prime number!

quasireal
  • 5
  • 2