Reputation: 305
I could successfully rum a simple program to check whether the number is prime or not in C. The code looks like this
void isPrime(int n)
{
int a=0,i;
for(i=1;i<=n;i++)
{
if(n%i==0)
a++;
}
if(a==2)
{
printf("\n%d is prime",n);
}
else
{
printf("\n%d is not prime",n);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
for(int i=2;i<=20;i++)
{
isPrime(i);
}
return 0;
}
The above code runs perfectly when I compile. I am a beginner in python and I have converted the same code into python, which looks like this.
def isPrime(n):
a=0
for x in range(1,n):
if n%x==0:
a=a+1
if a==2:
print("{} is prime".format(n))
else:
print("{} is not prime".format(n))
for n in range(2,20):
isPrime(n)
But I get a wrong output in python. The output is somewhat weird which says
2 is not prime
3 is not prime
4 is prime
5 is not prime
6 is not prime
7 is not prime
8 is not prime
9 is prime
10 is not prime
11 is not prime
12 is not prime
13 is not prime
14 is not prime
15 is not prime
16 is not prime
17 is not prime
18 is not prime
19 is not prime
I have found out that the count of 'a' is 1 less than the actual count required. For example, in case of n=8, a should be 4. But its getting counted as 3. What could be the reason?
Upvotes: 1
Views: 76
Reputation:
I think the problem was with your range as mentioned above. Can I give you some short tips to make your code more "Pythonic"? :)
Instead of
if n%x==0
you would simply write
if not n%x
and instead of
a=a+1
you could use the in-place operator, e.g.,
a += 1
Here, it wouldn't make much of a difference, but if you are working with mutable objects (due to the __iadd__
method, I have more details here) you would gain a significant performance increase, e.g.,
def slow(a):
for i in range(1000):
a = a + [1,2]
def fast(a):
for i in range(1000):
a += [1,2]
a = []
b = []
%timeit -r 3 -n 1000 slow(a)
%timeit -r 3 -n 1000 fast(b)
1000 loops, best of 3: 2.94 ms per loop
1000 loops, best of 3: 181 µs per loop
Same for the binary operator instead of the format()
method, however, I like the latter one better (due to its more powerful minilanguange and I would recommend it if you don't care about speed in certain computations)
%timeit -r 3 -n 1000 '{} World'.format('Hello')
%timeit -r 3 -n 1000 '%s World' %('Hello')
1000 loops, best of 3: 472 ns per loop
1000 loops, best of 3: 27.3 ns per loop
def isPrime(n):
a = 0
for x in range(1, n+1):
if not n%x:
a += 1
if a==2:
print("{} is prime".format(n))
else:
print("{} is not prime".format(n))
for n in range(2, 20):
isPrime(n)
Upvotes: 1
Reputation: 22882
The issue you have is that the last value produced range(start, stop)
is stop-1
; see the docs. Thus, isPrime
should have the following for
loop:
for x in range(1, n+1):
This will faithfully replicate the C code, and produce the correct output. (Note that this is also why you are only checking the numbers [2, 19] for whether they're prime, as opposed to [2, 20].)
Upvotes: 2
Reputation: 78700
Why don't you add some print
statements so you can see where the code fails? Adding some prints should be your first reflex when debugging.
def isPrime(n):
a=0
for x in range(1,n):
print('x,a', x,a)
if n%x==0:
print('incrementing a...')
a=a+1
print('a after loop:', a)
if a==2:
print("{} is prime".format(n))
else:
print("{} is not prime".format(n))
Output for isPrime(2)
:
x,a 1 0
incrementing a...
a after loop: 1
2 is not prime
Output for isPrime(7)
:
x,a 1 0
incrementing a...
x,a 2 1
x,a 3 1
x,a 4 1
x,a 5 1
x,a 6 1
a after loop: 1
7 is not prime
As you can see, a
is never 2 because the n%n
test is never executed, because with x in range(1,n)
, the last value for x
is n-1
. However, if you change your range
to range(1,n+1)
, the test will be made:
x,a 1 0
incrementing a...
x,a 2 1
x,a 3 1
x,a 4 1
x,a 5 1
x,a 6 1
x,a 7 1
incrementing a...
a after loop: 2
7 is prime
Upvotes: 4