Python Program to Check a Perfect Number
Beginner Numbers
Checks whether a number equals the sum of its proper divisors, the smaller numbers that divide it exactly, as 28 does.
A perfect number equals the sum of its proper divisors: the smaller numbers that divide it exactly. 28 is one: its proper divisors are 1, 2, 4, 7 and 14, and 1 + 2 + 4 + 7 + 14 = 28. Perfect numbers are rare: below 10,000 there are only four, 6, 28, 496 and 8128.
Program
def is_perfect(number):
"""True if number is a perfect number."""
total = 0
for divisor in range(1, number):
if number % divisor == 0:
total += divisor
return total == number
print("28:", is_perfect(28))
print("12:", is_perfect(12))
Open in the editor Download perfect_number.py
Output
28: True
12: False
How it works
Step through the program line by line: each step below shows up as its line runs.
-
totalholds the sum of the divisors found so far. It starts at 0. - The loop tries every number from 1 up to one less than
number.range()stops before its end, so the number itself, which always divides it, isn't counted. -
%gives the remainder of a division. A remainder of 0 meansdivisordivides the number exactly, so it's added to the total. - The number is perfect when that total equals the number itself.
- The program checks 28, which is perfect, and 12, which isn't: its proper divisors 1, 2, 3, 4 and 6 add up to 16.
Other ways to write it
With a list comprehension
A list comprehension collects the divisors in one line, and sum() adds them up:
def is_perfect(number):
divisors = [d for d in range(1, number) if number % d == 0]
return sum(divisors) == number
print(is_perfect(6), is_perfect(8))Checking divisors in pairs
Divisors come in pairs that multiply to the number: 2 ร 14 = 28 and 4 ร 7 = 28. The smaller of each pair is never more than the square root of the number, so the loop can stop there and add both. For 8128 that's 89 tries instead of 8127.
from math import isqrt
def is_perfect(number):
if number < 2: # 1 has no proper divisors
return False
total = 1 # 1 divides every number
for divisor in range(2, isqrt(number) + 1):
if number % divisor == 0:
partner = number // divisor
total += divisor
if partner != divisor: # 36 = 6 x 6: add 6 once
total += partner
return total == number
print(is_perfect(8128), is_perfect(8000))Try it yourself
- Check 6 and 496, which are perfect, and 1, which isn't: it has no proper divisors, so their total is 0.
- Print every perfect number below 1000 with a loop. There are three: 6, 28 and 496.
- Make the loop go only up to half the number, with
range(1, number // 2 + 1). No proper divisor is bigger than half, so the result is the same with half the work. - Say whether a number is abundant, with divisors that add up to more than it (12's make 16), or deficient, with divisors that add up to less (8's make 1 + 2 + 4 = 7).