I'm new to programming, and to practice learning Python, I'm trying to write a program that will test which numbers in a range from (2, n-1)
are prime, by testing if there are any factors num is divisible by between 2
and sqrt(n)
.
For the most part, the prime list is pretty accurate, but for some reason the squares of primes >= 11 make it through the loop. The for i in range
part of the loop should be filtering them out. I have a feeling it has to do wih how I ordered the if-statements
, or maybe how I indented everything, but I can't quite figure it out. Any help would be appreciated!
I also realize I could just keep adding num % 11 == 0
or num % 13 == 0
to line 7, but that kinda defeats the purpose of the program automating this for me.
Also, I know I could just find a million other Python prime checkers, but I'm trying to figure out where I'm going wrong here so I can improve. Thank you!!!
n = 362
prime = []
def prime_check(lst=range(2,n)):
for num in lst:
if num == 1 or num == 2 or num == 3 or num == 5 or num == 7:
prime.append(num)
if num % 2 == 0 or num % 3 == 0 or num % 5 == 0:
continue
for i in range(5, int(sqrt(n) 1), 2):
if num % i == 0:
continue
else:
prime.append(num)
print(prime)
CodePudding user response:
import math
n = 362
prime = []
def prime_check(lst=range(2,n)):
for num in lst:
if num == 2 or num == 3 or num == 5 or num == 7:
prime.append(num)
continue
if num % 2 == 0 or num % 3 == 0 or num % 5 == 0:
continue
flag = 0
for i in range(5, int(math.sqrt(num) 1), 2):
if num % i == 0:
flag=1
break
if flag == 0:
prime.append(num)
return prime
print(prime_check())
You had one issue in the logic. The flag
ensures a prime is added only once.
Note: As @Kelly Bundy mentioned wrongly, and I also got confused. The logic that you have wrote is wrong. That is exactly why the number 121 which is just 11x11 gets into the prime list.
Note2: One portion I wrote wrong earlier regarding else
part. (Corrected due to @Kelly Bundy)
def prime_check(lst=range(2,n)):
for num in lst:
flag = 0
if num % 2 == 0:
continue
for i in range(3, int(math.sqrt(num) 1), 2):
if num % i == 0:
flag=1
break
if flag == 0:
prime.append(num)
return prime
Note: 1
is non-prime.
My earlier answer and even now the current answer, avoided for-else
. Personally I, avoid it explicitly - using such syntactic constructs not only makes it less readable for me but the time to understand such things in large codebase is really difficult.
CodePudding user response:
You should use the correct root and use break
and not treat 7 inconsistently.
Fixed code (Try it online!):
from math import sqrt
n = 362
prime = []
def prime_check(lst=range(2,n)):
for num in lst:
if num == 1 or num == 2 or num == 3 or num == 5:
prime.append(num)
if num % 2 == 0 or num % 3 == 0 or num % 5 == 0:
continue
for i in range(5, int(sqrt(num) 1), 2):
if num % i == 0:
break
else:
prime.append(num)
print(prime)
prime_check()
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359]