Python prime number program

Hi there! I have an assignment to create a code in python that will display a boolean value, depending on whether or not the number (n) entered into the function is prime or not, and I am absolutely stuck. I just started coding for the first time last week so I am very new, but having done some research I found that you could use a ‘for i in range […]’. Unfortunately I’m not allowed to use loops or recursion in this assignment, only the ‘divides’ function, mapping, and sum

Thus far, I’ve come up with
def divides (n):
def div (k):
return n % k == 0
return div

def prime (n):
print (“Is it Prime?”, map (divides, range (2, n)) )
if True: return “False”
else: return “True”

When I run the divides function with a number prime number (ie 7) for any one number in the range (2-n) it works perfectly

However, when running my prime function, it always returns True, regardless of whether or not the number is prime

If anyone can offer some helpful hints or point me in the right direction I would greatly appreciate it!!

Thanks

Welcome to Python :slight_smile:

You’ve done a great job at explaining your problem and demonstrating research. It’s a great way to help those who are helping you. Another way to improve your future posts is to ensure your have good indentation in code blocks. (Look up “code fences in markdown” and you’ll see what I mean).

Anyhow, regarding your question:

… when running my prime function, it always returns True, regardless of whether or not the number is prime

Whatever prime() returns in your case is independent from divides because printing is separate from returning. Moreover, I would expect prime to always return the string "False". Perhaps I’m not interpreting your code correctly. Do you mind editing with the correct indentation? Also, please demonstrate how you are calling these functions and the output you get.

The code I currently have (slightly modified from earlier) is

def divides (n):
        def div (k):
            return n % k == 0
        return div

prime (n):
        print ("Is it Prime?", map (divides, range (2, n)) )
        if True: return "False"
        if False: return "True"

(hopefully that indented correctly)

After rerunning my function I realized that it does usually return “False”, but does not return “True” for prime numbers- my mistake. I had it flipped since the divides function returns “False” for prime numbers, as they aren’t divisible by the integer ‘k’

below is are examples of what python returns when i run the program with 2, 4 and 7 as ‘n’

>>> prime (2)
Is it Prime? []
'False'

>>>  prime (4)
Is it Prime? [<function divides.<locals>.div at 0x1089b3940>, <function divides.<locals>.div at 0x1089b39d0>]
'False'

>>>prime (7)
Is it Prime? [<function divides.<locals>.div at 0x1089b38b0>, <function divides.<locals>.div at 0x1089b3940>, <function divides.<locals>.div at 0x1089b39d0>, <function divides.<locals>.div at 0x1089b3a60>, <function divides.<locals>.div at 0x1089b3af0>]
'False'

When I enter 2 as ‘n’, I assume it shows the empty brackets “” because the range i entered in the code is (2,n), which of course wouldn’t show 2 as a prime number (I haven’t gotten far enough to try and solve that problem yet)

However for 7, I’m not sure why it wouldn’t run correctly.
Below is the prompt for the question which will hopefully give more insight into the proper way of how I should go about solving the problem.

" Write a function called prime(n) that takes a positive integer n as input
and returns True or False depending on whether n is prime or composite. You should not use any loop structures or recursion here. Instead, you may use ~map~, you may call the ~divides~ function above, and you may wish to use ~sum~ which takes a list of numbers as input and returns the sum of
the numbers in that list. Aside from the ‘def prime(n)’ line, your program should be at most three lines long (although it can be done in fewer lines!)."

Thank you so much for your help on this!! It’s been stressing me out for days. Please let me know if there’s anything else I can provide that would help.

Hi Mike,

You seem to be running Python 2. Is that intentional? Python 2 is now
unsupported and, if not completely obsolete, well on the way to being
obsolete.

Having said that, there’s a lot to be unpacked in your question. Let’s
start with the “divides” function:

def divides (n):
    def div (k):
        return n % k == 0
    return div

This is sometimes called a “factory function”, because it builds a new
function each time you call it, and returns that new function as if it
were a value like 23 or “hello world”. If this seems weird to you, you
aren’t alone: it is a rather advanced technique that managers to confuse
beginners and experts alike, at least until they get used to it.

Personally I love factory functions, but I think this specific example
is a horribly confusing and convoluted way to test for prime numbers.
But it is what it is, and you have to live with it.

So let’s unpack the divides function carefully. If you call it with
input 7, for example, it returns a new function that expects a number k
as input and returns whether or not 7 remainder k is 0:

>>> func = divides(7)
>>> print(func)
<function divides.<locals>.div at 0x7f8bf1621b90>
>>> func(1)
True
>>> func(2)
False
>>> func(7)
True

If the remainder is 0, then k divides 7.

How do we use this to test whether 7 is prime?

  • 1 always divides everything, so we can skip 1;
  • if 2 divides 7, then 7 isn’t prime;
  • if 3 divides 7, then 7 isn’t prime;
  • if 4 divides 7, then 7 isn’t prime;
  • if 5 divides 7, then 7 isn’t prime;
  • if 6 divides 7, then 7 isn’t prime;
  • and of course 7 divides 7, so we skip that.

Another way to do this would be to skip 1 and 7, and add up all the
“this divides 7” results. If the number of “this divides 7” results is
exactly 0 then 7 is prime; if the total is 1 or more, then 7 is not
prime.

(By the way, this is an inefficient way of checking for prime numbers,
but let’s not worry about efficiency now, let’s just get it working.)

So our first step might be to build a list of True/False “this divides
7” flags, and add them up:

div = divides(7)
total = sum([div(2), div(3), ... div(6)])
if total == 0:
    # prime, so return True
else:
    # not prime, so return False

This works because Python treats True as 1 and False as 0.

Clearly we don’t want to have to manually list all those individual
“this divides 7” tests, we want to use a loop. Except no loops are
allowed, so we have to use map.

div = divides(7)
flags = map(div, [2, 3, 4, 5, 6])

will give you a list of flags that you can then pass to sum to get the
total:

total = sum(flags)

So here is your exercise:

  • Put those steps into a function “prime(n)”.

  • Don’t hard code the value 7, but use the parameter n instead.

  • Likewise, don’t hard code the list [2, 3, 4, 5, 6]. Instead use the
    function range to generate that list.

  • Once you have added up the total number of “this divides n” then you
    can return either True or False as needed.

Remember that the True and False constants are different from the
strings “True” and “False”. There’s nothing special about the strings
“True” and “False” in Python, they’re just strings like “Hello”,
“Goodbye”, “wibble”, “qwerty” etc. The exercise here is to use the
special constants True and False, not the strings.

So once you have done all that, you should have a smallish function that
correctly returns whether or not it’s input is prime:

prime(2)  # must return True
prime(3)  # must return True
prime(4)  # must return False
prime(100)  # must return False
prime(101)  # must return False

Try to get that much working on your own, then we can look at
squeezing the function down into just three lines.

Good luck, and feel free to ask questions if any of this is unclear.

Hi Py,

I think you have missed that the exercise provides the divides()
function, and you must use it as given with no modifications.

Also I think you missed that Mike is using Python 2, where map returns a
list, not an iterator.

Hey Steven!
I can confirm I’m running python 3.8.5- I might’ve formatted my code wrong when entering it in my response.

Anyway, I took what you said, put the steps into prime, and then simplified it to make it exactly 3 lines!!

my final code was

        total = sum (map (divides (n),range (2,(n-1))))
        if total == 0: return True
        else: return False

Thank you SO much for your help, it was so satisfying to finally have it work!