Dhruv Marwha
Dhruv Marwha

Reputation: 1074

Can't check whether a number is a perfect or not

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

Answers (4)

brandizzi
brandizzi

Reputation: 27060

It is time for some...

DEBUGGING!!!

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?

Wrong indentation

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))

Strange message

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))

How meaningful names help

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!

The range limit

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):

Conclusion

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

thodnev
thodnev

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

gallium
gallium

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

Stidgeon
Stidgeon

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).

  1. you need to nest the if - else statements differently (see below).

  2. 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

Related Questions