0

I created a primality test algorithm, but it doesn't work.

In essence, these are the steps my program takes:

  • Ask the user for a lower and upper bound in which to look for primes
  • An array, primes, will store my primes
  • A nested for loop; the first for loop takes every number between the user's lower and upper bounds and then checks if every one of those numbers is divisible by any of the numbers between 2 and the user's upper bound
  • If any number between the lower and upper bounds is divisible by any number between 2 and the user's upper bound, the number is obviously not prime.
  • Otherwise, the number is appended to the array primes:
lower = int(input("Lower Bound: "))
upper = int(input("Upper Bound: "))

print ("Primes between " + str(lower) + " and " + str(upper) + ": ")

primes = []

for i in range (lower, upper): 
  for num in range (2, upper/2):
    if i % num == 0: 
      print (str(i-(lower-1)) + ". " + str(i) + " = No")
      break
  else: 
    primes.append(i)

print(primes)

However, the regardless whether a number is prime or not, the function always outputs no, but I have no idea why!

DarkRunner
  • 449
  • 4
  • 15
  • For your second loop you should only need to go to upper/2. The lowest multiplier you could get would be 2. 2x=n see `for num in range (2, int(upper/2)):` – wski Nov 06 '19 at 03:49
  • You should use `i` in the second loop range. – 001 Nov 06 '19 at 03:52
  • 1
    @BillSkiCO Yup; that was it. What a silly mistake – DarkRunner Nov 06 '19 at 03:53
  • @JohnnyMopp Isn't it interchangeable? – DarkRunner Nov 06 '19 at 03:55
  • The inner loop is testing if `i` is prime and `i != upper` – 001 Nov 06 '19 at 03:57
  • @JohnnyMopp Sorry, I don't understand; `for i in range (lower, upper)` are the numbers being tested against all the divisors in `for num in range (2, upper/2)`. So what do you mean by the inner loop and `i != upper`? Thanks – DarkRunner Nov 06 '19 at 04:12
  • @BillSkiCO for the second loop it's enough to go as high as `sqrt(i)`, saving a lot of time for the large numbers. And there's no point testing against even numbers, only the odd numbers, thus making things twice as fast. – lenik Nov 06 '19 at 06:33
  • @lenik true, I was assuming since they are using 2 for loops to get a prime and not recursive calling with lru_cache decorator, that importing math to use math.sqrt() wasn’t being allowed for the homework or whatever. – wski Nov 07 '19 at 14:22

1 Answers1

2

Fixed it. First, I did the floor division // operator so it returns an integer. Also, I made a condition that the divisor couldn't be divided by itself. Because otherwise 4 would be a prime of 4.

lower = int(input("Lower Bound: "))
upper = int(input("Upper Bound: "))

print ("Primes between " + str(lower) + " and " + str(upper) + ": ")

primes = []

for i in range (lower, upper):
  for num in range (2, upper//2):
    if i % num == 0 and num != i: # modification here
      print (str(i-(lower-1)) + ". " + str(i) + " = No")
      break
  else:
    primes.append(i)

print(primes)

Out[1]: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43]

Nicolas Gervais
  • 33,817
  • 13
  • 115
  • 143