How can I solve the error in this algorithm code (TypeError: 'NoneType' )?
Question:
I’m having trouble understanding and applying this exercise on my own with Python. I am getting this:
TypeError: '<' not supported between instances of 'int' and 'NoneType'
This is the exercise Algorithm:
Definition: An integer is said to be perfect if it is equal to the sum
of all its divisors. Examples: 6 and 28 are perfect since 6 = 1+2+3
(knowing that 1, 2 and 3 are the divisors of 6 less than 6) 28=
1+2+4+7+14 (knowing that 1, 2, 4, 7 and 14 are the divisors of 28 less
than 28)
-
Create a function liste_divisors(), which accepts an
integer N as a parameter and returns the list of its divisors less
than N (1 included).
-
Make a function is perfect(), which accepts a (positive) integer N
as a parameter and returns “True” if it is perfect and “False”
otherwise (use the function from the 1st question)
-
Create a Perfect List() function, which accepts a Limit parameter,
then returns a list containing the perfect numbers less than Limit
I’m having trouble with the last question
This is my attempt so far, but there are errors. How can I correct these errors?
def liste_diviseur(N):
t = []
for i in range(1,N):
if(N%i == 0):
t.append(i)
return t
def est_parfait(M):
s = 0
for i in liste_diviseur(M):
s += i
if(s == M):
return True
else:
return False
def liste_parfait(Limite):
t = []
lis = print(liste_diviseur(Limite))
if(Limite<lis):
t.append(Limite)
return t
m = int(input('Giving an number :'))
print(liste_parfait(m))
Answers:
Your error appears to be when you set lis = print(liste_diviseur(Limite))
. print() is a void function which will return null. Removing the print()
should fix your problem
You need to create a range and then check if each number in the range is perfect.
def liste_diviseur(n):
return [i for i in range(1,n//2+1) if n%i==0]
def est_parfait(n):
return n == sum(liste_diviseur(n))
def liste_parfait(limite):
return [i for i in range(2, limite) if est_parfait(i)]
test = int(input('Giving an number: '))
print(liste_parfait(test))
# output for 8129
[6, 28, 496, 8128]
The main part is generating the divisors. You can find some ideas for efficiency e.g. here.
For large numbers, one would use factorization of n
into its factors (see e.g. an answer I wrote for another problem), and then generate all divisors by combining those factors.
Here, we’ll go for simplicity:
from math import isqrt
def divisors(n):
m = isqrt(n)
for i in range(1, m + 1):
if n % i == 0:
yield i
j = n // i
if i < j < n:
yield n // i
Example:
>>> list(divisors(36))
[1, 2, 18, 3, 12, 4, 9, 6]
Note that divisors()
returns a generator, not a list
, and the divisors are produced out of order (more precisely: as pairs i
and n // i
). But this doesn’t matter to see if a number if perfect or not:
def is_perfect(n):
return sum(divisors(n)) == n
>>> is_perfect(5)
False
>>> is_perfect(6)
True
Now for a list of perfect numbers:
>>> [n for n in range(1, 10_000) if is_perfect(n)]
[6, 28, 496, 8128]
I’m having trouble understanding and applying this exercise on my own with Python. I am getting this:
TypeError: '<' not supported between instances of 'int' and 'NoneType'
This is the exercise Algorithm:
Definition: An integer is said to be perfect if it is equal to the sum
of all its divisors. Examples: 6 and 28 are perfect since 6 = 1+2+3
(knowing that 1, 2 and 3 are the divisors of 6 less than 6) 28=
1+2+4+7+14 (knowing that 1, 2, 4, 7 and 14 are the divisors of 28 less
than 28)
Create a function liste_divisors(), which accepts an
integer N as a parameter and returns the list of its divisors less
than N (1 included).Make a function is perfect(), which accepts a (positive) integer N
as a parameter and returns “True” if it is perfect and “False”
otherwise (use the function from the 1st question)Create a Perfect List() function, which accepts a Limit parameter,
then returns a list containing the perfect numbers less than Limit
I’m having trouble with the last question
This is my attempt so far, but there are errors. How can I correct these errors?
def liste_diviseur(N):
t = []
for i in range(1,N):
if(N%i == 0):
t.append(i)
return t
def est_parfait(M):
s = 0
for i in liste_diviseur(M):
s += i
if(s == M):
return True
else:
return False
def liste_parfait(Limite):
t = []
lis = print(liste_diviseur(Limite))
if(Limite<lis):
t.append(Limite)
return t
m = int(input('Giving an number :'))
print(liste_parfait(m))
Your error appears to be when you set lis = print(liste_diviseur(Limite))
. print() is a void function which will return null. Removing the print()
should fix your problem
You need to create a range and then check if each number in the range is perfect.
def liste_diviseur(n):
return [i for i in range(1,n//2+1) if n%i==0]
def est_parfait(n):
return n == sum(liste_diviseur(n))
def liste_parfait(limite):
return [i for i in range(2, limite) if est_parfait(i)]
test = int(input('Giving an number: '))
print(liste_parfait(test))
# output for 8129
[6, 28, 496, 8128]
The main part is generating the divisors. You can find some ideas for efficiency e.g. here.
For large numbers, one would use factorization of n
into its factors (see e.g. an answer I wrote for another problem), and then generate all divisors by combining those factors.
Here, we’ll go for simplicity:
from math import isqrt
def divisors(n):
m = isqrt(n)
for i in range(1, m + 1):
if n % i == 0:
yield i
j = n // i
if i < j < n:
yield n // i
Example:
>>> list(divisors(36))
[1, 2, 18, 3, 12, 4, 9, 6]
Note that divisors()
returns a generator, not a list
, and the divisors are produced out of order (more precisely: as pairs i
and n // i
). But this doesn’t matter to see if a number if perfect or not:
def is_perfect(n):
return sum(divisors(n)) == n
>>> is_perfect(5)
False
>>> is_perfect(6)
True
Now for a list of perfect numbers:
>>> [n for n in range(1, 10_000) if is_perfect(n)]
[6, 28, 496, 8128]