Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am a beginner in Python and just starting to learn. Please help me with the below code.
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n
if n % divisor = 0
sum = sum + divisor
divisor += 1
# Return the sum of all divisors of n, not including n
return sum
print(sum_divisors(0))
# 0
print(sum_divisors(3)) # Should sum of 1
# 1
print(sum_divisors(36)) # Should sum of 1+2+3+4+6+9+12+18
# 55
print(sum_divisors(102)) # Should be sum of 2+3+6+17+34+51
# 114
However, I am getting the below error, please help:
Error on line 4:
while divisor < n
^
SyntaxError: invalid syntax
You missed the trailing ":": while divisor < n:.
There are also various problems with the indentation.
This may fix your code:
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n:
if n % divisor == 0:
sum = sum + divisor
divisor += 1
# Return the sum of all divisors of n, not including n
return sum
It's simple:
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n:
if n % divisor == 0:
sum = sum + divisor
divisor += 1
It's simple syntax: there's supposed to be a ":" after the while and if statements.
And indentation after that.
Also == for if statements
You need a colon (:) after the while and if statements and proper indentation, and the = is for variable assigning, the operator for equality is ==:
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n:
if n % divisor == 0:
sum = sum + divisor
divisor += 1
You need to put : after while,if,for and function definitions. Also you need to check the equality with == instead of =.
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n:
if n % divisor == 0:
sum = sum + divisor
divisor += 1
# Return the sum of all divisors of n, not including n
return sum
There were few mistakes of missing colon. I have fixed them.
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n:
if n % divisor == 0:
sum = sum + divisor
divisor += 1
# Return the sum of all divisors of n, not including n
return sum
print(sum_divisors(0))
# 0
print(sum_divisors(3)) # Should sum of 1
# 1
print(sum_divisors(36)) # Should sum of 1+2+3+4+6+9+12+18
# 55
print(sum_divisors(102)) # Should be sum of 2+3+6+17+34+51
# 114
Related
i'm new to python and programming at all
Was trying to make a code to give me all the factors of a number, but can't see where i'm lacking
def divisores(numero):
divisor = 0
while divisor < numero :
divisor += 1
if numero % divisor == 0:
return(divisor)
divisores(50)
all it shows is "1", that is the first factor. If i use "print", it indeed gives all the factors,but i wanted it to be all in a single line
Return a list:
def divisores(numero):
divisor = 0
divs = [] # empty list
while divisor <= numero :
divisor += 1
if numero % divisor == 0:
divs.append(divisor)
return divs
Also, since you are counting 1 as an divisor, you likely want numero counting as a valid divisor as well. Hence, while divisor <= numero.
If you want your output on a single line then you can achieve this conveniently by writing a generator which you unpack as follows:
def factors(n):
def y(f):
nonlocal neg
yield f
if neg:
yield -f
if n == 0:
raise ValueError('Cannot factor zero')
if neg := n < 0:
n = -n
yield from y(1)
for factor in range(2, n // 2 + 1):
if n % factor == 0:
yield from y(factor)
yield from y(n)
print(*factors(50))
Output:
1 2 5 10 25
def sum_divisors(n):
sum = 0
# Return the sum of all divisors of n, not including n
return sum
print(sum_divisors(0))
# 0
print(sum_divisors(3)) # Should sum of 1
# 1
print(sum_divisors(36)) # Should sum of 1+2+3+4+6+9+12+18
# 55
print(sum_divisors(102)) # Should be sum of 2+3+6+17+34+51
# 114
I attempted to find the range of the numbers with this that I found on another question asked on here but I'm honestly just completely stumped with this question that I'm being asked even with the help that's alread given within the question.
for i in xrange(1,n/2+1):
if n%i == 0:
I'm not sure how to properly input it so it ended up looking like this
def sum_divisors(n):
for i in xrange(1,n/2+1):
if n%i == 0:
sum = 0
return sum
# Return the sum of all divisors of n, not including n
print(sum_divisors(0))
# 0
print(sum_divisors(3)) # Should sum of 1
# 1
print(sum_divisors(36)) # Should sum of 1+2+3+4+6+9+12+18
# 55
print(sum_divisors(102)) # Should be sum of 2+3+6+17+34+51
# 114
This should work:
def sum_divisors(n):
sum = 0
for i in range(1, int(n/2 + 1)):
if (n % i) == 0:
sum = sum + i
return sum
Be careful: xrange is used in Python 2 while range is Python 3, more info at this other question.
def sum_divisors(n):
sum = 0
for i in range(n-1):
i +=1
if n%i == 0:
sum += i
return sum
this is quite simple and works
Use the sum() function to add a sequence.
And you only need to go up to the square root of the number, not half the number.
from math import sqrt
def sum_divisors(n):
if n < 1:
return 0
return sum(i for i in range(int(sqrt(n))+1) if n % i == 0)
I have written some code below that is meant to print our how many times some integer n can be divided by a divisor:
for example if n = 100, divisor = 2 output = 6. (as 100 can be divided by 2, 6 times)
def divisions(n, divisor):
division_counter = 0
n2 = n // divisor
if n2 != 1:
division_counter += 1
n2 = divisions(n2,divisor)
else:
return division_counter
return n2
The question I have is with the last line of code- what should I be returning?- is it correct to return n2? My thought behind this is that this will execute after every if statement, and so by the way I have defined n2, this will cause a recursion of the function divisions().
And the recursion will break, and thus 'else' statement will print when n2 == 1, which will always happen eventually.
You are resetting the counter to 0 every time you go into the function. Instead, pass the counter along to each successive call. I've also fixed the off-by-one error below (if n2:) as the test case was producing 5 rather than 6.
def divisions(n, divisor, counter=0):
n2 = n // divisor
if n2:
counter += 1
n2 = divisions(n2, divisor, counter)
else:
return counter
return n2
>>> divisions(100, 2)
6
First step to set the result for boundary condition which to end the recursion.
for example:
if n < divisor:
return 0
If not, final result should one more times than result of divisions for new_n is n//divisor
So full code
def divisions(n, divisor):
if n < divisor:
return 0
return 1 + divisions(n//divisor, divisor)
print(divisions(100, 2)) # 6 for 100, 50, 25, 12, 6, 3
print(divisions(100, 3)) # 4 for 100, 33, 11, 3
You can go with recursion #Tigerhawk or you can go with iteration method as per my logic,
Just iteration with condition up to dividend become 0 by this operation n //= divisor.
And finally return number of iteration takes place
Check out this code
Method-1:
def divisions(n, divisor):
for i in range(n):
n //= divisor
if not n :
return i
print(divisions(100, 2))
Method-2:
def divisions(n, divisor):
number = 0
condn = True
while condn:
n //= divisor
if n:
number +=1
else:
return number
print(divisions(100, 2))
If a number is very large you can go with this method:
Method-3
from math import log
n = 100
k = int(log(n, 2))
print(k)
Recursion is a functional heritage and so we should avoid things like mutation, variable reassignment, and other side effects. We can rewrite this using mathematical induction -
if n is smaller than the divisor, no more divisions are possible. return the counter
(inductive) n is greater than or equal to the divisor, so at least one division is possible. return the result of the sub-problem (n // divisor, divisor, counter + 1)
def divisions(n, divisor, counter = 0):
if n < divisor:
return counter # 1
else:
return divisions(n // divisor, divisor, counter + 1) # 2
A simple variation removes the unnecessary counter variable -
if n is smaller than the divisor, zero divisions are possible. return 0
(inductive) n is greater than or equal to the divisor, so at least one division is possible. return 1 + the result of the sub-problem (n // divisor, divisor)
def divisions(n, divisor):
if n < divisor:
return 0 # 1
else:
return 1 + divisions(n // divisor, divisor) # 2
Another approach would be using math.log:
import math
def divisions(n, divisor):
return math.floor(math.log(n,divisor))
Beginner here. I tried to sum all divisors of a number but the number itself. I wrote a code without using elif.
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n:
if n == 0:
return 0
else:
n % divisor == 0
sum += divisor
divisor += 1
return sum
print(sum_divisors(0))
# 0
print(sum_divisors(3)) # Should sum of 1
# 1
print(sum_divisors(36)) # Should sum of 1+2+3+4+6+9+12+18
# 55
print(sum_divisors(102)) # Should be sum of 2+3+6+17+34+51
# 114
I got the answers 0, 1, 630 and 5151. Then, I rewrote the code by using elif. Got the right answers.
def sum_divisors(n):
sum = 0
divisor = 1
while divisor < n:
if n == 0:
return 0
elif n % divisor == 0:
sum += divisor
divisor += 1
else:
divisor += 1
return sum
print(sum_divisors(0))
print(sum_divisors(3))
print(sum_divisors(36))
print(sum_divisors(102))
There is something wrong in the first attempt, I feel it but I can't explain it. Is it related to the order of operations? Can someone explain what's going on in the execution of the first code?
You declared a statement with no usage n % divisor == 0 And in the second code block it is an elif statement. That's why the first code is not working - you have checked whether it is True but you did not add an elif statement and what should be executed there.
def sum_divisors(n):
sum1 = 0
divisor = 1
while divisor < n:
if n == 0:
return 0
elif n % divisor == 0:
sum1 += divisor
divisor += 1
else:
divisor += 1
return sum1
print(sum_divisors(36))
print(sum_divisors(102))
My code is very slow when it comes to very large numbers.
def divisors(num):
divs = 1
if num == 1:
return 1
for i in range(1, int(num/2)):
if num % i == 0:
divs += 1
elif int(num/2) == i:
break
else:
pass
return divs
For 10^9 i get a run time of 381.63s.
Here is an approach that determines the multiplicities of the various distinct prime factors of n. Each such power, k, contributes a factor of k+1 to the total number of divisors.
import math
def smallest_divisor(p,n):
#returns the smallest divisor of n which is greater than p
for d in range(p+1,1+math.ceil(math.sqrt(n))):
if n % d == 0:
return d
return n
def divisors(n):
divs = 1
p = 1
while p < n:
p = smallest_divisor(p,n)
k = 0
while n % p == 0:
k += 1
n //= p
divs *= (k+1)
return divs - 1
It returns the number of proper divisors (so not counting the number itself). If you want to count the number itself, don't subtract 1 from the result.
It works rapidly with numbers of the size 10**9, though will slow down dramatically with even larger numbers.
Division is expensive, multiplication is cheap.
Factorize the number into primes. (Download the list of primes, keep dividing from the <= sqrt(num).)
Then count all the permutations.
If your number is a power of exactly one prime, p^n, you obvioulsy have n divisors for it, excluding 1; 8 = 2^3 has 3 divisors: 8, 4, 2.
In general case, your number factors into k primes: p0^n0 * p1^n1 * ... * pk^nk. It has (n0 + 1) * (n1 + 1) * .. * (nk + 1) divisors. The "+1" term counts for the case when all other powers are 0, that is, contribute a 1 to the multiplication.
Alternatively, you could just google and RTFM.
Here is an improved version of my code in the question. The running time is better, 0.008s for 10^9 now.
def divisors(num):
ceiling = int(sqrt(num))
divs = []
if num == 1:
return [1]
for i in range(1, ceiling + 1):
if num % i == 0:
divs.append(num / i)
if i != num // i:
divs.append(i)
return divs
It is important for me to also keep the divisors, so if this can still
be improved I'd be glad.
Consider this:
import math
def num_of_divisors(n):
ct = 1
rest = n
for i in range(2, int(math.ceil(math.sqrt(n)))+1):
while rest%i==0:
ct += 1
rest /= i
print i # the factors
if rest == 1:
break
if rest != 1:
print rest # the last factor
ct += 1
return ct
def main():
number = 2**31 * 3**13
print '{} divisors in {}'.format(num_of_divisors(number), number)
if __name__ == '__main__':
main()
We can stop searching for factors at the square root of n. Multiple factors are found in the while loop. And when a factor is found we divide it out from the number.
edit:
#Mark Ransom is right, the factor count was 1 too small for numbers where one factor was greater than the square root of the number, for instance 3*47*149*6991. The last check for rest != 1 accounts for that.
The number of factors is indeed correct then - you don't have to check beyond sqrt(n) for this.
Both statements where a number is printed can be used to append this number to the number of factors, if desired.