Reputation: 1074
I'm trying to learn python but I ran into an error.
So, here's the code for the program I am trying to run: To check whether a number is a perfect number or not:
total=0
x=0
number=input('Enter a number to be checked whether it is perfect or not:')
number=int(number)
for divisor in range(1,number+1):
x=number%divisor
if x==0:
total+=x
else:
print('The number' +str(x)+'is not a divisor of' +str(number))
print('\n'+ 'The sum is:' +str(total))
if number==total:
print('The number' +str(number) + 'is a perfect number')
else:
print('The number' +str(number) +'is not a perfect number')
Upvotes: 1
Views: 324
Reputation: 27060
It is time for some...
I pasted your code in a file, and ran it:
$ python3 p.py
Enter a no to be checked whether it is perfect or no:6
The sum is:0
The no6is not a perfect no
Well, 6 is a perfect number, so what is going on?
Reading your code, I have the feeling the if
below is expected to be run on every value from the for
, right:
for divisor in range(1,number+1):
x=number%divisor
if x==0:
total+=x
else:
print('The no' +str(x)+'is not a divisor of' +str(number))
That is not happening because the indentation is wrong! To be inside the for
, the if
should be at the same line of the attribution:
for divisor in range(1,number+1):
x=number%divisor
if x==0:
total+=x
else:
print('The no' +str(x)+'is not a divisor of' +str(number))
So, let's try again:
$ python3 p.py
Enter a no to be checked whether it is perfect or no:6
The no2is not a divisor of6
The no1is not a divisor of6
The sum is:0
The no6is not a perfect no
Well, still wrong.
Weirdly, it says that 2 and 1 do not divide 6. Preposterous! But it is actually a problem with the print()
call:
print('The no' +str(x)+'is not a divisor of' +str(number))
x
is not the divisor—x
is the rest!
Well, you messed the variables up. That's normal when there are many variables... and they do not have meaningful names. Let's then rename x
to rest
:
for divisor in range(1,number+1):
rest=number%divisor
if rest==0:
total+=rest
else:
print('The no' +str(rest)+'is not a divisor of' +str(number))
Of course the printed message wrong: I want to show the divisor, not the rest! Let's change that:
print('The no' +str(divisor)+'is not a divisor of' +str(number))
Now comes something interesting: we are adding the rest to the total...
if rest==0:
total+=rest
...but we should add the divisor! Let's correct that:
for divisor in range(1,number+1):
rest=number%divisor
if rest==0:
total+=divisor
else:
print('The no' +str(divisor)+'is not a divisor of' +str(number))
Finally! Now the program will work correct... or will it?
$ python3 p.py
Enter a no to be checked whether it is perfect or no:6
The no4is not a divisor of6
The no5is not a divisor of6
The sum is:12
The no6is not a perfect no
Dang!
Why is it saying that the sum is 12? Well, let's look the loop again:
for divisor in range(1,number+1):
Oh, now I see... Let's just call it printing the numbers:
>>> number = 6
>>> for divisor in range(1,number+1):
... print(divisor)
...
1
2
3
4
5
6
That's it! When you run the loop from 1 to number+1
(in this case, 7), the number itself (6) is processed. Well, 6 is a divisor of 6, so it is also added to the total... duplicating it! So you should only go until number:
for divisor in range(1,number):
Does it work? See the output here:
$ python3 p.py
Enter a no to be checked whether it is perfect or no:6
The no4is not a divisor of6
The no5is not a divisor of6
The sum is:6
The no6is a perfect no
$ python3 p.py
Enter a no to be checked whether it is perfect or no:28
...
The no27is not a divisor of28
The sum is:28
The no28is a perfect no
$ python3 p.py
Enter a no to be checked whether it is perfect or no:9
The no2is not a divisor of9
...
The no8is not a divisor of9
The sum is:4
The no9is not a perfect no
Yes!
I guess it was really hard to you to see all the problems, because there were many. The secret is: learn to see one problem per time.
Upvotes: 5
Reputation: 1612
I think you mean 'prime' number. If so, it's not the best way to learn Python because prime check algorithms are not so simple, and thus may be better coded in C and then wrapped with Python. If you want a naive check, here's how it may look like:
def is_prime(number, *, verbose=False):
divisor = int(number / 2)
for divisor in range(divisor, 1, -1):
if number % divisor == 0:
return False, divisor if verbose else False
return True, None if verbose else True
numbers = [27, 11, 13, 2, 4]
for i in numbers:
print('Number ',i,'\tResult:',is_prime(i, verbose=True))
Number 27 Result: (False, 9)
Number 11 Result: (True, None)
Number 13 Result: (True, None)
Number 2 Result: (True, None)
Number 4 Result: (False, 2)
Upvotes: 0
Reputation: 301
I guess you've forgotten a "2*" in your code.
Here is a simple way to test if a number is perfect or not:
def sumDiv(n):
s = 0
for k in range(1,n+1):
if n%k==0:
s+=k
return s
def isPerfectNumber(n):
return 2*n == sumDiv(n)
number = 6 # for example
if isPerfectNumber(number):
print("{} is a perfect number".format(number))
Upvotes: 0
Reputation: 2723
There are a couple of issues with your code:
1. you refer to x
when summing divisors, but you want to refer to divisor
- x is the result of the modulus calculation (which, when 0, is the decider of whether to add divisor to your total).
you need to nest the if - else
statements differently (see below).
you need to divide your total by 2 when comparing to the original number. The way your code works with a perfect number - like 6 - is it finds that 1,2,3, and 6 are all divisors. So the sum will be 12 - which needs to be divided by 2 to produce a positive result.
Adjusted code is:
total=0
x=0
number=input('Enter a no to be checked whether it is perfect or no:')
number=int(number)
for divisor in range(1,number+1):
x = number % divisor
if x == 0:
print divisor
total += divisor
else:
print('The no' +str(divisor)+'is not a divisor of' +str(number))
print('\n'+ 'The sum is:' +str(total))
if number==total/2:
print('The no' +str(number) + 'is a perfect no')
else:
print('The no' +str(number) +'is not a perfect no')
Upvotes: 1