# My backwards logic

Rustom Mody rustompmody at gmail.com
Sat Sep 6 03:24:06 CEST 2014

```On Saturday, September 6, 2014 1:37:57 AM UTC+5:30, Paul Rubin wrote:
> Juan Christian  writes:
> >  I made this code just for fun and learning, it's working, but would
> >  this be a good approach? Thanks. ...
> >  ** ** for number in range(start, stop + 1):
> >  ** ** ** ** divisors = [(number % x) for x in range(1, number + 1)]
> >  ** ** ** ** ** ** print("{n} prime? {r}".format(n = number, r =
> >  (divisors.count(0) == 2)))

> 1. Mathematically it's better to stop checking once you've gone past
> the square root of the number, since if n = p*q and is composite,
> then at least one of p,q will be <= sqrt(n).

> 2. As a program design matter, it's generally preferable for functions
> like this to not print the answer.  They should just return a value, in
> this case a bool indicating whether the number is prime.  That makes it
> easier to re-use the function, to wrap it in a unit test framework, etc.
> If you want to print the result, then call the function and have the
> caller print the returned value.

Hoo boy! And we come full circle

> 3. As a simple optimization, once you have checked that the number is
> not divisible by 2, you don't have to check for other even divisors.
> So just check for 2, then the odd numbers 3,5,7...

> This is a little bit fancy but I like to use itertools for these
> sorts of problems:

>   from itertools import chain, takewhile, count

>   def is_prime(n):
>       if n < 2: return False
>       candidates = chain([2], count(3,2))
>       return all(n%d!=0 for d in takewhile(lambda d: d*d<=n, candidates))

Paul's suggestions without the fancy -- no sqrt stop, no generators, no itertools
etc -- (all to be learnt at their time of course!)

First of all I make for myself a closed range

>>> def crange(a,b) : return range(a,b+1)

Check it

>>> crange(1,10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Now for divisors of a number

>>> def divisors(n): return [fact for fact in crange(1,n) if n%fact == 0]

Check it

>>> divisors(4)
[1,2,4]

>>> divisors(7)
[1, 7]

So now a prime is a number n whose divisors are only 1 and n

>>> def is_prime(n): return divisors(n) == [1,n]

>>> is_prime(2)
True
>>> is_prime(3)
True
>>> is_prime(4)
False
>>> is_prime(5)
True
>>> is_prime(6)
False
>>> is_prime(7)
True

So collecting the code together

>>> def crange(a,b): return range(a,b+1)
>>> def divisors(n): return [fact for fact in crange(1,n) if n%fact == 0]
>>> def is_prime(n): return divisors(n) == [1,n]

```