1

I am about to execute a function which aim is to return a Prime/Not prime statement if its argument is or isn't a prime number. I succeeded using a for loop:

def prime1(n):

z = []

for i in range (1, n+1):
    if (n/i).is_integer():
        z.append(i)
        i=i+1

if len(z) == 2:
    print ("Prime")
else:
    print ("Not prime")`

Then I tried to do the same but using the while loop:

def prime2(n):

z = []
i = 1

while i < int(len(range(1, n+1))):
    if (n/i).is_integer():
        z.append(i)
        i=i+1

if len(z) == 2:
    print ("Prime")
else:
    print ("Not prime")

Unfortunately, my system continues to calculating without printing me an output.

Can you explain me where I have made a mistake?

Luca F.
  • 77
  • 5
  • `if (n/i).is_integer():` if this fails you never increased `i` therefore you are stuck in an infinite loop – MooingRawr Sep 19 '18 at 14:43
  • Duplicate of https://stackoverflow.com/questions/4114167/checking-if-a-number-is-a-prime-number-in-python – timgeb Sep 19 '18 at 14:44
  • The duplicate answers the question "how do you calculate primes numbers?", not the question as asked, which is "why aren't my `while` and `for` loops equivalent?". – chepner Sep 19 '18 at 14:55

5 Answers5

2

The i = i + 1 does nothing in your for loop, since the value of i is overwritten with the next value of the iterator; effectively, the for loop is performing i = i + 1 for you on every iteration, whether or not i divides n. You need to do the same thing in your while loop:

while i < n + 1:
    if (n/i).is_integer():
        z.append(i)
    i = i + 1
chepner
  • 389,128
  • 51
  • 403
  • 529
1

The most pythonic way I could think of is below:

def isPrime(n):
    return all(n % i for i in range(2, int(n ** 0.5) + 1)) and n > 1

for i in range(1, 20):
    print(isPrime(i))

Explanation:

  • all makes sure that every item in the given expression returns True

  • n % i returns True if n != 0 (even negative numbers are allowed)

  • int(n ** 0.5) is equivalent to sqrt(n) and as range always returns numbers up to n - 1 you must add 1

  • n > 1 makes sure that n is not 1

The problem in your code is that your i = i + 1 in the wrong scope
Your program checks if (n/i).is_integer() which returns False as n / 2 is not a integer

Improving your code:

Instead of (n/i).is_integer() you can use n % i == 0, which returns the remainder equals 0
Next you must place i = i + 1 in the outer scope

And personally, I was never a fan of i = i + 1. Use i += 1

I think the best way is using the code I have shown above.

Hope this helps!

Edit:

You can make it print 'Prime' or 'Not Prime' as follows:

def isPrime(n):
    print('Prime' if all(n % i for i in range(2, int(n ** 0.5) + 1))
                 and n > 1 else 'Not Prime')

for i in range(1, 20):
    isPrime(i)
Sriv
  • 346
  • 3
  • 14
0

You are increment the iterable variable i inside the if statement, so the variable is never incremented, stucking on an infinite loop.

When you used for it worked because the iterable changes itself after every full iteration of the block.

Moving the incremenf of i one identation block to the left (inside the while instead of for) will work just fine

Rodolfo Donã Hosp
  • 932
  • 1
  • 9
  • 21
0

Code adapted from https://www.programiz.com/python-programming/examples/prime-number

You don't need to check until num and you can go 2 by 2 if you don't have a database of prime numbers

import math
#num = 437
if num > 1:
    # check for factors
    for i in range(2, int(math.ceil(math.sqrt(num))), 2):
        if (num % i) == 0:
            print(num, "is not a prime number")
            print(i, "times", num // i, "is", num)
            break
    else:
        print(num, "is a prime number")

# if input number is less than
# or equal to 1, it is not prime
else:
    print(num, "is not a prime number")
PilouPili
  • 2,372
  • 2
  • 13
  • 27
0

Our preferred method should not be while loops if we don't need to use them, that being said, we could use list comprehensions:

def prime(n):
    z = []  
    [z.append(i) for i in range(1, n+1) if (n/i).is_integer()]
    [print("Prime") if len(z) == 2 else print("Not Prime")]

prime(101)

But lets take a loop at what you got your for loop:

for i in range (1, n+1):
    if (n/i).is_integer():
        z.append(i)
        i=i+1

The line i = i + doesn't serve the purpose you intend, the loop is going to iterate from 1 to n+1 no matter what

Now the while loop:

while i < int(len(range(1, n+1))):
   if (n/i).is_integer():
       z.append(i)
       # i=i+1 does not go inside if statement
   i += 1

Now you do need to increment i but if that incrementing only occurs when the if conditions are met, then if the if condition is not met you are going to be stuck at the same i looping over it. Also try using i += 1 means the same thing

vash_the_stampede
  • 4,274
  • 1
  • 5
  • 20