did my program on perfect numbers in python and not sure if i should use (1,1000) or (2, n+1) in range
Asked Answered
C

5

5

I did lab on perfect numbers in python it runs fine and prints numbers that I need. But not sure if I need to put (1, 1000) in range or (2, n+1) is fine? My instruction asking me to

"Write a python program to find all the perfect numbers from 1 to 10,000. When a perfect number is found, your logic should print it."

What is a perfect number:

In number theory, a perfect number is a positive integer that is equal to the sum of its proper positive divisors, that is, the sum of its positive divisors excluding the number itself (also known as its aliquot sum). Equivalently, a perfect number is a number that is half the sum of all of its positive divisors (including itself) i.e. σ1(n) = 2n.

When I run my program it prints out 6, 28, 496, and 8128.

 n = 1
 while True:
     factors = [1]
     [factors.append(i) for i in range(2,n+1) if n%i == 0]
     if sum(factors) == 2*n: print n
     n += 1
Calendula answered 14/9, 2012 at 20:52 Comment(5)
what's a perfect number?Eyecup
@AshwiniChaudhary en.wikipedia.org/wiki/Perfect_numberRembert
You need to use both I think. n should be the one from (1, 1000), and then go over (2, n+1) to check each n.Synthesis
Ashwini my first two perfect numbers are 6 and 28, there are two others in the range to 10000. and when I run program it give me 496 and 8128....my only question do I have to use range (1,1000) or range (2, n+1)...my program is working fine....Calendula
So millimoose I should add (1, 1000) in front of (2, n+1)?Calendula
G
2

No need to go all the way up to n in your inner loop. You can just use range(2, n/2 + 1), and then if sum(factors) == n - 1. Your outer loop should be through range(2, 10001) (i.e. you should test every n in this range). Note that 1 is not considered a perfect number, so we shouldn't include it in our range.

for n in range(2, 10001):
    if sum(i for i in range(2, n/2 + 1) if n % i == 0) == n - 1:
        print n
Gora answered 14/9, 2012 at 20:57 Comment(1)
oh got you A.R.S i tried to put 1, 1000 and it was giving me errorCalendula
E
5

something like: you can also use a range(1,n) as perfect number is equal to sum of all its divisors except itself, i.e. 6=1+2+3

n = 1
while True:
    factors =(i for i in range(1,n) if n%i == 0) #use a generator expression
    if sum(factors) == n: 
        print n
    n += 1

output:

6
28
496
8128

or a one liner:

In [2]: [x for x in xrange(1,10001) if sum(y for y in xrange(1,x) if x%y==0)==x]
Out[2]: [6, 28, 496, 8128]
Eyecup answered 14/9, 2012 at 21:2 Comment(0)
G
2

No need to go all the way up to n in your inner loop. You can just use range(2, n/2 + 1), and then if sum(factors) == n - 1. Your outer loop should be through range(2, 10001) (i.e. you should test every n in this range). Note that 1 is not considered a perfect number, so we shouldn't include it in our range.

for n in range(2, 10001):
    if sum(i for i in range(2, n/2 + 1) if n % i == 0) == n - 1:
        print n
Gora answered 14/9, 2012 at 20:57 Comment(1)
oh got you A.R.S i tried to put 1, 1000 and it was giving me errorCalendula
H
1

Well, there are quite a few simple improvements you can add.

First off, use a range(2,n). You know n%n is 0, so no need to check n at all. Just remember that the sum should be n and not 2*n (you're seeing 2*n because you've added n to the list of factors).

If you really want to speed things up, use range(2, int(math.sqrt(n))). If a is a factor of n, so is n/a. So you can append ([i, n/i]) instead of just i. Don't forget to import math'.

Hamel answered 14/9, 2012 at 20:58 Comment(3)
Note there's no bug here if n=aa. In that case you'll add a twice and wrongfully report a perfect number only if aa = a+a+1 - this doesn't happen.Hamel
ok let me try that ah and import math I should put before the code?Calendula
Imports are usually placed at the beginning of the file.Hamel
D
0

You want to ger all numbers from range [1 .. n] that divide n, so you should use range(2, n+1). Here is simplified version of your code:

for n in range(1, 10001):
  factors = [i for i in range(1,n+1) if n % i == 0]
  if sum(factors) == 2*n: print n
Drench answered 14/9, 2012 at 20:57 Comment(0)
C
0

Not that I wanted to insult you or something, but I really don't like the style of coding, when it takes time to understand, why something works properly (I mean, why writing n+1 and then sum(factors) == 2*n; why factors = [1] if you could just written factors = [] and in range(1,n). :)

I'd write the same as (or even removed list comprehension to spare the consciousness of python newbies):

n = 1
while True:
    factors = []
    [factors.append(i) for i in range(1,n) if n % i == 0]
    if sum(factors) == n:
        print n
    n += 1

The same output.

Centipoise answered 14/9, 2012 at 21:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.