how nested loop works in the following example - python

I have a code for printing all prime numbers lying in the range (2, 50)
num = 2
for i in range(2, 50):
j = 2
while(j <= (i/2)):
if (i % j == 0):
break
j += 1
if(j > i/j):
print(i,'is a prime number')
My doubt is regarding the use and significance of if(j > i/j) statement.

Based on the above, for all prime numbers by the time the code execution reaches if condition, j will always be equal to i and the if condition will become true.
Let's go through step by step for a prime and a non-prime number.
Example 1 : Prime number 7(Assume value of i is at 7 in the for loop)
i = 7
j = 2
# While statement condition check
2 <= 7/2 -> True
7%2 == 0 -> False
# Increment j, now j=3
7%3 == 0 -> False
.
.
# Increment continuously, and when j=7
7%7 == 0 -> True
#If Condition check(Current values are i=7 and j=7)
7 > 7/7 -> True
Example 2: Non-Prime Number. Let's say 9
i = 9
j = 2
# While statement condition check
2 <= 7/2 -> True
9%2 == 0 -> False
# Increment j, now j=3
9%3 == 0 -> True
#If Condition check(Current values are i=9 and j=3)
3 > 9/3 -> False
Do try for other examples step by step to understand better.

I haven't seen somebody use this algorithm for finding prime numbers before, you can do this for finding prime numbers:
for i in range(2, 50):
num, j = 0, 2
while j <= i:
if i % j == 0:
num += 1
j += 1
if num == 1:
print(i, 'is a prime number')

Honestly the best way to understand things like this, is to break it down step-by-step yourself to understand it. Take a smaller example, say range(2,6), and write the progress/steps down by hand.
Hint, do it for i = 39.

Related

Check Prime Number, in python. logic confusion

I found this code in a website for checking prime number
def isPrime(number):
if (number <= 1):
return False
elif (number <= 3):
return True
elif (number % 2 == 0 or number % 3 == 0):
return False
i = 5
while(i * i <= number):
if (number % i == 0 or number % (i + 2) == 0):
return False
i += 6
return True
but I can't understand the logic of if statement under while loop, that is if (number % i == 0 or number % (i + 2) == 0)
why need i+2??? when i is even, i+2 is also even and odd while i is odd. So, why need to check for i+2???
Except for 2 and 3, all prime numbers are of the form 6n±1. This code checks for 2 and 3 explicitly and then checks higher numbers in pairs: 6n-1, 6n+1, starting with 5. So it checks 5, 7 then 11, 13 then 17, 19 and so on. It steps 6 between pairs and steps 2 within each pair. Doing it this way avoids ever having to check multiples of 2 or 3.
i starts from 5, so adding 2 means taking in count only evens numbers.
It makes the check faster.
If you want to find out if a number is prime or not, here is a short sample
# Check if a positive integer number is a prime number. Check only till square root +1.
import math
def isPrime(n):
if ( n > 3 ):
if (n % 2 == 0):
return False
for i in range(3, math.isqrt(n), 2):
if (n % i == 0):
return False
return True
else:
return True

Python prime list

integer = int(input("Enter an integer: "))
if integer >= 2:
print(2)
for i in range(2, integer + 1): # range 2,3,...,integer (excludes 1)
for j in range(2, i): # we are going to try dividing by these
if i % j == 0: # not prime
break
else: # is prime
print(i)
input:
7
output:
2
3
5
5
5
7
7
7
7
7
output I want:
2
3
5
7
adding more detail to get past error:
It looks like your post is mostly code; please add some more details.
You're printing i for every value of j that doesn't divide it, until you get a value that does divide it and you execute break.
You should only print i when you don't break out of the loop. Put the else: statement on the for loop, not if. This else: statement is executed when the loop finishes normally instead of breaking.
for i in range(2, integer + 1): # range 2,3,...,integer (excludes 1)
for j in range(2, i): # we are going to try dividing by these
if i % j == 0: # not prime
break
else: # is prime
print(i)
Put the print(i) in the outer for loop with a flag that keeps track of the result.
for i in range(2, integer + 1): # range 2,3,...,integer (excludes 1)
isPrime = True
for j in range(2, i): # we are going to try dividing by these
if i % j == 0:
isPrime = False
break
if isPrime:
print(i)
Your logic is slightly wrong. I have added the correct code below with comments :
integer = int(input("Enter an integer: "))
if integer >= 2:
print(2)
for i in range(2, integer + 1): # range 2,3,...,integer (excludes 1)
prime=true #assume that i is prime
for j in range(2, i): # we are going to try dividing by these
if i % j == 0: # not prime
prime=false # we now know it is not prime
break
if prime==true: # if we didn't do prime=0, then it's a prime
print(i)
What you were doing is printing i for every j from 2 to i that did not divide i. But instead, what had to be done is print i only once when none of the j from 2 to i divided i.
Hope you understand the mistake and this clears your doubt !

Printing prime number in python

I am trying to print prime numbers in python in the range 3-50. Here is the code:
for i in range(3,51):
flag=0
for j in range(3,i):
if(i%j==0):
flag=1
if(flag==0):
print(i)
The code is running correctly except THAT IT IS ALSO PRINTING 4. Please tell if there is anything wrong with the logic of the code (ignore the efficiency issues).
print(2)
for i in range(3,51):
flag=0
for j in range(2,int(i/2)):
if(i%j==0):
flag=1
if(flag==0):
print(i)
When i = 4, the range will be range(2,2) which is 0. It will not enter the if(i%j == 0): block. Thus your flag would always be 0 when i = 4.
One way to solve it would be to just add a check if i is 4.
if(flag==0 and i != 4):
Edit : As commented by others, by incrementing the range by 1 would be a better fix than checking if the value is 4.
for j in range(2,int(i/2)+1)
change range(3,i) to range(2,i) because if we use range(3,i), 4 is not checked with division by 2. As a result 4 is returned as prime.
for i in range(3,51):
flag=0
for j in range(2,i):
if(i%j==0):
flag=1
if(flag==0):
print(i)
However, a more structural and efficient way is to use the following:-
def isPrime(num):
for i in range(2,num/2+1):
if (num%i==0):
return False
return True
for i in range(3,51):
if isPrime(i):
print i
We don't need to check the division by all numbers till the number itself for prime. Because if we can check till the half of the given number only for increased efficiency.
start = 3
end = 50
for val in range(start, end + 1):
# If num is divisible by any number
# between 2 and val, it is not prime
if val > 1:
for n in range(2, val):
if (val % n) == 0:
break
else:
print(val)
a = int(input("enter smaller no."))
b = int(input("enter larger no."))
for i in range (a,b+1):
if i>1:
for c in range(2,i):
if i%c == 0:
break
else:
print(i)
In the code above we ran a for loop from minimum to the maximum number and storing the value in i
for i in range (a,b+1):
then we check that the number stored in i is greater than 1 or not as all numbers are divisible by 1 and we don not want to consider it.
if i>1:
after this we run another loop, this time from 2 to 1 less then the number stored in i
for c in range(2,i):
Now we check that the number stored in i is divisible by any of the number from 2 to 1 number less then itself.
if i%c == 0:
If yes then clearly it is not a prime number and we break the loop.
break
And if no we print the number.
else:
print(i)
For 4 it probably does not go inside the if loop. So I increased the range for i.
print(2)
for i in range(3,51):
flag=0
for j in range(2,int(i/2)+1):
if(i%j==0):
flag=1
if(flag==0):
print(i)
for i in range(3,51):
flag=0
for j in range(2,i):
if(i%j==0):
flag=1
if(flag==0):
print(i)
This prints
3
5
7
11
13
17
19
23
29
31
37
41
43
47
4%2 = 0
4%3 = 1
So if you start from 3 you will miss out that 4%2 is = 0
If your list would have bigger numbers, you should change
range(2,int(i/2)+1)
for
range(2,math.floor(math.sqrt(n)+1))
For instance, 400 will try numbers until 20 instead of 200.
tryfor j in range(2,i):the numbers 4 is divisible is 1,2,4 if you start from 3 and continue until 4 but not four you can't find any divisors that is why it is considering 4 as a prime
import math
for num in range(1,50):
if num>1:
if num==2:
print(num)
elif num%2==0:
continue
else:
for i in range(3,math.ceil(math.sqrt(num)),2):
if num%i==0:
break
else:
print(num)
It is more efficient as it avoids even numbers and also check for the odd divisors up-to square root of the number which is more efficient than checking up-to only half of the given numbers

Prime number generator is not working Python

What I want to do is:
create a "list" of odd numbers
then test if they are prime
the test will be done with multiples up to half of the value of the odd number hence halfodd
put the prime number into a list
print that list
however my result is a list of numbers from 1 to 1003 that skip 3, 4, and 5
Is there a semantic error here?
#Prime number generator
def primenumber():
primelist = [1, 2]
num = 3
even = num%2
multi = 0
result = 0
while len(primelist) < 1000:
if even != 0:
oddnum = num
i = 2
halfodd = ((oddnum + 1)/2)
while i < halfodd:
i =+ 1
multi = oddnum%i
if multi == 0:
result += 1
if result != 0:
primelist.append(oddnum)
prime_num = oddnum
num += 1
print primelist
primenumber()
if result != 0:
Since result is (supposed to be) a count of how many factors you found, you want
if result == 0:
You're also not resetting result when you advance to a new candidate prime, you never recompute even, and if you did, you'd be considering the odd numbers twice each.
This should work:
def primenumber():
primelist = [1, 2]
candidate = 3
while len(primelist) < 1000:
isCandidatePrime = True
if (candidate % 2 == 0): # if candidate is even, not a prime
isCandidatePrime = False
else:
for i in range(3, (candidate+1)/2, 2): # else check odds up to 1/2 candidate
if (candidate % i == 0): # if i divides it, not a prime
isCandidatePrime = False
break
if (isCandidatePrime):
primelist.append(candidate)
candidate += 1
print primelist
I think there are several improvements (check only numbers less than or equal to the square root of the candidate, only check prime numbers, not all numbers less than the square root of the candidate) but I'll leave that alone for now.

How to generate the 1000th prime in python?

count = 0
i = 11
while count <= 1000 and i <= 10000:
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
continue
else:
print i,'is prime.'
count += 1
i+=1
I'm trying to generate the 1000th prime number only through the use of loops. I generate the primes correctly but the last prime i get is not the 1000th prime. How can i modify my code to do so. Thank in advance for the help.
EDIT: I understand how to do this problem now. But can someone please explain why the following code does not work ? This is the code I wrote before I posted the second one on here.
count = 1
i = 3
while count != 1000:
if i%2 != 0:
for k in range(2,i):
if i%k == 0:
print(i)
count += 1
break
i += 1
Let's see.
count = 1
i = 3
while count != 1000:
if i%2 != 0:
for k in range(2,i):
if i%k == 0: # 'i' is _not_ a prime!
print(i) # ??
count += 1 # ??
break
i += 1 # should be one space to the left,
# for proper indentation
If i%k==0, then i is not a prime. If we detect that it's not a prime, we should (a) not print it out, (b) not increment the counter of found primes and (c) we indeed should break out from the for loop - no need to test any more numbers.
Also, instead of testing i%2, we can just increment by 2, starting from 3 - they will all be odd then, by construction.
So, we now have
count = 1
i = 3
while count != 1000:
for k in range(2,i):
if i%k == 0:
break
else:
print(i)
count += 1
i += 2
The else after for gets executed if the for loop was not broken out of prematurely.
It works, but it works too hard, so is much slower than necessary. It tests a number by all the numbers below it, but it's enough to test it just up to its square root. Why? Because if a number n == p*q, with p and q between 1 and n, then at least one of p or q will be not greater than the square root of n: if they both were greater, their product would be greater than n.
So the improved code is:
from math import sqrt
count = 1
i = 1
while count < 1000:
i += 2
for k in range(2, 1+int(sqrt(i+1))):
if i%k == 0:
break
else:
# print(i) ,
count += 1
# if count%20==0: print ""
print i
Just try running it with range(2,i) (as in the previous code), and see how slow it gets. For 1000 primes it takes 1.16 secs, and for 2000 – 4.89 secs (3000 – 12.15 ses). But with the sqrt it takes just 0.21 secs to produce 3000 primes, 0.84 secs for 10,000 and 2.44 secs for 20,000 (orders of growth of ~ n2.1...2.2 vs. ~ n1.5).
The algorithm used above is known as trial division. There's one more improvement needed to make it an optimal trial division, i.e. testing by primes only. An example can be seen here, which runs about 3x faster, and at better empirical complexity of ~ n1.3.
Then there's the sieve of Eratosthenes, which is quite faster (for 20,000 primes, 12x faster than "improved code" above, and much faster yet after that: its empirical order of growth is ~ n1.1, for producing n primes, measured up to n = 1,000,000 primes):
from math import log
count = 1 ; i = 1 ; D = {}
n = 100000 # 20k:0.20s
m = int(n*(log(n)+log(log(n)))) # 100k:1.15s 200k:2.36s-7.8M
while count < n: # 400k:5.26s-8.7M
i += 2 # 800k:11.21-7.8M
if i not in D: # 1mln:13.20-7.8M (n^1.1)
count += 1
k = i*i
if k > m: break # break, when all is already marked
while k <= m:
D[k] = 0
k += 2*i
while count < n:
i += 2
if i not in D: count += 1
if i >= m: print "invalid: top value estimate too small",i,m ; error
print i,m
The truly unbounded, incremental, "sliding" sieve of Eratosthenes is about 1.5x faster yet, in this range as tested here.
A couple of problems are obvious. First, since you're starting at 11, you've already skipped over the first 5 primes, so count should start at 5.
More importantly, your prime detection algorithm just isn't going to work. You have to keep track of all the primes smaller than i for this kind of simplistic "sieve of Eratosthanes"-like prime detection. For example, your algorithm will think 11 * 13 = 143 is prime, but obviously it isn't.
PGsimple1 here is a correct implementatioin of what the prime detection you're trying to do here, but the other algorithms there are much faster.
Are you sure you are checking for primes correctly? A typical solution is to have a separate "isPrime" function you know that works.
def isPrime(num):
i = 0
for factor in xrange(2, num):
if num%factor == 0:
return False
return True
(There are ways to make the above function more effective, such as only checking odds, and only numbers below the square root, etc.)
Then, to find the n'th prime, count all the primes until you have found it:
def nthPrime(n):
found = 0
guess = 1
while found < n:
guess = guess + 1
if isPrime(guess):
found = found + 1
return guess
your logic is not so correct.
while :
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
this cannot judge if a number is prime or not .
i think you should check if all numbers below sqrt(i) divide i .
Here's a is_prime function I ran across somewhere, probably on SO.
def is_prime(n):
return all((n%j > 0) for j in xrange(2, n))
primes = []
n = 1
while len(primes) <= 1000:
if is_prime(n):
primes.append(n)
n += 1
Or if you want it all in the loop, just use the return of the is_prime function.
primes = []
n = 1
while len(primes) <= 1000:
if all((n%j > 0) for j in xrange(2, n)):
primes.append(n)
n += 1
This is probably faster: try to devide the num from 2 to sqrt(num)+1 instead of range(2,num).
from math import sqrt
i = 2
count = 1
while True:
i += 1
prime = True
div = 2
limit = sqrt(i) + 1
while div < limit:
if not (i % div):
prime = False
break
else:
div += 1
if prime:
count += 1
if count == 1000:
print "The 1000th prime number is %s" %i
break
Try this:
def isprime(num):
count = num//2 + 1
while count > 1:
if num %count == 0:
return False
count -= 1
else:
return True
num = 0
count = 0
while count < 1000:
num += 1
if isprime(num):
count += 1
if count == 1000:
prime = num
Problems with your code:
No need to check if i <= 10000.
You are doing this
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
Here, you are not checking if the number is divisible by a prime number greater than 7.
Thus your result: most probably divisible by 11
Because of 2. your algorithm says 17 * 13 * 11 is a prime(which it is not)
How about this:
#!/usr/bin/python
from math import sqrt
def is_prime(n):
if n == 2:
return True
if (n < 2) or (n % 2 == 0):
return False
return all(n % i for i in xrange(3, int(sqrt(n)) + 1, 2))
def which_prime(N):
n = 2
p = 1
while True:
x = is_prime(n)
if x:
if p == N:
return n
else:
p += 1
n += 1
print which_prime(1000)
n=2 ## the first prime no.
prime=1 ## we already know 2 is the first prime no.
while prime!=1000: ## to get 1000th prime no.
n+=1 ## increase number by 1
pon=1 ## sets prime_or_not(pon) counter to 1
for i in range(2,n): ## i varies from 2 to n-1
if (n%i)==0: ## if n is divisible by i, n is not prime
pon+=1 ## increases prime_or_not counter if n is not prime
if pon==1: ## checks if n is prime or not at the end of for loop
prime+=1 ## if n is prime, increase prime counter by 1
print n ## prints the thousandth prime no.
Here is yet another submission:
ans = 0;
primeCounter = 0;
while primeCounter < 1000:
ans += 1;
if ans % 2 != 0:
# we have an odd number
# start testing for prime
divisor = 2;
isPrime = True;
while divisor < ans:
if ans % divisor == 0:
isPrime = False;
break;
divisor += 1;
if isPrime:
print str(ans) + ' is the ' + str(primeCounter) + ' prime';
primeCounter += 1;
print 'the 1000th prime is ' + str(ans);
Here's a method using only if & while loops. This will print out only the 1000th prime number. It skips 2. I did this as problem set 1 for MIT's OCW 6.00 course & therefore only includes commands taught up to the second lecture.
prime_counter = 0
number = 3
while(prime_counter < 999):
divisor = 2
divcounter = 0
while(divisor < number):
if(number%divisor == 0):
divcounter = 1
divisor += 1
if(divcounter == 0):
prime_counter+=1
if(prime_counter == 999):
print '1000th prime number: ', number
number+=2
I just wrote this one. It will ask you how many prime number user wants to see, in this case it will be 1000. Feel free to use it :).
# p is the sequence number of prime series
# n is the sequence of natural numbers to be tested if prime or not
# i is the sequence of natural numbers which will be used to devide n for testing
# L is the sequence limit of prime series user wants to see
p=2;n=3
L=int(input('Enter the how many prime numbers you want to see: '))
print ('# 1 prime is 2')
while(p<=L):
i=2
while i<n:
if n%i==0:break
i+=1
else:print('#',p,' prime is',n); p+=1
n+=1 #Line X
#when it breaks it doesn't execute the else and goes to the line 'X'
This will be the optimized code with less number of executions, it can calculate and display 10000 prime numbers within a second.
it will display all the prime numbers, if want only nth prime number, just set while condition and print the prime number after you come out of the loop. if you want to check a number is prime or not just assign number to n, and remove while loop..
it uses the prime number property that
* if a number is not divisible by the numbers which are less than its square root then it is prime number.
* instead of checking till the end(Means 1000 iteration to figure out 1000 is prime or not) we can end the loop within 35 iterations,
* break the loop if it is divided by any number at the beginning(if it is even loop will break on first iteration, if it is divisible by 3 then 2 iteration) so we iterate till the end only for the prime numbers
remember one thing you can still optimize the iterations by using the property *if a number is not divisible with the prime numbers less than that then it is prime number but the code will be too large, we have to keep track of the calculated prime numbers, also it is difficult to find a particular number is a prime or not, so this will be the Best logic or code
import math
number=1
count = 0
while(count<10000):
isprime=1
number+=1
for j in range(2,int(math.sqrt(number))+1):
if(number%j==0):
isprime=0
break
if(isprime==1):
print(number,end=" ")
count+=1

Categories