Python Prime "C-number" - python

"C-number" is an integer n > 1 such that (b^n)mod n = b for all integers 1
Basically I have to create a program to run through about 2000 integers(1-2000), and have it satisfy the C-number condition, and then also check to see if it is NOT a prime number. I can't seem to get the loop working correctly.
I have a program that creates a list of non primes, and a working program that if I input a number, it will return me that number if it is a c-number, if not I'll get false returned.
I want it to just check numbers 1-2000 rather than just the one number I inputted, and then also check against the list of non prime numbers.
Here's my code:
import numpy
def primesfrom2to(n):
""" Input n>=6, Returns a array of primes, 2 <= p < n """
sieve = numpy.ones(n/3 + (n%6==2), dtype=numpy.bool)
for i in xrange(1,int(n**0.5)/3+1):
if sieve[i]:
k=3*i+1|1
sieve[ k*k/3 ::2*k] = False
sieve[k*(k-2*(i&1)+4)/3::2*k] = False
return numpy.r_[2,3,((3*numpy.nonzero(sieve)[0][1:]+1)|1)]
num=range(600)
mylist =primesfrom2to(600)
s = [item for item in num if item not in mylist]
a=[]
d=[]
from math import *
def numc(n):
for a in range(1,n):
c= a**n
d=c%n
if a == d:
return n
else:
return False
print numc(561)

You probably need to just fix the indentation (needs fixing in a lot of places):
def numc(n):
for a in range(1,n):
c= a**n
d=c%n
Python is pretty much written through indentation.

The easiest and even more important: cleanest way is to create two lists, one for prime numbers you found and one for c numbers. Then go through the lists to check which ones are in c numbers and not in prime numbers. Also split the functions for prime and c number in two functions. Something like:
prime_numbers = []
c_numbers = []
amount = 2000
for i in xrange(amount):
if is_prime(i):
prime_numbers.append(i)
if is_c_number(i):
c_numbers.append(i)
for i in xrange(amount):
if i in c_numbers and (not i in prime_numbers):
print i

First, not sure numc() does what you expect -- as written, that if statement will be tested only for the last value of a in the range. The if statement is not in the for loop block, so the loop will spin through the assignments, and the if statement only goes against the values assigned in the last iteration. This seems more what you're looking for:
def numc(n):
for a in range(1,n):
c= a**n
d=c%n
if a != d:
return False
return n
Here if some a value fails the if test, the function returns False. If all a values pass it returns true.
Second, neither my draft nor yours returns an array, just an integer or a boolean. To get an array of values passing, you have to call the function on each item of an array of candidates.
This gives you the output, integer or boolean, for each member of the candidate array:
c_values = [numc(i) for i in range(1, 2000)]
You can get just the passing values by testing in the loop:
c_values = [numc(i) for i in range(1, 2000) if numc(i)]
You can do so without calling numc() twice by nesting the list comprehensions:
c_values = [i for i in [numc(j) for j in range(1, 2000)] if i]
That first generates the complete array of output values, then returns only those that are True.
EDIT: You seem confused by the block indentation, or perhaps the two return statements. Here is another way with one return:
def numc(n):
retval = n
for a in range(1,n):
c= a**n
d=c%n
if a != d:
retval = False # reset return value
break # halt the loop
return retval
Here the default return value is << n >>, to be reset within the << for >>loop if cnumber conditionality is violated by some value of << a >>. In which case, << break >> halts the loop (though here it needn't.) The function just returns whatever << retval >> happens to be when the return statment is reached.
My initial draft had the same effect, but there the for loop was interrupted / 'broken' by the << return False >> statement -- which also there interrupted the function, preventing it from reaching the << return n >>. If that statement weren't reached, ie no << a >> violated conditionality, the function would reach and execute << return n >>. If a function has two return statements, it will only execute the first one reached, and all code after that will be ignored.

Related

What’s wrong with my recursion for finding primes? (Python)

I’m trying to create a program that lists all the primes below an inputted number, and I came up with the code:
def primes():
num = 20
numlist = list(range(1,num+1))
i = len(numlist)
for j in numlist[2:]:
ans = divisible(j,i)
if ans:
numlist.remove(j)
print(numlist)
def divisible(m,n):
if m!=n and m%n==0:
return True
elif n == 1:
return False
else:
divisible(m, n-1)
primes()
(I used an in-browser IDE so the num part was a proxy for the input.)
My idea was to create a separate function divisible() that when inputted two ints, m and n, would check if n divides m. I'm not sure if I was right in my recursion, but I wrote divisible(m,n-1) the idea was that it would iterate through all the integers from n downward and it would return True if any n divided m, or False if it reached 1.
In the main code, m iterated through all the numbers in a list, and n is the total number of elements in the same list. I put the print(numlist) inside the if statement as an error check. The problem I’m having is nothing is printing. The code returned literally nothing. Is there something I’ve missed in how recursion works here?
There's a lot wrong here:
You've made a common beginner's recursion error in that you have a recursive function that returns a value, but when you call it recursively, you ignore the returned value. You need to deal with it or pass it along.
It seems like this modulus is backward:
if ... and m%n==0:
Maybe it should be:
if ... and n % m == 0:
You're code doesn't appear to be calculating primes. It's looks like it's calculating relative primes to n.
You start your list of numbers at 1:
numlist = list(range(1,num+1))
But you start testing at index 2:
for j in numlist[2:]:
Which is the number 3 and you never check the divisibility of the number 2.
Even with all these fixes, I don't feel your algorithm will work.
Your divisible function doesn't return anything if it falls into else part. change it as
def divisible(m, n):
if m!=m and m%n==0:
return True
elif n==1 :
return False
else:
return divisible(m,n-1)
This should work

How can I find sum of contiguous sequences of elements in a list?

I need to write a function that given a list of integers L, it returns True if the list contains a consecutive sequence of values whose sum is n, and False otherwise.
Let's say my list is: L = [2,2,4,4,0,0,2,8] and n = 3.
The function should return False because there are not consecutive values summing up to 3.
requirement: Python's modules are not allowed
I tried with:
def consecutive(L,n):
for i in range(len(L)):
for j in range(i+1, len(L)):
if sum(L[i:j+1])==n:
return True
return False
L = [2,2,4,4,0,0,2,8]
consecutive(L,3)
This is partially working because when I set n=12, it returns True. I understand there is something to fix with slicing, but I can't find out what it is.
The main problem is simple: in this situation, the range must be len+1, otherwise it will fail in fringe cases. Working code is:
def consecutive(L, n):
for i in range(len(L)+1):
for j in range(i+1,len(L)+1):
s=sum(L[i:j])
if s == n:
print(i,j,s,'TRUE') #DEBUG: remove when done
#return True #uncomment this to reintegrate
else: print(i,j,s) #DEBUG: remove when done
return False
L = [2,2,4,4,0,0,2,-3]
consecutive(L,3)
better yet, in your example, you didn't show negative numbers. If you have no negatives, you can make the code more efficient by skipping the loop when it exceeds your search value, n:
def consecutive(L, n):
for i in range(len(L)+1):
for j in range(i+1,len(L)+1):
s=sum(L[i:j])
if s == n:
print(i,j,s,'TRUE') #DEBUG: remove when done
#return True #uncomment
elif s > n:
print(i,j,s,'too big') #DEBUG: remove when done
break
else: print(i,j,s) #DEBUG: remove when done
return False
L = [2,2,4,4,0,0,2,1]
consecutive(L,3)
The naive way would be to loop through each starting potential starting point (each index) and each window size (any number from 0 to the length of the list):
def consecutive(L, n):
for i in range(len(L)):
for window_size in range(len(L)):
if sum(L[i:i + window_size]) == n:
return True
else:
return False
Note this could easily be improved, starting with not double checking the same windows multiple times (e.g., if the list is length 3, then L[2:4] and L[2:3] would be the same thing).

Function That Sums All Elements in List Up to But Not Including The First Even Number

I'm trying to write a python function that will sum up all of the elements in a list up to but not including the first even number. The function needs to pass the following tests:
from test import testEqual
testEqual(sum_of_initial_odds([1,3,1,4,3,8]), 5)
testEqual(sum_of_initial_odds([6,1,3,5,7]), 0)
testEqual(sum_of_initial_odds([1, -7, 10, 23]), -6)
testEqual(sum_of_initial_odds(range(1,555,2)), 76729)
I tried the following:
import random
lst = []
def sum_of_initial_odds(nums):
sum = 0
#test if element is odd number - if it's odd, add it to the previous integer
for i in lst:
if i % 2 != 0:
sum = sum + i
return sum
#test if element is even number - if it's even, don't include it and break code
else:
if i % 2 == 0:
break:
I'm currently getting a parse error:
ParseError: bad input on line 11
which is the line:
else:
How else can I write this code so that it adds the elements in a list, but doesn't include the first even number, without getting Parse errors?
You can do this very easily using itertools.takewhile:
>>> import itertools
>>> sum(itertools.takewhile(lambda x: x % 2 == 1, [1,3,1,4,3,8]))
5
takewhile will yield elements from the given sequence while the predicate x % 2 == 1 is True, i.e. it will get you all numbers up to the first even one. And sum, well, sums those values.
You have a few problems:
Indentations, which others have already mentioned
You return sum the first time you hit an odd number; this is so not what you want.
You ignore the input parameter nums and work with the empty global lst.
Your lowest if is redundant: you already know you have an even number when you get here.
In general, stuff partial results into local variables; have a single return at the bottom of your routine.
import random
def sum_of_initial_odds(lst):
sum = 0
#test if element is odd number - if it's odd, add it to the previous integer
for i in lst:
if i % 2 != 0:
sum = sum + i
#test if element is even number - if it's even, don't include it and break code
else:
break
return sum
print sum_of_initial_odds([1,3,1,4,3,8]) == 5
print sum_of_initial_odds([6,1,3,5,7]) == 0
print sum_of_initial_odds([1, -7, 10, 23]) == -6
print sum_of_initial_odds(range(1,555,2)) == 76729
THe output from this is four True values.
You could also use
def sum(numbers):
sum = 0
for number in numbers:
if number % 2 == 0:
break
else:
sum += number
return sum
And test using the asset statement which is a specialized form of raise statement
The advantage is that it throws AssertionError only when __debug__ is true thus avoiding throwing exception in production.
assert sum([1,3,1,4,3,8]) == 5 , "Your message if assertion fails"
You can turn off __debug__ by
Start interactive mode with python -O
Setting variable PYTHONOPTIMIZE to True

Getting First Prime in a List of Random Numbers

I was playing around with the Python shell and I have what I believe is an extremely naive implementation of a function that simply returns the first prime number in a list of 100 randomly generated numbers (whose values are between 0 and 99, inclusive). Code below:
>>> def is_prime(n):
if n < 2:
return False
elif n == 2:
return True
for i in range(2, n):
if n % i == 0:
return False
return True
>>> from random import randint
>>> numbers = []
>>> for i in range(0, 100):
numbers.append(randint(0, 99))
>>> def get_first_prime(values):
temp = []
for i in values:
if is_prime(i):
temp.append(i)
return temp[0]
>>> get_first_prime(numbers)
I want this function to strictly return only the first prime number. My implementation uses a helper list to cache all primes and then simply return the element at the first index. It works, but I'm not convinced it's a good one. I'm sure there is a more efficient way of doing this that does not require scanning through the entire list, but I can't seem to think of one yet.
What are some better alternatives?
def get_first_prime(values):
for i in values:
if is_prime(i):
return i
This way you don't keep searching once you find a prime. The function implicitly returns None if no prime is found.
Yes, you do not even need to generate a list of all the random numbers, you can test each one as they are generated, and return as soon as you've found one.
from random import randint
import math
def is_prime(n):
if n < 2:
return False
elif n == 2:
return True
for i in range(2, int(math.sqrt(n) + 1)):
if n % i == 0:
return False
return True
def get_first_prime(number):
for i in range(number + 1):
n = randint(0, 99)
if is_prime(n):
return n
get_first_prime(100)
You are right. Your code not only has more time complexity (running through all the list elements even after finding the first prime) and space complexity (temp list to hold all the primes) but also stands a risk of throwing IndexError when there are no prime numbers in the list.
So you could mend it in the following manner:
def get_first_prime(values):
for i in values:
if is_prime(i):
return i
Note that when there is no prime in the input the return statement would never get executed that means there is no explicit return; in which case Python returns None. So, if you choose to, you can return the value of your choice at the end of the function outside for loop to indicate 'not found'.
def get_first_prime(values):
for i in values:
if is_prime(i):
return i
return -1
Pythonic way of dealing with this is to raise an Exception and let the caller of the function deal with the exception.
prime = next(filter(isprime, numbers))
See find first element in a sequence that matches a predicate.

How to write more Pythonic Code

I started learning python today from the tutorial on the official site.
When reading about filter(function, sequence) i thought of making a function that returns if a number is prime to use it with the filter.
notDividedBy = [2,3,4,5,6,7,8,9]
def prime(num):
"""True if num is prime, false otherwise"""
copy = notDividedBy[:]
check = True
if num in copy:
copy.remove(num)
for x in copy:
if num % x == 0:
check = False
break
return check
The above code works in the shell.
My question is: Since i feel like although a solution, it is not the most elegant one, can anyone transform this code to something more python-like?(better structure? less lines?)
I believe it would help me for better understanding of the basics of the language.
The thing is, don't use any imports or anything, just simple staff.
Creating many many copies of lists is not a particularly efficient way of doing things. Instead use the xrange() (Python 2.x) or range() (Python 3) iterator. Here's one (naive) way you could implement a primality test:
from math import sqrt
def isPrime(n):
if n < 2: return False
if n == 2: return True
if not n % 2: return False #test if n is even
#we've already remove all the even numbers, no need to test for 2
#we only need to test up to sqrt(n), because any composite numbers can be
# factored into 2 values, at least one of which is < sqrt(n)
for i in xrange(3, int(sqrt(n)) + 1, 2):
if not n % i:
return False
return True
How about this one:
def is_prime(num):
return not any(num%i == 0 for i in xrange(2,num/2+1))
for i in xrange(10):
print i, is_prime(i)
Explanation
start with:
(num%i==0 for i in xrange(2,num/2+1))
This is a generator expression. I could have made it a list comprehension:
[num%i==0 for i in xrange(2,num/2+1)]
The list comprehension is equivalent to:
ll=[]
for i in xrange(2,num/2+1):
ll.append(num%i==0)
The difference between the generator and the list comprehension is that the generator only gives up it's elements as you iterate over it -- whereas the list comprehension calculates all the values up front. Anyway, from the above code, you can see that the expression generates a sequence of True's and False's. True if the number can be divided by i and False otherwise. If we generate a sequence of all False numbers, we know we have a prime.
The next trick is the any built in function. It basically searches through an iterable and checks if any of the values is True. As soon as it hits a True, it returns True. If it gets to the end of the iterable, it returns False. So, if the entire sequence is False (a prime number) then any will return False, otherwise it returns True. This would be perfect for a not_prime function, but our function is is_prime, so we just need to invert that result using the not operator.
The benefit of using the generator expression is that it is nice and concise, but also that it allows any to return before checking every value which means that as soon as it finds a number that divides num, it returns instead of generating all num/2 numbers.
Anyway, I hope this explanation is helpful. If not, feel free to leave a comment and I'll try to explain better.
One thing off the bat, if you are going to implement prime testing in this fashion, there's no reason to use an auxillary array
def prime(num):
"""True if num is prime, false otherwise"""
check = True
#if num in copy:
# copy.remove(num)
for x in range(2,x-1):
if num % x == 0:
check = False
break
return check
Here's a 2 liner using filter().
def prime(num):
"""True if num is prime, false otherwise"""
if num < 2:
return False
return len(filter(lambda x: num % x == 0, range(2, num))) == 0

Categories