0

CodeWars problem:

Create a function named divisors that takes an integer and returns an array with all of the integer's divisors(except for 1 and the number itself). If the number is prime return the string '(integer) is prime'

My code below runs perfectly when I tested it in Spyder3 for Python.

def divisors(integer):
    arr = []
    for x in range(2,integer - 1): #if integer is 12
        if integer % x == 0:
            arr.append(x)
        
    if len(arr) == 0:
        print(integer, 'is prime')
    else:    
        print(arr)

However, when I submit it to CodeWars, it returns the following error:

divisors(15) should return [3, 5]; my function does this. The CodeWars window log shows that the answer is right, but proceeds to say None should equal [3, 5].

I checked to see if it was returning a something other than a list, but that checks out. Can anybody spot the problem?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Jack Ingram
  • 23
  • 1
  • 3
  • 1
    You're not returning the array. Also, you need to divide while it is a factor. Make sure it returns `3, 3` for `9`, for example – Artyer Jun 20 '17 at 22:08
  • 1
    Find+Replace All > print > return – cs95 Jun 20 '17 at 22:11
  • 1
    @Artyer: I suspect that returning multiple divisors will get the solution rejected. It asks for divisors, not prime factorization. – Prune Jun 20 '17 at 22:14
  • Does this answer your question? [Python Function Returning None](https://stackoverflow.com/questions/21471876/python-function-returning-none) – Tomerikoo Oct 17 '21 at 09:23

3 Answers3

3

The site expects you to return a value from your function - while you just print it:

if len(arr) == 0:
    return str(integer) + ' is prime'
else:    
    return arr
Uriel
  • 15,579
  • 6
  • 25
  • 46
1

Your function returns None -- there is no return statement, no return value. The default return value for a function is None, hence the error message you get.

def divisors(integer):
    arr = []
    for x in range(2,integer - 1): #if integer is 12
        if integer % x == 0:
            arr.append(x)

if len(arr) == 0:
    return str(integer) + ' is prime'
else:    
    return arr

for i in [1, 3, 9, 12, 64]:
    print (i, divisors(i))

Output:

1 1 is prime
3 3 is prime
9 [3]
12 [2, 3, 4, 6]
64 [2, 4, 8, 16, 32]
Prune
  • 76,765
  • 14
  • 60
  • 81
1

A Meta Answer to your question...

Since every other answer has addressed the (obvious) main issue, I'd like to offer an improvement to your existing algorithm (since this is codewars). This link will explain why this code works.

def divisors(integer):
    arr = []
    for x in range(2, round(integer ** 0.5)): #if integer is 12
        if integer % x == 0:
            arr.append(x)

    if len(arr) == 0:
        return str(integer) + ' is prime'
    else:    
        return arr 

A non-prime number will have factors only upto its square root in magnitude. This offers you complexity a little better than O(n), and the improvement is markedly seen for very large inputs.


You can now look at shortening your code considerably with a list comprehension.

def divisors(integer):
    arr = [x for x in range(2, round(integer ** 0.5)) if integer % x == 0]

    if len(arr) == 0:
        return str(integer) + ' is prime'

    return arr 

This does the same thing, but now the loop has been moved into the comprehension. The else is also redundant.

cs95
  • 379,657
  • 97
  • 704
  • 746
  • A bit too much to say for a comment, and also implicitly addresses the issue. :] – cs95 Jun 20 '17 at 22:37
  • 1
    you could sum it as `iterate until `round(integer ** 0.5)` rather than `integer - 1` [source]`. and there are a couple more improvements that could be put in place. I know the feeling that you want to share some really clever trick you've seen with OP - but answers are not the place. – Uriel Jun 20 '17 at 22:39
  • @Uriel I completely get it. I've mentioned that my answer is only a meta answer. I still feel this'd be useful for future readers. You have my +1. – cs95 Jun 20 '17 at 22:47
  • by the way, you could replace `if len(arr) == 0` with `if not arr`. though I do not suggest incorporating it into your answer – Uriel Jun 20 '17 at 22:51
  • not really. using `if arr` to check that a dictionary, list or any other boolean convertible type is not empty is quite common, easy, *and* pythonic. – Uriel Jun 20 '17 at 22:54